Get HWND on windows with Qt5 (from WId)
In Qt5 winEvent
was replaced by nativeEvent
:
bool winEvent(MSG* pMsg, long* result)
is now
bool nativeEvent(const QByteArray & eventType, void * message, long *result)
And in EcWin7::winEvent
you have to cast void
to MSG
:
bool EcWin7::winEvent(void * message, long * result)
{
MSG* msg = reinterpret_cast<MSG*>(message);
if (msg->message == mTaskbarMessageId)
{
...
I was able to get the application to work! Just replace:
mWindowId = wid;
with
mWindowId = (HWND)wid;
how can I obtain HWND of a class derived from QMainWindow
You can use QWidget::effectiveWinId() or QWidget::winId(), this holds the HWND of the widget on Windows.
MainWindow w;
w.show();
HWND hWnd = (HWND) w.winId();
Storing and using Windows Handle ( WId ) in registry
Depending on the bitness of the your program you can either use REG_DWORD
for 32-bit programs or REG_QWORD
for 64-bit programs.
Getting the HWND of a widget in Qt
You can use QWidget::winId() to get the HWND associated with a widget.
create QWidget width HWND parent
I found a way that works, but there are unknown messages on the screen
windowsProc: No Qt Window found for event 0x24 (WM_GETMINMAXINFO), hwnd=0x0x110956.
windowsProc: No Qt Window found for event 0x83 (WM_NCCALCSIZE), hwnd=0x0x110956.
windowsProc: No Qt Window found for event 0x5 (WM_SIZE), hwnd=0x0x110956.
windowsProc: No Qt Window found for event 0x3 (WM_MOVE), hwnd=0x0x110956.
setGeometryDp: Unable to set geometry 640x480+0+0 on QWindow/''. Resulting geometry: 640x480+-760+-370 (frame: 8, 30, 8, 8, custom margin: 0, 0, 0, 0, minimum size: 0x0, maximum size: 16777215x16777215).
setGeometryDp: Unable to set geometry 640x480+0+0 on QWindow/''. Resulting geometry: 640x480+-760+-370 (frame: 8, 30, 8, 8, custom margin: 0, 0, 0, 0, minimum size: 0x0, maximum size: 16777215x16777215).
listLabels.size() 4
Let a parent window be an ownerWin, and a child one QWidget-window named childWin;
If to use SetWindowLongPtr, the desirable result is achieved (the child window overlaps the parent one), but the child window still is in the memory when the parent window closes.
To fix a problem I create one more child window (middleWin with a parent ownerWin.) using WinApi. After wrapping this window with QWidget using createWindowContainer() it stops working normally. Then using standard Qt methods we can link our QWidget window. So we have three windows: parent, intermediate and mine. Then I close middleWin using close().All that manipulations needs to insure that when ownerWin closes, also childWin closes as well. If SetWindowLongPtr is used, then childWin will always be above the parent window, but it works only if called after function show() in child window.
Below are the functions I use. First call setWinParent(), then showWindow().
In setWinParent() lines 1 through 5 is "black box" for me. I don't know why window is created that way.
void setWinParent(HWND ownerWin)
{
HWND hwnd = (HWND)this->winId();
DWORD exStyle = GetWindowLong(hwnd, GWL_EXSTYLE) ;//1
DWORD style = GetWindowLong(hwnd, GWL_STYLE);//2
WCHAR className[256];//3
GetClassName(hwnd, className,256);//4
HWND newHwnd = CreateWindowEx(exStyle, className, NULL, style,//5
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
ownerWin, NULL, qWinAppInst(), NULL);
QWindow *qw=QWindow::fromWinId((WId)newHwnd);
QWidget* qWidget = createWindowContainer(qw);
qWidget->show();
this->setParent(qWidget);
this->setWindowFlags(Qt::Window);
qWidget->close();
}
void showWindow(HWND ownerHwnd)
{
show();
SetWindowLongPtr((HWND)this->winId(), GWLP_HWNDPARENT, (LONG)ownerHwnd);
}
Force QWidget Child to have its own Window Handle
Yes. You have several options for that. See the topic Native Widgets vs Alien Widgets in the QWidget class documentation.
- Use the QT_USE_NATIVE_WINDOWS=1 in your environment.
- Set the Qt::AA_NativeWindows attribute on your application. All widgets will be native widgets.
- Set the Qt::WA_NativeWindow attribute on widgets: The widget itself and all of its ancestors will become native (unless Qt::WA_DontCreateNativeAncestors is set).
- Call QWidget::winId to enforce a native window (this implies 3).
- Set the Qt::WA_PaintOnScreen attribute to enforce a native window (this implies 3).
Related Topics
How to Reverse the Order of Arguments of a Variadic Template Function
Rotate Cv::Mat Using Cv::Warpaffine Offsets Destination Image
Common Reasons for Bugs in Release Version Not Present in Debug Mode
Programmatically Reading a Web Page
Default Argument in the Middle of Parameter List
How to Create a Utf-8 String Literal in Visual C++ 2008
Cmake: Include Library Dependencies in a Static Library
Lvalue to Rvalue Implicit Conversion
How to Identify the File Content as Ascii or Binary
Capturing Perfectly-Forwarded Variable in Lambda
What Are the Use Cases for Having a Function Return by Const Value for Non-Builtin Type
Are C++ Templates Just MACros in Disguise
When Should You Use the "This" Keyword in C++
Qml and C++ Image Interoperability