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   
  • 相关阅读:
    Intent
    What should we do next in general after collecting relevant data
    NOTE FOR Secure Friend Discovery in Mobile Social Networks
    missing pcap.h
    after building Android Source code
    plot point(one column)
    When talking to someone else, don't infer that is has been talked with others at first. It may bring repulsion to the person who is talking with you.
    进程基本知识
    Python input和raw_input的区别
    强制 code review:reviewboard+svn 的方案
  • 原文地址:https://www.cnblogs.com/towerbit/p/12365841.html
Copyright © 2011-2022 走看看