Duilib 父窗口无效化和消息传递

1、父窗口无效化和消息传递

当使用duillib界面库时,我们往往需要建立多个窗口,子窗口和父窗口之间有一定的逻辑需要,比如当子窗口弹出时,让父窗口无法处理父窗口内的控件的消息,即将父窗口无效化,直到子窗口关闭再恢复。

建立多个窗口,我们可以定义多个窗口类来一一对应。我建立窗口类的时候继承的是duilib库里面封装的窗口类WindowImpBase。重载父类里的消息处理函数,就可以实现对消息的过滤。

     virtual LRESULT HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam);//消息处理函数

在建立子窗口的前面将父窗口无效化,然后在子窗口的WM_CLOSE消息处理中使父窗口还原,并获得焦点。代码如下:

void MainFrameWnd::Notify(TNotifyUI& msg){
	if (msg.sType == DUI_MSGTYPE_CLICK){
		if (msg.pSender == close_btn_){
			SendMessage(WM_SYSCOMMAND, SC_CLOSE, 0);
			return;
		}
		else if (msg.pSender == min_btn_){
			SendMessage(WM_SYSCOMMAND, SC_MINIMIZE, 0);
			return;
		}
		else if (msg.pSender == max_btn_){
			SendMessage(WM_SYSCOMMAND, SC_MAXIMIZE, 0);
			return;
		}
		else if (msg.pSender == restore_btn_){
			SendMessage(WM_SYSCOMMAND, SC_RESTORE, 0);
			return;
		}
		else if (msg.pSender == mul_btn_){
			::EnableWindow(this->GetHWND(), false);    //父窗口无效化
			if (second_frame_wnd_ == nullptr){
				second_frame_wnd_ = new SecondFrameWnd();
				second_frame_wnd_->Create(this->GetHWND(), SecondFrameWnd::kClassName_, UI_WNDSTYLE_FRAME, 0);
			}
			second_frame_wnd_->CenterWindow();
			second_frame_wnd_->ShowWindow();
		}
	}
	__super::Notify(msg);
}

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

LRESULT MainFrameWnd::HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam){
	//switch (uMsg)
	//{
	//case WM_CREATE:
	//	//其他初始化操作
	//	break;
	//case WM_KEYDOWN:{
	//	//处理键盘按下操作
	//	//VK_ESCAPE Esc键
	//	if (wParam == VK_ESCAPE){
	//		return 0;
	//	}
	//	break;
	//}
	//case WM_CLOSE:
	//	//处理窗口关闭事件
	//	break;
	//default:
	//	break;
	//}
	//return __super::HandleMessage(uMsg, wParam, lParam);                             //调用父类的消息处理函数

	if (uMsg == WM_CLOSE)
	{
		::EnableWindow(::GetParent(this->GetHWND()), TRUE);  // 父窗口还原 m_hwnd为子窗口句柄
		::SetFocus(::GetParent(this->GetHWND()));//设置焦点到父窗口
	}
	return __super::HandleMessage(uMsg, wParam, lParam);

}

这样就实现了父窗口的无效化,还可以给用户一点反馈。

这里我设计的是在父窗口的总布局内添加一个Control控件,让他覆盖整个父窗口,初始化为不可见,背景颜色设置为半透明的黑色。当父窗口无效化后,将Control控件设为可见,这样父窗口变灰,告诉用户父窗口不可用,还原后再设为不可见,这样就实现了一个父窗口无效化的反馈。这里就没写代码了,因为很简单就能实现。
在这里插入图片描述

2、EnableWindow()和SetFocus()的含义和用法

EnableWindow()函数用于启用或禁用窗口或控件。当传入参数为TRUE时,窗口或控件将启用,可以响应用户输入;当传入参数为FALSE时,窗口或控件将禁用,不再响应用户输入。

  • 该函数的调用格式为:EnableWindow(hWnd, bEnable),其中hWnd为窗口或控件的句柄,bEnable为一个BOOL值。
::EnableWindow(::GetParent(this->GetHWND()), TRUE);  // 父窗口还原 m_hwnd为子窗口句柄

SetFocus()函数用于设置焦点到指定的窗口或控件上。当调用该函数时,指定的窗口或控件将成为当前活动窗口,并接收用户输入。该函数的调用格式为:SetFocus(hWnd),其中hWnd为窗口或控件的句柄。

::SetFocus(::GetParent(this->GetHWND()));//设置焦点到父窗口

这些函数在DuiLib中也可以使用,通过获取控件的句柄(可以使用DuiLib提供的**FindControl()**等方法)来操作窗口或控件的启用状态和焦点。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

森明帮大于黑虎帮

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值