Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

HWND_BROADCAST и RegisterWindowMessage


Страницы:   1 2

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.


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо