#41, #49, #68, #76, #78, version 0.9.2.22

This commit is contained in:
Markus Hofknecht 2020-04-15 17:23:42 +02:00
parent b887c25bb3
commit b13eb62f52
9 changed files with 125 additions and 116 deletions

View file

@ -8,7 +8,6 @@ using System.Linq;
using System.Security;
using System.Windows.Forms;
using SystemTrayMenu.DataClasses;
using SystemTrayMenu.DllImports;
using SystemTrayMenu.Handler;
using SystemTrayMenu.Helper;
using SystemTrayMenu.UserInterface;
@ -27,7 +26,8 @@ namespace SystemTrayMenu
private readonly Screen screen = Screen.PrimaryScreen;
private readonly WaitLeave waitLeave = new WaitLeave(MenuDefines.TimeUntilClose);
private readonly KeyboardInput keyboardInput;
private int clicksInQueue = 0;
private readonly Timer timerStillActiveCheck = new Timer();
private DateTime deactivatedTime = DateTime.Now;
public SystemTrayMenu()
{
@ -53,9 +53,10 @@ namespace SystemTrayMenu
menuNotifyIcon.HandleClick += SwitchOpenClose;
void SwitchOpenClose()
{
if (string.IsNullOrEmpty(Config.Path))
if (string.IsNullOrEmpty(Config.Path) ||
(DateTime.Now - deactivatedTime).TotalMilliseconds < 300)
{
//Case when Folder Dialog open
//Case when Folder Dialog open or restarts to fast
}
else if (openCloseState == OpenCloseState.Opening ||
menus[0].Visible && openCloseState == OpenCloseState.Default)
@ -71,27 +72,10 @@ namespace SystemTrayMenu
openCloseState = OpenCloseState.Default;
}
}
else if (worker.IsBusy)
{
if (clicksInQueue < MenuDefines.MaxClicksInQueue)
{
clicksInQueue++;
while (worker.IsBusy)
{
Application.DoEvents();
}
clicksInQueue--;
SwitchOpenClose();
}
else
{
Log.Info("User is clicking too often => throw event away");
}
}
else
{
openCloseState = OpenCloseState.Opening;
menuNotifyIcon.LoadingStart();
menuNotifyIcon.LoadingStart(true);
worker.RunWorkerAsync();
}
}
@ -114,15 +98,8 @@ namespace SystemTrayMenu
DisposeMenu(menus[0]);
menus[0] = CreateMenu(menuData, Path.GetFileName(Config.Path));
menus[0].AdjustLocationAndSize(screen);
menus[0].Visible = false; // resets activated
menus[0].Visible = true; // resets activated
Menus().ToList().ForEach(m => { m.ShowWithFade(); });
menus[0].Activate();
menus[0].SetTitleColorActive();
NativeMethods.ForceForegroundWindow(menus[0].Handle);
}
openCloseState = OpenCloseState.Default;
}
menuNotifyIcon.OpenLog += Log.OpenLogFile;
@ -147,6 +124,7 @@ namespace SystemTrayMenu
keyboardInput.Dispose();
menuNotifyIcon.Dispose();
waitLeave.Dispose();
timerStillActiveCheck.Dispose();
DisposeMenu(menus[0]);
IconReader.Dispose();
}
@ -422,20 +400,36 @@ namespace SystemTrayMenu
menu.Deactivate += Deactivate;
void Deactivate(object sender, EventArgs e)
{
if (!(Form.ActiveForm is Menu))
if (!FadeHalfOrOutIfNeeded())
{
FadeHalfOrOutIfNeeded();
menus[0].SetTitleColorDeactive();
deactivatedTime = DateTime.Now;
}
}
menu.Activated += Activated;
void Activated(object sender, EventArgs e)
{
if (Form.ActiveForm is Menu)
if (Form.ActiveForm is Menu &&
menus[0].IsUsable)
{
FadeInIfNeeded();
menus[0].SetTitleColorActive();
Menus().ToList().ForEach(m => m.ShowWithFade());
}
CheckIfWindowsStartStoleFocusNoDeactivateInRareCase();
void CheckIfWindowsStartStoleFocusNoDeactivateInRareCase()
{
timerStillActiveCheck.Interval = 1000;
timerStillActiveCheck.Tick += StillActiveTick;
void StillActiveTick(object senderTimer, EventArgs eTimer)
{
if (!waitLeave.IsRunning &&
!FadeHalfOrOutIfNeeded())
{
timerStillActiveCheck.Stop();
}
}
timerStillActiveCheck.Start();
}
}
@ -549,7 +543,6 @@ namespace SystemTrayMenu
{
int level = (int)eDoWork.Argument;
BackgroundWorker worker = (BackgroundWorker)senderDoWork;
rowData.RestartLoading = false;
eDoWork.Result = ReadMenu(worker, rowData.TargetFilePath, level);
}
@ -560,12 +553,12 @@ namespace SystemTrayMenu
MenuData menuData = (MenuData)e.Result;
if (rowData.RestartLoading)
{
rowData.RestartLoading = false;
rowData.Reading.RunWorkerAsync(menuData.Level);
}
else
{
menuNotifyIcon.LoadingStop();
menuNotifyIcon.LoadWait();
if (menuData.Validity != MenuDataValidity.Invalid)
{
menu = CreateMenu(menuData);
@ -585,7 +578,6 @@ namespace SystemTrayMenu
rowData.SubMenu = menu;
rowData.MenuLoaded();
}
menuNotifyIcon.LoadStop();
}
}
}
@ -620,46 +612,35 @@ namespace SystemTrayMenu
DisposeMenu(menus[menuTriggered.Level]);
menus[menuTriggered.Level] = menuTriggered;
AdjustSubMenusLocationAndSize();
#warning wrap into showorshowtransparent or find way without asking active form
if (Form.ActiveForm is Menu)
{
menus[menuTriggered.Level].ShowWithFade();
}
else
{
menus[menuTriggered.Level].ShowTransparent();
}
menus[menuTriggered.Level].ShowWithFadeOrTransparent(
Form.ActiveForm is Menu);
}
private void FadeInIfNeeded()
{
if (menus[0].IsUsable)
{
if (Form.ActiveForm is Menu)
{
Menus().ToList().ForEach(menu => menu.ShowWithFade());
}
else
{
Menus().ToList().ForEach(menu => menu.ShowTransparent());
}
bool isActive = Form.ActiveForm is Menu;
Menus().ToList().ForEach(
menu => menu.ShowWithFadeOrTransparent(isActive));
}
}
private void FadeHalfOrOutIfNeeded()
private bool FadeHalfOrOutIfNeeded()
{
bool menuActive = false;
if (menus[0].IsUsable)
{
if (!(Form.ActiveForm is Menu))
menuActive = Form.ActiveForm is Menu;
if (!menuActive)
{
Point position = Control.MousePosition;
if (Menus().Any(m => m.IsMouseOn(position)))
{
if (!keyboardInput.InUse)
{
Menus().ToList().ForEach(menu =>
menu.ShowTransparent());
Menus().ToList().ForEach(
menu => menu.ShowTransparent());
}
}
else
@ -668,10 +649,13 @@ namespace SystemTrayMenu
}
}
}
return menuActive;
}
private void MenusFadeOut()
{
openCloseState = OpenCloseState.Closing;
Menus().ToList().ForEach(menu =>
{
if (menu.Level > 0)

View file

@ -10,10 +10,12 @@ namespace SystemTrayMenu.Handler
private readonly Timer timerLeaveCheck = new Timer();
public bool IsRunning => timerLeaveCheck.Enabled;
public WaitLeave(int timeUntilTriggered)
{
timerLeaveCheck.Interval = timeUntilTriggered;
timerLeaveCheck.Tick += Leave;
timerLeaveCheck.Tick += TimerLeaveCheckTick;
}
public void Start()
@ -27,7 +29,7 @@ namespace SystemTrayMenu.Handler
timerLeaveCheck.Stop();
}
private void Leave(object sender, EventArgs e)
private void TimerLeaveCheckTick(object sender, EventArgs e)
{
timerLeaveCheck.Stop();
LeaveTriggered.Invoke();

View file

@ -22,7 +22,6 @@ namespace SystemTrayMenu
internal const int Scrollspeed = 4;
internal const int WaitMenuOpen = 200;
internal const int MenusMax = 50;
internal const int MaxClicksInQueue = 1;
internal const int TimeUntilClose = 1000;
}

View file

@ -194,7 +194,7 @@ namespace SystemTrayMenu.DataClasses
}
catch (ArgumentException ex)
{
Log.Error($"iconLocation:'{iconLocation}'", ex);
Log.Warn($"iconLocation:'{iconLocation}'", ex);
}
}
}

