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

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

10
GlobalSuppressions.cs Normal file
View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -1,89 +1,49 @@
using System; // <copyright file="GetIcon.cs" company="PlaceholderCompany">
using System.Runtime.InteropServices; // Copyright (c) PlaceholderCompany. All rights reserved.
// </copyright>
namespace SystemTrayMenu.DllImports namespace SystemTrayMenu.DllImports
{ {
using System;
using System.Runtime.InteropServices;
/// <summary>
/// wraps the methodcalls to native windows dll's.
/// </summary>
public static partial class NativeMethods public static partial class NativeMethods
{ {
//[StructLayout(LayoutKind.Sequential)] #pragma warning disable SA1600 // Elements should be documented
//[System.Diagnostics.CodeAnalysis.SuppressMessage("Performance", "CA1815:Override equals and operator equals on value types", Justification = "<Pending>")]
//internal struct SHITEMID
//{
// public ushort cb;
// [MarshalAs(UnmanagedType.LPArray)]
// public byte[] abID;
//}
//[StructLayout(LayoutKind.Sequential)]
//[System.Diagnostics.CodeAnalysis.SuppressMessage("Performance", "CA1815:Override equals and operator equals on value types", Justification = "<Pending>")]
//internal struct ITEMIDLIST
//{
// public SHITEMID mkid;
//}
//[StructLayout(LayoutKind.Sequential)]
//[System.Diagnostics.CodeAnalysis.SuppressMessage("Performance", "CA1815:Override equals and operator equals on value types", Justification = "<Pending>")]
//internal struct BROWSEINFO
//{
// public IntPtr hwndOwner;
// public IntPtr pidlRoot;
// public IntPtr pszDisplayName;
// [MarshalAs(UnmanagedType.LPTStr)]
// public string lpszTitle;
// public uint ulFlags;
// public IntPtr lpfn;
// public int lParam;
// public IntPtr iImage;
//}
// Browsing for directory.
//public const uint BIF_RETURNONLYFSDIRS = 0x0001;
//public const uint BIF_DONTGOBELOWDOMAIN = 0x0002;
//public const uint BIF_STATUSTEXT = 0x0004;
//public const uint BIF_RETURNFSANCESTORS = 0x0008;
//public const uint BIF_EDITBOX = 0x0010;
//public const uint BIF_VALIDATE = 0x0020;
//public const uint BIF_NEWDIALOGSTYLE = 0x0040;
//public const uint BIF_USENEWUI = (BIF_NEWDIALOGSTYLE | BIF_EDITBOX);
//public const uint BIF_BROWSEINCLUDEURLS = 0x0080;
//public const uint BIF_BROWSEFORCOMPUTER = 0x1000;
//public const uint BIF_BROWSEFORPRINTER = 0x2000;
//public const uint BIF_BROWSEINCLUDEFILES = 0x4000;
//public const uint BIF_SHAREABLE = 0x8000;
public const uint ShgfiIcon = 0x000000100; // get icon 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 ShgfiSYSICONINDEX = 0x000004000; // get system icon index
public const uint ShgfiLINKOVERLAY = 0x000008000; // put a link overlay on icon 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 ShgfiLARGEICON = 0x000000000; // get large icon
public const uint ShgfiSMALLICON = 0x000000001; // get small icon public const uint ShgfiSMALLICON = 0x000000001; // get small icon
public const uint ShgfiOPENICON = 0x000000002; // get open 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 FileAttributeDirectory = 0x00000010;
public const uint FileAttributeNormal = 0x00000080; public const uint FileAttributeNormal = 0x00000080;
public const int IldTransparent = 0x00000001; public const int IldTransparent = 0x00000001;
#pragma warning restore SA1600 // Elements should be documented
/// <summary>
/// comctl32 ImageList_GetIcon(IntPtr hIcon).
/// </summary>
/// <param name="hIcon">hIcon.</param>
public static void Comctl32ImageListGetIcon(IntPtr hIcon)
{
_ = DestroyIcon(hIcon);
}
/// <summary>
/// comctl32 ImageList_GetIcon(IntPtr himl, int i, int flags).
/// </summary>
/// <param name="himl">himl.</param>
/// <param name="i">i.</param>
/// <param name="flags">flags.</param>
/// <returns>IntPtr.</returns>
[DllImport("comctl32")] [DllImport("comctl32")]
internal static extern IntPtr ImageList_GetIcon( internal static extern IntPtr ImageList_GetIcon(
IntPtr himl, IntPtr himl,
int i, int i,
int flags); int flags);
public static void Comctl32ImageListGetIcon(IntPtr hIcon)
{
_ = DestroyIcon(hIcon);
}
} }
} }

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -1,12 +1,19 @@
using System; // <copyright file="StrRetToBuf.cs" company="PlaceholderCompany">
using System.Runtime.InteropServices; // Copyright (c) PlaceholderCompany. All rights reserved.
using System.Text; // </copyright>
namespace SystemTrayMenu.DllImports namespace SystemTrayMenu.DllImports
{ {
using System;
using System.Runtime.InteropServices;
using System.Text;
/// <summary>
/// wraps the methodcalls to native windows dll's.
/// </summary>
public static partial class NativeMethods 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)] [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); private static extern int StrRetToBuf(IntPtr pstr, IntPtr pidl, StringBuilder pszBuf, int cchBuf);

