8、DuiLib创建子窗口

1、创建子窗口

一个大规模的应用不可能只有一个窗口,之前我们的案例都是在一个窗口实现的,接下来我们实现一个关于窗口,来介绍如何通过 DuiLib 实现子窗口管理。

2、创建子窗口 XML 配置文件

前面我们已经做了很多 XML 的案例了,所以这里就不多说了,直接将写好的 XML 贴上来给大家做一下简单分析,然后直接使用。

<?xml version="1.0" encoding="utf-8"?>
<Window size="480,360" caption="0,0,0,35">
  <Default name="Button" value="bordersize=&quot;3&quot; bordercolor=&quot;#FF222222&quot;" />
  <Font shared="true" id="1" name="微软雅黑" size="14" />
  <VerticalLayout>
    <!-- 标题栏 -->
    <HorizontalLayout height="35" bkcolor="#FFD6DBE9" inset="8,8,8,0">
      <HorizontalLayout width="185">
        <Control bkimage="logo.png" height="18" width="18" />
        <Label text="关于" height="18" padding="8" font="1"/>
      </HorizontalLayout>
      <Control />
      <HorizontalLayout width="32">
        <Button name="closebtn" height="32" width="32" normalimage="btn_close_normal.png" hotimage="btn_close_hovered.png" pushedimage="btn_close_pushed.png" />
      </HorizontalLayout>
    </HorizontalLayout>
    <HorizontalLayout bkcolor="#FFFFFFFF">
      <Label align="center" text="duilib tutorial, created by jiajia_deng" />
    </HorizontalLayout>
  </VerticalLayout>
</Window>

窗口还是保留标题栏,但只有一个关闭按钮了,并且关闭按钮的名字我修改成了btn_close ,目的就是不想让窗口走默认的关闭流程。窗口中只有一个 Label 显示了一串文字(毕竟这不是重点)。然后我们需要新建一个类,与 MainWndFrame 窗口一样,WindowImplBase 继承 实现各个虚函数。如下所示:
second_window.h:

#pragma once

class MulWndFrame :public WindowImplBase{
    
    
protected:
	virtual CDuiString GetSkinFolder()   override;                          //获取皮肤文件的目录,如果有多层目录这里可以设置,例如xml皮肤

	virtual CDuiString GetSkinFile()     override;                          //设置皮肤的名字     就是xml文件名字

	virtual LPCTSTR    GetWindowClassName(void) const override;             //设置当前窗口的名字  class name

	virtual DuiLib::UILIB_RESOURCETYPE GetResourceType() const override;    //返回资源类型

	virtual LPCTSTR    GetResourceID()   const override;                    //如果是ZIP资源,返回资源ID

	virtual void       InitWindow()      override;                          //窗口初始化函数

	virtual void       Notify(TNotifyUI& msg) override;                     //通知事件处理函数

public:
	static const LPCTSTR	kClassName;
	static const LPCTSTR	kMulWndFrame;

private:
	CButtonUI*				close_btn_ = nullptr;
};

second_window.cpp:

#include"stdafx.h"
#include"resource.h"
#include"second_window.h"

const LPCTSTR MulWndFrame::kClassName = _T("second_wnd_frame");
const LPCTSTR MulWndFrame::kMulWndFrame = _T("second_wnd_frame.xml");

CDuiString MulWndFrame::GetSkinFolder(){
    
    
#if _DEBUG
	return _T("theme");
#else
	return m_PaintManager.GetInstancePath();
#endif
}

CDuiString MulWndFrame::GetSkinFile(){
    
    
	return kMulWndFrame;
}

LPCTSTR MulWndFrame::GetWindowClassName(void) const {
    
    
	return kClassName;
}

DuiLib::UILIB_RESOURCETYPE MulWndFrame::GetResourceType() const {
    
    
#if _DEBUG
	return UILIB_FILE;
#else
	return UILIB_ZIPRESOURCE;
#endif
}

LPCTSTR MulWndFrame::GetResourceID() const{
    
    
	//return MAKEINTRESOURCE(IDR_ZIPRES1);
	return nullptr;
}

void MulWndFrame::InitWindow(){
    
    
	close_btn_ = dynamic_cast<CButtonUI*>(m_PaintManager.FindControl(_T("closebtn")));
}

//创建新窗口
void MulWndFrame::Notify(TNotifyUI& msg){
    
    
#if 0
	if (msg.sType == DUI_MSGTYPE_CLICK)
	{
    
    
		CDuiString strName = msg.pSender->GetName();
		if (strName == _T("btn_wnd_min"))
		{
    
    
			SendMessage(WM_SYSCOMMAND, SC_MINIMIZE, 0);
		}
	}
#endif
	if (msg.sType == DUI_MSGTYPE_CLICK){
    
    
		CDuiString str_name = msg.pSender->GetName();
		if (str_name == "closebtn"){
    
    
			HWND hWndParent = GetWindowOwner(m_hWnd);
			if (hWndParent)
			{
    
    
				::EnableWindow(hWndParent, TRUE);
				::SetFocus(hWndParent);
			}
			ShowWindow(false);
		}
	}
	//__super::Notify(msg);
}

随后在 main_wnd_frame.xml 中,增加一个多窗口按钮最小化按钮左边

<Button name="mulbtn" height="32" width="32" normalimage="btn_mul_wnd.png"  hotimage="btn_mul_wnd_hover.png" pushedimage="btn_mul_wnd_hover.png" />

