將QT窗口嵌入到WinForm窗口

要想 windows下抓取Qt進程主界面,並嵌入到自己的程序中顯示,需要首先設置qt窗口的windowTitle屬性,然後就可以通過 windows api 中的 FindWindow 函數查找到窗口的hWnd了,最後通過SetParent將QT窗口裝入即可。

抓取Qt界面窗口的時候,最好選用FindWindow的方式,因爲通過進程查找主窗口的方式可能導致抓取到的窗口句柄不是主窗口(一個進程可能對應多個主窗口或者沒有主窗口)

遇到抓取的Qt程序界面座標響應異常,會導致菜單欄和工具欄無法正常鼠標事件,解決方案如下

1.考慮Qt界面有自己的座標系機制,可以通過抓取QT程序界面開發接口所示方式解決座標系不一致問題。

 1 #include "doecwidget.h"   
 2    
 3 #include <QApplication>   
 4 #include <QMouseEvent>   
 5 #include <QMessageBox>   
 6    
 7 #include "mainwindow.h"   
 8    
 9    
10 class PosEventFilter : public QObject   
11 {   
12    
13 public:   
14    
15     PosEventFilter(QObject * parent = 0);   
16    
17     virtual ~PosEventFilter();   
18    
19     QWidget * m_curWindow;   
20    
21 protected:   
22    
23     bool eventFilter(QObject *obj, QEvent *event);   
24    
25 };   
26    
27 PosEventFilter::PosEventFilter(QObject * parent)   
28     : QObject(parent)   
29 {   
30     m_curWindow = NULL;   
31 }   
32    
33 PosEventFilter::~PosEventFilter()   
34 {   
35 }   
36    
37 bool PosEventFilter::eventFilter(QObject *obj, QEvent *event)   
38 {   
39     QWidget * t_curWidget = qobject_cast<QWidget *>(obj);   
40     ///多重判斷,以免導致winId函數引起事件無限循環   
41     if ((event->type() == QEvent::MouseMove) && (NULL != t_curWidget) && (!t_curWidget->internalWinId()))   
42     {   
43         t_curWidget->winId();   
44     }   
45    
46     return QObject::eventFilter(obj, event);   
47    
48     if ((event->type() == QEvent::MouseButtonRelease) && (m_curWindow == obj)) {   
49         QMouseEvent * t_mouseEvent = static_cast<QMouseEvent *>(event);   
50         QMessageBox::information(0, "", QString("Mouse press %1,%2").arg(t_mouseEvent->pos().x()).arg(t_mouseEvent->pos().y()));   
51         return true;   
52     } else {   
53         // standard event processing   
54         return QObject::eventFilter(obj, event);   
55     }   
56 }   
57    
58    
59 doecwidget::doecwidget()   
60 {   
61    
62 }   
63    
64 doecwidget::~doecwidget()   
65 {   
66    
67 }   
68    
69 void doecwidget::creatDockWidget(HWND _hwnd)   
70 {   
71     int t_argc = 1;   
72     char * t_argv = "";   
73     QApplication t_app(t_argc, &t_argv);   
74     PosEventFilter t_posEventFilter(&t_app);   
75     t_app.installEventFilter(&t_posEventFilter);   
76    
77     CMainWindow * t_mainWindow = new CMainWindow();   
78     t_posEventFilter.m_curWindow = t_mainWindow;   
79     t_mainWindow->show();   
80     SetParent(t_mainWindow->winId(), _hwnd);   
81     ///ShowWindow(t_dockWidget->winId(), SW_SHOW);   
82     t_app.exec();   
83 }   
84    
85 void doecwidget::creatDockWidget()   
86 {   
87     int t_argc = 1;   
88     char * t_argv = "";   
89     QApplication t_app(t_argc, &t_argv);   
90     PosEventFilter t_posEventFilter(&t_app);   
91     t_app.installEventFilter(&t_posEventFilter);   
92    
93     CMainWindow * t_mainWindow = new CMainWindow();   
94     t_posEventFilter.m_curWindow = t_mainWindow;   
95     t_mainWindow->show();   
96     t_app.exec();   
97 }   

2.也可以在抓取程序端,通過SendMessage函數在位置移動或大小改變事件中發送消息的方式保證座標系一致

 1     HWND t_curHWND;   
 2     ///t_curHWND = FindWindow(L"QWidget", L"編碼分析");   
 3     t_curHWND = FindWindow(L"QWidget", L"CMainWindow");   
 4     LONG style = GetWindowLong(t_curHWND, GWL_STYLE);// 14CF 0000   
 5     // 1=WS_VISIBLE 4=WS_CLIPSIBLINGS C=WS_CAPTION F= 0000   
 6     style &=~WS_CAPTION;   
 7     //style &=~WS_CLIPSIBLINGS;   
 8     //style |=WS_CHILD;   
 9     SetWindowLong(t_curHWND,GWL_STYLE,style);   
10     RECT t_rc;   
11     GetClientRect(AfxGetMainWnd()->GetSafeHwnd(), &t_rc);   
12    
13     MoveWindow(t_curHWND, 0, 0, t_rc.right - t_rc.left, t_rc.bottom - t_rc.top, TRUE);   
14     SetParent(t_curHWND, AfxGetMainWnd()->GetSafeHwnd());   
15     ///SetWindowLong(t_curHWND, GWL_STYLE, WS_VISIBLE);   
16     ///SendMessage(t_curHWND, WM_SYSCOMMAND, SC_MAXIMIZE, 0);   
17    
18     ShowWindow(t_curHWND, SW_MAXIMIZE);   
19    
20     POINT t_point;   
21     t_point.x = t_rc.left;   
22     t_point.y = t_rc.top;   
23     ClientToScreen(AfxGetMainWnd()->GetSafeHwnd(), &t_point);   
24    
25     RECT t_curWinRc, t_curCliRc;   
26     GetWindowRect(t_curHWND, &t_curWinRc);   
27     GetClientRect(t_curHWND, &t_curCliRc);   
28     ClientToScreen(t_curHWND, (LPPOINT)&t_curCliRc.left);   
29     ClientToScreen(t_curHWND, (LPPOINT)&t_curCliRc.right);   
30     ///t_point.x = t_point.x + t_curCliRc.left - t_curWinRc.left;   
31     ///t_point.y = t_point.y + t_curCliRc.top - t_curWinRc.top;   
32     SendMessage(t_curHWND, WM_MOVE, 0, MAKELPARAM(t_point.x, t_point.y));   
33     ///MAKELPARAM將xy轉換爲lParam   
34     ///MAKEPOINTS將lParam轉換爲POINTS   

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章