duilib程序中,编写自己的窗口类一般的继承关系有两种,一种是继承自CWindowWnd、INotifyUI、IMessageFilterUI,而第二种方式是继承自duilib封装好的通用窗口类WindowImplBase
从源码中可以看到WindowImplBase其实是继承自一般能用到的所有基础类:
class DUILIB_API WindowImplBase
: public CWindowWnd
, public CNotifyPump
, public INotifyUI
, public IMessageFilterUI
, public IDialogBuilderCallback
从上可以看到,一般编写自己的duilib窗口类所需要继承的几个类都已经被WindowImplBase继承了,而且已经做了部分封装,这样我们直接继承WindowImplBase不是方便了很多,而且只需要实现以下几个函数即可实现简单的duilib窗口,很简洁方便
virtual CDuiString GetSkinFolder() = 0;
virtual CDuiString GetSkinFile() = 0;
virtual LPCTSTR GetWindowClassName(void) const = 0 ;
WindowImplBase通用窗口类目前不完全统计bug较多,好多地方需要自己修改,这个就要根据自己的需求不同自己去调整该类的源码,达到自己想要的效果。
下面实现一个简单的例子:
#include "resource.h"
class CMainFrame : public WindowImplBase
{
public:
CMainFrame();
~CMainFrame();
public:
LPCTSTR GetWindowClassName() const;
virtual CDuiString GetSkinFile();
virtual CDuiString GetSkinFolder();
virtual LRESULT HandleCustomMessage(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
virtual LRESULT HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam);
public:
protected:
void Notify(TNotifyUI& msg);
bool OnBtnClickOfEnter(TNotifyUI& msg);
};
#include "stdafx.h"
#include "MainFrame.h"
#include "DefControlName.h"
#include "PersonalCenterDialog.h"
HWND g_hMainFrame = NULL;
CMainFrame::CMainFrame()
{
}
CMainFrame::~CMainFrame()
{
PostQuitMessage(0);
}
LPCTSTR CMainFrame::GetWindowClassName() const
{
return _T("App");
}
CDuiString CMainFrame::GetSkinFile()
{
return _T("MainFrame.xml");
}
CDuiString CMainFrame::GetSkinFolder()
{
return _T("skin\\");
}
//duilib自身消息
void CMainFrame::Notify(TNotifyUI& msg)
{
if (_tcsicmp(msg.sType, _T("windowinit")) == 0)
{
}
else if (_tcsicmp(msg.sType, _T("killfocus")) == 0)
{
}
else if (_tcsicmp(msg.sType, _T("click")) == 0)
{
if (_tcsicmp(msg.pSender->GetName(), kMainFrameBtnClose) == 0)
{
Close();
}
else if (_tcsicmp(msg.pSender->GetName(), kMainFrameBtnEnter) == 0)
{
OnBtnClickOfEnter(msg);
}
}
else if (_tcsicmp(msg.sType, _T("timer")) == 0)
{ }
else if (_tcsicmp(msg.sType, _T("selectchanged")) == 0)
{ }
else if (_tcsicmp(msg.sType, _T("itemactivate")) == 0)
{ }
else if (_tcsicmp(msg.sType, _T("itemclick")) == 0)
{ }
}
bool CMainFrame::OnBtnClickOfEnter(TNotifyUI & msg)
{
CPersonalCenterDialog* pDialog = new CPersonalCenterDialog();
if (pDialog == NULL)
return false;
DWORD dwStyle = UI_WNDSTYLE_FRAME;
dwStyle = dwStyle^WS_MAXIMIZEBOX;
#if defined(WIN32) && !defined(UNDER_CE)
pDialog->Create(NULL, _T("个人中心"), dwStyle | WS_POPUP, NULL, 0, 0, 0, 0);
#else
pDialog->Create(NULL, _T("个人中心"), dwStyle | WS_POPUP, NULL, 0, 0, 0, 0);
#endif
pDialog->CenterWindow();
::ShowWindow(g_hMainFrame, SW_HIDE);
::ShowWindow(*pDialog, SW_SHOW);
return true;
}
//处理自定义消息
LRESULT CMainFrame::HandleCustomMessage(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
switch (uMsg)
{
/*case WM_APPOBD_MSG_SHOW_MAIN_FRAME:
{
::ShowWindow(m_hWnd, SW_SHOW);
break;
}*/
default:
break;
}
return 0;
}
//处理事件消息
LRESULT CMainFrame::HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_DEVICECHANGE:
{
break;
}
//case WM_CLOSE:
// PostQuitMessage(0);
// break;
default:
break;
}
return WindowImplBase::HandleMessage(uMsg, wParam, lParam);
}
// stdafx.h : 标准系统包含文件的包含文件,
// 或是经常使用但不常更改的
// 特定于项目的包含文件
//
#pragma once
#include "targetver.h"
#define WIN32_LEAN_AND_MEAN // 从 Windows 头中排除极少使用的资料
// Windows 头文件:
#include
#include "..\DuiLib\UIlib.h"
using namespace DuiLib;
#ifdef _DEBUG
# ifdef _UNICODE
# pragma comment(lib, "..\\Lib\\DuiLib_ud.lib")
# else
# pragma comment(lib, "..\\Lib\\DuiLib_d.lib")
# endif
#else
# ifdef _UNICODE
# pragma comment(lib, "..\\Lib\\DuiLib_u.lib")
# else
# pragma comment(lib, "..\\Lib\\DuiLib.lib")
# endif
#endif
extern HWND g_hMainFrame;
// TODO: 在此处引用程序需要的其他头文件
#include "stdafx.h"
#include "MainFrame.h"
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE /*hPrevInstance*/, LPSTR /*lpCmdLine*/, int nCmdShow)
{
CPaintManagerUI::SetInstance(hInstance);
CWndShadow::Initialize(hInstance);
CMainFrame* pFrame = new CMainFrame();
if (pFrame == NULL)
return 0;
DWORD dwStyle = UI_WNDSTYLE_FRAME;
dwStyle = dwStyle^WS_MAXIMIZEBOX;
pFrame->Create(NULL, _T("云端软件"), dwStyle, WS_EX_STATICEDGE | WS_EX_APPWINDOW, 1, 1, 0, 0); //倒数第3第4个参数可以设置duilib左上角的坐标,倒数第1第2个参数因为继承了WindowImpBase,
//WindowImpBase类中在创建窗口大小时会取xml文件中的窗口大小数据,顾此处两个参数值无效。
pFrame->CenterWindow();
::ShowWindow(*pFrame, SW_SHOW);
CPaintManagerUI::MessageLoop(); //消息循环
::CoUninitialize();
return 0;
}