此时主窗口就会显示一个关于按钮了,注意我们也修改了父容器的宽度,因为比之前多了一个按钮,我们要算上按钮宽度和间距增大父容器的宽度。
在这里插入图片描述

<?xml version="1.0" encoding="utf-8"?>
<Window size="640,480" mininfo="640,480" caption="0,0,0,35" sizebox="4,4,4,4">
  <Default name="Button" value="bordersize=&quot;5&quot; bordercolor=&quot;#FF222222&quot;" />
  <Font shared="true" id="0" name="幼圆" size="12" default="true" />
  <Font shared="true" id="1" name="微软雅黑" size="18" underline="true" bold="true"/>
  <VerticalLayout>

    <!--标题栏-->
    <HorizontalLayout height="50" bkcolor="#FFD6DBE9" inset="4,4,8,6" >
      <HorizontalLayout width="185">
        <Control bkimage="logo.png" height="32" width="32"   />
        <Label text="duilib tutorial" height="32"   padding="8,-2,4,0" font="1" />
      </HorizontalLayout>
      <Control />
      <HorizontalLayout childpadding="3" width="250">
        <Button name="btnHideLoginDialog" text="隐藏登录框" tooltip="隐藏登录框"  width="100" height="100" textcolor="#00ffda8a"  normalimage="btn_min_hovered.png" hotimage="btn_min_hovered.png" />
        <Button name="mulbtn" height="32" width="32" normalimage="btn_mul_wnd.png"  hotimage="btn_mul_wnd_hover.png" pushedimage="btn_mul_wnd_hover.png" />
        <Button name="minbtn" height="32" width="32" normalimage="btn_min_normal.png" hotimage="btn_min_hovered.png" pushedimage="btn_min_pushed.png" />
        <Button name="maxbtn" height="32" width="32" normalimage="btn_max_normal.png" hotimage="btn_max_hovered.png" pushedimage="btn_max_pushed.png" />
        <Button name="restorebtn" visible="false" height="32" width="32" normalimage="btn_reset_normal.png" hotimage="btn_reset_hovered.png" pushedimage="btn_reset_pushed.png" />
        <Button name="closebtn" height="32" width="32" normalimage="btn_close_normal.png" hotimage="btn_close_hovered.png" pushedimage="btn_close_pushed.png" />
      </HorizontalLayout>
    </HorizontalLayout>

    <!--窗口内容区域-->
    <HorizontalLayout bkcolor="#FF4D6082">
      <List name="main_wnd_list" header="hidden" padding="10,10,10,10" />
    </HorizontalLayout>
  </VerticalLayout>
</Window>

接下来做关于按钮的响应,首先添加一个按钮的成员变量来接收关于按钮,然后再 inlucde 关于窗口的头文件 second_window.h,并添加一个窗口的成员变量 MulWndFrame。重载 OnClick 方法判断当前点击的是否是关于按钮,如果是那么就显示关于窗口。代码如下:

void MainFrameWnd::OnClick(TNotifyUI& msg){
    
    
	CDuiString str_name = msg.pSender->GetName();
	if (str_name == _T("minbtn")){
    
    
		SendMessage(WM_SYSCOMMAND, SC_MINIMIZE, 0);
		return;
	}
	else if (str_name == _T("maxbtn")){
    
    
		SendMessage(WM_SYSCOMMAND, SC_MAXIMIZE, 0);
		return;
	}
	else if (str_name == _T("restorebtn")){
    
    
		SendMessage(WM_SYSCOMMAND, SC_RESTORE, 0);
		return;
	}
	else if (str_name == _T("closebtn")){
    
    
		Close();
		return;
	}
	else if (str_name == _T("mulbtn")){
    
    
		if (mul_wnd_frame_ == nullptr){
    
    
			mul_wnd_frame_ = new MulWndFrame;
			mul_wnd_frame_->Create(this->GetHWND(), MulWndFrame::kClassName, UI_WNDSTYLE_FRAME, 0);
		}
		mul_wnd_frame_->CenterWindow(); 
		mul_wnd_frame_->ShowWindow();
	}
	__super::OnClick(msg);
	return;
}

这里有个小技巧就是判断窗口是不是 nullptr,如果是 nullptr 就全新 new 一个 MulWndFrame,如果是有效的指针则直接显示窗口。在 MulWndFrame中在关闭窗口时,只需要激活父窗口然后把自己隐藏掉就可以了。如下所示:

//创建新窗口
void MulWndFrame::Notify(TNotifyUI& msg){
    
    
#if 0
	if (msg.sType == DUI_MSGTYPE_CLICK)
	{
    
    
		CDuiString strName = msg.pSender->GetName();
		if (strName == _T("btn_wnd_min"))
		{
    
    
			SendMessage(WM_SYSCOMMAND, SC_MINIMIZE, 0);
		}
	}
#endif
	if (msg.sType == DUI_MSGTYPE_CLICK){
    
    
		CDuiString str_name = msg.pSender->GetName();
		if (str_name == "closebtn"){
    
    
			HWND hWndParent = GetWindowOwner(m_hWnd);
			if (hWndParent)
			{
    
    
				::EnableWindow(hWndParent, TRUE);
				::SetFocus(hWndParent);
			}
			ShowWindow(false);
		}
	}
	//__super::Notify(msg);
}

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_44918090/article/details/131310398
今日推荐