duilib入门问题集

2023-05-16

引入duilib时请确保引入头文件开始时先引入COMUTIL.H头文件


#include "COMUTIL.H"
#include "UIlib.h"


duilib基本程序结构


在stdafx.h文件中加入

[cpp] view plain copy print ?
  1. <span style="font-size:18px;">#include "COMUTIL.H"  
  2. #include "UIlib.h"  
  3. using namespace DuiLib;</span>  
<span style="font-size:18px;">#include "COMUTIL.H"
#include "UIlib.h"
using namespace DuiLib;</span>


[cpp] view plain copy print ?
  1. <span style="font-size:18px;">#ifndef LoginView_h__  
  2. #define LoginView_h__  
  3.   
  4.   
  5. class LoginView :  
  6.     public WindowImplBase// 只能放在最后,否则其消息路由出问题  
  7. {  
  8.   
  9.   
  10. public:  
  11.     DUI_DECLARE_MESSAGE_MAP()  
  12. public:  
  13.     LoginView(void);  
  14.     ~LoginView(void);  
  15.   
  16.   
  17.     void on_btn_click( DuiLib::TNotifyUI &msg );  
  18.   
  19.   
  20.     virtual CDuiString GetSkinFolder() { return _T ("skin\\"); }  
  21.     virtual CDuiString GetSkinFile() { return _T("login.xml"); }  
  22.     virtual LPCTSTR GetWindowClassName( void ) const { return _T("LoginView"); }  
  23. };  
  24.   
  25.   
  26. #endif // LoginView_h__</span>  
<span style="font-size:18px;">#ifndef LoginView_h__
#define LoginView_h__


class LoginView :
    public WindowImplBase// 只能放在最后,否则其消息路由出问题
{


public:
    DUI_DECLARE_MESSAGE_MAP()
public:
    LoginView(void);
    ~LoginView(void);


    void on_btn_click( DuiLib::TNotifyUI &msg );


    virtual CDuiString GetSkinFolder() { return _T ("skin\\"); }
    virtual CDuiString GetSkinFile() { return _T("login.xml"); }
    virtual LPCTSTR GetWindowClassName( void ) const { return _T("LoginView"); }
};


#endif // LoginView_h__</span>


[cpp] view plain copy print ?
  1. <span style="font-size:18px;">#include "StdAfx.h"  
  2. #include "LoginView.h"  
  3.   
  4. DUI_BEGIN_MESSAGE_MAP(LoginView, WindowImplBase)  
  5. DUI_ON_MSGTYPE(DUI_MSGTYPE_CLICK,on_btn_click)  
  6. DUI_END_MESSAGE_MAP()  
  7.   
  8.   
  9. LoginView::LoginView(void)  
  10. {  
  11. }  
  12.   
  13. LoginView::~LoginView(void)  
  14. {  
  15. }  
  16.   
  17.   
  18. void LoginView::on_btn_click( DuiLib::TNotifyUI &msg )  
  19. {  
  20.   
  21. }</span>  
<span style="font-size:18px;">#include "StdAfx.h"
#include "LoginView.h"

DUI_BEGIN_MESSAGE_MAP(LoginView, WindowImplBase)
DUI_ON_MSGTYPE(DUI_MSGTYPE_CLICK,on_btn_click)
DUI_END_MESSAGE_MAP()


LoginView::LoginView(void)
{
}

LoginView::~LoginView(void)
{
}


void LoginView::on_btn_click( DuiLib::TNotifyUI &msg )
{

}</span>


[cpp] view plain copy print ?
  1. <span style="font-size:18px;">// chatme.cpp : 定义应用程序的入口点。  
  2. //  
  3.   
  4. #include "stdafx.h"  
  5. #include "chatme.h"  
  6.   
  7. #include "LoginView.h"  
  8.   
  9. int APIENTRY _tWinMain(HINSTANCE hInstance,  
  10.                        HINSTANCE hPrevInstance,  
  11.                        LPTSTR    lpCmdLine,  
  12.                        int       nCmdShow)  
  13. {  
  14.     CPaintManagerUI::SetInstance(hInstance);  
  15.     CPaintManagerUI::SetResourcePath(CPaintManagerUI::GetInstancePath());  
  16.   
  17.   
  18.     HRESULT Hr = ::CoInitialize(NULL);  
  19.     if( FAILED(Hr) ) return 0;  
  20.   
  21.     LoginView login_view;  
  22.     login_view.Create(NULL, _T("LoginView"), UI_WNDSTYLE_DIALOG, WS_EX_STATICEDGE | WS_EX_APPWINDOW);  
  23.   
  24.     login_view.CenterWindow();  
  25.   
  26.     CPaintManagerUI::MessageLoop();  
  27.     ::CoUninitialize();  
  28.     return 0;  
  29. }</span>  
<span style="font-size:18px;">// chatme.cpp : 定义应用程序的入口点。
//

#include "stdafx.h"
#include "chatme.h"

#include "LoginView.h"

int APIENTRY _tWinMain(HINSTANCE hInstance,
                       HINSTANCE hPrevInstance,
                       LPTSTR    lpCmdLine,
                       int       nCmdShow)
{
    CPaintManagerUI::SetInstance(hInstance);
    CPaintManagerUI::SetResourcePath(CPaintManagerUI::GetInstancePath());


    HRESULT Hr = ::CoInitialize(NULL);
    if( FAILED(Hr) ) return 0;

    LoginView login_view;
    login_view.Create(NULL, _T("LoginView"), UI_WNDSTYLE_DIALOG, WS_EX_STATICEDGE | WS_EX_APPWINDOW);

    login_view.CenterWindow();

    CPaintManagerUI::MessageLoop();
    ::CoUninitialize();
    return 0;
}</span>