View file

@ -43,28 +43,16 @@ namespace SystemTrayMenu.UserInterface
StartStopTimer(state);
}
private void StartStopTimer(FadingState state)
private void StartStopTimer(FadingState newState)
{
#warning if too many threads throw some away? win32 exception if too fast here
if (state == FadingState.Idle)
if (newState == FadingState.Idle)
{
this.state = state;
state = newState;
timer.Stop();
}
else
{
ShowAtLeastTransparentBeforeHideItAgain();
void ShowAtLeastTransparentBeforeHideItAgain()
{
if (state == FadingState.Hide)
{
while (opacity < TransparentMinus)
{
Application.DoEvents();
}
}
}
this.state = state;
state = newState;
timer.Start();
FadeStep();
}

View file

@ -35,5 +35,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.9.2.21")]
[assembly: AssemblyFileVersion("0.9.2.21")]
[assembly: AssemblyVersion("0.9.2.22")]
[assembly: AssemblyFileVersion("0.9.2.22")]

View file

@ -111,6 +111,7 @@
<DebugType>full</DebugType>
<DebugSymbols>true</DebugSymbols>
<Prefer32Bit>false</Prefer32Bit>
<Optimize>true</Optimize>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'x64|AnyCPU'">
<PlatformTarget>AnyCPU</PlatformTarget>
@ -351,6 +352,9 @@
</ItemGroup>
<ItemGroup />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup>
<PreBuildEvent>taskkill /f /fi "imagename eq $(TargetFileName)"</PreBuildEvent>
</PropertyGroup>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">

View file

@ -67,19 +67,21 @@ namespace SystemTrayMenu.UserInterface
notifyIcon.MouseClick += NotifyIcon_MouseClick;
void NotifyIcon_MouseClick(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
HandleClick.Invoke();
}
VerifyClick(e);
}
notifyIcon.MouseDoubleClick += NotifyIcon_MouseDoubleClick;
void NotifyIcon_MouseDoubleClick(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
HandleClick.Invoke();
}
VerifyClick(e);
}
}
private void VerifyClick(MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
HandleClick.Invoke();
}
}
@ -90,8 +92,13 @@ namespace SystemTrayMenu.UserInterface
load.Dispose();
}
public void LoadingStart()
public void LoadingStart(bool reset = false)
{
if (reset)
{
threadsLoading = 0;
}
timeLoadingStart = DateTime.Now;
threadsLoading++;
load.Start();
@ -101,14 +108,16 @@ namespace SystemTrayMenu.UserInterface
{
threadsLoading--;
}
public void LoadWait()
{
notifyIcon.Icon = bitmapsLoading[loadCount++ % indexLoad];
}
public void LoadStop()
{
notifyIcon.Icon = R.SystemTrayMenu;
}
// Show a static icon when mainthread blocked
//public void LoadingStaticWait()
//{
// notifyIcon.Icon = bitmapsLoading[loadCount++ % indexLoad];
//}
//public void LoadingStaticStop()
//{
// notifyIcon.Icon = R.SystemTrayMenu;
//}
private void Load_Tick(object sender, EventArgs e)
{

View file

@ -16,10 +16,11 @@ namespace SystemTrayMenu.UserInterface
internal new event EventHandlerEmpty MouseEnter;
internal new event EventHandlerEmpty MouseLeave;
internal event EventHandlerEmpty UserClickedOpenFolder;
#warning use event not action
internal event Action<Keys> CmdKeyProcessed;
#warning #68 => use event and not a action here?
internal bool IsUsable => Visible && !fading.IsHiding;
internal bool IsUsable => Visible && !fading.IsHiding &&
!IsDisposed && !Disposing;
internal enum MenuType
{
@ -45,7 +46,30 @@ namespace SystemTrayMenu.UserInterface
fading.Show += Fading_Show;
void Fading_Show()
{
NativeMethods.User32ShowInactiveTopmost(this);
if (Level == 0)
{
try
{
Visible = true;
}
catch (ObjectDisposedException)
{
Visible = false;
Log.Info($"Could not open menu, menu already closed," +
$" IsDisposed={IsDisposed}");
}
if (Visible)
{
Activate();
NativeMethods.ForceForegroundWindow(Handle);
SetTitleColorActive();
}
}
else
{
NativeMethods.User32ShowInactiveTopmost(this);
}
}
fading.Hide += Hide;
@ -89,10 +113,12 @@ namespace SystemTrayMenu.UserInterface
{
SetType(MenuType.Sub);
}
internal void SetTypeEmpty()
{
SetType(MenuType.Empty);
}
internal void SetTypeNoAccess()
{
SetType(MenuType.NoAccess);
@ -127,17 +153,6 @@ namespace SystemTrayMenu.UserInterface
}
}
internal bool IsVisible()
{
return Visible;
}
internal bool IsActive(Form activeForm)
{
bool isActive = (this == activeForm);
return isActive;
}
internal bool IsMouseOn(Point mousePosition)
{
bool isMouseOn = Visible && ClientRectangle.Contains(
@ -149,10 +164,6 @@ namespace SystemTrayMenu.UserInterface
{
return dgv;
}
internal Label GetLabel()
{
return labelTitle;
}
internal void SetTitle(string title)
{
@ -166,6 +177,18 @@ namespace SystemTrayMenu.UserInterface
}
}
internal void ShowWithFadeOrTransparent(bool formActiveFormIsMenu)
{
if (formActiveFormIsMenu)
{
ShowWithFade();
}
else
{
ShowTransparent();
}
}
internal void ShowWithFade()
{
fading.Fade(Fading.FadingState.Show);