Текущий архив: 2003.07.07;
Скачать: CL | DM;
Вниз
Multiwindow Application on WinAPI Найти похожие ветки
← →
NewN (2003-05-05 09:02) [0]Здравствуйте, мастера!
Дайте пожалуйста совет, или ссылку, как реализуется диспатчинг сообщений для многооконного (но не MDI) приложения.
← →
Игорь Шевченко (2003-05-05 10:23) [1]GetMessage
TranslateMessage
DispatchMessage
← →
NewN (2003-05-05 10:41) [2]Игорь Шевченко © (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;
← →
NewN (2003-05-05 10:48) [3]Набирал по памяти, поэтому ошибки допустил. Вот, исправил что заметил
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;
← →
Игорь Шевченко (2003-05-05 10:50) [4]А почему бы не взять любой нормальный пример для обработки сообщений ? Или хотя бы посмотреть исходники VCL ?
В них везде один цикл для обработки сообщений всем окнам. Сама структура MSG содержит в себе Handle того окна, которому этот Message предназначен, и DispatchMessage вызывает оконную процедуру именно того окна, которому пришло сообщение.
← →
NewN (2003-05-05 11:18) [5]Да, про исходники 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 11:46) [6]while GetMessage(msg, 0, 0, 0) do begin
TranslateMessage(msg);
DispatchMessage(msg);
end;
И все :)
GetMessage тоже не привязана к отдельному окну, GetMessage, как и PeekMessage привязаны к очереди сообщений конкретного потока.
← →
NewN (2003-05-06 08:02) [7]Всё оказалось замечательно просто, работает "на ура" с нулём вместо хэндела. Признаюсь, ступил основательно с этим вопросом. Но спасибо, спасибо всем, кто удостоил вниманием мою скромную персону. Засим прощаюсь, с почтением, уважаемые Мастера Delphi.
До следующего вопроса! :-)
Страницы: 1 вся ветка
Текущий архив: 2003.07.07;
Скачать: CL | DM;
Память: 0.46 MB
Время: 0.006 c