问:如何把资源放入zip?
答: 先SetResourcePath设置资源目录,再SetResourceZip设置压缩资源文件名


问:如何设置窗体的初始化大小?
答:设置XML文件的Window标签的size属性。


问:如何设置鼠标可拖动窗体的范围大小?
答:设置XML文件的Window标签的caption属性。


问:如何设置窗体可以通过拖动边缘改变大小?
答:在窗体创建函数的第三个参数设置为UI_WNDSTYLE_FRAME才可响应拖动改变大小,和双击标题事件。


问:为何鼠标移动到边缘没有改变窗体大小的箭头出现,不能通过拖动改变窗体大小?
答:设置window标签的sizebox属性,例如sizebox="2,2,2,2"


问:窗体不可双击最大化如何实现?
答:在窗体创建函数的第三个参数设置为UI_WNDSTYLE_DIALOG。


问:应用程序exe图标如何设置?
答:使用窗体成员函数SetIcon,参数为资源icon的id。


问:初始化时,最大化窗体如何实现?
答:调用窗体的SendMessage给窗体发送最大化消息SC_MAXIMIZE,SendMessage(WM_SYSCOMMAND, SC_MAXIMIZE,0);


问:动态改变窗体的大小如何实现?
答:使用窗体函数ResizeClient,参数分别重设的宽和高。


问:如何设置窗体屏幕居中显示?

答:使用窗体的CenterWindow函数。


问:窗体透明度如何设置?
答:设置window标签属性bktrans="true" alpha="200" alpha的值为0-255。这种设置是全体窗体透明度,所有控件都将变透明。
如果想单纯设置背景透明度控件不透明度,可以制作半透明的背景图片,设置window标签的bktrans="true",并且不设置alpha属性,切记!此时背景透明,其它控件不透明。
单独设置某个控件的透明度,可以使用图片的fade属性,或者mask属性。fade表示设置图片透明度,取值0-255。mask为设置透明的颜色。


问:默认设置的图片为拉伸平铺模式,如何设置不拉伸显示?
答:设置图片的source和dest属性,soure="左,上,右,下" dest="左,上,右,下" 
表示将source区域的图片显示到按钮的dest区域上。这里的右和下是指坐标,不是指宽度和高度。右=左+width.下=top+height。


问:如何设置选定编辑框文字的背景颜色?

答:设置nativebkcolor属性。


问:如何设置按钮的鼠标悬浮时的字体颜色?
答:设置按钮的hottextcolor属性,相对的还有pushedtextcolor和focustextcolor.


问:如何设置按钮按下时字体的颜色?
答:设置按钮的pushedtextcolor属性,相对的还有hottextcolor和focustextcolor.




问:如何自定义xml控件?
答:自定义控件和复杂的控件类型都是由简单基本控件组成。
在写好一个自定义的控件xml模板后,
CDialogBuilder dlg_builder;
CControlUI * pControl = dlg_builder.Create("item.xml");
注意这里的item.xml要放在主界面的xml所在的文件夹内,并且无需在指定路径了。
该函数返回一个CControlUI的一个句柄,得到这样一个句柄就是一个控件了。
如果要获取复杂控件的某个子控件的句柄,然后想通过该句柄改变子控件的状态。
首先给这个子控件取一个名字,然后可以通过pControl的FindSubControl("name")来获取该
控件的句柄了。得到句柄后就可以设置它的所有属性了,例如
pbtn->SetAttribute(_T("normalimage"), _T("file='images\\downlist_ok.png' dest='20,14,32,26'"));就能更改它的状态图片了。


问:多线程下如何更改dui的界面信息?
答:线程里不要操作界面的信息,应该通过SendMessage或者PostMessage给界面的m_hWnd发送自定义消息。然后在界面的消息循环里面在做操作界面的动作。
自定义处理的消息处理函数可以从重写方法
LRESULT MyWnd::HandleCustomMessage( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled )
{
//这里处理完后,bHandled置true 返回基类,让基类去操作
return WindowImplBase::HandleCustomMessage(uMsg, wParam, lParam, bHandled);
}
具体可以如下使用:
#define ON_PERCENT_MSG              WM_USER + 500
然后在线程函数中发送消息给界面
int DownloadView::on_percent( double percent, int index, INT_PTR user_data )
{
    ::SendMessage(m_hWnd, ON_PERCENT_MSG, (WPARAM)&percent, (LPARAM)user_data);
    return 0;
}


最后在界面消息循环中进行处理消息
LRESULT DownloadView::HandleCustomMessage( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled )
{
    switch (uMsg)
    {
    case ON_PERCENT_MSG:
         // 处理界面相关的操作
        break;
    default:
        break;
    }
    return WindowImplBase::HandleCustomMessage(uMsg, wParam, lParam, bHandled);
}





问:如何让使用duilib的win32工程支持MFC?
答:
1、在stdafx.h加入以下
#define VC_EXTRALEAN
#include <afxwin.h>         // MFC 核心组件和标准组件
#include <afxext.h>         // MFC 扩展
#include <afxdisp.h>        // MFC 自动化类
#ifndef _AFX_NO_OLE_SUPPORT
#include <afxdtctl.h>
// MFC 对 Internet Explorer 4 公共控件的支持
#endif
#ifndef _AFX_NO_AFXCMN_SUPPORT
#include <afxcmn.h>
// MFC 对 Windows 公共控件的支持
#endif // _AFX_NO_AFXCMN_SUPPORT
2、在程序初始化main的开始加入mfc的初始化。
// initialize MFC and print and error on failure
if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
{
// TODO: change error code to suit your needs
_tprintf(_T("Fatal Error: MFC initialization failed\n"));
return 1;
}
3、设置页属性-->常规-->使用mfc设置为 Use MFC in a Shared DLL


