CloseWindow() vs ShowWindow(hWnd, SW_MINIMIZE) - winapi

Does anyone know the difference between those two?

CloseWindow() calls ShowWindow() with SW_SHOWMINIMIZED if the window is not already minimized.
Like IsIconic() and IsZoomed(), CloseWindow() is one of the old school window manipulation functions.

From MSDN:
CloseWindow
Minimizes (but does not destroy) the specified window.
ShowWindow (SW_MINIMIZE)
Minimizes the specified window and activates the
next top-level window in the Z order.
My guess is CloseWindow doesn't activate next top-level window.

Related

MFC: Show or minimize (to hide) window on startup

In CWinApp::InitInstance() I have:
if (!ProcessShellCommand(cmdInfo))
return FALSE;
m_pMainWnd->ShowWindow(m_MinimizeOnStartup ? SW_SHOWMINIMIZED : SW_SHOWNORMAL);
m_pMainWnd->UpdateWindow();
But my ShowWindow call is not resulting in an OnSize() or OnShowWindow() callback? During the ProcessShellCommand() those are called a few times as the first OnShowWindow() restores the window size when last shutdown via SetWindowPlacement(). That all works good, restoring to last state, but ProcessShellCommand() afterwards calls ShowWindow with SW_SHOW which causes a my hidden when minimized window to show on the taskbar. Where is the proper place to either show the window or minimize it (to hide it). Basically what happens is the minimize comes in (on SetWindowPlacement(), window is hidden, MFC later calls SW_SHOW which makes it minimized on the taskbar instead of hidden, my forced ShowWindow() doesn't do anything.
TIA!!
There is no OnSize() nor OnShowWindow() callback on ShowWindow() when already in those states. Set m_nCmdShow=SW_HIDE in CAppWnd then at the end of the InitInstance() call the SetWindowPlacement()

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().

Problem when maximizing window in C++

My program needs to arbitrarily maximize any window on the current desktop. I achieve this by calling ShowWindow(hWnd, SW_MAXIMIZE), where hWnd is the HWND of the window I want to maximize. When that line of code executes, the window in question (here, Notepad) looks like this:
Everything seems fine, except for the fact that the window has not been positioned correctly, i.e. the window seems to be a few pixels to low, and the title bar does not look "squashed" like it should. Compared to how it should look when the maximize button is clicked, the problem is clearly visible:
Does anyone know why this behaviour occurs, and what I can do to fix it?
Telling the window to maximize itself might bypass some internal adjustments that the program makes when it maximizes via a system menu command. To emulate clicking on the maximize button, send it a SC_MAXIMIZE command:
SendMessage(hwnd, WM_SYSCOMMAND, SC_MAXIMIZE, 0);
Antoher way to use SetWindowPos(); For example you got HWND handleWnd;
RECT rcWnd;
GetWindowRect(handleWnd,&rcWnd);
SetWindowPos(handleWnd,WHND_TOP,rcWnd.left,rcWnd.top,(rcWnd.right-rcWnd.left),(rcWnd.bottom-rcWnd.top),SWP_SHOWWINDOW);
So you got your previous position, place window on top of Z and show

Getting the size of a minimized window

I never knew this, but apparently:
By default, the system reduces a
minimized window to the size of its
taskbar button and moves the minimized
window to the taskbar. A restored
window is a window that has been
returned to its previous size and
position, that is, the size it was
before it was minimized or maximized.
In an application, we want to save the position/size of various windows at exit. This leads to a problem for minimized windows. Our solution is to restore all windows before running the save-state logic, but that just seems hacky. Is there a better way?
How about using GetWindowPlacement?
That returns a WINDOWPLACEMENT structure that contains information about the window's coordinates in the restored position.
Remember that (as Leo Davidson points out in the comments) that you must respect the difference between workspace and screen coordinates. As the WINDOWPLACEMENT documentation explains:
The coordinates used in a
WINDOWPLACEMENT structure should be
used only by the GetWindowPlacement
and SetWindowPlacement functions.
Passing workspace coordinates to
functions which expect screen
coordinates (such as SetWindowPos)
will result in the window appearing in
the wrong location. For example, if
the taskbar is at the top of the
screen, saving window coordinates
using GetWindowPlacement and restoring
them using SetWindowPos causes the
window to appear to "creep" up the
screen.
Or, the simpler solution that I've no doubt used before is just to check if the window is minimized before saving the state, and if it is, skip saving any state information.
As far as explaining why a window changes its size when it gets minimized, Raymond Chen's blog entry (and the linked entry as well) on the subject is mandatory reading. They don't really change to their taskbar button's size, but rather to a pre-defined size of 160x31. He explains that you can see this by minimizing a MDI child window into its parent—that's really its size.
Handle WM_SIZE message. If wParam is not SIZE_MAXIMIZED or SIZE_MINIMIZED, keep window size and position in some varibles. Use these variables when window is closed.

Is there any Windows API that can "normalize" or "maximize" a window?

I was using Ruby's Win32API to MoveWindow to move a window and resize it.
But if the window is minimized, it won't show.
SetWindowPos works too, and has a flag to hide or show the window, but it is to only make a window visible or invisible, not about minimizing or normalizing.
I also tried SetForegroundWindow and SetActiveWindow and they won't work either. Is there a call to make a window normalized or maximized?
ShowWindow(hwnd, SW_RESTORE) may be what you're looking for. See: MSDN docs

Resources