6、DuiLib控件消息响应处理

news2024/12/23 3:35:26

文章目录

  • 1、DuiLib控件消息响应处理
  • 2、基本的消息响应处理 Notify
  • 3、仿 MFC 形式消息响应 DUI_DECLARE_MESSAGE_MAP
  • 4、事件委托 MakeDelegate
  • 5、消息捕获(拦截)原生消息 HandleMessage

1、DuiLib控件消息响应处理

<?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="100">
        <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="#FFD81E06">
      
    </HorizontalLayout>
  </VerticalLayout>
</Window>

上一篇我们介绍了如何通过命名的 XML 控件转化为实际可操控的对象,实际上我们已经可以调用这些控件的一些方法来操作控件了,比如:

void MainWndFrame::InitWindow(){
	btn_min_ = dynamic_cast<CButtonUI*>(m_PaintManager.FindControl(_T("btn_wnd_min")));
	btn_max_ = dynamic_cast<CButtonUI*>(m_PaintManager.FindControl(_T("btn_wnd_max")));
	btn_close_ = dynamic_cast<CButtonUI*>(m_PaintManager.FindControl(_T("btn_wnd_close")));
	btn_min_->SetVisible(false);
}

我们调用了 CButtonUISetVisible 方法,将最小化控件隐藏了。但实际这并没有什么作用,我们真正需要的是点击某个控件后执行某些操作。
在这里插入图片描述

2、基本的消息响应处理 Notify

接下来我们希望实现更实用的功能,点击最小化按钮把窗口最小化、点击关闭按钮把窗口关闭等。这就要涉及到对控件消息的处理,同样父类 WindowImplBase 提供了 Notify 虚函数,可以提供我们覆写并处理消息。一下代码实现了点击最小化按钮将窗口最小化的功能。

// new_test_demo.cpp : 定义应用程序的入口点。
//

#include "stdafx.h"
#include "new_test_demo.h"
#include<iostream>
#include"UIlib.h"
using namespace DuiLib;

//duilib_tutorial.cpp: 定义应用程序的入口点。
//
//WindowImplBase窗口基类

class MainWndFrame : public WindowImplBase
{
public:
	MainWndFrame();
protected:
	virtual CDuiString GetSkinFolder() override;							// 获取皮肤文件的目录,如果有多层目录这里可以设置
	virtual CDuiString GetSkinFile() override;								// 设置皮肤文件名字
	virtual LPCTSTR GetWindowClassName(void) const override;				// 设置当前窗口的 class name

	virtual void InitWindow() override;										//窗口初始化函数
	virtual void Notify(TNotifyUI& msg) override;							//通知事件处理函数

	//virtual DuiLib::UILIB_RESOURCETYPE GetResourceType() const override;
	//virtual LPCTSTR GetResourceID() const override;

public:
	static const LPCTSTR kClassName;
	static const LPCTSTR kMainWndFrame;

private:
	CButtonUI* btn_min_;
	CButtonUI* btn_max_;
	CButtonUI* btn_reset_;
	CButtonUI* btn_close_;
};

MainWndFrame::MainWndFrame(){
	btn_min_ = nullptr;
	btn_max_ = nullptr;
	btn_reset_ = nullptr;
	btn_close_ = nullptr;
}

DuiLib::CDuiString MainWndFrame::GetSkinFolder()
{
	// GetInstancePath 接口返回默认的皮肤文件位置
	// 在 main 函数中我们可以通过 SetResourcePath 来设置路径
	return m_PaintManager.GetInstancePath();
}

DuiLib::CDuiString MainWndFrame::GetSkinFile()
{
	// 成员变量定义的皮肤文件名
	return kMainWndFrame;
}

LPCTSTR MainWndFrame::GetWindowClassName(void) const
{
	// 成员变量定义的窗口 class name
	return kClassName;
}

void MainWndFrame::InitWindow(){
	btn_min_ = dynamic_cast<CButtonUI*>(m_PaintManager.FindControl(_T("minbtn")));
	btn_max_ = dynamic_cast<CButtonUI*>(m_PaintManager.FindControl(_T("maxbtn")));
	btn_reset_ = dynamic_cast<CButtonUI*>(m_PaintManager.FindControl(_T("restorebtn")));
	btn_close_ = dynamic_cast<CButtonUI*>(m_PaintManager.FindControl(_T("closebtn")));
	//btn_min_->SetVisible(false);
}

