Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue #1895: add check for updates and common features on Tray Icon #1902

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 35 additions & 3 deletions src/modules/imageresizer/ui/App.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
// See the LICENSE file in the project root for more information. Code forked from Brice Lambson's https://github.com/bricelam/ImageResizer/

using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows;
using GalaSoft.MvvmLight.Threading;
Expand All @@ -16,6 +18,14 @@ namespace ImageResizer
{
public partial class App : Application
{
// Import the FindWindow API to find our window
[DllImportAttribute("User32.dll")]
private static extern int FindWindow(string className, string windowName);

// Import the SetForeground API to activate it
[DllImportAttribute("User32.dll")]
private static extern IntPtr SetForegroundWindow(int hWnd);

static App()
{
Console.InputEncoding = Encoding.Unicode;
Expand All @@ -28,10 +38,32 @@ protected override void OnStartup(StartupEventArgs e)

// TODO: Add command-line parameters that can be used in lieu of the input page (issue #14)
var mainWindow = new MainWindow(new MainViewModel(batch, Settings.Default));
mainWindow.Show();

// Temporary workaround for issue #1273
BecomeForegroundWindow(new System.Windows.Interop.WindowInteropHelper(mainWindow).Handle);
// Check process running
if (Process.GetProcessesByName(Process.GetCurrentProcess().ProcessName).GetUpperBound(0) == 0)
{
mainWindow.Show();

// Temporary workaround for issue #1273
BecomeForegroundWindow(new System.Windows.Interop.WindowInteropHelper(mainWindow).Handle);
}
else
{
// The program has the open file dialog window and the image resizer window
// Find the window, using the Window title
// Check which window is running
int hWndOpen = FindWindow(null, "Image Resizer - Open files");
int hWndImageResizer = FindWindow(null, "Image Resizer");
if (hWndOpen > 0)
{
SetForegroundWindow(hWndOpen); // Activate Image Resizer - Open files window
}

if (hWndImageResizer > 0)
{
SetForegroundWindow(hWndImageResizer); // Activate Image Resizer window
}
}
}

private void BecomeForegroundWindow(IntPtr hWnd)
Expand Down
14 changes: 13 additions & 1 deletion src/modules/imageresizer/ui/Views/MainWindow.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ public IEnumerable<string> OpenPictureFiles()
AppResources.AllFilesFilter + "|*.*",
InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyPictures),
Multiselect = true,

// Create the Window title for OpenFileDialog
Title = "Image Resizer - Open files",
};

if (openFileDialog.ShowDialog() != true)
Expand All @@ -43,6 +46,15 @@ public void ShowAdvanced(AdvancedViewModel viewModel)
=> viewModel.Close(new AdvancedWindow(viewModel).ShowDialog() == true);

void IMainView.Close()
=> Dispatcher.Invoke((Action)Close);
{
Dispatcher.Invoke((Action)Close);

// Close background processes when close the program
var processes = System.Diagnostics.Process.GetProcessesByName("ImageResizer");
foreach (var process in processes)
{
process.Kill();
}
}
}
}
3 changes: 3 additions & 0 deletions src/runner/resource.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,6 @@
#define ID_EXIT_MENU_COMMAND 40001
#define ID_SETTINGS_MENU_COMMAND 40002
#define ID_ABOUT_MENU_COMMAND 40003
#define ID_CHECK_FOR_UPDATES_COMMAND 40004
#define ID_IMAGE_RESIZER_COMMAND 40005
#define ID_WINDOW_WALKER_COMMAND 40006
Binary file modified src/runner/runner.rc
Binary file not shown.
42 changes: 42 additions & 0 deletions src/runner/tray_icon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,15 @@ LRESULT __stdcall tray_icon_window_proc(HWND window, UINT message, WPARAM wparam
case ID_SETTINGS_MENU_COMMAND:
open_settings_window();
break;
case ID_IMAGE_RESIZER_COMMAND:
start_image_resizer();
break;
case ID_WINDOW_WALKER_COMMAND:
start_window_walker();
break;
case ID_CHECK_FOR_UPDATES_COMMAND:
start_check_for_updates();
break;
case ID_EXIT_MENU_COMMAND:
if (h_menu)
{
Expand Down Expand Up @@ -206,3 +215,36 @@ void stop_tray_icon()
SendMessage(tray_icon_hwnd, WM_CLOSE, 0, 0);
}
}

void start_check_for_updates()
{
ShellExecute(NULL, NULL, L"https://github.com/microsoft/PowerToys/releases", NULL, NULL, SW_SHOW);
}

void start_image_resizer()
{
start_exe_file(const_cast<wchar_t*>(L".\\modules\\ImageResizer.exe"));
}

void start_window_walker()
{
start_exe_file(const_cast<wchar_t*>(L".\\modules\\WindowWalker.exe"));
}

