Реклама
  • 9 октября 2017 г. 14:37

Qt. Показать запущенное приложение поверх своего.

Здравствуйте!
Есть у меня несколько приложений. Часть на Qt, часть - нет. И есть главное приложение, которое должно вызывать эти несколько приложений. Причем, если приложение не запущено, то оно должно запускаться, а если запущено, его окно должно выводиться на передний план. Для вызова приложений использую QProcess.
Выглядит это следующим образом.
Создание процесса:

QProcess *app;
bool pw = false;
...
void createProcess()
{
    app = new QProcess(this);
    app->setProgram("MyProgram.exe");
    app->setArguments(QStringList() << "arg1" << "arg2");
    connect(app, SIGNAL(started()), this, SLOT(onProcStarted()));
    connect(app, SIGNAL(finished()), this, SLOT(onProcFinished()));
}
Вызов:
if (!pw){
    app->start(QIODevice::ReadOnly);
} else {
    HWND hWnd = FindWindow(nullptr, L"Заголовок главного окна");
    if (hWnd > 0){
        ShowWindow(hWnd, SW_RESTORE);
        SetForegroundWindow(hWnd);
    }
}
Слоты:
void onProcStarted()
{
    pw = true;
}

void onProcFinished(int)
{
    pw = false;
}
Как я понял, QProcess не умеет выводить на передний план окно запущенного процесса. Поэтому приходится прибегать к WinApi. Но показ окна не работает. Причем, не работает функция FindWindow. Она не возвращает корректный хэндл. Хотя окно есть.
Я написал небольшую консольную программу на Delphi, используя эти же вызовы. Она работает и показывает нужное окно. Вот ее код:
program BTFArmAdmin;

{$APPTYPE CONSOLE}

uses
  Windows, SysUtils;

const
  WinCaption = 'Заголовок окна';

var
  hWndArm : hwnd;


begin
  try
    hWndArm := FindWindow(nil, WinCaption);
    if hWndArm > 0 then
    begin
      ShowWindow(hWndArm, SW_RESTORE);
      SetForegroundWindow(hWndArm);
    end;

  except
    on E:Exception do
      Writeln(E.Classname, ': ', E.Message);
  end;
end.
Вот эту программу я вызываю из главной программы Qt для показа окна.
Но это некрасиво.
Как сделать так, чтобы это работало из Qt? Что не так у меня в коде?
Заранее очень благодарен за ответ!

Пробовал делать так, но все равно не работает:
Q_PID pi = app->pid();
ShowWindow((HWND)pi->hProcess, SW_RESTORE);
SetForegroundWindow((HWND)pi->hProcess);
  • #
  • отредактировано 9 октября 2017 г. 15:07
  • 9 октября 2017 г. 15:00

Добрый день!
Я сейчас мало работаю с WinAPI , но могу предположить, что неработоспособность функции FindWindow заключается в кодировке. Скорее всего нужно передать массив символов в кодировке cp1251 , а там передаётся что-то другое.


Что касается QProcess , то он возвращает id процесса через метод QProcess::processId()
И кое-где на форумах можно найти варианты, когда перебирают все хендлеры окон, сравнивая текущий id процесса с тем, который нужен. Например, что-нибудь такое
void GetProcessMainWindows (DWORD dwProcessID, vector <HWND> &vWindows)
{
    HWND hwnd = NULL;

    do 
    {
        hwnd = FindWindowEx (NULL, hwnd, NULL, NULL);
        DWORD dwPID = 0;
        GetWindowThreadProcessId (hwnd, &dwPID);
        if (dwPID == dwProcessID)
           vWindows.push_back (hwnd);
    }
    while (hwnd != NULL);
}
Смысл этого кода заключается в том, что пытаемся найти все окна вне зависимости от названия, дёрнуть processId каждого окна и проверить, соответствует ли он тому, что нам нужен, если да, то загружаем в вектор окон. (Просто окон может быть несколько для одного процесса).

А вообще, скорее всего неработоспособность вашего первого варианта заключается в кодировке текста, который передаётся в FindWindow
  • #
  • Ответ был помечен как решение
  • 9 октября 2017 г. 20:09

Спасибо большое!
С Вашей подсказкой получилось.
Вот код:

        QTextCodec *codec = QTextCodec::codecForName("UTF-8");
        QString s = codec->toUnicode("Заголовок главного окна");
        LPCWSTR lps = (LPCWSTR)s.utf16();

        HWND hWnd = FindWindow(nullptr, lps);
        if (hWnd > 0) {
            ShowWindow(hWnd, SW_RESTORE);
            SetForegroundWindow(hWnd);
        }

