Get Hwnd on Windows with Qt5 (From Wid)

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.

  1. Use the QT_USE_NATIVE_WINDOWS=1 in your environment.
  2. Set the Qt::AA_NativeWindows attribute on your application. All widgets will be native widgets.
  3. 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).
  4. Call QWidget::winId to enforce a native window (this implies 3).
  5. Set the Qt::WA_PaintOnScreen attribute to enforce a native window (this implies 3).


Related Topics



Leave a reply



Submit