В вашем коде и тексте предлагается несколько недоразумений о том, как работают обработчики сообщений. Сначала вы спрашиваете о доступе к личным обработчикам сообщений. Вам не нужен доступ к личным обработчикам сообщений из родительских классов. Вы можете переопределить обработчик любого сообщения, независимо от того, обрабатывает ли этот класс родительский класс. Просто напишите свой обработчик сообщений. Он автоматически переопределит обработчик родителя, даже если обработчик родителя был закрыт. (На самом деле, поэтому мы часто объявляем, что обработчики сообщений являются частными в первую очередь - потомки всегда могут их переопределять, и поскольку нет причин для прямого вызова, нет никаких оснований публиковать его.)
Похоже, вы 'пытаюсь получить поведение обработки сообщений базового класса, вызвав DefaultHandler
. Это будет работать иногда, но только случайно. DefaultHandler
отправляется в базовый класс обработчик сообщения. Если между базовым классом и вашим потомком существуют другие классы, вызов DefaultHandler
пропустит их обработчики. Вместо этой функции используйте директиву inherited
, как и при переопределении обычных методов.
Если вы хотите, чтобы ваш объект действовал , как будто было отправлено какое-то сообщение, вам не всегда нужно отправлять ему сообщение с SendMessage
. Вместо этого вы можете вызвать метод объекта Perform
. Все те же операции отправки сообщений будут происходить, но вы можете пропустить очередь сообщений Windows.
Если у вас есть два метода, которые должны выполнять множество подобных задач, у вас есть несколько вариантов:
- Скопируйте и вставьте код, чтобы обе функции выглядят одинаково.
- Поместите весь код в одну функцию, а затем вызовите его из второй функции.
- Поместите весь код в новую, третью функцию, а затем вызовите ее из обеих функций.
Первый вариант обычно не является хорошей идеей. Второй вариант может быть хорошим, если первая функция гарантировала всегда быть подмножеством второй функции. Если ему нужно сделать что-то, что вторая функция не всегда будет хотеть, однако, нецелесообразно вызывать ее из второй функции. Третий вариант - это то, что предлагает Robert's answer.
Второй вариант может быть тем, что вам нужно, если мой хрустальный шар работает правильно. Я думаю, что вы хотите, чтобы ваш обработчик 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-команд, но сложно сказать, что вы на самом деле после.
Похоже на вопрос, который вы должны были задать: * Как изменить поведение кнопок кнопок заголовка? * –
Wll - не exeatly. Самое подходящее - как имитировать WM с другой процедуры WM ... »«, но я не набрал его, поскольку он в каком-то смысле взломает предопределения OS behaivor ... не стоит рисковать с серьезными разговорами с модераторами здесь. –