zoukankan      html  css  js  c++  java
  • MFC 悬浮窗口

    http://hi.baidu.com/zll2117/blog/item/29f697ee44ef9325adafd532.html

    使用VS2008+SP1创建悬浮窗口的步骤: (自己写的文档, 以备以后使用)

    1. 创建悬浮窗口类
    每一个悬浮窗口都是一个CDockablePane的派生类的对象, 因此要为每一个悬浮窗口创建一个新类

    1.1 添加类
    通过菜单Project->Add Class...或者在类视图中工程名字处右键选择Add->Class...添加类
    选择MFC Class, 点Add按钮进入下一步
    Class name处写入新类的名字, 这里用CDock, 选择Base class为CDockablePane
    按Finish按钮, 添加类完成.

    1.2 添加消息处理函数
    一般至少要处理两个消息, 一个是WM_CREATE, 一个是WM_SIZE, 具体步骤为:
    (1) 头文件中添加函数声明(函数名及参数不可写错)
    protected:
    afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
    afx_msg void OnSize(UINT nType, int cx, int cy);
    (2) cpp文件中添加消息映射
    BEGIN_MESSAGE_MAP(CDock, CDockablePane)
    ON_WM_CREATE()
    ON_WM_SIZE()
    END_MESSAGE_MAP()
    这里BEGIN_MESSAGE_MAP和END_MESSAGE_MAP宏都是自动生成的, 只需要添加中间两行代码即可
    (3) 添加函数实现部分
    int CDock::OnCreate(LPCREATESTRUCT lpCreateStruct)
    {
    if (CDockablePane::OnCreate(lpCreateStruct) == -1)
      return -1;
    // 在这儿创建控件
    return 0;
    }
    void CDock::OnSize(UINT nType, int cx, int cy)
    {
    CDockablePane::OnSize(nType, cx, cy);
    // 这儿添加代码
    }

    1.3 添加控件
    现在创建的CDock类中由于没有任何控件, 因此如果现在创建该类的对象并显示, 该区域中由于全是垃圾数据, 故可能该窗口显示时为花屏. 如果程序运行期间出现类似花屏的问题, 大概会有几种可能性: 1. 没有创建控件 2. 已创建控件, 但控件位置不对或未覆盖整个的dockablePane 3. 控件虽然占据整个区域, 但不能自动刷新
    这里以添加一个listBox为例:
    (1) 在类的头文件中添加控件对象, 代码为:
    protected:
    CListBox _listBox;
    (2) 在OnCreate()中添加创建控件窗口的代码:
    这里必须要注意, 需要先调用基类的函数OnCreate()
    int CDock1::OnCreate(LPCREATESTRUCT lpCreateStruct)
    {
    if (CDockablePane::OnCreate(lpCreateStruct) == -1)
      return -1;

    // 在这儿创建控件
    // nID为该控件的ID, 可以自行设置, 如果对ID不感兴趣, 也可以选择传递0让系统做处理
    if (!_listBox.Create(WS_CHILD | WS_VISIBLE, CRect(0, 0, 0, 0), this, nID))
    {
      TRACE0("创建listbox失败");
      return -1;
    }

    return 0;
    }
    (3) 在OnSize中设置各个控件的位置
    这里要注意的是, 需要将控件布满整个窗口. 这里只有一个listBox, 故可以直接用listBox覆盖窗口.
    同理, 必须要先调用基类函数CDockablePane::OnSize(nType, cx, cy)
    void CDock::OnSize(UINT nType, int cx, int cy)
    {
    CDockablePane::OnSize(nType, cx, cy);
    // 这儿添加代码
    if (GetSafeHwnd() == NULL)
    {
      return;
    }

    if (_listBox.GetSafeHwnd() != NULL)
    {
      CRect rectClient;
      GetClientRect(rectClient);
      _listBox.SetWindowPos(NULL, rectClient.left, rectClient.top, rectClient.Width(), rectClient.Height(), SWP_NOACTIVATE | SWP_NOZORDER);
    }

    }

    2. 在程序中添加悬浮窗口对象
    上面一步只是给工程添加了一个悬浮窗口类, 但并没生成该类的实例. 这里创建该实例(在CMainFrame类中)

    2.1 在主框架类声明中添加对象, 代码为:
    protected: 
    CDock m_wndDock;

    2.2 创建dockablePane的窗口, 在主框架的OnCreate()函数中
    (注: 这里我建议在OnCreate函数中自动生成代码EnableAutoHidePanes(CBRS_ALIGN_ANY)的后面添加)
    int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
    {
    ...
    EnableAutoHidePanes(CBRS_ALIGN_ANY);
    // 利用这里的CBRS_RIGHT来设置最初的窗口停靠的位置, 可以的取值是
    // CBRS_NOALIGN, CBRS_LEFT, CBRS_TOP, CBRS_RIGHT, CBRS_BOTTOM
    DWORD style = WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | CBRS_RIGHT | CBRS_FLOAT_MULTI;
    if (!wndDock1.Create(
      // 该dock窗口的标题(如果可以有的话...)
      _T("Dock1"),
      // 该dock窗口的parent, 设置为this
      this,
      //  窗口的大小, 注意是"悬浮"的情况下的大小, 处于dock状态时大小与该值无关
      CRect(0, 0, 200, 200),
      // 该dock窗口是否有标题, 如果为FALSE, 则第一个字符串参数显示不出来
      TRUE,
      // 该dock窗口的ID值. 注意: 如果希望dock窗口的状态可以保存在注册表中(这样下次启动程序时仍保持该状态),  则该值必须的唯一的
      nID,
      //
      style))
    {
      return FALSE;
    }
    ...
    }

    2.3 给悬浮窗口添加icon, 暂时省略.

    3. 设置窗口悬浮方式, 令窗口悬浮

    3.1 设置窗口悬浮位置
    这部分代码也应该在MainFrame类的OnCreate函数中, 而且紧跟创建悬浮窗口的后面.
    设置悬浮位置只需要调用CDockablePane::EnableDocking即可
    m_wndDock.EnableDocking(CBRS_ALIGN_ANY);
    其中, 参数可以是CBRS_ALIGN_TOP, CBRS_ALIGN_RIGHT, CBRS_ALIGN_BOTTOM, CBRS_ALIGN_ANY

    3.2 令窗口悬浮
    欲使一个CDockablePane对象悬浮, 只需要调用框架类的DockPane函数即可:
    DockPane(&m_wndDock);
    但是若有另外一个悬浮窗口的对象需要和m_wndDock在一起显示, 构成一个组(就像VS的资源视力和类视图), 那么第二个悬浮窗口需要使用CDockablePane类的AttchToTabWnd函数, 代码如下:
    DockPane(&m_wndDock);
    CDockablePane *pTabbedBar = NULL;
    m_wndDock2.AttachToTabWnd(&m_wndDock, DM_SHOW, FALSE, &pTabbedBar);

  • 相关阅读:
    Linux下的ping命令
    git stash
    ansiable
    「疫期集训day4」硝烟
    「线段树」「单点修改」洛谷P1198 [JSOI2008]最大数
    「状压DP」「暴力搜索」排列perm
    「疫期集训day3」要塞
    「疫期集训day2」高地
    「疫期集训day1」无言
    「区间DP」「洛谷P1043」数字游戏
  • 原文地址:https://www.cnblogs.com/marryZhan/p/2213922.html
Copyright © 2011-2022 走看看