Code Analyze and Refactor 0.12 (#109), version 0.11.4.2

This commit is contained in:
Markus Hofknecht 2020-07-06 21:15:45 +02:00
parent 48805cc0f2
commit 2d2eb88339
63 changed files with 1263 additions and 1017 deletions

View file

@ -1,15 +1,22 @@
using Microsoft.Win32;
using System;
using System.Windows.Forms;
using SystemTrayMenu.Business;
using SystemTrayMenu.UserInterface;
using SystemTrayMenu.Utilities;
// <copyright file="App.cs" company="PlaceholderCompany">
// Copyright (c) PlaceholderCompany. All rights reserved.
// </copyright>
namespace SystemTrayMenu
{
using Microsoft.Win32;
using System;
using System.Windows.Forms;
using SystemTrayMenu.Business;
using SystemTrayMenu.UserInterface;
using SystemTrayMenu.Utilities;
/// <summary>
/// App contains the notifyicon, the taskbarform and the menus.
/// </summary>
internal class App : IDisposable
{
private readonly MenuNotifyIcon menuNotifyIcon = new MenuNotifyIcon();
private readonly AppNotifyIcon menuNotifyIcon = new AppNotifyIcon();
private readonly Menus menus = new Menus();
private readonly TaskbarForm taskbarForm = new TaskbarForm();
@ -30,37 +37,37 @@ namespace SystemTrayMenu
menuNotifyIcon.OpenLog += Log.OpenLogFile;
menus.MainPreload();
taskbarForm.Activated += TasbkarItemActivated;
void TasbkarItemActivated(object sender, EventArgs e)
{
SetStateNormal();
taskbarForm.Activate();
taskbarForm.Focus();
menus.SwitchOpenCloseByTaskbarItem();
}
taskbarForm.Resize += TaskbarForm_Resize;
taskbarForm.FormClosed += TaskbarForm_FormClosed;
static void TaskbarForm_FormClosed(object sender, FormClosedEventArgs e)
{
Application.Exit();
}
taskbarForm.Deactivate += TaskbarForm_Deactivate;
void TaskbarForm_Resize(object sender, EventArgs e)
{
SetStateNormal();
}
DllImports.NativeMethods.User32ShowInactiveTopmost(taskbarForm);
}
private void TaskbarForm_FormClosed(object sender, FormClosedEventArgs e)
{
Application.Exit();
}
private void TaskbarForm_Resize(object sender, EventArgs e)
{
SetStateNormal();
}
internal void TasbkarItemActivated(object sender, EventArgs e)
{
SetStateNormal();
taskbarForm.Activate();
taskbarForm.Focus();
menus.SwitchOpenCloseByTaskbarItem();
}
private void TaskbarForm_Deactivate(object sender, EventArgs e)
{
SetStateNormal();
}
/// <summary>
/// This ensures that next click on taskbaritem works as activate event/click event
/// This ensures that next click on taskbaritem works as activate event/click event.
/// </summary>
private void SetStateNormal()
{
@ -69,6 +76,7 @@ namespace SystemTrayMenu
taskbarForm.WindowState = FormWindowState.Normal;
}
}
public void Dispose()
{
taskbarForm.Dispose();

View file

@ -1,15 +1,19 @@
using System;
using System.Drawing;
using System.Globalization;
using System.Linq;
using System.Windows.Forms;
using SystemTrayMenu.DataClasses;
using SystemTrayMenu.Helper;
using SystemTrayMenu.Utilities;
using Menu = SystemTrayMenu.UserInterface.Menu;
// <copyright file="KeyboardInput.cs" company="PlaceholderCompany">
// Copyright (c) PlaceholderCompany. All rights reserved.
// </copyright>
namespace SystemTrayMenu.Handler
{
using System;
using System.Drawing;
using System.Globalization;
using System.Linq;
using System.Windows.Forms;
using SystemTrayMenu.DataClasses;
using SystemTrayMenu.Helper;
using SystemTrayMenu.Utilities;
using Menu = SystemTrayMenu.UserInterface.Menu;
internal class KeyboardInput : IDisposable
{
internal event EventHandlerEmpty HotKeyPressed;
@ -36,20 +40,6 @@ namespace SystemTrayMenu.Handler
hook.Dispose();
}
private int GetMenuIndex(in Menu currentMenu)
{
int index = 0;
foreach (Menu menuFindIndex in menus.Where(m => m != null))
{
if (currentMenu == menuFindIndex)
{
break;
}
index++;
}
return index;
}
internal void RegisterHotKey()
{
if (!string.IsNullOrEmpty(Properties.Settings.Default.HotKey))
@ -111,6 +101,7 @@ namespace SystemTrayMenu.Handler
menus[indexNew].FocusTextBox();
}
break;
case Keys.Tab | Keys.Shift:
{
@ -129,6 +120,7 @@ namespace SystemTrayMenu.Handler
menus[indexNew].FocusTextBox();
}
break;
case Keys.Apps:
{
@ -143,10 +135,27 @@ namespace SystemTrayMenu.Handler
trigger.MouseDown(dgv, mea);
}
}
break;
default:
break;
}
int GetMenuIndex(in Menu currentMenu)
{
int index = 0;
foreach (Menu menuFindIndex in menus.Where(m => m != null))
{
if (currentMenu == menuFindIndex)
{
break;
}
index++;
}
return index;
}
}
/// <summary>
@ -185,6 +194,11 @@ namespace SystemTrayMenu.Handler
}
}
internal void ClearIsSelectedByKey()
{
ClearIsSelectedByKey(iMenuKey, iRowKey);
}
private bool IsAnyMenuSelectedByKey(
ref DataGridView dgv,
ref Menu menuFromSelected,
@ -265,6 +279,7 @@ namespace SystemTrayMenu.Handler
EnterPressed.Invoke(dgv, iRowKey);
}
}
break;
case Keys.Up:
if (SelectMatchedReverse(dgv, iRowKey) ||
@ -274,6 +289,7 @@ namespace SystemTrayMenu.Handler
SelectRow(dgv, iRowKey);
toClear = true;
}
break;
case Keys.Down:
if (SelectMatched(dgv, iRowKey) ||
@ -283,6 +299,7 @@ namespace SystemTrayMenu.Handler
SelectRow(dgv, iRowKey);
toClear = true;
}
break;
case Keys.Left:
int iMenuKeyNext = iMenuKey + 1;
@ -322,6 +339,7 @@ namespace SystemTrayMenu.Handler
}
}
}
break;
case Keys.Right:
if (iMenuKey > 0)
@ -349,6 +367,7 @@ namespace SystemTrayMenu.Handler
toClear = true;
Cleared?.Invoke();
}
break;
case Keys.Escape:
RowDeselected(iRowBefore, dgvBefore);
@ -382,8 +401,10 @@ namespace SystemTrayMenu.Handler
}
}
}
break;
}
if (isStillSelected && toClear)
{
ClearIsSelectedByKey(iMenuBefore, iRowBefore);
@ -396,8 +417,7 @@ namespace SystemTrayMenu.Handler
RowSelected(dgv, iRowKey);
}
private bool SelectMatched(DataGridView dgv,
int indexStart, string keyInput = "")
private bool SelectMatched(DataGridView dgv, int indexStart, string keyInput = "")
{
bool found = false;
for (int i = indexStart; i < dgv.Rows.Count; i++)
@ -408,11 +428,11 @@ namespace SystemTrayMenu.Handler
break;
}
}
return found;
}
private bool SelectMatchedReverse(DataGridView dgv,
int indexStart, string keyInput = "")
private bool SelectMatchedReverse(DataGridView dgv, int indexStart, string keyInput = "")
{
bool found = false;
for (int i = indexStart; i > -1; i--)
@ -423,6 +443,7 @@ namespace SystemTrayMenu.Handler
break;
}
}
return found;
}
@ -433,6 +454,7 @@ namespace SystemTrayMenu.Handler
{
ClearIsSelectedByKey();
}
iRowKey = i;
iMenuKey = newiMenuKey;
DataGridViewRow row = dgv.Rows[i];
@ -440,13 +462,12 @@ namespace SystemTrayMenu.Handler
rowData.IsSelected = true;
if (refreshview)
{
row.Selected = false; //event trigger
row.Selected = true; //event trigger
row.Selected = false;
row.Selected = true;
}
}
private bool Select(DataGridView dgv, int i,
string keyInput = "")
private bool Select(DataGridView dgv, int i, string keyInput = "")
{
bool found = false;
if (i > -1 &&
@ -460,8 +481,8 @@ namespace SystemTrayMenu.Handler
{
iRowKey = rowData.RowIndex;
rowData.IsSelected = true;
row.Selected = false; //event trigger
row.Selected = true; //event trigger
row.Selected = false;
row.Selected = true;
if (row.Index < dgv.FirstDisplayedScrollingRowIndex)
{
dgv.FirstDisplayedScrollingRowIndex = row.Index;
@ -477,12 +498,8 @@ namespace SystemTrayMenu.Handler
found = true;
}
}
return found;
}
internal void ClearIsSelectedByKey()
{
ClearIsSelectedByKey(iMenuKey, iRowKey);
return found;
}
private void ClearIsSelectedByKey(int menuIndex, int rowIndex)

View file

@ -1,22 +1,23 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Security;
using System.Windows.Forms;
using SystemTrayMenu.DataClasses;
using SystemTrayMenu.Handler;
using SystemTrayMenu.Helper;
using SystemTrayMenu.Utilities;
using Menu = SystemTrayMenu.UserInterface.Menu;
using Timer = System.Windows.Forms.Timer;

namespace SystemTrayMenu.Business
{
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Security;
using System.Windows.Forms;
using SystemTrayMenu.DataClasses;
using SystemTrayMenu.Handler;
using SystemTrayMenu.Helper;
using SystemTrayMenu.Utilities;
using Menu = SystemTrayMenu.UserInterface.Menu;
using Timer = System.Windows.Forms.Timer;
internal class Menus : IDisposable
{
internal event EventHandlerEmpty LoadStarted;
@ -99,12 +100,13 @@ namespace SystemTrayMenu.Business
{
workerSubMenu = new BackgroundWorker
{
WorkerSupportsCancellation = true
WorkerSupportsCancellation = true,
};
workerSubMenu.DoWork += LoadMenu;
workerSubMenu.RunWorkerCompleted += LoadSubMenuCompleted;
workersSubMenu.Add(workerSubMenu);
}
workerSubMenu.RunWorkerAsync(rowData); ;
}
@ -129,6 +131,7 @@ namespace SystemTrayMenu.Business
menu.SetTypeNoAccess();
break;
}
menu.Tag = menuData.RowDataParent;
menuData.RowDataParent.SubMenu = menu;
if (menus[0].IsUsable)
@ -191,11 +194,11 @@ namespace SystemTrayMenu.Business
waitToOpenMenu.MouseActive = byClick;
if (byClick && (DateTime.Now - deactivatedTime).TotalMilliseconds < 200)
{
//By click on notifyicon the menu gets deactivated and closed
// By click on notifyicon the menu gets deactivated and closed
}
else if (string.IsNullOrEmpty(Config.Path))
{
//Case when Folder Dialog open
// Case when Folder Dialog open
}
else if (openCloseState == OpenCloseState.Opening ||
menus[0].Visible && openCloseState == OpenCloseState.Default)
@ -213,6 +216,7 @@ namespace SystemTrayMenu.Business
openCloseState = OpenCloseState.Opening;
StartWorker();
}
deactivatedTime = DateTime.MinValue;
}
@ -223,6 +227,7 @@ namespace SystemTrayMenu.Business
{
worker.Dispose();
}
waitToOpenMenu.Dispose();
keyboardInput.Dispose();
timerStillActiveCheck.Dispose();
@ -269,7 +274,7 @@ namespace SystemTrayMenu.Business
{
RowDatas = new List<RowData>(),
Validity = MenuDataValidity.AbortedOrUnknown,
Level = level
Level = level,
};
if (!worker.CancellationPending)
{
@ -277,7 +282,7 @@ namespace SystemTrayMenu.Business
try
{
if (LnkHelper.IsNetworkRoot(path))
if (FileLnk.IsNetworkRoot(path))
{
directories = GetDirectoriesInNetworkLocation(path);
static string[] GetDirectoriesInNetworkLocation(string networkLocationRootPath)
@ -314,6 +319,7 @@ namespace SystemTrayMenu.Business
{
directories = Directory.GetDirectories(path);
}
Array.Sort(directories, new WindowsExplorerSort());
}
catch (UnauthorizedAccessException ex)
@ -355,14 +361,11 @@ namespace SystemTrayMenu.Business
try
{
if (LnkHelper.IsNetworkRoot(path))
{
//UNC root can not have files
}
else
if (!FileLnk.IsNetworkRoot(path))
{
files = Directory.GetFiles(path);
}
Array.Sort(files, new WindowsExplorerSort());
}
catch (UnauthorizedAccessException ex)
@ -421,10 +424,10 @@ namespace SystemTrayMenu.Business
internal void MainPreload()
{
menus[0] = Create(GetData(workerMainMenu, Config.Path, 0),
menus[0] = Create(
GetData(workerMainMenu, Config.Path, 0),
Path.GetFileName(Config.Path));
menus[0].AdjustSizeAndLocation(screenHeight,
screenRight, taskbarHeight);
menus[0].AdjustSizeAndLocation(screenHeight, screenRight, taskbarHeight);
DisposeMenu(menus[0]);
}
@ -446,13 +449,13 @@ namespace SystemTrayMenu.Business
}
}
private static RowData ReadRowData(string fileName,
bool isResolvedLnk, RowData rowData = null)
private static RowData ReadRowData(string fileName, bool isResolvedLnk, RowData rowData = null)
{
if (rowData == null)
{
rowData = new RowData();
}
rowData.IsResolvedLnk = isResolvedLnk;
try
@ -471,6 +474,7 @@ namespace SystemTrayMenu.Business
{
rowData.SetText(rowData.FileInfo.Name);
}
rowData.TargetFilePathOrig = rowData.FileInfo.FullName;
}
}
@ -556,8 +560,10 @@ namespace SystemTrayMenu.Business
{
rowData.SetData(rowData, dataTable);
}
dgv.DataSource = dataTable;
}
DataGridView dgv = menu.GetDataGridView();
dgv.CellMouseEnter += waitToOpenMenu.MouseEnter;
waitToOpenMenu.MouseEnterOk += Dgv_CellMouseEnter;
@ -574,6 +580,7 @@ namespace SystemTrayMenu.Business
keyboardInput.Select(dgv, rowIndex, false);
}
}
dgv.CellMouseLeave += waitToOpenMenu.MouseLeave;
dgv.MouseMove += waitToOpenMenu.MouseMove;
dgv.MouseDown += Dgv_MouseDown;
@ -591,10 +598,12 @@ namespace SystemTrayMenu.Business
{
AdjustMenusSizeAndLocation();
}
if (!menu.Visible)
{
DisposeMenu(menu);
}
if (!AsEnumerable.Any(m => m.Visible))
{
openCloseState = OpenCloseState.Default;
@ -641,7 +650,7 @@ namespace SystemTrayMenu.Business
if (rowData == null)
{
//Case when filtering a previous menu
// Case when filtering a previous menu
}
else if (!menus[0].IsUsable)
{
@ -667,6 +676,7 @@ namespace SystemTrayMenu.Business
row.Selected = false;
}
}
dgv.Refresh();
}
@ -679,24 +689,17 @@ namespace SystemTrayMenu.Business
{
RowData rowData = (RowData)row.Cells[2].Value;
Rectangle rowBounds = new Rectangle(
0, e.RowBounds.Top,
dgv.Columns[0].Width +
dgv.Columns[1].Width,
e.RowBounds.Height);
int width = dgv.Columns[0].Width + dgv.Columns[1].Width;
Rectangle rowBounds = new Rectangle(0, e.RowBounds.Top, width, e.RowBounds.Height);
if (rowData.IsMenuOpen && rowData.IsSelected)
{
ControlPaint.DrawBorder(e.Graphics, rowBounds,
MenuDefines.ColorSelectedItemBorder,
ButtonBorderStyle.Solid);
ControlPaint.DrawBorder(e.Graphics, rowBounds, MenuDefines.ColorSelectedItemBorder, ButtonBorderStyle.Solid);
row.DefaultCellStyle.SelectionBackColor = MenuDefines.ColorSelectedItem;
}
else if (rowData.IsMenuOpen)
{
ControlPaint.DrawBorder(e.Graphics, rowBounds,
MenuDefines.ColorOpenFolderBorder,
ButtonBorderStyle.Solid);
ControlPaint.DrawBorder(e.Graphics, rowBounds, MenuDefines.ColorOpenFolderBorder, ButtonBorderStyle.Solid);
row.DefaultCellStyle.SelectionBackColor = MenuDefines.ColorOpenFolder;
}
}
@ -713,7 +716,7 @@ namespace SystemTrayMenu.Business
private void HideOldMenu(Menu menuToShow, bool keepOrSetIsMenuOpen = false)
{
//Clean up menu status IsMenuOpen for previous one
// Clean up menu status IsMenuOpen for previous one
Menu menuPrevious = menus[menuToShow.Level - 1];
DataGridView dgvPrevious = menuPrevious.GetDataGridView();
foreach (DataRow row in ((DataTable)dgvPrevious.DataSource).Rows)
@ -728,9 +731,10 @@ namespace SystemTrayMenu.Business
rowDataToClear.IsMenuOpen = false;
}
}
RefreshSelection(dgvPrevious);
//Hide old menu
// Hide old menu
foreach (Menu menuToClose in menus.Where(
m => m != null && m.Level > menuPrevious.Level))
{
@ -740,11 +744,11 @@ namespace SystemTrayMenu.Business
}
}
internal void FadeHalfOrOutIfNeeded()
private void FadeHalfOrOutIfNeeded()
{
if (menus[0].IsUsable)
{
if (!(IsActive()))
if (!IsActive())
{
Point position = Control.MousePosition;
if (AsList.Any(m => m.IsMouseOn(position)))
@ -777,6 +781,7 @@ namespace SystemTrayMenu.Business
{
menus[menu.Level] = null;
}
menu.HideWithFade();
});
}
@ -787,13 +792,11 @@ namespace SystemTrayMenu.Business
int widthPredecessors = -1; // -1 padding
bool directionToRight = false;
menus[0].AdjustSizeAndLocation(screenHeight,
screenRight, taskbarHeight);
menus[0].AdjustSizeAndLocation(screenHeight, screenRight, taskbarHeight);
foreach (Menu menu in AsEnumerable.Where(m => m.Level > 0))
{
int newWith = (menu.Width -
menu.Padding.Horizontal + menuPredecessor.Width);
int newWith = menu.Width - menu.Padding.Horizontal + menuPredecessor.Width;
if (directionToRight)
{
if (widthPredecessors - menus[0].Width - menu.Width < 0)
@ -811,8 +814,7 @@ namespace SystemTrayMenu.Business
widthPredecessors -= newWith;
}
menu.AdjustSizeAndLocation(screenHeight, screenRight, taskbarHeight,
menuPredecessor, directionToRight);
menu.AdjustSizeAndLocation(screenHeight, screenRight, taskbarHeight, menuPredecessor, directionToRight);
widthPredecessors += menu.Width - menu.Padding.Left;
menuPredecessor = menu;
}

View file

