Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Программа в программе

16K
16 января 2012 года
Rezus666
46 / / 15.08.2007
Доброго времени суток, заранее прошу прощения если подобный вопрос уже задавался.

Моя задача создать средствами QT приложение которое запускало бы ехе у себя во вкладках.
Поясню имеется некоторое приложение , предположим prog.exe, мне нужно запустить это приложение и встроить его в табвиджет приложения на QT4.7.1, с запуском проблем нет, использую QProcces::start, но встроить в виджет не получается, прошу помочь.


Код:
#include "MainWindow.h"
#include "ui_MainWindow.h"
#include "AppRunEmbeded.h"
#include <QDir>

#ifndef Q_WS_WIN
#include <QX11EmbedContainer>
QX11EmbedContainer* container;
#else
#include "qt_windows.h"
#endif


MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow),
    m_Process(NULL),
    winEmbedded(0)
{
    ui->setupUi(this);
#ifndef Q_WS_WIN
    container = new QX11EmbedContainer(ui->widget);
    container->show();
#endif
}

MainWindow::~MainWindow()
{
    delete ui;
}


void MainWindow::on_pushButton_clicked()
{
    // original size of application window
    // used to resize it after embedding
    origSize = ui->widget->size();

   
    // working directory
        QString workDir = "D:\\prog\\";

    // prepare environment variables and run the program
    QDir::setCurrent(workDir);
        m_Process = new QProcess;
    m_Process->setWorkingDirectory(workDir);
        QStringList env = QProcess::systemEnvironment();
        int index = env.indexOf(QRegExp("^PATH=(.*)", Qt::CaseInsensitive));
        QString old = env[index];
        QString newPath = old + ";" +
                workDir+";" +
                "";
        env[index] = newPath;
        m_Process->setEnvironment(env);
        qDebug(qPrintable("newPath : " + newPath));

    qDebug("Before run");
        QString eee = "prog.exe ";

        m_Process->start(eee/*, arguments*/);

    // embed process to a widget
    if (m_Process) qDebug("Yes process");
    if (ui->widget) qDebug("Yes widget");
    EmbedResult::T er = embedProcess(m_Process, ui->widget, &winEmbedded);
    QString output = QString("Result: %1 - WindId - %2").
        arg(EmbedResult::toText(er)).
        arg(qint64(winEmbedded));
    qDebug(qPrintable(output));







Код:
#include "AppRunEmbeded.h"
#include <QProcess>
#include <QStringList>
#include <QDir>
#include <QtGui/QApplication>


#ifdef Q_WS_WIN
#include "qt_windows.h"
bool AttachToWin(HWND parentWnd, qint64 pid);
#endif

// milliseconds to wait for process starts if it is not runinng
const int WAIT_FOR_RUN = 250;
// number of tries to look for main window
const int MAX_TRIES = 5;
// number of seconds between main window searches
const int TRY_PAUSE = 50;

#ifdef Q_WS_WIN
//------- Windows Utilites -------------------------------------------------
// Iterate through all existing windows
HWND theHwnd;
BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam)
{
    DWORD processId;
    ::GetWindowThreadProcessId(hwnd, &processId);

    if( processId == (DWORD)lParam )
    {
        theHwnd = hwnd;
        return FALSE;
    }
    return TRUE;
}

// Embed process to a widget
// parentWnd = window to embed in
// pid       = pid of running process
// winId     = pointer to a embedded window
// return true in case of success
bool AttachToWin(HWND parentWnd, qint64 pid, WId *winId)
{
    theHwnd = 0;
    EnumWindows(EnumWindowsProc, (LPARAM)pid);
    if (theHwnd)
    {
        qDebug(qPrintable(QString("Window %1 is found").arg(qint64(theHwnd))));

        if (winId)
        {
            *winId = theHwnd;
        }
        // Embed application to a widget
        LONG style = GetWindowLong(theHwnd, GWL_STYLE);
        style &= ~(WS_BORDER | WS_THICKFRAME);
        SetWindowLong(theHwnd, GWL_STYLE, style);
        SetParent(theHwnd, parentWnd);

        // resize parent widget to a embedded one
        RECT rct;
        GetWindowRect(parentWnd, &rct);
        MoveWindow(theHwnd, 0, 0, (rct.right - rct.left), (rct.bottom - rct.top), TRUE);

        return true;
    }
    else
    {
        qDebug("Window of the launched application is not found!");
        return false;
    }
}
#endif

QString EmbedResult::toText(EmbedResult::T res)
{
    switch (res) {
    case EmbedResult::Ok: return "OK";
    case EmbedResult::InvalidParam: return "Invalid argument";
    case EmbedResult::ProcessNotRunning: return "Process is not found";
    case EmbedResult::ProcessInfoFailed: return "Failed to get process information";
    case EmbedResult::NoMainWindow: return "Failed to get main process windows (console process?)";
    case EmbedResult::Unsupported: return "OS is not supported. Windows only function.";
    default: return "????";
    }
}

// a try to embed process
EmbedResult::T try_attach(QWidget *parent, qint64 pid, WId *winHandle)
{
    if (! pid) return EmbedResult::InvalidParam;

    bool attached = AttachToWin(parent->winId(), pid, winHandle);
    if (!attached) return EmbedResult::NoMainWindow;

    return EmbedResult::Ok;
}

// main procedure of process embedding
EmbedResult::T embedProcess(
    QProcess *process,
    QWidget *parent,
    WId *winHandle)
{
    if (! process || ! parent) return EmbedResult::InvalidParam;

    #ifndef Q_WS_WIN
    return EmbedResult::Unsupported;
    #else

    // if process is not running yet then wait it some time
    Sleep(WAIT_FOR_RUN);
    if (process->state() != QProcess::Running)
    {
        Sleep(WAIT_FOR_RUN);
        if (process->state() != QProcess::Running)
        {
            return EmbedResult::ProcessNotRunning;
        }
    }

    // find main process window
    _PROCESS_INFORMATION *pInfo = process->pid();
    if (pInfo)
    {
        for(int i = 0; i < MAX_TRIES; ++i)
        {
            qDebug(qPrintable(QString("Try #%1").arg(i+1)));
            EmbedResult::T rc = try_attach(parent, pInfo->dwProcessId, winHandle);
            if (rc != EmbedResult::NoMainWindow) return rc;
            Sleep(TRY_PAUSE);
        }
        return EmbedResult::NoMainWindow;
    }
    else {
        return EmbedResult::ProcessInfoFailed;
    }

    return EmbedResult::Ok;
    #endif
}
14
16 января 2012 года
Phodopus
3.3K / / 19.06.2008
QT на такие извращения не рассчитана
16K
18 января 2012 года
Rezus666
46 / / 15.08.2007
Тогда посоветуйте пожалуйста возможное решение этой задачи
297
18 января 2012 года
koodeer
1.2K / / 02.05.2009
Должна помочь винапишная функция SetParent.
Попробовал сейчас в WinForms C#: Блокнот нормально запускается и показывается во вкладке TabControl'а с использованием SetParent.
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог