Is It Possible To Change a Window's Size in The Background - windows

Related to, but a more general question than How to Maximize a Window in background?
It is possible to Minimize, Restore, Move and Resize, and/or Maximize an Application Window using the ShowWindow() and SetWindowPos() API's
Using these has the disadvantage of changing the Active Window and Z-Order
Is it possible to make these changes in The Background, so that the changes only become noticable the next time it is Activated?
A soultion using using API's or VB6 is preferred
"Rest assured that things will get worse, before they get a lot worse" - Anon.

SetWindowPos doesn't have to change the z-order or activate the window.
Use the SWP_NOZORDER flag to prevent the z-order from changing.
Use the SWP_NOOWNERZORDER flag to prevent the window's owner's z-order from changing (if the window is owned)
Use the SWP_NOACTIVATE flag to prevent the window from being activated.
These flags (and their values) are documented here.

Related

How to make a fixed position and size window in X11

So I wanna make my window not moveable and resizable, is there anyway to do it? Below is my current window creation code.
testbwidgetptr->basewin = XCreateWindow(BOTIFDisplay,
tmp->drawarea,
testbwidgetptr->bwidgetx,
testbwidgetptr->bwidgety,
testbwidgetptr->bwidgetwidth,
testbwidgetptr->bwidgetheight,
0, CopyFromParent, InputOutput,
CopyFromParent, valuemask, &winatt);
XSetWindowBackground(BOTIFDisplay, testbwidgetptr->basewin, WhiteDot);
I wanna make my window not moveable and resizable
In X11 window management, the client doesn't get to define what they want. They can ask the window manager to do this or that (or not to do that), but in the end it is always up to the window manager. In fact, the specifications state clearly that the client application must deal with any size the window manager assigns to it – so the answer is: no, you cannot do that if you want your window to be managed.
As pointed out in a comment, you can set override_redirect on your window. This tells the window manager not to manage your window, which means that the window manager will not interfere with it. However, in theory any client could still resize your window (though this is extremely unlikely to happen).
However, you should be careful about this. Bypassing the window manager also means that you lose a lot of things: window decorations, focus handling and the like will all be gone. In particular, focus handling must be done by you.
To summarize, you should really consider whether override_redirect is actually what you want to use. In most cases, you should instead just build a client that can deal with arbitrary window sizes and positions.

CPropertySheet app lauched with CreateProcess steals focus [duplicate]

I was investigating an issue related to losing focus and changing activation of windows. What I found was that if I create an invisible property sheet, the active/foreground window changes and so does the focus window. Here is some sample MFC code:
// ignore CAutoDeleter, just a template that calls "delete this " in PostNcDestroy()
CPropertySheet* pSheet = new CAutoDeleter<CPropertySheet>(_T("Test Sheet"));
CTestPage* pPage = new CAutoDeleter<CTestPage>();
pSheet->AddPage(pPage);
DWORD style = WS_SYSMENU | WS_POPUP | WS_CAPTION | DS_MODALFRAME | DS_CONTEXTHELP;
// style |= WS_DISABLED; //does nothing to help
DWORD exStyle = 0;
//exStyle = WS_EX_NOPARENTNOTIFY|WS_EX_NOACTIVATE; // does nothing to help
pSheet->Create(AfxGetMainWnd(), style, exStyle); // adding
After the call to pSheet->Create(), the active/foreground/focus window has changed and the application window is on top. If I use Spy++ and look at the window that is created, it turns out that a property sheet is a DIALOG window class. I am assuming it has a different WNDPROC, of course. What is interesting, is if I create an invisible modeless dialog using, it does not exhibit the problem. If I create the invisible modeless dialog, the active/foreground/focus window remains the same.
I tried setting various flags as in the code snippet, but alas they did not have any discernible effect--I still had the flashing and activation non-sense.
I could get some improvement by setting and clearing a hook (WH_CBT) before and after pSheet->Create()--and then eating the activation messages. When I do that, I don't have the horrible flashing and my application window does not come to the top. However, the focus (and caret for windows that have carets) does go away from whichever window had it before the Create().
Does anyone know a way to keep the focus and activation unchanged when creating an invisible property sheet? (At some point, the property sheet may or may not be set visible. And, if the property sheet is invisible when being destroyed, it also causes the blinking and activation changes.)
I tried using the values returned in GetUIThreadInfo() to try and restore things after the call to Create(), but it causes some flashing as well.
I just want to know how to create an invisible Property Sheet which won't cause the active, foreground, and focus window to change.
Unfortunately the underlying API function PropertySheet calls SetForegroundWindow on the main property sheet dialog after creation. There's no easy way around this - your kludge with the WH_CBT hook is probably your best option.
Edit: As suggested by #stephen in the comments on this duplicate question, you may be able to prevent the activation/focus change using LockSetForegroundWindow.
I have been struggling with this same issue for weeks, with a similar project, where my main application launches a secondary EXE process to act as a server in an audio application (which needs to be a separate process to shield the application from plugin faults, and so it can be high priority for real-time audio processing).
My secondary EXE is a modeless CPropertySheet, for status and diagnostic display, but is intended to be launched hidden and in the background. However it was always stealing the activation from the main application on launch, regardless of what workarounds I tried (such as overriding OnWindowPosChanging).
I thought I was going to go mad, so I was very happy to find this question. The WH_CBT trick is useful, but I found while it prevented activation of the secondary EXE, it did not prevent deactivation of the main application.
But then I discovered an excellent solution, in the LockSetForegroundWindow API (available since Win2K) which I had never heard of before. Looks like it is intended for exactly this purpose, to disable the change of foreground activation and prevent peer processes from stealing it.
https://msdn.microsoft.com/en-us/library/windows/desktop/ms633532(v=vs.85).aspx
It works very well to nullify the internal call to SetForegroundWindow that happens deep within the property sheet common control, and works equally well whether used in the main application before CreateProcess or in the secondary EXE. I chose the latter case, to wrap the property sheet creation:
LockSetForegroundWindow(LSFW_LOCK);
pSheet->Create(NULL, dwStyle, dwExStyle);
LockSetForegroundWindow(LSFW_UNLOCK);
This minimises the scope of the intervention and keeps the fix localised to the process that is the source of the problem. I hope this will save others from wasting as much time on this tedious issue as I did.

Creating invisible and modeless property sheet causes focus change?

I was investigating an issue related to losing focus and changing activation of windows. What I found was that if I create an invisible property sheet, the active/foreground window changes and so does the focus window. Here is some sample MFC code:
// ignore CAutoDeleter, just a template that calls "delete this " in PostNcDestroy()
CPropertySheet* pSheet = new CAutoDeleter<CPropertySheet>(_T("Test Sheet"));
CTestPage* pPage = new CAutoDeleter<CTestPage>();
pSheet->AddPage(pPage);
DWORD style = WS_SYSMENU | WS_POPUP | WS_CAPTION | DS_MODALFRAME | DS_CONTEXTHELP;
// style |= WS_DISABLED; //does nothing to help
DWORD exStyle = 0;
//exStyle = WS_EX_NOPARENTNOTIFY|WS_EX_NOACTIVATE; // does nothing to help
pSheet->Create(AfxGetMainWnd(), style, exStyle); // adding
After the call to pSheet->Create(), the active/foreground/focus window has changed and the application window is on top. If I use Spy++ and look at the window that is created, it turns out that a property sheet is a DIALOG window class. I am assuming it has a different WNDPROC, of course. What is interesting, is if I create an invisible modeless dialog using, it does not exhibit the problem. If I create the invisible modeless dialog, the active/foreground/focus window remains the same.
I tried setting various flags as in the code snippet, but alas they did not have any discernible effect--I still had the flashing and activation non-sense.
I could get some improvement by setting and clearing a hook (WH_CBT) before and after pSheet->Create()--and then eating the activation messages. When I do that, I don't have the horrible flashing and my application window does not come to the top. However, the focus (and caret for windows that have carets) does go away from whichever window had it before the Create().
Does anyone know a way to keep the focus and activation unchanged when creating an invisible property sheet? (At some point, the property sheet may or may not be set visible. And, if the property sheet is invisible when being destroyed, it also causes the blinking and activation changes.)
I tried using the values returned in GetUIThreadInfo() to try and restore things after the call to Create(), but it causes some flashing as well.
I just want to know how to create an invisible Property Sheet which won't cause the active, foreground, and focus window to change.
Unfortunately the underlying API function PropertySheet calls SetForegroundWindow on the main property sheet dialog after creation. There's no easy way around this - your kludge with the WH_CBT hook is probably your best option.
Edit: As suggested by #stephen in the comments on this duplicate question, you may be able to prevent the activation/focus change using LockSetForegroundWindow.
I have been struggling with this same issue for weeks, with a similar project, where my main application launches a secondary EXE process to act as a server in an audio application (which needs to be a separate process to shield the application from plugin faults, and so it can be high priority for real-time audio processing).
My secondary EXE is a modeless CPropertySheet, for status and diagnostic display, but is intended to be launched hidden and in the background. However it was always stealing the activation from the main application on launch, regardless of what workarounds I tried (such as overriding OnWindowPosChanging).
I thought I was going to go mad, so I was very happy to find this question. The WH_CBT trick is useful, but I found while it prevented activation of the secondary EXE, it did not prevent deactivation of the main application.
But then I discovered an excellent solution, in the LockSetForegroundWindow API (available since Win2K) which I had never heard of before. Looks like it is intended for exactly this purpose, to disable the change of foreground activation and prevent peer processes from stealing it.
https://msdn.microsoft.com/en-us/library/windows/desktop/ms633532(v=vs.85).aspx
It works very well to nullify the internal call to SetForegroundWindow that happens deep within the property sheet common control, and works equally well whether used in the main application before CreateProcess or in the secondary EXE. I chose the latter case, to wrap the property sheet creation:
LockSetForegroundWindow(LSFW_LOCK);
pSheet->Create(NULL, dwStyle, dwExStyle);
LockSetForegroundWindow(LSFW_UNLOCK);
This minimises the scope of the intervention and keeps the fix localised to the process that is the source of the problem. I hope this will save others from wasting as much time on this tedious issue as I did.