void start_exe_file(wchar_t* path)
{
STARTUPINFO info = { sizeof(info) };
PROCESS_INFORMATION processInfo;
if (CreateProcess(path, NULL, NULL, NULL, TRUE, 0, NULL, NULL, &info, &processInfo))
{
//WaitForSingleObject(processInfo.hProcess, INFINITE); // Cannot open more than one window during the program is running
CloseHandle(processInfo.hProcess);
CloseHandle(processInfo.hThread);
}
else
{
MessageBox(NULL, L"Please report the bug to\nhttps://github.com/microsoft/PowerToys/issues\n", L"Error", MB_OK);
}

/*ShellExecute(NULL, NULL, L".\\modules\\ImageResizer.exe", NULL, NULL, SW_SHOW);*/ // Can open more than one window during the program is running
}
10 changes: 10 additions & 0 deletions src/runner/tray_icon.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
#pragma once
#include <windows.h>
#include <shellapi.h>
// Start the Tray Icon
void start_tray_icon();
// Stop the Tray Icon
Expand All @@ -9,3 +11,11 @@ void open_settings_window();
typedef void (*main_loop_callback_function)(PVOID);
// Calls a callback in _callback
bool dispatch_run_on_main_ui_thread(main_loop_callback_function _callback, PVOID data);
// Start .exe file
void start_exe_file(wchar_t* path);
// Open url check for updates
void start_check_for_updates();
// Open Image Resizer
void start_image_resizer();
// Open Window Walker
void start_window_walker();
101 changes: 101 additions & 0 deletions src/tests/win-app-driver/ImageResizerOpeningTwiceTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium.Appium.Windows;
using OpenQA.Selenium.Interactions;
using System.Diagnostics;
using System.Runtime.InteropServices;

namespace PowerToysTests
{
[TestClass]
public class ImageResizerOpeningTwiceTest : PowerToysSession
{
// Import the FindWindow API to find our window
[DllImportAttribute("User32.dll")]
private static extern int FindWindow(string className, string windowName);
int hWndOpen = FindWindow(null, "Image Resizer - Open files");
int hWndImageResizer = FindWindow(null, "Image Resizer");
private bool isTrayOpened;
[TestMethod]
public void OpenImageResizer()
{
//open tray
trayButton.Click();
isTrayOpened = true;

//open PowerToys context menu
WindowsElement pt = session.FindElementByName("PowerToys");
Assert.IsNotNull(pt);

new Actions(session).MoveToElement(pt).ContextClick().Perform();
ShortWait();

//open Image Resizer window twice
session.FindElementByXPath("//MenuItem[@Name=\"Image Resizer\"]").Click();
ShortWait();
trayButton.Click();
new Actions(session).MoveToElement(pt).ContextClick().Perform();
ShortWait();
session.FindElementByXPath("//MenuItem[@Name=\"Image Resizer\"]").Click();
ShortWait();

//check Open File Dialog window opened
Assert.AreNotEqual(hWndOpen, 0);
ShortWait();

//close Open File Dialog window
CloseWindow("Image Resizer - Open files");
ShortWait();

//check Open File Dialog window closed
Assert.AreEqual(hWndOpen, 0);

//check Image Resizer window opened
Assert.AreNotEqual(hWndImageResizer, 0);
ShortWait();

//open Image Resizer window one more time = twice
new Actions(session).MoveToElement(pt).ContextClick().Perform();
ShortWait();
session.FindElementByXPath("//MenuItem[@Name=\"Image Resizer\"]").Click();
ShortWait();

//close Image Resizer window
CloseWindow("Image Resizer");
ShortWait();

//check Image Resizer Closed
Assert.AreEqual(hWndImageResizer, 0);

//close Image Resizer include background processes
CloseWindowByProcessName("ImageResizer");
}

[ClassInitialize]
public static void ClassInitialize(TestContext context)
{
Setup(context);
}

[ClassCleanup]
public static void ClassCleanup()
{
TearDown();
}

[TestInitialize]
public void TestInitialize()
{

}

[TestCleanup]
public void TestCleanup()
{
if (isTrayOpened)
{
trayButton.Click();
}
}
}
}

35 changes: 35 additions & 0 deletions src/tests/win-app-driver/PowerToysSession.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using OpenQA.Selenium.Appium;
using OpenQA.Selenium.Appium.Windows;
using OpenQA.Selenium.Interactions;
using System.Diagnostics;

namespace PowerToysTests
{
Expand Down Expand Up @@ -276,5 +277,39 @@ private static void RestoreUserSettings()
File.Delete(_zoneSettingsPath);
}
}

// Close window by using FindElementByName
public static void CloseWindow(string windowName)
{
try
{
WindowsElement window = session.FindElementByName(windowName);
if (window != null)
{
window.SendKeys(Keys.Alt + Keys.F4);
}
}
catch (Exception)
{

}
}

// Close processes by GetProcessesByName
public static void CloseWindowByProcessName(string processName)
{
try
{
Process[] processes = Process.GetProcessesByName(processName);
foreach (Process process in processes)
{
process.Kill();
}
}
catch (Exception)
{

}
}
}
}
Loading