找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 209|回复: 1

2013 duilib入门简明教程 -- 结合win32和MFC (16)

[复制链接]

52

主题

62

回帖

0

积分

版主

积分
0
发表于 2013-10-29 11:01:54 | 显示全部楼层 |阅读模式

虽然duilib自带在MFC中使用duilib的Demo,但只是MFC窗口和duilib窗口不重叠的情况。如果要在MFC窗口中嵌入duilib控件,或者在duilib控件中嵌入MFC的控件的话,就没有Demo可以看了,其实Alberl开始也不知道怎么办,看了下ActiveXUI控件,这个就是结合HWND的,但是由于接触duilib不久,所以一时无法看懂ActiveXUI到底是怎么将win32的HWND画上去的,只好在群里问啦,多谢铅笔群的Troy大神指导:

    当时解决完之后上传了代码,不过还是有网友看不懂,于是昨晚要求Alberl先写duilib结合MFC的教程,当然啦,这个教程本来就在Alberl的计划之类,所以就折中一下啦,上一篇教程只写了一半,等写完这个教程再去补充,如果小伙伴们还有其他要求,也可以提哦,如果在Alberl的计划内,Alberl会尽量满足小伙伴们的要求的~O(∩_∩)O~
   
    一、在MFC中使用duilib
    只需要将前面教程的CDuiFrameWnd的父窗口指定为MFC的窗口就好啦,
    将CDuiFrameWnd m_duiFrame; 定义为MFC的成员变量,在MFC的初始化函数OnInitDialog里面创建duilib的窗口,代码如下:

  1. // TODO: 在此添加额外的初始化代码
  2.     CPaintManagerUI::SetInstance(AfxGetInstanceHandle());                    // 指定duilib的实例
  3.     CPaintManagerUI::SetResourcePath(CPaintManagerUI::GetInstancePath());    // 指定duilib资源的路径,这里指定为和exe同目录
  4.     ::CoInitialize(NULL);  // 记得释放::CoUninitialize();
  5.     m_duiFrame.Create(*this, _T("DUIWnd"), UI_WNDSTYLE_CHILD, 0, 0, 0, 800, 600);
  6.     m_duiFrame.ShowWindow(TRUE);
  7.     return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE
复制代码


    这里只是将duilib嵌入到MFC的主窗口,如果想要将duilib嵌入到MFC的某个控件,也是很简单的,因为只需要一个HWND句柄就行了,就不赘述了~
    不过可以发现以下几个问题:
1、之前ActiveXUI的那个bug不再出现了。
2、所有的MFC控件都显示在duilib窗口的上面,这里和ZORD顺序应该有关系。
3、在duilib窗口上面的【确定】按钮点了没反应,【取消】按钮只有在点击不在duilib上面的那部分才会有反应。
    由于Alberl暂时只是研究界面方面,还没研究到事件响应方面,所以不去研究细节。如果有小伙伴急用的话,可以将MFC控件嵌入到duilib的控件上,或者把MFC控件放到非duilib区域,这样就可以响应了。
   
    二、在duilib中使用MFC控件
    这里示例将MFC按钮放到duilib滑块条控件的位置:
    1、准备好一个duilib控件来容纳MFC控件,代码如下:
  1. // 将带句柄HWND的控件显示到CControlUI上面
  2. class CWndUI: public CControlUI
  3. {
  4. public:
  5.     CWndUI(): m_hWnd(NULL){}
  6.     virtual void SetInternVisible(bool bVisible = true)
  7.     {
  8.         __super::SetInternVisible(bVisible);
  9.         ::ShowWindow(m_hWnd, bVisible);
  10.     }
  11.     virtual void SetPos(RECT rc)
  12.     {
  13.         __super::SetPos(rc);
  14.         ::SetWindowPos(m_hWnd, NULL, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, SWP_NOZORDER | SWP_NOACTIVATE);
  15.     }
  16.     BOOL Attach(HWND hWndNew)
  17.     {
  18.         if (! ::IsWindow(hWndNew))
  19.         {
  20.             return FALSE;
  21.         }
  22.         m_hWnd = hWndNew;
  23.         return TRUE;
  24.     }
  25.     HWND Detach()
  26.     {
  27.         HWND hWnd = m_hWnd;
  28.         m_hWnd = NULL;
  29.         return hWnd;
  30.     }
  31. protected:
  32.     HWND m_hWnd;
  33. };
复制代码
2、将XML中Slider节点换成Wnd,并且只保留位置信息,XML如下:
  1. <Wnd float="true" pos="30,77,0,0" width="139" height="18" />
复制代码
3、创建Wnd控件:由于Slider是duilib内置的控件,所以duilib会根据XML信息自动创建Slider控件,而CWndUI是我们自定义的控件,所以需要自己创建,只需要响应CreateControl函数(如果duilib发现自定义控件,会自动调用此函数来获取控件),在CDuiFrameWnd加上如下函数:
  1. virtual CControlUI* CreateControl(LPCTSTR pstrClassName)
  2.     {
  3.         if (_tcsicmp(pstrClassName, _T("Wnd")) == 0)
  4.         {
  5.             CWndUI  *pUI  = new CWndUI;            
  6.             HWND    hWnd  = CreateWindow(_T("BUTTON"), _T("win32"), WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON, 0, 0, 0, 0, m_PaintManager.GetPaintWindow(), NULL, NULL, NULL);
  7.             pUI->Attach(hWnd);  
  8.             //// 上面用的是win32的按钮,下面这段用MFC的按钮
  9.             //CButton *pBtn = new CButton;    // 记得释放内存
  10.             //pBtn->Create(_T("MFC"), WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON, CRect(0, 0, 0, 0), CWnd::FromHandle(m_PaintManager.GetPaintWindow()), 0);
  11.             //pUI->Attach(*pBtn);            
  12.             return pUI;
  13.         }
  14.         return NULL;
  15.     }
复制代码

52

主题

62

回帖

0

积分

版主

积分
0
 楼主| 发表于 2013-10-29 11:02:17 | 显示全部楼层


上面的代码用了win32的按钮,其中注释部分是MFC按钮,亲们可以都试下效果:
   
    到现在为止,我们既可以在duilib中添加MFC控件,也可以在原有的MFC项目中添加duilib控件,就不用再担心不能使用以前的控件啦~O(∩_∩)O~




来自为知笔记(Wiz)
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

果子博客
扫码关注微信公众号

Archiver|手机版|小黑屋|风叶林

GMT+8, 2026-2-1 03:31 , Processed in 0.082091 second(s), 20 queries .

Powered by 风叶林

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表