Пожалуйста.

С таким вопросом впору и заметку накидать. Интересный момент с кодировкой.
  • #
  • 11 октября 2017 г. 13:27

Спасибо.
А как это сделать?

  • grig_p
  • #
  • отредактировано 11 октября 2017 г. 13:35
  • 11 октября 2017 г. 13:34

Если есть желание, то можете оставлять заметки на сайте в виде статей, это может быть всего несколько абзацев о какой-нибудь полезняшке в программировании.


Например, была такая проблема -> Решил её таким образом. Или захотел сделать что-то -> сделал это так.

Справа вверху в меню есть пункт "Написать статью" .
Кликаете, пишете материал, нажимаете опубликовать или сохранить, если недописали и планируете вернуться поздней. Статья проходит модерацию, правку вёрстки и одобряется, будет видна пользователям сайта после этого. Получаете статус автора и статьи уже публикуются сразу с постмодерацией (иногда приходится править вёрстку)

Для отделения текста, который будет показан в ленте новостей от всего остального текста статьи используете горизонтальную линию. В редакторе статьей есть кнопка для добавления горизонтальной линии. Работает наподобие ката на Хабре.
Статьи можно написать на двух языках, там две вкладки, но это не обязательно (я всё равно потом добавляю перевод и слегка правлю вёрстку). То есть достаточно и русского варианта текста.
Реклама

Ответы

Только авторизованные пользователи могут отвечать на форуме.
Пожалуйста, Авторизуйтесь или Зарегистрируйтесь
  • BlinCT
  • 22 октября 2017 г. 12:46

C++ - Тест 003. Условия и циклы

  • Результат 64 баллов
  • Очки рейтинга -1
  • Kiops
  • 22 октября 2017 г. 3:56

C++ - Тест 001. Первая программа и типы данных

  • Результат 86 баллов
  • Очки рейтинга 6
  • Kiops
  • 22 октября 2017 г. 2:41

Qt - Тест 001. Сигналы и слоты

  • Результат 100 баллов
  • Очки рейтинга 10
Последние комментарии
  • EVILEG
  • 21 октября 2017 г. 3:06

Qt/C++ - Урок 031. QCustomPlot - строим график по времени

Добавил архив с проектом

  • EVILEG
  • 20 октября 2017 г. 20:06

Qt/C++ - Урок 031. QCustomPlot - строим график по времени

После работы поищу, должен где-то быть на винте.

  • Миша
  • 20 октября 2017 г. 20:04

Qt/C++ - Урок 031. QCustomPlot - строим график по времени

не могли бы вы выложить архив с рабочей версией скрипта?

  • EVILEG
  • 20 октября 2017 г. 20:03

Qt/C++ - Урок 030. QCustomPlot - быстрый старт в работе с графиками

Использование дизайнера в Qt Creator и использование ui файлов является распространённой практикой в Qt фреймворке. Написать отдельную статью про то, что это такое? - может быть. Опи...

  • Миша
  • 20 октября 2017 г. 19:43

Qt/C++ - Урок 030. QCustomPlot - быстрый старт в работе с графиками

Но почему вы это не описали? Не могли бы вы описать.

Сейчас обсуждают на форуме
  • EVILEG
  • 22 октября 2017 г. 12:05

Закрепление якорей в момент создания объекта через JS

Добрый день! Якоря - это не те свойства, которые можно устанавливать сразу по инициализации, лучше их править после создания объекта, поскольку при одновременной установке они могут в...

  • EVILEG
  • 21 октября 2017 г. 23:33

Создание истории редактирования постов на сайте

Ясно. Тогда я лучше не буду тратить время на его проверку. Тем более, что я использую гугловский prettyprint для подсветки кода. Спасибо за информацию.

QFile::copy() возвращает false

Получилось! Спасибо огромное! path1 = "C:/Users/555/Pictures/00GAF13AP001-002.jpg"true

  • cordsac
  • 19 октября 2017 г. 15:49

How can I select the QGraphicView Item and change the properties

Ok I'll check it sir,If you can please do article(tutorial) about this,Its really useful.Thank you if you can give me some sample code when you free.thanks again

  • cordsac
  • 17 октября 2017 г. 19:28

How can I open SVG file through QT

Okay,Thank you sir :)