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时为引用程序失去焦点.此时可以添加一个自定义事件.在这个自定义事件中进行处理

  • 相关阅读:
    Windows Svr 2008 Ent R2 性能计数器显示不全
    SQL Server的keepalive
    C语言字符串常见操作-strcpy、strlen、strcat和strcmp实现
    计算机中数据的编码方式
    OC中的排序方法
    关于C语言内存对齐
    C语言内存管理总结-野指针
    Objective-C基础学习笔记(九)-Foundation
    Objective-C基础学习笔记(八)-内存管理-autorelease使用-property创建对象的内存管理-循环引用的内管管理
    Objective-C基础学习笔记(七)-分类-Category-类的本质-load和+initialize方法-SEL数据
  • 原文地址:https://www.cnblogs.com/xuchonglei/p/2178713.html
Copyright © 2011-2022 走看看