mirror of
https://github.com/Hofknecht/SystemTrayMenu.git
synced 2024-05-05 04:53:05 +12:00
Code Analyze and Refactor 0.12 (#109), version 0.11.4.4
This commit is contained in:
parent
2686adf0df
commit
d38750c0b9
|
@ -1,12 +1,11 @@
|
|||
// <copyright file="App.cs" company="PlaceholderCompany">
|
||||
// Copyright (c) PlaceholderCompany. All rights reserved.
|
||||
// </copyright>
|
||||
|
||||
namespace SystemTrayMenu
|
||||
{
|
||||
using Microsoft.Win32;
|
||||
using System;
|
||||
using System.Windows.Forms;
|
||||
using Microsoft.Win32;
|
||||
using SystemTrayMenu.Business;
|
||||
using SystemTrayMenu.UserInterface;
|
||||
using SystemTrayMenu.Utilities;
|
||||
|
@ -61,6 +60,13 @@ namespace SystemTrayMenu
|
|||
DllImports.NativeMethods.User32ShowInactiveTopmost(taskbarForm);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
taskbarForm.Dispose();
|
||||
menus.Dispose();
|
||||
menuNotifyIcon.Dispose();
|
||||
}
|
||||
|
||||
private void TaskbarForm_Deactivate(object sender, EventArgs e)
|
||||
{
|
||||
SetStateNormal();
|
||||
|
@ -76,12 +82,5 @@ namespace SystemTrayMenu
|
|||
taskbarForm.WindowState = FormWindowState.Normal;
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
taskbarForm.Dispose();
|
||||
menus.Dispose();
|
||||
menuNotifyIcon.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -16,8 +16,6 @@ namespace SystemTrayMenu.Handler
|
|||
|
||||
internal class KeyboardInput : IDisposable
|
||||
{
|
||||
internal bool InUse = false;
|
||||
|
||||
private readonly Menu[] menus;
|
||||
private readonly KeyboardHook hook = new KeyboardHook();
|
||||
|
||||
|
@ -41,6 +39,8 @@ namespace SystemTrayMenu.Handler
|
|||
|
||||
internal event EventHandlerEmpty Cleared;
|
||||
|
||||
internal bool InUse { get; set; } = false;
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
hook.Dispose();
|
||||
|
@ -205,6 +205,26 @@ namespace SystemTrayMenu.Handler
|
|||
ClearIsSelectedByKey(iMenuKey, iRowKey);
|
||||
}
|
||||
|
||||
internal void Select(DataGridView dgv, int i, bool refreshview)
|
||||
{
|
||||
int newiMenuKey = ((Menu)dgv.TopLevelControl).Level;
|
||||
if (i != iRowKey || newiMenuKey != iMenuKey)
|
||||
{
|
||||
ClearIsSelectedByKey();
|
||||
}
|
||||
|
||||
iRowKey = i;
|
||||
iMenuKey = newiMenuKey;
|
||||
DataGridViewRow row = dgv.Rows[i];
|
||||
RowData rowData = (RowData)row.Cells[2].Value;
|
||||
rowData.IsSelected = true;
|
||||
if (refreshview)
|
||||
{
|
||||
row.Selected = false;
|
||||
row.Selected = true;
|
||||
}
|
||||
}
|
||||
|
||||
private bool IsAnyMenuSelectedByKey(
|
||||
ref DataGridView dgv,
|
||||
ref Menu menuFromSelected,
|
||||
|
@ -453,26 +473,6 @@ namespace SystemTrayMenu.Handler
|
|||
return found;
|
||||
}
|
||||
|
||||
public void Select(DataGridView dgv, int i, bool refreshview)
|
||||
{
|
||||
int newiMenuKey = ((Menu)dgv.TopLevelControl).Level;
|
||||
if (i != iRowKey || newiMenuKey != iMenuKey)
|
||||
{
|
||||
ClearIsSelectedByKey();
|
||||
}
|
||||
|
||||
iRowKey = i;
|
||||
iMenuKey = newiMenuKey;
|
||||
DataGridViewRow row = dgv.Rows[i];
|
||||
RowData rowData = (RowData)row.Cells[2].Value;
|
||||
rowData.IsSelected = true;
|
||||
if (refreshview)
|
||||
{
|
||||
row.Selected = false;
|
||||
row.Selected = true;
|
||||
}
|
||||
}
|
||||
|
||||
private bool Select(DataGridView dgv, int i, string keyInput = "")
|
||||
{
|
||||
bool found = false;
|
||||
|
|
|
@ -194,43 +194,6 @@ namespace SystemTrayMenu.Business
|
|||
|
||||
private List<Menu> AsList => AsEnumerable.ToList();
|
||||
|
||||
internal void SwitchOpenCloseByTaskbarItem()
|
||||
{
|
||||
SwitchOpenClose(true);
|
||||
timerStillActiveCheck.Start();
|
||||
}
|
||||
|
||||
internal void SwitchOpenClose(bool byClick)
|
||||
{
|
||||
waitToOpenMenu.MouseActive = byClick;
|
||||
if (byClick && (DateTime.Now - deactivatedTime).TotalMilliseconds < 200)
|
||||
{
|
||||
// By click on notifyicon the menu gets deactivated and closed
|
||||
}
|
||||
else if (string.IsNullOrEmpty(Config.Path))
|
||||
{
|
||||
// Case when Folder Dialog open
|
||||
}
|
||||
else if (openCloseState == OpenCloseState.Opening ||
|
||||
(menus[0].Visible && openCloseState == OpenCloseState.Default))
|
||||
{
|
||||
openCloseState = OpenCloseState.Closing;
|
||||
MenusFadeOut();
|
||||
StopWorker();
|
||||
if (!AsEnumerable.Any(m => m.Visible))
|
||||
{
|
||||
openCloseState = OpenCloseState.Default;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
openCloseState = OpenCloseState.Opening;
|
||||
StartWorker();
|
||||
}
|
||||
|
||||
deactivatedTime = DateTime.MinValue;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
workerMainMenu.Dispose();
|
||||
|
@ -247,38 +210,6 @@ namespace SystemTrayMenu.Business
|
|||
DisposeMenu(menus[0]);
|
||||
}
|
||||
|
||||
internal void DisposeMenu(Menu menuToDispose)
|
||||
{
|
||||
if (menuToDispose != null)
|
||||
{
|
||||
menuToDispose.MouseWheel -= AdjustMenusSizeAndLocation;
|
||||
menuToDispose.MouseLeave -= waitLeave.Start;
|
||||
menuToDispose.MouseEnter -= waitLeave.Stop;
|
||||
menuToDispose.KeyPress -= keyboardInput.KeyPress;
|
||||
menuToDispose.CmdKeyProcessed -= keyboardInput.CmdKeyProcessed;
|
||||
menuToDispose.SearchTextChanging -= keyboardInput.SearchTextChanging;
|
||||
menuToDispose.SearchTextChanged -= Menu_SearchTextChanged;
|
||||
DataGridView dgv = menuToDispose.GetDataGridView();
|
||||
dgv.CellMouseEnter -= waitToOpenMenu.MouseEnter;
|
||||
dgv.CellMouseLeave -= waitToOpenMenu.MouseLeave;
|
||||
dgv.MouseMove -= waitToOpenMenu.MouseMove;
|
||||
dgv.MouseDown -= Dgv_MouseDown;
|
||||
dgv.MouseDoubleClick -= Dgv_MouseDoubleClick;
|
||||
dgv.SelectionChanged -= Dgv_SelectionChanged;
|
||||
dgv.RowPostPaint -= Dgv_RowPostPaint;
|
||||
dgv.ClearSelection();
|
||||
|
||||
foreach (DataGridViewRow row in dgv.Rows)
|
||||
{
|
||||
RowData rowData = (RowData)row.Cells[2].Value;
|
||||
rowData.Dispose();
|
||||
DisposeMenu(rowData.SubMenu);
|
||||
}
|
||||
|
||||
menuToDispose.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
internal static MenuData GetData(BackgroundWorker worker, string path, int level)
|
||||
{
|
||||
MenuData menuData = new MenuData
|
||||
|
@ -434,6 +365,75 @@ namespace SystemTrayMenu.Business
|
|||
return menuData;
|
||||
}
|
||||
|
||||
internal void SwitchOpenCloseByTaskbarItem()
|
||||
{
|
||||
SwitchOpenClose(true);
|
||||
timerStillActiveCheck.Start();
|
||||
}
|
||||
|
||||
internal void SwitchOpenClose(bool byClick)
|
||||
{
|
||||
waitToOpenMenu.MouseActive = byClick;
|
||||
if (byClick && (DateTime.Now - deactivatedTime).TotalMilliseconds < 200)
|
||||
{
|
||||
// By click on notifyicon the menu gets deactivated and closed
|
||||
}
|
||||
else if (string.IsNullOrEmpty(Config.Path))
|
||||
{
|
||||
// Case when Folder Dialog open
|
||||
}
|
||||
else if (openCloseState == OpenCloseState.Opening ||
|
||||
(menus[0].Visible && openCloseState == OpenCloseState.Default))
|
||||
{
|
||||
openCloseState = OpenCloseState.Closing;
|
||||
MenusFadeOut();
|
||||
StopWorker();
|
||||
if (!AsEnumerable.Any(m => m.Visible))
|
||||
{
|
||||
openCloseState = OpenCloseState.Default;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
openCloseState = OpenCloseState.Opening;
|
||||
StartWorker();
|
||||
}
|
||||
|
||||
deactivatedTime = DateTime.MinValue;
|
||||
}
|
||||
|
||||
internal void DisposeMenu(Menu menuToDispose)
|
||||
{
|
||||
if (menuToDispose != null)
|
||||
{
|
||||
menuToDispose.MouseWheel -= AdjustMenusSizeAndLocation;
|
||||
menuToDispose.MouseLeave -= waitLeave.Start;
|
||||
menuToDispose.MouseEnter -= waitLeave.Stop;
|
||||
menuToDispose.KeyPress -= keyboardInput.KeyPress;
|
||||
menuToDispose.CmdKeyProcessed -= keyboardInput.CmdKeyProcessed;
|
||||
menuToDispose.SearchTextChanging -= keyboardInput.SearchTextChanging;
|
||||
menuToDispose.SearchTextChanged -= Menu_SearchTextChanged;
|
||||
DataGridView dgv = menuToDispose.GetDataGridView();
|
||||
dgv.CellMouseEnter -= waitToOpenMenu.MouseEnter;
|
||||
dgv.CellMouseLeave -= waitToOpenMenu.MouseLeave;
|
||||
dgv.MouseMove -= waitToOpenMenu.MouseMove;
|
||||
dgv.MouseDown -= Dgv_MouseDown;
|
||||
dgv.MouseDoubleClick -= Dgv_MouseDoubleClick;
|
||||
dgv.SelectionChanged -= Dgv_SelectionChanged;
|
||||
dgv.RowPostPaint -= Dgv_RowPostPaint;
|
||||
dgv.ClearSelection();
|
||||
|
||||
foreach (DataGridViewRow row in dgv.Rows)
|
||||
{
|
||||
RowData rowData = (RowData)row.Cells[2].Value;
|
||||
rowData.Dispose();
|
||||
DisposeMenu(rowData.SubMenu);
|
||||
}
|
||||
|
||||
menuToDispose.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
internal void MainPreload()
|
||||
{
|
||||
menus[0] = Create(
|
||||
|
@ -509,6 +509,12 @@ namespace SystemTrayMenu.Business
|
|||
return rowData;
|
||||
}
|
||||
|
||||
private static bool IsActive()
|
||||
{
|
||||
return Form.ActiveForm is Menu ||
|
||||
Form.ActiveForm is UserInterface.TaskbarForm;
|
||||
}
|
||||
|
||||
private Menu Create(MenuData menuData, string title = null)
|
||||
{
|
||||
Menu menu = new Menu();
|
||||
|
@ -777,12 +783,6 @@ namespace SystemTrayMenu.Business
|
|||
}
|
||||
}
|
||||
|
||||
private static bool IsActive()
|
||||
{
|
||||
return Form.ActiveForm is Menu ||
|
||||
Form.ActiveForm is UserInterface.TaskbarForm;
|
||||
}
|
||||
|
||||
private void MenusFadeOut()
|
||||
{
|
||||
openCloseState = OpenCloseState.Closing;
|
||||
|
|
|
@ -20,26 +20,26 @@ namespace SystemTrayMenu.Handler
|
|||
|
||||
public event EventHandlerEmpty LeaveTriggered;
|
||||
|
||||
public void Start()
|
||||
public void Dispose()
|
||||
{
|
||||
timerLeaveCheck.Dispose();
|
||||
}
|
||||
|
||||
internal void Start()
|
||||
{
|
||||
timerLeaveCheck.Stop();
|
||||
timerLeaveCheck.Start();
|
||||
}
|
||||
|
||||
public void Stop()
|
||||
internal void Stop()
|
||||
{
|
||||
timerLeaveCheck.Stop();
|
||||
}
|
||||
|
||||
private void TimerLeaveCheckTick(object sender, EventArgs e)
|
||||
internal void TimerLeaveCheckTick(object sender, EventArgs e)
|
||||
{
|
||||
timerLeaveCheck.Stop();
|
||||
LeaveTriggered?.Invoke();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
timerLeaveCheck.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,8 +13,6 @@ namespace SystemTrayMenu.Handler
|
|||
|
||||
internal class WaitToLoadMenu : IDisposable
|
||||
{
|
||||
internal bool MouseActive = false;
|
||||
|
||||
private readonly Timer timerStartLoad = new Timer();
|
||||
private DataGridView dgv = null;
|
||||
private int rowIndex = 0;
|
||||
|
@ -39,6 +37,16 @@ namespace SystemTrayMenu.Handler
|
|||
|
||||
internal event Action<DataGridView, int> MouseEnterOk;
|
||||
|
||||
internal bool MouseActive { get; set; } = false;
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
timerStartLoad.Stop();
|
||||
timerStartLoad.Dispose();
|
||||
dgv?.Dispose();
|
||||
dgvTmp?.Dispose();
|
||||
}
|
||||
|
||||
internal void MouseEnter(object sender, DataGridViewCellEventArgs e)
|
||||
{
|
||||
if (MouseActive)
|
||||
|
@ -193,13 +201,5 @@ namespace SystemTrayMenu.Handler
|
|||
this.rowIndex = 0;
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
timerStartLoad.Stop();
|
||||
timerStartLoad.Dispose();
|
||||
dgv?.Dispose();
|
||||
dgvTmp?.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
19
Config/AppColors.cs
Normal file
19
Config/AppColors.cs
Normal file
|
@ -0,0 +1,19 @@
|
|||
// <copyright file="AppColors.cs" company="PlaceholderCompany">
|
||||
// Copyright (c) PlaceholderCompany. All rights reserved.
|
||||
// </copyright>
|
||||
|
||||
namespace SystemTrayMenu
|
||||
{
|
||||
using System.Drawing;
|
||||
|
||||
internal static class AppColors
|
||||
{
|
||||
internal static readonly Color Blue = Color.FromArgb(204, 232, 255);
|
||||
internal static readonly Color BlueBorder = Color.FromArgb(153, 209, 255);
|
||||
internal static readonly Color Green = Color.FromArgb(194, 245, 222);
|
||||
internal static readonly Color GreenBorder = Color.FromArgb(153, 255, 165);
|
||||
internal static readonly Color Red = Color.FromArgb(255, 204, 232);
|
||||
internal static readonly Color Yellow = Color.LightYellow;
|
||||
internal static readonly Color Azure = Color.Azure;
|
||||
}
|
||||
}
|
|
@ -8,7 +8,7 @@ namespace SystemTrayMenu
|
|||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Windows.Forms;
|
||||
using SystemTrayMenu.UserInterface.Dialogs;
|
||||
using SystemTrayMenu.UserInterface.FolderBrowseDialog;
|
||||
using SystemTrayMenu.Utilities;
|
||||
|
||||
public static class Config
|
||||
|
|
|
@ -23,15 +23,4 @@ namespace SystemTrayMenu
|
|||
internal static readonly Color ColorTitleSelected = AppColors.Yellow;
|
||||
internal static readonly Color ColorTitleBackground = AppColors.Azure;
|
||||
}
|
||||
|
||||
internal static class AppColors
|
||||
{
|
||||
internal static readonly Color Blue = Color.FromArgb(204, 232, 255);
|
||||
internal static readonly Color BlueBorder = Color.FromArgb(153, 209, 255);
|
||||
internal static readonly Color Green = Color.FromArgb(194, 245, 222);
|
||||
internal static readonly Color GreenBorder = Color.FromArgb(153, 255, 165);
|
||||
internal static readonly Color Red = Color.FromArgb(255, 204, 232);
|
||||
internal static readonly Color Yellow = Color.LightYellow;
|
||||
internal static readonly Color Azure = Color.Azure;
|
||||
}
|
||||
}
|
|
@ -4,7 +4,6 @@
|
|||
|
||||
namespace SystemTrayMenu.DataClasses
|
||||
{
|
||||
using IWshRuntimeLibrary;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
|
@ -16,24 +15,13 @@ namespace SystemTrayMenu.DataClasses
|
|||
using System.Security;
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
using IWshRuntimeLibrary;
|
||||
using SystemTrayMenu.Utilities;
|
||||
using TAFactory.IconPack;
|
||||
using Menu = SystemTrayMenu.UserInterface.Menu;
|
||||
|
||||
internal class RowData : IDisposable
|
||||
{
|
||||
internal FileInfo FileInfo;
|
||||
internal Menu SubMenu;
|
||||
internal bool IsMenuOpen;
|
||||
internal bool IsSelected;
|
||||
internal bool ContainsMenu;
|
||||
internal bool IsContextMenuOpen;
|
||||
internal bool IsResolvedLnk;
|
||||
internal bool HiddenEntry;
|
||||
internal string TargetFilePath;
|
||||
internal string TargetFilePathOrig;
|
||||
internal int RowIndex;
|
||||
internal int MenuLevel;
|
||||
private static DateTime contextMenuClosed;
|
||||
private string workingDirectory;
|
||||
private string arguments;
|
||||
|
@ -46,6 +34,36 @@ namespace SystemTrayMenu.DataClasses
|
|||
{
|
||||
}
|
||||
|
||||
internal FileInfo FileInfo { get; set; }
|
||||
|
||||
internal Menu SubMenu { get; set; }
|
||||
|
||||
internal bool IsMenuOpen { get; set; }
|
||||
|
||||
internal bool IsSelected { get; set; }
|
||||
|
||||
internal bool ContainsMenu { get; set; }
|
||||
|
||||
internal bool IsContextMenuOpen { get; set; }
|
||||
|
||||
internal bool IsResolvedLnk { get; set; }
|
||||
|
||||
internal bool HiddenEntry { get; set; }
|
||||
|
||||
internal string TargetFilePath { get; set; }
|
||||
|
||||
internal string TargetFilePathOrig { get; set; }
|
||||
|
||||
internal int RowIndex { get; set; }
|
||||
|
||||
internal int MenuLevel { get; set; }
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
internal void SetText(string text)
|
||||
{
|
||||
this.text = text;
|
||||
|
@ -225,12 +243,6 @@ namespace SystemTrayMenu.DataClasses
|
|||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (!isDisposed)
|
||||
|
|
|
@ -4,8 +4,10 @@
|
|||
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
|
||||
[assembly: SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1600:Elements should be documented", Justification = "TODO")]
|
||||
[assembly: SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1601:Partial elements should be documented", Justification = "TODO")]
|
||||
[assembly: SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1602:Enumeration items should be documented", Justification = "TODO")]
|
||||
[assembly: SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA0001:XML comment analysis is disabled due to project configuration", Justification = "no idea what this is")]
|
||||
|
||||
[assembly: SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1600:Elements should be documented", Justification = "we need to document")]
|
||||
[assembly: SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1601:Partial elements should be documented", Justification = "we need to document")]
|
||||
[assembly: SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1602:Enumeration items should be documented", Justification = "we need to document")]
|
||||
|
||||
[assembly: SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1101:Prefix local calls with this", Justification = "Standard codecleanup removes the this")]
|
||||
|
|
|
@ -51,11 +51,25 @@ namespace SystemTrayMenu.UserInterface
|
|||
|
||||
internal bool IsHiding => state == FadingState.Hide;
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
internal void Fade(FadingState state)
|
||||
{
|
||||
StartStopTimer(state);
|
||||
}
|
||||
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
timer.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
private void StartStopTimer(FadingState newState)
|
||||
{
|
||||
if (newState == FadingState.Idle)
|
||||
|
@ -143,19 +157,5 @@ namespace SystemTrayMenu.UserInterface
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
timer.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
28
Helpers/KeyPressedEventArgs.cs
Normal file
28
Helpers/KeyPressedEventArgs.cs
Normal file
|
@ -0,0 +1,28 @@
|
|||
// <copyright file="KeyPressedEventArgs.cs" company="PlaceholderCompany">
|
||||
// Copyright (c) PlaceholderCompany. All rights reserved.
|
||||
// </copyright>
|
||||
|
||||
namespace SystemTrayMenu.Helper
|
||||
{
|
||||
using System;
|
||||
using System.Windows.Forms;
|
||||
|
||||
/// <summary>
|
||||
/// Event Args for the event that is fired after the hot key has been pressed.
|
||||
/// </summary>
|
||||
internal class KeyPressedEventArgs : EventArgs
|
||||
{
|
||||
private readonly KeyboardHookModifierKeys modifier;
|
||||
private readonly Keys key;
|
||||
|
||||
internal KeyPressedEventArgs(KeyboardHookModifierKeys modifier, Keys key)
|
||||
{
|
||||
this.modifier = modifier;
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
internal KeyboardHookModifierKeys Modifier => modifier;
|
||||
|
||||
internal Keys Key => key;
|
||||
}
|
||||
}
|
|
@ -6,7 +6,7 @@ namespace SystemTrayMenu.Helper
|
|||
{
|
||||
using System;
|
||||
using System.Windows.Forms;
|
||||
using SystemTrayMenu.UserInterface.Controls;
|
||||
using SystemTrayMenu.UserInterface.HotkeyTextboxControl;
|
||||
using SystemTrayMenu.Utilities;
|
||||
|
||||
/// <summary>
|
||||
|
@ -160,23 +160,4 @@ namespace SystemTrayMenu.Helper
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Event Args for the event that is fired after the hot key has been pressed.
|
||||
/// </summary>
|
||||
internal class KeyPressedEventArgs : EventArgs
|
||||
{
|
||||
private readonly KeyboardHookModifierKeys modifier;
|
||||
private readonly Keys key;
|
||||
|
||||
internal KeyPressedEventArgs(KeyboardHookModifierKeys modifier, Keys key)
|
||||
{
|
||||
this.modifier = modifier;
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
internal KeyboardHookModifierKeys Modifier => modifier;
|
||||
|
||||
internal Keys Key => key;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,13 +12,13 @@ namespace SystemTrayMenu.DllImports
|
|||
/// </summary>
|
||||
public static partial class NativeMethods
|
||||
{
|
||||
// The CreatePopupMenu function creates a drop-down menu, submenu, or shortcut menu. The menu is initially empty. You can insert or append menu items by using the InsertMenuItem function. You can also use the InsertMenu function to insert menu items and the AppendMenu function to append menu items.
|
||||
[DllImport("user32", SetLastError = true, CharSet = CharSet.Unicode)]
|
||||
private static extern IntPtr CreatePopupMenu();
|
||||
|
||||
public static IntPtr User32CreatePopupMenu()
|
||||
{
|
||||
return CreatePopupMenu();
|
||||
}
|
||||
|
||||
// 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.
|
||||
[DllImport("user32", SetLastError = true, CharSet = CharSet.Unicode)]
|
||||
private static extern IntPtr CreatePopupMenu();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,12 +12,12 @@ namespace SystemTrayMenu.DllImports
|
|||
/// </summary>
|
||||
public static partial class NativeMethods
|
||||
{
|
||||
[DllImport("User32.dll")]
|
||||
private static extern int DestroyIcon(IntPtr hIcon);
|
||||
|
||||
public static void User32DestroyIcon(IntPtr hIcon)
|
||||
{
|
||||
_ = DestroyIcon(hIcon);
|
||||
}
|
||||
|
||||
[DllImport("User32.dll")]
|
||||
private static extern int DestroyIcon(IntPtr hIcon);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,13 +12,13 @@ namespace SystemTrayMenu.DllImports
|
|||
/// </summary>
|
||||
public static partial class NativeMethods
|
||||
{
|
||||
// The DestroyMenu function destroys the specified menu and frees any memory that the menu occupies.
|
||||
[DllImport("user32", SetLastError = true, CharSet = CharSet.Unicode)]
|
||||
private static extern bool DestroyMenu(IntPtr hMenu);
|
||||
|
||||
public static bool User32DestroyMenu(IntPtr hMenu)
|
||||
{
|
||||
return DestroyMenu(hMenu);
|
||||
}
|
||||
|
||||
// The DestroyMenu function destroys the specified menu and frees any memory that the menu occupies.
|
||||
[DllImport("user32", SetLastError = true, CharSet = CharSet.Unicode)]
|
||||
private static extern bool DestroyMenu(IntPtr hMenu);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,12 +12,12 @@ namespace SystemTrayMenu.DllImports
|
|||
/// </summary>
|
||||
public static partial class NativeMethods
|
||||
{
|
||||
[DllImport("shell32.dll", CharSet = CharSet.Unicode)]
|
||||
private static extern int FindExecutable(string lpFile, string lpDirectory, [Out] StringBuilder lpResult);
|
||||
|
||||
public static void Shell32FindExecutable(string lpFile, string lpDirectory, [Out] StringBuilder lpResult)
|
||||
{
|
||||
_ = FindExecutable(lpFile, lpDirectory, lpResult);
|
||||
}
|
||||
|
||||
[DllImport("shell32.dll", CharSet = CharSet.Unicode)]
|
||||
private static extern int FindExecutable(string lpFile, string lpDirectory, [Out] StringBuilder lpResult);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,13 +12,13 @@ namespace SystemTrayMenu.DllImports
|
|||
/// </summary>
|
||||
public static partial class NativeMethods
|
||||
{
|
||||
// Determines the default menu item on the specified menu
|
||||
[DllImport("user32", SetLastError = true, CharSet = CharSet.Unicode)]
|
||||
private static extern int GetMenuDefaultItem(IntPtr hMenu, bool fByPos, uint gmdiFlags);
|
||||
|
||||
public static int User32GetMenuDefaultItem(IntPtr hMenu, bool fByPos, uint gmdiFlags)
|
||||
{
|
||||
return GetMenuDefaultItem(hMenu, fByPos, gmdiFlags);
|
||||
}
|
||||
|
||||
// Determines the default menu item on the specified menu
|
||||
[DllImport("user32", SetLastError = true, CharSet = CharSet.Unicode)]
|
||||
private static extern int GetMenuDefaultItem(IntPtr hMenu, bool fByPos, uint gmdiFlags);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,20 +13,6 @@ namespace SystemTrayMenu.DllImports
|
|||
/// </summary>
|
||||
public static partial class NativeMethods
|
||||
{
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
private static extern bool RegisterHotKey(IntPtr hWnd, int id, uint fsModifiers, uint virtualKeyCode);
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
private static extern bool UnregisterHotKey(IntPtr hWnd, int id);
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
private static extern uint MapVirtualKey(uint uCode, uint uMapType);
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
|
||||
private static extern int GetKeyNameText(uint lParam, [Out] StringBuilder lpString, int nSize);
|
||||
|
||||
public static bool User32RegisterHotKey(IntPtr hWnd, int id, uint fsModifiers, uint vk)
|
||||
{
|
||||
return RegisterHotKey(hWnd, id, fsModifiers, vk);
|
||||
|
@ -46,5 +32,19 @@ namespace SystemTrayMenu.DllImports
|
|||
{
|
||||
return GetKeyNameText(lParam, lpString, nSize);
|
||||
}
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
private static extern bool RegisterHotKey(IntPtr hWnd, int id, uint fsModifiers, uint virtualKeyCode);
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
private static extern bool UnregisterHotKey(IntPtr hWnd, int id);
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
private static extern uint MapVirtualKey(uint uCode, uint uMapType);
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
|
||||
private static extern int GetKeyNameText(uint lParam, [Out] StringBuilder lpString, int nSize);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,13 +12,13 @@ namespace SystemTrayMenu.DllImports
|
|||
/// </summary>
|
||||
public static partial class NativeMethods
|
||||
{
|
||||
// Retrieves the IShellFolder interface for the desktop folder, which is the root of the Shell's namespace.
|
||||
[DllImport("shell32.dll")]
|
||||
private static extern int SHGetDesktopFolder(out IntPtr ppshf);
|
||||
|
||||
public static int Shell32SHGetDesktopFolder(out IntPtr ppshf)
|
||||
{
|
||||
return SHGetDesktopFolder(out ppshf);
|
||||
}
|
||||
|
||||
// Retrieves the IShellFolder interface for the desktop folder, which is the root of the Shell's namespace.
|
||||
[DllImport("shell32.dll")]
|
||||
private static extern int SHGetDesktopFolder(out IntPtr ppshf);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,12 +13,12 @@ namespace SystemTrayMenu.DllImports
|
|||
/// </summary>
|
||||
public static partial class NativeMethods
|
||||
{
|
||||
[DllImport("shfolder.dll", CharSet = CharSet.Unicode)]
|
||||
private static extern int SHGetFolderPath(IntPtr hwndOwner, int nFolder, IntPtr hToken, int dwFlags, StringBuilder lpszPath);
|
||||
|
||||
public static int ShfolderSHGetFolderPath(IntPtr hwndOwner, int nFolder, IntPtr hToken, int dwFlags, StringBuilder lpszPath)
|
||||
{
|
||||
return SHGetFolderPath(hwndOwner, nFolder, hToken, dwFlags, lpszPath);
|
||||
}
|
||||
|
||||
[DllImport("shfolder.dll", CharSet = CharSet.Unicode)]
|
||||
private static extern int SHGetFolderPath(IntPtr hwndOwner, int nFolder, IntPtr hToken, int dwFlags, StringBuilder lpszPath);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,12 +11,12 @@ namespace SystemTrayMenu.DllImports
|
|||
/// </summary>
|
||||
public static partial class NativeMethods
|
||||
{
|
||||
[DllImport("user32.dll")]
|
||||
private static extern bool SetProcessDPIAware();
|
||||
|
||||
public static void User32SetProcessDPIAware()
|
||||
{
|
||||
_ = SetProcessDPIAware();
|
||||
}
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
private static extern bool SetProcessDPIAware();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,12 +11,12 @@ namespace SystemTrayMenu.DllImports
|
|||
/// </summary>
|
||||
public static partial class NativeMethods
|
||||
{
|
||||
[DllImport("shlwapi.dll", CharSet = CharSet.Unicode, ExactSpelling = true)]
|
||||
private static extern int StrCmpLogicalW(string x, string y);
|
||||
|
||||
public static int ShlwapiStrCmpLogicalW(string x, string y)
|
||||
{
|
||||
return StrCmpLogicalW(x, y);
|
||||
}
|
||||
|
||||
[DllImport("shlwapi.dll", CharSet = CharSet.Unicode, ExactSpelling = true)]
|
||||
private static extern int StrCmpLogicalW(string x, string y);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,13 +13,13 @@ namespace SystemTrayMenu.DllImports
|
|||
/// </summary>
|
||||
public static partial class NativeMethods
|
||||
{
|
||||
// Takes a STRRET structure returned by IShellFolder::GetDisplayNameOf, converts it to a string, and places the result in a buffer.
|
||||
[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);
|
||||
|
||||
public static int ShlwapiStrRetToBuf(IntPtr pstr, IntPtr pidl, StringBuilder pszBuf, int cchBuf)
|
||||
{
|
||||
return StrRetToBuf(pstr, pidl, pszBuf, cchBuf);
|
||||
}
|
||||
|
||||
// Takes a STRRET structure returned by IShellFolder::GetDisplayNameOf, converts it to a string, and places the result in a buffer.
|
||||
[DllImport("shlwapi.dll", EntryPoint = "StrRetToBuf", ExactSpelling = false, CharSet = CharSet.Unicode, SetLastError = true)]
|
||||
private static extern int StrRetToBuf(IntPtr pstr, IntPtr pidl, StringBuilder pszBuf, int cchBuf);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,5 +39,5 @@ using System.Runtime.InteropServices;
|
|||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("0.11.4.3")]
|
||||
[assembly: AssemblyFileVersion("0.11.4.3")]
|
||||
[assembly: AssemblyVersion("0.11.4.4")]
|
||||
[assembly: AssemblyFileVersion("0.11.4.4")]
|
||||
|
|
|
@ -197,10 +197,6 @@
|
|||
</BootstrapperPackage>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="3.0.0">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="StyleCop.Analyzers.Unstable" Version="1.2.0.164">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
|
||||
namespace SystemTrayMenu.UserInterface
|
||||
{
|
||||
using Microsoft.Win32;
|
||||
using System;
|
||||
using System.Collections.Specialized;
|
||||
using System.Drawing;
|
||||
|
@ -14,6 +13,7 @@ namespace SystemTrayMenu.UserInterface
|
|||
using System.Security;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Windows.Forms;
|
||||
using Microsoft.Win32;
|
||||
using SystemTrayMenu.Utilities;
|
||||
|
||||
/// <summary>
|
||||
|
@ -189,14 +189,6 @@ namespace SystemTrayMenu.UserInterface
|
|||
set => buttonDetails.Visible = value;
|
||||
}
|
||||
|
||||
private void TabPanelDetails_SelectedIndexChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (TabPanelDetails.SelectedTab == TabPageAssemblyDetails)
|
||||
{
|
||||
AssemblyNamesComboBox.Focus();
|
||||
}
|
||||
}
|
||||
|
||||
// <summary>
|
||||
// exception-safe retrieval of LastWriteTime for this assembly.
|
||||
// </summary>
|
||||
|
@ -438,6 +430,64 @@ namespace SystemTrayMenu.UserInterface
|
|||
return strSysInfoPath;
|
||||
}
|
||||
|
||||
// <summary>
|
||||
// populate a listview with the specified key and value strings
|
||||
// </summary>
|
||||
private static void Populate(ListView lvw, string key, string value)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(value))
|
||||
{
|
||||
ListViewItem lvi = new ListViewItem
|
||||
{
|
||||
Text = key,
|
||||
};
|
||||
lvi.SubItems.Add(value);
|
||||
lvw.Items.Add(lvi);
|
||||
}
|
||||
}
|
||||
|
||||
// <summary>
|
||||
// populate details for a single assembly
|
||||
// </summary>
|
||||
private static void PopulateAssemblyDetails(Assembly a, ListView lvw)
|
||||
{
|
||||
lvw.Items.Clear();
|
||||
|
||||
// this assembly property is only available in framework versions 1.1+
|
||||
Populate(lvw, "Image Runtime Version", a.ImageRuntimeVersion);
|
||||
Populate(lvw, "Loaded from GAC", a.GlobalAssemblyCache.ToString(CultureInfo.InvariantCulture));
|
||||
|
||||
NameValueCollection nvc = AssemblyAttribs(a);
|
||||
foreach (string strKey in nvc)
|
||||
{
|
||||
Populate(lvw, strKey, nvc[strKey]);
|
||||
}
|
||||
}
|
||||
|
||||
// <summary>
|
||||
// matches assembly by Assembly.GetName.Name; returns nothing if no match
|
||||
// </summary>
|
||||
private static Assembly MatchAssemblyByName(string assemblyName)
|
||||
{
|
||||
foreach (Assembly a in AppDomain.CurrentDomain.GetAssemblies())
|
||||
{
|
||||
if (a.GetName().Name == assemblyName)
|
||||
{
|
||||
return a;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private void TabPanelDetails_SelectedIndexChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (TabPanelDetails.SelectedTab == TabPageAssemblyDetails)
|
||||
{
|
||||
AssemblyNamesComboBox.Focus();
|
||||
}
|
||||
}
|
||||
|
||||
// <summary>
|
||||
// launch the MSInfo "system information" application (works on XP, 2003, and Vista)
|
||||
// </summary>
|
||||
|
@ -464,22 +514,6 @@ namespace SystemTrayMenu.UserInterface
|
|||
Log.ProcessStart(strSysInfoPath);
|
||||
}
|
||||
|
||||
// <summary>
|
||||
// populate a listview with the specified key and value strings
|
||||
// </summary>
|
||||
private static void Populate(ListView lvw, string key, string value)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(value))
|
||||
{
|
||||
ListViewItem lvi = new ListViewItem
|
||||
{
|
||||
Text = key,
|
||||
};
|
||||
lvi.SubItems.Add(value);
|
||||
lvw.Items.Add(lvi);
|
||||
}
|
||||
}
|
||||
|
||||
// <summary>
|
||||
// populates the Application Information listview
|
||||
// </summary>
|
||||
|
@ -620,40 +654,6 @@ namespace SystemTrayMenu.UserInterface
|
|||
return s;
|
||||
}
|
||||
|
||||
// <summary>
|
||||
// populate details for a single assembly
|
||||
// </summary>
|
||||
private static void PopulateAssemblyDetails(Assembly a, ListView lvw)
|
||||
{
|
||||
lvw.Items.Clear();
|
||||
|
||||
// this assembly property is only available in framework versions 1.1+
|
||||
Populate(lvw, "Image Runtime Version", a.ImageRuntimeVersion);
|
||||
Populate(lvw, "Loaded from GAC", a.GlobalAssemblyCache.ToString(CultureInfo.InvariantCulture));
|
||||
|
||||
NameValueCollection nvc = AssemblyAttribs(a);
|
||||
foreach (string strKey in nvc)
|
||||
{
|
||||
Populate(lvw, strKey, nvc[strKey]);
|
||||
}
|
||||
}
|
||||
|
||||
// <summary>
|
||||
// matches assembly by Assembly.GetName.Name; returns nothing if no match
|
||||
// </summary>
|
||||
private static Assembly MatchAssemblyByName(string assemblyName)
|
||||
{
|
||||
foreach (Assembly a in AppDomain.CurrentDomain.GetAssemblies())
|
||||
{
|
||||
if (a.GetName().Name == assemblyName)
|
||||
{
|
||||
return a;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
// <summary>
|
||||
// things to do when form is loaded
|
||||
// </summary>
|
||||
|
|
|
@ -82,14 +82,6 @@ namespace SystemTrayMenu.UserInterface
|
|||
|
||||
public event EventHandlerEmpty Exit;
|
||||
|
||||
private void VerifyClick(MouseEventArgs e)
|
||||
{
|
||||
if (e.Button == MouseButtons.Left)
|
||||
{
|
||||
Click?.Invoke();
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
notifyIcon.Icon = null;
|
||||
|
@ -109,6 +101,14 @@ namespace SystemTrayMenu.UserInterface
|
|||
threadsLoading = false;
|
||||
}
|
||||
|
||||
private void VerifyClick(MouseEventArgs e)
|
||||
{
|
||||
if (e.Button == MouseButtons.Left)
|
||||
{
|
||||
Click?.Invoke();
|
||||
}
|
||||
}
|
||||
|
||||
private void Load_Tick(object sender, EventArgs e)
|
||||
{
|
||||
if (threadsLoading)
|
||||
|
|
157
UserInterface/FolderBrowseDialog/FolderDialog.cs
Normal file
157
UserInterface/FolderBrowseDialog/FolderDialog.cs
Normal file
|
@ -0,0 +1,157 @@
|
|||
// <copyright file="FolderDialog.cs" company="PlaceholderCompany">
|
||||
// Copyright (c) PlaceholderCompany. All rights reserved.
|
||||
// </copyright>
|
||||
|
||||
namespace SystemTrayMenu.UserInterface.FolderBrowseDialog
|
||||
{
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Windows.Forms;
|
||||
using SystemTrayMenu.Utilities;
|
||||
|
||||
public class FolderDialog : IFolderDialog, IDisposable
|
||||
{
|
||||
private bool isDisposed;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets /sets folder in which dialog will be open.
|
||||
/// </summary>
|
||||
public string InitialFolder { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets /sets directory in which dialog will be open
|
||||
/// if there is no recent directory available.
|
||||
/// </summary>
|
||||
public string DefaultFolder { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets selected folder.
|
||||
/// </summary>
|
||||
public string Folder { get; set; }
|
||||
|
||||
public DialogResult ShowDialog()
|
||||
{
|
||||
return ShowDialog(owner: new WindowWrapper(IntPtr.Zero));
|
||||
}
|
||||
|
||||
public DialogResult ShowDialog(IWin32Window owner)
|
||||
{
|
||||
if (Environment.OSVersion.Version.Major >= 6)
|
||||
{
|
||||
return ShowVistaDialog(owner);
|
||||
}
|
||||
else
|
||||
{
|
||||
return ShowLegacyDialog(owner);
|
||||
}
|
||||
}
|
||||
|
||||
public DialogResult ShowVistaDialog(IWin32Window owner)
|
||||
{
|
||||
NativeMethods.IFileDialog frm = (NativeMethods.IFileDialog)new NativeMethods.FileOpenDialogRCW();
|
||||
frm.GetOptions(out uint options);
|
||||
options |= NativeMethods.FOS_PICKFOLDERS |
|
||||
NativeMethods.FOS_FORCEFILESYSTEM |
|
||||
NativeMethods.FOS_NOVALIDATE |
|
||||
NativeMethods.FOS_NOTESTFILECREATE |
|
||||
NativeMethods.FOS_DONTADDTORECENT;
|
||||
frm.SetOptions(options);
|
||||
if (InitialFolder != null)
|
||||
{
|
||||
Guid riid = new Guid("43826D1E-E718-42EE-BC55-A1E261C37BFE"); // IShellItem
|
||||
if (NativeMethods.SHCreateItemFromParsingName(
|
||||
InitialFolder,
|
||||
IntPtr.Zero,
|
||||
ref riid,
|
||||
out NativeMethods.IShellItem directoryShellItem) == NativeMethods.S_OK)
|
||||
{
|
||||
frm.SetFolder(directoryShellItem);
|
||||
}
|
||||
}
|
||||
|
||||
if (DefaultFolder != null)
|
||||
{
|
||||
Guid riid = new Guid("43826D1E-E718-42EE-BC55-A1E261C37BFE"); // IShellItem
|
||||
if (NativeMethods.SHCreateItemFromParsingName(
|
||||
DefaultFolder,
|
||||
IntPtr.Zero,
|
||||
ref riid,
|
||||
out NativeMethods.IShellItem directoryShellItem) == NativeMethods.S_OK)
|
||||
{
|
||||
frm.SetDefaultFolder(directoryShellItem);
|
||||
}
|
||||
}
|
||||
|
||||
if (owner != null && frm.Show(owner.Handle) == NativeMethods.S_OK)
|
||||
{
|
||||
if (frm.GetResult(out NativeMethods.IShellItem shellItem) == NativeMethods.S_OK)
|
||||
{
|
||||
if (shellItem.GetDisplayName(
|
||||
NativeMethods.SIGDN_FILESYSPATH,
|
||||
out IntPtr pszString) == NativeMethods.S_OK)
|
||||
{
|
||||
if (pszString != IntPtr.Zero)
|
||||
{
|
||||
try
|
||||
{
|
||||
Folder = Marshal.PtrToStringAuto(pszString);
|
||||
return DialogResult.OK;
|
||||
}
|
||||
finally
|
||||
{
|
||||
Marshal.FreeCoTaskMem(pszString);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return DialogResult.Cancel;
|
||||
}
|
||||
|
||||
public DialogResult ShowLegacyDialog(IWin32Window owner)
|
||||
{
|
||||
using SaveFileDialog frm = new SaveFileDialog
|
||||
{
|
||||
CheckFileExists = false,
|
||||
CheckPathExists = true,
|
||||
CreatePrompt = false,
|
||||
Filter = "|" + Guid.Empty.ToString(),
|
||||
FileName = "any",
|
||||
};
|
||||
if (InitialFolder != null)
|
||||
{
|
||||
frm.InitialDirectory = InitialFolder;
|
||||
}
|
||||
|
||||
frm.OverwritePrompt = false;
|
||||
frm.Title = Translator.GetText("Select Folder");
|
||||
frm.ValidateNames = false;
|
||||
if (frm.ShowDialog(owner) == DialogResult.OK)
|
||||
{
|
||||
Folder = Path.GetDirectoryName(frm.FileName);
|
||||
return DialogResult.OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
return DialogResult.Cancel;
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (!isDisposed)
|
||||
{
|
||||
}
|
||||
|
||||
isDisposed = true;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2,7 +2,7 @@
|
|||
// Copyright (c) PlaceholderCompany. All rights reserved.
|
||||
// </copyright>
|
||||
|
||||
namespace SystemTrayMenu.UserInterface.Dialogs
|
||||
namespace SystemTrayMenu.UserInterface.FolderBrowseDialog
|
||||
{
|
||||
using System.Windows.Forms;
|
||||
|
|
@ -1,179 +1,12 @@
|
|||
// <copyright file="FolderDialog.cs" company="PlaceholderCompany">
|
||||
// <copyright file="NativeMethods.cs" company="PlaceholderCompany">
|
||||
// Copyright (c) PlaceholderCompany. All rights reserved.
|
||||
// </copyright>
|
||||
|
||||
namespace SystemTrayMenu.UserInterface.Dialogs
|
||||
namespace SystemTrayMenu.UserInterface.FolderBrowseDialog
|
||||
{
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Windows.Forms;
|
||||
using SystemTrayMenu.Utilities;
|
||||
|
||||
public class FolderDialog : IFolderDialog, IDisposable
|
||||
{
|
||||
private bool isDisposed;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets /sets folder in which dialog will be open.
|
||||
/// </summary>
|
||||
public string InitialFolder { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets /sets directory in which dialog will be open
|
||||
/// if there is no recent directory available.
|
||||
/// </summary>
|
||||
public string DefaultFolder { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets selected folder.
|
||||
/// </summary>
|
||||
public string Folder { get; set; }
|
||||
|
||||
public DialogResult ShowDialog()
|
||||
{
|
||||
return ShowDialog(owner: new WindowWrapper(IntPtr.Zero));
|
||||
}
|
||||
|
||||
public DialogResult ShowDialog(IWin32Window owner)
|
||||
{
|
||||
if (Environment.OSVersion.Version.Major >= 6)
|
||||
{
|
||||
return ShowVistaDialog(owner);
|
||||
}
|
||||
else
|
||||
{
|
||||
return ShowLegacyDialog(owner);
|
||||
}
|
||||
}
|
||||
|
||||
public DialogResult ShowVistaDialog(IWin32Window owner)
|
||||
{
|
||||
NativeMethods.IFileDialog frm = (NativeMethods.IFileDialog)new NativeMethods.FileOpenDialogRCW();
|
||||
frm.GetOptions(out uint options);
|
||||
options |= NativeMethods.FOS_PICKFOLDERS |
|
||||
NativeMethods.FOS_FORCEFILESYSTEM |
|
||||
NativeMethods.FOS_NOVALIDATE |
|
||||
NativeMethods.FOS_NOTESTFILECREATE |
|
||||
NativeMethods.FOS_DONTADDTORECENT;
|
||||
frm.SetOptions(options);
|
||||
if (InitialFolder != null)
|
||||
{
|
||||
Guid riid = new Guid("43826D1E-E718-42EE-BC55-A1E261C37BFE"); // IShellItem
|
||||
if (NativeMethods.SHCreateItemFromParsingName(
|
||||
InitialFolder,
|
||||
IntPtr.Zero,
|
||||
ref riid,
|
||||
out NativeMethods.IShellItem directoryShellItem) == NativeMethods.S_OK)
|
||||
{
|
||||
frm.SetFolder(directoryShellItem);
|
||||
}
|
||||
}
|
||||
|
||||
if (DefaultFolder != null)
|
||||
{
|
||||
Guid riid = new Guid("43826D1E-E718-42EE-BC55-A1E261C37BFE"); // IShellItem
|
||||
if (NativeMethods.SHCreateItemFromParsingName(
|
||||
DefaultFolder,
|
||||
IntPtr.Zero,
|
||||
ref riid,
|
||||
out NativeMethods.IShellItem directoryShellItem) == NativeMethods.S_OK)
|
||||
{
|
||||
frm.SetDefaultFolder(directoryShellItem);
|
||||
}
|
||||
}
|
||||
|
||||
if (owner != null && frm.Show(owner.Handle) == NativeMethods.S_OK)
|
||||
{
|
||||
if (frm.GetResult(out NativeMethods.IShellItem shellItem) == NativeMethods.S_OK)
|
||||
{
|
||||
if (shellItem.GetDisplayName(
|
||||
NativeMethods.SIGDN_FILESYSPATH,
|
||||
out IntPtr pszString) == NativeMethods.S_OK)
|
||||
{
|
||||
if (pszString != IntPtr.Zero)
|
||||
{
|
||||
try
|
||||
{
|
||||
Folder = Marshal.PtrToStringAuto(pszString);
|
||||
return DialogResult.OK;
|
||||
}
|
||||
finally
|
||||
{
|
||||
Marshal.FreeCoTaskMem(pszString);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return DialogResult.Cancel;
|
||||
}
|
||||
|
||||
public DialogResult ShowLegacyDialog(IWin32Window owner)
|
||||
{
|
||||
using SaveFileDialog frm = new SaveFileDialog
|
||||
{
|
||||
CheckFileExists = false,
|
||||
CheckPathExists = true,
|
||||
CreatePrompt = false,
|
||||
Filter = "|" + Guid.Empty.ToString(),
|
||||
FileName = "any",
|
||||
};
|
||||
if (InitialFolder != null)
|
||||
{
|
||||
frm.InitialDirectory = InitialFolder;
|
||||
}
|
||||
|
||||
frm.OverwritePrompt = false;
|
||||
frm.Title = Translator.GetText("Select Folder");
|
||||
frm.ValidateNames = false;
|
||||
if (frm.ShowDialog(owner) == DialogResult.OK)
|
||||
{
|
||||
Folder = Path.GetDirectoryName(frm.FileName);
|
||||
return DialogResult.OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
return DialogResult.Cancel;
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (!isDisposed)
|
||||
{
|
||||
}
|
||||
|
||||
isDisposed = true;
|
||||
}
|
||||
}
|
||||
|
||||
public class WindowWrapper : System.Windows.Forms.IWin32Window
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="WindowWrapper"/> class.
|
||||
/// </summary>
|
||||
/// <param name="handle">Handle to wrap.</param>
|
||||
public WindowWrapper(IntPtr handle)
|
||||
{
|
||||
hwnd = handle;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets original ptr.
|
||||
/// </summary>
|
||||
public IntPtr Handle => hwnd;
|
||||
|
||||
private readonly IntPtr hwnd;
|
||||
}
|
||||
|
||||
internal static class NativeMethods
|
||||
{
|
||||
|
@ -187,14 +20,6 @@ namespace SystemTrayMenu.UserInterface.Dialogs
|
|||
|
||||
public const uint SIGDN_FILESYSPATH = 0x80058000;
|
||||
|
||||
[ComImport]
|
||||
[ClassInterface(ClassInterfaceType.None)]
|
||||
[TypeLibType(TypeLibTypeFlags.FCanCreate)]
|
||||
[Guid("DC1C5A9C-E88A-4DDE-A5A1-60F82A20AEF7")]
|
||||
internal class FileOpenDialogRCW
|
||||
{
|
||||
}
|
||||
|
||||
[ComImport]
|
||||
[Guid("42F85136-DB7E-439C-85F1-E4075D135FC8")]
|
||||
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
||||
|
@ -308,5 +133,13 @@ namespace SystemTrayMenu.UserInterface.Dialogs
|
|||
IntPtr pbc,
|
||||
ref Guid riid,
|
||||
[MarshalAs(UnmanagedType.Interface)] out IShellItem ppv);
|
||||
|
||||
[ComImport]
|
||||
[ClassInterface(ClassInterfaceType.None)]
|
||||
[TypeLibType(TypeLibTypeFlags.FCanCreate)]
|
||||
[Guid("DC1C5A9C-E88A-4DDE-A5A1-60F82A20AEF7")]
|
||||
internal class FileOpenDialogRCW
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
27
UserInterface/FolderBrowseDialog/WindowWrapper.cs
Normal file
27
UserInterface/FolderBrowseDialog/WindowWrapper.cs
Normal file
|
@ -0,0 +1,27 @@
|
|||
// <copyright file="WindowWrapper.cs" company="PlaceholderCompany">
|
||||
// Copyright (c) PlaceholderCompany. All rights reserved.
|
||||
// </copyright>
|
||||
|
||||
namespace SystemTrayMenu.UserInterface.FolderBrowseDialog
|
||||
{
|
||||
using System;
|
||||
|
||||
public class WindowWrapper : System.Windows.Forms.IWin32Window
|
||||
{
|
||||
private readonly IntPtr hwnd;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="WindowWrapper"/> class.
|
||||
/// </summary>
|
||||
/// <param name="handle">Handle to wrap.</param>
|
||||
public WindowWrapper(IntPtr handle)
|
||||
{
|
||||
hwnd = handle;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets original ptr.
|
||||
/// </summary>
|
||||
public IntPtr Handle => hwnd;
|
||||
}
|
||||
}
|
34
UserInterface/HotkeyTextboxControl/EventDelay.cs
Normal file
34
UserInterface/HotkeyTextboxControl/EventDelay.cs
Normal file
|
@ -0,0 +1,34 @@
|
|||
// <copyright file="EventDelay.cs" company="PlaceholderCompany">
|
||||
// Copyright (c) PlaceholderCompany. All rights reserved.
|
||||
// </copyright>
|
||||
|
||||
namespace SystemTrayMenu.UserInterface.HotkeyTextboxControl
|
||||
{
|
||||
using System;
|
||||
|
||||
#pragma warning restore CA1308
|
||||
|
||||
public class EventDelay
|
||||
{
|
||||
private readonly long waitTime;
|
||||
private long lastCheck;
|
||||
|
||||
public EventDelay(long ticks)
|
||||
{
|
||||
waitTime = ticks;
|
||||
}
|
||||
|
||||
public bool Check()
|
||||
{
|
||||
#pragma warning disable CA2002
|
||||
lock (this)
|
||||
#pragma warning restore CA2002
|
||||
{
|
||||
long now = DateTime.Now.Ticks;
|
||||
bool isPassed = now - lastCheck > waitTime;
|
||||
lastCheck = now;
|
||||
return isPassed;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2,7 +2,7 @@
|
|||
// Copyright (c) PlaceholderCompany. All rights reserved.
|
||||
// </copyright>
|
||||
|
||||
namespace SystemTrayMenu.UserInterface.Controls
|
||||
namespace SystemTrayMenu.UserInterface.HotkeyTextboxControl
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
@ -55,24 +55,6 @@ namespace SystemTrayMenu.UserInterface.Controls
|
|||
PopulateModifierLists();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets used to make sure that there is no right-click menu available.
|
||||
/// </summary>
|
||||
public override ContextMenuStrip ContextMenuStrip
|
||||
{
|
||||
get => dummy;
|
||||
set => base.ContextMenuStrip = dummy;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether forces the control to be non-multiline.
|
||||
/// </summary>
|
||||
public override bool Multiline
|
||||
{
|
||||
get => base.Multiline;
|
||||
set => base.Multiline = false;
|
||||
}
|
||||
|
||||
// Delegates for hooking up events.
|
||||
public delegate void HotKeyHandler();
|
||||
|
||||
|
@ -96,143 +78,21 @@ namespace SystemTrayMenu.UserInterface.Controls
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Populates the ArrayLists specifying disallowed hotkeys
|
||||
/// such as Shift+A, Ctrl+Alt+4 (would produce a dollar sign) etc.
|
||||
/// Gets or sets used to make sure that there is no right-click menu available.
|
||||
/// </summary>
|
||||
private void PopulateModifierLists()
|
||||
public override ContextMenuStrip ContextMenuStrip
|
||||
{
|
||||
// Shift + 0 - 9, A - Z
|
||||
for (Keys k = Keys.D0; k <= Keys.Z; k++)
|
||||
{
|
||||
needNonShiftModifier.Add((int)k);
|
||||
}
|
||||
|
||||
// Shift + Numpad keys
|
||||
for (Keys k = Keys.NumPad0; k <= Keys.NumPad9; k++)
|
||||
{
|
||||
needNonShiftModifier.Add((int)k);
|
||||
}
|
||||
|
||||
// Shift + Misc (,;<./ etc)
|
||||
for (Keys k = Keys.Oem1; k <= Keys.OemBackslash; k++)
|
||||
{
|
||||
needNonShiftModifier.Add((int)k);
|
||||
}
|
||||
|
||||
// Shift + Space, PgUp, PgDn, End, Home
|
||||
for (Keys k = Keys.Space; k <= Keys.Home; k++)
|
||||
{
|
||||
needNonShiftModifier.Add((int)k);
|
||||
}
|
||||
|
||||
// Misc keys that we can't loop through
|
||||
needNonShiftModifier.Add((int)Keys.Insert);
|
||||
needNonShiftModifier.Add((int)Keys.Help);
|
||||
needNonShiftModifier.Add((int)Keys.Multiply);
|
||||
needNonShiftModifier.Add((int)Keys.Add);
|
||||
needNonShiftModifier.Add((int)Keys.Subtract);
|
||||
needNonShiftModifier.Add((int)Keys.Divide);
|
||||
needNonShiftModifier.Add((int)Keys.Decimal);
|
||||
needNonShiftModifier.Add((int)Keys.Return);
|
||||
needNonShiftModifier.Add((int)Keys.Escape);
|
||||
needNonShiftModifier.Add((int)Keys.NumLock);
|
||||
|
||||
// Ctrl+Alt + 0 - 9
|
||||
for (Keys k = Keys.D0; k <= Keys.D9; k++)
|
||||
{
|
||||
needNonAltGrModifier.Add((int)k);
|
||||
}
|
||||
get => dummy;
|
||||
set => base.ContextMenuStrip = dummy;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets this hotkey control to None.
|
||||
/// Gets or sets a value indicating whether forces the control to be non-multiline.
|
||||
/// </summary>
|
||||
public new void Clear()
|
||||
public override bool Multiline
|
||||
{
|
||||
Hotkey = Keys.None;
|
||||
HotkeyModifiers = Keys.None;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fires when a key is pushed down. Here, we'll want to update the text in the box
|
||||
/// to notify the user what combination is currently pressed.
|
||||
/// </summary>
|
||||
private void HotkeyControl_KeyDown(object sender, KeyEventArgs e)
|
||||
{
|
||||
// Clear the current hotkey
|
||||
if (e.KeyCode == Keys.Back || e.KeyCode == Keys.Delete)
|
||||
{
|
||||
ResetHotkey();
|
||||
}
|
||||
else
|
||||
{
|
||||
modifiers = e.Modifiers;
|
||||
hotkey = e.KeyCode;
|
||||
Redraw();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fires when all keys are released. If the current hotkey isn't valid, reset it.
|
||||
/// Otherwise, do nothing and keep the text and hotkey as it was.
|
||||
/// </summary>
|
||||
private void HotkeyControl_KeyUp(object sender, KeyEventArgs e)
|
||||
{
|
||||
// Somehow the PrintScreen only comes as a keyup, therefore we handle it here.
|
||||
if (e.KeyCode == Keys.PrintScreen)
|
||||
{
|
||||
modifiers = e.Modifiers;
|
||||
hotkey = e.KeyCode;
|
||||
Redraw();
|
||||
}
|
||||
|
||||
if (hotkey == Keys.None && ModifierKeys == Keys.None)
|
||||
{
|
||||
ResetHotkey();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Prevents the letter/whatever entered to show up in the TextBox
|
||||
/// Without this, a "A" key press would appear as "aControl, Alt + A".
|
||||
/// </summary>
|
||||
private void HotkeyControl_KeyPress(object sender, KeyPressEventArgs e)
|
||||
{
|
||||
e.Handled = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles some misc keys, such as Ctrl+Delete and Shift+Insert.
|
||||
/// </summary>
|
||||
/// <param name="msg">msg.</param>
|
||||
/// <param name="keyData">keyData.</param>
|
||||
/// <returns>bool if handled.</returns>
|
||||
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
|
||||
{
|
||||
if (keyData == Keys.Delete || keyData == (Keys.Control | Keys.Delete))
|
||||
{
|
||||
ResetHotkey();
|
||||
return true;
|
||||
}
|
||||
|
||||
// Paste
|
||||
if (keyData == (Keys.Shift | Keys.Insert))
|
||||
{
|
||||
return true; // Don't allow
|
||||
}
|
||||
|
||||
// Allow the rest
|
||||
return base.ProcessCmdKey(ref msg, keyData);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clears the current hotkey and resets the TextBox.
|
||||
/// </summary>
|
||||
public void ResetHotkey()
|
||||
{
|
||||
hotkey = Keys.None;
|
||||
modifiers = Keys.None;
|
||||
Redraw();
|
||||
get => base.Multiline;
|
||||
set => base.Multiline = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -248,17 +108,6 @@ namespace SystemTrayMenu.UserInterface.Controls
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Used to get/set the hotkey (e.g. Keys.A).
|
||||
/// </summary>
|
||||
/// <param name="hotkey">hotkey.</param>
|
||||
public void SetHotkey(string hotkey)
|
||||
{
|
||||
this.hotkey = HotkeyFromString(hotkey);
|
||||
modifiers = HotkeyModifiersFromString(hotkey);
|
||||
Redraw(true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets used to get/set the modifier keys (e.g. Keys.Alt | Keys.Control).
|
||||
/// </summary>
|
||||
|
@ -272,80 +121,6 @@ namespace SystemTrayMenu.UserInterface.Controls
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Redraws the TextBox when necessary.
|
||||
/// </summary>
|
||||
/// <param name="bCalledProgramatically">Specifies whether this function was called by the Hotkey/HotkeyModifiers properties or by the user.</param>
|
||||
private void Redraw(bool bCalledProgramatically = false)
|
||||
{
|
||||
// No hotkey set
|
||||
if (hotkey == Keys.None)
|
||||
{
|
||||
Text = string.Empty;
|
||||
return;
|
||||
}
|
||||
|
||||
// LWin/RWin doesn't work as hotkeys (neither do they work as modifier keys in .NET 2.0)
|
||||
if (hotkey == Keys.LWin || hotkey == Keys.RWin)
|
||||
{
|
||||
Text = string.Empty;
|
||||
return;
|
||||
}
|
||||
|
||||
// Only validate input if it comes from the user
|
||||
if (bCalledProgramatically == false)
|
||||
{
|
||||
// No modifier or shift only, AND a hotkey that needs another modifier
|
||||
if ((modifiers == Keys.Shift || modifiers == Keys.None) && needNonShiftModifier.Contains((int)hotkey))
|
||||
{
|
||||
if (modifiers == Keys.None)
|
||||
{
|
||||
// Set Ctrl+Alt as the modifier unless Ctrl+Alt+<key> won't work...
|
||||
if (needNonAltGrModifier.Contains((int)hotkey) == false)
|
||||
{
|
||||
modifiers = Keys.Alt | Keys.Control;
|
||||
}
|
||||
else
|
||||
{
|
||||
// ... in that case, use Shift+Alt instead.
|
||||
modifiers = Keys.Alt | Keys.Shift;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// User pressed Shift and an invalid key (e.g. a letter or a number),
|
||||
// that needs another set of modifier keys
|
||||
hotkey = Keys.None;
|
||||
Text = string.Empty;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Check all Ctrl+Alt keys
|
||||
if ((modifiers == (Keys.Alt | Keys.Control)) && needNonAltGrModifier.Contains((int)hotkey))
|
||||
{
|
||||
// Ctrl+Alt+4 etc won't work; reset hotkey and tell the user
|
||||
hotkey = Keys.None;
|
||||
Text = string.Empty;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// I have no idea why this is needed, but it is. Without this code, pressing only Ctrl
|
||||
// will show up as "Control + ControlKey", etc.
|
||||
if (hotkey == Keys.Menu /* Alt */ || hotkey == Keys.ShiftKey || hotkey == Keys.ControlKey)
|
||||
{
|
||||
hotkey = Keys.None;
|
||||
}
|
||||
|
||||
Text = HotkeyToLocalizedString(modifiers, hotkey);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return HotkeyToString(HotkeyModifiers, Hotkey);
|
||||
}
|
||||
|
||||
public static string GetLocalizedHotkeyStringFromString(string hotkeyString)
|
||||
{
|
||||
Keys virtualKeyCode = HotkeyFromString(hotkeyString);
|
||||
|
@ -679,30 +454,230 @@ namespace SystemTrayMenu.UserInterface.Controls
|
|||
return givenKey.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore CA1308
|
||||
|
||||
public class EventDelay
|
||||
{
|
||||
private readonly long waitTime;
|
||||
private long lastCheck;
|
||||
|
||||
public EventDelay(long ticks)
|
||||
/// <summary>
|
||||
/// Resets this hotkey control to None.
|
||||
/// </summary>
|
||||
public new void Clear()
|
||||
{
|
||||
waitTime = ticks;
|
||||
Hotkey = Keys.None;
|
||||
HotkeyModifiers = Keys.None;
|
||||
}
|
||||
|
||||
public bool Check()
|
||||
/// <summary>
|
||||
/// Clears the current hotkey and resets the TextBox.
|
||||
/// </summary>
|
||||
public void ResetHotkey()
|
||||
{
|
||||
#pragma warning disable CA2002
|
||||
lock (this)
|
||||
#pragma warning restore CA2002
|
||||
hotkey = Keys.None;
|
||||
modifiers = Keys.None;
|
||||
Redraw();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Used to get/set the hotkey (e.g. Keys.A).
|
||||
/// </summary>
|
||||
/// <param name="hotkey">hotkey.</param>
|
||||
public void SetHotkey(string hotkey)
|
||||
{
|
||||
this.hotkey = HotkeyFromString(hotkey);
|
||||
modifiers = HotkeyModifiersFromString(hotkey);
|
||||
Redraw(true);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return HotkeyToString(HotkeyModifiers, Hotkey);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles some misc keys, such as Ctrl+Delete and Shift+Insert.
|
||||
/// </summary>
|
||||
/// <param name="msg">msg.</param>
|
||||
/// <param name="keyData">keyData.</param>
|
||||
/// <returns>bool if handled.</returns>
|
||||
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
|
||||
{
|
||||
if (keyData == Keys.Delete || keyData == (Keys.Control | Keys.Delete))
|
||||
{
|
||||
long now = DateTime.Now.Ticks;
|
||||
bool isPassed = now - lastCheck > waitTime;
|
||||
lastCheck = now;
|
||||
return isPassed;
|
||||
ResetHotkey();
|
||||
return true;
|
||||
}
|
||||
|
||||
// Paste
|
||||
if (keyData == (Keys.Shift | Keys.Insert))
|
||||
{
|
||||
return true; // Don't allow
|
||||
}
|
||||
|
||||
// Allow the rest
|
||||
return base.ProcessCmdKey(ref msg, keyData);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Redraws the TextBox when necessary.
|
||||
/// </summary>
|
||||
/// <param name="bCalledProgramatically">Specifies whether this function was called by the Hotkey/HotkeyModifiers properties or by the user.</param>
|
||||
private void Redraw(bool bCalledProgramatically = false)
|
||||
{
|
||||
// No hotkey set
|
||||
if (hotkey == Keys.None)
|
||||
{
|
||||
Text = string.Empty;
|
||||
return;
|
||||
}
|
||||
|
||||
// LWin/RWin doesn't work as hotkeys (neither do they work as modifier keys in .NET 2.0)
|
||||
if (hotkey == Keys.LWin || hotkey == Keys.RWin)
|
||||
{
|
||||
Text = string.Empty;
|
||||
return;
|
||||
}
|
||||
|
||||
// Only validate input if it comes from the user
|
||||
if (bCalledProgramatically == false)
|
||||
{
|
||||
// No modifier or shift only, AND a hotkey that needs another modifier
|
||||
if ((modifiers == Keys.Shift || modifiers == Keys.None) && needNonShiftModifier.Contains((int)hotkey))
|
||||
{
|
||||
if (modifiers == Keys.None)
|
||||
{
|
||||
// Set Ctrl+Alt as the modifier unless Ctrl+Alt+<key> won't work...
|
||||
if (needNonAltGrModifier.Contains((int)hotkey) == false)
|
||||
{
|
||||
modifiers = Keys.Alt | Keys.Control;
|
||||
}
|
||||
else
|
||||
{
|
||||
// ... in that case, use Shift+Alt instead.
|
||||
modifiers = Keys.Alt | Keys.Shift;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// User pressed Shift and an invalid key (e.g. a letter or a number),
|
||||
// that needs another set of modifier keys
|
||||
hotkey = Keys.None;
|
||||
Text = string.Empty;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Check all Ctrl+Alt keys
|
||||
if ((modifiers == (Keys.Alt | Keys.Control)) && needNonAltGrModifier.Contains((int)hotkey))
|
||||
{
|
||||
// Ctrl+Alt+4 etc won't work; reset hotkey and tell the user
|
||||
hotkey = Keys.None;
|
||||
Text = string.Empty;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// I have no idea why this is needed, but it is. Without this code, pressing only Ctrl
|
||||
// will show up as "Control + ControlKey", etc.
|
||||
if (hotkey == Keys.Menu /* Alt */ || hotkey == Keys.ShiftKey || hotkey == Keys.ControlKey)
|
||||
{
|
||||
hotkey = Keys.None;
|
||||
}
|
||||
|
||||
Text = HotkeyToLocalizedString(modifiers, hotkey);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Populates the ArrayLists specifying disallowed hotkeys
|
||||
/// such as Shift+A, Ctrl+Alt+4 (would produce a dollar sign) etc.
|
||||
/// </summary>
|
||||
private void PopulateModifierLists()
|
||||
{
|
||||
// Shift + 0 - 9, A - Z
|
||||
for (Keys k = Keys.D0; k <= Keys.Z; k++)
|
||||
{
|
||||
needNonShiftModifier.Add((int)k);
|
||||
}
|
||||
|
||||
// Shift + Numpad keys
|
||||
for (Keys k = Keys.NumPad0; k <= Keys.NumPad9; k++)
|
||||
{
|
||||
needNonShiftModifier.Add((int)k);
|
||||
}
|
||||
|
||||
// Shift + Misc (,;<./ etc)
|
||||
for (Keys k = Keys.Oem1; k <= Keys.OemBackslash; k++)
|
||||
{
|
||||
needNonShiftModifier.Add((int)k);
|
||||
}
|
||||
|
||||
// Shift + Space, PgUp, PgDn, End, Home
|
||||
for (Keys k = Keys.Space; k <= Keys.Home; k++)
|
||||
{
|
||||
needNonShiftModifier.Add((int)k);
|
||||
}
|
||||
|
||||
// Misc keys that we can't loop through
|
||||
needNonShiftModifier.Add((int)Keys.Insert);
|
||||
needNonShiftModifier.Add((int)Keys.Help);
|
||||
needNonShiftModifier.Add((int)Keys.Multiply);
|
||||
needNonShiftModifier.Add((int)Keys.Add);
|
||||
needNonShiftModifier.Add((int)Keys.Subtract);
|
||||
needNonShiftModifier.Add((int)Keys.Divide);
|
||||
needNonShiftModifier.Add((int)Keys.Decimal);
|
||||
needNonShiftModifier.Add((int)Keys.Return);
|
||||
needNonShiftModifier.Add((int)Keys.Escape);
|
||||
needNonShiftModifier.Add((int)Keys.NumLock);
|
||||
|
||||
// Ctrl+Alt + 0 - 9
|
||||
for (Keys k = Keys.D0; k <= Keys.D9; k++)
|
||||
{
|
||||
needNonAltGrModifier.Add((int)k);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fires when a key is pushed down. Here, we'll want to update the text in the box
|
||||
/// to notify the user what combination is currently pressed.
|
||||
/// </summary>
|
||||
private void HotkeyControl_KeyDown(object sender, KeyEventArgs e)
|
||||
{
|
||||
// Clear the current hotkey
|
||||
if (e.KeyCode == Keys.Back || e.KeyCode == Keys.Delete)
|
||||
{
|
||||
ResetHotkey();
|
||||
}
|
||||
else
|
||||
{
|
||||
modifiers = e.Modifiers;
|
||||
hotkey = e.KeyCode;
|
||||
Redraw();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fires when all keys are released. If the current hotkey isn't valid, reset it.
|
||||
/// Otherwise, do nothing and keep the text and hotkey as it was.
|
||||
/// </summary>
|
||||
private void HotkeyControl_KeyUp(object sender, KeyEventArgs e)
|
||||
{
|
||||
// Somehow the PrintScreen only comes as a keyup, therefore we handle it here.
|
||||
if (e.KeyCode == Keys.PrintScreen)
|
||||
{
|
||||
modifiers = e.Modifiers;
|
||||
hotkey = e.KeyCode;
|
||||
Redraw();
|
||||
}
|
||||
|
||||
if (hotkey == Keys.None && ModifierKeys == Keys.None)
|
||||
{
|
||||
ResetHotkey();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Prevents the letter/whatever entered to show up in the TextBox
|
||||
/// Without this, a "A" key press would appear as "aControl, Alt + A".
|
||||
/// </summary>
|
||||
private void HotkeyControl_KeyPress(object sender, KeyPressEventArgs e)
|
||||
{
|
||||
e.Handled = true;
|
||||
}
|
||||
}
|
||||
}
|
13
UserInterface/Language.cs
Normal file
13
UserInterface/Language.cs
Normal file
|
@ -0,0 +1,13 @@
|
|||
// <copyright file="Language.cs" company="PlaceholderCompany">
|
||||
// Copyright (c) PlaceholderCompany. All rights reserved.
|
||||
// </copyright>
|
||||
|
||||
namespace SystemTrayMenu.UserInterface
|
||||
{
|
||||
public class Language
|
||||
{
|
||||
public string Name { get; set; }
|
||||
|
||||
public string Value { get; set; }
|
||||
}
|
||||
}
|
|
@ -17,7 +17,6 @@ namespace SystemTrayMenu.UserInterface
|
|||
|
||||
internal partial class Menu : Form
|
||||
{
|
||||
internal int Level = 0;
|
||||
private readonly Fading fading = new Fading();
|
||||
private bool isShowing = false;
|
||||
|
||||
|
@ -131,25 +130,26 @@ namespace SystemTrayMenu.UserInterface
|
|||
MaxReached,
|
||||
}
|
||||
|
||||
internal int Level { get; set; } = 0;
|
||||
|
||||
internal bool IsUsable => Visible && !fading.IsHiding &&
|
||||
!IsDisposed && !Disposing;
|
||||
|
||||
protected override CreateParams CreateParams
|
||||
{
|
||||
get
|
||||
{
|
||||
CreateParams createparams = base.CreateParams;
|
||||
createparams.ExStyle |= 0x80;
|
||||
return createparams;
|
||||
}
|
||||
}
|
||||
|
||||
internal void FocusTextBox()
|
||||
{
|
||||
textBoxSearch.Focus();
|
||||
}
|
||||
|
||||
private static void SetDoubleBuffer(Control ctl, bool doubleBuffered)
|
||||
{
|
||||
typeof(Control).InvokeMember(
|
||||
"DoubleBuffered",
|
||||
BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.SetProperty,
|
||||
null,
|
||||
ctl,
|
||||
new object[] { doubleBuffered },
|
||||
CultureInfo.InvariantCulture);
|
||||
}
|
||||
|
||||
internal void SetTypeSub()
|
||||
{
|
||||
SetType(MenuType.Sub);
|
||||
|
@ -378,6 +378,53 @@ namespace SystemTrayMenu.UserInterface
|
|||
Location = new Point(x, y);
|
||||
}
|
||||
|
||||
internal void SetTitleColorActive()
|
||||
{
|
||||
labelTitle.ForeColor = Color.Black;
|
||||
}
|
||||
|
||||
internal void KeyPressedSearch(string letter)
|
||||
{
|
||||
textBoxSearch.Text += letter;
|
||||
textBoxSearch.SelectionStart = textBoxSearch.Text.Length;
|
||||
textBoxSearch.SelectionLength = 0;
|
||||
textBoxSearch.Focus();
|
||||
}
|
||||
|
||||
protected override bool ProcessCmdKey(ref Message msg, Keys keys)
|
||||
{
|
||||
switch (keys)
|
||||
{
|
||||
case Keys.Enter:
|
||||
case Keys.Up:
|
||||
case Keys.Down:
|
||||
case Keys.Left:
|
||||
case Keys.Right:
|
||||
case Keys.Escape:
|
||||
case Keys.Control | Keys.F:
|
||||
case Keys.Tab:
|
||||
case Keys.Tab | Keys.Shift:
|
||||
case Keys.Apps:
|
||||
CmdKeyProcessed.Invoke(this, keys);
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return base.ProcessCmdKey(ref msg, keys);
|
||||
}
|
||||
|
||||
private static void SetDoubleBuffer(Control ctl, bool doubleBuffered)
|
||||
{
|
||||
typeof(Control).InvokeMember(
|
||||
"DoubleBuffered",
|
||||
BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.SetProperty,
|
||||
null,
|
||||
ctl,
|
||||
new object[] { doubleBuffered },
|
||||
CultureInfo.InvariantCulture);
|
||||
}
|
||||
|
||||
private void AdjustDataGridViewWidth()
|
||||
{
|
||||
DataGridViewExtensions.FastAutoSizeColumns(dgv);
|
||||
|
@ -456,11 +503,6 @@ namespace SystemTrayMenu.UserInterface
|
|||
MouseWheel?.Invoke();
|
||||
}
|
||||
|
||||
internal void SetTitleColorActive()
|
||||
{
|
||||
labelTitle.ForeColor = Color.Black;
|
||||
}
|
||||
|
||||
private void LabelTitle_MouseDoubleClick(object sender, MouseEventArgs e)
|
||||
{
|
||||
if (e.Button == MouseButtons.Left)
|
||||
|
@ -479,39 +521,6 @@ namespace SystemTrayMenu.UserInterface
|
|||
labelTitle.BackColor = MenuDefines.ColorTitleBackground;
|
||||
}
|
||||
|
||||
protected override CreateParams CreateParams
|
||||
{
|
||||
get
|
||||
{
|
||||
CreateParams createparams = base.CreateParams;
|
||||
createparams.ExStyle |= 0x80;
|
||||
return createparams;
|
||||
}
|
||||
}
|
||||
|
||||
protected override bool ProcessCmdKey(ref Message msg, Keys keys)
|
||||
{
|
||||
switch (keys)
|
||||
{
|
||||
case Keys.Enter:
|
||||
case Keys.Up:
|
||||
case Keys.Down:
|
||||
case Keys.Left:
|
||||
case Keys.Right:
|
||||
case Keys.Escape:
|
||||
case Keys.Control | Keys.F:
|
||||
case Keys.Tab:
|
||||
case Keys.Tab | Keys.Shift:
|
||||
case Keys.Apps:
|
||||
CmdKeyProcessed.Invoke(this, keys);
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return base.ProcessCmdKey(ref msg, keys);
|
||||
}
|
||||
|
||||
private void TextBoxSearch_TextChanged(object sender, EventArgs e)
|
||||
{
|
||||
DataTable data = (DataTable)dgv.DataSource;
|
||||
|
@ -531,13 +540,5 @@ namespace SystemTrayMenu.UserInterface
|
|||
|
||||
SearchTextChanged.Invoke(this, null);
|
||||
}
|
||||
|
||||
internal void KeyPressedSearch(string letter)
|
||||
{
|
||||
textBoxSearch.Text += letter;
|
||||
textBoxSearch.SelectionStart = textBoxSearch.Text.Length;
|
||||
textBoxSearch.SelectionLength = 0;
|
||||
textBoxSearch.Focus();
|
||||
}
|
||||
}
|
||||
}
|
4
UserInterface/SettingsForm.Designer.cs
generated
4
UserInterface/SettingsForm.Designer.cs
generated
|
@ -1,4 +1,4 @@
|
|||
using SystemTrayMenu.UserInterface.Controls;
|
||||
using SystemTrayMenu.UserInterface.HotkeyTextboxControl;
|
||||
|
||||
namespace SystemTrayMenu.UserInterface
|
||||
{
|
||||
|
@ -37,7 +37,7 @@ namespace SystemTrayMenu.UserInterface
|
|||
this.tableLayoutPanelGeneral = new System.Windows.Forms.TableLayoutPanel();
|
||||
this.comboBoxLanguage = new System.Windows.Forms.ComboBox();
|
||||
this.labelLanguage = new System.Windows.Forms.Label();
|
||||
this.textBoxHotkey = new SystemTrayMenu.UserInterface.Controls.HotkeyControl();
|
||||
this.textBoxHotkey = new SystemTrayMenu.UserInterface.HotkeyTextboxControl.HotkeyControl();
|
||||
this.checkBoxAutostart = new System.Windows.Forms.CheckBox();
|
||||
this.labelHotkey = new System.Windows.Forms.Label();
|
||||
this.labelAutostart = new System.Windows.Forms.Label();
|
||||
|
|
|
@ -4,21 +4,19 @@
|
|||
|
||||
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 Microsoft.Win32;
|
||||
using SystemTrayMenu.UserInterface.HotkeyTextboxControl;
|
||||
using SystemTrayMenu.Utilities;
|
||||
using static SystemTrayMenu.UserInterface.Controls.HotkeyControl;
|
||||
using static SystemTrayMenu.UserInterface.HotkeyTextboxControl.HotkeyControl;
|
||||
|
||||
public partial class SettingsForm : Form
|
||||
{
|
||||
public string NewHotKey => newHotKey;
|
||||
|
||||
private readonly string newHotKey = string.Empty;
|
||||
private bool inHotkey = false;
|
||||
|
||||
|
@ -79,82 +77,15 @@ namespace SystemTrayMenu.UserInterface
|
|||
}
|
||||
}
|
||||
|
||||
private void SettingsForm_Load(object sender, EventArgs e)
|
||||
{
|
||||
tabControl1.Size = new Size(
|
||||
tableLayoutPanelGeneral.Size.Width,
|
||||
tableLayoutPanelGeneral.Size.Height);
|
||||
}
|
||||
public string NewHotKey => newHotKey;
|
||||
|
||||
private void ButtonOk_Click(object sender, EventArgs e)
|
||||
/// <summary>
|
||||
/// Registers all hotkeys as configured, displaying a dialog in case of hotkey conflicts with other tools.
|
||||
/// </summary>
|
||||
/// <returns>Whether the hotkeys could be registered to the users content. This also applies if conflicts arise and the user decides to ignore these (i.e. not to register the conflicting hotkey).</returns>
|
||||
public static bool RegisterHotkeys()
|
||||
{
|
||||
SetAutostart();
|
||||
SetHotkey();
|
||||
SetLanguage();
|
||||
Properties.Settings.Default.Save();
|
||||
DialogResult = DialogResult.OK;
|
||||
Close();
|
||||
}
|
||||
|
||||
private void SetAutostart()
|
||||
{
|
||||
if (checkBoxAutostart.Checked)
|
||||
{
|
||||
RegistryKey key = Registry.CurrentUser.OpenSubKey(
|
||||
@"SOFTWARE\Microsoft\Windows\CurrentVersion\Run", true);
|
||||
key.SetValue(
|
||||
Assembly.GetExecutingAssembly().GetName().Name,
|
||||
System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName);
|
||||
Properties.Settings.Default.IsAutostartActivated = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
RegistryKey key = Registry.CurrentUser.OpenSubKey(
|
||||
@"SOFTWARE\Microsoft\Windows\CurrentVersion\Run", true);
|
||||
key.DeleteValue("SystemTrayMenu", false);
|
||||
Properties.Settings.Default.IsAutostartActivated = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void SetHotkey()
|
||||
{
|
||||
Properties.Settings.Default.HotKey =
|
||||
new KeysConverter().ConvertToInvariantString(
|
||||
textBoxHotkey.Hotkey | textBoxHotkey.HotkeyModifiers);
|
||||
}
|
||||
|
||||
private void SetLanguage()
|
||||
{
|
||||
Properties.Settings.Default.CurrentCultureInfoName =
|
||||
comboBoxLanguage.SelectedValue.ToString();
|
||||
}
|
||||
|
||||
private void ButtonCancel_Click(object sender, EventArgs e)
|
||||
{
|
||||
Properties.Settings.Default.Reload();
|
||||
DialogResult = DialogResult.Cancel;
|
||||
Close();
|
||||
}
|
||||
|
||||
private void ButtonChange_Click(object sender, EventArgs e)
|
||||
{
|
||||
Config.SetFolderByUser(false);
|
||||
textBoxFolder.Text = Config.Path;
|
||||
}
|
||||
|
||||
private void TextBoxHotkeyEnter(object sender, EventArgs e)
|
||||
{
|
||||
HotkeyControl.UnregisterHotkeys();
|
||||
inHotkey = true;
|
||||
}
|
||||
|
||||
private void TextBoxHotkey_Leave(object sender, EventArgs e)
|
||||
{
|
||||
Properties.Settings.Default.HotKey =
|
||||
new KeysConverter().ConvertToInvariantString(
|
||||
textBoxHotkey.Hotkey | textBoxHotkey.HotkeyModifiers);
|
||||
RegisterHotkeys();
|
||||
inHotkey = false;
|
||||
return RegisterHotkeys(false);
|
||||
}
|
||||
|
||||
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
|
||||
|
@ -216,15 +147,6 @@ namespace SystemTrayMenu.UserInterface
|
|||
return success;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Registers all hotkeys as configured, displaying a dialog in case of hotkey conflicts with other tools.
|
||||
/// </summary>
|
||||
/// <returns>Whether the hotkeys could be registered to the users content. This also applies if conflicts arise and the user decides to ignore these (i.e. not to register the conflicting hotkey).</returns>
|
||||
public static bool RegisterHotkeys()
|
||||
{
|
||||
return RegisterHotkeys(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Registers all hotkeys as configured, displaying a dialog in case of hotkey conflicts with other tools.
|
||||
/// </summary>
|
||||
|
@ -312,12 +234,83 @@ namespace SystemTrayMenu.UserInterface
|
|||
|
||||
return success;
|
||||
}
|
||||
}
|
||||
|
||||
public class Language
|
||||
{
|
||||
public string Name { get; set; }
|
||||
private void SettingsForm_Load(object sender, EventArgs e)
|
||||
{
|
||||
tabControl1.Size = new Size(
|
||||
tableLayoutPanelGeneral.Size.Width,
|
||||
tableLayoutPanelGeneral.Size.Height);
|
||||
}
|
||||
|
||||
public string Value { get; set; }
|
||||
private void ButtonOk_Click(object sender, EventArgs e)
|
||||
{
|
||||
SetAutostart();
|
||||
SetHotkey();
|
||||
SetLanguage();
|
||||
Properties.Settings.Default.Save();
|
||||
DialogResult = DialogResult.OK;
|
||||
Close();
|
||||
}
|
||||
|
||||
private void SetAutostart()
|
||||
{
|
||||
if (checkBoxAutostart.Checked)
|
||||
{
|
||||
RegistryKey key = Registry.CurrentUser.OpenSubKey(
|
||||
@"SOFTWARE\Microsoft\Windows\CurrentVersion\Run", true);
|
||||
key.SetValue(
|
||||
Assembly.GetExecutingAssembly().GetName().Name,
|
||||
System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName);
|
||||
Properties.Settings.Default.IsAutostartActivated = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
RegistryKey key = Registry.CurrentUser.OpenSubKey(
|
||||
@"SOFTWARE\Microsoft\Windows\CurrentVersion\Run", true);
|
||||
key.DeleteValue("SystemTrayMenu", false);
|
||||
Properties.Settings.Default.IsAutostartActivated = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void SetHotkey()
|
||||
{
|
||||
Properties.Settings.Default.HotKey =
|
||||
new KeysConverter().ConvertToInvariantString(
|
||||
textBoxHotkey.Hotkey | textBoxHotkey.HotkeyModifiers);
|
||||
}
|
||||
|
||||
private void SetLanguage()
|
||||
{
|
||||
Properties.Settings.Default.CurrentCultureInfoName =
|
||||
comboBoxLanguage.SelectedValue.ToString();
|
||||
}
|
||||
|
||||
private void ButtonCancel_Click(object sender, EventArgs e)
|
||||
{
|
||||
Properties.Settings.Default.Reload();
|
||||
DialogResult = DialogResult.Cancel;
|
||||
Close();
|
||||
}
|
||||
|
||||
private void ButtonChange_Click(object sender, EventArgs e)
|
||||
{
|
||||
Config.SetFolderByUser(false);
|
||||
textBoxFolder.Text = Config.Path;
|
||||
}
|
||||
|
||||
private void TextBoxHotkeyEnter(object sender, EventArgs e)
|
||||
{
|
||||
HotkeyControl.UnregisterHotkeys();
|
||||
inHotkey = true;
|
||||
}
|
||||
|
||||
private void TextBoxHotkey_Leave(object sender, EventArgs e)
|
||||
{
|
||||
Properties.Settings.Default.HotKey =
|
||||
new KeysConverter().ConvertToInvariantString(
|
||||
textBoxHotkey.Hotkey | textBoxHotkey.HotkeyModifiers);
|
||||
RegisterHotkeys();
|
||||
inHotkey = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -13,6 +13,26 @@ namespace SystemTrayMenu.Utilities
|
|||
{
|
||||
public static event EventHandlerEmpty BeforeRestarting;
|
||||
|
||||
internal static void ByThreadException()
|
||||
{
|
||||
Restart(GetCurrentMethod());
|
||||
}
|
||||
|
||||
internal static void ByMenuNotifyIcon()
|
||||
{
|
||||
Restart(GetCurrentMethod());
|
||||
}
|
||||
|
||||
internal static void ByDisplaySettings(object sender, EventArgs e)
|
||||
{
|
||||
Restart(GetCurrentMethod());
|
||||
}
|
||||
|
||||
internal static void ByConfigChange()
|
||||
{
|
||||
Restart(GetCurrentMethod());
|
||||
}
|
||||
|
||||
private static void Restart(string reason)
|
||||
{
|
||||
BeforeRestarting?.Invoke();
|
||||
|
@ -38,25 +58,5 @@ namespace SystemTrayMenu.Utilities
|
|||
|
||||
return sf.GetMethod().Name;
|
||||
}
|
||||
|
||||
internal static void ByThreadException()
|
||||
{
|
||||
Restart(GetCurrentMethod());
|
||||
}
|
||||
|
||||
internal static void ByMenuNotifyIcon()
|
||||
{
|
||||
Restart(GetCurrentMethod());
|
||||
}
|
||||
|
||||
internal static void ByDisplaySettings(object sender, EventArgs e)
|
||||
{
|
||||
Restart(GetCurrentMethod());
|
||||
}
|
||||
|
||||
internal static void ByConfigChange()
|
||||
{
|
||||
Restart(GetCurrentMethod());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,10 +4,10 @@
|
|||
|
||||
namespace SystemTrayMenu.Utilities
|
||||
{
|
||||
using Shell32;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using Shell32;
|
||||
|
||||
internal class FileLnk
|
||||
{
|
||||
|
@ -34,6 +34,28 @@ namespace SystemTrayMenu.Utilities
|
|||
return resolvedFilename;
|
||||
}
|
||||
|
||||
public static bool IsDirectory(string filePath)
|
||||
{
|
||||
bool isDirectory = false;
|
||||
if (Directory.Exists(filePath))
|
||||
{
|
||||
FileAttributes attributes = File.GetAttributes(filePath);
|
||||
if ((attributes & FileAttributes.Directory) == FileAttributes.Directory)
|
||||
{
|
||||
isDirectory = true;
|
||||
}
|
||||
}
|
||||
|
||||
return isDirectory;
|
||||
}
|
||||
|
||||
public static bool IsNetworkRoot(string path)
|
||||
{
|
||||
return !System.IO.File.Exists(path) &&
|
||||
path.StartsWith(@"\\", StringComparison.InvariantCulture) &&
|
||||
!path.Substring(2).Contains(@"\", StringComparison.InvariantCulture);
|
||||
}
|
||||
|
||||
private static string GetShortcutFileNamePath(object shortcutFilename)
|
||||
{
|
||||
string resolvedFilename = string.Empty;
|
||||
|
@ -65,27 +87,5 @@ namespace SystemTrayMenu.Utilities
|
|||
|
||||
return resolvedFilename;
|
||||
}
|
||||
|
||||
public static bool IsDirectory(string filePath)
|
||||
{
|
||||
bool isDirectory = false;
|
||||
if (Directory.Exists(filePath))
|
||||
{
|
||||
FileAttributes attributes = File.GetAttributes(filePath);
|
||||
if ((attributes & FileAttributes.Directory) == FileAttributes.Directory)
|
||||
{
|
||||
isDirectory = true;
|
||||
}
|
||||
}
|
||||
|
||||
return isDirectory;
|
||||
}
|
||||
|
||||
public static bool IsNetworkRoot(string path)
|
||||
{
|
||||
return !System.IO.File.Exists(path) &&
|
||||
path.StartsWith(@"\\", StringComparison.InvariantCulture) &&
|
||||
!path.Substring(2).Contains(@"\", StringComparison.InvariantCulture);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -69,83 +69,6 @@ namespace SystemTrayMenu.Utilities
|
|||
return icon;
|
||||
}
|
||||
|
||||
private static bool IsExtensionWitSameIcon(string fileExtension)
|
||||
{
|
||||
bool isExtensionWitSameIcon = true;
|
||||
List<string> extensionsWithDiffIcons = new List<string>
|
||||
{ string.Empty, ".EXE", ".LNK", ".ICO", ".URL" };
|
||||
if (extensionsWithDiffIcons.Contains(fileExtension.ToUpperInvariant()))
|
||||
{
|
||||
isExtensionWitSameIcon = false;
|
||||
}
|
||||
|
||||
return isExtensionWitSameIcon;
|
||||
}
|
||||
|
||||
private static Icon GetFileIcon(string filePath, bool linkOverlay, IconSize size = IconSize.Small)
|
||||
{
|
||||
Icon icon = null;
|
||||
DllImports.NativeMethods.SHFILEINFO shfi = default;
|
||||
uint flags = DllImports.NativeMethods.ShgfiIcon | DllImports.NativeMethods.ShgfiSYSICONINDEX;
|
||||
|
||||
if (linkOverlay)
|
||||
{
|
||||
flags += DllImports.NativeMethods.ShgfiLINKOVERLAY;
|
||||
}
|
||||
|
||||
/* Check the size specified for return. */
|
||||
if (size == IconSize.Small)
|
||||
{
|
||||
flags += DllImports.NativeMethods.ShgfiSMALLICON;
|
||||
}
|
||||
else
|
||||
{
|
||||
flags += DllImports.NativeMethods.ShgfiLARGEICON;
|
||||
}
|
||||
|
||||
IntPtr hImageList = DllImports.NativeMethods.Shell32SHGetFileInfo(
|
||||
filePath,
|
||||
DllImports.NativeMethods.FileAttributeNormal,
|
||||
ref shfi,
|
||||
(uint)Marshal.SizeOf(shfi),
|
||||
flags);
|
||||
if (hImageList != IntPtr.Zero)
|
||||
{
|
||||
IntPtr hIcon;
|
||||
if (linkOverlay)
|
||||
{
|
||||
hIcon = shfi.hIcon; // Get icon directly
|
||||
}
|
||||
else
|
||||
{
|
||||
// Get icon from .ink without overlay
|
||||
hIcon = DllImports.NativeMethods.ImageList_GetIcon(hImageList, shfi.iIcon, DllImports.NativeMethods.IldTransparent);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// Copy (clone) the returned icon to a new object, thus allowing us to clean-up properly
|
||||
icon = (Icon)Icon.FromHandle(hIcon).Clone();
|
||||
}
|
||||
#pragma warning disable CA1031 // Do not catch general exception types
|
||||
catch (Exception ex)
|
||||
#pragma warning restore CA1031 // Do not catch general exception types
|
||||
{
|
||||
Log.Error($"filePath:'{filePath}'", ex);
|
||||
}
|
||||
|
||||
// Cleanup
|
||||
if (!linkOverlay)
|
||||
{
|
||||
DllImports.NativeMethods.User32DestroyIcon(hIcon);
|
||||
}
|
||||
|
||||
DllImports.NativeMethods.User32DestroyIcon(shfi.hIcon);
|
||||
}
|
||||
|
||||
return icon;
|
||||
}
|
||||
|
||||
public static Icon GetFolderIcon(
|
||||
string directoryPath,
|
||||
FolderType folderType,
|
||||
|
@ -224,5 +147,82 @@ namespace SystemTrayMenu.Utilities
|
|||
|
||||
return icon;
|
||||
}
|
||||
|
||||
private static bool IsExtensionWitSameIcon(string fileExtension)
|
||||
{
|
||||
bool isExtensionWitSameIcon = true;
|
||||
List<string> extensionsWithDiffIcons = new List<string>
|
||||
{ string.Empty, ".EXE", ".LNK", ".ICO", ".URL" };
|
||||
if (extensionsWithDiffIcons.Contains(fileExtension.ToUpperInvariant()))
|
||||
{
|
||||
isExtensionWitSameIcon = false;
|
||||
}
|
||||
|
||||
return isExtensionWitSameIcon;
|
||||
}
|
||||
|
||||
private static Icon GetFileIcon(string filePath, bool linkOverlay, IconSize size = IconSize.Small)
|
||||
{
|
||||
Icon icon = null;
|
||||
DllImports.NativeMethods.SHFILEINFO shfi = default;
|
||||
uint flags = DllImports.NativeMethods.ShgfiIcon | DllImports.NativeMethods.ShgfiSYSICONINDEX;
|
||||
|
||||
if (linkOverlay)
|
||||
{
|
||||
flags += DllImports.NativeMethods.ShgfiLINKOVERLAY;
|
||||
}
|
||||
|
||||
/* Check the size specified for return. */
|
||||
if (size == IconSize.Small)
|
||||
{
|
||||
flags += DllImports.NativeMethods.ShgfiSMALLICON;
|
||||
}
|
||||
else
|
||||
{
|
||||
flags += DllImports.NativeMethods.ShgfiLARGEICON;
|
||||
}
|
||||
|
||||
IntPtr hImageList = DllImports.NativeMethods.Shell32SHGetFileInfo(
|
||||
filePath,
|
||||
DllImports.NativeMethods.FileAttributeNormal,
|
||||
ref shfi,
|
||||
(uint)Marshal.SizeOf(shfi),
|
||||
flags);
|
||||
if (hImageList != IntPtr.Zero)
|
||||
{
|
||||
IntPtr hIcon;
|
||||
if (linkOverlay)
|
||||
{
|
||||
hIcon = shfi.hIcon; // Get icon directly
|
||||
}
|
||||
else
|
||||
{
|
||||
// Get icon from .ink without overlay
|
||||
hIcon = DllImports.NativeMethods.ImageList_GetIcon(hImageList, shfi.iIcon, DllImports.NativeMethods.IldTransparent);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// Copy (clone) the returned icon to a new object, thus allowing us to clean-up properly
|
||||
icon = (Icon)Icon.FromHandle(hIcon).Clone();
|
||||
}
|
||||
#pragma warning disable CA1031 // Do not catch general exception types
|
||||
catch (Exception ex)
|
||||
#pragma warning restore CA1031 // Do not catch general exception types
|
||||
{
|
||||
Log.Error($"filePath:'{filePath}'", ex);
|
||||
}
|
||||
|
||||
// Cleanup
|
||||
if (!linkOverlay)
|
||||
{
|
||||
DllImports.NativeMethods.User32DestroyIcon(hIcon);
|
||||
}
|
||||
|
||||
DllImports.NativeMethods.User32DestroyIcon(shfi.hIcon);
|
||||
}
|
||||
|
||||
return icon;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -4,11 +4,11 @@
|
|||
|
||||
namespace SystemTrayMenu.Utilities
|
||||
{
|
||||
using Shell32;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
using Shell32;
|
||||
|
||||
internal static class FolderOptions
|
||||
{
|
||||
|
|
13
Utilities/Language.cs
Normal file
13
Utilities/Language.cs
Normal file
|
@ -0,0 +1,13 @@
|
|||
// <copyright file="Language.cs" company="PlaceholderCompany">
|
||||
// Copyright (c) PlaceholderCompany. All rights reserved.
|
||||
// </copyright>
|
||||
|
||||
namespace SystemTrayMenu.Utilities
|
||||
{
|
||||
internal class Language
|
||||
{
|
||||
public string Name { get; set; }
|
||||
|
||||
public string Value { get; set; }
|
||||
}
|
||||
}
|
|
@ -4,13 +4,13 @@
|
|||
|
||||
namespace SystemTrayMenu.Utilities
|
||||
{
|
||||
using Clearcove.Logging;
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Windows.Forms;
|
||||
using Clearcove.Logging;
|
||||
|
||||
internal static class Log
|
||||
{
|
||||
|
|
|
@ -9,14 +9,14 @@ namespace SystemTrayMenu.Utilities
|
|||
|
||||
internal static class Scaling
|
||||
{
|
||||
internal static float Factor = 1;
|
||||
|
||||
private enum DeviceCap
|
||||
{
|
||||
VERTRES = 10,
|
||||
DESKTOPVERTRES = 117,
|
||||
}
|
||||
|
||||
public static float Factor { get; private set; } = 1;
|
||||
|
||||
internal static void Initialize()
|
||||
{
|
||||
CalculateScalingFactor();
|
||||
|
|
|
@ -34,11 +34,4 @@ namespace SystemTrayMenu.Utilities
|
|||
return rm.GetString(id, culture);
|
||||
}
|
||||
}
|
||||
|
||||
public class Language
|
||||
{
|
||||
public string Name { get; set; }
|
||||
|
||||
public string Value { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue