Win32:全屏和隐藏任务栏
我有一个窗口,我 SetWindowPos(window, HWND_TOP, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN), SWP_FRAMECHANGED);
它覆盖了整个屏幕,好吧,但需要一段时间(0.5 秒)也覆盖任务栏。
有没有办法立即跳出任务栏?我发现设置 HWND_TOPMOST
会立即执行此操作,但即使我切换应用程序,它仍然位于所有其他窗口之上 - 这是我不想要的。另外,如果我先隐藏窗口然后显示它,它会以某种方式强制窗口重新绘制并立即覆盖任务栏,但它会闪烁(因为隐藏)。还有别的办法吗?
I have a window, which I SetWindowPos(window, HWND_TOP, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN), SWP_FRAMECHANGED);
It covers the whole screen, ok, but it takes a while (0.5 sec) to cover the taskbar as well.
Is there a way to come over the taskbar immediately? I found that setting HWND_TOPMOST
does it immediately, but it stays above all the other windows, even if I switch the app - this is something I don't want. Also, if I first hide the window and then show it, it somehow forces the window to redraw and covers the taskbar immediately, but it flickers (because of the hiding). Is there another way?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
编辑2。甚至还有一种更好的全屏方式,即 chromium 方式,来源取自此处:
http://src.chromium.org/viewvc/chrome/trunk/src/ui/views/win/fullscreen_handler.cc?revision=HEAD&view=标记
编辑。
正如 BrendanMcK 在对此答案的评论中指出的那样,创建一个全屏窗口可能会更好,请参阅此链接:http://blogs.msdn.com/b/oldnewthing/archive/2005/05/05/414910.aspx(“如何用全屏窗口?”)
使用上面链接的新代码将是:
下面的旧答案 - 不要使用它,仅保留如何不这样做的记录。
您必须隐藏任务栏并菜单栏立即全屏显示。
这是代码(使用 WTL),调用 SetFullScreen(true) 进入全屏模式:
您还必须向 WM_CLOSE 消息添加一些代码:
如果您的应用程序崩溃或通过任务管理器终止,此解决方案有一个警告,那么用户将永久失去系统上的任务栏! (除非他再次运行您的应用程序,进入全屏并退出,然后他将再次看到任务栏)。
在我的回答前面,我指出了“atlwince.h”,但该函数仅适用于 Windows CE,我上面粘贴的函数适用于 XP、Vista 和 7。
Edit 2. There is even a better way for doing fullscreen, the chromium way, source taken from here:
http://src.chromium.org/viewvc/chrome/trunk/src/ui/views/win/fullscreen_handler.cc?revision=HEAD&view=markup
Edit.
It is probably better to create a fullscreen window as BrendanMcK pointed it out in a comment to this answer, see this link: http://blogs.msdn.com/b/oldnewthing/archive/2005/05/05/414910.aspx ("How do I cover the taskbar with a fullscreen window?")
The new code using the link above would be:
Old answer below - do not use it, stays only for the record on how NOT to do this.
You have to hide taskbar and menubar to see fullscreen immediately.
Here is the code (uses WTL), call SetFullScreen(true) to go into full screen mode:
You also have to add some code to WM_CLOSE message:
There is one caveat with this solution, if your application crashes or is killed through task manager, then user losses taskbar on his system permanently! (unless he runs your application again, goes into fullscreen and exits, then he will see the taskbar again).
Earlier in my answer I pointed to "atlwince.h" but that function worked only on Windows CE, the one I pasted above works fine with XP, Vista and 7.
是的,
HWND_TOPMOST
为我做到了。这是一段使全屏对我来说运行良好(且快速)的代码:
请注意,如果您告诉它错误的设置,这将更改分辨率。这是我通常想要的,但如果您不喜欢这样,您可以使用 (其中
mainWindow
是从CreateWindow()
或CreateWindowEx()
):当您想退出全屏时,您可以执行以下操作:
我将代码设置为使用热键在全屏和窗口模式之间切换,并保持窗口模式模式变量为全局变量,因此当更改为窗口模式时,它保持不变。
这段代码还有一个优点是可以在相当于“独占模式”的情况下运行(我使用的是 XP,还没有在较新版本的 Windows 上尝试过),这意味着它会快得多。如果我在压缩代码(来自我更大的代码)时犯了任何错误,请告诉我。
Yup,
HWND_TOPMOST
does it for me.Here is a section of code that makes full-screen work well (and quick) for me:
Note that this will change the resolution if you tell it the wrong settings. This is what I usually want, but if you don't like that, you can find out your resolution by using (where
mainWindow
is returned from something likeCreateWindow()
orCreateWindowEx()
):When you want to get out of full-screen you do something like this:
I set my code to change between full-screen and windowed mode using a hotkey, and I keep the windowed mode variables as global, so that when changing to windowed mode, it stays put.
This code also has the advantage of running in the equivalent of "exclusive mode" (I'm using XP, and haven't tried it on the newer versions of windows), which means it'll be much, much faster. Let me know if I've made any mistakes from condensing the code (from my much bigger code).
Raymond Chen 在他的博客中描述了执行此操作的“正确”方法:
https: //devblogs.microsoft.com/oldnewthing/20100412-00/?p=14353
明确摆弄任务栏窗口是不推荐的行为。
Raymond Chen describes the "correct" way to do this at his blog:
https://devblogs.microsoft.com/oldnewthing/20100412-00/?p=14353
Fiddling with the task bar window explicitly is not recommended behaviour.
这是最新完整链接到Raymond Chen 回答。
由于 MSDN/Microsoft 不断破坏链接,我将在下面粘贴以供后代使用:
出于某种原因, 人们想得太难了。如果您想创建一个覆盖任务栏的全屏窗口,只需创建一个全屏窗口,任务栏就会自动消失。不要到处寻找任务栏并戳它;让它做它该做的事。
与往常一样,从临时程序开始并添加如下所示:
请注意,该示例程序并不担心会破坏该全屏窗口或阻止用户创建多个全屏窗口。这只是一个样本。重点是看CreateFullScreenWindow函数是怎么写的。
我们使用 MonitorFromWindow 函数来确定我们应该使用哪个监视器进入全屏模式。请注意,在多显示器系统中,这可能与任务栏所在的显示器不同。幸运的是,我们不必担心这一点;任务栏可以解决这个问题。
我见过人们寻找任务栏窗口,然后在其上执行 ShowWindow(hwndTaskbar, SW_HIDE) 。出于多种原因,这很疯狂。
首先是在评估这样的技巧时应该始终使用的心理练习:“如果两个程序都尝试了这个技巧怎么办?”现在您有两个程序,它们都认为自己负责隐藏和显示任务栏,但两者都不相互协调。结果一团糟。一个程序隐藏任务栏,然后另一个程序隐藏任务栏,然后第一个程序决定它已完成,因此它取消隐藏任务栏,但第二个程序尚未完成,并在它认为应该隐藏时获得可见的任务栏。事情只会从那里开始走下坡路。
其次,如果您的程序在有机会取消隐藏任务栏之前崩溃了怎么办?任务栏现在永久隐藏,用户必须注销并重新登录才能恢复任务栏。这不太好。
第三,如果根本没有任务栏怎么办?在终端服务器方案中,通常 无需资源管理器即可自行运行程序 (已存档)。在此配置中,没有资源管理器,没有任务栏。或者,也许您运行的 Windows 的未来版本没有任务栏,它已被其他某种机制取代。你的程序现在要做什么?
不要对任务栏做任何这种混乱的事情。只需创建全屏窗口并让任务栏自动执行其操作即可。
Here's the latest unbroken link to Raymond Chen answer.
Since MSDN/Microsoft keeps breaking links I'll paste below for posterity:
For some reason, people think too hard. 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. Don't go around hunting for the taskbar and poking it; let it do its thing.
As always, start with the scratch program and add the following:
Note that this sample program doesn't worry about destroying that fullscreen window or preventing the user from creating more than one. It's just a sample. The point is seeing how the CreateFullScreenWindow function is written.
We use the MonitorFromWindow function to figure out which monitor we should go fullscreen to. Note that in a multiple monitor system, this might not be the same monitor that the taskbar is on. Fortunately, we don't have to worry about that; the taskbar figures it out.
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.
First is a mental exercise you should always use when evaluating tricks like this: "What if two programs tried this trick?" Now you have two programs both of which think they are in charge of hiding and showing the taskbar, neither of which is coordinating with the other. The result is a mess. One program hides the taskbar, then the other does, then the first decides it's finished so it unhides the taskbar, but the second program wasn't finished yet and gets a visible taskbar when it thought it should be hidden. Things only go downhill from there.
Second, what if your program crashes before it gets a chance to unhide the taskbar? The taskbar is now permanently hidden and the user has to log off and back on to get their taskbar back. That's not very nice.
Third, what if there is no taskbar at all? It is common in Terminal Server scenarios to run programs by themselves without Explorer (archived). In this configuration, there is no Explorer, no taskbar. Or maybe you're running on a future version of Windows that doesn't have a taskbar, it having been replaced by some other mechanism. What will your program do now?
Don't do any of this messing with the taskbar. Just create your fullscreen window and let the taskbar do its thing automatically.
我相信当它的 shell 钩子告诉它一个“粗鲁的应用程序”时,任务栏会摆脱困境,这可能需要一段时间。
如果您从窗口 HWND_TOPMOST 开始并使其在 1 秒后不再位于最顶层怎么办?
I believe the taskbar will get out of the way when its shell hook tells it about a "rude app", this might take a little while.
What if you start out with the window HWND_TOPMOST and make it not top most after 1 second?
任务栏属于用户,他们需要关心当您的应用程序全屏显示时是否需要 1/2 秒自动隐藏。如果他们想改变这种行为,那么他们就可以改变它。
如果您在嵌入式系统中工作,那么您可能有合理的理由隐藏任务栏。但在这种情况下,没有理由不简单地将任务栏配置为不始终位于顶部。如果您想更改代码中的某些设置,您还可以查看
SystemParametersInfo
。The taskbar belongs to the user, It's up to them to care about having it take 1/2 second to auto-hide when you app goes full screen. If they want to change that behavior then they can change it.
If you are working in an embedded system, then you may have a legitimate reason to hide the taskbar. But in that case, there's no reason not to simply configure the taskbar to not always be on top. You could also have a look at
SystemParametersInfo
if you want to change some of these settings in your code.