Delphi programming blog
Источник: http://teran.karelia.pro/articles/item_4409.html
 

windows 7, списки переходов и delphi #2

Опубликовано 30.03.2010 г. 22:15

В прошлый раз мое изучение использование категории tasks (задач) в списках переходов остановилось на том, что можно использовать элементы списка переходов для переключения статуса приложения. В реализации данного пункта была одна маленькая проблема, решение которой оказалось простым, но поскольку с подобным я раньше не работал, то данное решение пришло не сразу, а после прочтения заметки на delphi.about.com итак, мы сформировали список задач в списке переходов. каждый элемент представляет возможный статус приложения, имеет команду запуска приложения, и соответственно параметр командной строки, равный нужному статусу. Далее алгоритм работы нашего приложения должен быть следующий. 1. при нажатии на элемент списка запускается новый экземпляр приложения 2. новый экземпляр проверяет, а не запущено ли уже данное приложение. 3. если приложение запущено то осуществляется передача windows сообщения о смене статуса и выход. 4. запущенный экземпляр должен обработать полученное сообщение. модифицируем исходный код проекта. Для контроля того запущен ли уже экземпляр приложения воспользуемся так называемым Mutex Object. Данный объект создается с уникальным именем, и сигнализирует о том, создан ли в системе уже подобный экземпляр с таким именем. Таким образом, перед запуском основной программы, создадим подобный объект с помощью CreateMutex, если получили ошибочный или нулевой результат, значит копия приложения уже запущена. Тогда далее нам следует отправить сообщение нашей копии, и завершить работу. Для того что бы отправить сообщение существующему экземпляру приложения можно пойти двумя способами: либо отправить сообщение всем окнам, либо найти нужное нам и отправить только ему. мы пойдем первым путем, поскольку он гораздо проще. при отправке широковещательного сообщения, надо убедиться, что данное сообщение будет уникально в системе. Поэтому код сообщения сгенерируем предварительно с помощью RegisterWindowMessage по нашему уникальному имени. Для отправки сообщения воспользуемся функцией SendMessage, где параметром обработчика окна назначения будет HWND_BROADCAST, в качестве кода сообщения мы передадим наше зарегистрированное сообщение, и в качестве параметра передадим нужный нам статус из параметра командной строки. по окончании работы приложения следует также освободить наш Mutex Object. следуя данной логике, код запуска приложения, получается следующий:

var setState : integer;
    mutex : THandle;
begin

    statusMsg := RegisterWindowMessage('My_Application_Message_Name');
    mutex := CreateMutex(nil, True, 'My_Application_Mutex_Name');
    if (Mutex = 0) or (getLastError() = ERROR_ALREADY_EXISTS) then   begin
        if paramCount > 0 then
            setState := strToInt(paramStr(1));
        SendMessage(HWND_BROADCAST, statusMsg, taskStates[setState].value, 0);
    end
    else begin
        Application.Initialize;
        Application.MainFormOnTaskbar := True;
        Application.CreateForm(TMainForm, MainForm);
        Application.Run;
        if mutex <> 0 then closeHandle(mutex);
    end;
end.

Далее (в чем в прошлый раз была загвоздка) следует обработать полученное сообщение смены статуса в нашем приложении. и загвоздка была в том, что обработку сообщения я хотел провести в обработчике application.onMessage. однако выяснилось что данный обработчик не обрабатывает сообщения отправленные с помощью sendMessage, поэтому обработку сообщения проведем в методе DefaultHandler главной формы приложения. И если приложение получило сообщение с нашим зарегистрированным значением, то следует изменить статус, иначе вызвать родительский обработчик сообщения.

TMainForm = class(TForm)
...
private
    procedure DefaultHandler(var Msg);override;
...
end;

var statusMsg : Cardinal; {код сообщения}

procedure TMainForm.defaultHandler(var msg);
begin
    if TMessage(msg).Msg = statusMsg then begin
        stateSelect.ItemIndex := TMessage(msg).WParam;
        exit;
    end
    else
        inherited;
end;

как вариант можно использовать уже упомянутый выше обработчик onMessage, только в данном случае сообщение надо отправлять с помощью PostMessage.

Метки:  windows 7  |  jumplists 

Комментарии

Нет комментариев
- Имя
- e-mail*
- Сайт
вы можете использовать теги [i],[b],[code],[quote]
Дополнительно