void MainWndFrame::Notify(TNotifyUI& msg){
	if (msg.sType == DUI_MSGTYPE_CLICK){
		CDuiString str_name = msg.pSender->GetName();
		if (str_name == _T("mintbn")){
			SendMessage(WM_SYSCOMMAND, SC_MINIMIZE, 0);
		}
		else if (str_name == _T("maxbtn")){
			SendMessage(WM_SYSCOMMAND, SC_MAXIMIZE, 0);
		}
		else if (str_name==_T("restorebtn")){
			SendMessage(WM_SYSCOMMAND, SC_RESTORE, 0);
		}
		else if (str_name == _T("closebtn")){
			SendMessage(WM_SYSCOMMAND, SC_CLOSE, 0);
		}
	}
	__super::Notify(msg);
}

//theme压缩包资源
//DuiLib::UILIB_RESOURCETYPE MainWndFrame::GetResourceType() const
//{
//	return UILIB_ZIPRESOURCE;
//}
//
//LPCTSTR MainWndFrame::GetResourceID() const
//{
//	return MAKEINTRESOURCE(IDR_ZIPRES1);
//}

//生成的窗口名字
const LPCTSTR MainWndFrame::kClassName = _T("main_wnd_frame");
//theme文件下的xml文件
const LPCTSTR MainWndFrame::kMainWndFrame = _T("main_wnd_frame.xml");

int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
	_In_opt_ HINSTANCE hPrevInstance,
	_In_ LPWSTR    lpCmdLine,
	_In_ int       nCmdShow)
{
	//UNREFERENCED_PARAMETER(hPrevInstance);
	//UNREFERENCED_PARAMETER(lpCmdLine);

	// 设置窗口关联的实例
	CPaintManagerUI::SetInstance(hInstance);

	// 设置皮肤的默认路径
	CPaintManagerUI::SetCurrentPath(CPaintManagerUI::GetInstancePath());

	//theme文件夹
	CPaintManagerUI::SetResourcePath(_T("theme"));

	//theme压缩包
	//CPaintManagerUI::SetResourcePath(CPaintManagerUI::GetInstancePath());
	//CPaintManagerUI::SetResourceZip(_T("theme.zip"));

	// 创建窗口
	MainWndFrame* pMainWndFrame = new MainWndFrame();
	if (nullptr == pMainWndFrame){
		return 0;
	}
	pMainWndFrame->Create(nullptr, MainWndFrame::kClassName, UI_WNDSTYLE_DIALOG, 0);
	pMainWndFrame->CenterWindow();
	pMainWndFrame->ShowWindow();
	CPaintManagerUI::MessageLoop();

	if (nullptr != pMainWndFrame)
	{
		delete pMainWndFrame;
	}

	return 0;
}

首先我们在 Notify 函数中判断了一下消息的类型,如果是鼠标点击那么我们获取一下触发的控件名称,根据名称判断是不是 btn_wnd_min 然后执行指定操作。最后别忘记调用父类的 Notify 函数来继续其他消息的处理(其实父类什么都没做)。

然后这里我在加上放大和关闭按钮:

void MainWndFrame::Notify(TNotifyUI& msg){
	if (msg.sType == DUI_MSGTYPE_CLICK){
		CDuiString str_name = msg.pSender->GetName();
		if (str_name == _T("minbtn")){
			SendMessage(WM_SYSCOMMAND, SC_MINIMIZE, 0);
		}
		else if (str_name == _T("maxbtn")){
			SendMessage(WM_SYSCOMMAND, SC_MAXIMIZE, 0);
		}
		else if (str_name==_T("restorebtn")){
			SendMessage(WM_SYSCOMMAND, SC_RESTORE, 0);
		}
		else if (str_name == _T("closebtn")){
			SendMessage(WM_SYSCOMMAND, SC_CLOSE, 0);
		}
	}
	__super::Notify(msg);
}

在这里插入图片描述

3、仿 MFC 形式消息响应 DUI_DECLARE_MESSAGE_MAP

以上是一个基本的响应过程。另外还有一种类似 MFC 方式的响应方法,首先在 new_test_demo.h 中添加一句 DUI_DECLARE_MESSAGE_MAP()

在这里插入图片描述

