![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
HWND_BROADCAST и RegisterWindowMessage
NAlexey © (2004-01-15 12:20:00)Необходимо отослать сообщение в которое вложить строку уже запущенному приложению, например из второго запущенного. Делаю:
MyMessage := RegisterWindowMessage('My Message');переопределяю WndProc, в нем ловлю:
if Msg = MyMessage then
begin
Str := PChar(wParam);
end;
Отсылаю так:
SendMessage(HWND_BROADCAST, MyMessage, Application.Handle, LongInt(PChar(Str)));
Не получается однако, как можно передать строку другому приложению? Нужно ли использовать WM_COPYDATA?
NAlexey (2004-01-15 16:09:00) [1]Digitman ©
Ok
Digitman (2004-01-15 15:58:00) [2]
> недостаточно хорошо знаком с этой темой
ты просто обрати внимание и изучи детально описания всего пары ф-ций : Createfilemapping() и MapViewOfFile() ... это практически все что тебе нужно для реализации задачи ср-вами MMF
NAlexey (2004-01-15 15:32:00) [3]>Digitman © (15.01.04 15:21) [18]
К сожалению недостаточно хорошо знаком с этой темой, требуется некоторое время для реализации, его нет.
Digitman (2004-01-15 15:21:00) [4]
> Надо запрещать запускать 2 приложения на одной машине с
> одинаковым паролем
ну вот для этой цели MMF как раз - оч простое и стабильное решение
каждый экз-р стартующего приложения пытается создать именованый MMF
если создание прошло успешно, то это - первый экз-р ... после создания в MMF-структуре инкрементируется некий сч-к и фиксируется пароль
если создание прошло с признаком ERROR_ALREADY_EXISTS, то анализируется значение сч-ка : если он = 1 и пароль тот же, то - инкремент, иначе если пароль иной - инкремент сч-ка, ассоциированного с паролем, иначе - до свидания и Terminate
NAlexey (2004-01-15 15:11:00) [5]>MBo ©
Хм... Придется переделать как советовал Digitman © (15.01.04 13:01) [5].
MBo (2004-01-15 15:00:00) [6]>Digitman © (15.01.04 14:34) [11]
Проверил - срабатывает
>NAlexey
Есть все же сомнения по поводу рассылки WM_COPYDATA бродкастно. Ведь если найдется окно, которое тоже ждет WM_COPYDATA, то в его обработчике освободятся внутренние структуры ОС (MMF), хранящие тело посылки. Что будет потом - неясно
кроме того, может быть, ответ посылать PostMessage вместо Send?
При тесте у меня deadlock-а не было, но, как мне кажется, он не исключен...
NAlexey (2004-01-15 14:59:00) [7]>Digitman ©
Нет, дело не в этом. Приложение логинится с определенным паролем, который хранится на протяжении сесси. Надо запрещать запускать 2 приложения на одной машине с одинаковым паролем.
Digitman (2004-01-15 14:56:00) [8]
> NAlexey © (15.01.04 14:51) [13]
я понял
но если тебе требуется логика организации работы только одного экз-ра твоего приложения, то весь этот геморрой с сообщениями совершенно ни к чему ... существуют гораздо простые/изящные и эффективные решения, использующие, например, технологии и механизмы глобальных ОС-объектов, таких как mutex, atom и т.п.
NAlexey (2004-01-15 14:51:00) [9]Да, вместо WMB_INSTANCE_EXISTS и B_INSTANCE_EXISTS - MyMessage. Тороплюсь, время поджимает...
NAlexey (2004-01-15 14:50:00) [10]>MBo ©
>Digitman ©
Спасибо за участие, как я уже сказал решение найдено, единственное что, возможно я ошибся с реализацией:
var
CDS: TCopyDataStruct;
begin
CDS.dwData := 0;
CDS.cbData := Length(Str);;
CDS.lpData := @Str[1];
SendMessage(HWND_BROADCAST, WM_COPYDATA, Application.Handle, Integer(@CDS));
end;
MyMessage := RegisterWindowMessage('My Message');
в WndProc:
if Msg = WM_COPYDATA then
begin
Hnd := wParam;
if Hnd <> Application.Handle then
begin
CDS := PCopyDataStruct(Pointer(lParam))^;
Str := PChar(CDS.lpData);
if Str = 'ЧтоНадо' then
begin
SendMessage(Hnd, WMB_INSTANCE_EXISTS, 0, 0);
Result := 1;
end else
Result := CallWindowProc(WProc, Handle, Msg, wParam, lParam);
end else
Result := CallWindowProc(WProc, Handle, Msg, wParam, lParam);
end else if Msg = B_INSTANCE_EXISTS then
{DoSmth}
else
Result := CallWindowProc(WProc, Handle, Msg, wParam, lParam);
?
Digitman (2004-01-15 14:34:00) [11]
> MBo
в случае с WM_COPYDATA, как следует из док-ции, вернуть произвольный код возврата не удастся ... только ДА (обработано) или НЕТ (не обработано) ... хотя шут его знает, что можно вернуть под "соусом" True-результата ... но можно проверить)
Digitman (2004-01-15 14:31:00) [12]
> Внутри обработки WM_COPYDATA не получается ничего сделать,
> ни сообщения отослать, ни даже почемуто Halt(0) не работает.
а кому отсылать-то ? чтобы послать окну сообщение, нужно знать хэндл окна, а приложение-приемник об этом ничего не знает ... приложение-передатчик должно само позаботиться об информировании приложения-приемника о том, хендл какого конкретно окна следует использовать для отправки ответа... пусть приложение-передатчик всместе с данными, посылаемыми по бродкасту (или обычным образом), передает и хендл некоего своего окна для приема ответа/ответов
Halt-то зачем ? поясни ...
и вообще - приведи-ка свой код обработки WM_COPYDATA ... что-то ты там намудрил, наверно ...
MBo (2004-01-15 14:28:00) [13]Msg.Result можно задать - это вернется как результат SendMessage
NAlexey (2004-01-15 14:27:00) [14]Ээээ... Все, решение найдено.
NAlexey (2004-01-15 14:20:00) [15]Что то запутался опять, никак не соображу. Задача такая: необходимо послать в другое приложение(свое) строку, которую оно обработает и в зависимости от этого ответит. Так вот не могу этого реализовать. Отсылаю сообщениие WM_COPYDATA, приложение его получает, обрабатывает, но как ответить? Внутри обработки WM_COPYDATA не получается ничего сделать, ни сообщения отослать, ни даже почемуто Halt(0) не работает. Может я чего не так делаю?
NAlexey (2004-01-15 13:21:00) [16]>Digitman ©
Спасибо.
Digitman (2004-01-15 13:01:00) [17]
> NAlexey © (15.01.04 12:57) [4]
уточни в MSDN ... я просто не помню... навскидку думаю, что не прокатит это дело... но, в конце-концов, чтобы не городить огород с MMF и пр. можно просто отказаться от HWND_BROADCAST-опции и разослать последовательно всем нужным окнам WM_COPYDATA - сообщение, перечислив перед этим целевые окна с пом. EnumWindows[Ex]
NAlexey (2004-01-15 12:57:00) [18]>Digitman © (15.01.04 12:50) [3]
ХМ... Реально использовать WM_COPYDATA совместно с HWND_BROADCAST?
Digitman (2004-01-15 12:50:00) [19]
> Нужно ли использовать WM_COPYDATA?
если не принимать никаких иных мер по обеспечению глобальной доступности рассылаемых данных, то решение чуть ли не одно - WM_COPYDATA
можно использовать и RegisterWindowMessage(), но перед бродкастом создать MMF с предопределенным (известным всем заинтересованным в получении бродкаст-сообщения приложениям) именем и записать в него рассылаемые данные .... приложение-получатель бродкаст-сообщения открывает MMF c заранее известным именем и считывает оттуда данные
Nikolay M. (2004-01-15 12:48:00) [20]1) Как именно не получается?
2)
> переопределяю WndProc
???
Зачем? Message methods в хелпе не пробовал смотреть?
3) Попробуй не SendMessage, а PostMessage.