Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.03.28;
Скачать: CL | DM;

Вниз

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 вся ветка

Текущий архив: 2004.03.28;
Скачать: CL | DM;

Наверх




Память: 0.52 MB
Время: 0.021 c
1-1078413592
Demon_mhm
2004-03-04 18:19
2004.03.28
Конструктор объекта и выделение памяти.


14-1077964876
NailMan
2004-02-28 13:41
2004.03.28
Фотки с MMP(как и обещал вчера)


3-1077876131
Salivan
2004-02-27 13:02
2004.03.28
паковка DBF таблиц из программы


1-1079003717
3asys
2004-03-11 14:15
2004.03.28
Определение компонента, над которым находится курсор мыши.


8-1067257669
Urvin
2003-10-27 15:27
2004.03.28
Размер Экрана и ДиректХ