Форум: "WinAPI";
Текущий архив: 2004.03.28;
Скачать: [xml.tar.bz2];
Вниз
HWND_BROADCAST и RegisterWindowMessage Найти похожие ветки
← →
NAlexey © (2004-01-15 12:20) [0]Необходимо отослать сообщение в которое вложить строку уже запущенному приложению, например из второго запущенного. Делаю:
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 12:22) [1]Всмысле конечноже строка
Str := PChar(wParam);
на самом деле строкаStr := PChar(lParam);
← →
Nikolay M. © (2004-01-15 12:48) [2]1) Как именно не получается?
2)
> переопределяю WndProc
???
Зачем? Message methods в хелпе не пробовал смотреть?
3) Попробуй не SendMessage, а PostMessage.
← →
Digitman © (2004-01-15 12:50) [3]
> Нужно ли использовать WM_COPYDATA?
если не принимать никаких иных мер по обеспечению глобальной доступности рассылаемых данных, то решение чуть ли не одно - WM_COPYDATA
можно использовать и RegisterWindowMessage(), но перед бродкастом создать MMF с предопределенным (известным всем заинтересованным в получении бродкаст-сообщения приложениям) именем и записать в него рассылаемые данные .... приложение-получатель бродкаст-сообщения открывает MMF c заранее известным именем и считывает оттуда данные
← →
NAlexey © (2004-01-15 12:57) [4]>Digitman © (15.01.04 12:50) [3]
ХМ... Реально использовать WM_COPYDATA совместно с HWND_BROADCAST?
← →
Digitman © (2004-01-15 13:01) [5]
> NAlexey © (15.01.04 12:57) [4]
уточни в MSDN ... я просто не помню... навскидку думаю, что не прокатит это дело... но, в конце-концов, чтобы не городить огород с MMF и пр. можно просто отказаться от HWND_BROADCAST-опции и разослать последовательно всем нужным окнам WM_COPYDATA - сообщение, перечислив перед этим целевые окна с пом. EnumWindows[Ex]
← →
NAlexey © (2004-01-15 13:21) [6]>Digitman ©
Спасибо.
← →
NAlexey © (2004-01-15 14:20) [7]Что то запутался опять, никак не соображу. Задача такая: необходимо послать в другое приложение(свое) строку, которую оно обработает и в зависимости от этого ответит. Так вот не могу этого реализовать. Отсылаю сообщениие WM_COPYDATA, приложение его получает, обрабатывает, но как ответить? Внутри обработки WM_COPYDATA не получается ничего сделать, ни сообщения отослать, ни даже почемуто Halt(0) не работает. Может я чего не так делаю?
← →
NAlexey © (2004-01-15 14:27) [8]Ээээ... Все, решение найдено.
← →
MBo © (2004-01-15 14:28) [9]Msg.Result можно задать - это вернется как результат SendMessage
← →
Digitman © (2004-01-15 14:31) [10]
> Внутри обработки WM_COPYDATA не получается ничего сделать,
> ни сообщения отослать, ни даже почемуто Halt(0) не работает.
а кому отсылать-то ? чтобы послать окну сообщение, нужно знать хэндл окна, а приложение-приемник об этом ничего не знает ... приложение-передатчик должно само позаботиться об информировании приложения-приемника о том, хендл какого конкретно окна следует использовать для отправки ответа... пусть приложение-передатчик всместе с данными, посылаемыми по бродкасту (или обычным образом), передает и хендл некоего своего окна для приема ответа/ответов
Halt-то зачем ? поясни ...
и вообще - приведи-ка свой код обработки WM_COPYDATA ... что-то ты там намудрил, наверно ...
← →
Digitman © (2004-01-15 14:34) [11]
> MBo
в случае с WM_COPYDATA, как следует из док-ции, вернуть произвольный код возврата не удастся ... только ДА (обработано) или НЕТ (не обработано) ... хотя шут его знает, что можно вернуть под "соусом" True-результата ... но можно проверить)
← →
NAlexey © (2004-01-15 14:50) [12]>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);
?
← →
NAlexey © (2004-01-15 14:51) [13]Да, вместо WMB_INSTANCE_EXISTS и B_INSTANCE_EXISTS - MyMessage. Тороплюсь, время поджимает...
← →
Digitman © (2004-01-15 14:56) [14]
> NAlexey © (15.01.04 14:51) [13]
я понял
но если тебе требуется логика организации работы только одного экз-ра твоего приложения, то весь этот геморрой с сообщениями совершенно ни к чему ... существуют гораздо простые/изящные и эффективные решения, использующие, например, технологии и механизмы глобальных ОС-объектов, таких как mutex, atom и т.п.
← →
NAlexey © (2004-01-15 14:59) [15]>Digitman ©
Нет, дело не в этом. Приложение логинится с определенным паролем, который хранится на протяжении сесси. Надо запрещать запускать 2 приложения на одной машине с одинаковым паролем.
← →
MBo © (2004-01-15 15:00) [16]>Digitman © (15.01.04 14:34) [11]
Проверил - срабатывает
>NAlexey
Есть все же сомнения по поводу рассылки WM_COPYDATA бродкастно. Ведь если найдется окно, которое тоже ждет WM_COPYDATA, то в его обработчике освободятся внутренние структуры ОС (MMF), хранящие тело посылки. Что будет потом - неясно
кроме того, может быть, ответ посылать PostMessage вместо Send?
При тесте у меня deadlock-а не было, но, как мне кажется, он не исключен...
← →
NAlexey © (2004-01-15 15:11) [17]>MBo ©
Хм... Придется переделать как советовал Digitman © (15.01.04 13:01) [5].
← →
Digitman © (2004-01-15 15:21) [18]
> Надо запрещать запускать 2 приложения на одной машине с
> одинаковым паролем
ну вот для этой цели MMF как раз - оч простое и стабильное решение
каждый экз-р стартующего приложения пытается создать именованый MMF
если создание прошло успешно, то это - первый экз-р ... после создания в MMF-структуре инкрементируется некий сч-к и фиксируется пароль
если создание прошло с признаком ERROR_ALREADY_EXISTS, то анализируется значение сч-ка : если он = 1 и пароль тот же, то - инкремент, иначе если пароль иной - инкремент сч-ка, ассоциированного с паролем, иначе - до свидания и Terminate
← →
NAlexey © (2004-01-15 15:32) [19]>Digitman © (15.01.04 15:21) [18]
К сожалению недостаточно хорошо знаком с этой темой, требуется некоторое время для реализации, его нет.
← →
Digitman © (2004-01-15 15:58) [20]
> недостаточно хорошо знаком с этой темой
ты просто обрати внимание и изучи детально описания всего пары ф-ций : Createfilemapping() и MapViewOfFile() ... это практически все что тебе нужно для реализации задачи ср-вами MMF
← →
NAlexey © (2004-01-15 16:09) [21]Digitman ©
Ok
Страницы: 1 вся ветка
Форум: "WinAPI";
Текущий архив: 2004.03.28;
Скачать: [xml.tar.bz2];
Память: 0.5 MB
Время: 0.031 c