View file

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

View file

@ -2,7 +2,7 @@
using System.Resources; using System.Resources;
using System.Runtime.InteropServices; 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 // set of attributes. Change these attribute values to modify the information
// associated with an assembly. // associated with an assembly.
[assembly: AssemblyTitle("SystemTrayMenu")] [assembly: AssemblyTitle("SystemTrayMenu")]
@ -14,26 +14,26 @@ using System.Runtime.InteropServices;
[assembly: AssemblyTrademark("TAMAHO")] [assembly: AssemblyTrademark("TAMAHO")]
[assembly: AssemblyCulture("")] [assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible // 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 // to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type. // COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)] [assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM // The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("116c8741-a9b0-4560-8e82-7cf412894340")] [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")] [assembly: NeutralResourcesLanguage("en")]
// Version information for an assembly consists of the following four values: // Version information for an assembly consists of the following four values:
// //
// Major Version // Major Version
// Minor Version // Minor Version
// Build Number // Build Number
// Revision // 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: // by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")] // [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("0.11.4.1")] [assembly: AssemblyVersion("0.11.4.2")]
[assembly: AssemblyFileVersion("0.11.4.1")] [assembly: AssemblyFileVersion("0.11.4.2")]

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -1,15 +1,18 @@
using System; // <copyright file="LabelNoCopy.cs" company="PlaceholderCompany">
using System.Windows.Forms; // Copyright (c) PlaceholderCompany. All rights reserved.
// </copyright>
namespace SystemTrayMenu.UserInterface namespace SystemTrayMenu.UserInterface
{ {
using System;
using System.Windows.Forms;
/// <summary> /// <summary>
/// Workaround class for "Clipboard" issue on .Net Windows Forms Label (https://github.com/Hofknecht/SystemTrayMenu/issues/5) /// 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. /// 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. /// 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. /// 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) /// (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. /// 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. /// This will place the required files into the Designer's cache and becomes able to show the GUI as usual.
/// </summary> /// </summary>
@ -23,7 +26,7 @@ namespace SystemTrayMenu.UserInterface
{ {
if (value == null) if (value == null)
{ {
value = ""; value = string.Empty;
} }
if (_text != value) if (_text != value)

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -1,11 +1,11 @@
using Shell32; namespace SystemTrayMenu.Utilities
using System;
using System.IO;
using System.Threading;
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) public static string GetResolvedFileName(string shortcutFilename)
{ {
@ -21,6 +21,7 @@ namespace SystemTrayMenu.Utilities
{ {
resolvedFilename = GetShortcutFileNamePath(shortcutFilename); resolvedFilename = GetShortcutFileNamePath(shortcutFilename);
} }
staThread.SetApartmentState(ApartmentState.STA); staThread.SetApartmentState(ApartmentState.STA);
staThread.Start(shortcutFilename); staThread.Start(shortcutFilename);
staThread.Join(); staThread.Join();

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

14
stylecop.json Normal file
View file

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