The taskbar allows fullscreen windows to cover it. That way, when you are projecting a slide show or making a presentation, you don’t have a taskbar at the bottom. The autodetection algorithm works fairly well most of the time: If the client area covers the entire screen, then it is a fullscreen window.
But you may find that the taskbar sometimes treats your window as a fullscreen window when you didn’t mean it to, or it fails to treat your window as fullscreen when you intended it to.
One case where you don’t want your screen-sized window to be treated as a fullscreen window is if your window is trying to apply an effect to the screen, like showing a 50% opacity black window in order to apply a dimming effect, such as that used by the Find My Mouse PowerToy. And a case where you want to force your screen-sized window to be treated as a fullscreen window is if you have a caption, because the caption is nonclient, and the fullscreen calculations look only at the client area.
You have two ways to influence the decision, both documented on the same page: One is to use ITaskbarÂList2::
, and another is to use the NonRudeHWND
window property.
The two settings are somewhat complementary in that each one tugs the Taskbar in different directions.
If you pass TRUE
to ITaskbarÂList2::
, then you are declaring that your window is a fullscreen window.¹ If you pass FALSE
, then you are canceling this declaration. Note that passing FALSE
does not mean “I am declaring that this is not a fullscreen window.” Rather, it means “I am not declaring that this is a fullscreen window.”
You can call MarkÂFullscreenÂWindow
before showing the window, or you can do it while the window is already shown, in which case it takes effect immediately. However, once you hide the window, any setting you applied is lost. If you want it to carry forward to the next time the window is shown, you need to set it again. The marking is also lost if Explorer crashes, so listen for the TaskbarCreated
message and reapply your marking.
The NonRudeHWND
property is consulted when the window is shown or when the system detects that your window might be a fullscreen window (like when it changes size to cover the screen). Changing the value after the decision has been made has no effect until the system needs to make a new decision, such as if you hide your window and then show it again. If the NonRudeHWND
property is set to 1
, then you are declaring that your window is definitely not a fullscreen window. Removing the property does not force your window to be treated as a fullscreen window; rather, it means “Just continue with your normal fullscreen detection logic.”
I’ll summarize in a table.
 | MarkFullscreenWindow | NonRudeHWND |
---|---|---|
Effect if set | Window is treated as fullscreen | Window is treated as non-fullscreen |
Best time to call | Before showing or resizing window | |
How often to call | Each time you show the window | Once is enough |
If changed while visible | Takes effect | Nothing happens |
If TaskbarCreated | Call it again | Don’t need to |
¹ The window still has to meet some basic criteria like, y’know, actually covering the screen. You can’t create a little 1×1 window and declare “I am a fullscreen window!”
Well, I mean you could, but people would just laugh at you.
I guess this is the perfect post to do a shameless plug for some intense reverse engineering work I did a couple of years ago, where I found a couple of Windows bugs specifically related to these fullscreen window and taskbar Z-order behaviors: https://github.com/dechamps/RudeWindowFixer
(I had no idea `NonRudeHWND` was officially documented… this may have saved me some time if I had known. Oh well.)
There was a bug report in an open source document reader app recently. A maximized window showed an ugly white line at the bottom.
Investigating it, it called DwmExtendFrameIntoClientArea when maximized, with the comment saying "hack: prevent window to cover taskbar". The software creates its own non-client area by using a borderless Win32 window, and I suppose that when it was maximized to fill the working area with the taskbar set to auto-hide (working area == full screen), it would prevent access to the taskbar as Windows saw it as "fullscreen". Extending the DWM frame supposedly also prevents this from...
I'm curious what happens if you mark the window as full-screen using the COM API but also mark it as non-rude using window property. My theory (1): "rude" means a window is full-screen without declaring itself to be, so if a window is non-rude, it can still be full-screen by calling MarkFullscreenWindow. My theory (2): "rude" means a window meaningfully covers somewhere not in the working area (a full-screen window is always rude, unless there're zero application toolbars; a maximized window just with its borders bleeding outside the working area is not rude), so a non-rude window will not be...
I considered investigating this, and then realized that there’s no point because nobody should be setting contradictory values anyway.