Ваш код и текст указывают на то, что у вас есть некоторые недопонимания о том, как работают обработчики сообщений. Во-первых, вы спрашиваете о доступе к обработчикам личных сообщений. Вам не нужен доступ к обработчикам личных сообщений из родительских классов. Вы можете переопределить обработчик любого сообщения, независимо от того, обрабатывает ли это сообщение родительский класс. Просто напишите свой обработчик сообщений. Он автоматически переопределит родительский обработчик, даже если родительский обработчик был закрытым. (На самом деле, именно поэтому мы часто объявляем обработчики сообщений закрытыми в первую очередь — потомки всегда могут их переопределить, а поскольку нет причин вызывать их напрямую, нет причин и делать их общедоступными.)
Похоже, вы пытаетесь получить поведение обработки сообщений базового класса, вызывая DefaultHandler
. Иногда это срабатывает, но только случайно. DefaultHandler
переходит к обработчику сообщений базового класса. Если между базовым классом и вашим потомком есть другие классы, вызов DefaultHandler
пропустит их обработчики. Вместо этой функции используйте директиву inherited
, как при переопределении обычных методов.
Если вы хотите, чтобы ваш объект вел себя как если бы ему было отправлено сообщение, вам не всегда нужно отправлять ему сообщение с SendMessage
. Вместо этого вы можете вызвать метод Perform
объекта. Будут выполняться все те же операции отправки сообщений, но вы можете пропустить очередь сообщений Windows.
Если у вас есть два метода, которые должны выполнять много похожих задач, у вас есть несколько вариантов:
- Скопируйте и вставьте код, чтобы обе функции выглядели одинаково.
- Поместите весь код в одну функцию, а затем вызовите ее из второй функции.
- Поместите весь код в новую, третью функцию, а затем вызовите ее из обеих функций.
Первый вариант обычно не является хорошей идеей. Второй вариант может быть хорош, если гарантировано, что первая функция всегда будет подмножеством второй функции. Однако, если ей нужно сделать что-то, чего вторая функция не всегда хочет, то не следует вызывать ее из второй функции. Третий вариант — это то, что Роберта ответ предполагает.
Второй вариант может быть тем, что вам нужно, если мой хрустальный шар работает правильно. Я думаю, вы хотите, чтобы ваш обработчик wm_SysCommand выполнял проверку попадания, поэтому вы хотите вызвать обработчик сообщений wm_NCHitTest
. Это легко.
procedure TForm1.WMSysCommand;
var
Hit: DWord;
begin
Hit := Perform(wm_NCHitTest, ...);
if (Msg.CmdType = SC_MAXIMIZE) or (Hit = htCaption) then // if command is Maximize or reciever message of Caption Bar click
begin
if CheckWin32Version(6, 0) then
Constraints.MaxHeight := 507
else
Constraints.MaxHeight := 499;
Constraints.MaxWidth := 0;
end
else if (Msg.CmdType = SC_MINIMIZE) or (Hit = htCaption) then // if command is Minimize
begin
if (EnsureRange(Width, 252, 510) >= (510 / 2)) then
PreviewOpn.Caption := '<'
else
PreviewOpn.Caption := '>';
end;
inherited;
end;
Обратите внимание на несколько изменений, которые я внес в ваш код. Во-первых, я использую Perform
для вызова обработчика wm_NCHitTest объекта и сохраняю результат в переменной. Я использую эту переменную в следующих условиях, чтобы проверить, где была нажата мышь. Во-вторых, я удалил or
тестов из ваших условий. Вы комбинировали именованные константы с их числовыми эквивалентами, что бессмысленно и сбивает с толку. В-третьих, я заменил вызов DefaultHandler
на вызов inherited
.
Однако будьте осторожны: сообщение wm_SysCommand отправляется как для сообщений клавиатуры, так и для сообщений мыши. Не всегда будет действительный тест на попадание. Вы, вероятно, ошибаетесь в этом обработчике sys-команд, но трудно сказать, что вам действительно нужно.
person
Rob Kennedy
schedule
14.06.2010