void MainWndFrame::OnClick(TNotifyUI& msg){
	CDuiString str_name = msg.pSender->GetName();
	if (str_name == _T("mintbn")){
		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;
	}
	return;
}

然后在 new_test_demo.h 中添加如下代码:

DUI_BEGIN_MESSAGE_MAP(MainWndFrame, CNotifyPump)
	DUI_ON_MSGTYPE(DUI_MSGTYPE_CLICK, OnClick)
DUI_END_MESSAGE_MAP()

这样我们就将 DUI_MSGTYPE_CLICK 类型的消息映射到了 OnClick 函数中,而 OnClick 函数在父类 WindowImplBase 中已经提供了一个虚函数了。

void WindowImplBase::OnClick(TNotifyUI& msg)
{
	CDuiString sCtrlName = msg.pSender->GetName();
	if( sCtrlName == _T("closebtn") )
	{
		Close();
		return; 
	}
	else if( sCtrlName == _T("minbtn"))
	{ 
		SendMessage(WM_SYSCOMMAND, SC_MINIMIZE, 0); 
		return; 
	}
	else if( sCtrlName == _T("maxbtn"))
	{ 
		SendMessage(WM_SYSCOMMAND, SC_MAXIMIZE, 0); 
		return; 
	}
	else if( sCtrlName == _T("restorebtn"))
	{ 
		SendMessage(WM_SYSCOMMAND, SC_RESTORE, 0); 
		return; 
	}
	return;
}

可以看出,DuiLib 已经默认帮我们实现了几个按钮的鼠标点击功能。我们只需要根据它设定的名字修改一下我们控件的 name 属性就可以实现几个功能了。当然如果我们要添加其他控件的处理,是需要覆写这个 OnClick 函数的。
在这里插入图片描述
修改完成后最小化、最大化、还原三个按钮都可以正常工作了,但是关闭按钮点击后并不能完全退出程序,而仅仅是把程序隐藏了,这主要原因是当我们点击关闭按钮时调用的是父类的 Close 函数,该函数发送了退出消息后,窗口接收到该消息的处理函数 OnClose 未做任何措施,如下所示:
在这里插入图片描述
父类中的**WindowImplBase::OnClose()**任务管理器中的进程并没有结束掉:
在这里插入图片描述

要解决这个问题很简单,我们只需要覆写一下这个 OnClose 方法,然后执行退出操作就可以了。

LRESULT MainWndFrame::OnClose(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
	if (uMsg == WM_CLOSE)
	{
		PostQuitMessage(0L);
	}

	return __super::OnClose(uMsg, wParam, lParam, bHandled);
}

在这里插入图片描述
覆写完成后,我们三个功能按钮(哦不,是四个)就都可以正常使用了。另外我自己还发现了两个小问题,窗口的标题栏双击是无法最大化的,这个解决很简单,在 main 函数创建窗口的时候,将窗口的 UI_WNDSTYLE_DIALOG 属性修改为 UI_WNDSTYLE_FRAME 就可以了,至于两个参数什么意思,我有一篇DuiLib文章介绍了,有兴趣可以去查看。
在这里插入图片描述

pMainWndFrame->Create(nullptr, MainWndFrame::kClassName, UI_WNDSTYLE_FRAME, 0);

在这里插入图片描述
另外一个问题是窗口是无法拖动放大缩小的,这个也很好解决,我们修改 XML,添加上窗口最小大小和可拖动范围就可以了。如下所示:

<?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="100">
        <Button name="btn_wnd_min" height="32" width="32" normalimage="btn_min_normal.png" hotimage="btn_min_hovered.png" pushedimage="btn_min_pushed.png" />
        <Button name="btn_wnd_max" height="32" width="32" normalimage="btn_max_normal.png" hotimage="btn_max_hovered.png" pushedimage="btn_max_pushed.png" />
        <Button name="btn_wnd_reset" height="32" width="32" normalimage="btn_reset_normal.png" hotimage="btn_reset_hovered.png" pushedimage="btn_reset_pushed.png"  visible="false"/>
        <Button name="btn_wnd_close" height="32" width="32" normalimage="btn_close_normal.png" hotimage="btn_close_hovered.png" pushedimage="btn_close_pushed.png" />
      </HorizontalLayout>
    </HorizontalLayout>
    <!--窗口内容区域-->
    <HorizontalLayout bkcolor="#FFD81E06">
      
    </HorizontalLayout>
  </VerticalLayout>