4、设置C++-->代码生成-->运行时库根据debug或者release设置为MDD或者MD。

[cpp] view plain copy print ?
  1. #pragma once  
  2.   
  3.   
  4. #define DUI_MFCCTRL_COMMAND_MSG _T("MFC_CTRL_NOTIFY_MSG")  
  5. #define DUI_MFCCTRL_NOTIFY_MSG _T("MFC_CTRL_COMMAND_MSG")  
  6.   
  7.   
  8. // 封装MFC控件到DUI控件中,实现duilib中嵌入MFC控件  
  9. // 通过维护一个HWND实现  
  10. class CDUIMFCCtrlWrapper : public DuiLib::CControlUI, public DuiLib::IMessageFilterUI  
  11. {  
  12. public:  
  13.     CDUIMFCCtrlWrapper(void) : m_hWnd(NULL), m_bAddedMessageFilter(FALSE){}  
  14.   
  15.   
  16.     ~CDUIMFCCtrlWrapper(void){}  
  17.   
  18.   
  19.     // 绑定  
  20.     BOOL Attach(HWND hWndNew);  
  21.   
  22.   
  23.     HWND Detach();  
  24.   
  25.   
  26. protected:  
  27.     // 控制显示  
  28.     virtual void SetInternVisible(bool bVisible = true);  
  29.   
  30.   
  31.     // 控制位置  
  32.     virtual void SetPos(RECT rc);  
  33.   
  34.   
  35.     // 对控件消息的分派,例如对发送给如对命令消息和通知消息进行分派  
  36.     // 通过SendNotify实现,可以在OnNotify中进行响应。  
  37.     virtual LRESULT MessageHandler( UINT uMsg, WPARAM wParam, LPARAM lParam, bool& bHandled );  
  38.   
  39.   
  40.     virtual void SetManager( DuiLib::CPaintManagerUI* pManager, DuiLib::CControlUI* pParent, bool bInit = true );  
  41.   
  42.   
  43. protected:  
  44.     HWND m_hWnd;  
  45.     BOOL m_bAddedMessageFilter; // 防止重复设置消息监听  
  46. };  
#pragma once


#define DUI_MFCCTRL_COMMAND_MSG _T("MFC_CTRL_NOTIFY_MSG")
#define DUI_MFCCTRL_NOTIFY_MSG _T("MFC_CTRL_COMMAND_MSG")


// 封装MFC控件到DUI控件中,实现duilib中嵌入MFC控件
// 通过维护一个HWND实现
class CDUIMFCCtrlWrapper : public DuiLib::CControlUI, public DuiLib::IMessageFilterUI
{
public:
	CDUIMFCCtrlWrapper(void) : m_hWnd(NULL), m_bAddedMessageFilter(FALSE){}


	~CDUIMFCCtrlWrapper(void){}


    // 绑定
    BOOL Attach(HWND hWndNew);


    HWND Detach();


protected:
	// 控制显示
	virtual void SetInternVisible(bool bVisible = true);


	// 控制位置
	virtual void SetPos(RECT rc);


	// 对控件消息的分派,例如对发送给如对命令消息和通知消息进行分派
	// 通过SendNotify实现,可以在OnNotify中进行响应。
	virtual LRESULT MessageHandler( UINT uMsg, WPARAM wParam, LPARAM lParam, bool& bHandled );


	virtual void SetManager( DuiLib::CPaintManagerUI* pManager, DuiLib::CControlUI* pParent, bool bInit = true );


protected:
	HWND m_hWnd;
	BOOL m_bAddedMessageFilter; // 防止重复设置消息监听
};



[cpp] view plain copy print ?
  1. #include "StdAfx.h"  
  2.   
  3.   
  4. #include "DUIMFCCtrlWrapper.h"  
  5.   
  6.   
  7. using namespace DuiLib;  
  8.   
  9.   
  10. void CDUIMFCCtrlWrapper::SetManager( CPaintManagerUI* pManager, CControlUI* pParent, bool bInit /*= true */ )  
  11. {  
  12.     if (pManager && !m_bAddedMessageFilter)  
  13.     {  
  14.         m_bAddedMessageFilter = TRUE;  
  15.         // 设置本控件封装能接收到消息,从而进行分派  
  16.         pManager->AddMessageFilter(this);  
  17.     }  
  18.     CControlUI::SetManager(pManager, pParent, false);  
  19. }  
  20.   
  21.   
  22. LRESULT CDUIMFCCtrlWrapper::MessageHandler( UINT uMsg, WPARAM wParam, LPARAM lParam, bool& bHandled )  
  23. {  
  24.     bHandled = TRUE; // 如果是命令消息和通知消息等MFC控件消息则不用再传递下去  
  25.     if (uMsg == WM_NOTIFY)  
  26.     {  
  27.         NMHDR* pNMHDR = (NMHDR*)lParam;  
  28.         HWND hWndCtrl = pNMHDR->hwndFrom;  
  29.         UINT nId = LOWORD(wParam);  
  30.         int nCode = pNMHDR->code;  
  31.         ASSERT(NULL != hWndCtrl);  
  32.         ASSERT(::IsWindow(hWndCtrl));  
  33.         typedef struct _CtrlNotifyStruct  
  34.         {  
  35.             NMHDR* pNMHDR;  
  36.             int nCode;  
  37.         }CtrlNotifyStruct;  
  38.         CtrlNotifyStruct ns;  
  39.         ns.pNMHDR = pNMHDR;  
  40.         ns.nCode = nCode;  
  41.         m_pManager->SendNotify(this, DUI_MFCCTRL_COMMAND_MSG, WPARAM(nId), LPARAM(&ns));  
  42.     }  
  43.     else if (WM_COMMAND == uMsg)  
  44.     {  
  45.         UINT nID = LOWORD(wParam);  
  46.         HWND hWndCtrl = (HWND)lParam;  
  47.         int nCode = HIWORD(wParam);  
  48.         m_pManager->SendNotify(this, DUI_MFCCTRL_NOTIFY_MSG, nID, nCode);  
  49.     }  
  50.     //else if(XTPWM_PROPERTYGRID_NOTIFY == uMsg)  
  51.     //{  
  52.     //    m_pManager->SendNotify(this, DUI_MFCCTRL_NOTIFY_MSG, wParam, lParam);  
  53.     //}  
  54.     else  
  55.     {  
  56.         // 否则该消息需要继续传递下去  
  57.         bHandled = FALSE;  
  58.         return 1;  
  59.     }  
  60.     return 0;  
  61. }  
  62.   
  63.   
  64. void CDUIMFCCtrlWrapper::SetPos( RECT rc )  
  65. {  
  66.     __super::SetPos(rc);  
  67.     ::SetWindowPos(m_hWnd, NULL, rc.left,   
  68.         rc.top, rc.right - rc.left, rc.bottom - rc.top,  
  69.         SWP_NOZORDER | SWP_NOACTIVATE);  
  70. }  
  71.   
  72.   
  73. void CDUIMFCCtrlWrapper::SetInternVisible( bool bVisible /*= true*/ )  
  74. {  
  75.     __super::SetInternVisible(bVisible);  
  76.     ::ShowWindow(m_hWnd, bVisible);  
  77. }  
  78.   
  79.   
  80. HWND CDUIMFCCtrlWrapper::Detach()  
  81. {  
  82.     HWND hWnd = m_hWnd;  
  83.     m_hWnd = NULL;  
  84.     return hWnd;  
  85. }  
  86.   
  87.   
  88. BOOL CDUIMFCCtrlWrapper::Attach( HWND hWndNew )  
  89. {  
  90.     if (! ::IsWindow(hWndNew))  
  91.     {  
  92.         return FALSE;  
  93.     }  
  94.     m_hWnd = hWndNew;  
  95.     return TRUE;  
  96. }  
