zoukankan      html  css  js  c++  java
  • 将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   
  • 相关阅读:
    剑指offer--29.从上往下打印二叉树
    剑指offer--28.栈的压入、弹出序列
    剑指offer--27.包含min函数的栈
    剑指offer--26.顺时针打印矩阵
    剑指offer--25.二叉树的镜像
    剑指offer--24.树的子结构
    剑指offer--23.合并两个排序的链表
    剑指offer--22.反转链表
    剑指offer--21.链表中倒数第k个结点
    剑指offer--20.矩形覆盖
  • 原文地址:https://www.cnblogs.com/towerbit/p/12365841.html
Copyright © 2011-2022 走看看