win7系统下 将第三方软件的界面,嵌入到Qt的窗口中

lufei_003 2015-11-20 04:09:22
小弟在尝试将第三方软件的窗口嵌入到QWidget中,并能够跟随QWidget放大缩小和关闭。
但是在界面拖动变化后,发现如下问题:
内嵌并不一定能跟随QWidget变大, 宽度增加一定后不再改变。。而且周为有滚动条的残留。。
求大神知道这是什么原因


...全文
493 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
lufei_003 2015-11-27
  • 打赏
  • 举报
回复
引用 8 楼 goldenhawking 的回复:
做重定向控制台的案例,是通过管道实现?
之前也考虑过,但有些功能用这种方法实现不了,例如vi编辑器可以在cygwin下使用,但就没法通过重定向做出来。
  • 打赏
  • 举报
回复
做重定向控制台的案例,是通过管道实现?
lufei_003 2015-11-24
  • 打赏
  • 举报
回复
引用 5 楼 zyq5945 的回复:
去github下载qt-solutions, qtwinmigrate就是你要的工程。
请教,CreateWindow()如何创建或获取第三方程序的窗口???
zyq5945 2015-11-23
  • 打赏
  • 举报
回复
去github下载qt-solutions, qtwinmigrate就是你要的工程。
lufei_003 2015-11-23
  • 打赏
  • 举报
回复
@Geek-小黑 @BEYONDMA 求各路大神路过指导一下
lufei_003 2015-11-23
  • 打赏
  • 举报
回复
下面是代码,我是从网上搜寻,然后自己码的,但功能很残废,希望各位大大指导一下,代码贴出来:
#include <QWidget>
#include <windows.h>

class EmbedExternalWindow : public QWidget
{
    Q_OBJECT
public:
    HANDLE m_hRead;
    HANDLE m_hWrite;
    static HANDLE handle;//process handle
    static HWND apphwnd;//window handle
    HANDLE hProcess;//cygwin process
    HANDLE hThread; //cygwin thread
    explicit EmbedExternalWindow(QWidget *parent = 0);
    ~EmbedExternalWindow();
    static int CALLBACK EnumWindowsProc(HWND hwnd, LPARAM param);
    HANDLE StartProcess(LPCTSTR program);
    void terminateCygwin();
    void closeCygwinBash();
    int CreateEmbedWindow(char* showName,char* processPath,char *params);
    virtual void resizeEvent(QResizeEvent *);
    virtual void closeEvent(QCloseEvent *);

public slots:
    void executeCmdSlot();
};

#include <windows.h>
#include <winuser.h>
#include <Tlhelp32.h>
#include <QMouseEvent>
#include <QDebug>

#include "EmbedExternalWindow.h"

EmbedExternalWindow::EmbedExternalWindow(QWidget *parent) : QWidget(parent)
{
    resize(800, 500);
    setMinimumHeight(200);
}

HANDLE EmbedExternalWindow::handle = 0;//process handle
HWND EmbedExternalWindow::apphwnd = 0;//window handle

EmbedExternalWindow::~EmbedExternalWindow()
{
    closeCygwinBash();//terminate the process;
}

int CALLBACK EmbedExternalWindow::EnumWindowsProc(HWND hwnd, LPARAM param)
{
  DWORD pID;
  DWORD TpID = GetWindowThreadProcessId(hwnd, &pID);//get process id
  if (TpID == (DWORD)param)
  {
    EmbedExternalWindow::apphwnd=hwnd;//hwnd is the window handle
    return false;
  }
  return true;
}

int EmbedExternalWindow::CreateEmbedWindow(char* showName,char* processPath,char*params)
{
//    char ch[1024] = "C:\\cygwin64\\bin\\mintty.exe";
    int num = MultiByteToWideChar(0,0,processPath,-1,NULL,0);
    wchar_t *path = new wchar_t[num];
    MultiByteToWideChar(0,0,processPath,-1,path,num);
   // char ch1[1024] = "";
    int num1 = MultiByteToWideChar(0,0,params,-1,NULL,0);
    wchar_t *param = new wchar_t[num1];
    MultiByteToWideChar(0,0,params,-1,param,num1);
//    EmbedExternalWindow::handle = StartProcess(path, param);
    EmbedExternalWindow::handle = onPipeCreate(path);
    QRect rect = this->geometry();
//    HWND wnd = GetActiveWindow();
    if(EmbedExternalWindow::apphwnd!=NULL)
    {
        ::SetParent(EmbedExternalWindow::apphwnd,(HWND)this->winId());
        SetWindowLong(EmbedExternalWindow::apphwnd, GWL_STYLE, WS_VISIBLE);

//        SetWindowLong(EmbedExternalWindow::apphwnd, GWL_STYLE, WS_BORDER);
        ::MoveWindow(EmbedExternalWindow::apphwnd, 0, 0,rect.width(), rect.height(), true);
        this->show();
    }
    setWindowTitle(showName);
    return 0;
}

void EmbedExternalWindow::resizeEvent(QResizeEvent *)
{
    QRect rect;
    rect = geometry();
//    ::MoveWindow(EmbedExternalWindow::apphwnd, -8, -30,rect.width()+18, rect.height()+40, true);
    ::MoveWindow(EmbedExternalWindow::apphwnd, 0, 0, rect.width(), rect.height(), true);
//    ShowWindow(EmbedExternalWindow::apphwnd, SW_SHOWMINIMIZED);
}

void EmbedExternalWindow::closeEvent(QCloseEvent *)
{
    CloseWindow(EmbedExternalWindow::apphwnd);
    CloseHandle(EmbedExternalWindow::handle);
    closeCygwinBash();//terminate the process;
}