SwitchToThisWindow sends current window to the back

So yes, I find myself in the dubious position of implementing a SwitchToThisWindow call to force my window to the front. I agree, its not ideal, but its not always possible to argue against product "features" that others deem necessary.
Now, I consider SwitchToThisWindow to be a win over the AttachThreadInput hack to do a forced window switch as its less likely to deadlock, and should SwitchToThisWindow be removed, or cease to function I won't complain.
However, SwitchToThisWindow has the unfortunate side effect of pushing the current foreground window to the bottom of the z-order in addition to bringing the target window to the top when FALSE is passed for the fAltTab parameter, and not doing anything if TRUE is passed.
How can I avoid this 'push current active to z-bottom' behavior without resorting to AttachThreadInput?
Alternatively, MS can just remove AttachThreadInput as a viable workaround and I can just tell my manager that the impossible, is in fact, actually, impossible.
I don't know if this helps, but the only way i found out to bring my window to top reliably is to make the following 2 calls:
ShowWindow(myhwnd, SW_MINIMIZE);
ShowWindow(myhwnd, SW_RESTORE);
Obviously these calls only should be made, when your window currently is not the topmost one in order to avoid flickering. But this also should not have the side effect of bringing the current front window to the bottom of the z order.
When passing fAltTab=FALSE you are actually emulating Alt+Esc. So you could reverse this z-order change with SetWindowPos and its hWndInsertAfter after the SwitchToThisWindow call, but then you are back in ugly hacky-land IMHO.
The question is, do you really need keyboard focus?
Let me suggest another alternative:
If your window is minimized, restore it
Set your window to be topmost, when your window is activated remove the style again.
Call SetForegroundWindow to flash the taskbar button (Or FlashWindowEx)
This should avoid the scenario where a user is typing and ends up performing some action in your UI without even looking at the screen.
Edit:
HWND hwndFgnd=GetForegroundWindow();
SetWindowPos(hwnd,hwndFgnd,0,0,0,0,SWP_NOSIZE|SWP_NOMOVE|SWP_NOACTIVATE);
SetWindowPos(hwndFgnd,hwnd,0,0,0,0,SWP_NOSIZE|SWP_NOMOVE);
..will probably work if you don't want to set the topmost bit at any point (Even if your window is at the top of the z-order, you still can't legally get the focus with SetForegroundWindow)
This is a bad problem I faced too. See my solution here. It works both for Show() and ShowDialog().

