Using SetForegroundWindow to focus on a window - c#

var hwnd = GetWindowHandle(); //Custom function that returns the target window's handle
var currentThreadId = GetCurrentThreadId();
uint pid;
var targetThreadId = GetWindowThreadProcessId(hwnd, out pid);
if (targetThreadId == IntPtr.Zero) return;
if (targetThreadId != currentThreadId)
{
AttachThreadInput(currentThreadId, targetThreadId, true);
}
SetForegroundWindow(hwnd);
if (currentThreadId != targetThreadId)
{
AttachThreadInput(currentThreadId, targetThreadId, false);
}
I have used the above code to put focus to another window, using the Handle of the targeted window. The above code is placed inside a method which is called when a shortcut key is pressed.
The issue that I am facing is that for the first time focus is getting stuck at the window, i.e., the focus is not shifting to other controls in the window (on tab press). So I have to bring the focus inside the window, using mouse. On pressing the shortcut for the 2nd time, the focus is not getting stuck anymore, its moving correctly on tab press.
Also please note that I have tried using SetFocus, but I am getting the same issue.
Please suggest of there is anything wrong with the code, or if I can use any alternate method to achieve the same behavior. Thanks.

Related

How to keep window visible at all times, but not force it to be on top

I'm creating a "desktop gadget" of sorts, I've disabled manual minimizing of the window, but now there is another problem: the system can still hide the window if the user presses Windows+D, for example.
When hidden that way, no usual minimize/resize/visibility events are fired.
I want to do something almost like TopMost, but without forcing the window order.
Maybe it's possible to install a global shortcut event using win32 API, and briefly set TopMost to true, but that sounds very hackish.
I found one solution, but it does not seem to work on Windows 10: Keeping window visible through "Show Desktop"/Win+D
The other common option, which would be writing an actual desktop gadget, is not possible on Windows 10, given their deprecation.
Are there any other methods to keep a window visible (but not on top of the screen) at all moments?
This function is working for me:
BOOL FixShowDesktop(HWND hWnd)
{
HWND hWndTmp = FindWindowEx(NULL, NULL, L"Progman", NULL);
if (hWndTmp)
{
hWndTmp = FindWindowEx(hWndTmp, NULL, L"SHELLDLL_DefView", NULL);
if (hWndTmp)
{
SetWindowLongPtr(hWnd, -8, (LONG_PTR)hWndTmp);
return TRUE;
}
}
return FALSE;
}
Note, this code is a bit better then from Keeping window visible through "Show Desktop"/Win+D because the window can be overflowed by other windows (like any other window). Using SetParent places window under all other windows.

How to get hidden windows handle of the windows that show hidden system tray icons