#include "StdAfx.h"


#include "DUIMFCCtrlWrapper.h"


using namespace DuiLib;


void CDUIMFCCtrlWrapper::SetManager( CPaintManagerUI* pManager, CControlUI* pParent, bool bInit /*= true */ )
{
    if (pManager && !m_bAddedMessageFilter)
    {
        m_bAddedMessageFilter = TRUE;
        // 设置本控件封装能接收到消息,从而进行分派
        pManager->AddMessageFilter(this);
    }
    CControlUI::SetManager(pManager, pParent, false);
}


LRESULT CDUIMFCCtrlWrapper::MessageHandler( UINT uMsg, WPARAM wParam, LPARAM lParam, bool& bHandled )
{
    bHandled = TRUE; // 如果是命令消息和通知消息等MFC控件消息则不用再传递下去
    if (uMsg == WM_NOTIFY)
    {
        NMHDR* pNMHDR = (NMHDR*)lParam;
        HWND hWndCtrl = pNMHDR->hwndFrom;
        UINT nId = LOWORD(wParam);
        int nCode = pNMHDR->code;
        ASSERT(NULL != hWndCtrl);
        ASSERT(::IsWindow(hWndCtrl));
        typedef struct _CtrlNotifyStruct
        {
            NMHDR* pNMHDR;
            int nCode;
        }CtrlNotifyStruct;
        CtrlNotifyStruct ns;
        ns.pNMHDR = pNMHDR;
        ns.nCode = nCode;
        m_pManager->SendNotify(this, DUI_MFCCTRL_COMMAND_MSG, WPARAM(nId), LPARAM(&ns));
    }
    else if (WM_COMMAND == uMsg)
    {
        UINT nID = LOWORD(wParam);
        HWND hWndCtrl = (HWND)lParam;
        int nCode = HIWORD(wParam);
        m_pManager->SendNotify(this, DUI_MFCCTRL_NOTIFY_MSG, nID, nCode);
    }
    //else if(XTPWM_PROPERTYGRID_NOTIFY == uMsg)
    //{
    //    m_pManager->SendNotify(this, DUI_MFCCTRL_NOTIFY_MSG, wParam, lParam);
    //}
    else
    {
        // 否则该消息需要继续传递下去
        bHandled = FALSE;
        return 1;
    }
    return 0;
}


void CDUIMFCCtrlWrapper::SetPos( RECT rc )
{
    __super::SetPos(rc);
    ::SetWindowPos(m_hWnd, NULL, rc.left, 
        rc.top, rc.right - rc.left, rc.bottom - rc.top,
        SWP_NOZORDER | SWP_NOACTIVATE);
}


void CDUIMFCCtrlWrapper::SetInternVisible( bool bVisible /*= true*/ )
{
    __super::SetInternVisible(bVisible);
    ::ShowWindow(m_hWnd, bVisible);
}


HWND CDUIMFCCtrlWrapper::Detach()
{
    HWND hWnd = m_hWnd;
    m_hWnd = NULL;
    return hWnd;
}


BOOL CDUIMFCCtrlWrapper::Attach( HWND hWndNew )
{
    if (! ::IsWindow(hWndNew))
    {
        return FALSE;
    }
    m_hWnd = hWndNew;
    return TRUE;
}