Can a window be always on top of just one other window?

In Windows, is it possible to set window A such that it is always on top of window B, yet allow other windows to work as normal and appear over the top of both, when active.
In other words, I want a parent-child relationship between two windows. Can this be done without making window A a child of window B, MDI-style? Window B isn't mine (Internet Explorer), and screws my dialog A's graphics up when I try to achieve this with SetParent.
I thought I'd cracked it with this idea from an MSDN forum post, but alas windows A is still always on top of everything, not just window B.
// Place window A on top
SetWindowPos(hWndWindow, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);
// Place window B underneath it
SetWindowPos(hWndParent, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOSIZE|SWP_NOMOVE);
Is it possible?
Wouldn't creating an ownership relationship do the trick?
SetWindowLong(hwndChild, GWL_HWNDPARENT, hwndOwner)
The windows can be in different processes and you can call this from any process. This will ensure that the child window is always above the owner window. This is different than SetParent which actually creates a Parent / Child relationship. Read through this article (its from 1993 but still mostly correct) to see the distinction between ownership and parenting.
When your window's Z-order (or size or position) is changing, it should receive a WM_WINDOWPOSCHANGING message. If you process that message, you have an opportunity to modify the final Z-order (or size or position) to which the window is moved.
To illustrate, in hWndA's window procedure:
case WM_WINDOWPOSCHANGING:
DefWindowProc(hWnd, msg, wParam, lParam);
WINDOWPOS *p = (WINDOWPOS*)lParam;
p->hwndInsertAfter = hWndB;
p->flags &= ~SWP_NOZORDER;
return 0;
should insert hWndA after hWndB in the Z-order any time hWndA's position changes.
Until Vista, one way to do it would have been to use SetWindowsHookEx, and hook the WH_CBT or WH_CALLWNDPROC hook, and then take appropriate action when you detect the Z order changing. However this doesn't work with Vista (as far as I can tell from googling).
The only other solution I can think of is to set up a timer to fire every few seconds, and then when you receive a WM_TIMER, you interrogate the system using GetNextWindow to find out which window is behind yours. If it's not IE, then call SetWindowPos to position your window above IE (I assume you have a HWND for the IE window you care about - remember there can be multiple IE windows).
This will cause problems if people try to bring your window to the front - it will flip back to being just above IE. In this case, in your code you could handle WM_ACTIVATE and try to change the Z-order of IE's window so it's below your window (call SetWindowPos to move IE's window so it's above the window that is currently below your window). This solution may be fraught with problems as Windows may try to prevent you messing with the windows of another process, for security reasons. On the other hand, the MSDN docs for SetWindowPos don't explicitly mention that you can't manipulate the windows of another process. There may be obscure limitations though.
Even with this timer hack, you're going to effectively have a busy-waiting loop in your app (with the frequent WM_TIMER messages) and this is generally a bad thing to do, especially for battery life of laptops etc. (because you prevent the CPU from entering a sleep state, and so on).
I'd say there's no good way of doing this, and anything you're likely to get working will be brittle and cause problems. I strongly recommend not trying to do it. Is it possible to make your program into some kind of plug-in or toolbar for IE instead?
NB Be particularly aware that SetWindowsHookEx imposes a performance penalty at a system-wide level if you go down this route.
Maurice's answer is the best out of what's here but is missing an important step. When you call show on your window that you want as the overlay, you need to call the show method that has the parameter. You'll need to define a class that implements the IWin32Window interface and just make a new instance of that. The only thing that interface cares about is the Handle so just set that to the handle of the IE window and it should work pretty well
If the parent-child relationship is made by yourself with the SetWindowPos() function, your desire can be implemented.
Can you access the Z-order of the windows?
I cannot recall the default z-order of windows, but I think it is 1. You might be able to set IE to a -1 and your app to 0.
Try this:
// Place window A on top of window B
SetWindowPos(hWndA, hWndB, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);
The second window handle parameter specifies the next window down in the Z order.
Note this doesn't actually change the window parent-child relationships - but you can simulate it.

Resources