Maximized WS_POPUP window goes in front of the taskbar - c++

I'm creating a window in C++ with that code:
HWnd = CreateWindow(wc.lpszClassName,
"myapp",
WS_POPUP |WS_VISIBLE,
10, 10, 1000, 800, 0, 0, hInst, NULL);
It appears as I want but when I maximize it with like this:
ShowWindow(hwnd, SW_SHOWMAXIMIZED);
then it's like a fullscreen window so that the taskbar is hidden.
I think it's because it is a POPUP window but this is like I want it to appear.
Do I need to create my own maximize function or is there a parameter to avoid that ?
Thanks

You can add WS_CAPTION | WS_SYSMENU | WS_MAXIMIZEBOX style.
If you want your window to be without caption then you will need to adjust window size manually to fit into desktop work area that you can query using SystemParametersInfo specifying SPI_GETWORKAREA flag.

This is a feature where the Taskbar will get out of your full-screen application:
If you want to create a fullscreen window that covers the taskbar, just create a fullscreen window and the taskbar will automatically get out of the way.
I’ve seen people hunt for the taskbar window and then do a ShowWindow(hwndTaskbar, SW_HIDE) on it. This is nuts for many reasons.
Don’t do any of this messing with the taskbar. Just create your fullscreen window and let the taskbar do its thing automatically.
Since this is Stackoverflow, a combination of Wikipedia and Reddit, i want this relevant information saved for the next guy asking this question.

Related

check current application clicked in taskbar? (C++, Windows API)