[cpp] view plain copy print ?
  1. #include "stdafx.h"  
  2. #include "DUIMFCCtrlWrapper.h"  
  3. #include "Mycug.h"  
  4.   
  5.   
  6. using namespace DuiLib;  
  7.   
  8.   
  9. class CFrameWindowWnd : public WindowImplBase  
  10. {  
  11.     DUI_DECLARE_MESSAGE_MAP()  
  12. public:  
  13.       
  14. protected:  
  15.     virtual CDuiString GetSkinFolder()   
  16.     {  
  17.         return CPaintManagerUI::GetInstancePath();  
  18.     }  
  19.   
  20.   
  21.     virtual CDuiString GetSkinFile()   
  22.     {  
  23.         return _T("test.xml");  
  24.     }  
  25.   
  26.   
  27.     virtual LPCTSTR GetWindowClassName( void ) const  
  28.     {  
  29.         return _T("CFrameWindowWnd");  
  30.     }  
  31.   
  32.   
  33.     virtual CControlUI* CreateControl( LPCTSTR pstrClass )   
  34.     {  
  35.         if (_tcscmp(pstrClass, _T("MfcCtrl")) == 0)  
  36.         {  
  37.             return new CDUIMFCCtrlWrapper();  
  38.         }  
  39.         return NULL;  
  40.     }  
  41.    
  42.     void OnClick(TNotifyUI& msg)  
  43.     {  
  44.         CDuiString sCtrlName = msg.pSender->GetName();  
  45.         if( sCtrlName == _T("closebtn") )  
  46.         {  
  47.             PostMessage(WM_QUIT, 0, 0);  
  48.             return;   
  49.         }  
  50.         else if( sCtrlName == _T("minbtn"))  
  51.         {   
  52.             SendMessage(WM_SYSCOMMAND, SC_MINIMIZE, 0);   
  53.             return;   
  54.         }  
  55.         else if( sCtrlName == _T("maxbtn"))  
  56.         {   
  57.             SendMessage(WM_SYSCOMMAND, SC_MAXIMIZE, 0);   
  58.             return;   
  59.         }  
  60.         else if( sCtrlName == _T("restorebtn"))  
  61.         {   
  62.             SendMessage(WM_SYSCOMMAND, SC_RESTORE, 0);   
  63.             return;   
  64.         }  
  65.     }   
  66.   
  67.   
  68.     virtual void InitWindow()   
  69.     {  
  70.         CDUIMFCCtrlWrapper* pCtrl = (CDUIMFCCtrlWrapper*)m_PaintManager.FindControl(_T("grid"));  
  71.         if (pCtrl)  
  72.         {  
  73.             m_GridCtrl.CreateGrid(WS_CHILD|WS_VISIBLE,CRect(0,0,0,0),CWnd::FromHandle(GetHWND()),1234);  
  74.             pCtrl->Attach(m_GridCtrl.GetSafeHwnd());  
  75.         }  
  76.     }  
  77.   
  78.   
  79.     MyCug m_GridCtrl;  
  80. };  
#include "stdafx.h"
#include "DUIMFCCtrlWrapper.h"
#include "Mycug.h"


using namespace DuiLib;


class CFrameWindowWnd : public WindowImplBase
{
    DUI_DECLARE_MESSAGE_MAP()
public:
    
protected:
    virtual CDuiString GetSkinFolder() 
    {
        return CPaintManagerUI::GetInstancePath();
    }


    virtual CDuiString GetSkinFile() 
    {
        return _T("test.xml");
    }


    virtual LPCTSTR GetWindowClassName( void ) const
    {
        return _T("CFrameWindowWnd");
    }


    virtual CControlUI* CreateControl( LPCTSTR pstrClass ) 
    {
        if (_tcscmp(pstrClass, _T("MfcCtrl")) == 0)
        {
            return new CDUIMFCCtrlWrapper();
        }
        return NULL;
    }
 
    void OnClick(TNotifyUI& msg)
    {
        CDuiString sCtrlName = msg.pSender->GetName();
        if( sCtrlName == _T("closebtn") )
        {
            PostMessage(WM_QUIT, 0, 0);
            return; 
        }
        else if( sCtrlName == _T("minbtn"))
        { 
            SendMessage(WM_SYSCOMMAND, SC_MINIMIZE, 0); 
            return; 
        }
        else if( sCtrlName == _T("maxbtn"))
        { 
            SendMessage(WM_SYSCOMMAND, SC_MAXIMIZE, 0); 
            return; 
        }
        else if( sCtrlName == _T("restorebtn"))
        { 
            SendMessage(WM_SYSCOMMAND, SC_RESTORE, 0); 
            return; 
        }
    } 


    virtual void InitWindow() 
    {
        CDUIMFCCtrlWrapper* pCtrl = (CDUIMFCCtrlWrapper*)m_PaintManager.FindControl(_T("grid"));
        if (pCtrl)
        {
            m_GridCtrl.CreateGrid(WS_CHILD|WS_VISIBLE,CRect(0,0,0,0),CWnd::FromHandle(GetHWND()),1234);
            pCtrl->Attach(m_GridCtrl.GetSafeHwnd());
        }
    }


    MyCug m_GridCtrl;
};


[cpp] view plain copy print ?
  1. DUI_BEGIN_MESSAGE_MAP(CFrameWindowWnd, WindowImplBase)  
  2.     DUI_ON_MSGTYPE(DUI_MSGTYPE_CLICK,OnClick)  
  3. DUI_END_MESSAGE_MAP()  
  4.   
  5.   
  6. int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE /*hPrevInstance*/LPSTR /*lpCmdLine*/int nCmdShow)  
  7. {  
  8.     // initialize MFC and print and error on failure  
  9.     if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))  
  10.     {  
  11.         // TODO: change error code to suit your needs  
  12.         _tprintf(_T("Fatal Error: MFC initialization failed\n"));  
  13.         return 1;  
  14.     }  
  15.     CPaintManagerUI::SetInstance(hInstance);  
  16.     CPaintManagerUI::SetResourcePath(CPaintManagerUI::GetInstancePath());  
  17.   
  18.   
  19.     HRESULT Hr = ::CoInitialize(NULL);  
  20.     if( FAILED(Hr) ) return 0;  
  21.   
  22.   
  23.     CFrameWindowWnd* pFrame = new CFrameWindowWnd();  
  24.     if( pFrame == NULL ) return 0;  
  25.     pFrame->Create(NULL, _T("测试"), UI_WNDSTYLE_FRAME, WS_EX_WINDOWEDGE);  
  26.     pFrame->CenterWindow();  
  27.     pFrame->ShowWindow(true);  
  28.     CPaintManagerUI::MessageLoop();  
  29.   
  30.   
  31.     ::CoUninitialize();  
  32.     return 0;  
  33. }  