</Window>

在这里插入图片描述
mininfo 属性决定了窗口最小大小,sizebox 属性是指定当鼠标移动到窗口边缘多少像素的时候显示拖放手势。这里指定的是 4 像素,这样指定后窗口就可以拖动了,而且最小不允许小于默认的 640x480

4、事件委托 MakeDelegate

除了以上两种方式外,我们还可以通过事件委托的方式来处理指定控件的消息。如下示例演示了事件委托的实现方式。

void MainWndFrame::InitWindow()
{
	m_pMinBtn = dynamic_cast<CButtonUI*>(m_PaintManager.FindControl(_T("minbtn")));
	m_pMaxBtn = dynamic_cast<CButtonUI*>(m_PaintManager.FindControl(_T("maxbtn")));
	m_pRestoreBtn = dynamic_cast<CButtonUI*>(m_PaintManager.FindControl(_T("restorebtn")));
	m_pCloseBtn = dynamic_cast<CButtonUI*>(m_PaintManager.FindControl(_T("closebtn")));

	m_pMinBtn->OnNotify += MakeDelegate(this, &MainWndFrame::OnBtnTest);
}

在 InitWindow 函数中,我们给最小化按钮委托了一个 OnBtnTest 的处理函数,当我们对最小化按钮做某些操作时,就会到达 OnBtnTest 处理函数中。OnBtnTest 的实现如下:

bool MainWndFrame::OnBtnTest(void* param)
{
	TNotifyUI* msg = reinterpret_cast<TNotifyUI*>(param);
	if (msg->sType == DUI_MSGTYPE_CLICK)
	{
		// ... do something
	}

	return true;
}

这种方式同样可以实现处理控件的消息功能,如果对委托的函数指针加以改造,还可以使用 C++11 的 lambda 表达式来实现具体的处理函数功能。

5、消息捕获(拦截)原生消息 HandleMessage

DuiLib 提供了虚函数 HandleMessage,可以提供我们覆写来捕获或者拦截原声的系统消息。比如我们希望监听剪切板的消息时,就可以像一下方法一样来实现

virtual LRESULT HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam);

在这里插入图片描述

在这里插入图片描述

LRESULT MainWndFrame::HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam){
	if (uMsg == WM_CHANGECBCHAIN){
		//
	}
	else if (uMsg = WM_DRAWCLIPBOARD){
		//
	}
	return __super::HandleMessage(uMsg, wParam, lParam);
}

老版本的 DuiLib 中窗口创建完成后,按下 ESC 窗口会被关闭,如果想屏蔽掉 ESC 按下的消息,就可以通过这个函数来实现。

// new_test_demo.cpp : 定义应用程序的入口点。
//

#include "stdafx.h"
#include "new_test_demo.h"
#include<iostream>
#include"UIlib.h"
using namespace DuiLib;

//duilib_tutorial.cpp: 定义应用程序的入口点。
//
//WindowImplBase窗口基类

class MainWndFrame : public WindowImplBase
{
public:
	MainWndFrame();
protected:
	virtual CDuiString GetSkinFolder() override;							// 获取皮肤文件的目录,如果有多层目录这里可以设置
	virtual CDuiString GetSkinFile() override;								// 设置皮肤文件名字
	virtual LPCTSTR GetWindowClassName(void) const override;				// 设置当前窗口的 class name

	virtual void InitWindow() override;                                     //窗口初始化函数
	//virtual void Notify(TNotifyUI& msg) override;							//通知事件处理函数

	virtual void OnClick(TNotifyUI& msg) override;            
	virtual LRESULT OnClose(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) override;

	virtual LRESULT HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam);

	DUI_DECLARE_MESSAGE_MAP()

	//virtual DuiLib::UILIB_RESOURCETYPE GetResourceType() const override;
	//virtual LPCTSTR GetResourceID() const override;

public:
	static const LPCTSTR kClassName;
	static const LPCTSTR kMainWndFrame;

private:
	CButtonUI* btn_min_;
	CButtonUI* btn_max_;
	CButtonUI* btn_reset_;
	CButtonUI* btn_close_;
};

MainWndFrame::MainWndFrame(){
	btn_min_ = nullptr;
	btn_max_ = nullptr;
	btn_reset_ = nullptr;
	btn_close_ = nullptr;
}

