8、DuiLib创建子窗口

news/2024/6/16 19:43:14

文章目录

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

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

在这里插入图片描述


http://www.niftyadmin.cn/n/453667.html

相关文章

API 天气预报查询等各种免费好用的 API 推荐

常用API 天气预报查询&#xff1a;支持全国以及全球多个城市的天气查询&#xff0c;包含国内3400个城市以及国际4万个城市的实况数据&#xff0c;同时也支持国内任意经纬度查询&#xff0c;接口会返回该经纬度最近的站点信息&#xff1b;更新频率分钟级别。 空气质量查询&…

2.3 vim常用快捷操作

一、命令行模式 h 或 向左箭头键(←)光标向左移动一个字符j 或 向下箭头键(↓)光标向下移动一个字符k 或 向上箭头键(↑)光标向上移动一个字符l 或 向右箭头键(→)光标向右移动一个字符n(h或j或k或l)&#xff0c;n代表整数nj/nk光标向上/下移动n行 nh/nl光标向左/右移动n个字…

提示工程 - 150个ChatGPT角色扮演指令,全网的角色扮演指令都在这里!让你的ChatGPT成为任何领域的专家(2/15)

150个ChatGPT角色扮演指令&#xff0c;全网的角色扮演指令都在这里&#xff01;让你的ChatGPT成为任何领域的专家&#xff08;2/15&#xff09; 专注人工智能领域的生活化应用&#xff0c;致力于使人工智能的简单化并普及普通人&#xff0c;公众号内置大量有关AIGC的资料&…

MySQL出现Specified key was too long; max key length is 3072 bytes解决方案

大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。现为CSDN博客专家、人工智能领域优质创作者。喜欢通过博客创作的方式对所学的…

AutoSAR系列讲解 - AutoSAR标准文档概览

目录 一、文档下载 二、文档结构 三、文档内容 四、各部分介绍 1、Introduction and functional o 目录 一、文档下载 二、文档结构 三、文档内容 四、各部分介绍 1、Introduction and functional overview 2、Acronyms and abbreviations 3、Related documentati…

TBOX的技术点

一、TBOX是什么 T-BOX是车联网系统中的一个重要组成部分&#xff0c;它是一个智能终端设备&#xff0c;通过连接车载CAN总线和外部云平台&#xff0c;实现车辆与车辆&#xff08;V2V&#xff09;、车辆与基础设施&#xff08;V2I&#xff09;、车辆与互联网&#xff08;V2N&…

Qt颜色、文件、字体对话框

项目目录 界面 一、颜色对话框 QColor color QColorDialog::getColor(QColor(255,0,0));qDebug()<<"r"<<color.red()<<" g "<<color.green()<<" b "<<color.blue(); 二、文件对话框 //文件对话框QString…

检测 ARP 欺骗

地址解析协议 &#xff08;ARP&#xff09; 是网络通信的基本推动因素。作为网络互联网层和网络链路层之间的桥梁&#xff0c;此网络协议将网络地址 &#xff08;IP&#xff09; 转换为物理层地址&#xff08;MAC 地址&#xff09;。ARP协议支持的地址转换在促进同一LAN中不同网…