-
ТимоховД (11.03.13 15:23) [0]Здравствуйте!
(возможно вопрос может показаться по контролам, но имхо это по WinAPI)
Ситуация.
1. Есть контролы TMyEdit и TMyGrid (контролы моей разработки).
2. В TMyEdit есть некий код, который срабатывает при обработке CM_EXIT (суть кода - проверка корректности ввода).
Сценарий в хронологическом порядке:
1. Пользователь вводил в TMyEdit что-то.
2. Кликнул на TMyGrid.
3. Контролу TMyEdit пришло сообщение CM_EXIT.
4. Потом проходит контролу TMyGrid сообщение WM_LBUTTONDOWN.
ВОПРОС
1. Если в ходе обработки CM_EXIT (шаг 3 из сценария выше) я пошлю через PostMessage свое сообщение (WM_USER + 200) контролу TMyGrid, то можно ли гарантировать, что порядок обработки сообщений в TMyGrid будет такой: сначала WM_LBUTTONDOWN, а потом мое сообщение?
2. Проще говоря - гарантирован ли порядок обработки POST-сообщений в контроле?
Спасибо. -
Dimka Maslov © (12.03.13 09:17) [1]SendMessage непосредственно вызывает функцию окна. Дельфийские сообщения работают через Perform, т.е. тоже сразу вызывают функцию окна.
PostMessage добавляет сообщение в очередь, таким образом, чтобы это сообщение гарантированно было обработано не раньше чем закончится обработка текущего сообщения.
Сообщения пользовательского ввода добавляются с очередь сообщений. Таким образом СM_EXIT уже есть реакция на WM_LBUTTONDOWN, а значит WM_USER + 200 из обработчика CM_EXIT придёт гарантированно позже WM_LBUTTONDOWN. А вообще есть такая програ Spy++ называется, показывает помимо всего прочего все сообщения приходящие в выбранное окно. (кроме CM_xxxx, которые вообще не сообщения с точки зрения венды) -
Игорь Шевченко © (13.03.13 14:23) [2]Dimka Maslov © (12.03.13 09:17) [1]
> (кроме CM_xxxx, которые вообще не сообщения с точки зрения
> венды)
Если эти сообщения проходят через оконную процедуру, они тоже показываются.
ТимоховД (11.03.13 15:23)
> Проще говоря - гарантирован ли порядок обработки POST-сообщений
> в контроле?
У сообщений в очереди есть приоритет, насколько я помню, пользовательские сообщения и сообщения мыши по этому признаку не отличаются. У Рихтера про приоритеты подробно описано.
Для своих программ могу рекомендовать способ перехвата всех сообщений, в том числе и посланных через Perform перекрытием свойства WindowProc у TControl
где-то так, для идеи:unit HSControlMessagePumpHook;
interface
uses
HSObjectList, Controls, Messages;
type
THSControlMessagePumpHook = class
private
FControl: TControl;
FOldWndProc: TWndMethod;
procedure HookWndProc (var Message: TMessage);
public
constructor Create (AControl: TControl);
end;
THSControlMessagePumpHookList = class(THSObjectList)
end;
const
EnableMsgHook = true;
implementation
uses
Windows, SysUtils, MessageLogger;
{ THSControlMessagePumpHook }
constructor THSControlMessagePumpHook.Create(AControl: TControl);
begin
FControl := AControl;
FOldWndProc := FControl.WindowProc;
FControl.WindowProc := HookWndProc;
end;
procedure THSControlMessagePumpHook.HookWndProc(var Message: TMessage);
begin
if Assigned(FControl) and (FControl is TWinControl) and
TWinControl(FControl).HandleAllocated then
LogMessage(Format('%s.WndProc', [FControl.Name]),
TWinControl(FControl).Handle, Message.Msg,
Message.WParam, Message.LParam)
else
LogMessage(Format('%s.WndProc', [FControl.Name]),
0, Message.Msg,
Message.WParam, Message.LParam);
FOldWndProc(Message);
LogMsgReturn(Format('%s.WndProc', [FControl.Name]), Message);
end;
end.
и применяемость:type
TMyForm = class(TForm)
....
private
FHooks: THSControlMessagePumpHookList;
.....
public
....
procedure Loaded; override;
end;
procedure TMyForm.Loaded;
begin
inherited;
FHooks := THSControlMessagePumpHookList.Create;
FHooks.Add(THSControlMessagePumpHook.Create(Self));
FHooks.Add(THSControlMessagePumpHook.Create(ScrollBox));
....
все нужные компоненты, чьи сообщения интересны
end; -
Dimka Maslov © (13.03.13 17:22) [3]
> Если эти сообщения проходят через оконную процедуру, они
> тоже показываются.
Обычно они идут через метод Perform и не показываются в Spy++. Но если традиционными способами послать - тогда да. -
ТимоховД (14.03.13 10:11) [4]Коллеги, спасибо за комментарии.
Про Рихтера потом уже вспомнил.
Разобрался в вопросе.
Игорь, хороший пример. Каждый раз вспоминаю, когда надо, как перехватывать. Буду пользоваться. -
ТимоховД (14.03.13 10:11) [5]Коллеги, спасибо за комментарии.
Про Рихтера потом уже вспомнил.
Разобрался в вопросе.
Игорь, хороший пример. Каждый раз вспоминаю, когда надо, как перехватывать. Буду пользоваться.