DUI_BEGIN_MESSAGE_MAP(CFrameWindowWnd, WindowImplBase)
    DUI_ON_MSGTYPE(DUI_MSGTYPE_CLICK,OnClick)
DUI_END_MESSAGE_MAP()


int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE /*hPrevInstance*/, LPSTR /*lpCmdLine*/, int nCmdShow)
{
    // initialize MFC and print and error on failure
    if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
    {
        // TODO: change error code to suit your needs
        _tprintf(_T("Fatal Error: MFC initialization failed\n"));
        return 1;
    }
    CPaintManagerUI::SetInstance(hInstance);
    CPaintManagerUI::SetResourcePath(CPaintManagerUI::GetInstancePath());


    HRESULT Hr = ::CoInitialize(NULL);
    if( FAILED(Hr) ) return 0;


    CFrameWindowWnd* pFrame = new CFrameWindowWnd();
    if( pFrame == NULL ) return 0;
    pFrame->Create(NULL, _T("测试"), UI_WNDSTYLE_FRAME, WS_EX_WINDOWEDGE);
    pFrame->CenterWindow();
    pFrame->ShowWindow(true);
    CPaintManagerUI::MessageLoop();


    ::CoUninitialize();
    return 0;
}




duilib绘图部分

图像的绘制大部分使用了绘制引擎的DrawImageString函数,该函数实现知道图像名称绘制到指定目标区域的功能
并且通过指定pStrModify的属性能够进行不同需求的绘制,例如,仅扣取源图像的某个位置绘制到目标的某个区域、
设置四边圆角绘制、为bmp等指定某种颜色为透明颜色、平铺或者拉伸绘制、设置透明度等。
DrawImageString最终又调用CRenderEngine::DrawImage进行绘制。


[cpp] view plain copy print ?
  1. // hDc HDC句柄  
  2. // CPaintManagerUI句柄  
  3. // rc 目标画布的大小  
  4. // rcPaint 绘制区域  
  5. // pStrImage 为源图像的名称,不需提供路径,函数内部会自动加上资源位置的路径,路径为CPaintManagerUI::SetResourcePath设置的路径。  
  6. // pStrModify 设置绘制属性,含义为:  
  7. // 2、file='aaa.jpg' res='' restype='0' dest='0,0,0,0' source='0,0,0,0' corner='0,0,0,0'   
  8. // mask='#FF0000' fade='255' hole='false' xtiled='false' ytiled='false'  
  9. // source和dest表示从源图像的source区域贴到目标图像的dest区域,mask表示让某颜色为透明色,例如mask="#FF000000",设置黑色为透明色。  
  10. // xtiled,ytiled 设置为true表示横向和纵向的图像不拉伸显示而是平铺显示  
  11. // hole 为true表示不绘制中间部分,为某些场合提高性能  
  12. bool CRenderEngine::DrawImageString(HDC hDC, CPaintManagerUI* pManager, const RECT& rc, const RECT& rcPaint,   
  13.                                           LPCTSTR pStrImage, LPCTSTR pStrModify)  
  14. {  
  15.     if ((pManager == NULL) || (hDC == NULL)) return false;  
  16.   
  17.   
  18.     // 1、aaa.jpg  
  19.     // 2、file='aaa.jpg' res='' restype='0' dest='0,0,0,0' source='0,0,0,0' corner='0,0,0,0'   
  20.     // mask='#FF0000' fade='255' hole='false' xtiled='false' ytiled='false'  
  21.   
  22.   
  23. }  
  24. void CRenderEngine::DrawImage(HDC hDC, HBITMAP hBitmap, const RECT& rc, const RECT& rcPaint,  
  25.                                     const RECT& rcBmpPart, const RECT& rcCorners, bool alphaChannel,   
  26.                                     BYTE uFade, bool hole, bool xtiled, bool ytiled)  
// hDc HDC句柄
// CPaintManagerUI句柄
// rc 目标画布的大小
// rcPaint 绘制区域
// pStrImage 为源图像的名称,不需提供路径,函数内部会自动加上资源位置的路径,路径为CPaintManagerUI::SetResourcePath设置的路径。
// pStrModify 设置绘制属性,含义为:
// 2、file='aaa.jpg' res='' restype='0' dest='0,0,0,0' source='0,0,0,0' corner='0,0,0,0' 
// mask='#FF0000' fade='255' hole='false' xtiled='false' ytiled='false'
// source和dest表示从源图像的source区域贴到目标图像的dest区域,mask表示让某颜色为透明色,例如mask="#FF000000",设置黑色为透明色。
// xtiled,ytiled 设置为true表示横向和纵向的图像不拉伸显示而是平铺显示
// hole 为true表示不绘制中间部分,为某些场合提高性能
bool CRenderEngine::DrawImageString(HDC hDC, CPaintManagerUI* pManager, const RECT& rc, const RECT& rcPaint, 
                                          LPCTSTR pStrImage, LPCTSTR pStrModify)
{
	if ((pManager == NULL) || (hDC == NULL)) return false;


    // 1、aaa.jpg
    // 2、file='aaa.jpg' res='' restype='0' dest='0,0,0,0' source='0,0,0,0' corner='0,0,0,0' 
    // mask='#FF0000' fade='255' hole='false' xtiled='false' ytiled='false'


}
void CRenderEngine::DrawImage(HDC hDC, HBITMAP hBitmap, const RECT& rc, const RECT& rcPaint,
                                    const RECT& rcBmpPart, const RECT& rcCorners, bool alphaChannel, 
                                    BYTE uFade, bool hole, bool xtiled, bool ytiled)