I am trying to write application in C# that catch the handle of the hidden windows that appear when pressing the button ("Show hidden icons").
When we don't show all the notification area we have hidden system tray icons.
When we press on the button ("Show hidden icons") that show them we have a new window that all the icons inside it:
The hidden windows marked with green circle
How can I catch the handle of this hidden window ?
When I used Spy++ I couldn't find this window because the windows dissapears when I click any other key on the keyboard.
So I found the handle of the button and used the logging option:
In the logging results I only saw windows handles of the regular system tray tool bar:
So how can I catch the handle of the hidden window (the one I marked with green in the begging of my question, first pictuare).
References (links I found but didn't help me):
How to capture Notification icons properties using Microsoft Spy++
Get information about hidden tray icons in windows7
I succeed !
I succeed to catch it with Spy++:
Code solution:
static IntPtr GetHiddenSystemTrayHandle()
{
IntPtr hWndTray = User32.FindWindow("NotifyIconOverflowWindow", null);
if (hWndTray != IntPtr.Zero)
{
if (hWndTray != IntPtr.Zero)
{
// Windows caption "Overflow Notification Area"
hWndTray = User32.FindWindowEx(hWndTray, IntPtr.Zero, "ToolbarWindow32", null);
return hWndTray;
}
}
return IntPtr.Zero;
}

How to tell if a textbox is focused in the OS or not?

I need to program a keyboard, with some configurations and customizations.
I need to configure it to be enabled if any text area is focused before the keyboard.
mainly I need to know what control is selected.
The Keyboard is a standalone application, so it cannot deal directly with the controls, just by accessing the OS.
for more explanation, I am gonna tell you the scenario:
the user runs the keyboard application, which its 'topmost' is set, and ShowInTaskBar is unset, and the keyboard is disabled.
the user clicks on any text control in the window, like the notepad or a TextBox in Microsoft Word or Paint, then after clicking the keyboard application is enabled.
the user clicks on the keyboard application and its keys to write text on the TextBox selected before in step 2, please note that the previous TextBox will loose focus but the keyboard will still enabled.
You can try with Focused property
foreach (var control in this.Controls)
{
if (control.Focused)
{
....
}
}
Link : http://msdn.microsoft.com/fr-fr/library/system.windows.forms.control.focused.aspx
You will need two of the windows API function
GetActiveWindow(void);
GetWindowClass()
First will give you the active windows (Focussed window) and the second one will let you know if it is a text window or not.
You will need further functions sendmessage(...) to get the current text of the window and also to set the text.
It is more about windows API.
It is easy by searching for the caret position, since it should be larger than 0
GUITHREADINFO lpgui = new GUITHREADINFO();
IntPtr fore = GetForegroundWindow();
uint tpid = GetWindowThreadProcessId(fore, IntPtr.Zero);
lpgui.cbSize = Marshal.SizeOf(lpgui.GetType());
bool flag = GetGUIThreadInfo(tpid, out lpgui);
WINDOWINFO pwi = new WINDOWINFO();
pwi.cbSize = (uint)Marshal.SizeOf(pwi.GetType());
GetWindowInfo((IntPtr)lpgui.hwndCaret, ref pwi);
if (flag)
{
if (!(lpgui.rcCaret.Location.X == 0 && lpgui.rcCaret.Location.Y == 0))
{
//TODO
}
}

c# remove 3rd party application from taskbar

How to remove an 3rd party application from the Windows taskbar by its handle?
I've found this:
Remove application from taskbar with C# wrapper?
But it doesnt worked for me.
It only sets another style (small x to close, no maximize/minimize button) to the Window i selected (notepad).
Any ideas about this?
EDIT: I dont want to remove MY application from the taskbar, i want to remove an external application by handle
If you have the handle to the window you can call ShowWindow() through the Win32 API. Then you can do:
// Let the window disappear (even from taskbar)
ShowWindow(this.Handle, WindowShowStyle.Hide);
// Revive the window back to the user
ShowWindow(this.Handle, WindowShowStyle.ShowNoActivate);
So from now, all your problem is to get the handle of the window you like to hide:
Process[] procs = Process.GetProcesses();
IntPtr hWnd;
foreach(Process proc in procs)
{
if ((hWnd = proc.MainWindowHandle) != IntPtr.Zero)
{
Console.WriteLine("{0} : {1}", proc.ProcessName, hWnd);
}
}
To hide it from windows task bar you just need to set ShowInTaskbar property to false :
this.ShowInTaskbar = false;
As for moving of windows you can use spy++ to check windows events and identify it.
How to remove an application from the Windows taskbar?
this.ShowInTaskbar = false;
Easy:
this.ShowInTaskbar = false;
As for the Form movement: you can use the Move event under Layout events

Set active window

I'm trying to make an app that gives a quake style drop-down HUD console. I can get it to show and hide the window, but I can't figure out how to set it as the active window after showing it. Im using Win API calls to show and hide the window. I've tried SetForegroundWindow(IntPtr hWnd) and SetFocus(IntPtr hWnd) to no avail. Anyone have any ideas?
http://pastebin.com/DgtJJGiv
public void ShowApp()
{
IntPtr h = FindWindow(null, "C:\\Windows\\system32\\cmd.exe");
ShowWindow(h, SW_SHOW);
//EnableWindow(h, true);
isHidden = false;
// set focus to console window
SetForegroundWindow(h);
System.Diagnostics.Debug.WriteLine(h);
}
I found an answer here:
How to show form in front in C#
The winAPI approaches were not working correctly for me but this did:
form.TopMost = true;
form.TopMost = false;
I originally was only setting TopMost to true but I ran into problems with dialog boxes displaying behind the form. It appears that setting TopMost to true pulls the form to the front and holds it there. Setting it to false doesn't push it back but does allow other forms to be shown in front. I was still having problems with focus so I ended up going with the following:
form.Activate();
You may use SetActiveWindow winAPI method. Hope this helps...
Try this (works for me):
public static void ShowApp()
{
IntPtr h = FindWindow(null, "C:\\Windows\\system32\\cmd.exe");
ShowWindow(h, ShowWindowCommands.Show);
SetForegroundWindow(h);
SetFocus(h);
System.Diagnostics.Debug.WriteLine(h);
}
Is there any reason why you can't implement your own console window? What I mean is a simple Form with a Textbox set to the correct style. You would probably have more control over how it works than trying to use the 'cmd' process.
Just a thought.

Categories