DUI_BEGIN_MESSAGE_MAP(MainWndFrame, CNotifyPump)
DUI_ON_MSGTYPE(DUI_MSGTYPE_CLICK, OnClick)
DUI_END_MESSAGE_MAP()

DuiLib::CDuiString MainWndFrame::GetSkinFolder()
{
	// GetInstancePath 接口返回默认的皮肤文件位置
	// 在 main 函数中我们可以通过 SetResourcePath 来设置路径
	return m_PaintManager.GetInstancePath();
}

DuiLib::CDuiString MainWndFrame::GetSkinFile()
{
	// 成员变量定义的皮肤文件名
	return kMainWndFrame;
}

LPCTSTR MainWndFrame::GetWindowClassName(void) const
{
	// 成员变量定义的窗口 class name
	return kClassName;
}

void MainWndFrame::InitWindow(){
	btn_min_ = dynamic_cast<CButtonUI*>(m_PaintManager.FindControl(_T("mintbn")));
	btn_max_ = dynamic_cast<CButtonUI*>(m_PaintManager.FindControl(_T("maxbtn")));
	btn_reset_ = dynamic_cast<CButtonUI*>(m_PaintManager.FindControl(_T("restorebtn")));
	btn_close_ = dynamic_cast<CButtonUI*>(m_PaintManager.FindControl(_T("closebtn")));
	//btn_min_->SetVisible(false);
}

//void MainWndFrame::Notify(TNotifyUI& msg){
//	if (msg.sType == DUI_MSGTYPE_CLICK){
//		CDuiString str_name = msg.pSender->GetName();
//		if (str_name == _T("btn_wnd_min")){
//			SendMessage(WM_SYSCOMMAND, SC_MINIMIZE, 0);
//		}
//		else if (str_name == _T("btn_wnd_max")){
//			SendMessage(WM_SYSCOMMAND, SC_MAXIMIZE, 0);
//		}
//		else if (str_name==_T("btn_wnd_reset")){
//			SendMessage(WM_SYSCOMMAND, SC_RESTORE, 0);
//		}
//		else if (str_name == _T("btn_wnd_close")){
//			SendMessage(WM_SYSCOMMAND, SC_CLOSE, 0);
//		}
//	}
//	__super::Notify(msg);
//}

void MainWndFrame::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;
	}
	return;
}

LRESULT  MainWndFrame::OnClose(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) {
	if (uMsg == WM_CLOSE){
		PostQuitMessage(0L);
	}
	return __super::OnClose(uMsg, wParam, lParam, bHandled);
}

LRESULT MainWndFrame::HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam){
	if (uMsg == WM_CHANGECBCHAIN){
		//
	}
	else if (uMsg = WM_DRAWCLIPBOARD){
		//
	}
	return __super::HandleMessage(uMsg, wParam, lParam);
}

//theme压缩包资源
//DuiLib::UILIB_RESOURCETYPE MainWndFrame::GetResourceType() const
//{
//	return UILIB_ZIPRESOURCE;
//}
//
//LPCTSTR MainWndFrame::GetResourceID() const
//{
//	return MAKEINTRESOURCE(IDR_ZIPRES1);
//}

//生成的窗口名字
const LPCTSTR MainWndFrame::kClassName = _T("main_wnd_frame");
//theme文件下的xml文件
const LPCTSTR MainWndFrame::kMainWndFrame = _T("main_wnd_frame.xml");

