How to change back and forth application focus with global hotkey in C#

345 views Asked by At

I am creating my own C# clipboard manager and I have a global hotkey, ALT+H, that will trigger removal of text formatting from the clipboard. My application runs in the backend with a tray icon only. As such this is working fine but my problem is that when I am inside an application, e.g. Word and I am pressing my hotkey, then it will show me all kind of menus inside those applications and I do not want that.

Just for info then this is very related to another question I have on SO currently, How to stop further processing global hotkeys in C#. In the other question, this is based on finding a solution for the hotkey but another approach, which I think could even be better, could be to temporary switch focus to my application and once my hotkey is no longer applicable then the focus can be switched back to the originating application.

However then I have no idea how to switch back to the originating application again!?

My code so far, only focussing on the application changing mechanishmn:

Programs.cs:

// Import the required "SetForegroundWindow" method
[DllImport("user32.dll")]
public static extern bool SetForegroundWindow(IntPtr hWnd);

Form1.cs:

// Change focus to my application (when hotkey is active)
Program.SetForegroundWindow(this.Handle);

I am not fully sure if this actually does work but I can see that the originating application (e.g. Word) looses focus and my application works fine still so I do expect it works fine.

My problem is - how to get the hWnd(?) handle from the originating application so I can switch back to it once done? And what if I am not within any application but e.g. just on the WIndows desktop? What will then happen - can it change back to that?

I would appreciate any hints that can help as I am by far no real C# developer ;-)

1

There are 1 answers

0
Beauvais On BEST ANSWER

I have found the solution myself and will explain what worked out for me. I have this code here:

using System.Runtime.InteropServices;

[DllImport("user32.dll")]
public static extern bool SetForegroundWindow(IntPtr hWnd);

[DllImport("user32.dll")]
public static extern IntPtr GetForegroundWindow();

// I get in to here when the clipboard has changed and I need to find the application that has changed the clipboard

// Get the active/originating application handle
IntPtr originatingHandle = GetForegroundWindow();

// ------------------
// Do "some stuff" - this is not required for the application switching but it will get the application process name for the active/originating application

// Get the process ID from the active application
uint processId = 0;
GetWindowThreadProcessId(originatingHandle, out processId);

// Get the process name from the process ID
string appProcessName = Process.GetProcessById((int)processId).ProcessName;

// End "some stuff"
// ------------------

// Change focus to my application - this code is inside my main form (Form1)
SetForegroundWindow(this.Handle);

// Do some more stuff - whatever is required for my application to do
// ...

// Change focus back to the originating application again
SetForegroundWindow(originatingHandle);

At least the above code works for me.