Unsolved CWND to QWidget*
-
Good day,
I'm using MFC to build a GUI on vs2012 and I recently integrated Qt5.4.1 library in my project. Does anyone know how to connect an CWND pointer to QWidget pointer? I can get the HWND from a widget using winId() but how to get a widget from a HWND or a CWND?
CWnd* pMfc to the argument of myQtfunction(QWidget* pwidget)
Thanks in advance!
Massi
-
Hello @Massi,
A
QWidget
is quite a complex class; many of its internals are managed byQApplication
. Therefore, you cannot convert a CWND/HWND window directly to aQWidget
, because those are managed outside ofQApplication
.Now, it is possible to create a
QWindow
object to manipulate external windows. It is also possible to embed aQWindow
inside aQWidget
. You can kind of combine them like this:WId externalWindow = (WId)FindWindow(NULL, L"Untitled - Notepad"); // Get HWND by window title QWindow *myWindow = QWindow::fromWinId(externalWindow); QWidget *myWidget = QWidget::createWindowContainer(myWindow);
However,
QWidget::createWindowContainer()
was not really designed to handle external windows. You will likely encounter strange issues. See https://bugreports.qt.io/browse/QTBUG-40320 for details. -
Thanks for your reply @JKSH
Unfortunately it didn't work and even if I have a pointer to the window as shown below, it crashes.
BOOL myFMCclass::OnFileOpen(LPCTSTR szPathname, CWnd* pParent) { QFile file(szPathname); if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) return false; //Embed a QWindow inside a QWidget QWindow* myWindow = QWindow::fromWinId((WId)pParent); QWidget* myWidget = QWidget::createWindowContainer(myWindow); myQtclass* m_widgetptr = new myQtclass(myWidget); return true; }
Well I'm trying to display a QGraphicView within an FMC GUI. and if I create a new QWidget instead of using QWidget::createWindowContainer() I get the following error:
QWidget: Must construct a QApplication before a QWidgetAgain thanks for you help!!!
Massi
-
@Massi said in CWND to QWidget*:
even if I have a pointer to the window as shown below, it crashes.
BOOL myFMCclass::OnFileOpen(LPCTSTR szPathname, CWnd* pParent)
My example is for a
HWND
, not aCWnd*
. You need to convert your pointer to a HWND first. See http://forums.codeguru.com/showthread.php?328037-Converting-CWND*-to-HWNDWell I'm trying to display a QGraphicView within an FMC GUI...
**QWidget: Must construct a QApplication before a QWidget**
As the error message says, you need to create a
QApplication
before you can create aQWidget
. Furthermore, you must callQApplication::exec()
before you can interact with any QWidgets -- this requirement makes it tricky to add QWidgets to an existing non-Qt program, becauseQApplication::exec()
blocks the calling thread.You could work around this by creating your QApplication and QWidgets in a different thread (see http://stackoverflow.com/questions/22289423/how-to-avoid-qt-app-exec-blocking-main-thread/22290909#22290909 ). However, I have only done that with "native" QWidgets, not using QWidget::createWindowContainer(). it sounds like you want to embed an MFC window inside a QWidget, and then use that QWidget inside the external MFC application...? This is very convoluted, and I have a feeling it won't work nicely.
-
Hello @JKSH ,
Well I want to embed a QGraphicView widget inside a MFC application. I don't know if QWidget class is enough to handle CWnd and use it as a simple QWidget. should I create a Qdialog window and insert the QGraphicView in it and then try to connect it with my MFC GUI?
BOOL myFMCclass::OnFileOpen(LPCTSTR szPathname, CWnd* pParent) { QFile file(szPathname); if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) return false; //Embed a QWindow inside a QWidget HWND hWind = pParent->GetSafeHwnd(); if(hWind != NULL) { QWindow* myWindow = QWindow::fromWinId((WId)hWind); QWidget* myWidget = QWidget::createWindowContainer(myWindow); if(myWidget) myQtclass* m_widgetptr = new myQtclass(myWidget); } return true; }
Many thanks!
Massi
-
Hello,
I have to do exactly the same as you, so I tried to code it the same way. but when I run
QWindow *myWindow = QWindow::fromWinId(externalWindow);
I am getting an access violation error. Have you had this problem? Do you know how to fix it?
Thank you,
Emmanuel -
@EmmanuelC
If your code is also like:QWindow* myWindow = QWindow::fromWinId((WId)pParent); QWidget* myWidget = QWidget::createWindowContainer(myWindow);
are you sure that your access violation comes during
fromWinId()
rather than fromcreateWindowContainer
? If it's the latter it might be worth looking at https://stackoverflow.com/questions/30162091/drawing-errors-and-crash-with-qwidgetcreatewindowcontainer. -
Hello JonB, thank you for your answer. Yes I am sure because I didn't even include QWidget::createWindowContainer yet. (I wanted to test first if the four first functions worked.)
For now my code is like this:
CWnd* cwnd= GetDlgItem(IDC_STATIC); HWND hWnd = cwnd->GetSafeHwnd(); WId externalWindow = (WId)hWnd; QWindow *myWindow = QWindow::fromWinId(externalWindow);
I don't call any other function after that, and really don't understand why I have an access violation here!
-
@EmmanuelC
I know nothing about this, but...The example above (@JKSH) using
fromWinId()
called it on the result of aFindWindow()
for a window from another process,externalWindow
. https://doc.qt.io/qt-5/qwindow.html#fromWinId says:Creates a local representation of a window created by another process or by using native libraries below Qt.
You have a
CWnd
, from an internal window I believe. I don't know how that plays.As I said, I know nothing, so I probably can't say much more than this....