Запуск дочерних процессов. Простейшие способы взаимодействия (обмена данными), страница 4

HANDLE      hTemplateFile);   //обычно 0, если нет - дескриптор файла, содержащего атрибуты для вновь создаваемого файла. При этом значения dwFlagsAndAttributes игнорируются

2. Посылка пользовательского межпроцессного сообщения

Последовательность действий.

Родительский процесс:

1)  предусмотреть событие, по которому будет отправляться сообщение (нажатие кнопки)

2)  зарегистрировать свое пользовательское межпроцессное сообщение

3)  отправить сообщение (два варианта): а) получить дескриптор или указатель на главное окно дочернего процесса (FindWindow() ) и послать ему сообщение с помощью SendMessage() или PostMessage() б) использовать SendMessage() или PostMessage() с параметром HWND_BROADCAST

Дочерний процесс – должен быть GUI-приложением, так как должен обработать полученное сообщение:

1. Для главного окна перегрузить виртуальный метод protected:

virtualboolwinEvent ( MSG * message, long * result ) ;

2. В реализации методаwinEvent(): a) зарегистрировать сообщение с тем же именем - RegisterWindowMessage()

b) Проверить – если получено зарегистрированное сообщение, выдать MessageBox

c) сформировать: *result = 0;

d)вернуть true, чтобы механизм событий Qt не обрабатывал это сообщение дальше

e) во всех остальных случаях вернуть false

Протестируйте данный вид взаимодействия.

Запустите несколько экземпляров дочернего процесса и передайте им всем пользовательское сообщение посредством HWND_BROADCAST

3. Передача данных с помощью WM_COPYDATA

Процесс-отправитель (отправляет дочернему процессу динамически формируемую строчку текста):

1)  для GUI-приложения введите в диалоговую панель элемент “Line edit” – для формирования отправляемых данных.

2)  предусмотрите событие, по которому Вы будете отправлять данные процессу-получателю (неплохо реализовать следующее взаимодействие: как только в элементе edit отправителя пользователь что-нибудь меняет, так сразу эти изменения должен отображать процесс-получатель) – > перейти к слоту/ TextChanged а) создать и проинициализировать структуру:

struct COPYDATASTRUCT{

ULONG_PTR dwData; //32-битовое число для передачи данных принимающему процессу – может служить признаком – какого рода данные Вы отправляете

DWORD cbData; //количество байт, на которые указывает lpData

PVOID lpData; //указатель на данные. Может быть NULL. Замечание: будьте осторожны - это адрес в адресном пространстве процесса-процесса-отправителя (каким бы образом Вы этот блок не создавали – в стеке, глобально, динамически)! => в нем не может быть в свою очередь других адресов

}; б) отправить сообщение WM_COPYDATA

SendMessage( дескриптор (HWND) целевого окна – получателя,//Замечание: в данном случае, может быть, лучше отправлять сообщение не всем top-level окнам, а конкретному окну, дескриптор которого можно получить с помощью FindWindow()

WM_COPYDATA,              // идентификатор сообщения

(WPARAM) дескриптор (HWND) окна – отправителя,

(LPARAM) указатель на структуру COPYDATASTRUCT

);

Процесс-приемник сообщения:

1.  В классе главного окна перегрузить виртуальный метод winEvent():

class ChildWindow : public QMainWindow

{

protected:

virtualboolwinEvent ( MSG * message, long * result ) ;

};

2.  Получать сообщение WM_COPYDATA ,будет главное окно приложения, а обрабатывать совсем другое – надпись (Text Label), которая в свою очередь является дочерним окном  CentralWidget, поэтому с помощью механизма сигналов/слотов требуется перенаправить информацию надписи. В нашем примере будем с помощью WM_COPYDATA пересылать строчку, поэтому параметром сигнала может быть QString:

class ChildWindow : public QMainWindow

{

protected:

virtual bool winEvent ( MSG * message, long * result ) ;