zoukankan      html  css  js  c++  java
  • AutoClose=false的情况下自动关闭下拉框(ToolStripHost)

    应用场景:

    1,Winform

    2,ToolStripHost与输入控件组合焦点可在两者直接自由切换.

    3,当输入控件获取焦点后,ToolStripHost不能自动关闭.所以只能将AutoClose设置为false.

    实现目标:

    组合控件失去焦点或单击其他区域时,隐藏ToolStripHost

    实现:

    1,失去焦点可在LostFoucus事件处理或重写WndProc方法处理WM_KILLFOCUS消息.

    2,单击其他区域时有两种方法处理

    (1)通过全局鼠标钩子http://globalmousekeyhook.codeplex.com/获取单击时的坐标并判断坐标是否落在组合控件上.

                if (this._dropDown.Visible)
                {
                    Rectangle baseRect = new Rectangle(base.Parent.PointToScreen(base.Location), base.Size);//输入控件坐标转换为屏幕坐标
                    Rectangle dropRect = new Rectangle(this._dropDown.Location, this._dropDown.Size);//ToolStripHost坐标本身为屏幕坐标不需转换
    
                    if (!baseRect.Contains(e.X, e.Y) && !dropRect.Contains(e.X, e.Y))
                        this._dropDown.Hide();//隐藏
                }
    

    特别说明:构造函数中注册钩子,Dispose方法中卸载钩子.

    (2)组合控件实现IMessageFilter接口

    在程序调度消息之前处理几个鼠标消息即可

      public bool PreFilterMessage(ref Message m)
            {
                switch (m.Msg)
                {
                    case NativeMethods.WM_LBUTTONDOWN:
                    case NativeMethods.WM_RBUTTONDOWN:
                    case NativeMethods.WM_MBUTTONDOWN:
                    case NativeMethods.WM_NCLBUTTONDOWN:
                    case NativeMethods.WM_NCRBUTTONDOWN:
                    case NativeMethods.WM_NCMBUTTONDOWN:
                        OnClickBlank(ref m);
                        break;
    
                    default:
                        break;
    
                }
    
                return false;
            }
    

    在关闭的方法中判断下句柄如果句柄不是组合控件就关闭ToolStripHost

    总结:

    第一种方法,在加载钩子的时候虽然放到了线程池中但是依然很卡,调试命中断点后鼠标会很卡.

    第二种方法,比较好不会出现卡顿的情况

    自己在实现的时候遇到了不少困难.最终找到了合适的方法.也希望能给有相同需求的同学一些帮助.

    不足之处大家多多批评~~

    -----------------------------------

    测试时发现,ToolStripHost在获取焦点的情况下单击其他应用程序不会自动关闭.

    使用spy++发现当应用程序失去焦点时系统会对应用程序的所有控件send(直接发送到控件不进入消息队列,所以无法在PreFilterMessage过滤) WM_ACTIVEAPP消息.

    解决方法,继承ToolStripHost重写WndProc方法处理WM_ACTIVEAPP消息.wParam==0时为引用程序失去焦点.此时可以添加一个自定义事件.在这个自定义事件中进行处理

  • 相关阅读:
    Servlet学习小结
    HTTP学习小结
    SpringMVC第二天
    使用Servlet 编写过滤器
    项目使用框架
    java-web
    SSM框架集成.下(供自己练习查阅用)
    SSM框架集成.中(供自己练习查阅用)
    SSM框架集成.上(供自己练习查阅用)
    debug
  • 原文地址:https://www.cnblogs.com/xuchonglei/p/2178713.html
Copyright © 2011-2022 走看看