@ -1,11 +1,15 @@
using System;
using System.Reflection;
using System.Threading;
using System.Windows.Forms;
using SystemTrayMenu.Utilities;
// <copyright file="Program.cs" company="PlaceholderCompany">
// Copyright (c) PlaceholderCompany. All rights reserved.
// </copyright>
namespace SystemTrayMenu
{
using System;
using System.Reflection;
using System.Threading;
using System.Windows.Forms;
using SystemTrayMenu.Utilities;
internal static class Program
{
[STAThread]
@ -53,9 +57,12 @@ namespace SystemTrayMenu
{
Log.Error("Application Crashed", ex);
if (MessageBox.Show("A problem has been encountered and the application needs to restart. " +
"Reporting this error will help us make our product better. Press yes to open your standard email app.",
"SystemTrayMenu BugSplat", MessageBoxButtons.YesNo) == DialogResult.Yes)
if (MessageBox.Show(
"A problem has been encountered and the application needs to restart. " +
"Reporting this error will help us make our product better. " +
"Press yes to open your standard email app.",
"SystemTrayMenu BugSplat",
MessageBoxButtons.YesNo) == DialogResult.Yes)
{
Log.ProcessStart("mailto:" + "markus@hofknecht.eu" +
"?subject=SystemTrayMenu Bug reported " +

View file

@ -1,9 +1,12 @@
using System;
using SystemTrayMenu.Utilities;
using Timer = System.Windows.Forms.Timer;
// <copyright file="WaitLeave.cs" company="PlaceholderCompany">
// Copyright (c) PlaceholderCompany. All rights reserved.
// </copyright>
namespace SystemTrayMenu.Handler
{
using System;
using SystemTrayMenu.Utilities;
using Timer = System.Windows.Forms.Timer;
internal class WaitLeave : IDisposable
{
public event EventHandlerEmpty LeaveTriggered;

View file

@ -1,18 +1,23 @@
using System;
using System.Windows.Forms;
using SystemTrayMenu.DataClasses;
using SystemTrayMenu.UserInterface;
using SystemTrayMenu.Utilities;
using Timer = System.Windows.Forms.Timer;
// <copyright file="WaitToLoadMenu.cs" company="PlaceholderCompany">
// Copyright (c) PlaceholderCompany. All rights reserved.
// </copyright>
namespace SystemTrayMenu.Handler
{
using System;
using System.Windows.Forms;
using SystemTrayMenu.DataClasses;
using SystemTrayMenu.UserInterface;
using SystemTrayMenu.Utilities;
using Timer = System.Windows.Forms.Timer;
internal class WaitToLoadMenu : IDisposable
{
internal event Action<RowData> StartLoadMenu;
internal event Action<int> CloseMenu;
internal event EventHandlerEmpty StopLoadMenu;
internal event Action<DataGridView, int> MouseEnterOk;
internal bool MouseActive = false;
private readonly Timer timerStartLoad = new Timer();
private DataGridView dgv = null;
@ -20,7 +25,6 @@ namespace SystemTrayMenu.Handler
private DataGridView dgvTmp = null;
private int rowIndexTmp = 0;
internal bool MouseActive = false;
private int mouseMoveEvents = 0;
private DateTime dateTimeLastMouseMoveEvent = DateTime.Now;
private bool checkForMouseActive = true;
@ -70,7 +74,7 @@ namespace SystemTrayMenu.Handler
}
}
internal void RowDeselected(int rowIndex, DataGridView dgv) //iMenuBefore not needed
internal void RowDeselected(int rowIndex, DataGridView dgv)
{
timerStartLoad.Stop();
StopLoadMenu?.Invoke();
@ -113,6 +117,7 @@ namespace SystemTrayMenu.Handler
MouseEnter(dgvTmp, new DataGridViewCellEventArgs(
0, rowIndexTmp));
}
mouseMoveEvents = 0;
}
else if (DateTime.Now - dateTimeLastMouseMoveEvent <

View file

@ -1,12 +1,16 @@
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Windows.Forms;
using SystemTrayMenu.UserInterface.Dialogs;
using SystemTrayMenu.Utilities;
// <copyright file="Config.cs" company="PlaceholderCompany">
// Copyright (c) PlaceholderCompany. All rights reserved.
// </copyright>
namespace SystemTrayMenu
{
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Windows.Forms;
using SystemTrayMenu.UserInterface.Dialogs;
using SystemTrayMenu.Utilities;
public static class Config
{
public const string Language = "en";
@ -38,11 +42,14 @@ namespace SystemTrayMenu
if (!pathOK)
{
string textFirstStart = Translator.GetText("TextFirstStart");
MessageBox.Show(textFirstStart, Translator.GetText("SystemTrayMenu"),
MessageBox.Show(
textFirstStart,
Translator.GetText("SystemTrayMenu"),
MessageBoxButtons.OK);
ShowHelpFAQ();
pathOK = SetFolderByUser();
}
return pathOK;
}
@ -75,7 +82,7 @@ namespace SystemTrayMenu
}
}
while (!pathOK && !userAborted);
};
}
return pathOK;
}

View file

@ -1,8 +1,11 @@
using System.Drawing;
using System.Reflection;
// <copyright file="MenuDefines.cs" company="PlaceholderCompany">
// Copyright (c) PlaceholderCompany. All rights reserved.
// </copyright>
namespace SystemTrayMenu
{
using System.Drawing;
using System.Reflection;
internal static class MenuDefines
{
internal static string NotifyIconText = Assembly.GetExecutingAssembly().GetCustomAttribute<AssemblyTitleAttribute>().Title;

View file

@ -1,13 +1,17 @@
using System.Collections.Generic;
// <copyright file="MenuData.cs" company="PlaceholderCompany">
// Copyright (c) PlaceholderCompany. All rights reserved.
// </copyright>
namespace SystemTrayMenu.DataClasses
{
using System.Collections.Generic;
internal enum MenuDataValidity
{
AbortedOrUnknown,
Valid,
Empty,
NoAccess
NoAccess,
}
internal struct MenuData
@ -16,5 +20,5 @@ namespace SystemTrayMenu.DataClasses
internal MenuDataValidity Validity;
internal int Level;
internal RowData RowDataParent;
};
}
}

View file

@ -1,21 +1,25 @@
using IWshRuntimeLibrary;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Security;
using System.Text;
using System.Windows.Forms;
using SystemTrayMenu.Utilities;
using TAFactory.IconPack;
using Menu = SystemTrayMenu.UserInterface.Menu;
// <copyright file="RowData.cs" company="PlaceholderCompany">
// Copyright (c) PlaceholderCompany. All rights reserved.
// </copyright>
namespace SystemTrayMenu.DataClasses
{
using IWshRuntimeLibrary;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Security;
using System.Text;
using System.Windows.Forms;
using SystemTrayMenu.Utilities;
using TAFactory.IconPack;
using Menu = SystemTrayMenu.UserInterface.Menu;
internal class RowData : IDisposable
{
internal FileInfo FileInfo;
@ -24,19 +28,19 @@ namespace SystemTrayMenu.DataClasses
internal bool IsSelected;
internal bool ContainsMenu;
internal bool IsContextMenuOpen;
private static DateTime ContextMenuClosed;
internal bool IsResolvedLnk;
internal bool HiddenEntry;
internal string TargetFilePath;
internal string TargetFilePathOrig;
internal int RowIndex;
internal int MenuLevel;
private static DateTime ContextMenuClosed;
private string WorkingDirectory;
private string Arguments;
private string Text;
private Icon Icon = null;
private bool diposeIcon = true;
private bool isDisposed = false;
internal int MenuLevel;
internal RowData()
{
@ -81,8 +85,10 @@ namespace SystemTrayMenu.DataClasses
}
else if (isDirectory)
{
Icon = IconReader.GetFolderIcon(TargetFilePath,
IconReader.FolderType.Closed, false);
Icon = IconReader.GetFolderIcon(
TargetFilePath,
IconReader.FolderType.Closed,
false);
}
else
{
@ -111,14 +117,14 @@ namespace SystemTrayMenu.DataClasses
diposeIcon = false;
// other project -> fails sometimes
//icon = IconHelper.ExtractIcon(TargetFilePath, 0);
// icon = IconHelper.ExtractIcon(TargetFilePath, 0);
// standard way -> fails sometimes
//icon = Icon.ExtractAssociatedIcon(filePath);
// icon = Icon.ExtractAssociatedIcon(filePath);
// API Code Pack -> fails sometimes
//ShellFile shellFile = ShellFile.FromFilePath(filePath);
//Bitmap shellThumb = shellFile.Thumbnail.ExtraLargeBitmap;
// ShellFile shellFile = ShellFile.FromFilePath(filePath);
// Bitmap shellThumb = shellFile.Thumbnail.ExtraLargeBitmap;
}
catch (Exception ex)
{
@ -141,20 +147,115 @@ namespace SystemTrayMenu.DataClasses
return isLnkDirectory;
}
internal void MouseDown(DataGridView dgv, MouseEventArgs e)
{
if (e != null &&
e.Button == MouseButtons.Right &&
FileInfo != null &&
dgv != null &&
dgv.Rows.Count > RowIndex &&
(DateTime.Now - ContextMenuClosed).TotalMilliseconds > 200)
{
IsContextMenuOpen = true;
Color colorbefore = dgv.Rows[RowIndex].DefaultCellStyle.SelectionBackColor;
dgv.Rows[RowIndex].DefaultCellStyle.SelectionBackColor =
MenuDefines.ColorSelectedItem;
ShellContextMenu ctxMnu = new ShellContextMenu();
Point location = dgv.FindForm().Location;
Point point = new Point(
e.X + location.X + dgv.Location.X,
e.Y + location.Y + dgv.Location.Y);
if (ContainsMenu)
{
DirectoryInfo[] dir = new DirectoryInfo[1];
dir[0] = new DirectoryInfo(TargetFilePathOrig);
ctxMnu.ShowContextMenu(dir, point);
}
else
{
FileInfo[] arrFI = new FileInfo[1];
arrFI[0] = new FileInfo(TargetFilePathOrig);
ctxMnu.ShowContextMenu(arrFI, point);
}
if (!dgv.IsDisposed)
{
dgv.Rows[RowIndex].DefaultCellStyle.SelectionBackColor = colorbefore;
}
IsContextMenuOpen = false;
ContextMenuClosed = DateTime.Now;
}
}
internal void DoubleClick(MouseEventArgs e)
{
if (e == null ||
e.Button == MouseButtons.Left &&
!ContainsMenu)
{
try
{
using Process p = new Process
{
StartInfo = new ProcessStartInfo(TargetFilePath)
{
FileName = TargetFilePathOrig,
Arguments = Arguments,
WorkingDirectory = WorkingDirectory,
CreateNoWindow = true,
UseShellExecute = true,
}
};
p.Start();
}
catch (Win32Exception ex)
{
Log.Warn($"path:'{TargetFilePath}'", ex);
MessageBox.Show(ex.Message);
}
}
if (e == null ||
e.Button == MouseButtons.Left &&
ContainsMenu)
{
Log.ProcessStart("explorer.exe", TargetFilePath);
}
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (!isDisposed)
{
if (diposeIcon)
{
Icon?.Dispose();
}
}
isDisposed = true;
}
private bool SetLnk(ref bool isLnkDirectory,
ref string resolvedLnkPath)
{
bool handled = false;
resolvedLnkPath = LnkHelper.GetResolvedFileName(TargetFilePath);
if (LnkHelper.IsDirectory(resolvedLnkPath))
resolvedLnkPath = FileLnk.GetResolvedFileName(TargetFilePath);
if (FileLnk.IsDirectory(resolvedLnkPath))
{
Icon = IconReader.GetFolderIcon(TargetFilePath,
IconReader.FolderType.Open, true);
Icon = IconReader.GetFolderIcon(TargetFilePath, IconReader.FolderType.Open, true);
handled = true;
isLnkDirectory = true;
}
else if (LnkHelper.IsNetworkRoot(resolvedLnkPath))
else if (FileLnk.IsNetworkRoot(resolvedLnkPath))
{
isLnkDirectory = true;
}
@ -283,101 +384,5 @@ namespace SystemTrayMenu.DataClasses
return handled;
}
internal void MouseDown(DataGridView dgv, MouseEventArgs e)
{
if (e != null &&
e.Button == MouseButtons.Right &&
FileInfo != null &&
dgv != null &&
dgv.Rows.Count > RowIndex &&
(DateTime.Now - ContextMenuClosed).TotalMilliseconds > 200)
{
IsContextMenuOpen = true;
Color colorbefore = dgv.Rows[RowIndex].DefaultCellStyle.SelectionBackColor;
dgv.Rows[RowIndex].DefaultCellStyle.SelectionBackColor =
MenuDefines.ColorSelectedItem;
ShellContextMenu ctxMnu = new ShellContextMenu();
Point location = dgv.FindForm().Location;
Point point = new Point(
e.X + location.X + dgv.Location.X,
e.Y + location.Y + dgv.Location.Y);
if (ContainsMenu)
{
DirectoryInfo[] dir = new DirectoryInfo[1];
dir[0] = new DirectoryInfo(TargetFilePathOrig);
ctxMnu.ShowContextMenu(dir, point);
}
else
{
FileInfo[] arrFI = new FileInfo[1];
arrFI[0] = new FileInfo(TargetFilePathOrig);
ctxMnu.ShowContextMenu(arrFI, point);
}
if (!dgv.IsDisposed)
{
dgv.Rows[RowIndex].DefaultCellStyle.SelectionBackColor = colorbefore;
}
IsContextMenuOpen = false;
ContextMenuClosed = DateTime.Now;
}
}
internal void DoubleClick(MouseEventArgs e)
{
if (e == null ||
e.Button == MouseButtons.Left &&
!ContainsMenu)
{
try
{
using (Process p = new Process())
{
p.StartInfo = new ProcessStartInfo(TargetFilePath)
{
FileName = TargetFilePathOrig,
Arguments = Arguments,
WorkingDirectory = WorkingDirectory,
CreateNoWindow = true,
UseShellExecute = true
};
p.Start();
};
}
catch (Win32Exception ex)
{
Log.Warn($"path:'{TargetFilePath}'", ex);
MessageBox.Show(ex.Message);
}
}
if (e == null ||
e.Button == MouseButtons.Left &&
ContainsMenu)
{
Log.ProcessStart("explorer.exe", TargetFilePath);
}
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (!isDisposed)
{
if (diposeIcon)
{
Icon?.Dispose();
}
}
isDisposed = true;
}
}
}

10
GlobalSuppressions.cs Normal file
View file

@ -0,0 +1,10 @@
// This file is used by Code Analysis to maintain SuppressMessage
// attributes that are applied to this project.
// Project-level suppressions either have no target or are given
// a specific target and scoped to a namespace, type, member, etc.
using System.Diagnostics.CodeAnalysis;
[assembly: SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1600:Elements should be documented", Justification = "TODO")]
[assembly: SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1101:Prefix local calls with this", Justification = "Standard codecleanup removes the this")]

View file

@ -1,26 +1,34 @@
using System;
using System.Windows.Forms;
using SystemTrayMenu.Utilities;
// <copyright file="Fading.cs" company="PlaceholderCompany">
// Copyright (c) PlaceholderCompany. All rights reserved.
// </copyright>
namespace SystemTrayMenu.UserInterface
{
using System;
using System.Windows.Forms;
using SystemTrayMenu.Utilities;
public class Fading : IDisposable
{
internal event EventHandlerEmpty Hide;
internal event EventHandlerEmpty Show;
internal event EventHandler<double> ChangeOpacity;
internal enum FadingState { Idle, Show, ShowTransparent, Hide };
internal enum FadingState { Idle, Show, ShowTransparent, Hide }
internal bool IsHiding => state == FadingState.Hide;
private const int Interval60FPS = 16; //60fps=>1s/60fps=~16.6ms
private const int Interval60FPS = 16; // 60fps=>1s/60fps=~16.6ms
private const double StepIn = 0.20;
private const double StepOut = 0.10;
private const double Transparent = 0.80;
private const double TransparentMinus = 0.60; //Transparent - StepIn
private const double TransparentPlus = 0.85; //Transparent + StepOut
private const double TransparentMinus = 0.60; // Transparent - StepIn
private const double TransparentPlus = 0.85; // Transparent + StepOut
private const double Shown = 1.00;
private const double ShownMinus = 0.80; //Shown - StepIn
private const double ShownMinus = 0.80; // Shown - StepIn
private readonly Timer timer = new Timer();
private FadingState state = FadingState.Idle;
@ -80,6 +88,7 @@ namespace SystemTrayMenu.UserInterface
ChangeOpacity?.Invoke(this, Shown);
StartStopTimer(FadingState.Idle);
}
break;
case FadingState.ShowTransparent:
if (!visible)
@ -104,6 +113,7 @@ namespace SystemTrayMenu.UserInterface
ChangeOpacity?.Invoke(this, Transparent);
StartStopTimer(FadingState.Idle);
}
break;
case FadingState.Hide:
if (opacity > StepOut)
@ -119,6 +129,7 @@ namespace SystemTrayMenu.UserInterface
Hide?.Invoke();
StartStopTimer(FadingState.Idle);
}
break;
case FadingState.Idle:
default:

View file

@ -1,10 +1,14 @@
using System;
using System.Windows.Forms;
using SystemTrayMenu.UserInterface.Controls;
using SystemTrayMenu.Utilities;
// <copyright file="KeyboardHook.cs" company="PlaceholderCompany">
// Copyright (c) PlaceholderCompany. All rights reserved.
// </copyright>
namespace SystemTrayMenu.Helper
{
using System;
using System.Windows.Forms;
using SystemTrayMenu.UserInterface.Controls;
using SystemTrayMenu.Utilities;
public sealed class KeyboardHook : IDisposable
{
/// <summary>
@ -23,7 +27,7 @@ namespace SystemTrayMenu.Helper
/// <summary>
/// Overridden to get the notifications.
/// </summary>
/// <param name="m"></param>
/// <param name="m">m.</param>
protected override void WndProc(ref Message m)
{
base.WndProc(ref m);
@ -42,14 +46,10 @@ namespace SystemTrayMenu.Helper
public event EventHandler<KeyPressedEventArgs> KeyPressed;
#region IDisposable Members
public void Dispose()
{
DestroyHandle();
}
#endregion
}
private readonly Window _window = new Window();
@ -84,15 +84,18 @@ namespace SystemTrayMenu.Helper
{
modifiers |= KeyboardHookModifierKeys.Alt;
}
if (modifiersString.ToUpperInvariant().Contains("CTRL", StringComparison.InvariantCulture) ||
modifiersString.ToUpperInvariant().Contains("STRG", StringComparison.InvariantCulture))
{
modifiers |= KeyboardHookModifierKeys.Control;
}
if (modifiersString.ToUpperInvariant().Contains("SHIFT", StringComparison.InvariantCulture))
{
modifiers |= KeyboardHookModifierKeys.Shift;
}
if (modifiersString.ToUpperInvariant().Contains("WIN", StringComparison.InvariantCulture))
{
modifiers |= KeyboardHookModifierKeys.Win;
@ -109,7 +112,6 @@ namespace SystemTrayMenu.Helper
/// </summary>
/// <param name="modifier">The modifiers that are associated with the hot key.</param>
/// <param name="key">The key itself that is associated with the hot key.</param>
//internal void RegisterHotKey(KeyboardHookModifierKeys modifier, Keys key)
internal void RegisterHotKey(KeyboardHookModifierKeys modifier, Keys key)
{
RegisterHotKey((uint)modifier, key);
@ -132,8 +134,6 @@ namespace SystemTrayMenu.Helper
/// </summary>
internal event EventHandler<KeyPressedEventArgs> KeyPressed;
#region IDisposable Members
public void Dispose()
{
// unregister all the registered hot keys.
@ -145,8 +145,6 @@ namespace SystemTrayMenu.Helper
// dispose the inner native window.
_window.Dispose();
}
#endregion
}
/// <summary>
@ -178,6 +176,6 @@ namespace SystemTrayMenu.Helper
Alt = 1,
Control = 2,
Shift = 4,
Win = 8
Win = 8,
}
}

View file

@ -1,7 +1,10 @@
using System.Collections.Generic;
// <copyright file="WindowsExplorerSort.cs" company="PlaceholderCompany">
// Copyright (c) PlaceholderCompany. All rights reserved.
// </copyright>
namespace SystemTrayMenu.Helper
{
using System.Collections.Generic;
internal class WindowsExplorerSort : IComparer<string>
{
public int Compare(string x, string y)

View file

@ -1,11 +1,13 @@
using System;
using System.Drawing;
using System.Runtime.InteropServices;
using static SystemTrayMenu.DllImports.NativeMethods;
// <copyright file="WindowsTaskbar.cs" company="PlaceholderCompany">
// Copyright (c) PlaceholderCompany. All rights reserved.
// </copyright>
//Microsoft.WindowsAPICodePack.Taskbar.TaskbarManager do not have the bounds implemented?
namespace SystemTrayMenu.Helper
{
using System;
using System.Drawing;
using System.Runtime.InteropServices;
using static SystemTrayMenu.DllImports.NativeMethods;
public enum TaskbarPosition
{
Unknown = -1,
@ -24,19 +26,23 @@ namespace SystemTrayMenu.Helper
get;
private set;
}
public TaskbarPosition Position
{
get;
private set;
}
public Point Location => Bounds.Location;
public Size Size => Bounds.Size;
//Always returns false under Windows 7
public bool AlwaysOnTop
{
get;
private set;
}
public bool AutoHide
{
get;
@ -50,12 +56,11 @@ namespace SystemTrayMenu.Helper
APPBARDATA data = new APPBARDATA
{
cbSize = (uint)Marshal.SizeOf(typeof(APPBARDATA)),
hWnd = taskbarHandle
hWnd = taskbarHandle,
};
IntPtr result = Shell32SHAppBarMessage(ABM.GetTaskbarPos, ref data);
if (result == IntPtr.Zero)
{
//throw new InvalidOperationException();
Bounds = new Rectangle(20, 20, 20, 20);
}
else

View file

@ -1,8 +1,14 @@
using System;
using System.Runtime.InteropServices;
// <copyright file="BringWindowToTop.cs" company="PlaceholderCompany">
// Copyright (c) PlaceholderCompany. All rights reserved.
// </copyright>
namespace SystemTrayMenu.DllImports
{
using System;
using System.Runtime.InteropServices;
/// <summary>
/// wraps the methodcalls to native windows dll's.
/// </summary>
public static partial class NativeMethods
{
[DllImport("user32.dll")]

View file

@ -1,8 +1,14 @@
using System;
using System.Runtime.InteropServices;
// <copyright file="CreatePopupMenu.cs" company="PlaceholderCompany">
// Copyright (c) PlaceholderCompany. All rights reserved.
// </copyright>
namespace SystemTrayMenu.DllImports
{
using System;
using System.Runtime.InteropServices;
/// <summary>
/// wraps the methodcalls to native windows dll's.
/// </summary>
public static partial class NativeMethods
{
// The CreatePopupMenu function creates a drop-down menu, submenu, or shortcut menu. The menu is initially empty. You can insert or append menu items by using the InsertMenuItem function. You can also use the InsertMenu function to insert menu items and the AppendMenu function to append menu items.

View file

@ -1,8 +1,14 @@
using System;
using System.Runtime.InteropServices;
// <copyright file="DestroyIcon.cs" company="PlaceholderCompany">
// Copyright (c) PlaceholderCompany. All rights reserved.
// </copyright>
namespace SystemTrayMenu.DllImports
{
using System;
using System.Runtime.InteropServices;
/// <summary>
/// wraps the methodcalls to native windows dll's.
/// </summary>
public static partial class NativeMethods
{
[DllImport("User32.dll")]

View file

@ -1,8 +1,15 @@
using System;
using System.Runtime.InteropServices;
// <copyright file="DestroyMenu.cs" company="PlaceholderCompany">
// Copyright (c) PlaceholderCompany. All rights reserved.
// </copyright>
namespace SystemTrayMenu.DllImports
{
using System;
using System.Runtime.InteropServices;
/// <summary>
/// wraps the methodcalls to native windows dll's.
/// </summary>
public static partial class NativeMethods
{
// The DestroyMenu function destroys the specified menu and frees any memory that the menu occupies.

View file

@ -1,8 +1,15 @@
using System.Runtime.InteropServices;
using System.Text;
// <copyright file="FindExecuteable.cs" company="PlaceholderCompany">
// Copyright (c) PlaceholderCompany. All rights reserved.
// </copyright>
namespace SystemTrayMenu.DllImports
{
using System.Runtime.InteropServices;
using System.Text;
/// <summary>
/// wraps the methodcalls to native windows dll's.
/// </summary>
public static partial class NativeMethods
{
[DllImport("shell32.dll", CharSet = CharSet.Unicode)]

View file

@ -1,16 +1,24 @@
using System;
using System.Runtime.InteropServices;
// <copyright file="FindWindow.cs" company="PlaceholderCompany">
// Copyright (c) PlaceholderCompany. All rights reserved.
// </copyright>
namespace SystemTrayMenu.DllImports
{
using System;
using System.Runtime.InteropServices;
/// <summary>
/// wraps the methodcalls to native windows dll's.
/// </summary>
public static partial class NativeMethods
{
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1600:Elements should be documented", Justification = "<Pending>")]
public static IntPtr User32FindWindow(string lpClassName, string lpWindowName)
{
return FindWindow(lpClassName, lpWindowName);
}
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
}
}

View file

@ -1,8 +1,15 @@
using System;
using System.Runtime.InteropServices;
// <copyright file="GetDeviceCaps.cs" company="PlaceholderCompany">
// Copyright (c) PlaceholderCompany. All rights reserved.
// </copyright>
namespace SystemTrayMenu.DllImports
{
using System;
using System.Runtime.InteropServices;
/// <summary>
/// wraps the methodcalls to native windows dll's.
/// </summary>
public static partial class NativeMethods
{
[DllImport("gdi32.dll")]

View file

@ -1,89 +1,49 @@
using System;
using System.Runtime.InteropServices;
// <copyright file="GetIcon.cs" company="PlaceholderCompany">
// Copyright (c) PlaceholderCompany. All rights reserved.
// </copyright>
namespace SystemTrayMenu.DllImports
{
using System;
using System.Runtime.InteropServices;
/// <summary>
/// wraps the methodcalls to native windows dll's.
/// </summary>
public static partial class NativeMethods
{
//[StructLayout(LayoutKind.Sequential)]
//[System.Diagnostics.CodeAnalysis.SuppressMessage("Performance", "CA1815:Override equals and operator equals on value types", Justification = "<Pending>")]
//internal struct SHITEMID
//{
// public ushort cb;
// [MarshalAs(UnmanagedType.LPArray)]
// public byte[] abID;
//}
//[StructLayout(LayoutKind.Sequential)]
//[System.Diagnostics.CodeAnalysis.SuppressMessage("Performance", "CA1815:Override equals and operator equals on value types", Justification = "<Pending>")]
//internal struct ITEMIDLIST
//{
// public SHITEMID mkid;
//}
//[StructLayout(LayoutKind.Sequential)]
//[System.Diagnostics.CodeAnalysis.SuppressMessage("Performance", "CA1815:Override equals and operator equals on value types", Justification = "<Pending>")]
//internal struct BROWSEINFO
//{
// public IntPtr hwndOwner;
// public IntPtr pidlRoot;
// public IntPtr pszDisplayName;
// [MarshalAs(UnmanagedType.LPTStr)]
// public string lpszTitle;
// public uint ulFlags;
// public IntPtr lpfn;
// public int lParam;
// public IntPtr iImage;
//}
// Browsing for directory.
//public const uint BIF_RETURNONLYFSDIRS = 0x0001;
//public const uint BIF_DONTGOBELOWDOMAIN = 0x0002;
//public const uint BIF_STATUSTEXT = 0x0004;
//public const uint BIF_RETURNFSANCESTORS = 0x0008;
//public const uint BIF_EDITBOX = 0x0010;
//public const uint BIF_VALIDATE = 0x0020;
//public const uint BIF_NEWDIALOGSTYLE = 0x0040;
//public const uint BIF_USENEWUI = (BIF_NEWDIALOGSTYLE | BIF_EDITBOX);
//public const uint BIF_BROWSEINCLUDEURLS = 0x0080;
//public const uint BIF_BROWSEFORCOMPUTER = 0x1000;
//public const uint BIF_BROWSEFORPRINTER = 0x2000;
//public const uint BIF_BROWSEINCLUDEFILES = 0x4000;
//public const uint BIF_SHAREABLE = 0x8000;
#pragma warning disable SA1600 // Elements should be documented
public const uint ShgfiIcon = 0x000000100; // get icon
//public const uint SHGFI_DISPLAYNAME = 0x000000200; // get display name
//public const uint SHGFI_TYPENAME = 0x000000400; // get type name
//public const uint SHGFI_ATTRIBUTES = 0x000000800; // get attributes
//public const uint SHGFI_ICONLOCATION = 0x000001000; // get icon location
//public const uint SHGFI_EXETYPE = 0x000002000; // return exe type
public const uint ShgfiSYSICONINDEX = 0x000004000; // get system icon index
public const uint ShgfiLINKOVERLAY = 0x000008000; // put a link overlay on icon
//public const uint SHGFI_SELECTED = 0x000010000; // show icon in selected state
//public const uint SHGFI_ATTR_SPECIFIED = 0x000020000; // get only specified attributes
public const uint ShgfiLARGEICON = 0x000000000; // get large icon
public const uint ShgfiSMALLICON = 0x000000001; // get small icon
public const uint ShgfiOPENICON = 0x000000002; // get open icon
//public const uint SHGFI_SHELLICONSIZE = 0x000000004; // get shell size icon
//public const uint SHGFI_PIDL = 0x000000008; // pszPath is a pidl
//public const uint SHGFI_USEFILEATTRIBUTES = 0x000000010; // use passed dwFileAttribute
//public const uint SHGFI_ADDOVERLAYS = 0x000000020; // apply the appropriate overlays
//public const uint SHGFI_OVERLAYINDEX = 0x000000040; // Get the index of the overlay
public const uint FileAttributeDirectory = 0x00000010;
public const uint FileAttributeNormal = 0x00000080;
public const int IldTransparent = 0x00000001;
#pragma warning restore SA1600 // Elements should be documented
/// <summary>
/// comctl32 ImageList_GetIcon(IntPtr hIcon).
/// </summary>
/// <param name="hIcon">hIcon.</param>
public static void Comctl32ImageListGetIcon(IntPtr hIcon)
{
_ = DestroyIcon(hIcon);
}
/// <summary>
/// comctl32 ImageList_GetIcon(IntPtr himl, int i, int flags).
/// </summary>
/// <param name="himl">himl.</param>
/// <param name="i">i.</param>
/// <param name="flags">flags.</param>
/// <returns>IntPtr.</returns>
[DllImport("comctl32")]
internal static extern IntPtr ImageList_GetIcon(
IntPtr himl,
int i,
int flags);
public static void Comctl32ImageListGetIcon(IntPtr hIcon)
{
_ = DestroyIcon(hIcon);
}
}
}

View file

@ -1,8 +1,15 @@
using System;
using System.Runtime.InteropServices;
// <copyright file="GetMenuDefaultItem.cs" company="PlaceholderCompany">
// Copyright (c) PlaceholderCompany. All rights reserved.
// </copyright>
namespace SystemTrayMenu.DllImports
{
using System;
using System.Runtime.InteropServices;
/// <summary>
/// wraps the methodcalls to native windows dll's.
/// </summary>
public static partial class NativeMethods
{
// Determines the default menu item on the specified menu

View file

@ -1,12 +1,16 @@
using System.Runtime.InteropServices;
// <copyright file="IsTouchEnabled.cs" company="PlaceholderCompany">
// Copyright (c) PlaceholderCompany. All rights reserved.
// </copyright>
namespace SystemTrayMenu.DllImports
{
using System.Runtime.InteropServices;
/// <summary>
/// wraps the methodcalls to native windows dll's.
/// </summary>
public static partial class NativeMethods
{
[DllImport("user32.dll")]
private static extern int GetSystemMetrics(int nIndex);
public static bool IsTouchEnabled()
{
const int MAXTOUCHES_INDEX = 95;
@ -14,5 +18,8 @@ namespace SystemTrayMenu.DllImports
return maxTouches > 0;
}
[DllImport("user32.dll")]
private static extern int GetSystemMetrics(int nIndex);
}
}

View file

@ -1,9 +1,16 @@
using System;
using System.Runtime.InteropServices;
using System.Text;
// <copyright file="RegisterHotKey.cs" company="PlaceholderCompany">
// Copyright (c) PlaceholderCompany. All rights reserved.
// </copyright>
namespace SystemTrayMenu.DllImports
{
using System;
using System.Runtime.InteropServices;
using System.Text;
/// <summary>
/// wraps the methodcalls to native windows dll's.
/// </summary>
public static partial class NativeMethods
{
[DllImport("user32.dll", SetLastError = true)]

View file

@ -1,18 +1,17 @@
using System;
using System.Runtime.InteropServices;
// <copyright file="SHAppBarMessage.cs" company="PlaceholderCompany">
// Copyright (c) PlaceholderCompany. All rights reserved.
// </copyright>
namespace SystemTrayMenu.DllImports
{
using System;
using System.Runtime.InteropServices;
/// <summary>
/// wraps the methodcalls to native windows dll's.
/// </summary>
public static partial class NativeMethods
{
[DllImport("shell32.dll", SetLastError = true)]
private static extern IntPtr SHAppBarMessage(ABM dwMessage, [In] ref APPBARDATA pData);
internal static IntPtr Shell32SHAppBarMessage(ABM dwMessage, [In] ref APPBARDATA pData)
{
return SHAppBarMessage(dwMessage, ref pData);
}
internal enum ABM : uint
{
New = 0x00000000,
@ -33,7 +32,7 @@ namespace SystemTrayMenu.DllImports
Left = 0,
Top = 1,
Right = 2,
Bottom = 3
Bottom = 3,
}
internal static class ABS
@ -61,5 +60,13 @@ namespace SystemTrayMenu.DllImports
public int right;
public int bottom;
}
internal static IntPtr Shell32SHAppBarMessage(ABM dwMessage, [In] ref APPBARDATA pData)
{
return SHAppBarMessage(dwMessage, ref pData);
}
[DllImport("shell32.dll", SetLastError = true)]
private static extern IntPtr SHAppBarMessage(ABM dwMessage, [In] ref APPBARDATA pData);
}
}

View file

@ -1,8 +1,15 @@
using System;
using System.Runtime.InteropServices;
// <copyright file="SHGetDesktopFolder.cs" company="PlaceholderCompany">
// Copyright (c) PlaceholderCompany. All rights reserved.
// </copyright>
namespace SystemTrayMenu.DllImports
{
using System;
using System.Runtime.InteropServices;
/// <summary>
/// wraps the methodcalls to native windows dll's.
/// </summary>
public static partial class NativeMethods
{
// Retrieves the IShellFolder interface for the desktop folder, which is the root of the Shell's namespace.

View file

@ -1,36 +1,19 @@
using System;
using System.Runtime.InteropServices;
// <copyright file="SHGetFileInfo.cs" company="PlaceholderCompany">
// Copyright (c) PlaceholderCompany. All rights reserved.
// </copyright>
namespace SystemTrayMenu.DllImports
{
using System;
using System.Runtime.InteropServices;
/// <summary>
/// wraps the methodcalls to native windows dll's.
/// </summary>
public static partial class NativeMethods
{
private const int maxPath = 256;
[DllImport("Shell32.dll", CharSet = CharSet.Unicode)]
private static extern IntPtr SHGetFileInfo(
string pszPath,
uint dwFileAttributes,
ref SHFILEINFO psfi,
uint cbFileInfo,
uint uFlags
);
internal static IntPtr Shell32SHGetFileInfo(
string pszPath,
uint dwFileAttributes,
ref SHFILEINFO psfi,
uint cbFileInfo,
uint uFlags
)
{
return SHGetFileInfo(pszPath,
dwFileAttributes,
ref psfi,
cbFileInfo,
uFlags);
}
[StructLayout(LayoutKind.Sequential)]
internal struct SHFILEINFO
{
@ -43,7 +26,28 @@ namespace SystemTrayMenu.DllImports
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = NAMESIZE)]
public string szTypeName;
}
internal static IntPtr Shell32SHGetFileInfo(
string pszPath,
uint dwFileAttributes,
ref SHFILEINFO psfi,
uint cbFileInfo,
uint uFlags)
{
return SHGetFileInfo(
pszPath,
dwFileAttributes,
ref psfi,
cbFileInfo,
uFlags);
}
[DllImport("Shell32.dll", CharSet = CharSet.Unicode)]
private static extern IntPtr SHGetFileInfo(
string pszPath,
uint dwFileAttributes,
ref SHFILEINFO psfi,
uint cbFileInfo,
uint uFlags);
}
}

View file

@ -1,9 +1,16 @@
using System;
using System.Runtime.InteropServices;
using System.Text;
// <copyright file="SHGetFolderPath.cs" company="PlaceholderCompany">
// Copyright (c) PlaceholderCompany. All rights reserved.
// </copyright>
namespace SystemTrayMenu.DllImports
{
using System;
using System.Runtime.InteropServices;
using System.Text;
/// <summary>
/// wraps the methodcalls to native windows dll's.
/// </summary>
public static partial class NativeMethods
{
[DllImport("shfolder.dll", CharSet = CharSet.Unicode)]

View file

@ -1,7 +1,13 @@
using System.Runtime.InteropServices;
// <copyright file="SetProcessDPIAware.cs" company="PlaceholderCompany">
// Copyright (c) PlaceholderCompany. All rights reserved.
// </copyright>
namespace SystemTrayMenu.DllImports
{
using System.Runtime.InteropServices;
/// <summary>
/// wraps the methodcalls to native windows dll's.
/// </summary>
public static partial class NativeMethods
{
[DllImport("user32.dll")]

View file

@ -1,14 +1,37 @@
using System.Runtime.InteropServices;
using System.Windows.Forms;
// <copyright file="ShowInactiveTopmost.cs" company="PlaceholderCompany">
// Copyright (c) PlaceholderCompany. All rights reserved.
// </copyright>
namespace SystemTrayMenu.DllImports
{
using System.Runtime.InteropServices;
using System.Windows.Forms;
/// <summary>
/// wraps the methodcalls to native windows dll's.
/// </summary>
public static partial class NativeMethods
{
private const int SW_SHOWNOACTIVATE = 4;
private const int HWND_TOPMOST = -1;
private const uint SWP_NOACTIVATE = 0x0010;
public static void User32ShowInactiveTopmost(Form form)
{
if (form != null)
{
_ = ShowWindow(form.Handle, SW_SHOWNOACTIVATE);
SetWindowPos(
form.Handle.ToInt32(),
HWND_TOPMOST,
form.Left,
form.Top,
form.Width,
form.Height,
SWP_NOACTIVATE);
}
}
[DllImport("user32.dll", EntryPoint = "SetWindowPos")]
private static extern bool SetWindowPos(
int hWnd, // Window handle
@ -18,16 +41,5 @@ namespace SystemTrayMenu.DllImports
int cx, // Width
int cy, // Height
uint uFlags); // Window positioning flags
public static void User32ShowInactiveTopmost(Form form)
{
if (form != null)
{
_ = ShowWindow(form.Handle, SW_SHOWNOACTIVATE);
SetWindowPos(form.Handle.ToInt32(), HWND_TOPMOST,
form.Left, form.Top, form.Width, form.Height,
SWP_NOACTIVATE);
}
}
}
}

View file

@ -1,8 +1,14 @@
using System;
using System.Runtime.InteropServices;
// <copyright file="ShowWindow.cs" company="PlaceholderCompany">
// Copyright (c) PlaceholderCompany. All rights reserved.
// </copyright>
namespace SystemTrayMenu.DllImports
{
using System;
using System.Runtime.InteropServices;
/// <summary>
/// wraps the methodcalls to native windows dll's.
/// </summary>
public static partial class NativeMethods
{
[DllImport("user32.dll")]

View file

@ -1,7 +1,13 @@
using System.Runtime.InteropServices;
// <copyright file="StrCmpLogicalW.cs" company="PlaceholderCompany">
// Copyright (c) PlaceholderCompany. All rights reserved.
// </copyright>
namespace SystemTrayMenu.DllImports
{
using System.Runtime.InteropServices;
/// <summary>
/// wraps the methodcalls to native windows dll's.
/// </summary>
public static partial class NativeMethods
{
[DllImport("shlwapi.dll", CharSet = CharSet.Unicode, ExactSpelling = true)]

View file

@ -1,12 +1,19 @@
using System;
using System.Runtime.InteropServices;
using System.Text;
// <copyright file="StrRetToBuf.cs" company="PlaceholderCompany">
// Copyright (c) PlaceholderCompany. All rights reserved.
// </copyright>
namespace SystemTrayMenu.DllImports
{
using System;
using System.Runtime.InteropServices;
using System.Text;
/// <summary>
/// wraps the methodcalls to native windows dll's.
/// </summary>
public static partial class NativeMethods
{
// Takes a STRRET structure returned by IShellFolder::GetDisplayNameOf, converts it to a string, and places the result in a buffer.
// Takes a STRRET structure returned by IShellFolder::GetDisplayNameOf, converts it to a string, and places the result in a buffer.
[DllImport("shlwapi.dll", EntryPoint = "StrRetToBuf", ExactSpelling = false, CharSet = CharSet.Unicode, SetLastError = true)]
private static extern int StrRetToBuf(IntPtr pstr, IntPtr pidl, StringBuilder pszBuf, int cchBuf);

View file

@ -1,32 +1,30 @@
using System;
using System.Runtime.InteropServices;
// <copyright file="TrackPopupMenuEx.cs" company="PlaceholderCompany">
// Copyright (c) PlaceholderCompany. All rights reserved.
// </copyright>
namespace SystemTrayMenu.DllImports
{
using System;
using System.Runtime.InteropServices;
/// <summary>
/// wraps the methodcalls to native windows dll's.
/// </summary>
public static partial class NativeMethods
{
// The TrackPopupMenuEx function displays a shortcut menu at the specified location and tracks the selection of items on the shortcut menu. The shortcut menu can appear anywhere on the screen.
[DllImport("user32.dll", ExactSpelling = true, CharSet = CharSet.Unicode)]
private static extern uint TrackPopupMenuEx(IntPtr hmenu, TPM flags, int x, int y, IntPtr hwnd, IntPtr lptpm);
internal static uint User32TrackPopupMenuEx(IntPtr hmenu, TPM flags, int x, int y, IntPtr hwnd, IntPtr lptpm)
{
return TrackPopupMenuEx(hmenu, flags, x, y, hwnd, lptpm);
}
// Specifies how TrackPopupMenuEx positions the shortcut menu horizontally
/// <summary>
/// Specifies how TrackPopupMenuEx positions the shortcut menu horizontally.
/// </summary>
[Flags]
internal enum TPM : uint
{
LEFTBUTTON = 0x0000,
#pragma warning disable SA1602 // Enumeration items should be documented
LEFTBUTTON = 0x0000, // LEFTALIGN = 0x0000, // TOPALIGN = 0x0000, // HORIZONTAL = 0x0000,
RIGHTBUTTON = 0x0002,
//LEFTALIGN = 0x0000,
CENTERALIGN = 0x0004,
RIGHTALIGN = 0x0008,
//TOPALIGN = 0x0000,
VCENTERALIGN = 0x0010,
BOTTOMALIGN = 0x0020,
//HORIZONTAL = 0x0000,
VERTICAL = 0x0040,
NONOTIFY = 0x0080,
RETURNCMD = 0x0100,
@ -36,7 +34,27 @@ namespace SystemTrayMenu.DllImports
VERPOSANIMATION = 0x1000,
VERNEGANIMATION = 0x2000,
NOANIMATION = 0x4000,
LAYOUTRTL = 0x8000
LAYOUTRTL = 0x8000,
#pragma warning restore SA1602 // Enumeration items should be documented
}
/// <summary>
/// user32 TrackPopupMenuEx.
/// </summary>
/// <param name="hmenu">hmenu.</param>
/// <param name="flags">flags.</param>
/// <param name="x">x.</param>
/// <param name="y">y.</param>
/// <param name="hwnd">hwnd.</param>
/// <param name="lptpm">lptpm.</param>
/// <returns>uint.</returns>
internal static uint User32TrackPopupMenuEx(IntPtr hmenu, TPM flags, int x, int y, IntPtr hwnd, IntPtr lptpm)
{
return TrackPopupMenuEx(hmenu, flags, x, y, hwnd, lptpm);
}
// The TrackPopupMenuEx function displays a shortcut menu at the specified location and tracks the selection of items on the shortcut menu. The shortcut menu can appear anywhere on the screen.
[DllImport("user32.dll", ExactSpelling = true, CharSet = CharSet.Unicode)]
private static extern uint TrackPopupMenuEx(IntPtr hmenu, TPM flags, int x, int y, IntPtr hwnd, IntPtr lptpm);
}
}

View file

@ -2,7 +2,7 @@
using System.Resources;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("SystemTrayMenu")]
@ -14,26 +14,26 @@ using System.Runtime.InteropServices;
[assembly: AssemblyTrademark("TAMAHO")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("116c8741-a9b0-4560-8e82-7cf412894340")]
//https://stackoverflow.com/questions/4068360/c-sharp-warning-mark-assemblies-with-neutralresourceslanguageattribute
// https://stackoverflow.com/questions/4068360/c-sharp-warning-mark-assemblies-with-neutralresourceslanguageattribute
[assembly: NeutralResourcesLanguage("en")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("0.11.4.1")]
[assembly: AssemblyFileVersion("0.11.4.1")]
[assembly: AssemblyVersion("0.11.4.2")]
[assembly: AssemblyFileVersion("0.11.4.2")]

View file

@ -197,11 +197,7 @@
</BootstrapperPackage>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="3.0.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.CodeQuality.Analyzers" Version="3.0.0">
<PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="2.9.6">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>

View file

@ -1,17 +1,17 @@
using Microsoft.Win32;
using System;
using System.Collections.Specialized;
using System.Drawing;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Security;
using System.Text.RegularExpressions;
using System.Windows.Forms;
using SystemTrayMenu.Utilities;
namespace SystemTrayMenu.UserInterface
namespace SystemTrayMenu.UserInterface
{
using Microsoft.Win32;
using System;
using System.Collections.Specialized;
using System.Drawing;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Security;
using System.Text.RegularExpressions;
using System.Windows.Forms;
using SystemTrayMenu.Utilities;
/// <summary>
/// Generic, self-contained About Box dialog
/// </summary>
@ -42,7 +42,7 @@ namespace SystemTrayMenu.UserInterface
// returns the entry assembly for the current application domain
// </summary>
// <remarks>
// This is usually read-only, but in some weird cases (Smart Client apps)
// This is usually read-only, but in some weird cases (Smart Client apps)
// you won't have an entry assembly, so you may want to set this manually.
// </remarks>
public Assembly AppEntryAssembly
@ -55,7 +55,7 @@ namespace SystemTrayMenu.UserInterface
// single line of text to show in the application title section of the about box dialog
// </summary>
// <remarks>
// defaults to "%title%"
// defaults to "%title%"
// %title% = Assembly: AssemblyTitle
// </remarks>
public string AppTitle
@ -203,7 +203,7 @@ namespace SystemTrayMenu.UserInterface
}
// <summary>
// returns DateTime this Assembly was last built. Will attempt to calculate from build number, if possible.
// returns DateTime this Assembly was last built. Will attempt to calculate from build number, if possible.
// If not, the actual LastWriteTime on the assembly file will be returned.
// </summary>
// <param name="a">Assembly to get build date for</param>
@ -227,6 +227,7 @@ namespace SystemTrayMenu.UserInterface
{
dt = dt.AddHours(1);
}
if (dt > DateTime.Now || AssemblyVersion.Build < 730 || AssemblyVersion.Revision == 0)
{
dt = AssemblyLastWriteTime(a);
@ -255,75 +256,77 @@ namespace SystemTrayMenu.UserInterface
// </remarks>
private static NameValueCollection AssemblyAttribs(Assembly a)
{
string TypeName;
string Name;
string Value;
string typeName;
string name;
string value;
NameValueCollection nvc = new NameValueCollection();
Regex r = new Regex(@"(\.Assembly|\.)(?<Name>[^.]*)Attribute$", RegexOptions.IgnoreCase);
foreach (object attrib in a.GetCustomAttributes(false))
{
TypeName = attrib.GetType().ToString();
Name = r.Match(TypeName).Groups["Name"].ToString();
Value = "";
switch (TypeName)
typeName = attrib.GetType().ToString();
name = r.Match(typeName).Groups["Name"].ToString();
value = string.Empty;
switch (typeName)
{
case "System.CLSCompliantAttribute":
Value = ((CLSCompliantAttribute)attrib).IsCompliant.ToString(CultureInfo.InvariantCulture); break;
value = ((CLSCompliantAttribute)attrib).IsCompliant.ToString(CultureInfo.InvariantCulture); break;
case "System.Diagnostics.DebuggableAttribute":
Value = ((System.Diagnostics.DebuggableAttribute)attrib).IsJITTrackingEnabled.ToString(CultureInfo.InvariantCulture); break;
value = ((System.Diagnostics.DebuggableAttribute)attrib).IsJITTrackingEnabled.ToString(CultureInfo.InvariantCulture); break;
case "System.Reflection.AssemblyCompanyAttribute":
Value = ((AssemblyCompanyAttribute)attrib).Company.ToString(CultureInfo.InvariantCulture); break;
value = ((AssemblyCompanyAttribute)attrib).Company.ToString(CultureInfo.InvariantCulture); break;
case "System.Reflection.AssemblyConfigurationAttribute":
Value = ((AssemblyConfigurationAttribute)attrib).Configuration.ToString(CultureInfo.InvariantCulture); break;
value = ((AssemblyConfigurationAttribute)attrib).Configuration.ToString(CultureInfo.InvariantCulture); break;
case "System.Reflection.AssemblyCopyrightAttribute":
Value = ((AssemblyCopyrightAttribute)attrib).Copyright.ToString(CultureInfo.InvariantCulture); break;
value = ((AssemblyCopyrightAttribute)attrib).Copyright.ToString(CultureInfo.InvariantCulture); break;
case "System.Reflection.AssemblyDefaultAliasAttribute":
Value = ((AssemblyDefaultAliasAttribute)attrib).DefaultAlias.ToString(CultureInfo.InvariantCulture); break;
value = ((AssemblyDefaultAliasAttribute)attrib).DefaultAlias.ToString(CultureInfo.InvariantCulture); break;
case "System.Reflection.AssemblyDelaySignAttribute":
Value = ((AssemblyDelaySignAttribute)attrib).DelaySign.ToString(CultureInfo.InvariantCulture); break;
value = ((AssemblyDelaySignAttribute)attrib).DelaySign.ToString(CultureInfo.InvariantCulture); break;
case "System.Reflection.AssemblyDescriptionAttribute":
Value = ((AssemblyDescriptionAttribute)attrib).Description.ToString(CultureInfo.InvariantCulture); break;
value = ((AssemblyDescriptionAttribute)attrib).Description.ToString(CultureInfo.InvariantCulture); break;
case "System.Reflection.AssemblyInformationalVersionAttribute":
Value = ((AssemblyInformationalVersionAttribute)attrib).InformationalVersion.ToString(CultureInfo.InvariantCulture); break;
value = ((AssemblyInformationalVersionAttribute)attrib).InformationalVersion.ToString(CultureInfo.InvariantCulture); break;
case "System.Reflection.AssemblyKeyFileAttribute":
Value = ((AssemblyKeyFileAttribute)attrib).KeyFile.ToString(CultureInfo.InvariantCulture); break;
value = ((AssemblyKeyFileAttribute)attrib).KeyFile.ToString(CultureInfo.InvariantCulture); break;
case "System.Reflection.AssemblyProductAttribute":
Value = ((AssemblyProductAttribute)attrib).Product.ToString(CultureInfo.InvariantCulture); break;
value = ((AssemblyProductAttribute)attrib).Product.ToString(CultureInfo.InvariantCulture); break;
case "System.Reflection.AssemblyTrademarkAttribute":
Value = ((AssemblyTrademarkAttribute)attrib).Trademark.ToString(CultureInfo.InvariantCulture); break;
value = ((AssemblyTrademarkAttribute)attrib).Trademark.ToString(CultureInfo.InvariantCulture); break;
case "System.Reflection.AssemblyTitleAttribute":
Value = ((AssemblyTitleAttribute)attrib).Title.ToString(CultureInfo.InvariantCulture); break;
value = ((AssemblyTitleAttribute)attrib).Title.ToString(CultureInfo.InvariantCulture); break;
case "System.Resources.NeutralResourcesLanguageAttribute":
Value = ((System.Resources.NeutralResourcesLanguageAttribute)attrib).CultureName.ToString(CultureInfo.InvariantCulture); break;
value = ((System.Resources.NeutralResourcesLanguageAttribute)attrib).CultureName.ToString(CultureInfo.InvariantCulture); break;
case "System.Resources.SatelliteContractVersionAttribute":
Value = ((System.Resources.SatelliteContractVersionAttribute)attrib).Version.ToString(CultureInfo.InvariantCulture); break;
value = ((System.Resources.SatelliteContractVersionAttribute)attrib).Version.ToString(CultureInfo.InvariantCulture); break;
case "System.Runtime.InteropServices.ComCompatibleVersionAttribute":
{
System.Runtime.InteropServices.ComCompatibleVersionAttribute x;
x = ((System.Runtime.InteropServices.ComCompatibleVersionAttribute)attrib);
Value = x.MajorVersion + "." + x.MinorVersion + "." + x.RevisionNumber + "." + x.BuildNumber; break;
x = (System.Runtime.InteropServices.ComCompatibleVersionAttribute)attrib;
value = x.MajorVersion + "." + x.MinorVersion + "." + x.RevisionNumber + "." + x.BuildNumber; break;
}
case "System.Runtime.InteropServices.ComVisibleAttribute":
Value = ((System.Runtime.InteropServices.ComVisibleAttribute)attrib).Value.ToString(CultureInfo.InvariantCulture); break;
value = ((System.Runtime.InteropServices.ComVisibleAttribute)attrib).Value.ToString(CultureInfo.InvariantCulture); break;
case "System.Runtime.InteropServices.GuidAttribute":
Value = ((System.Runtime.InteropServices.GuidAttribute)attrib).Value.ToString(CultureInfo.InvariantCulture); break;
value = ((System.Runtime.InteropServices.GuidAttribute)attrib).Value.ToString(CultureInfo.InvariantCulture); break;
case "System.Runtime.InteropServices.TypeLibVersionAttribute":
{
System.Runtime.InteropServices.TypeLibVersionAttribute x;
x = ((System.Runtime.InteropServices.TypeLibVersionAttribute)attrib);
Value = x.MajorVersion + "." + x.MinorVersion; break;
x = (System.Runtime.InteropServices.TypeLibVersionAttribute)attrib;
value = x.MajorVersion + "." + x.MinorVersion; break;
}
case "System.Security.AllowPartiallyTrustedCallersAttribute":
Value = "(Present)"; break;
value = "(Present)"; break;
default:
// debug.writeline("** unknown assembly attribute '" + TypeName + "'")
Value = TypeName; break;
value = typeName; break;
}
if (nvc[Name] == null)
if (nvc[name] == null)
{
nvc.Add(Name, Value);
nvc.Add(name, value);
}
}
@ -333,7 +336,7 @@ namespace SystemTrayMenu.UserInterface
{
if (!a.IsDynamic)
{
nvc.Add("CodeBase", a.CodeBase.Replace("file:///", "", StringComparison.InvariantCulture));
nvc.Add("CodeBase", a.CodeBase.Replace("file:///", string.Empty, StringComparison.InvariantCulture));
}
}
#pragma warning disable CA1031 // Do not catch general exception types
@ -342,6 +345,7 @@ namespace SystemTrayMenu.UserInterface
{
nvc.Add("CodeBase", "(not supported)");
}
// build date
DateTime dt = AssemblyBuildDate(a, false);
if (dt == DateTime.MaxValue)
@ -352,6 +356,7 @@ namespace SystemTrayMenu.UserInterface
{
nvc.Add("BuildDate", dt.ToString("yyyy-MM-dd hh:mm tt", CultureInfo.InvariantCulture));
}
// location
try
{
@ -377,6 +382,7 @@ namespace SystemTrayMenu.UserInterface
version = a.GetName().Version.ToString();
}
}
nvc.Add("Version", version);
if (!a.IsDynamic)
@ -428,11 +434,13 @@ namespace SystemTrayMenu.UserInterface
if (string.IsNullOrEmpty(strSysInfoPath))
{
MessageBox.Show("System Information is unavailable at this time." +
Environment.NewLine +
Environment.NewLine +
MessageBox.Show(
"System Information is unavailable at this time." +
Environment.NewLine + Environment.NewLine +
"(couldn't find path for Microsoft System Information Tool in the registry.)",
Text, MessageBoxButtons.OK, MessageBoxIcon.Warning);
Text,
MessageBoxButtons.OK,
MessageBoxIcon.Warning);
return;
}
@ -448,7 +456,7 @@ namespace SystemTrayMenu.UserInterface
{
ListViewItem lvi = new ListViewItem
{
Text = Key
Text = Key,
};
lvi.SubItems.Add(Value);
lvw.Items.Add(lvi);
@ -463,13 +471,7 @@ namespace SystemTrayMenu.UserInterface
AppDomain d = AppDomain.CurrentDomain;
Populate(AppInfoListView, "Application Name", Assembly.GetEntryAssembly().GetName().Name);
Populate(AppInfoListView, "Application Base", d.SetupInformation.ApplicationBase);
//Populate(AppInfoListView, "Cache Path", d.SetupInformation.CachePath);
//Populate(AppInfoListView, "Configuration File", d.SetupInformation.ConfigurationFile);
//Populate(AppInfoListView, "Dynamic Base", d.SetupInformation.DynamicBase);
Populate(AppInfoListView, "Friendly Name", d.FriendlyName);
//Populate(AppInfoListView, "License File", d.SetupInformation.LicenseFile);
//Populate(AppInfoListView, "private Bin Path", d.SetupInformation.PrivateBinPath);
//Populate(AppInfoListView, "Shadow Copy Directories", d.SetupInformation.ShadowCopyDirectories);
Populate(AppInfoListView, " ", " ");
Populate(AppInfoListView, "Entry Assembly", _EntryAssemblyName);
Populate(AppInfoListView, "Executing Assembly", _ExecutingAssemblyName);
@ -485,6 +487,7 @@ namespace SystemTrayMenu.UserInterface
{
PopulateAssemblySummary(a);
}
AssemblyNamesComboBox.SelectedIndex = AssemblyNamesComboBox.FindStringExact(_EntryAssemblyName);
}
@ -500,26 +503,26 @@ namespace SystemTrayMenu.UserInterface
ListViewItem lvi = new ListViewItem
{
Text = strAssemblyName,
Tag = strAssemblyName
Tag = strAssemblyName,
};
if (strAssemblyName == _CallingAssemblyName)
{
lvi.Text += " (calling)";
}
if (strAssemblyName == _ExecutingAssemblyName)
{
lvi.Text += " (executing)";
}
if (strAssemblyName == _EntryAssemblyName)
{
lvi.Text += " (entry)";
}
lvi.SubItems.Add(nvc["version"]);
lvi.SubItems.Add(nvc["builddate"]);
lvi.SubItems.Add(nvc["codebase"]);
//lvi.SubItems.Add(AssemblyVersion(a))
//lvi.SubItems.Add(AssemblyBuildDatestring(a, true))
//lvi.SubItems.Add(AssemblyCodeBase(a))
AssemblyInfoListView.Items.Add(lvi);
AssemblyNamesComboBox.Items.Add(strAssemblyName);
}
@ -548,17 +551,12 @@ namespace SystemTrayMenu.UserInterface
_EntryAssemblyAttribCollection = AssemblyAttribs(_EntryAssembly);
// set icon from parent, if present
if (Owner == null)
{
//ImagePictureBox.Visible = false;
//AppTitleLabel.Left = AppCopyrightLabel.Left;
//AppDescriptionLabel.Left = AppCopyrightLabel.Left;
}
else
if (Owner != null)
{
Icon = Owner.Icon;
ImagePictureBox.Image = Icon.ToBitmap();
}
// replace all labels and window title
Text = ReplaceTokens(Text);
AppTitleLabel.Text = ReplaceTokens(AppTitleLabel.Text);
@ -566,18 +564,22 @@ namespace SystemTrayMenu.UserInterface
{
AppDescriptionLabel.Text = ReplaceTokens(AppDescriptionLabel.Text);
}
if (AppCopyrightLabel.Visible)
{
AppCopyrightLabel.Text = ReplaceTokens(AppCopyrightLabel.Text);
}
if (AppVersionLabel.Visible)
{
AppVersionLabel.Text = ReplaceTokens(AppVersionLabel.Text);
}
if (AppDateLabel.Visible)
{
AppDateLabel.Text = ReplaceTokens(AppDateLabel.Text);
}
if (MoreRichTextBox.Visible)
{
MoreRichTextBox.Text = ReplaceTokens(MoreRichTextBox.Text);
@ -631,6 +633,7 @@ namespace SystemTrayMenu.UserInterface
return a;
}
}
return null;
}
@ -644,6 +647,7 @@ namespace SystemTrayMenu.UserInterface
{
_EntryAssembly = Assembly.GetEntryAssembly();
}
if (_EntryAssembly == null)
{
_EntryAssembly = Assembly.GetExecutingAssembly();
@ -655,8 +659,6 @@ namespace SystemTrayMenu.UserInterface
// for web hosted apps, GetEntryAssembly = nothing
_EntryAssemblyName = Assembly.GetEntryAssembly().GetName().Name;
//_MinWindowHeight = AppCopyrightLabel.Top + AppCopyrightLabel.Height + buttonOk.Height + 30;
TabPanelDetails.Visible = false;
if (!MoreRichTextBox.Visible)
{
@ -749,6 +751,7 @@ namespace SystemTrayMenu.UserInterface
intTargetCol = -Convert.ToInt32(AssemblyInfoListView.Tag, CultureInfo.InvariantCulture);
}
}
AssemblyInfoListView.Tag = intTargetCol;
AssemblyInfoListView.ListViewItemSorter = new ListViewItemComparer(intTargetCol, true);
}
@ -785,6 +788,7 @@ namespace SystemTrayMenu.UserInterface
{
_IsAscending = ascending;
}
_intCol = Math.Abs(column) - 1;
}
@ -793,7 +797,8 @@ namespace SystemTrayMenu.UserInterface
int intResult = string.Compare(
((ListViewItem)x).SubItems[_intCol].Text,
((ListViewItem)y).SubItems[_intCol].Text,
CultureInfo.InvariantCulture, CompareOptions.None);
CultureInfo.InvariantCulture,
CompareOptions.None);
if (_IsAscending)
{
return intResult;

View file

@ -1,13 +1,16 @@
using System;
using System.Diagnostics;
using System.Drawing;
using System.Reflection;
using System.Windows.Forms;
using SystemTrayMenu.UserInterface;
using SystemTrayMenu.Utilities;
// <copyright file="AppContextMenu.cs" company="PlaceholderCompany">
// Copyright (c) PlaceholderCompany. All rights reserved.
// </copyright>
namespace SystemTrayMenu.Helper
{
using System;
using System.Diagnostics;
using System.Drawing;
using System.Reflection;
using System.Windows.Forms;
using SystemTrayMenu.UserInterface;
using SystemTrayMenu.Utilities;
internal class AppContextMenu
{
public event EventHandlerEmpty ClickedOpenLog;
@ -18,16 +21,16 @@ namespace SystemTrayMenu.Helper
{
ContextMenuStrip menu = new ContextMenuStrip
{
BackColor = SystemColors.Control
BackColor = SystemColors.Control,
};
ToolStripMenuItem settings = new ToolStripMenuItem()
{
ImageScaling = ToolStripItemImageScaling.SizeToFit,
Text = Translator.GetText("Settings")
Text = Translator.GetText("Settings"),
};
settings.Click += Settings_Click;
void Settings_Click(object sender, EventArgs e)
static void Settings_Click(object sender, EventArgs e)
{
SettingsForm settingsForm = new SettingsForm();
if (settingsForm.ShowDialog() == DialogResult.OK)
@ -35,44 +38,47 @@ namespace SystemTrayMenu.Helper
AppRestart.ByConfigChange();
}
}
menu.Items.Add(settings);
ToolStripSeparator seperator = new ToolStripSeparator
{
BackColor = SystemColors.Control
BackColor = SystemColors.Control,
};
menu.Items.Add(seperator);
ToolStripMenuItem openLog = new ToolStripMenuItem
{
Text = Translator.GetText("Log File")
Text = Translator.GetText("Log File"),
};
openLog.Click += OpenLog_Click;
void OpenLog_Click(object sender, EventArgs e)
{
ClickedOpenLog?.Invoke();
}
menu.Items.Add(openLog);
menu.Items.Add(new ToolStripSeparator());
ToolStripMenuItem helpFAQ = new ToolStripMenuItem
{
Text = Translator.GetText("HelpFAQ")
Text = Translator.GetText("HelpFAQ"),
};
helpFAQ.Click += HelpFAQ_Click;
void HelpFAQ_Click(object sender, EventArgs e)
static void HelpFAQ_Click(object sender, EventArgs e)
{
Config.ShowHelpFAQ();
}
menu.Items.Add(helpFAQ);
ToolStripMenuItem about = new ToolStripMenuItem
{
Text = Translator.GetText("About")
Text = Translator.GetText("About"),
};
about.Click += About_Click;
void About_Click(object sender, EventArgs e)
static void About_Click(object sender, EventArgs e)
{
FileVersionInfo versionInfo = FileVersionInfo.GetVersionInfo(
Assembly.GetEntryAssembly().Location);
@ -82,7 +88,7 @@ namespace SystemTrayMenu.Helper
AppDescription = versionInfo.FileDescription,
AppVersion = $"Version {versionInfo.FileVersion}",
AppCopyright = versionInfo.LegalCopyright,
AppMoreInfo = versionInfo.LegalCopyright
AppMoreInfo = versionInfo.LegalCopyright,
};
ab.AppMoreInfo += Environment.NewLine;
ab.AppMoreInfo += "Markus Hofknecht (mailto:Markus@Hofknecht.eu)";
@ -99,30 +105,33 @@ namespace SystemTrayMenu.Helper
ab.AppDetailsButton = true;
ab.ShowDialog();
}
menu.Items.Add(about);
menu.Items.Add(new ToolStripSeparator());
ToolStripMenuItem restart = new ToolStripMenuItem
{
Text = Translator.GetText("Restart")
Text = Translator.GetText("Restart"),
};
restart.Click += Restart_Click;
void Restart_Click(object sender, EventArgs e)
{
ClickedRestart?.Invoke();
}
menu.Items.Add(restart);
ToolStripMenuItem exit = new ToolStripMenuItem
{
Text = Translator.GetText("Exit")
Text = Translator.GetText("Exit"),
};
exit.Click += Exit_Click;
void Exit_Click(object sender, EventArgs e)
{
ClickedExit?.Invoke();
}
menu.Items.Add(exit);
return menu;

View file

@ -1,23 +1,26 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;
using SystemTrayMenu.Helper;
using SystemTrayMenu.Utilities;
using R = SystemTrayMenu.Properties.Resources;
using Timer = System.Windows.Forms.Timer;
// <copyright file="AppNotifyIcon.cs" company="PlaceholderCompany">
// Copyright (c) PlaceholderCompany. All rights reserved.
// </copyright>
namespace SystemTrayMenu.UserInterface
{
internal class MenuNotifyIcon : IDisposable
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;
using SystemTrayMenu.Helper;
using SystemTrayMenu.Utilities;
using R = SystemTrayMenu.Properties.Resources;
using Timer = System.Windows.Forms.Timer;
internal class AppNotifyIcon : IDisposable
{
public event EventHandlerEmpty Click;
public event EventHandlerEmpty OpenLog;
public event EventHandlerEmpty Restart;
public event EventHandlerEmpty Exit;
private const int Interval60FPS = 16; //60fps=>1s/60fps=~16.6ms
private const int Interval60FPS = 16; // 60fps=>1s/60fps=~16.6ms
private readonly NotifyIcon notifyIcon = new NotifyIcon();
private DateTime timeLoadingStart;
private bool threadsLoading = false;
@ -26,9 +29,9 @@ namespace SystemTrayMenu.UserInterface
private readonly int indexLoad = 0;
private readonly List<Icon> bitmapsLoading = new List<Icon>() { R.L010, R.L020, R.L030,
R.L040, R.L050, R.L060, R.L070, R.L080, R.L090, R.L100, R.L110, R.L120,
R.L130, R.L140, R.L150, R.L160, R.L170, R.L180};
R.L130, R.L140, R.L150, R.L160, R.L170, R.L180, };
public MenuNotifyIcon()
public AppNotifyIcon()
{
indexLoad = bitmapsLoading.Count;
notifyIcon.Icon = bitmapsLoading.First();
@ -63,6 +66,7 @@ namespace SystemTrayMenu.UserInterface
{
VerifyClick(e);
}
notifyIcon.MouseDoubleClick += NotifyIcon_MouseDoubleClick;
void NotifyIcon_MouseDoubleClick(object sender, MouseEventArgs e)
{

View file

@ -1,13 +1,17 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Text;
using System.Windows.Forms;
using SystemTrayMenu.DllImports;
using SystemTrayMenu.Utilities;
// <copyright file="HotkeyControl.cs" company="PlaceholderCompany">
// Copyright (c) PlaceholderCompany. All rights reserved.
// </copyright>
namespace SystemTrayMenu.UserInterface.Controls
{
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Text;
using System.Windows.Forms;
using SystemTrayMenu.DllImports;
using SystemTrayMenu.Utilities;
/// <summary>
/// A simple control that allows the user to select pretty much any valid hotkey combination
/// See: http://www.codeproject.com/KB/buttons/hotkeycontrol.aspx
@ -35,17 +39,17 @@ namespace SystemTrayMenu.UserInterface.Controls
CTRL = 2,
SHIFT = 4,
WIN = 8,
NOREPEAT = 0x4000
NOREPEAT = 0x4000,
}
[SuppressMessage("ReSharper", "InconsistentNaming")]
private enum MapType : uint
{
MAPVK_VK_TO_VSC = 0, //The uCode parameter is a virtual-key code and is translated into a scan code. If it is a virtual-key code that does not distinguish between left- and right-hand keys, the left-hand scan code is returned. If there is no translation, the function returns 0.
MAPVK_VSC_TO_VK = 1, //The uCode parameter is a scan code and is translated into a virtual-key code that does not distinguish between left- and right-hand keys. If there is no translation, the function returns 0.
MAPVK_VK_TO_CHAR = 2, //The uCode parameter is a virtual-key code and is translated into an unshifted character value in the low order word of the return value. Dead keys (diacritics) are indicated by setting the top bit of the return value. If there is no translation, the function returns 0.
MAPVK_VSC_TO_VK_EX = 3, //The uCode parameter is a scan code and is translated into a virtual-key code that distinguishes between left- and right-hand keys. If there is no translation, the function returns 0.
MAPVK_VK_TO_VSC_EX = 4 //The uCode parameter is a virtual-key code and is translated into a scan code. If it is a virtual-key code that does not distinguish between left- and right-hand keys, the left-hand scan code is returned. If the scan code is an extended scan code, the high byte of the uCode value can contain either 0xe0 or 0xe1 to specify the extended scan code. If there is no translation, the function returns 0.
MAPVK_VK_TO_VSC = 0, // The uCode parameter is a virtual-key code and is translated into a scan code. If it is a virtual-key code that does not distinguish between left- and right-hand keys, the left-hand scan code is returned. If there is no translation, the function returns 0.
MAPVK_VSC_TO_VK = 1, // The uCode parameter is a scan code and is translated into a virtual-key code that does not distinguish between left- and right-hand keys. If there is no translation, the function returns 0.
MAPVK_VK_TO_CHAR = 2, // The uCode parameter is a virtual-key code and is translated into an unshifted character value in the low order word of the return value. Dead keys (diacritics) are indicated by setting the top bit of the return value. If there is no translation, the function returns 0.
MAPVK_VSC_TO_VK_EX = 3, // The uCode parameter is a scan code and is translated into a virtual-key code that distinguishes between left- and right-hand keys. If there is no translation, the function returns 0.
MAPVK_VK_TO_VSC_EX = 4, // The uCode parameter is a virtual-key code and is translated into a scan code. If it is a virtual-key code that does not distinguish between left- and right-hand keys, the left-hand scan code is returned. If the scan code is an extended scan code, the high byte of the uCode value can contain either 0xe0 or 0xe1 to specify the extended scan code. If there is no translation, the function returns 0.
}
// These variables store the current hotkey and modifier(s)
@ -80,7 +84,7 @@ namespace SystemTrayMenu.UserInterface.Controls
}
/// <summary>
/// Creates a new HotkeyControl
/// Initializes a new instance of the <see cref="HotkeyControl"/> class.
/// </summary>
public HotkeyControl()
{
@ -277,14 +281,14 @@ namespace SystemTrayMenu.UserInterface.Controls
// No hotkey set
if (_hotkey == Keys.None)
{
Text = "";
Text = string.Empty;
return;
}
// LWin/RWin doesn't work as hotkeys (neither do they work as modifier keys in .NET 2.0)
if (_hotkey == Keys.LWin || _hotkey == Keys.RWin)
{
Text = "";
Text = string.Empty;
return;
}
@ -312,16 +316,17 @@ namespace SystemTrayMenu.UserInterface.Controls
// User pressed Shift and an invalid key (e.g. a letter or a number),
// that needs another set of modifier keys
_hotkey = Keys.None;
Text = "";
Text = string.Empty;
return;
}
}
// Check all Ctrl+Alt keys
if ((_modifiers == (Keys.Alt | Keys.Control)) && _needNonAltGrModifier.Contains((int)_hotkey))
{
// Ctrl+Alt+4 etc won't work; reset hotkey and tell the user
_hotkey = Keys.None;
Text = "";
Text = string.Empty;
return;
}
}
@ -332,6 +337,7 @@ namespace SystemTrayMenu.UserInterface.Controls
{
_hotkey = Keys.None;
}
Text = HotkeyToLocalizedString(_modifiers, _hotkey);
}
@ -359,18 +365,22 @@ namespace SystemTrayMenu.UserInterface.Controls
{
hotkeyString.Append("Alt").Append(" + ");
}
if ((modifierKeyCode & Keys.Control) > 0)
{
hotkeyString.Append("Ctrl").Append(" + ");
}
if ((modifierKeyCode & Keys.Shift) > 0)
{
hotkeyString.Append("Shift").Append(" + ");
}
if (modifierKeyCode == Keys.LWin || modifierKeyCode == Keys.RWin)
{
hotkeyString.Append("Win").Append(" + ");
}
return hotkeyString.ToString();
}
@ -387,18 +397,22 @@ namespace SystemTrayMenu.UserInterface.Controls
{
hotkeyString.Append(GetKeyName(Keys.Alt)).Append(" + ");
}
if ((modifierKeyCode & Keys.Control) > 0)
{
hotkeyString.Append(GetKeyName(Keys.Control)).Append(" + ");
}
if ((modifierKeyCode & Keys.Shift) > 0)
{
hotkeyString.Append(GetKeyName(Keys.Shift)).Append(" + ");
}
if (modifierKeyCode == Keys.LWin || modifierKeyCode == Keys.RWin)
{
hotkeyString.Append("Win").Append(" + ");
}
return hotkeyString.ToString();
}
@ -412,20 +426,24 @@ namespace SystemTrayMenu.UserInterface.Controls
{
modifiers |= Keys.Alt;
}
if (modifiersString.ToUpperInvariant().Contains("CTRL", StringComparison.InvariantCulture) ||
modifiersString.ToUpperInvariant().Contains("STRG", StringComparison.InvariantCulture))
{
modifiers |= Keys.Control;
}
if (modifiersString.ToUpperInvariant().Contains("SHIFT", StringComparison.InvariantCulture))
{
modifiers |= Keys.Shift;
}
if (modifiersString.ToUpperInvariant().Contains("WIN", StringComparison.InvariantCulture))
{
modifiers |= Keys.LWin;
}
}
return modifiers;
}
@ -438,6 +456,7 @@ namespace SystemTrayMenu.UserInterface.Controls
{
hotkey = hotkey.Remove(0, hotkey.LastIndexOf('+') + 1).Trim();
}
try
{
hotkey = hotkey.
@ -450,6 +469,7 @@ namespace SystemTrayMenu.UserInterface.Controls
Log.Warn($"{hotkey} can not be parsed", ex);
}
}
return key;
}
@ -476,29 +496,34 @@ namespace SystemTrayMenu.UserInterface.Controls
{
return 0;
}
// Convert Modifiers to fit HKM_SETHOTKEY
uint modifiers = 0;
if ((modifierKeyCode & Keys.Alt) > 0)
{
modifiers |= (uint)Modifiers.ALT;
}
if ((modifierKeyCode & Keys.Control) > 0)
{
modifiers |= (uint)Modifiers.CTRL;
}
if ((modifierKeyCode & Keys.Shift) > 0)
{
modifiers |= (uint)Modifiers.SHIFT;
}
if (modifierKeyCode == Keys.LWin || modifierKeyCode == Keys.RWin)
{
modifiers |= (uint)Modifiers.WIN;
}
// Disable repeating hotkey for Windows 7 and beyond, as described in #1559
if (IsWindows7OrOlder)
{
modifiers |= (uint)Modifiers.NOREPEAT;
}
if (NativeMethods.User32RegisterHotKey(_hotkeyHwnd, _hotKeyCounter, modifiers, (uint)virtualKeyCode))
{
KeyHandlers.Add(_hotKeyCounter, handler);
@ -517,7 +542,7 @@ namespace SystemTrayMenu.UserInterface.Controls
{
NativeMethods.User32UnregisterHotKey(_hotkeyHwnd, hotkey);
}
// Remove all key handlers
KeyHandlers.Clear();
}
@ -532,6 +557,7 @@ namespace SystemTrayMenu.UserInterface.Controls
removeHotkey = true;
}
}
if (removeHotkey)
{
// Remove key handler
@ -540,25 +566,27 @@ namespace SystemTrayMenu.UserInterface.Controls
}
/// <summary>
/// Handle WndProc messages for the hotkey
/// Handle WndProc messages for the hotkey.
/// </summary>
/// <param name="m"></param>
/// <returns>true if the message was handled</returns>
/// <param name="m">m.</param>
/// <returns>true if the message was handled.</returns>
public static bool HandleMessages(ref Message m)
{
if (m.Msg != WM_HOTKEY)
{
return false;
}
// Call handler
if (!IsWindows7OrOlder && !EventDelay.Check())
{
return true;
}
if (KeyHandlers.TryGetValue((int)m.WParam, out HotKeyHandler handler))
{
handler();
}
return true;
}
@ -585,26 +613,31 @@ namespace SystemTrayMenu.UserInterface.Controls
case Keys.Multiply:
if (NativeMethods.User32GetKeyNameText(numpad << 16, keyName, 100) > 0)
{
keyString = keyName.ToString().Replace("*", "", StringComparison.InvariantCulture).Trim().ToLowerInvariant();
keyString = keyName.ToString().Replace("*", string.Empty, StringComparison.InvariantCulture).Trim().ToLowerInvariant();
if (keyString.IndexOf("(", StringComparison.Ordinal) >= 0)
{
return "* " + keyString;
}
keyString = keyString.Substring(0, 1).ToUpperInvariant() + keyString.Substring(1).ToLowerInvariant();
}
return keyString + " *";
case Keys.Divide:
if (NativeMethods.User32GetKeyNameText(numpad << 16, keyName, 100) > 0)
{
keyString = keyName.ToString().Replace("*", "", StringComparison.InvariantCulture).Trim().ToLowerInvariant();
keyString = keyName.ToString().Replace("*", string.Empty, StringComparison.InvariantCulture).Trim().ToLowerInvariant();
if (keyString.IndexOf("(", StringComparison.Ordinal) >= 0)
{
return "/ " + keyString;
}
keyString = keyString.Substring(0, 1).ToUpperInvariant() + keyString.Substring(1).ToLowerInvariant();
}
return keyString + " /";
}
uint scanCode = NativeMethods.User32MapVirtualKey((uint)virtualKey, (uint)MapType.MAPVK_VK_TO_VSC);
// because MapVirtualKey strips the extended bit for some keys
@ -621,7 +654,6 @@ namespace SystemTrayMenu.UserInterface.Controls
case Keys.Insert:
case Keys.Delete:
case Keys.NumLock:
//Log.Debug("Modifying Extended bit");
scanCode |= 0x100; // set extended bit
break;
case Keys.PrintScreen: // PrintScreen
@ -631,6 +663,7 @@ namespace SystemTrayMenu.UserInterface.Controls
scanCode = 69;
break;
}
scanCode |= 0x200;
if (NativeMethods.User32GetKeyNameText(scanCode << 16, keyName, 100) != 0)
{
@ -639,6 +672,7 @@ namespace SystemTrayMenu.UserInterface.Controls
{
visibleName = visibleName.Substring(0, 1) + visibleName.Substring(1).ToLowerInvariant();
}
return visibleName;
}
else
@ -651,8 +685,9 @@ namespace SystemTrayMenu.UserInterface.Controls
public class EventDelay
{
private long lastCheck;
private readonly long waitTime;
private long lastCheck;
public EventDelay(long ticks)
{
waitTime = ticks;
@ -671,8 +706,4 @@ namespace SystemTrayMenu.UserInterface.Controls
}
}
}
}
}

View file

@ -1,12 +1,16 @@
using System;
using System.IO;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using SystemTrayMenu.Utilities;
// <copyright file="FolderDialog.cs" company="PlaceholderCompany">
// Copyright (c) PlaceholderCompany. All rights reserved.
// </copyright>
namespace SystemTrayMenu.UserInterface.Dialogs
{
using System;
using System.IO;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using SystemTrayMenu.Utilities;
public class FolderDialog : IFolderDialog, IDisposable
{
private bool isDisposed;
@ -17,7 +21,7 @@ namespace SystemTrayMenu.UserInterface.Dialogs
public string InitialFolder { get; set; }
/// <summary>
/// Gets/sets directory in which dialog will be open
/// Gets/sets directory in which dialog will be open
/// if there is no recent directory available.
/// </summary>
public string DefaultFolder { get; set; }
@ -30,6 +34,7 @@ namespace SystemTrayMenu.UserInterface.Dialogs
{
return ShowDialog(owner: new WindowWrapper(IntPtr.Zero));
}
public DialogResult ShowDialog(IWin32Window owner)
{
if (Environment.OSVersion.Version.Major >= 6)
@ -41,9 +46,10 @@ namespace SystemTrayMenu.UserInterface.Dialogs
return ShowLegacyDialog(owner);
}
}
public DialogResult ShowVistaDialog(IWin32Window owner)
{
NativeMethods.IFileDialog frm = (NativeMethods.IFileDialog)(new NativeMethods.FileOpenDialogRCW());
NativeMethods.IFileDialog frm = (NativeMethods.IFileDialog)new NativeMethods.FileOpenDialogRCW();
frm.GetOptions(out uint options);
options |= NativeMethods.FOS_PICKFOLDERS |
NativeMethods.FOS_FORCEFILESYSTEM |
@ -53,19 +59,24 @@ namespace SystemTrayMenu.UserInterface.Dialogs
frm.SetOptions(options);
if (InitialFolder != null)
{
Guid riid = new Guid("43826D1E-E718-42EE-BC55-A1E261C37BFE"); //IShellItem
if (NativeMethods.SHCreateItemFromParsingName
(InitialFolder, IntPtr.Zero, ref riid,
Guid riid = new Guid("43826D1E-E718-42EE-BC55-A1E261C37BFE"); // IShellItem
if (NativeMethods.SHCreateItemFromParsingName(
InitialFolder,
IntPtr.Zero,
ref riid,
out NativeMethods.IShellItem directoryShellItem) == NativeMethods.S_OK)
{
frm.SetFolder(directoryShellItem);
}
}
if (DefaultFolder != null)
{
Guid riid = new Guid("43826D1E-E718-42EE-BC55-A1E261C37BFE"); //IShellItem
if (NativeMethods.SHCreateItemFromParsingName
(DefaultFolder, IntPtr.Zero, ref riid,
Guid riid = new Guid("43826D1E-E718-42EE-BC55-A1E261C37BFE"); // IShellItem
if (NativeMethods.SHCreateItemFromParsingName(
DefaultFolder,
IntPtr.Zero,
ref riid,
out NativeMethods.IShellItem directoryShellItem) == NativeMethods.S_OK)
{
frm.SetDefaultFolder(directoryShellItem);
@ -94,8 +105,10 @@ namespace SystemTrayMenu.UserInterface.Dialogs
}
}
}
return DialogResult.Cancel;
}
public DialogResult ShowLegacyDialog(IWin32Window owner)
{
using SaveFileDialog frm = new SaveFileDialog
@ -104,7 +117,7 @@ namespace SystemTrayMenu.UserInterface.Dialogs
CheckPathExists = true,
CreatePrompt = false,
Filter = "|" + Guid.Empty.ToString(),
FileName = "any"
FileName = "any",
};
if (InitialFolder != null) { frm.InitialDirectory = InitialFolder; }
frm.OverwritePrompt = false;
@ -131,15 +144,16 @@ namespace SystemTrayMenu.UserInterface.Dialogs
{
if (!isDisposed)
{
//just to have possibility of Using statement.
}
isDisposed = true;
}
}
public class WindowWrapper : System.Windows.Forms.IWin32Window
{
/// <summary>
/// Constructor
/// Initializes a new instance of the <see cref="WindowWrapper"/> class.
/// </summary>
/// <param name="handle">Handle to wrap</param>
public WindowWrapper(IntPtr handle)
@ -151,13 +165,11 @@ namespace SystemTrayMenu.UserInterface.Dialogs
/// Original ptr
/// </summary>
public IntPtr Handle => _hwnd;
private readonly IntPtr _hwnd;
}
internal static class NativeMethods
{
#region Constants
public const uint FOS_PICKFOLDERS = 0x00000020;
public const uint FOS_FORCEFILESYSTEM = 0x00000040;
public const uint FOS_NOVALIDATE = 0x00000100;
@ -168,10 +180,6 @@ namespace SystemTrayMenu.UserInterface.Dialogs
public const uint SIGDN_FILESYSPATH = 0x80058000;
#endregion
#region COM
[ComImport, ClassInterface(ClassInterfaceType.None),
TypeLibType(TypeLibTypeFlags.FCanCreate),
Guid("DC1C5A9C-E88A-4DDE-A5A1-60F82A20AEF7")]
@ -184,7 +192,7 @@ namespace SystemTrayMenu.UserInterface.Dialogs
[MethodImpl(MethodImplOptions.InternalCall,
MethodCodeType = MethodCodeType.Runtime)]
[PreserveSig()]
uint Show([In, Optional] IntPtr hwndOwner); //IModalWindow
uint Show([In, Optional] IntPtr hwndOwner);
[MethodImpl(MethodImplOptions.InternalCall,
MethodCodeType = MethodCodeType.Runtime)]
@ -290,32 +298,30 @@ namespace SystemTrayMenu.UserInterface.Dialogs
{
[MethodImpl(MethodImplOptions.InternalCall,
MethodCodeType = MethodCodeType.Runtime)]
uint BindToHandler([In] IntPtr pbc, [In] ref Guid rbhid,
[In] ref Guid riid, [Out, MarshalAs(UnmanagedType.Interface)] out IntPtr ppvOut);
uint BindToHandler(
[In] IntPtr pbc,
[In] ref Guid rbhid,
[In] ref Guid riid,
[Out, MarshalAs(UnmanagedType.Interface)] out IntPtr ppvOut);
[MethodImpl(MethodImplOptions.InternalCall,
MethodCodeType = MethodCodeType.Runtime)]
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
uint GetParent([MarshalAs(UnmanagedType.Interface)] out IShellItem ppsi);
[MethodImpl(MethodImplOptions.InternalCall,
MethodCodeType = MethodCodeType.Runtime)]
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
uint GetDisplayName([In] uint sigdnName, out IntPtr ppszName);
[MethodImpl(MethodImplOptions.InternalCall,
MethodCodeType = MethodCodeType.Runtime)]
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
uint GetAttributes([In] uint sfgaoMask, out uint psfgaoAttribs);
[MethodImpl(MethodImplOptions.InternalCall,
MethodCodeType = MethodCodeType.Runtime)]
uint Compare([In, MarshalAs(UnmanagedType.Interface)] IShellItem psi,
[In] uint hint, out int piOrder);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
uint Compare([In, MarshalAs(UnmanagedType.Interface)] IShellItem psi, [In] uint hint, out int piOrder);
}
#endregion
[DllImport("shell32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
internal static extern int SHCreateItemFromParsingName
([MarshalAs(UnmanagedType.LPWStr)] string pszPath, IntPtr pbc,
ref Guid riid, [MarshalAs(UnmanagedType.Interface)] out IShellItem ppv);
internal static extern int SHCreateItemFromParsingName(
[MarshalAs(UnmanagedType.LPWStr)] string pszPath,
IntPtr pbc,
ref Guid riid,
[MarshalAs(UnmanagedType.Interface)] out IShellItem ppv);
}
}

View file

@ -1,7 +1,11 @@
using System.Windows.Forms;
// <copyright file="IFolderDialog.cs" company="PlaceholderCompany">
// Copyright (c) PlaceholderCompany. All rights reserved.
// </copyright>
namespace SystemTrayMenu.UserInterface.Dialogs
{
using System.Windows.Forms;
public interface IFolderDialog
{
string InitialFolder { get; set; }

View file

@ -1,15 +1,18 @@
using System;
using System.Windows.Forms;
// <copyright file="LabelNoCopy.cs" company="PlaceholderCompany">
// Copyright (c) PlaceholderCompany. All rights reserved.
// </copyright>
namespace SystemTrayMenu.UserInterface
{
using System;
using System.Windows.Forms;
/// <summary>
/// Workaround class for "Clipboard" issue on .Net Windows Forms Label (https://github.com/Hofknecht/SystemTrayMenu/issues/5)
/// On Label MouseDoubleClick the framework will copy the title text into the clipboard.
/// We avoid this by overriding the Text atrribute and use own _text attribute.
/// Text will remain unset and clipboard copy will not take place but it is still possible to get/set Text attribute as usual from outside.
/// (see: https://stackoverflow.com/questions/2519587/is-there-any-way-to-disable-the-double-click-to-copy-functionality-of-a-net-l)
///
///
/// Note: When you have trouble with the Visual Studio Designer not showing the GUI properly, simply build once and reopen the Designer.
/// This will place the required files into the Designer's cache and becomes able to show the GUI as usual.
/// </summary>
@ -23,7 +26,7 @@ namespace SystemTrayMenu.UserInterface
{
if (value == null)
{
value = "";
value = string.Empty;
}
if (_text != value)

View file

@ -1,16 +1,16 @@
using System;
using System.Data;
using System.Drawing;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Windows.Forms;
using SystemTrayMenu.DataClasses;
using SystemTrayMenu.DllImports;
using SystemTrayMenu.Utilities;
namespace SystemTrayMenu.UserInterface
namespace SystemTrayMenu.UserInterface
{
using System;
using System.Data;
using System.Drawing;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Windows.Forms;
using SystemTrayMenu.DataClasses;
using SystemTrayMenu.DllImports;
using SystemTrayMenu.Utilities;
internal partial class Menu : Form
{
internal new event EventHandlerEmpty MouseWheel;
@ -30,7 +30,7 @@ namespace SystemTrayMenu.UserInterface
Sub,
Empty,
NoAccess,
MaxReached
MaxReached,
}
internal int Level = 0;
@ -48,6 +48,7 @@ namespace SystemTrayMenu.UserInterface
Opacity = newOpacity;
}
}
fading.Show += Fading_Show;
void Fading_Show()
{
@ -84,6 +85,7 @@ namespace SystemTrayMenu.UserInterface
textBoxSearch.Focus();
}
}
fading.Hide += Hide;
InitializeComponent();
@ -93,12 +95,13 @@ namespace SystemTrayMenu.UserInterface
e.Graphics.DrawIcon(Properties.Resources.search2,
new Rectangle(0, 0, pictureBoxSearch.Width, pictureBoxSearch.Height));
}
SetDoubleBuffer(dgv, true);
DataGridViewCellStyle dgvCellStyle = new DataGridViewCellStyle
{
SelectionBackColor = MenuDefines.ColorSelectedItem,
SelectionForeColor = Color.Black
SelectionForeColor = Color.Black,
};
dgv.DefaultCellStyle = dgvCellStyle;
@ -111,6 +114,7 @@ namespace SystemTrayMenu.UserInterface
{
MouseEnter?.Invoke();
}
scrollBar.MouseLeave += ControlsMouseLeave;
dgv.MouseLeave += ControlsMouseLeave;
labelTitle.MouseLeave += ControlsMouseLeave;
@ -129,7 +133,9 @@ namespace SystemTrayMenu.UserInterface
{
typeof(Control).InvokeMember("DoubleBuffered",
BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.SetProperty,
null, ctl, new object[] { DoubleBuffered },
null,
ctl,
new object[] { DoubleBuffered },
CultureInfo.InvariantCulture);
}
@ -157,6 +163,7 @@ namespace SystemTrayMenu.UserInterface
{
labelTitle.Dispose();
}
break;
case MenuType.Empty:
SetTitle(Translator.GetText("Folder empty"));
@ -206,6 +213,7 @@ namespace SystemTrayMenu.UserInterface
{
title = $"{title.Substring(0, MenuDefines.LengthMax)}...";
}
labelTitle.Text = title;
}
}
@ -240,8 +248,10 @@ namespace SystemTrayMenu.UserInterface
}
}
internal void AdjustSizeAndLocation(int screenHeight,
int screenRight, int taskbarHeight,
internal void AdjustSizeAndLocation(
int screenHeight,
int screenRight,
int taskbarHeight,
Menu menuPredecessor = null,
bool directionToRight = false)
{
@ -264,6 +274,7 @@ namespace SystemTrayMenu.UserInterface
{
row.Height = dgv.RowTemplate.Height;
}
dgv.Tag = true;
}
}
@ -275,6 +286,7 @@ namespace SystemTrayMenu.UserInterface
{
row.Height = dgv.RowTemplate.Height;
}
dgv.Tag = true;
}
}
@ -310,15 +322,13 @@ namespace SystemTrayMenu.UserInterface
{
x = menuPredecessor.Location.X +
menuPredecessor.Width -
(int)Math.Round(Scaling.Factor, 0,
MidpointRounding.AwayFromZero);
(int)Math.Round(Scaling.Factor, 0, MidpointRounding.AwayFromZero);
}
else
{
x = menuPredecessor.Location.X -
Width +
(int)Math.Round(Scaling.Factor, 0,
MidpointRounding.AwayFromZero);
(int)Math.Round(Scaling.Factor, 0, MidpointRounding.AwayFromZero);
}
}
@ -344,6 +354,7 @@ namespace SystemTrayMenu.UserInterface
0, trigger.RowIndex, false);
distanceFromItemToDgvTop = cellRectangle.Top;
}
y = menuPredecessor.Location.Y +
menuPredecessor.dgv.Location.Y +
distanceFromItemToDgvTop;
@ -375,11 +386,15 @@ namespace SystemTrayMenu.UserInterface
dgv.Width = newWidth;
}
//Only scaling correct with Sans Serif for textBoxSearch. Workaround:
textBoxSearch.Font = new Font("Segoe UI", 8.25F * Scaling.Factor,
FontStyle.Regular, GraphicsUnit.Point, 0);
// Only scaling correct with Sans Serif for textBoxSearch. Workaround:
textBoxSearch.Font = new Font(
"Segoe UI",
8.25F * Scaling.Factor,
FontStyle.Regular,
GraphicsUnit.Point,
0);
//Ancor not working like in the label
// Ancor not working like in the label
textBoxSearch.Width = newWidth -
pictureBoxSearch.Width -
pictureBoxSearch.Margin.Horizontal -
@ -487,6 +502,7 @@ namespace SystemTrayMenu.UserInterface
default:
break;
}
return base.ProcessCmdKey(ref msg, keys);
}
@ -496,8 +512,11 @@ namespace SystemTrayMenu.UserInterface
string filterField = dgv.Columns[1].Name;
SearchTextChanging?.Invoke();
data.DefaultView.RowFilter = string.Format(CultureInfo.InvariantCulture,
"[{0}] LIKE '%{1}%'", filterField, textBoxSearch.Text);
data.DefaultView.RowFilter = string.Format(
CultureInfo.InvariantCulture,
"[{0}] LIKE '%{1}%'",
filterField,
textBoxSearch.Text);
foreach (DataGridViewRow row in dgv.Rows)
{
RowData rowData = (RowData)row.Cells[2].Value;

View file

@ -1,16 +1,20 @@
using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Reflection;
using System.Text;
using System.Windows.Forms;
using SystemTrayMenu.UserInterface.Controls;
using SystemTrayMenu.Utilities;
using static SystemTrayMenu.UserInterface.Controls.HotkeyControl;
// <copyright file="SettingsForm.cs" company="TAMAHO">
// Copyright (c) TAMAHO. All rights reserved.
// </copyright>
namespace SystemTrayMenu.UserInterface
{
using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Reflection;
using System.Text;
using System.Windows.Forms;
using SystemTrayMenu.UserInterface.Controls;
using SystemTrayMenu.Utilities;
using static SystemTrayMenu.UserInterface.Controls.HotkeyControl;
public partial class SettingsForm : Form
{
public string NewHotKey => newHotKey;
@ -61,7 +65,7 @@ namespace SystemTrayMenu.UserInterface
List<Language> dataSource = new List<Language>
{
new Language() { Name = "English", Value = "en" },
new Language() { Name = "Deutsch", Value = "de" }
new Language() { Name = "Deutsch", Value = "de" },
};
comboBoxLanguage.DataSource = dataSource;
comboBoxLanguage.DisplayMember = "Name";
@ -172,15 +176,15 @@ namespace SystemTrayMenu.UserInterface
{
return base.ProcessCmdKey(ref msg, keyData);
}
break;
default:
return base.ProcessCmdKey(ref msg, keyData);
}
return true;
}
#region hotkeys
/// <summary>
/// Helper method to cleanly register a hotkey
/// </summary>
@ -197,20 +201,16 @@ namespace SystemTrayMenu.UserInterface
{
if (HotkeyControl.RegisterHotKey(modifierKeyCode, virtualKeyCode, handler) < 0)
{
//LOG.DebugFormat("Failed to register {0} to hotkey: {1}", functionName, hotkeyString);
if (failedKeys.Length > 0)
{
failedKeys.Append(", ");
}
failedKeys.Append(hotkeyString);
return false;
}
//LOG.DebugFormat("Registered {0} to hotkey: {1}", functionName, hotkeyString);
}
else
{
//LOG.InfoFormat("Skipping hotkey registration for {0}, no hotkey set!", functionName);
}
return true;
}
@ -220,7 +220,7 @@ namespace SystemTrayMenu.UserInterface
//try
//{
bool success = RegisterHotkey(failedKeys,
//hotkeyValue.Value.ToString(),
//hotkeyValue.Value.ToString(),
Properties.Settings.Default.HotKey,
handler);
//if (!success && ignoreFailedRegistration)
@ -240,7 +240,7 @@ namespace SystemTrayMenu.UserInterface
// //hotkeyValue.UseValueOrDefault(null);
// //hotkeyValue.ContainingIniSection.IsDirty = true;
// return RegisterHotkey(failedKeys,
// //hotkeyValue.Value.ToString(),
// //hotkeyValue.Value.ToString(),
// Properties.Settings.Default.HotKey,
// handler);
//}
@ -279,15 +279,8 @@ namespace SystemTrayMenu.UserInterface
{
success = HandleFailedHotkeyRegistration(failedKeys.ToString());
}
else
{
// if failures have been ignored, the config has probably been updated
//if (_conf.IsDirty)
//{
// IniConfig.Save();
//}
}
}
return success || ignoreFailedRegistration;
}
@ -321,7 +314,7 @@ namespace SystemTrayMenu.UserInterface
//}
/// <summary>
/// Displays a dialog for the user to choose how to handle hotkey registration failures:
/// Displays a dialog for the user to choose how to handle hotkey registration failures:
/// retry (allowing to shut down the conflicting application before),
/// ignore (not registering the conflicting hotkey and resetting the respective config to "None", i.e. not trying to register it again on next startup)
/// abort (do nothing about it)
@ -346,9 +339,9 @@ namespace SystemTrayMenu.UserInterface
HotkeyControl.UnregisterHotkeys();
success = RegisterHotkeys(true);
}
return success;
}
#endregion
}
public class Language

View file

@ -1,27 +1,27 @@
using System;
using System.Drawing;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;
using SystemTrayMenu.Helper;
namespace SystemTrayMenu.Utilities
namespace SystemTrayMenu.Utilities
{
using System;
using System.Drawing;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;
using SystemTrayMenu.Helper;
/// <summary>
/// "Stand-alone" shell context menu
///
///
/// It isn't really debugged but is mostly working.
/// Create an instance and call ShowContextMenu with a list of FileInfo for the files.
/// Limitation is that it only handles files in the same directory but it can be fixed
/// by changing the way files are translated into PIDLs.
///
///
/// Based on FileBrowser in C# from CodeProject
/// http://www.codeproject.com/useritems/FileBrowser.asp
///
///
/// Hooking class taken from MSDN Magazine Cutting Edge column
/// http://msdn.microsoft.com/msdnmag/issues/02/10/CuttingEdge/
///
///
/// Andreas Johansson
/// afjohansson@hotmail.com
/// http://afjohansson.spaces.live.com
@ -34,23 +34,22 @@ namespace SystemTrayMenu.Utilities
/// </example>
public class ShellContextMenu : NativeWindow
{
#region Constructor
/// <summary>Default constructor</summary>
/// <summary>
/// Initializes a new instance of the <see cref="ShellContextMenu"/> class.
/// </summary>
public ShellContextMenu()
{
CreateHandle(new CreateParams());
}
#endregion
#region Destructor
/// <summary>Ensure all resources get released</summary>
/// <summary>
/// Finalizes an instance of the <see cref="ShellContextMenu"/> class.
/// </summary>
~ShellContextMenu()
{
ReleaseAll();
}
#endregion
#region GetContextMenuInterfaces()
/// <summary>Gets the interfaces to the context menu</summary>
/// <param name="oParentFolder">Parent folder</param>
/// <param name="arrPIDLs">PIDLs</param>
@ -89,47 +88,23 @@ namespace SystemTrayMenu.Utilities
return false;
}
}
#endregion
#region Override
/// <summary>
/// This method receives WindowMessages. It will make the "Open With" and "Send To" work
/// by calling HandleMenuMsg and HandleMenuMsg2. It will also call the OnContextMenuMouseHover
/// This method receives WindowMessages. It will make the "Open With" and "Send To" work
/// by calling HandleMenuMsg and HandleMenuMsg2. It will also call the OnContextMenuMouseHover
/// method of Browser when hovering over a ContextMenu item.
/// </summary>
/// <param name="m">the Message of the Browser's WndProc</param>
/// <returns>true if the message has been handled, false otherwise</returns>
protected override void WndProc(ref Message m)
{
#region IContextMenu
if (_oContextMenu != null &&
m.Msg == (int)WM.MENUSELECT &&
((int)ShellHelper.HiWord(m.WParam) & (int)MFT.SEPARATOR) == 0 &&
((int)ShellHelper.HiWord(m.WParam) & (int)MFT.POPUP) == 0)
{
//string info = string.Empty;
//if (ShellHelper.LoWord(m.WParam) == (int)CMD_CUSTOM.ExpandCollapse)
//{
// info = "Expands or collapses the current selected item";
//}
//else
//{
// info = "";/* ContextMenuHelper.GetCommandString(
// _oContextMenu,
// ShellHelper.LoWord(m.WParam) - CMD_FIRST,
// false);*/
//}
//br.OnContextMenuMouseHover(new ContextMenuMouseHoverEventArgs(info.ToString()));
}
#endregion
#region IContextMenu2
if (_oContextMenu2 != null &&
(m.Msg == (int)WM.INITMENUPOPUP ||
m.Msg == (int)WM.MEASUREITEM ||
@ -142,10 +117,6 @@ namespace SystemTrayMenu.Utilities
}
}
#endregion
#region IContextMenu3
if (_oContextMenu3 != null &&
m.Msg == (int)WM.MENUCHAR)
{
@ -156,14 +127,9 @@ namespace SystemTrayMenu.Utilities
}
}
#endregion
base.WndProc(ref m);
}
#endregion
#region InvokeCommand
private static void InvokeCommand(IContextMenu contextMenu, uint nCmd, string strFolder, Point pointInvoke)
{
CMINVOKECOMMANDINFOEX invoke = new CMINVOKECOMMANDINFOEX
@ -177,53 +143,54 @@ namespace SystemTrayMenu.Utilities
((Control.ModifierKeys & Keys.Control) != 0 ? CMIC.CONTROL_DOWN : 0) |
((Control.ModifierKeys & Keys.Shift) != 0 ? CMIC.SHIFT_DOWN : 0),
ptInvoke = new POINT(pointInvoke.X, pointInvoke.Y),
nShow = SW.SHOWNORMAL
nShow = SW.SHOWNORMAL,
};
_ = contextMenu.InvokeCommand(ref invoke);
}
#endregion
#region ReleaseAll()
/// <summary>
/// Release all allocated interfaces, PIDLs
/// Release all allocated interfaces, PIDLs.
/// </summary>
private void ReleaseAll()
{
if (null != _oContextMenu)
if (_oContextMenu != null)
{
Marshal.ReleaseComObject(_oContextMenu);
_oContextMenu = null;
}
if (null != _oContextMenu2)
if (_oContextMenu2 != null)
{
Marshal.ReleaseComObject(_oContextMenu2);
_oContextMenu2 = null;
}
if (null != _oContextMenu3)
if (_oContextMenu3 != null)
{
Marshal.ReleaseComObject(_oContextMenu3);
_oContextMenu3 = null;
}
if (null != _oDesktopFolder)
if (_oDesktopFolder != null)
{
Marshal.ReleaseComObject(_oDesktopFolder);
_oDesktopFolder = null;
}
if (null != _oParentFolder)
if (_oParentFolder != null)
{
Marshal.ReleaseComObject(_oParentFolder);
_oParentFolder = null;
}
if (null != _arrPIDLs)
if (_arrPIDLs != null)
{
FreePIDLs(_arrPIDLs);
_arrPIDLs = null;
}
}
#endregion
#region GetDesktopFolder()
/// <summary>
/// Gets the desktop folder
/// </summary>
@ -240,14 +207,13 @@ namespace SystemTrayMenu.Utilities
throw new ShellContextMenuException("Failed to get the desktop shell folder");
#pragma warning restore CA1303 //=> Exceptions not translated in logfile => OK
}
_oDesktopFolder = (IShellFolder)Marshal.GetTypedObjectForIUnknown(pUnkownDesktopFolder, typeof(IShellFolder));
}
return _oDesktopFolder;
}
#endregion
#region GetParentFolder()
/// <summary>
/// Gets the parent folder
/// </summary>
@ -288,14 +254,13 @@ namespace SystemTrayMenu.Utilities
{
return null;
}
_oParentFolder = (IShellFolder)Marshal.GetTypedObjectForIUnknown(pUnknownParentFolder, typeof(IShellFolder));
}
return _oParentFolder;
}
#endregion
#region GetPIDLs()
/// <summary>
/// Get the PIDLs
/// </summary>
@ -328,6 +293,7 @@ namespace SystemTrayMenu.Utilities
FreePIDLs(arrPIDLs);
return null;
}
arrPIDLs[n] = pPIDL;
n++;
}
@ -367,22 +333,21 @@ namespace SystemTrayMenu.Utilities
FreePIDLs(arrPIDLs);
return null;
}
arrPIDLs[n] = pPIDL;
n++;
}
return arrPIDLs;
}
#endregion
#region FreePIDLs()
/// <summary>
/// Free the PIDLs
/// </summary>
/// <param name="arrPIDLs">Array of PIDLs (IntPtr)</param>
protected static void FreePIDLs(IntPtr[] arrPIDLs)
{
if (null != arrPIDLs)
if (arrPIDLs != null)
{
for (int n = 0; n < arrPIDLs.Length; n++)
{
@ -394,9 +359,6 @@ namespace SystemTrayMenu.Utilities
}
}
}
#endregion
#region ShowContextMenu()
/// <summary>
/// Shows the context menu
@ -440,16 +402,13 @@ namespace SystemTrayMenu.Utilities
try
{
//Application.AddMessageFilter(this);
//_arrPIDLs = GetPIDLs(arrFI);
if (null == _arrPIDLs)
if (_arrPIDLs == null)
{
ReleaseAll();
return;
}
if (false == GetContextMenuInterfaces(_oParentFolder, _arrPIDLs, out iContextMenuPtr))
if (!GetContextMenuInterfaces(_oParentFolder, _arrPIDLs, out iContextMenuPtr))
{
ReleaseAll();
return;
@ -462,9 +421,7 @@ namespace SystemTrayMenu.Utilities
0,
CMD_FIRST,
CMD_LAST,
CMF.EXPLORE |
CMF.NORMAL |
((Control.ModifierKeys & Keys.Shift) != 0 ? CMF.EXTENDEDVERBS : 0));
CMF.EXPLORE | CMF.NORMAL | ((Control.ModifierKeys & Keys.Shift) != 0 ? CMF.EXTENDEDVERBS : 0));
Marshal.QueryInterface(iContextMenuPtr, ref IID_IContextMenu2, out iContextMenuPtr2);
Marshal.QueryInterface(iContextMenuPtr, ref IID_IContextMenu3, out iContextMenuPtr3);
@ -472,8 +429,6 @@ namespace SystemTrayMenu.Utilities
_oContextMenu2 = (IContextMenu2)Marshal.GetTypedObjectForIUnknown(iContextMenuPtr2, typeof(IContextMenu2));
_oContextMenu3 = (IContextMenu3)Marshal.GetTypedObjectForIUnknown(iContextMenuPtr3, typeof(IContextMenu3));
//hook.Install();
uint nSelected = DllImports.NativeMethods.User32TrackPopupMenuEx(
pMenu,
DllImports.NativeMethods.TPM.RETURNCMD,
@ -496,7 +451,6 @@ namespace SystemTrayMenu.Utilities
}
finally
{
//hook.Uninstall();
if (pMenu != IntPtr.Zero)
{
DllImports.NativeMethods.User32DestroyMenu(pMenu);
@ -520,9 +474,7 @@ namespace SystemTrayMenu.Utilities
ReleaseAll();
}
}
#endregion
#region Local variabled
private IContextMenu _oContextMenu;
private IContextMenu2 _oContextMenu2;
private IContextMenu3 _oContextMenu3;
@ -530,9 +482,6 @@ namespace SystemTrayMenu.Utilities
private IShellFolder _oParentFolder;
private IntPtr[] _arrPIDLs;
private string _strParentFolder;
#endregion
#region Variables and Constants
private const int MAX_PATH = 260;
private const uint CMD_FIRST = 1;
@ -543,19 +492,11 @@ namespace SystemTrayMenu.Utilities
private static readonly int cbMenuItemInfo = Marshal.SizeOf(typeof(MENUITEMINFO));
private static readonly int cbInvokeCommand = Marshal.SizeOf(typeof(CMINVOKECOMMANDINFOEX));
#endregion
#region Shell GUIDs
private static Guid IID_IShellFolder = new Guid("{000214E6-0000-0000-C000-000000000046}");
private static Guid IID_IContextMenu = new Guid("{000214e4-0000-0000-c000-000000000046}");
private static Guid IID_IContextMenu2 = new Guid("{000214f4-0000-0000-c000-000000000046}");
private static Guid IID_IContextMenu3 = new Guid("{bcfce0a0-ec17-11d0-8d10-00a0c90f2719}");
#endregion
#region Structs
[StructLayout(LayoutKind.Sequential)]
private struct CWPSTRUCT
{
@ -627,7 +568,7 @@ namespace SystemTrayMenu.Utilities
public IntPtr hbmpItem;
}
// A generalized global memory handle used for data transfer operations by the
// A generalized global memory handle used for data transfer operations by the
// IAdviseSink, IDataObject, and IOleCache interfaces
[StructLayout(LayoutKind.Sequential)]
private struct STGMEDIUM
@ -657,11 +598,7 @@ namespace SystemTrayMenu.Utilities
public int y;
}
#endregion
#region Enums
// Defines the values used with the IShellFolder::GetDisplayNameOf and IShellFolder::SetNameOf
// Defines the values used with the IShellFolder::GetDisplayNameOf and IShellFolder::SetNameOf
// methods to specify the type of file or folder names used by those methods
[Flags]
private enum SHGNO
@ -670,7 +607,7 @@ namespace SystemTrayMenu.Utilities
INFOLDER = 0x0001,
FOREDITING = 0x1000,
FORADDRESSBAR = 0x4000,
FORPARSING = 0x8000
FORPARSING = 0x8000,
}
// The attributes that the caller is requesting, when calling IShellFolder::GetAttributesOf
@ -681,12 +618,12 @@ namespace SystemTrayMenu.Utilities
CANCOPY = 1,
CANDELETE = 0x20,
CANLINK = 4,
CANMONIKER = 0x400000,
CANMONIKER = 0x400000, // HASSTORAGE = 0x400000, //STREAM = 0x400000,
CANMOVE = 2,
CANRENAME = 0x10,
CAPABILITYMASK = 0x177,
COMPRESSED = 0x4000000,
CONTENTSMASK = 0x80000000,
CONTENTSMASK = 0x80000000, // HASSUBFOLDER = 0x80000000,
DISPLAYATTRMASK = 0xfc000,
DROPTARGET = 0x100,
ENCRYPTED = 0x2000,
@ -695,8 +632,6 @@ namespace SystemTrayMenu.Utilities
FOLDER = 0x20000000,
GHOSTED = 0x8000,
HASPROPSHEET = 0x40,
//HASSTORAGE = 0x400000,
//HASSUBFOLDER = 0x80000000,
HIDDEN = 0x80000,
ISSLOW = 0x4000,
LINK = 0x10000,
@ -708,11 +643,10 @@ namespace SystemTrayMenu.Utilities
STORAGE = 8,
STORAGEANCESTOR = 0x800000,
STORAGECAPMASK = 0x70c50008,
//STREAM = 0x400000,
VALIDATE = 0x1000000
VALIDATE = 0x1000000,
}
// Determines the type of items included in an enumeration.
// Determines the type of items included in an enumeration.
// These values are used with the IShellFolder::EnumObjects method
[Flags]
private enum SHCONTF
@ -739,7 +673,7 @@ namespace SystemTrayMenu.Utilities
NODEFAULT = 0x00000020,
INCLUDESTATIC = 0x00000040,
EXTENDEDVERBS = 0x00000100,
RESERVED = 0xffff0000
RESERVED = 0xffff0000,
}
// Flags specifying the information to return when calling IContextMenu::GetCommandString
@ -751,13 +685,13 @@ namespace SystemTrayMenu.Utilities
VALIDATEA = 2,
VERBW = 4,
HELPTEXTW = 5,
VALIDATEW = 6
VALIDATEW = 6,
}
// The cmd for a custom added menu item
private enum CMD_CUSTOM
{
ExpandCollapse = (int)CMD_LAST + 1
ExpandCollapse = (int)CMD_LAST + 1,
}
// Flags used with the CMINVOKECOMMANDINFOEX structure
@ -774,7 +708,7 @@ namespace SystemTrayMenu.Utilities
SHIFT_DOWN = 0x10000000,
CONTROL_DOWN = 0x40000000,
FLAG_LOG_USAGE = 0x04000000,
PTINVOKE = 0x20000000
PTINVOKE = 0x20000000,
}
// Specifies how the window is to be shown
@ -782,11 +716,9 @@ namespace SystemTrayMenu.Utilities
private enum SW
{
HIDE = 0,
SHOWNORMAL = 1,
//NORMAL = 1,
SHOWNORMAL = 1, // NORMAL = 1,
SHOWMINIMIZED = 2,
SHOWMAXIMIZED = 3,
//MAXIMIZE = 3,
SHOWMAXIMIZED = 3, // MAXIMIZE = 3,
SHOWNOACTIVATE = 4,
SHOW = 5,
MINIMIZE = 6,
@ -866,12 +798,11 @@ namespace SystemTrayMenu.Utilities
HSCROLLCLIPBOARD = 0x30E,
ICONERASEBKGND = 0x27,
IME_CHAR = 0x286,
IME_COMPOSITION = 0x10F,
IME_COMPOSITION = 0x10F, // IME_KEYLAST = 0x10F,
IME_COMPOSITIONFULL = 0x284,
IME_CONTROL = 0x283,
IME_ENDCOMPOSITION = 0x10E,
IME_KEYDOWN = 0x290,
//IME_KEYLAST = 0x10F,
IME_KEYUP = 0x291,
IME_NOTIFY = 0x282,
IME_REQUEST = 0x288,
@ -1008,7 +939,7 @@ namespace SystemTrayMenu.Utilities
WINDOWPOSCHANGED = 0x47,
WINDOWPOSCHANGING = 0x46,
//WININICHANGE = 0x1A,
SH_NOTIFY = 0x0401
SH_NOTIFY = 0x0401,
}
// Specifies the content of the new menu item
@ -1027,7 +958,7 @@ namespace SystemTrayMenu.Utilities
RIGHTORDER = 0x00002000,
BYCOMMAND = 0x00000000,
BYPOSITION = 0x00000400,
POPUP = 0x00000010
POPUP = 0x00000010,
}
// Specifies the state of the new menu item
@ -1041,7 +972,7 @@ namespace SystemTrayMenu.Utilities
ENABLED = 0x00000000,
//UNCHECKED = 0x00000000,
//UNHILITE = 0x00000000,
DEFAULT = 0x00001000
DEFAULT = 0x00001000,
}
// Specifies the content of the new menu item
@ -1056,7 +987,7 @@ namespace SystemTrayMenu.Utilities
STATE = 0x01,
STRING = 0x40,
SUBMENU = 0x04,
TYPE = 0x10
TYPE = 0x10,
}
// Indicates the type of storage medium being used in a data transfer
@ -1070,12 +1001,9 @@ namespace SystemTrayMenu.Utilities
ISTORAGE = 8,
ISTREAM = 4,
MFPICT = 0x20,
NULL = 0
NULL = 0,
}
#endregion
#region IShellFolder
[ComImport]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[Guid("000214E6-0000-0000-C000-000000000046")]
@ -1111,7 +1039,7 @@ namespace SystemTrayMenu.Utilities
ref Guid riid,
out IntPtr ppv);
// Requests a pointer to an object's storage interface.
// Requests a pointer to an object's storage interface.
// Return value: error code, if any
[PreserveSig]
int BindToStorage(
@ -1125,11 +1053,11 @@ namespace SystemTrayMenu.Utilities
// CODE field of the HRESULT contains one of the following values (the code
// can be retrived using the helper function GetHResultCode): Negative A
// negative return value indicates that the first item should precede
// the second (pidl1 < pidl2).
// the second (pidl1 < pidl2).
// Positive A positive return value indicates that the first item should
// follow the second (pidl1 > pidl2). Zero A return value of zero
// indicates that the two items are the same (pidl1 = pidl2).
// indicates that the two items are the same (pidl1 = pidl2).
[PreserveSig]
int CompareIDs(
IntPtr lParam,
@ -1145,7 +1073,7 @@ namespace SystemTrayMenu.Utilities
Guid riid,
out IntPtr ppv);
// Retrieves the attributes of one or more file objects or subfolders.
// Retrieves the attributes of one or more file objects or subfolders.
// Return value: error code, if any
[PreserveSig]
int GetAttributesOf(
@ -1167,7 +1095,7 @@ namespace SystemTrayMenu.Utilities
IntPtr rgfReserved,
out IntPtr ppv);
// Retrieves the display name for the specified file object or subfolder.
// Retrieves the display name for the specified file object or subfolder.
// Return value: error code, if any
[PreserveSig()]
int GetDisplayNameOf(
@ -1187,9 +1115,7 @@ namespace SystemTrayMenu.Utilities
SHGNO uFlags,
out IntPtr ppidlOut);
}
#endregion
#region IContextMenu
[ComImport()]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[GuidAttribute("000214e4-0000-0000-c000-000000000046")]
@ -1209,8 +1135,8 @@ namespace SystemTrayMenu.Utilities
int InvokeCommand(
ref CMINVOKECOMMANDINFOEX info);
// Retrieves information about a shortcut menu command,
// including the help string and the language-independent,
// Retrieves information about a shortcut menu command,
// including the help string and the language-independent,
// or canonical, name for the command
[PreserveSig()]
int GetCommandString(
@ -1240,8 +1166,8 @@ namespace SystemTrayMenu.Utilities
int InvokeCommand(
ref CMINVOKECOMMANDINFOEX info);
// Retrieves information about a shortcut menu command,
// including the help string and the language-independent,
// Retrieves information about a shortcut menu command,
// including the help string and the language-independent,
// or canonical, name for the command
[PreserveSig()]
int GetCommandString(
@ -1252,7 +1178,7 @@ namespace SystemTrayMenu.Utilities
StringBuilder commandstring,
int cch);
// Allows client objects of the IContextMenu interface to
// Allows client objects of the IContextMenu interface to
// handle messages associated with owner-drawn menu items
[PreserveSig]
int HandleMenuMsg(
@ -1279,8 +1205,8 @@ namespace SystemTrayMenu.Utilities
int InvokeCommand(
ref CMINVOKECOMMANDINFOEX info);
// Retrieves information about a shortcut menu command,
// including the help string and the language-independent,
// Retrieves information about a shortcut menu command,
// including the help string and the language-independent,
// or canonical, name for the command
[PreserveSig()]
int GetCommandString(
@ -1291,7 +1217,7 @@ namespace SystemTrayMenu.Utilities
StringBuilder commandstring,
int cch);
// Allows client objects of the IContextMenu interface to
// Allows client objects of the IContextMenu interface to
// handle messages associated with owner-drawn menu items
[PreserveSig]
int HandleMenuMsg(
@ -1299,7 +1225,7 @@ namespace SystemTrayMenu.Utilities
IntPtr wParam,
IntPtr lParam);
// Allows client objects of the IContextMenu3 interface to
// Allows client objects of the IContextMenu3 interface to
// handle messages associated with owner-drawn menu items
[PreserveSig]
int HandleMenuMsg2(
@ -1308,6 +1234,5 @@ namespace SystemTrayMenu.Utilities
IntPtr lParam,
IntPtr plResult);
}
#endregion
}
}

