代码仓库:https://github.com/yangpan4485/duilib/tree/develop/MyDemo
一、使用xml基础类
1、duilib对常用的基础类使用了包装,我们可以直接使用WindowImplBase进行操作,这样可以减少我们的代码操作
2、WindowImplBase是以xml作为界面描述的,所有使用WindowImplBase基础类的时候也要使用到xml文件
3、xml文件不改变,只改变我们的main.cpp文件,内容如下
#include <Windows.h>
#include <iostream>
#include "UIlib.h"
class CDuiFrameWnd : public DuiLib::WindowImplBase
{
public:
virtual LPCTSTR GetWindowClassName() const {
return _T("DUIMainFrame");
}
virtual DuiLib::CDuiString GetSkinFile() {
return _T("MyDemo.xml");
}
virtual DuiLib::CDuiString GetSkinFolder() {
return _T("resources");
}
virtual void Notify(DuiLib::TNotifyUI& msg) {
if (msg.sType == _T("click"))
{
if (msg.pSender->GetName() == _T("btnWnd"))
{
std::cout << "btn click" << std::endl;
}
}
}
};
int main(void) {
HINSTANCE hInstance = GetModuleHandle(0);
DuiLib::CPaintManagerUI::SetInstance(hInstance);
CDuiFrameWnd duiFrame;
duiFrame.Create(NULL, _T("DUIWnd"), UI_WNDSTYLE_FRAME, WS_EX_WINDOWEDGE);
duiFrame.ShowModal();
}
4、运行结果
通过运行结果可以发现我们的标题栏没了,这个时候就需要我们去自绘标题栏了,当然你想要自带的标题栏,那么就可以不用使用dui基础类
二、自绘标题栏
1、接下来修改我们的xml文件
<?xml version="1.0" encoding="UTF-8"?>
<Window size="960,540" mininfo="600,400" caption="0,0,0,32" sizebox="4,4,4,4"> <!-- 窗口的初始尺寸(宽800,高600)、窗口的最小尺寸(宽600,高400)、标题栏拖拽区域(高32)、可拖拽边框大小(这里添加sizebox后就可以拖拽边框调整大小了) -->
<VerticalLayout bkcolor="#FFF0F0F0" bkcolor2="#FFAAAAA0"> <!-- 整个窗口的背景色 -->
<!-- 标题栏区 -->
<HorizontalLayout height="32" bkcolor="#FFE6E6DC" bkcolor2="#FFAAAAA0"> <!-- 标题栏背景色 ->
<VerticalLayout /> <!-- 占空位,占据左边所有的空位-->
<VerticalLayout width="77"> <!-- 右边三个控件所占的宽度-->
<Button name="minbtn" tooltip="最小化" float="true" pos="0,5,22,24" width="23" normalimage=" file='sysbtn/btn_mini_normal.png' " hotimage=" file='sysbtn/btn_mini_highlight.png' " pushedimage=" file='sysbtn/btn_mini_down.png' "/>
<Button name="maxbtn" tooltip="最大化" float="true" pos="22,5,44,24" width="23" normalimage=" file='sysbtn/btn_max_normal.png' " hotimage=" file='sysbtn/btn_max_highlight.png' " pushedimage=" file='sysbtn/btn_max_down.png' " />
<Button name="restorebtn" visible="false" tooltip="还原" float="true" pos="22,5,44,24" width="23" normalimage=" file='sysbtn/btn_restore_normal.png' " hotimage=" file='sysbtn/btn_restore_highlight.png' " pushedimage=" file='sysbtn/btn_restore_down.png' " />
<Button name="closebtn" tooltip="关闭" float="true" pos="44,5,74,24" width="28" normalimage=" file='sysbtn/btn_close_normal.png' " hotimage=" file='sysbtn/btn_close_highlight.png' " pushedimage=" file='sysbtn/btn_close_down.png' "/>
</VerticalLayout>
</HorizontalLayout>
<!-- 客户区 -->
<HorizontalLayout>
<Button name="btnHello" text="Hello World"/>
</HorizontalLayout>
</VerticalLayout>
</Window>
其中
name:表示 Button 的名字
tooltip:表示当把鼠标移动到上面显示的文字
float:true 表示使用绝对布局
pos:位置
normalimage:原始图片
hotimage:当把鼠标移动上去显示的图片
pushedimage:当鼠标按下显示的图片
其中标题栏的几个 Button 名字是固定的,我们不可以做修改
2、运行结果
感觉还是原始的最大化最小化按钮好看,自定义的按钮不好看
3、我们可以看到在这里已经有我们的自定义标题栏了,但是点击没有效果,需要我们在代码中再做一些处理,具体代码如下
#include <Windows.h>
#include <iostream>
#include "UIlib.h"
using DuiLib::CButtonUI;
using DuiLib::CControlUI;
class CDuiFrameWnd : public DuiLib::WindowImplBase
{
public:
virtual LPCTSTR GetWindowClassName() const override {
return _T("DUIMainFrame");
}
virtual DuiLib::CDuiString GetSkinFile() override {
return _T("MyDemo.xml");
}
virtual DuiLib::CDuiString GetSkinFolder() override {
return _T("resources");
}
virtual void Notify(DuiLib::TNotifyUI& msg) override {
return WindowImplBase::Notify(msg);
}
void InitWindow() override {
m_pCloseBtn = static_cast<CButtonUI*>(m_PaintManager.FindControl(_T("closebtn")));
m_pMaxBtn = static_cast<CButtonUI*>(m_PaintManager.FindControl(_T("maxbtn")));
m_pRestoreBtn = static_cast<CButtonUI*>(m_PaintManager.FindControl(_T("restorebtn")));
m_pMinBtn = static_cast<CButtonUI*>(m_PaintManager.FindControl(_T("minbtn")));
m_pHelloBtn = static_cast<CButtonUI*>(m_PaintManager.FindControl(_T("btnHello")));
}
void OnClick(DuiLib::TNotifyUI &msg) override {
if (msg.pSender == m_pCloseBtn) {
PostQuitMessage(0);
return;
}
else if (msg.pSender == m_pMinBtn) {
SendMessage(WM_SYSCOMMAND, SC_MINIMIZE, 0); return;
}
else if (msg.pSender == m_pMaxBtn) {
SendMessage(WM_SYSCOMMAND, SC_MAXIMIZE, 0); return;
}
else if (msg.pSender == m_pRestoreBtn) {
SendMessage(WM_SYSCOMMAND, SC_RESTORE, 0); return;
}
else if (msg.pSender == m_pHelloBtn) {
std::cout << "btn click" << std::endl;
}
}
LRESULT OnSysCommand(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) override {
// 有时会在收到WM_NCDESTROY后收到wParam为SC_CLOSE的WM_SYSCOMMAND
if (wParam == SC_CLOSE) {
::PostQuitMessage(0L);
bHandled = TRUE;
return 0;
}
// 是不是最大化
BOOL bZoomed = ::IsZoomed(*this);
LRESULT lRes = CWindowWnd::HandleMessage(uMsg, wParam, lParam);
// 进行图片的切换
if (::IsZoomed(*this) != bZoomed) {
if (!bZoomed) {
CControlUI* pControl = static_cast<CControlUI*>(m_PaintManager.FindControl(_T("maxbtn")));
if (pControl) pControl->SetVisible(false);
pControl = static_cast<CControlUI*>(m_PaintManager.FindControl(_T("restorebtn")));
if (pControl) pControl->SetVisible(true);
}
else {
CControlUI* pControl = static_cast<CControlUI*>(m_PaintManager.FindControl(_T("maxbtn")));
if (pControl) pControl->SetVisible(true);
pControl = static_cast<CControlUI*>(m_PaintManager.FindControl(_T("restorebtn")));
if (pControl) pControl->SetVisible(false);
}
}
return lRes;
}
private:
CButtonUI* m_pCloseBtn;
CButtonUI* m_pMaxBtn;
CButtonUI* m_pRestoreBtn;
CButtonUI* m_pMinBtn;
CButtonUI* m_pHelloBtn;
};
int main(void) {
HINSTANCE hInstance = GetModuleHandle(0);
DuiLib::CPaintManagerUI::SetInstance(hInstance);
CDuiFrameWnd duiFrame;
duiFrame.Create(NULL, _T("DUIWnd"), UI_WNDSTYLE_FRAME, WS_EX_WINDOWEDGE);
duiFrame.ShowModal();
return 0;
}