HANDLE EmbedExternalWindow::StartProcess(LPCTSTR program)
{
//    HANDLE hProcess = NULL;
    hProcess = NULL;
    PROCESS_INFORMATION processInfo;
    STARTUPINFO startupInfo;
    ::ZeroMemory(&startupInfo, sizeof(startupInfo));
    startupInfo.cb = sizeof(startupInfo);
    startupInfo.dwFlags = STARTF_USESHOWWINDOW;
    startupInfo.wShowWindow = SW_HIDE;

    if(::CreateProcess(NULL, (LPTSTR)program,
     NULL,  // process security
     NULL,  // thread security
     FALSE, // no inheritance
     0,     // no startup flags
     NULL,  // no special environment
     NULL,  // default startup directory
     &startupInfo,
     &processInfo))
    {
        Sleep(1000);
        ::EnumWindows(&EnumWindowsProc, processInfo.dwThreadId);//Iterate all windows
        hProcess = processInfo.hProcess;
        hThread = processInfo.hThread;
    }
    return hProcess;
}

void EmbedExternalWindow::terminateCygwin()
{
    HANDLE hSnapShot=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);

    //-----we get info of all the process here;
    //-----get data from hSnapShot into PROCESSENTRY32 structure;
    //-----this structure is a process which is apart of ToolHelp32 API
    //use Process32First() && Process32Next()to get process
    //here we use Process32Next():
    //BOOL WINAPI Process32Next(HANDLE hSnapshot,LPPROCESSENTRY32 lppe);
    PROCESSENTRY32* processInfoNew=new PROCESSENTRY32;
    //-----set PROCESSENTRY32 's variable dwSize;
    processInfoNew->dwSize=sizeof(PROCESSENTRY32);
    int index=0;

    int ID = 0;
    while(Process32Next(hSnapShot,processInfoNew)!=FALSE)
    {
        index++;
        int size=WideCharToMultiByte(CP_ACP,0,processInfoNew->szExeFile,-1,NULL,0,NULL,NULL);
        char *ch=new char[size+1];
        if(WideCharToMultiByte(CP_ACP,0,processInfoNew->szExeFile,-1,ch,size,NULL,NULL))
        {
            if(strstr(ch,"bash.exe"))//this is the name of process;
            {
                ID = processInfoNew->th32ProcessID;
                // qDebug()<<"ID ="<<ID;
                HANDLE hProcess;
                // use TerminateProcess() to terminate the process
                // here use : PROCESS_ALL_ACCESS
                hProcess=OpenProcess(PROCESS_ALL_ACCESS,TRUE,ID);
                TerminateProcess(hProcess,0);
                CloseHandle(hProcess);
            }
        }
    }
    CloseHandle(hSnapShot);
    delete processInfoNew;
}

void EmbedExternalWindow::closeCygwinBash()
{
//    ExitProcess(processInfo.dwProcessId);
//    ExitThread(processInfo.dwThreadId);
    //-----only can close process "mintty", cannot close bash;
    //-----now is used 'terminateCygwin()' to close bash;
    TerminateProcess(hProcess,0);
    CloseHandle(hProcess);
    TerminateThread(hThread, 0);
    CloseHandle(hThread);
}


//界面中:
void MainWindow::setupUi()
{
    //------have to add a " -" after cygwin path, otherwise
    //all the command in the '/bin' cannot be used;
//    QString cygWinPath = "C:\\cygwin\\bin\\bash.exe --login -i";
//    QString cygWinPath = "C:\\Qt\\Qt5.4.0\\Tools\\QtCreator\\bin\\qtcreator.exe";
    QString cygWinPath = "cmd.exe";
    EmbedExternalWindow *embedWd = new EmbedExternalWindow();
    embedWd->CreateEmbedWindow(QString("Cygwin").toLatin1().data(),
                               QString("%1").arg(cygWinPath).toLatin1().data(),
                               QString("").toLatin1().data());

    QWidget *centralWgt = new QWidget(this);
    centralWgt->setContentsMargins(0, 0, 0, 0);
    QVBoxLayout *verticalLyt = new QVBoxLayout();
    verticalLyt->setContentsMargins(0, 0, 0, 0);

    QPushButton *cmdBtn = new QPushButton("pwd", this);
    cmdBtn->setMaximumWidth(50);
    connect(cmdBtn, SIGNAL(clicked()), embedWd, SLOT(executeCmdSlot()));

    verticalLyt->addWidget(cmdBtn);
    verticalLyt->addWidget(embedWd);

    centralWgt->setLayout(verticalLyt);

    setCentralWidget(centralWgt);
}
lufei_003 2015-11-23
  • 打赏
  • 举报
回复
引用 5 楼 zyq5945 的回复:
去github下载qt-solutions, qtwinmigrate就是你要的工程。
是使用其中的 qwinhost 么?看了一下HostWindow的例子,还是没有明白。。 没看出来那个CreateWindow() 可以怎样让我打开第三方的程序?求讲解
炫彩灵感 2015-11-21
  • 打赏
  • 举报
回复
我想请教下楼主,这个功能你是如何实现的?思路是啥
beyondma 2015-11-20
  • 打赏
  • 举报
回复
莫有代码没有办法看,哈哈

16,201

社区成员

发帖
与我相关
我的任务
社区描述
Qt 是一个跨平台应用程序框架。通过使用 Qt,您可以一次性开发应用程序和用户界面,然后将其部署到多个桌面和嵌入式操作系统,而无需重复编写源代码。
社区管理员
  • Qt
  • 亭台六七座
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