将表单保留在任务栏上方?

时间:2013-08-31 05:22:03

标签: c# .net winforms

我的总体目标是渲染第二个(或第三个,第四个......)鼠标光标。为此,我创建了一个无框,最顶部,透明的窗口。我可以在这个窗口上绘图(我有4个按钮,表明它正确地覆盖整个桌面) - 但是当我点击任务栏时,它会被带到顶部并覆盖我的按钮和绘制线。

如何将我的窗口保持在任务栏上?

或者,有没有办法可以在屏幕的“最终”版本上绘制?

这是我的.Designer.cs文件中的代码:

this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
this.BackColor = System.Drawing.Color.White;
this.CausesValidation = false;
this.ClientSize = new System.Drawing.Size(332, 332);
this.ControlBox = false;
this.Controls.Add(this.button4);
this.Controls.Add(this.button3);
this.Controls.Add(this.button2);
this.Controls.Add(this.button1);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
this.MaximizeBox = false;
this.MinimizeBox = false;
this.Name = "Screen";
this.ShowIcon = false;
this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide;
this.StartPosition = System.Windows.Forms.FormStartPosition.WindowsDefaultBounds;
this.TopMost = true;
this.TransparencyKey = System.Drawing.Color.White;

4 个答案:

答案 0 :(得分:2)

如果不分析这样做的确切动机以及这种方法是否是最好的方法,您应该注意到任务栏的行为等同于任何其他窗口的行为:TopMost可以没有任何限制地使用。另一方面,它被认为是在“WorkingArea”之外,因此,根据您使用的属性,它可能会被忽略。请查看下面的示例代码,以便更好地理解这一点。

Main Form覆盖任务栏上方的所有可用空间:

this.ClientSize = new System.Drawing.Size(Screen.PrimaryScreen.WorkingArea.Width, Screen.PrimaryScreen.WorkingArea.Height);
this.Location = new Point(Screen.PrimaryScreen.WorkingArea.Left, Screen.PrimaryScreen.WorkingArea.Top);

Main Form覆盖了屏幕的整个可用空间:

this.ClientSize = new System.Drawing.Size(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height);
this.Location = new Point(Screen.PrimaryScreen.WorkingArea.Left, Screen.PrimaryScreen.WorkingArea.Top);

因此,您可以将表单放在任务栏的顶部而不会出现任何问题,因为它表示它代表了屏幕WorkingAreaBounds之间的差异。

澄清:这个答案强调了可能导致任务栏的处理方式不同于屏幕的任何其他部分的原因。这并不意味着您必须使您的表单与整个屏幕一样大,以便将其放在任务栏上;您可以根据需要随意放置任务栏。您必须记住的是WorkingArea不提供屏幕的整个维度,而只是提供任务栏上方的区域;如果您想考虑任务栏,请考虑Bounds

答案 1 :(得分:1)

我将使用varocarbas回答,但我想添加一些我认为可能有用的内容。

我认为有些事情可能会有所帮助,当我读到你的问题时,我想到的第一个想法是创建一个GlobalHook来监控消息WM_CBT,这条消息被发送到当系统即将Maximize,Minimize,Restore or Focus一个Window时,GlobalHook过程。当任何钩子被捕获时,你可以覆盖任何所需的事件来阻止该窗口成为最顶层的窗口,从而使your Form有机会保持最顶层Window.This方法将非常有用,如果它按照我期望的那样工作。

如果您对此感兴趣,以下是使GlobalHook工作所需的方法。 SetWindowsHookEx(),用于告诉系统创建GlobalHook HookProc,表示挂钩捕获受监视事件时调用的方法 HookType,枚举传递给SetWindowsHookEx调用的有效钩子类型 CallNextHook。如果使用互操作性很混乱,请尝试在托管包装中包含WindowsAPI函数的this开源库。希望这对您有所帮助,同时我也试图让这些东西为您工作。< / p>

答案 2 :(得分:1)

我遇到同样的问题我已经挣了几个小时。我想到了一个很好的解决方案:只要表单最大化,就动态地更改表单的底部填充。

If Me.WindowState = FormWindowState.Maximized then
    Dim pd As New Padding
    pd.Left = Me.Padding.Left
    pd.Right = Me.Padding.Right
    pd.Top = Me.Padding.Top
    pd.Bottom = Me.Height - Screen.PrimaryScreen.WorkingArea.Height
    Me.Padding = pd
end if

这样表单不在任务栏上方,但至少你的控件是! 注意:在设计表单时,可以保留底部填充0。 如果您希望表单能够最小化/正常调整大小,那么您可能希望在另一个表单事件中将底部填充重置为0.

答案 3 :(得分:0)

我发布后大约15分钟就找到了解决方案。 (这不总是这样吗?研究几个小时,但是一旦你寻求帮助,你就可以自己解决。)

我有一个事件是通过位置更新来调用我的代码。如果我在这个事件中简单地叫“BringToFront”,它就可以了。该事件每秒被调用多次,但如果我将我的行为调整回1/4秒,它仍然可以很好地运行。