int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
	_In_opt_ HINSTANCE hPrevInstance,
	_In_ LPWSTR    lpCmdLine,
	_In_ int       nCmdShow)
{
	//UNREFERENCED_PARAMETER(hPrevInstance);
	//UNREFERENCED_PARAMETER(lpCmdLine);

	// 设置窗口关联的实例
	CPaintManagerUI::SetInstance(hInstance);

	// 设置皮肤的默认路径
	CPaintManagerUI::SetCurrentPath(CPaintManagerUI::GetInstancePath());

	//theme文件夹
	CPaintManagerUI::SetResourcePath(_T("theme"));

	//theme压缩包
	//CPaintManagerUI::SetResourcePath(CPaintManagerUI::GetInstancePath());
	//CPaintManagerUI::SetResourceZip(_T("theme.zip"));

	// 创建窗口
	MainWndFrame* pMainWndFrame = new MainWndFrame();
	if (nullptr == pMainWndFrame){
		return 0;
	}
	pMainWndFrame->Create(nullptr, MainWndFrame::kClassName, UI_WNDSTYLE_FRAME, 0);
	pMainWndFrame->CenterWindow();
	pMainWndFrame->ShowWindow();
	CPaintManagerUI::MessageLoop();

	if (nullptr != pMainWndFrame)
	{
		delete pMainWndFrame;
	}

	return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/653163.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

软件测试基础教程学习3

文章目录 软件质量与测试3.1 软件质量问题的原因3.2 对软件质量特性的理解3.3 基于软件质量特性的测试3.4 软件能力成熟度模型&#xff08;CMM&#xff09; 软件质量与测试 3.1 软件质量问题的原因 软件质量问题的原因有以下几种&#xff1a; 软件本身的特点和目前普遍采用的…

AWTK实现汽车仪表Cluster/DashBoard嵌入式GUI开发(五):芯片型号

前言 随着汽车四化的推进,可以说汽车仪表也变成越来越智能化的一个ECU部件了。市面上的车型很多,油车发展了很多年,都有仪表,电车也发展起来了,车型也非常丰富,也都有仪表。仪表现在是作为多屏中一个屏存在的,现在车上最多的就是屏了,最大的要算中控屏了,有的还有空调…

【基础】MQTT -- MQTT 协议详解

【基础】MQTT -- MQTT协议详解 与 Broker 建立连接CONNECT 数据包CONNACK 数据包 断开连接DISCONNECT 数据包 订阅与发布PUBLISH 数据包SUBSCRIBE 数据包SUBACK 数据包UNSUBSCRIBE 数据包UNSUBACK 数据包 本文内容针对 MQTT 3.1.1 版本&#xff0c;从连接、发布与订阅等方面对协…

OpenCV做个熊猫表情

有的时候很想把一些有意思的图中的人脸做成熊猫表情&#xff0c;但是由于不太会ps&#xff0c;只能无奈放弃&#xff0c;so sad... 正好最近想了解下opencv的使用&#xff0c;那就先试试做个简单的熊猫表情生成器把~~ 思路就是&#xff0c;工具给两个参数&#xff0c;一个是人…

最小系统板STM32F103C8T6烧录程序指南

STM32F103C8T6烧录程序 【购买链接】&#xff1a;STM32F103C8T6最小系统板 方法一&#xff1a;使用SWD模式烧录 此时BOOT0 0&#xff0c;BOOT1 X&#xff08;任意&#xff09;&#xff0c;跳线帽接法如下图所示 接好后&#xff0c;若手边有STLINK的话&#xff0c;可以使用…

DAY25:二叉树(十五)修剪二叉搜索树+有序数组转换为二叉搜索树+二叉搜索树转化为累加树

文章目录 669.修剪二叉搜索树思路错误代码示例最开始的写法debug测试逻辑错误&#xff1a;需要两次递归的原因内存操作报错&#xff1a;操作了已经被删除的内存的指针&#xff08;力扣平台delete操作的问题&#xff0c;放IDE里就好了&#xff09;打日志debug示例 力扣平台delet…

高并发之限流-RateLimiter

背景 限流是保护高并发系统的三把利器之一&#xff0c;另外两个是缓存和降级。限流在很多场景中用来限制并发和请求量&#xff0c;比如说秒杀抢购&#xff0c;保护自身系统和下游系统不被巨型流量冲垮等。 限流的目的是通过对并发访问/请求进行限速或者一个时间窗口内的的请求进…

华为OD机试之 ABR 车路协同场景(Java源码)

ABR 车路协同场景 题目描述 数轴有两个点的序列 A{A1&#xff0c; A2, …, Am}和 B{B1, B2, ..., Bn}&#xff0c; Ai 和 Bj 均为正整数&#xff0c; A、 B 已经从小到大排好序&#xff0c; A、 B 均肯定不为空&#xff0c; 给定一个距离 R&#xff08;正整数&#xff09;&a…

一文详解!Selenium浏览器自动化测试框架

目录 前言&#xff1a; selenium简介 介绍 功能 优势 基本使用 获取单节点 获取多节点 节点交互 动作链 执行JavaScript代码 获取节点信息 切换frame 延时等待 前进和后退 cookies 选项卡管理 异常处理 选项卡切换 无头浏览器 前言&#xff1a; Selenium是…

双功能螯合剂:NOTA-C6-amine,NOTA-C6-氨基,含有大环配体NOTA和氨基

文章关键词&#xff1a;双功能螯合剂&#xff0c;大环化合物 【产品描述】 西安凯新生物科技有限公司供应的​NOTA-C6-amine中含有大环配体NOTA和氨基&#xff0c;其中氨基与羧酸、活化的 NHS 酯、羰基&#xff08;酮、醛&#xff09;等反应。NOTA及其衍生物是新型双功能整合剂…

【Android】移动端设备介绍(工业手持机)

系列文章 【Android】移动端设备介绍&#xff08;工业手持机&#xff09; 本文链接&#xff1a;https://blog.csdn.net/youcheng_ge/article/details/130604517 【Android】开发”打地鼠“小游戏 本文链接&#xff1a;https://blog.csdn.net/youcheng_ge/article/details/129…

华为OD机试之检查是否存在满足条件的数字组合(Java源码)

检查是否存在满足条件的数字组合 题目描述 给定一个正整数数组&#xff0c;检查数组中是否存在满足规则的数字组合 规则&#xff1a;A B 2C 输入描述 第一行输出数组的元素个数。 接下来一行输出所有数组元素&#xff0c;用空格隔开。 输出描述 如果存在满足要求的数…

C++入门前必看,超详细

目录 前言 一.C的关键字 二.命名空间 2.1命名空间定义 2.2命名空间的使用 三.C的输入及输出 四.缺省参数 4.1概念 4.2缺省参数分类 4.3缺省参数的注意点 五.引用 5.1 概念 5.2引用的特性 六.内联函数 6.1概念 6.2内联函数的特性 七.auto 7.1auto概念 7.2auto的…

【JAVA集合篇】ArrayList源码详解

文章目录 前言继承体系源码解析属性ArrayList(int initialCapacity)构造方法 ArrayList()构造方法ArrayList 构造方法add(E e)方法add(int index, E element)方法addAll 方法get(int index)方法remove(int index)方法remove(Object o)方法retainAll方法removeAll 总结 前言 Ar…

【Java高级语法】(四)包装类:关于包装类的那些细节你都清楚吗?~

Java高级语法详解之包装类 :one: 概念:two: 设计目的&#xff08;作用&#xff09;和用途:three: 使用3.1 自动装箱与拆箱3.2 常用方法3.3 常用属性3.4 null和默认值 :four: 注意事项:ear_of_rice: 总结:bookmark_tabs: 本文源码下载地址 1️⃣ 概念 在Java编程中&#xff0c;…

什么是TM的kotlin协程?就是靠 恢复和挂起,像同步一样写异步代码

作者&#xff1a;J船长 一、协程协程&#xff0c;恢复挂起&#xff0c;让异步像同步 重要的说三遍 协程协程&#xff0c;恢复挂起&#xff0c;让异步像同步协程协程&#xff0c;恢复挂起&#xff0c;让异步像同步协程协程&#xff0c;恢复挂起&#xff0c;让异步像同步 经常…

Apikit 自学日记:导入第三方产品 API 数据

除了手动创建API文档&#xff0c;系统也提供了一键导入 Swagger、Postman、RAP、YAPI 等产品数据的功能。方便从其他平台进行迁移。 产品支持度导入文件的后缀名Eolinker API 研发管理完全支持.jsonPostman V2.1支持导入API基础信息&#xff0c;超过10级分组的API数据将不会被导…

接口测试——接口测试文档

在执行接口测试前&#xff0c;测试人员肯定会先拿到开发给予的接口文档。测试人员可以根据这个文 档编写接口测试用例。所以&#xff0c;我们要先了解接口文档的主要构成及含义。 以购买开心产品项目接口文档为例&#xff0c;解析一下接口文档的组成。 完整的接口文档有公共信…

【VMD-DBO-LSTM】变分模态分解-蜣螂优化算法-长短时记忆神经网络研究(Python代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

乐鑫 Thread 边界路由器解决方案

乐鑫科技 Thread 边界路由器 (Thread Border Router) 解决方案正式获得了由 Thread Group 颁发的 Thread Certified Component 证书&#xff0c;符合最新的 Thread 1.3 标准&#xff0c;并支持 Matter 应用场景。 本文将深入探讨该解决方案的技术细节和优势&#xff0c;以及如…