Programmatically handling the Vista Sidebar - c#

Is there an api to bring the vista side bar to the front (Win+Space) programatically and to do the reverse (send it to the back ground).

Probably using SetWindowPos you can change it to be placed the top / bottom of the z-order or even as the top-most window. You would need to find the handle to the sidebar using FindWindow or an application like WinSpy.
But after that something like.
Sets the window on top, but not top most.
SetWindowPos(sidebarHandle, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NORESIZE);
Sets the window at the bottom.
SetWindowPos(sidebarHandle, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE | SWP_NORESIZE);
This is my best guess on achieving what you asked, hopefully it helps.

You probably shouldn't do it at all, since such action may annoy the user when executed at the wrong time (95% of cases*), just like stealing focus with a "Yes/No" prompt.
Unless your product's task is to toggle the sidebar of course. ;)
There's no official API for that anyway.
*Purely hypothetical figure

Related

How to keep a window on top of a specific window only?

My application is a Winforms transparent overlay attached to another application.
Since there can be multiple overlays running at one time for different apps, I need my overlay to be always on top, but only over its target application.
What I tried was to bring the form to the foreground with
[DllImport("User32.dll")]
public static extern Int32 SetForegroundWindow(int hWnd);
When target app gains focus through my WindowHook eventType == NativeMethods.SWEH_Events.EVENT_OBJECT_FOCUS.
The problem is that the overlay gains focus after going on top, not allowing me to interact with the app underneath. Like if I try to drag the target app it will block me at first, and if I try to click anywhere nothing happens despite being clickthrough (works when I set Winforms TopMost = true;).
I would consider setting the form topmost when target app gains focus, but there is no event to check for loss of focus to undo the topmost, and even then it would be less than an elegant solution, to say the least.
There must be a simpler way to keep my overlay on top of its target app process. Or the very least, a way to bring the form on top without gaining focus / disrupting my mouse events.
So EVENT_SYSTEM_CAPTUREEND = 0x0009 gets called after any interaction with the target process window. This means I can set my form topmost
SetWindowPos(Handle, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
and undo it with
SetWindowPos(Handle, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); on EVENT_SYSTEM_CAPTUREEND.
I'm not a fan of this solution but works and it's seamless.

How to focus a process window over a running webbrowser window in c#?

I have a small Windows Forms program (agent) running in the Systray. The purpose of this agent written in C# is to start other programs, focus them and putting them into the foreground.
This agent receives the commands to start other programs from the browser and reports the successful start back to it. This means the browser is always up and running.
Starting external programs from the agent is working fine, but I have much trouble to get the focus and foreground topic to work. It seems like the browser is always in focus and the programs started from the agent are moved right behind the browser window.
I have tried the following methods from the User32.dll without success:
SetForegroundWindow(IntPtr handle)
SwitchToThisWindow(IntPtr hWnd, bool fAltTab)
The strange thing is that if I am running the agent in my Visual Studio the focus works perfect!
Help is much appreciated, since I am new to windows internals.
Update 1: I noticed if for instance a powershell window (could be anything arbitrary) lays over the browser window, focusing the started process window works as expected.
Update 2: I was able to get the right focus by calling
SetWindowPos(browserProcess.MainWindowHandle, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
on the browser process window and
SetWindowPos(process.MainWindowHandle, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_SHOWWINDOW);
on the started process window. But I think this is a bad approach since the browser window may vanish behind other open windows. I have also tried
SetWindowPos(browserProcess.MainWindowHandle, process.MainWindowHandle, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_SHOWWINDOW);
to switch the Z order of the browser window and the process window, but without success.
Question: How I can switch the Z order of the browser process and the started process?
Seems like SendKeys.SendWait("%"); was the magic I needed.% is the ALT key.
From the documentation of LockSetForegroundWindow
The system automatically enables calls to SetForegroundWindow if the user presses the ALT key or takes some action that causes the system itself to change the foreground window (for example, clicking a background window).
Calling AllowSetForegroundWindow returned FALSE in the first place so I was not able to set the foreground window. A call to GetLastError revealed the error code ERROR_ACCESS_DENIED. Calling SendKeys.SendWait("%") before User32dll.SetForegroundWindow(windowHandle) enables calls to SetForegroundWindow to be successful.
To put it together it looks like this:
var windowHandle = User32dll.FindWindow(null, nameOfWindow);
SendKeys.SendWait("%");
User32dll.SetForegroundWindow(windowHandle);
If the window is minimized, using User32dll.ShowWindow(windowHandle, User32dll.SW_RESTORE) is sufficient.
How do you retrieve the handle for that window?
This works for me:
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool SetForegroundWindow(IntPtr hWnd);
SetForegroundWindow((IntPtr)handle);

Programmatically Maximize Window On Half Of Screen

I want to maximize a random window on the left side of my screen. Can I use Windows Aero functions from my code ? This window can be maximized like that with the mouse. I just want to do that programmatically.
I use C# and I can get the IntPtr of the window.
If possible without faking mouse or keyboard input.
This can be done without p/invoke.
Try this:
Rectangle rect = Screen.PrimaryScreen.WorkingArea;
rect.Width = rect.Width / 2;
Bounds = rect;
This will put the current window on the left of the primary screen.
Then just add this to put it on the right of the screen.
Location = new Point(rect.Width, 0);
It's not exactly the same but fakes it well:
ShowWindow(handle, SW_MAXIMIZE);
// for a split second you might see a maximized window here
MoveWindow(handle, 0, 0, Screen.PrimaryScreen.WorkingArea.Width / 2, Screen.PrimaryScreen.WorkingArea.Height, true);
Will require heavy lifting for real-time placements, especially for non-child processes. Example - www.ishadow.com/vdm. For manual "fixing" of maximized windows position MoveWindow(hWnd, startPos, 0, winWidth, winHeight, true) after ShowWindow(hWnd, SW_MAXIMIZE) usually (try Task Manager on Windows 10) works as pointed above.

How to monitor a window's position with Win32?

I need to draw an overlay using WPF on top of a number of Win32 windows. In order to draw the overlay in the correct place, I will need to hook into the window move, but have no idea how to do this. Which Win32 calls should I be looking at?
SetWinEventHook
var hook = SetWinEventHook(EVENT_SYSTEM_MOVESIZESTART,
EVENT_SYSTEM_MOVESIZEEND, NULL, WinEventProc,
0, 0, WINEVENT_OUTOFCONTEXT | WINEVENT_SKIPOWNPROCESS);

Removing WS_BORDER and WS_CAPTION from windows styles doesn't work

I created a small app in C# that removes border and caption from window, then it sets size to the user's resolution and centers it. It's a utility for me to use when I want to play games in windowed mode without being annoyed by the borders. Everything works fine with most games, but I tried to use it on a recently released game Alpha Protocol and it doesn't work. I could almost say that the game reverts my changes, but I'm not sure how to tell if that's true or not. I'm using imported API functions MoveWindow, SetWindowLong and SetWindowPos.
Snippet:
Win32.MoveWindow(hWnd, 0, 0, Convert.ToInt32(sizeXText.Text), Convert.ToInt32(sizeYText.Text), true);
Win32.SetWindowLong(hWnd, GWL_STYLE, Win32.GetWindowLong(hWnd, GWL_STYLE) & ~WS_CAPTION & ~WS_BORDER);
Win32.SetWindowPos(hWnd, 0, 0, 0, 0, SWP_NOZORDER|SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE|SWP_DRAWFRAME);
Every time SetWindowPos is called it sends a message: WM_WINDOWPOSCHANGING to the window with a writable copy of the SetWindowPos parameters. This gives the window the chance to validate and change the parameters. Many window's automatically react to repositioning and sizing to "smartly" manage their non-client decorations - which I guess is what is happening here. The OnWindowPosChanging code is re-setting the non client decorations just before the DRAWFRAME is handled.
You should use Spy++ to investigate the game's window structure.

Categories