我正在制作一个小工具,用于在浮动侧边栏中切换“笔”按钮后用鼠标在屏幕上绘图。
我已经做到了这一点(请不要笑),方法是使用最顶层的窗口窗体及其背景,因为它的透明键覆盖整个屏幕。
当我处于绘图模式时,我需要使鼠标不会点击表单到下面的内容上。我尝试按照以下步骤操作:Windows窗体背景透明,无法点击 https://stackoverflow.com/questions/1436059/windows-form-with-a-transparent-background-that-cannot-be-clicked-through
如何禁用透明控件上的点击? https://stackoverflow.com/questions/3386058/how-to-disable-click-through-on-transparent-control
它成功地停止了鼠标,但也取消了窗体的最大化,并用鼠标拖动它(使用 HTCAPTION IntPtr(2) 这是)我尝试使用 MSDN 上列出的一些其他值,但没有运气。
我超出了我的深度,非常感谢任何帮助(请新手友好!)
PS我现在就用这个..
//code for allowing clicking through of menus
protected override void WndProc(ref Message m)
{
if (penMode && m.Msg == 0x84)
{
m.Result = new IntPtr(2);
}
else
base.WndProc(ref m);
}
更新:现在通过完全以另一种方式解决问题。看起来 WndProc 不起作用,所以我只是在整个屏幕上创建了一个空白表单,并从中显示了我的主表单(form.Show(this))。然后将位于下方的空白表单的不透明度从 0% 调整到 1%,以允许/阻止点击。作品!
感谢所有答案,教会了我很多。
事实上,没必要笑——在我看来,你已经在以正确的方式这样做了。由于您不拥有桌面,因此您不应该直接在桌面上绘图。相反,您需要通过覆盖您所使用的透明表单来模拟它do自己的,然后借鉴它。因为你拥有透明的覆盖窗体,所以在上面绘图是没有问题的。
但除此之外,听起来您只是随机尝试值,而没有清楚地了解它们的实际作用。这就像闭着眼睛扔飞镖一样。你不会有很高的命中数。
让我们首先了解您的代码的作用。魔法值0x84
对应于WM_NCHITTEST http://msdn.microsoft.com/en-us/library/windows/desktop/ms645618消息,由 Windows 发送到窗口以确定应如何处理该窗口上的鼠标单击。为了回复该消息,您回复了以下内容之一HT*
值,在链接文档中给出。每个值都有特定的含义,文档中也有解释。例如:
HTCAPTION
(值为 2)表示窗口的单击部分应被视为窗口的标题栏。通过使用 Windows,您知道可以使用标题栏在屏幕上拖动窗口,因此返回是有意义的HTCAPTION
响应鼠标点击将允许您的窗口可拖动。您将看到它用于无边框表单(即没有标题栏的表单),以允许它们可移动。
HTTRANSPARENT
(其值为-1)是另一个可用值。这个很简单。它只是让你的窗户看起来透明。这就像在说“别介意我,这里没有窗户!”鼠标点击会简单地传递到按 Z 顺序位于您的窗口下方的窗口,就好像您不在那里一样。
HTCLIENT
(值为 1)是当单击发生在窗口工作区任意位置时的默认结果。当您希望一切正常工作时,您可以返回此值(或简单地调用默认窗口过程)。返回此值的单击事件将继续由框架正常处理,从而引发表单的Click
事件,或传递给位于窗体上的子控件。
所以,当你not画画,你可能想回来HTTRANSPARENT
。当你are画画,你可能想回来HTCLIENT
以便您的绘图代码可以看到鼠标事件并绘制结果。
修复你的代码,然后:
// Code for allowing clicking through of the form
protected override void WndProc(ref Message m)
{
const uint WM_NCHITTEST = 0x84;
const int HTTRANSPARENT = -1;
const int HTCLIENT = 1;
const int HTCAPTION = 2;
// ... or define an enum with all the values
if (m.Msg == WM_NCHITTEST)
{
// If it's the message we want, handle it.
if (penMode)
{
// If we're drawing, we want to see mouse events like normal.
m.Result = new IntPtr(HTCLIENT);
}
else
{
// Otherwise, we want to pass mouse events on to the desktop,
// as if we were not even here.
m.Result = new IntPtr(HTTRANSPARENT);
}
return; // bail out because we've handled the message
}
// Otherwise, call the base class implementation for default processing.
base.WndProc(ref m);
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)