通过透明的Windows窗体防止鼠标单击

时间:2013-04-07 12:31:32

标签: c# winforms

在浮动侧边栏中切换“笔”按钮后,我正在制作一个用鼠标在屏幕上绘图的小工具。

我已经完成了这个(请不要笑)最顶级的窗体形式及其背景,因为它的透明度键覆盖整个屏幕。 当我处于绘图模式时,我需要让鼠标不要点击表单到下面的东西。我试着按照这个: Windows form with a transparent background that cannot be clicked through How to disable click through on transparent control?

成功地停止了鼠标,但也没有最大化表格并用鼠标拖动它(使用HTCAPTION IntPtr(2)这是)我尝试使用MSDN上列出的一些其他值,但没有运气。< / p>

我离开了我的深度,任何帮助都非常感激(请新手友好!)

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%以允许/防止点击。作品!  感谢所有答案,教会了我很多。

2 个答案:

答案 0 :(得分:5)

实际上,没有必要笑 - 这对我来说听起来就像你正在以正确的方式做到这一点。由于您不拥有桌面,因此不应直接在桌面上绘制。相反,您需要通过覆盖您 拥有的透明表单来模拟它,然后绘制它。因为您拥有透明覆盖表单,所以在它上面绘制没有问题。

但除此之外,听起来你只是在没有清楚地了解他们实际做什么的情况下随意尝试价值。这就像闭上眼睛一样投掷飞镖。你不会有很高的命中率。

让我们首先了解您的代码所做的事情。魔术值0x84对应于WM_NCHITTEST消息,该消息由Windows发送到窗口以确定应如何处理该窗口上的鼠标点击。在回复该消息时,您将回复链接文档中给出的HT*值之一。这些值中的每一个都具有特定含义,也在文档中进行了解释。例如:

  • HTCAPTION(其值为2)表示窗口的单击部分应被视为窗口的标题/标题栏。您知道从使用Windows可以使用标题栏在屏幕上拖动窗口,因此返回HTCAPTION以响应鼠标单击将允许您的窗口可以拖动是有道理的。你会看到这在无边框表格(即那些没有标题栏的表格)上使用,以允许它们移动。

  • HTTRANSPARENT(其值为-1)是另一个可用值。这一个很简单。它只是让你的窗口看起来透明。这就像说“不要介意我,这里没有窗户!”鼠标点击只是简单地传递到Z顺序下面的窗口,就好像你不在那里一样。

  • HTCLIENT(值为1)是单击窗口客户区上任何位置时的默认结果。当您希望一切正常工作时,您将返回此(或只是调用默认窗口过程)。返回此值的单击事件将继续由框架正常处理,引发表单的Click事件,或传递给表单上的子控件。

因此,当您绘图时,您可能想要返回HTTRANSPARENT。当 绘图时,您可能希望返回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);
}

答案 1 :(得分:1)

您可能只想将窗口的可见性设置为大约5%左右,并保持透明密钥停用。

你基本上不会注意到它并将它喷射到那里:D

希望这会有所帮助