嵌入Win32原生子窗口后Qt父窗口WM_NCHITTEST消息丢失
解决QWinHost嵌入原生窗口后父窗口WM_NCHITTEST消息被拦截的问题
以下是几个可行的解决方向,你可以根据自己的场景尝试:
给嵌入的原生子窗口添加WS_EX_TRANSPARENT扩展样式
这个样式会让子窗口不处理鼠标输入,所有鼠标消息会自动传递给父窗口。你需要在创建旧Win32窗口时,把WS_EX_TRANSPARENT加入到扩展样式参数中:HWND hOldWindow = CreateWindowEx( WS_EX_TRANSPARENT | 你的原有扩展样式, 窗口类名, 窗口标题, 原有窗口样式, x, y, width, height, parentHwnd, nullptr, hInstance, nullptr );注意:如果旧窗口本身需要处理鼠标交互,这个方法不适用,得换其他方案。
子类化QWinHost的原生窗口过程,转发WM_NCHITTEST消息
QWinHost内部会创建一个中间原生窗口来承载旧窗口,这个窗口可能拦截了鼠标消息。你可以通过子类化它的窗口过程,把WM_NCHITTEST消息转发给Qt主窗口:LRESULT CALLBACK CustomHostWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData) { if (msg == WM_NCHITTEST) { // 获取Qt主窗口的原生句柄 HWND mainHwnd = reinterpret_cast<HWND>(dwRefData); if (mainHwnd) { // 把消息转发给主窗口,返回主窗口的处理结果 return SendMessage(mainHwnd, msg, wParam, lParam); } } // 其他消息交给默认处理 return DefSubclassProc(hWnd, msg, wParam, lParam); } // 在QWinHost初始化完成后调用(比如在show之后) void setupHostWndProc(QWinHost* winHost, QMainWindow* mainWindow) { HWND hostHwnd = reinterpret_cast<HWND>(winHost->winId()); SetWindowSubclass(hostHwnd, CustomHostWndProc, 0, reinterpret_cast<DWORD_PTR>(mainWindow->winId())); }直接在Qt主窗口的nativeEvent中处理WM_NCHITTEST
绕过子窗口的拦截,主动在主窗口的nativeEvent方法中处理WM_NCHITTEST消息,直接返回对应的区域判断结果:bool MainWindow::nativeEvent(const QByteArray& eventType, void* message, long* result) { MSG* msg = static_cast<MSG*>(message); if (msg->message == WM_NCHITTEST) { POINT screenPt = { LOWORD(msg->lParam), HIWORD(msg->lParam) }; POINT clientPt = screenPt; ScreenToClient(msg->hwnd, &clientPt); // 自定义区域判断:标题栏区域(假设高度30) if (clientPt.y <= 30) { *result = HTCAPTION; return true; } // 左边框(宽度5) if (clientPt.x <= 5) { *result = HTLEFT; return true; } // 右边框 if (clientPt.x >= width() - 5) { *result = HTRIGHT; return true; } // 下边框 if (clientPt.y >= height() - 5) { *result = HTBOTTOM; return true; } // 其他边角区域可以继续补充... } return QMainWindow::nativeEvent(eventType, message, result); }调整QWinHost的布局范围
如果QWinHost控件占满了整个Qt主窗口,所有鼠标消息都会先被它接收。可以给主窗口留出标题栏和边框的空白区域,只让QWinHost填充客户区部分,这样标题栏和边框的消息会直接被主窗口捕获。
内容的提问来源于stack exchange,提问作者Mazrog
相关产品推荐
相关产品推荐