I've spent many hours on google and haven't found any relevent results on this particular subject.
I have an application I am wanting to be minimized when the user clicks on it in the taskbar (if it's not already minimized). The problem seems to be related to the fact the window is borderless. When I set it to have a border, it minimizes just fine when clicking it in the taskbar, without any code intervention. But I need the window borderless because I'm making a "custom border" using the client area.
tl;dr how do I check if the current application is being clicked in the taskbar?
Many thanks!
Samuel
There is no need to tinker with the taskbar.
Just make sure you have the WS_MINIMIZEBOX|WS_MAXIMIZEBOX styles set for your window. Otherwise your window won't handle WM_SYSCOMMAND with a wParam of SC_MINIMIZE and SC_RESTORE.
Some resource editors like the one in Visual Studio make it impossible to set WS_MINIMIZEBOX|WS_MAXIMIZEBOX when you remove the standard window border. You may programmatically add the styles back like this:
DWORD style = GetWindowLong( hwnd, GWL_STYLE );
SetWindowLong( hwnd, GWL_STYLE, style | WS_MINIMIZEBOX | WS_MAXIMIZEBOX );

Creating window frame without maximize button and without resizing options?

I need to create a window that acts like "normal" one, but without maximize button, and sizing border.
Searching through Internet, and studying MSDN, I have learned that natively achieving both is impossible.
There is no window style that does both ( I can disable maximize button, but that is not my aim; as for removing resizing options, I have found suitable window styles in the documentation ).
The closest description would be the dialogbox frame behavior ( no sizing border ), but with extra minimize button.
QUESTION:
Is there a way to achieve my goal some other way?
If yes, can you please provide links to tutorials or code examples? This would be the first time for me to do such a thing and could use all the help I could get?
An important note: I have found this example while searching for a solution, but it will not help me because I target Windows XP onwards.
Creating a window as below will give you a non-sizeable window with a title bar, a minimize button and an exit button.
dwStyle = WS_SYSMENU | WS_CAPTION | WS_MINIMIZEBOX;
hWnd = CreateWindow(szAppName, szTitle, dwStyle,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0,
NULL, NULL, hInstance, NULL);
See http://msdn.microsoft.com/en-us/library/windows/desktop/ms632679%28v=vs.85%29.aspx
and http://msdn.microsoft.com/en-us/library/windows/desktop/ms632600%28v=vs.85%29.aspx
I suppose you are creating the window using CreateWindowEx. Then, if you omit both WS_MAXIMIZEBOX and WS_MINIMIZEBOX flags (the dwStyle parameter), the window will have only the close button (no minimize/maximize) buttons. If you ommit just WS_MAXIMIZEBOX, Windows draw the maximize box disabled to keep the graphics layout consistent for all windows. There is no way to change this behavior, and it can change in different versions of Windows (Win3.1, for instance, didn't draw the maximize button at all when the flags were set as mentioned.)
Resizable border is disabled by setting other frame than WS_THICKFRAME (ie. WS_BORDER or WS_EX_DLGMODALFRAME in the dwExStyle parameter).
You can also control the user sizing/moving of your window by intercepting messages WM_WINDOWPOSCHANGING, WM_WINDOWPOSCHANGED, WM_ENTERSIZEMOVE, WM_EXITSIZEMOVE, WM_SIZING and WM_MOVING.
In theory, you can also completly change the appearance of the non-client area of the window, but it's hardly worth the effort, and it's questionable whether it's a good idea to fight with the default graphic layout of the operating system when all the developers and user are used to it and content with it. (In other words: if you don't want your window to be maximized, just omit the WS_MAXIMIZEBOX flag and leave it on the operating system how to realize this particular decision.)
I'm pretty sure it is documented on MSDN that the window style you want to OMIT is WS_THICKFRAME, since the Window Styles page says that a thick frame is a sizing frame.

Groupbox resizing issue with radio buttons on top

I'm not sure what I'm doing wrong here. I'm trying to implement a resizing dialog window using MFC. The code is pretty straightforward. I override the following sizing notification:
void CMyDlg::OnSize(UINT nType, int cx, int cy)
{
CDialog::OnSize(nType, cx, cy);
// TODO: Add your message handler code here
//...
//First move the groupbox, pGroupbox is of type CWnd
pGroupbox->MoveWindow(rcGroupbox);
//And then move all radio buttons in it
//Each is moved the exact same way
//pEachRadioButton is of type CWnd
pEachRadioButton->MoveWindow(rcEachRadioButton);
}
But what I get as a result is this.
First here's the initial groupbox:
It happens only when I start dragging the bottom of the main window frame down. I get this artifact:
Note that the radio button positions themselves are correct. If I move the mouse over either of them, it redraws itself correctly (like this "shut-down" button):
Here's the layout of the dialog itself:
IDD_MY_DIALOG DIALOGEX 0, 0, 437, 190
STYLE DS_SETFONT | DS_FIXEDSYS | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME
EXSTYLE WS_EX_APPWINDOW
CAPTION "My dialog"
MENU IDR_MENU_MAIN
FONT 8, "MS Shell Dlg", 0, 0, 0x1
BEGIN
PUSHBUTTON "&Cancel",IDCANCEL,381,169,50,14
GROUPBOX "When Tasks Are Completed",IDC_STATIC_WHEN_COMPLETED,7,113,423,36
CONTROL "Close the pro&gram",IDC_RADIO_CLOSE_PROGRAM,"Button",BS_AUTORADIOBUTTON | WS_GROUP,26,129,73,8
CONTROL "Put computer to sleep",IDC_RADIO_SLEEP,"Button",BS_AUTORADIOBUTTON,122,129,84,10
CONTROL "Hibernate computer",IDC_RADIO_HIBERNATE,"Button",BS_AUTORADIOBUTTON,229,129,78,10
CONTROL "Shut down computer",IDC_RADIO_SHUT_DOWN,"Button",BS_AUTORADIOBUTTON,330,129,81,10
DEFPUSHBUTTON "&OK",IDC_BUTTON_SET,311,161,67,22
END
I did some search and found this article, but unfortunately setting those styles did not fix the bug.
Any idea how to fix this?
PS. I'm testing it on Windows Vista, 7, or 8 with visual themes enabled.
When you move a window, the window manager will move the current image of the window as it exists. Unfortunately because you moved the frame first, all those windows got clipped. Flipping them around wouldn't help, because then the tops would get clipped.
The easy way to fix it would be to call InvalidateRect on each control after moving it.
The better way would be to call BeginDeferWindowPos before you start moving anything, then EndDeferWindowPos when you're done so that all the windows move together.
P.S. Windows prefers for the group box to come after the radio buttons in the tab order, that might make a difference too.

WinAPI: Create resizable window without title bar, but with minimize/maximize/close buttons (as Firefox/Chrome/Opera)

If you look at the windows of the browsers Firefox, Chrome or Opera, you'll notice that their windows
have minimize/maximize/close buttons
are resizable
but have no title bar
I'm interested: how can I create such a window?
What I have already tried:
I looked around on StackOverflow (and googled, too), and found this: opening a window that has no title bar with win32
Unluckily, this didn't help completely:
The first step was to extend the solution proposed on opening a window that has no title bar with win32
hWnd = CreateWindow(szWindowClass, szTitle, WS_BORDER,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, hInstance, NULL);
SetWindowLong(hWnd, GWL_STYLE, WS_SIZEBOX);
// See remarks on http://msdn.microsoft.com/en-us/library/windows/desktop/ms633545.aspx
SetWindowPos(hWnd, 0,
0, 0, 0, 0, // Position + Size
SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);
Of course, this delivers no minimize/maximize buttons, but on the other hand, if I want minimize/maximize buttons, I have to do:
SetWindowLong(hWnd, GWL_STYLE, WS_SIZEBOX | WS_MAXIMIZEBOX |
WS_MINIMIZEBOX | WS_SYSMENU | WS_CAPTION);
Why does this combination seem to be necessary? First I probably want WS_MAXIMIZEBOX | WS_MINIMIZEBOX since I want these buttons.
But http://msdn.microsoft.com/en-us/library/ms632600.aspx says that if I set one of WS_MAXIMIZEBOX and WS_MINIMIZEBOX, I also have to set WS_SYSMENU. And when I set WS_SYSMENU, I also have to set WS_CAPTION but this is not what I want, because I wanted to avoid the title bar (indeed: if WS_CAPTION is not set, no minimize/maximize buttons are shown).
So what is to do?
The programs remove the non-client area (the title bar) and have a bunch of custom handling for reproducing the window buttons, icons, system menu etc. The benefit of this is that they can draw to the new "title bar", which is actually part of the standard client area, adding tabs or other custom controls.
The following two articles will show you how to do this on Vista and above (using the DWM):
Setting up a custom title bar on Windows Vista / 7
Setting up a custom title bar - reprise This one has a demo app showing the result of a number of variations / options.
This is very complex to do and get right, so the above two articles are invaluable. The author must have put a lot of work into them! Both links have example code written in Delphi, but it should be easy enough to translate it to C++ - the concepts are identical, it's just syntax.
You might also be interested in general resources on Glass and DWM, since it's all closely related. You'll spot the above two links included in that list :)
You can create a window with or without caption - whatever is more appropriate from the point of view of desired customization (that is "without" is you want to do it "without title bar" as you say), and the important wart is that you take over painting non-client area - this is the key thing.
At this point, there is no one to paint your mimimize/maximize buttons already. It does not however mean that you have to do the painting right from scratch and mimic standard UI. There is DrawFrameControl and friends API where you can use DFCS_CAPTIONMIN argument and have minimize button painted for you. You will also want to respond to other non-client area messages, e.g. handle WM_NCHITTEST to tell Windows where your new window buttons are.
You might also want to check Visual Styles Reference to leverage theme-enabled drawing API such as DrawThemeBackground.
A simple example of this activity is putting an additional button onto caption, such as described in detail here: CCaptionButton (buttons for the titlebar).
I believe they create a normal window and then paint over the title bar with their custom widgets/tabs. This is evident in Firefox, as when it hangs you can see the normal Windows title bar appear over the tabs.