duilib中所有元素的显示都在整个消息循环的WM_PAINT中进行绘制。
第一次绘制之前会发送一个名为_T("windowinit")的通知。
然后为CControlUI的绘制,绘制的顺序为:背景颜色->背景图->状态图->文本->边框
会顺序调用CControlUI的以下函数。        
[cpp] view plain copy print ?
  1. PaintBkColor(hDC);            // 绘制背景颜色  
  2. PaintBkImage(hDC);          // 绘制背景图  
  3. PaintStatusImage(hDC);   // 绘制状态图  
  4. PaintText(hDC);                 // 绘制文本  
  5. PaintBorder(hDC);            // 绘制边框  
PaintBkColor(hDC);            // 绘制背景颜色
PaintBkImage(hDC);          // 绘制背景图
PaintStatusImage(hDC);   // 绘制状态图
PaintText(hDC);                 // 绘制文本
PaintBorder(hDC);            // 绘制边框


所以有需求在界面上动态绘制一些内容时,可以通过CControlUI进行子类化,然后重写PaintStatusImage,
在PaintStatusImage里面进行绘图操作。绘制时可以直接调用duilib绘制引擎进行绘制,比较便捷。当然也可以使用GDI+等库直接进行绘制。


duilib的图像文件的加载是通过一个开源库stb_image.c实现。
并只使用了该库的stbi_load_from_memory和stbi_image_free这两个功能函数。
该库的链接地址:http://nothings.org/stb_image.c
该库对图片的格式的支持情况说明如下:
JPEG 支持Baseline标准型的JPEG,不支持渐进式Progressive的JPEG
PNG   仅支持8位的png图像
BMP  不支持1bpp的bmp,不支持行程编码RLE的bmp
PSD  紧显示合成的图像,不支持额外的通道
GIF *comp always reports as 4-channel


所以在duilib中使用的图片时需要注意到这个限制,否则有些图片将显示不出来。


duilib中把图片文件加载到内存后,由库stb_image.c解析并最终转为DIB处理。
duilib支持从图片文件、从包含图片文件的压缩包文件和VC资源中载入图片。
载入后最终返回TImageInfo结构体指针,包含HBITMAP、图像宽度、图像高度、alpha通道、mask和资源类型等信息。
载入函数为:TImageInfo* CRenderEngine::LoadImage(STRINGorID bitmap, LPCTSTR type, DWORD mask);
duilib中所有的图片资源只从加载一次,然后保存在CPaintManagerUI中的m_mImageHash成员中,该成员为一个
hashmap存储TImageInfo*信息,当已经存在要绘制显示的图片信息时,直接从map中获取显示,否则从文件加载
在添加到map中。



问:如何管理duilib界面皮肤资源?
答:把所有XML文件在同一个目录下,图片资源另外放在一个地方。当如下进行布局资源时,skin目录为设置资源的目录,imagedir1目录放置1.xml文件利用到的图片资源,imagedir2放置2.xml文件利用到的资源。
然后1.xml文件文件中的图片资源名称需要加上相对于当前xml文件的路径信息即可。例如:normalimage="imagedir1/1.png"这样的形式。使用设计器为XML添加资源时会自动转化为相对路径。
skin/
1.xml
2.xml
imagedir1/
1.png
2.png
imagedir2/
1.png
2.png




需注意一个问题,那就是字体的管理。字体对于一个窗口来说是全局的,索引从0开始,font = 0表示使用排在第一位的字体。如果一个界面被拆分为多个XML文件管理,并且当每个单独的文件自己添加字体时,联合起来的时候,会跟其它的字体发生冲突,即索引不是原来的索引了。索引得从全局来看。按照全局的方式进行设置好索引后,对于每个xml文件的预览操作时,又看不到所见即所得的效果了。




关于设计器
问题:为什么给控件设置name属性后保存,但该属性信息丢失?
答:设置控件名称,需要注意,名称中不能含有该控件类名的字段,例如设置其中一个选项按钮的名字为OptionUIMyTest,将不会被保存,因为默认的OptionUI1、OptionUI2等为设计器默认使用的名字当存在OptionUI时,设计器认为是默认的,并非用户设定,所以没有保存该信息到XML文件中。



问:如何把一个内容很长的xml文件分为拆分进行管理?
答:可以使用ChildLayout布局。指定xmlfile属性设置为引用的xml文件。例如以下例子,必须注意一个问题,就是tab_main.xml设置上<Window>标签,并且不要设置size属性,否则会跟主窗体冲突,该大小会作为主窗体的大小而发生错误。


            <TabLayout name="MainTab" width="870" height="362">
                <ChildLayout xmlfile="tab_main.xml" />
                <VerticalLayout padding="1,0,1,1" bkcolor="#FFFFFFFF" />
            </TabLayout>


除了使用ChildLayout布局外,可以使用Include标签,例如:
<Include source="scrollbar.xml" />
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

duilib入门问题集 的相关文章

