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()**等方法)来操作窗口或控件的启用状态和焦点。

猜你喜欢

转载自blog.csdn.net/qq_44918090/article/details/131723739