日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

duilib入门问题集

發布時間:2023/12/18 编程问答 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 duilib入门问题集 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

引入duilib時請確保引入頭文件開始時先引入COMUTIL.H頭文件


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


duilib基本程序結構


在stdafx.h文件中加入

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

    [cpp] view plaincopy print?
  • <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>??
  • <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 plaincopy print?
  • <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>??
  • <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 plaincopy print?
  • <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>??
  • <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 plaincopy print?
  • #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;?//?防止重復設置消息監聽??
  • };??
  • #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 plaincopy print?
  • #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;??
  • }??
  • #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 plaincopy print?
  • #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;??
  • };??
  • #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 plaincopy print?
  • 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;??
  • }??
  • 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 failureif (!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 plaincopy print?
  • //?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)??
  • // 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 plaincopy print?
  • PaintBkColor(hDC);????????????//?繪制背景顏色??
  • PaintBkImage(hDC);??????????//?繪制背景圖??
  • PaintStatusImage(hDC);???//?繪制狀態圖??
  • PaintText(hDC);?????????????????//?繪制文本??
  • 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" />

    總結

    以上是生活随笔為你收集整理的duilib入门问题集的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。