diff --git a/Business/App.cs b/Business/App.cs index 3f63d1d..1eb10a5 100644 --- a/Business/App.cs +++ b/Business/App.cs @@ -1,15 +1,22 @@ -using Microsoft.Win32; -using System; -using System.Windows.Forms; -using SystemTrayMenu.Business; -using SystemTrayMenu.UserInterface; -using SystemTrayMenu.Utilities; +// +// Copyright (c) PlaceholderCompany. All rights reserved. +// namespace SystemTrayMenu { + using Microsoft.Win32; + using System; + using System.Windows.Forms; + using SystemTrayMenu.Business; + using SystemTrayMenu.UserInterface; + using SystemTrayMenu.Utilities; + + /// + /// App contains the notifyicon, the taskbarform and the menus. + /// 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(); } /// - /// 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. /// private void SetStateNormal() { @@ -69,6 +76,7 @@ namespace SystemTrayMenu taskbarForm.WindowState = FormWindowState.Normal; } } + public void Dispose() { taskbarForm.Dispose(); diff --git a/Business/KeyboardInput.cs b/Business/KeyboardInput.cs index 6beaa00..c29533c 100644 --- a/Business/KeyboardInput.cs +++ b/Business/KeyboardInput.cs @@ -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 (c) PlaceholderCompany. All rights reserved. +// 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; + } } /// @@ -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) diff --git a/Business/Menus.cs b/Business/Menus.cs index b7034dd..e594c94 100644 --- a/Business/Menus.cs +++ b/Business/Menus.cs @@ -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(), 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; } diff --git a/Business/Program.cs b/Business/Program.cs index cf528bc..dffe6e6 100644 --- a/Business/Program.cs +++ b/Business/Program.cs @@ -1,11 +1,15 @@ -using System; -using System.Reflection; -using System.Threading; -using System.Windows.Forms; -using SystemTrayMenu.Utilities; +// +// Copyright (c) PlaceholderCompany. All rights reserved. +// 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 " + diff --git a/Business/WaitLeave.cs b/Business/WaitLeave.cs index 545c050..a2a86e5 100644 --- a/Business/WaitLeave.cs +++ b/Business/WaitLeave.cs @@ -1,9 +1,12 @@ -using System; -using SystemTrayMenu.Utilities; -using Timer = System.Windows.Forms.Timer; +// +// Copyright (c) PlaceholderCompany. All rights reserved. +// namespace SystemTrayMenu.Handler { + using System; + using SystemTrayMenu.Utilities; + using Timer = System.Windows.Forms.Timer; internal class WaitLeave : IDisposable { public event EventHandlerEmpty LeaveTriggered; diff --git a/Business/WaitToLoadMenu.cs b/Business/WaitToLoadMenu.cs index 6d15e10..e9fb748 100644 --- a/Business/WaitToLoadMenu.cs +++ b/Business/WaitToLoadMenu.cs @@ -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 (c) PlaceholderCompany. All rights reserved. +// 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 StartLoadMenu; internal event Action CloseMenu; internal event EventHandlerEmpty StopLoadMenu; internal event Action 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 < diff --git a/Config/Config.cs b/Config/Config.cs index 6d31f21..a5c722f 100644 --- a/Config/Config.cs +++ b/Config/Config.cs @@ -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 (c) PlaceholderCompany. All rights reserved. +// 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; } diff --git a/Config/MenuDefines.cs b/Config/MenuDefines.cs index 3d96526..abc2aa7 100644 --- a/Config/MenuDefines.cs +++ b/Config/MenuDefines.cs @@ -1,8 +1,11 @@ -using System.Drawing; -using System.Reflection; +// +// Copyright (c) PlaceholderCompany. All rights reserved. +// namespace SystemTrayMenu { + using System.Drawing; + using System.Reflection; internal static class MenuDefines { internal static string NotifyIconText = Assembly.GetExecutingAssembly().GetCustomAttribute().Title; diff --git a/DataClasses/MenuData.cs b/DataClasses/MenuData.cs index 978ddd0..3427c3e 100644 --- a/DataClasses/MenuData.cs +++ b/DataClasses/MenuData.cs @@ -1,13 +1,17 @@ -using System.Collections.Generic; +// +// Copyright (c) PlaceholderCompany. All rights reserved. +// 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; - }; + } } \ No newline at end of file diff --git a/DataClasses/RowData.cs b/DataClasses/RowData.cs index 999bd34..b343dfb 100644 --- a/DataClasses/RowData.cs +++ b/DataClasses/RowData.cs @@ -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 (c) PlaceholderCompany. All rights reserved. +// 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; - } } } diff --git a/GlobalSuppressions.cs b/GlobalSuppressions.cs new file mode 100644 index 0000000..eb4337a --- /dev/null +++ b/GlobalSuppressions.cs @@ -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")] diff --git a/Helpers/Fading.cs b/Helpers/Fading.cs index ae0345e..43d6e8b 100644 --- a/Helpers/Fading.cs +++ b/Helpers/Fading.cs @@ -1,26 +1,34 @@ -using System; -using System.Windows.Forms; -using SystemTrayMenu.Utilities; +// +// Copyright (c) PlaceholderCompany. All rights reserved. +// 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 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: diff --git a/Helpers/KeyboardHook.cs b/Helpers/KeyboardHook.cs index b09341d..03f57b8 100644 --- a/Helpers/KeyboardHook.cs +++ b/Helpers/KeyboardHook.cs @@ -1,10 +1,14 @@ -using System; -using System.Windows.Forms; -using SystemTrayMenu.UserInterface.Controls; -using SystemTrayMenu.Utilities; +// +// Copyright (c) PlaceholderCompany. All rights reserved. +// namespace SystemTrayMenu.Helper { + using System; + using System.Windows.Forms; + using SystemTrayMenu.UserInterface.Controls; + using SystemTrayMenu.Utilities; + public sealed class KeyboardHook : IDisposable { /// @@ -23,7 +27,7 @@ namespace SystemTrayMenu.Helper /// /// Overridden to get the notifications. /// - /// + /// m. protected override void WndProc(ref Message m) { base.WndProc(ref m); @@ -42,14 +46,10 @@ namespace SystemTrayMenu.Helper public event EventHandler 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 /// /// The modifiers that are associated with the hot key. /// The key itself that is associated with the hot key. - //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 /// internal event EventHandler 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 } /// @@ -178,6 +176,6 @@ namespace SystemTrayMenu.Helper Alt = 1, Control = 2, Shift = 4, - Win = 8 + Win = 8, } } diff --git a/Helpers/WindowsExplorerSort.cs b/Helpers/WindowsExplorerSort.cs index 1b49190..72fa726 100644 --- a/Helpers/WindowsExplorerSort.cs +++ b/Helpers/WindowsExplorerSort.cs @@ -1,7 +1,10 @@ -using System.Collections.Generic; +// +// Copyright (c) PlaceholderCompany. All rights reserved. +// namespace SystemTrayMenu.Helper { + using System.Collections.Generic; internal class WindowsExplorerSort : IComparer { public int Compare(string x, string y) diff --git a/Helpers/WindowsTaskbar.cs b/Helpers/WindowsTaskbar.cs index f7f9d6a..ac429d3 100644 --- a/Helpers/WindowsTaskbar.cs +++ b/Helpers/WindowsTaskbar.cs @@ -1,11 +1,13 @@ -using System; -using System.Drawing; -using System.Runtime.InteropServices; -using static SystemTrayMenu.DllImports.NativeMethods; +// +// Copyright (c) PlaceholderCompany. All rights reserved. +// -//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 diff --git a/NativeDllImport/BringWindowToTop.cs b/NativeDllImport/BringWindowToTop.cs index 32afeb0..f945a8e 100644 --- a/NativeDllImport/BringWindowToTop.cs +++ b/NativeDllImport/BringWindowToTop.cs @@ -1,8 +1,14 @@ -using System; -using System.Runtime.InteropServices; +// +// Copyright (c) PlaceholderCompany. All rights reserved. +// namespace SystemTrayMenu.DllImports { + using System; + using System.Runtime.InteropServices; + /// + /// wraps the methodcalls to native windows dll's. + /// public static partial class NativeMethods { [DllImport("user32.dll")] diff --git a/NativeDllImport/CreatePopupMenu.cs b/NativeDllImport/CreatePopupMenu.cs index 476455d..e4a0e2f 100644 --- a/NativeDllImport/CreatePopupMenu.cs +++ b/NativeDllImport/CreatePopupMenu.cs @@ -1,8 +1,14 @@ -using System; -using System.Runtime.InteropServices; +// +// Copyright (c) PlaceholderCompany. All rights reserved. +// namespace SystemTrayMenu.DllImports { + using System; + using System.Runtime.InteropServices; + /// + /// wraps the methodcalls to native windows dll's. + /// 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. diff --git a/NativeDllImport/DestroyIcon.cs b/NativeDllImport/DestroyIcon.cs index 6198dde..852ed98 100644 --- a/NativeDllImport/DestroyIcon.cs +++ b/NativeDllImport/DestroyIcon.cs @@ -1,8 +1,14 @@ -using System; -using System.Runtime.InteropServices; +// +// Copyright (c) PlaceholderCompany. All rights reserved. +// namespace SystemTrayMenu.DllImports { + using System; + using System.Runtime.InteropServices; + /// + /// wraps the methodcalls to native windows dll's. + /// public static partial class NativeMethods { [DllImport("User32.dll")] diff --git a/NativeDllImport/DestroyMenu.cs b/NativeDllImport/DestroyMenu.cs index d8a3d90..ea353d0 100644 --- a/NativeDllImport/DestroyMenu.cs +++ b/NativeDllImport/DestroyMenu.cs @@ -1,8 +1,15 @@ -using System; -using System.Runtime.InteropServices; +// +// Copyright (c) PlaceholderCompany. All rights reserved. +// namespace SystemTrayMenu.DllImports { + using System; + using System.Runtime.InteropServices; + + /// + /// wraps the methodcalls to native windows dll's. + /// public static partial class NativeMethods { // The DestroyMenu function destroys the specified menu and frees any memory that the menu occupies. diff --git a/NativeDllImport/FindExecuteable.cs b/NativeDllImport/FindExecuteable.cs index 2bc5698..0a4a45e 100644 --- a/NativeDllImport/FindExecuteable.cs +++ b/NativeDllImport/FindExecuteable.cs @@ -1,8 +1,15 @@ -using System.Runtime.InteropServices; -using System.Text; +// +// Copyright (c) PlaceholderCompany. All rights reserved. +// namespace SystemTrayMenu.DllImports { + using System.Runtime.InteropServices; + using System.Text; + + /// + /// wraps the methodcalls to native windows dll's. + /// public static partial class NativeMethods { [DllImport("shell32.dll", CharSet = CharSet.Unicode)] diff --git a/NativeDllImport/FindWindow.cs b/NativeDllImport/FindWindow.cs index 1727498..cdbc479 100644 --- a/NativeDllImport/FindWindow.cs +++ b/NativeDllImport/FindWindow.cs @@ -1,16 +1,24 @@ -using System; -using System.Runtime.InteropServices; +// +// Copyright (c) PlaceholderCompany. All rights reserved. +// namespace SystemTrayMenu.DllImports { + using System; + using System.Runtime.InteropServices; + + /// + /// wraps the methodcalls to native windows dll's. + /// 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 = "")] 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); } } diff --git a/NativeDllImport/GetDeviceCaps.cs b/NativeDllImport/GetDeviceCaps.cs index 7861662..ea263ea 100644 --- a/NativeDllImport/GetDeviceCaps.cs +++ b/NativeDllImport/GetDeviceCaps.cs @@ -1,8 +1,15 @@ -using System; -using System.Runtime.InteropServices; +// +// Copyright (c) PlaceholderCompany. All rights reserved. +// namespace SystemTrayMenu.DllImports { + using System; + using System.Runtime.InteropServices; + + /// + /// wraps the methodcalls to native windows dll's. + /// public static partial class NativeMethods { [DllImport("gdi32.dll")] diff --git a/NativeDllImport/GetIcon.cs b/NativeDllImport/GetIcon.cs index a0e3c9d..9dd9a74 100644 --- a/NativeDllImport/GetIcon.cs +++ b/NativeDllImport/GetIcon.cs @@ -1,89 +1,49 @@ -using System; -using System.Runtime.InteropServices; +// +// Copyright (c) PlaceholderCompany. All rights reserved. +// namespace SystemTrayMenu.DllImports { + using System; + using System.Runtime.InteropServices; + + /// + /// wraps the methodcalls to native windows dll's. + /// public static partial class NativeMethods { - //[StructLayout(LayoutKind.Sequential)] - //[System.Diagnostics.CodeAnalysis.SuppressMessage("Performance", "CA1815:Override equals and operator equals on value types", Justification = "")] - //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 = "")] - //internal struct ITEMIDLIST - //{ - // public SHITEMID mkid; - //} - - //[StructLayout(LayoutKind.Sequential)] - //[System.Diagnostics.CodeAnalysis.SuppressMessage("Performance", "CA1815:Override equals and operator equals on value types", Justification = "")] - //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 + /// + /// comctl32 ImageList_GetIcon(IntPtr hIcon). + /// + /// hIcon. + public static void Comctl32ImageListGetIcon(IntPtr hIcon) + { + _ = DestroyIcon(hIcon); + } + + /// + /// comctl32 ImageList_GetIcon(IntPtr himl, int i, int flags). + /// + /// himl. + /// i. + /// flags. + /// IntPtr. [DllImport("comctl32")] internal static extern IntPtr ImageList_GetIcon( IntPtr himl, int i, int flags); - - public static void Comctl32ImageListGetIcon(IntPtr hIcon) - { - _ = DestroyIcon(hIcon); - } } } diff --git a/NativeDllImport/GetMenuDefaultItem.cs b/NativeDllImport/GetMenuDefaultItem.cs index 268f9ea..da44e9f 100644 --- a/NativeDllImport/GetMenuDefaultItem.cs +++ b/NativeDllImport/GetMenuDefaultItem.cs @@ -1,8 +1,15 @@ -using System; -using System.Runtime.InteropServices; +// +// Copyright (c) PlaceholderCompany. All rights reserved. +// namespace SystemTrayMenu.DllImports { + using System; + using System.Runtime.InteropServices; + + /// + /// wraps the methodcalls to native windows dll's. + /// public static partial class NativeMethods { // Determines the default menu item on the specified menu diff --git a/NativeDllImport/IsTouchEnabled.cs b/NativeDllImport/IsTouchEnabled.cs index dd0c536..6a15f83 100644 --- a/NativeDllImport/IsTouchEnabled.cs +++ b/NativeDllImport/IsTouchEnabled.cs @@ -1,12 +1,16 @@ -using System.Runtime.InteropServices; +// +// Copyright (c) PlaceholderCompany. All rights reserved. +// namespace SystemTrayMenu.DllImports { + using System.Runtime.InteropServices; + + /// + /// wraps the methodcalls to native windows dll's. + /// 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); } } diff --git a/NativeDllImport/RegisterHotKey.cs b/NativeDllImport/RegisterHotKey.cs index cfdf95d..0d0d9f3 100644 --- a/NativeDllImport/RegisterHotKey.cs +++ b/NativeDllImport/RegisterHotKey.cs @@ -1,9 +1,16 @@ -using System; -using System.Runtime.InteropServices; -using System.Text; +// +// Copyright (c) PlaceholderCompany. All rights reserved. +// namespace SystemTrayMenu.DllImports { + using System; + using System.Runtime.InteropServices; + using System.Text; + + /// + /// wraps the methodcalls to native windows dll's. + /// public static partial class NativeMethods { [DllImport("user32.dll", SetLastError = true)] diff --git a/NativeDllImport/SHAppBarMessage.cs b/NativeDllImport/SHAppBarMessage.cs index 2a5f3a7..0d1e8e1 100644 --- a/NativeDllImport/SHAppBarMessage.cs +++ b/NativeDllImport/SHAppBarMessage.cs @@ -1,18 +1,17 @@ -using System; -using System.Runtime.InteropServices; +// +// Copyright (c) PlaceholderCompany. All rights reserved. +// namespace SystemTrayMenu.DllImports { + using System; + using System.Runtime.InteropServices; + + /// + /// wraps the methodcalls to native windows dll's. + /// 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); } } diff --git a/NativeDllImport/SHGetDesktopFolder.cs b/NativeDllImport/SHGetDesktopFolder.cs index 7d88cf1..ddc775b 100644 --- a/NativeDllImport/SHGetDesktopFolder.cs +++ b/NativeDllImport/SHGetDesktopFolder.cs @@ -1,8 +1,15 @@ -using System; -using System.Runtime.InteropServices; +// +// Copyright (c) PlaceholderCompany. All rights reserved. +// namespace SystemTrayMenu.DllImports { + using System; + using System.Runtime.InteropServices; + + /// + /// wraps the methodcalls to native windows dll's. + /// public static partial class NativeMethods { // Retrieves the IShellFolder interface for the desktop folder, which is the root of the Shell's namespace. diff --git a/NativeDllImport/SHGetFileInfo.cs b/NativeDllImport/SHGetFileInfo.cs index e72ddad..2c84764 100644 --- a/NativeDllImport/SHGetFileInfo.cs +++ b/NativeDllImport/SHGetFileInfo.cs @@ -1,36 +1,19 @@ -using System; -using System.Runtime.InteropServices; +// +// Copyright (c) PlaceholderCompany. All rights reserved. +// namespace SystemTrayMenu.DllImports { + using System; + using System.Runtime.InteropServices; + + /// + /// wraps the methodcalls to native windows dll's. + /// 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); } } - - diff --git a/NativeDllImport/SHGetFolderPath.cs b/NativeDllImport/SHGetFolderPath.cs index 688e24a..e7d72a5 100644 --- a/NativeDllImport/SHGetFolderPath.cs +++ b/NativeDllImport/SHGetFolderPath.cs @@ -1,9 +1,16 @@ -using System; -using System.Runtime.InteropServices; -using System.Text; +// +// Copyright (c) PlaceholderCompany. All rights reserved. +// namespace SystemTrayMenu.DllImports { + using System; + using System.Runtime.InteropServices; + using System.Text; + + /// + /// wraps the methodcalls to native windows dll's. + /// public static partial class NativeMethods { [DllImport("shfolder.dll", CharSet = CharSet.Unicode)] diff --git a/NativeDllImport/SetProcessDPIAware.cs b/NativeDllImport/SetProcessDPIAware.cs index 91c9b3b..30747d9 100644 --- a/NativeDllImport/SetProcessDPIAware.cs +++ b/NativeDllImport/SetProcessDPIAware.cs @@ -1,7 +1,13 @@ -using System.Runtime.InteropServices; +// +// Copyright (c) PlaceholderCompany. All rights reserved. +// namespace SystemTrayMenu.DllImports { + using System.Runtime.InteropServices; + /// + /// wraps the methodcalls to native windows dll's. + /// public static partial class NativeMethods { [DllImport("user32.dll")] diff --git a/NativeDllImport/ShowInactiveTopmost.cs b/NativeDllImport/ShowInactiveTopmost.cs index aaf7dff..93645df 100644 --- a/NativeDllImport/ShowInactiveTopmost.cs +++ b/NativeDllImport/ShowInactiveTopmost.cs @@ -1,14 +1,37 @@ -using System.Runtime.InteropServices; -using System.Windows.Forms; +// +// Copyright (c) PlaceholderCompany. All rights reserved. +// namespace SystemTrayMenu.DllImports { + using System.Runtime.InteropServices; + using System.Windows.Forms; + + /// + /// wraps the methodcalls to native windows dll's. + /// 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); - } - } } } diff --git a/NativeDllImport/ShowWindow.cs b/NativeDllImport/ShowWindow.cs index e0e4739..bfb6a92 100644 --- a/NativeDllImport/ShowWindow.cs +++ b/NativeDllImport/ShowWindow.cs @@ -1,8 +1,14 @@ -using System; -using System.Runtime.InteropServices; +// +// Copyright (c) PlaceholderCompany. All rights reserved. +// namespace SystemTrayMenu.DllImports { + using System; + using System.Runtime.InteropServices; + /// + /// wraps the methodcalls to native windows dll's. + /// public static partial class NativeMethods { [DllImport("user32.dll")] diff --git a/NativeDllImport/StrCmpLogicalW.cs b/NativeDllImport/StrCmpLogicalW.cs index cc746b5..3fa7b29 100644 --- a/NativeDllImport/StrCmpLogicalW.cs +++ b/NativeDllImport/StrCmpLogicalW.cs @@ -1,7 +1,13 @@ -using System.Runtime.InteropServices; +// +// Copyright (c) PlaceholderCompany. All rights reserved. +// namespace SystemTrayMenu.DllImports { + using System.Runtime.InteropServices; + /// + /// wraps the methodcalls to native windows dll's. + /// public static partial class NativeMethods { [DllImport("shlwapi.dll", CharSet = CharSet.Unicode, ExactSpelling = true)] diff --git a/NativeDllImport/StrRetToBuf.cs b/NativeDllImport/StrRetToBuf.cs index 7096b79..bd3d7d7 100644 --- a/NativeDllImport/StrRetToBuf.cs +++ b/NativeDllImport/StrRetToBuf.cs @@ -1,12 +1,19 @@ -using System; -using System.Runtime.InteropServices; -using System.Text; +// +// Copyright (c) PlaceholderCompany. All rights reserved. +// namespace SystemTrayMenu.DllImports { + using System; + using System.Runtime.InteropServices; + using System.Text; + + /// + /// wraps the methodcalls to native windows dll's. + /// 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); diff --git a/NativeDllImport/TrackPopupMenuEx.cs b/NativeDllImport/TrackPopupMenuEx.cs index 510f037..0a13da6 100644 --- a/NativeDllImport/TrackPopupMenuEx.cs +++ b/NativeDllImport/TrackPopupMenuEx.cs @@ -1,32 +1,30 @@ -using System; -using System.Runtime.InteropServices; +// +// Copyright (c) PlaceholderCompany. All rights reserved. +// namespace SystemTrayMenu.DllImports { + using System; + using System.Runtime.InteropServices; + + /// + /// wraps the methodcalls to native windows dll's. + /// 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 + /// + /// Specifies how TrackPopupMenuEx positions the shortcut menu horizontally. + /// [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 } + + /// + /// user32 TrackPopupMenuEx. + /// + /// hmenu. + /// flags. + /// x. + /// y. + /// hwnd. + /// lptpm. + /// uint. + 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); } } diff --git a/Properties/AssemblyInfo.cs b/Properties/AssemblyInfo.cs index 3f87554..1f4c1a1 100644 --- a/Properties/AssemblyInfo.cs +++ b/Properties/AssemblyInfo.cs @@ -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")] diff --git a/SystemTrayMenu.csproj b/SystemTrayMenu.csproj index b317ca3..ba57cc8 100644 --- a/SystemTrayMenu.csproj +++ b/SystemTrayMenu.csproj @@ -197,11 +197,7 @@ - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/UserInterface/AboutBox.cs b/UserInterface/AboutBox.cs index 27e3104..2387eca 100644 --- a/UserInterface/AboutBox.cs +++ b/UserInterface/AboutBox.cs @@ -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; + /// /// Generic, self-contained About Box dialog /// @@ -42,7 +42,7 @@ namespace SystemTrayMenu.UserInterface // returns the entry assembly for the current application domain // // - // 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. // 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 // // - // defaults to "%title%" + // defaults to "%title%" // %title% = Assembly: AssemblyTitle // public string AppTitle @@ -203,7 +203,7 @@ namespace SystemTrayMenu.UserInterface } // - // 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. // // Assembly to get build date for @@ -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 // 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|\.)(?[^.]*)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; diff --git a/UserInterface/AppContextMenu.cs b/UserInterface/AppContextMenu.cs index c2fa531..e5e963c 100644 --- a/UserInterface/AppContextMenu.cs +++ b/UserInterface/AppContextMenu.cs @@ -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 (c) PlaceholderCompany. All rights reserved. +// 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; diff --git a/UserInterface/AppNotifyIcon.cs b/UserInterface/AppNotifyIcon.cs index 815d882..486e22f 100644 --- a/UserInterface/AppNotifyIcon.cs +++ b/UserInterface/AppNotifyIcon.cs @@ -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 (c) PlaceholderCompany. All rights reserved. +// 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 bitmapsLoading = new List() { 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) { diff --git a/UserInterface/Controls/HotkeyControl.cs b/UserInterface/Controls/HotkeyControl.cs index 4a04a21..c3b480a 100644 --- a/UserInterface/Controls/HotkeyControl.cs +++ b/UserInterface/Controls/HotkeyControl.cs @@ -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 (c) PlaceholderCompany. All rights reserved. +// 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; + /// /// 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 } /// - /// Creates a new HotkeyControl + /// Initializes a new instance of the class. /// 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 } /// - /// Handle WndProc messages for the hotkey + /// Handle WndProc messages for the hotkey. /// - /// - /// true if the message was handled + /// m. + /// true if the message was handled. 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 } } } -} - - - - +} \ No newline at end of file diff --git a/UserInterface/Dialogs/FolderDialog.cs b/UserInterface/Dialogs/FolderDialog.cs index 9c795e4..38305fd 100644 --- a/UserInterface/Dialogs/FolderDialog.cs +++ b/UserInterface/Dialogs/FolderDialog.cs @@ -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 (c) PlaceholderCompany. All rights reserved. +// 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; } /// - /// 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. /// 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 { /// - /// Constructor + /// Initializes a new instance of the class. /// /// Handle to wrap public WindowWrapper(IntPtr handle) @@ -151,13 +165,11 @@ namespace SystemTrayMenu.UserInterface.Dialogs /// Original ptr /// 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); } } diff --git a/UserInterface/Dialogs/IFolderDialog.cs b/UserInterface/Dialogs/IFolderDialog.cs index fd8e6ca..2586772 100644 --- a/UserInterface/Dialogs/IFolderDialog.cs +++ b/UserInterface/Dialogs/IFolderDialog.cs @@ -1,7 +1,11 @@ -using System.Windows.Forms; +// +// Copyright (c) PlaceholderCompany. All rights reserved. +// namespace SystemTrayMenu.UserInterface.Dialogs { + using System.Windows.Forms; + public interface IFolderDialog { string InitialFolder { get; set; } diff --git a/UserInterface/LabelNoCopy.cs b/UserInterface/LabelNoCopy.cs index 1da9231..9d2f1d1 100644 --- a/UserInterface/LabelNoCopy.cs +++ b/UserInterface/LabelNoCopy.cs @@ -1,15 +1,18 @@ -using System; -using System.Windows.Forms; +// +// Copyright (c) PlaceholderCompany. All rights reserved. +// namespace SystemTrayMenu.UserInterface { + using System; + using System.Windows.Forms; /// /// 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. /// @@ -23,7 +26,7 @@ namespace SystemTrayMenu.UserInterface { if (value == null) { - value = ""; + value = string.Empty; } if (_text != value) diff --git a/UserInterface/Menu.cs b/UserInterface/Menu.cs index 6878643..9782ca7 100644 --- a/UserInterface/Menu.cs +++ b/UserInterface/Menu.cs @@ -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; diff --git a/UserInterface/SettingsForm.cs b/UserInterface/SettingsForm.cs index c8b195e..8fef51e 100644 --- a/UserInterface/SettingsForm.cs +++ b/UserInterface/SettingsForm.cs @@ -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 (c) TAMAHO. All rights reserved. +// 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 dataSource = new List { 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 - /// /// Helper method to cleanly register a hotkey /// @@ -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 //} /// - /// 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 diff --git a/UserInterface/ShellContextMenu/ShellContextMenu.cs b/UserInterface/ShellContextMenu/ShellContextMenu.cs index 3d0e198..6235164 100644 --- a/UserInterface/ShellContextMenu/ShellContextMenu.cs +++ b/UserInterface/ShellContextMenu/ShellContextMenu.cs @@ -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; + /// /// "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 /// public class ShellContextMenu : NativeWindow { - #region Constructor - /// Default constructor + /// + /// Initializes a new instance of the class. + /// public ShellContextMenu() { CreateHandle(new CreateParams()); } - #endregion - #region Destructor - /// Ensure all resources get released + /// + /// Finalizes an instance of the class. + /// ~ShellContextMenu() { ReleaseAll(); } - #endregion - #region GetContextMenuInterfaces() /// Gets the interfaces to the context menu /// Parent folder /// PIDLs @@ -89,47 +88,23 @@ namespace SystemTrayMenu.Utilities return false; } } - #endregion - - #region Override /// - /// 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. /// /// the Message of the Browser's WndProc /// true if the message has been handled, false otherwise 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() /// - /// Release all allocated interfaces, PIDLs + /// Release all allocated interfaces, PIDLs. /// 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() /// /// Gets the desktop folder /// @@ -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() /// /// Gets the parent folder /// @@ -288,14 +254,13 @@ namespace SystemTrayMenu.Utilities { return null; } + _oParentFolder = (IShellFolder)Marshal.GetTypedObjectForIUnknown(pUnknownParentFolder, typeof(IShellFolder)); } return _oParentFolder; } - #endregion - #region GetPIDLs() /// /// Get the PIDLs /// @@ -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() /// /// Free the PIDLs /// /// Array of PIDLs (IntPtr) 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() /// /// 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 } } diff --git a/UserInterface/ShellContextMenu/ShellContextMenuException.cs b/UserInterface/ShellContextMenu/ShellContextMenuException.cs index aa44a0f..6f96959 100644 --- a/UserInterface/ShellContextMenu/ShellContextMenuException.cs +++ b/UserInterface/ShellContextMenu/ShellContextMenuException.cs @@ -1,8 +1,11 @@ -using System; -using System.Runtime.Serialization; +// +// Copyright (c) PlaceholderCompany. All rights reserved. +// 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. } diff --git a/UserInterface/ShellContextMenu/ShellHelper.cs b/UserInterface/ShellContextMenu/ShellHelper.cs index 258a007..c503b1f 100644 --- a/UserInterface/ShellContextMenu/ShellHelper.cs +++ b/UserInterface/ShellContextMenu/ShellHelper.cs @@ -1,11 +1,12 @@ -using System; +// +// Copyright (c) PlaceholderCompany. All rights reserved. +// namespace SystemTrayMenu.Helper { + using System; internal static class ShellHelper { - #region Low/High Word - /// /// Retrieves the High Word of a WParam of a WindowMessage /// @@ -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 } } diff --git a/UserInterface/TaskbarForm.cs b/UserInterface/TaskbarForm.cs index ade04d1..8030579 100644 --- a/UserInterface/TaskbarForm.cs +++ b/UserInterface/TaskbarForm.cs @@ -1,8 +1,11 @@ -using System.Drawing; -using System.Windows.Forms; +// +// Copyright (c) PlaceholderCompany. All rights reserved. +// namespace SystemTrayMenu.UserInterface { + using System.Drawing; + using System.Windows.Forms; public partial class TaskbarForm : Form { public TaskbarForm() diff --git a/Utilities/AppRestart.cs b/Utilities/AppRestart.cs index 7523a75..52637ee 100644 --- a/Utilities/AppRestart.cs +++ b/Utilities/AppRestart.cs @@ -1,10 +1,13 @@ -using System; -using System.Diagnostics; -using System.Runtime.CompilerServices; -using System.Windows.Forms; +// +// Copyright (c) PlaceholderCompany. All rights reserved. +// 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(); } diff --git a/Utilities/DataGridViewExtensions.cs b/Utilities/DataGridViewExtensions.cs index dfc63ba..219070f 100644 --- a/Utilities/DataGridViewExtensions.cs +++ b/Utilities/DataGridViewExtensions.cs @@ -1,10 +1,14 @@ -using System.Data; -using System.Drawing; -using System.Linq; -using System.Windows.Forms; +// +// Copyright (c) PlaceholderCompany. All rights reserved. +// namespace SystemTrayMenu.Utilities { + using System.Data; + using System.Drawing; + using System.Linq; + using System.Windows.Forms; + internal static class DataGridViewExtensions { /// @@ -15,36 +19,36 @@ namespace SystemTrayMenu.Utilities { System.Collections.Generic.IEnumerable rows = dgv.Rows.Cast(); - 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; } } } diff --git a/Utilities/File/FileIni.cs b/Utilities/File/FileIni.cs index 28465ef..1d82ef8 100644 --- a/Utilities/File/FileIni.cs +++ b/Utilities/File/FileIni.cs @@ -1,9 +1,12 @@ -using System.Collections.Generic; -using System.IO; -using System.Linq; +// +// Copyright (c) PlaceholderCompany. All rights reserved. +// namespace SystemTrayMenu.Utilities { + using System.Collections.Generic; + using System.IO; + using System.Linq; public class FileIni { private readonly Dictionary 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; } } diff --git a/Utilities/File/FileLnk.cs b/Utilities/File/FileLnk.cs index d9443a3..3cef6e9 100644 --- a/Utilities/File/FileLnk.cs +++ b/Utilities/File/FileLnk.cs @@ -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(); diff --git a/Utilities/File/FileUrl.cs b/Utilities/File/FileUrl.cs index 6765654..e42a0ef 100644 --- a/Utilities/File/FileUrl.cs +++ b/Utilities/File/FileUrl.cs @@ -1,7 +1,11 @@ -using Microsoft.Win32; +// +// Copyright (c) PlaceholderCompany. All rights reserved. +// 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 diff --git a/Utilities/File/IconReader.cs b/Utilities/File/IconReader.cs index ecfb8a7..0a3b19a 100644 --- a/Utilities/File/IconReader.cs +++ b/Utilities/File/IconReader.cs @@ -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 (c) PlaceholderCompany. All rights reserved. +// 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); diff --git a/Utilities/FolderOptions.cs b/Utilities/FolderOptions.cs index 6d3dd11..c55d0c3 100644 --- a/Utilities/FolderOptions.cs +++ b/Utilities/FolderOptions.cs @@ -1,11 +1,14 @@ -using Shell32; -using System; -using System.IO; -using System.Reflection; -using System.Runtime.InteropServices; +// +// Copyright (c) PlaceholderCompany. All rights reserved. +// 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; diff --git a/Utilities/Log.cs b/Utilities/Log.cs index fbb1fcd..68fdf07 100644 --- a/Utilities/Log.cs +++ b/Utilities/Log.cs @@ -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 (c) PlaceholderCompany. All rights reserved. +// 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) { diff --git a/Utilities/Scaling.cs b/Utilities/Scaling.cs index 2dcf4ce..e750d85 100644 --- a/Utilities/Scaling.cs +++ b/Utilities/Scaling.cs @@ -1,8 +1,11 @@ -using System; -using System.Drawing; +// +// Copyright (c) PlaceholderCompany. All rights reserved. +// 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) { diff --git a/Utilities/SingleAppInstance.cs b/Utilities/SingleAppInstance.cs index 14210d5..d181f8b 100644 --- a/Utilities/SingleAppInstance.cs +++ b/Utilities/SingleAppInstance.cs @@ -1,10 +1,13 @@ -using System; -using System.ComponentModel; -using System.Diagnostics; -using System.Linq; +// +// Copyright (c) PlaceholderCompany. All rights reserved. +// 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)) diff --git a/Utilities/Translator.cs b/Utilities/Translator.cs index b5849ef..280d0b0 100644 --- a/Utilities/Translator.cs +++ b/Utilities/Translator.cs @@ -1,10 +1,14 @@ -using System.Globalization; -using System.Resources; -using SystemTrayMenu.Properties; -using SystemTrayMenu.UserInterface; +// +// Copyright (c) PlaceholderCompany. All rights reserved. +// namespace SystemTrayMenu.Utilities { + using System.Globalization; + using System.Resources; + using SystemTrayMenu.Properties; + using SystemTrayMenu.UserInterface; + internal static class Translator { internal static CultureInfo Culture; diff --git a/stylecop.json b/stylecop.json new file mode 100644 index 0000000..ef95ea9 --- /dev/null +++ b/stylecop.json @@ -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" + } + } +}