随机推荐

  • 在C++中调用DLL中的函数

    1 dll 的优点 代码复用是提高软件开发效率的重要途径 一般而言 xff0c 只要某部分代码具有通用性 xff0c 就可将它构造成相对独立的功能模块并在之后的项目中重复使用 比较常见的例子是各种应用程序框架 xff0c ATL MFC 等
  • HC-SR04超级简单教程(快速入门)

    目录 一 模块介绍 xff08 个人理解 xff09 1 简单理解 2 该模块的参数 二 HC SR04的操作 三 代码 1 代码前的注意事项 2 关键代码 四 代码实战效果图 五 结束 一 模块介绍 xff08 个人理解 xff09 1
  • C++中对于类来说头文件(.h)和源文件(.cpp)都应该写些什么 (类的常规创建)

    头文件 h xff1a 写类的声明 xff08 包括类里面的成员和方法的声明 xff09 函数原型 define常数等 xff0c 但一般来说不写出具体的实现 在写头文件时需要注意 xff0c 在开头和结尾处必须按照如下样式加上预编译语句
  • c#的接口详解

    什么是接口 xff1f 其实 xff0c 接口简单理解就是一种约定 xff0c 使得实现接口的类或结构在形式上保持一致 个人觉得 xff0c 使用接口可以使程序更加清晰和条理化 xff0c 这就是接口的好处 xff0c 但并不是所有的编程语
  • C语言中的全局变量定义与使用

    1 书中对 全局变量 的定义 在函数内定义的变量是局部变量 xff0c 而在函数外定义的变量叫做外部变量 xff0c 外部变量是全局变量 全局变量可以为本文件中其他函数所共用它的有效范围从定义变量的位置开始到本源文件结束 建立全局变量的作用
  • C,C++,C#note

    1 c 43 43 中的类的定义和声明可以都写在头文件中 xff0c 然后cpp文件include头文件 xff1b 也可以声明在头文件 xff0c 定义在cpp文件 xff1b 或者所有声明和定义都放在cpp文件 xff1b 混写定义与声
  • 在C++中可以用3种方法访问一个字符串

    用字符数组存放一个字符串 例6 10 定义一个字符数组并初始化 xff0c 然后输出其中的字符串 ol class snippet num style margin top 0px margin bottom 0px margin left
  • 动态存储和静态存储区域区别

    动态存储方式 所谓动态存储方式是指在程序运行期间根据需要进行动态的分配存储空间的方式 动态存储变量是在程序执行过程中 xff0c 使用它时才分配存储单元 xff0c 使用完毕立即释放 典型的例子是函数的形式参数 xff0c 在函数定义时并不
  • c++中默认32位int类型转换截取高位部分

    int类型的变量固定为4个字节 xff0c 共32位 int类型变量初始值一般为0 xff0c 范围 2 31 2 31 1 即 2147483648 xff0c 2147483647 16 位系统下 xff0c int 是 2 个字节 x
  • c#-接口

    c 中的接口中必须是未实现的方法 xff0c 例如属性 xff0c 事件 xff0c 索引器 xff0c 一般函数等 除此之外不能有其他的成员 xff0c 类可以继承两个或两个以上的接口 xff0c 派生类中必须实现接口中的所有方法
  • C# SerialPort 读写三菱FX系列PLC

    1 xff1a 串口初始化 com 61 new SerialPort 34 COM3 34 9600 Parity Even 7 StopBits One 2 xff1a 打开关闭串口 if com IsOpen com Close co
  • c++中用new和不用new创建对象的本质区别

    1 xff1a 作用域不同 不用new xff1a 作用域限制在定义类对象的方法中 xff0c 当方法结束时 xff0c 类对象也被系统释放了 xff0c xff08 安全不会造成内存系统泄漏 xff09 用new xff1a 创建的是指向
  • ubuntu系统通过ifconfig查看eth0只有ipv6没有ipv4的解决方案

    只有inet6 addr 配置eth0 3 重新启动sudo etc init d networking restart IP地址出来了 看起来就正常 4 看其他资料 xff0c linux 43 QT4 0 xff0c 在这个开发板上的l
  • Action<T> 无参数委托详解

    C 委托Action Action lt T gt Func lt T gt Predicate lt T gt CLR环境中给我们内置了几个常用委托Action Action lt T gt Func lt T gt Predicate
  • 在C++里,有两种方法创建对象:

    方法一 xff1a ClassName object param 这样就声明了一个ClassName类型的object对象 xff0c C 43 43 会为它分配足够的存放对象所有成员的存储空间 注意 xff1a 为节省存储空间 xff0c
  • C++中引用(&)的用法和应用实例

    对于习惯使用C进行开发的朋友们 xff0c 在看到c 43 43 中出现的 amp 符号 xff0c 可能会犯迷糊 xff0c 因为在C语言中这个符号表示了取地址符 xff0c 但是在C 43 43 中它却有着不同的用途 xff0c 掌握C
  • C++中重载与重写函数区别及虚函数(转载)

    C 43 43 中重载与重写函数区别及虚函数 C 43 43 中的虚函数 virtual function 1 简介 虚函数是C 43 43 中用于实现多态 polymorphism 的机制 核心理念就是通过基类访问派生类定义的函数 假设我
  • c#中的静态构造函数

    静态构造函数是C 的一个新特性 xff0c 其实好像很少用到 不过当我们想初始化一些静态变量的时候就需要用到它了 这个构造函数是属于类的 xff0c 而不是属于哪里实例的 xff0c 就是说这个构造函数只会被执行一次 也就是在创建第一个实例
  • C++中重写与覆写(虚函数virtual)的区别

    本文章已收录于 xff1a 虚函数的情况下调用成员函数时调用的是指向对象的所属类的成员函数例子中为apple class fruit public void func printf 34 fruit n 34 virtual void vf
  • duilib入门问题集

    引入duilib时 请确保引入头文件开始时先引入COMUTIL H头文件 include 34 COMUTIL H 34 include 34 UIlib h 34 duilib基本程序结构 在stdafx h文件中加入 cpp view