代码仓库: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、运行结果

duilib开发(四):使用xml基础类、并自绘标题栏_标题栏

通过运行结果可以发现我们的标题栏没了,这个时候就需要我们去自绘标题栏了,当然你想要自带的标题栏,那么就可以不用使用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、运行结果

duilib开发(四):使用xml基础类、并自绘标题栏_标题栏_02

感觉还是原始的最大化最小化按钮好看,自定义的按钮不好看 

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;
}