![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Multiwindow Application on ;WinAPI [D5, Win95/98, WinXP]
NewN © (2003-05-05 09:02:00)Здравствуйте, мастера!
Дайте пожалуйста совет, или ссылку, как реализуется диспатчинг сообщений для многооконного (но не MDI) приложения.
NewN (2003-05-06 08:02:00) [1]Всё оказалось замечательно просто, работает "на ура" с нулём вместо хэндела. Признаюсь, ступил основательно с этим вопросом. Но спасибо, спасибо всем, кто удостоил вниманием мою скромную персону. Засим прощаюсь, с почтением, уважаемые Мастера Delphi.
До следующего вопроса! :-)
Игорь Шевченко (2003-05-05 11:46:00) [2]while GetMessage(msg, 0, 0, 0) do begin
TranslateMessage(msg);
DispatchMessage(msg);
end;
И все :)
GetMessage тоже не привязана к отдельному окну, GetMessage, как и PeekMessage привязаны к очереди сообщений конкретного потока.
NewN (2003-05-05 11:18:00) [3]Да, про исходники VCL я как то запамятовал, напомнили.
Результаты раскопок:
function TApplication.ProcessMessage: Boolean;
var
Handled: Boolean;
Msg: TMsg;
begin
Result := False;
if PeekMessage(Msg, 0, 0, 0, PM_REMOVE)then
begin
Result := True;
if Msg.Message <> WM_QUIT then
begin
Handled := False;
if Assigned(FOnMessage) then FOnMessage(Msg, Handled);
if not IsHintMsg(Msg) and not Handled and not IsMDIMsg(Msg) and
not IsKeyMsg(Msg) and not IsDlgMsg(Msg) then
begin
TranslateMessage(Msg);
DispatchMessage(Msg);
end;
end
else
FTerminate := True;
end;
end;
т.е. вместо GetMessage следует использовать PeekMessage, которая не привязана к конкректному окну. К сожалению сейчас не могу проверить, т.к. кода под руками нет, прошу сказать лишь, на верном ли пути я?
Игорь Шевченко (2003-05-05 10:50:00) [4]А почему бы не взять любой нормальный пример для обработки сообщений ? Или хотя бы посмотреть исходники VCL ?
В них везде один цикл для обработки сообщений всем окнам. Сама структура MSG содержит в себе Handle того окна, которому этот Message предназначен, и DispatchMessage вызывает оконную процедуру именно того окна, которому пришло сообщение.
NewN (2003-05-05 10:48:00) [5]Набирал по памяти, поэтому ошибки допустил. Вот, исправил что заметил
procedure Run(WindowHandles: array of HWND);
var
min, max, i: Integer;
b,
bb: Bool;
Message: TMsg;
begin
min:= Low(WindowHandles);
max:= High(WindowHandles);
bb:= True;
while bb do
begin
bb:= False;
for i:= min to max do
begin
b:= GetMessage(Message, WindowHandles[i], 0, 0);
if b and Integer(b) <> - 1 then
begin
TranslateMessage(Message);
DispatchMessage(Message);
bb:= True;
end;
end;
end;
end;
NewN (2003-05-05 10:41:00) [6]Игорь Шевченко © (05.05.03 10:23)
Я так и делаю, но когда пытаюсь так в цикле для двух окон, то непонятные глюки (щёлкаешь мышкой по заголовку первого окна, второе само меняет координаты свои), и страшные тормоза (перерисовка за минуту, на кнопки не нажимается), хотя для каждого окна по отдельности такой же цикл нормально работает, а я не понимаю почему, ну в два раза медленнее пускай сообщения отрабатываются, но не на столько же?
Вот мой код:
procedure Run(WindowHandles: array of HWND);
var
min, max, i: Integer;
b,
bb: Bool;
begin
min:= Low(WindowHandles);
max:= Low(WindowHandles);
bb:= True;
while bb do
begin
bb:= False;
for i:= min to max do
begin
b:= GetMessage(Message, WindowHandles[i], 0, 0);
if b and Integer(b) <> - 1 then
begin
TranslateMessage(Message);
DispatchMessage(Message);
bb:= True;
end;
end;
end;
end;
Игорь Шевченко (2003-05-05 10:23:00) [7]GetMessage
TranslateMessage
DispatchMessage