windows beneath not being painted when using a layered window

I will try to explain my problem the best i can,
I'm creating a layered window in c++ (using windowsXP), all works fine until i drag my created window near the windows start button, and then when i press the star button of windows taskbar and close it again all the windows beneath of my layered window aren't being painted (only in the area of the start window that pops over my window).
My create window is like this:
CWnd::CreateEx( WS_EX_TOOLWINDOW |
WS_EX_LAYERED,
AfxRegisterWndClass(0),
lpstr_name, WS_POPUP, 0,0,0,0,
pc_parent->GetSafeHwnd(), 0);
...
When i create the window with this styles the problem ocurrs, but if i create with the extended style WS_EX_TRANSPARENT and all the others the problem does not occur any more. And if instead of a WS_POPUP window is a WS_CHILD or WS_OVERLAPPED then this also doesn't occur...
Can anyone please explain why when i create a WS_POPUP window with the WS_EX_LAYERED style all the beneath windows aren't updated, and if i add the style WS_EX_TRANSPARENT this works fine.
Note: why i do not use the WS_EX_TRANSPARENT style if it works right? if i use it then my window can not be dragged and i need it to do it :)
Updated:
alt text http://img17.imageshack.us/img17/586/clipboard01il.jpg
The image above is to describe better what is happening:
The first part of the image you can see my leyered window and beneath is the vs, in the second img i press the start button and then in the last image i already drag my layered window to the right and you can see that the vs window does not updates the affected area.
Note that this situation until now only occurs with the start window?! with other windows it does not happen!?...
Thanks
only in the area of the start window that pops over my window
That's expected. Only that clipping rectangle is obscured by the start menu so only that region will be repainted. What behavior are you expecting? If there are windows covered by more upper level windows, then they won't be repainted either -- why repaint something just to paint over it?
All underneath windows need to get repainted though if you use transparent because GDI can't calculate the final color of the pixel without knowing the area below the window's color.