View file

@ -1,8 +1,11 @@
using System;
using System.Runtime.Serialization;
// <copyright file="ShellContextMenuException.cs" company="PlaceholderCompany">
// Copyright (c) PlaceholderCompany. All rights reserved.
// </copyright>
namespace SystemTrayMenu.Helper
{
using System;
using System.Runtime.Serialization;
[Serializable]
public class ShellContextMenuException : Exception
{
@ -11,19 +14,22 @@ namespace SystemTrayMenu.Helper
// Add any type-specific logic, and supply the default message.
}
public ShellContextMenuException(string message) : base(message)
public ShellContextMenuException(string message)
: base(message)
{
// Add any type-specific logic.
}
public ShellContextMenuException(string message, Exception innerException) :
base(message, innerException)
public ShellContextMenuException(string message, Exception innerException)
: base(message, innerException)
{
// Add any type-specific logic for inner exceptions.
}
protected ShellContextMenuException(SerializationInfo info,
StreamingContext context) : base(info, context)
protected ShellContextMenuException(
SerializationInfo info,
StreamingContext context)
: base(info, context)
{
// Implement type-specific serialization constructor logic.
}

View file

@ -1,11 +1,12 @@
using System;
// <copyright file="ShellHelper.cs" company="PlaceholderCompany">
// Copyright (c) PlaceholderCompany. All rights reserved.
// </copyright>
namespace SystemTrayMenu.Helper
{
using System;
internal static class ShellHelper
{
#region Low/High Word
/// <summary>
/// Retrieves the High Word of a WParam of a WindowMessage
/// </summary>
@ -16,7 +17,7 @@ namespace SystemTrayMenu.Helper
uint param32 = (uint)(ptr.ToInt64() | 0xffffffffL);
if ((param32 & 0x80000000) == 0x80000000)
{
return (param32 >> 16);
return param32 >> 16;
}
else
{
@ -32,9 +33,7 @@ namespace SystemTrayMenu.Helper
public static uint LoWord(IntPtr ptr)
{
uint param32 = (uint)(ptr.ToInt64() | 0xffffffffL);
return (param32 & 0xffff);
return param32 & 0xffff;
}
#endregion
}
}

View file

@ -1,8 +1,11 @@
using System.Drawing;
using System.Windows.Forms;
// <copyright file="TaskbarForm.cs" company="PlaceholderCompany">
// Copyright (c) PlaceholderCompany. All rights reserved.
// </copyright>
namespace SystemTrayMenu.UserInterface
{
using System.Drawing;
using System.Windows.Forms;
public partial class TaskbarForm : Form
{
public TaskbarForm()

View file

@ -1,10 +1,13 @@
using System;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Windows.Forms;
// <copyright file="AppRestart.cs" company="PlaceholderCompany">
// Copyright (c) PlaceholderCompany. All rights reserved.
// </copyright>
namespace SystemTrayMenu.Utilities
{
using System;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Windows.Forms;
internal class AppRestart
{
public static event EventHandlerEmpty BeforeRestarting;
@ -21,7 +24,8 @@ namespace SystemTrayMenu.Utilities
Process.GetCurrentProcess().
MainModule.FileName);
p.Start();
};
}
Application.Exit();
}

View file

@ -1,10 +1,14 @@
using System.Data;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;
// <copyright file="DataGridViewExtensions.cs" company="PlaceholderCompany">
// Copyright (c) PlaceholderCompany. All rights reserved.
// </copyright>
namespace SystemTrayMenu.Utilities
{
using System.Data;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;
internal static class DataGridViewExtensions
{
/// <summary>
@ -15,36 +19,36 @@ namespace SystemTrayMenu.Utilities
{
System.Collections.Generic.IEnumerable<DataGridViewRow> rows =
dgv.Rows.Cast<DataGridViewRow>();
using (Graphics gfx = dgv.CreateGraphics())
using Graphics gfx = dgv.CreateGraphics();
int i = 1;
gfx.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
float widthMax = dgv.Columns[i].HeaderCell.Size.Width;
foreach (DataGridViewRow row in rows)
{
int i = 1;
gfx.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
float widthMax = dgv.Columns[i].HeaderCell.Size.Width;
foreach (DataGridViewRow row in rows)
float checkWidth = gfx.MeasureString(
row.Cells[i].Value.ToString() + "_",
dgv.RowTemplate.DefaultCellStyle.Font
).Width * Scaling.Factor;
if (checkWidth > widthMax)
{
float checkWidth = gfx.MeasureString(
row.Cells[i].Value.ToString() + "_",
dgv.RowTemplate.DefaultCellStyle.Font
).Width * Scaling.Factor;
if (checkWidth > widthMax)
{
widthMax = checkWidth;
}
widthMax = checkWidth;
}
if (widthMax > MenuDefines.MaxMenuWidth)
{
widthMax = MenuDefines.MaxMenuWidth;
}
dgv.Columns[i].Width = (int)(widthMax + 0.5);
string stringWithWidthLikeIcon = "____";
#pragma warning disable CA1303 // Do not pass literals as localized parameters
float Width0 = gfx.MeasureString(stringWithWidthLikeIcon,
#pragma warning restore CA1303 // Do not pass literals as localized parameters
dgv.RowTemplate.DefaultCellStyle.Font
).Width * Scaling.Factor;
dgv.Columns[0].Width = (int)Width0;
}
if (widthMax > MenuDefines.MaxMenuWidth)
{
widthMax = MenuDefines.MaxMenuWidth;
}
dgv.Columns[i].Width = (int)(widthMax + 0.5);
#pragma warning disable CA1303 // Do not pass literals as localized parameters
string stringWithWidthLikeIcon = "____";
float width0 = gfx.MeasureString(
stringWithWidthLikeIcon,
#pragma warning restore CA1303 // Do not pass literals as localized parameters
dgv.RowTemplate.DefaultCellStyle.Font).Width * Scaling.Factor;
dgv.Columns[0].Width = (int)width0;
}
}
}

View file

@ -1,9 +1,12 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
// <copyright file="FileIni.cs" company="PlaceholderCompany">
// Copyright (c) PlaceholderCompany. All rights reserved.
// </copyright>
namespace SystemTrayMenu.Utilities
{
using System.Collections.Generic;
using System.IO;
using System.Linq;
public class FileIni
{
private readonly Dictionary<string, string> values;
@ -16,12 +19,14 @@ namespace SystemTrayMenu.Utilities
.ToDictionary(parts => parts[0].Trim(), parts =>
parts.Length > 1 ? parts[1].Trim() : null);
}
public string Value(string name, string value = null)
{
if (values != null && values.ContainsKey(name))
{
return values[name];
}
return value;
}
}

View file

@ -1,11 +1,11 @@
using Shell32;
using System;
using System.IO;
using System.Threading;
namespace SystemTrayMenu.Utilities
namespace SystemTrayMenu.Utilities
{
internal class LnkHelper
using Shell32;
using System;
using System.IO;
using System.Threading;
internal class FileLnk
{
public static string GetResolvedFileName(string shortcutFilename)
{
@ -21,6 +21,7 @@ namespace SystemTrayMenu.Utilities
{
resolvedFilename = GetShortcutFileNamePath(shortcutFilename);
}
staThread.SetApartmentState(ApartmentState.STA);
staThread.Start(shortcutFilename);
staThread.Join();

View file

@ -1,7 +1,11 @@
using Microsoft.Win32;
// <copyright file="FileUrl.cs" company="PlaceholderCompany">
// Copyright (c) PlaceholderCompany. All rights reserved.
// </copyright>
namespace SystemTrayMenu.Utilities
{
using Microsoft.Win32;
public static class FileUrl
{
private static string browserPath = string.Empty;
@ -10,7 +14,7 @@ namespace SystemTrayMenu.Utilities
string urlAssociation = @"Software\Microsoft\Windows\Shell\Associations\UrlAssociations\http";
string browserPathKey = @"$BROWSER$\shell\open\command";
RegistryKey userChoiceKey = null;
RegistryKey userChoiceKey;
string browserPath = FileUrl.browserPath;
if (string.IsNullOrEmpty(browserPath))
@ -31,6 +35,7 @@ namespace SystemTrayMenu.Utilities
Registry.CurrentUser.OpenSubKey(
urlAssociation, false);
}
string path = CleanifyBrowserPath(browserKey.GetValue(null) as string);
browserKey.Close();
return path;
@ -38,7 +43,7 @@ namespace SystemTrayMenu.Utilities
else
{
// user defined browser choice was found
string progId = (userChoiceKey.GetValue("ProgId").ToString());
string progId = userChoiceKey.GetValue("ProgId").ToString();
userChoiceKey.Close();
// now look up the path of the executable

View file

@ -1,13 +1,17 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Runtime.InteropServices;
// <copyright file="IconReader.cs" company="PlaceholderCompany">
// Copyright (c) PlaceholderCompany. All rights reserved.
// </copyright>
namespace SystemTrayMenu.Utilities
{
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Runtime.InteropServices;
// from https://www.codeproject.com/Articles/2532/Obtaining-and-managing-file-and-folder-icons-using
// added ImageList_GetIcon, IconCache, AddIconOverlay
@ -23,14 +27,14 @@ namespace SystemTrayMenu.Utilities
private static readonly object readIcon = new object();
public enum IconSize
{
Large = 0, //32x32 pixels
Small = 1 //16x16 pixels
Large = 0, // 32x32 pixels
Small = 1, // 16x16 pixels
}
public enum FolderType
{
Open = 0,
Closed = 1
Closed = 1,
}
public static void Dispose()
@ -41,8 +45,7 @@ namespace SystemTrayMenu.Utilities
}
}
public static Icon GetFileIconWithCache(string filePath, bool linkOverlay,
IconSize size = IconSize.Small)
public static Icon GetFileIconWithCache(string filePath, bool linkOverlay, IconSize size = IconSize.Small)
{
Icon icon = null;
string extension = Path.GetExtension(filePath);
@ -74,26 +77,23 @@ namespace SystemTrayMenu.Utilities
{
isExtensionWitSameIcon = false;
}
return isExtensionWitSameIcon;
}
private static Icon GetFileIcon(string filePath, bool linkOverlay,
IconSize size = IconSize.Small)
private static Icon GetFileIcon(string filePath, bool linkOverlay, IconSize size = IconSize.Small)
{
Icon icon = null;
DllImports.NativeMethods.SHFILEINFO shfi = new DllImports.NativeMethods.SHFILEINFO();
uint flags = DllImports.NativeMethods.ShgfiIcon | DllImports.NativeMethods.ShgfiSYSICONINDEX;
//MH: Removed, otherwise wrong icon
// | Shell32.SHGFI_USEFILEATTRIBUTES ;
if (true == linkOverlay)
if (linkOverlay)
{
flags += DllImports.NativeMethods.ShgfiLINKOVERLAY;
}
/* Check the size specified for return. */
if (IconSize.Small == size)
if (size == IconSize.Small)
{
flags += DllImports.NativeMethods.ShgfiSMALLICON;
}
@ -144,29 +144,31 @@ namespace SystemTrayMenu.Utilities
return icon;
}
public static Icon GetFolderIcon(string directoryPath,
FolderType folderType, bool linkOverlay,
public static Icon GetFolderIcon(
string directoryPath,
FolderType folderType,
bool linkOverlay,
IconSize size = IconSize.Small)
{
Icon icon = null;
// Need to add size check, although errors generated at present!
//uint flags = Shell32.SHGFI_ICON | Shell32.SHGFI_USEFILEATTRIBUTES;
// uint flags = Shell32.SHGFI_ICON | Shell32.SHGFI_USEFILEATTRIBUTES;
//MH: Removed SHGFI_USEFILEATTRIBUTES, otherwise was wrong folder icon
// MH: Removed SHGFI_USEFILEATTRIBUTES, otherwise was wrong folder icon
uint flags = DllImports.NativeMethods.ShgfiIcon; // | Shell32.SHGFI_USEFILEATTRIBUTES;
if (true == linkOverlay)
if (linkOverlay)
{
flags += DllImports.NativeMethods.ShgfiLINKOVERLAY;
}
if (FolderType.Open == folderType)
if (folderType == FolderType.Open)
{
flags += DllImports.NativeMethods.ShgfiOPENICON;
}
if (IconSize.Small == size)
if (size == IconSize.Small)
{
flags += DllImports.NativeMethods.ShgfiSMALLICON;
}
@ -207,7 +209,8 @@ namespace SystemTrayMenu.Utilities
if (originalIcon != null)
{
using Bitmap target = new Bitmap(
originalIcon.Width, originalIcon.Height,
originalIcon.Width,
originalIcon.Height,
PixelFormat.Format32bppArgb);
Graphics graphics = Graphics.FromImage(target);
graphics.DrawIcon(originalIcon, 0, 0);

View file

@ -1,11 +1,14 @@
using Shell32;
using System;
using System.IO;
using System.Reflection;
using System.Runtime.InteropServices;
// <copyright file="FolderOptions.cs" company="PlaceholderCompany">
// Copyright (c) PlaceholderCompany. All rights reserved.
// </copyright>
namespace SystemTrayMenu.Utilities
{
using Shell32;
using System;
using System.IO;
using System.Reflection;
using System.Runtime.InteropServices;
internal static class FolderOptions
{
private static bool hideHiddenEntries = false;

View file

@ -1,16 +1,19 @@
using Clearcove.Logging;
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Windows.Forms;
// <copyright file="Log.cs" company="PlaceholderCompany">
// Copyright (c) PlaceholderCompany. All rights reserved.
// </copyright>
namespace SystemTrayMenu.Utilities
{
using Clearcove.Logging;
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Windows.Forms;
internal static class Log
{
private static readonly Logger log = new Logger("");
private static readonly Logger log = new Logger(string.Empty);
internal static void Initialize()
{
Logger.Start(new FileInfo(GetLogFilePath()));
@ -26,16 +29,10 @@ namespace SystemTrayMenu.Utilities
log.Warn($"{message}{Environment.NewLine}{ex}");
}
//internal static void Debug(string message)
//{
// log.Debug($"{message}{Environment.NewLine}" +
// $"{Environment.StackTrace.ToString()}");
//}
internal static void Error(string message, Exception ex)
{
log.Error($"{message}{Environment.NewLine}" +
$"{ex.ToString()}");
$"{ex}");
}
internal static string GetLogFilePath()
@ -77,15 +74,15 @@ namespace SystemTrayMenu.Utilities
{
try
{
using (Process p = new Process())
using Process p = new Process
{
p.StartInfo = new ProcessStartInfo(fileName)
StartInfo = new ProcessStartInfo(fileName)
{
Arguments = arguments,
UseShellExecute = true
};
p.Start();
UseShellExecute = true,
}
};
p.Start();
}
catch (Exception ex)
{

View file

@ -1,8 +1,11 @@
using System;
using System.Drawing;
// <copyright file="Scaling.cs" company="PlaceholderCompany">
// Copyright (c) PlaceholderCompany. All rights reserved.
// </copyright>
namespace SystemTrayMenu.Utilities
{
using System;
using System.Drawing;
internal static class Scaling
{
internal static float Factor = 1;
@ -17,7 +20,7 @@ namespace SystemTrayMenu.Utilities
{
CalculateScalingFactor();
SetProcessDPIAwareWhenNecessary();
void SetProcessDPIAwareWhenNecessary()
static void SetProcessDPIAwareWhenNecessary()
{
if (Environment.OSVersion.Version.Major >= 6)
{

View file

@ -1,10 +1,13 @@
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
// <copyright file="SingleAppInstance.cs" company="PlaceholderCompany">
// Copyright (c) PlaceholderCompany. All rights reserved.
// </copyright>
namespace SystemTrayMenu.Utilities
{
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
internal static class SingleAppInstance
{
internal static void Initialize()
@ -27,6 +30,7 @@ namespace SystemTrayMenu.Utilities
{
p.Kill();
}
p.WaitForExit();
p.Close();
killedAProcess = true;
@ -48,9 +52,9 @@ namespace SystemTrayMenu.Utilities
return killedAProcess;
}
}
bool IsAnyOtherInstancesofAppAlreadyRunning()
static bool IsAnyOtherInstancesofAppAlreadyRunning()
{
//string pid = Process.Id.ToString();
foreach (Process p in Process.GetProcessesByName(
Process.GetCurrentProcess().ProcessName).
Where(s => s.Id != Process.GetCurrentProcess().Id))

View file

@ -1,10 +1,14 @@
using System.Globalization;
using System.Resources;
using SystemTrayMenu.Properties;
using SystemTrayMenu.UserInterface;
// <copyright file="Translator.cs" company="PlaceholderCompany">
// Copyright (c) PlaceholderCompany. All rights reserved.
// </copyright>
namespace SystemTrayMenu.Utilities
{
using System.Globalization;
using System.Resources;
using SystemTrayMenu.Properties;
using SystemTrayMenu.UserInterface;
internal static class Translator
{
internal static CultureInfo Culture;

14
stylecop.json Normal file
View file

@ -0,0 +1,14 @@
{
// ACTION REQUIRED: This file was automatically added to your project, but it
// will not take effect until additional steps are taken to enable it. See the
// following page for additional information:
//
// https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/EnableConfiguration.md
"$schema": "https://raw.githubusercontent.com/DotNetAnalyzers/StyleCopAnalyzers/master/StyleCop.Analyzers/StyleCop.Analyzers/Settings/stylecop.schema.json",
"settings": {
"documentationRules": {
"companyName": "TAMAHO"
}
}
}