2010-06-14 2 views
0

Я использую сообщения WMSysCommand для изменения кнопки Caption bar (Maximize/Minimize) behayivor и недавнего обновления, требуемого для использования WMNCHitTest, но я не хочу разделить эти два связанных сообщения в мультипликационные процедуры из-за длительного кода.Доступ к Windows Message для другого сообщения Windows в Delphi

Могу ли я получить доступ к частной декларации (сообщению) из другого сообщения? И если смогу - как это сделать?

procedure TForm1.WMNCHitTest(var Msg: TWMNCHitTest) ; 
    begin 
    SendMessage(Handle, HTCAPTION, WM_NCHitTest, 0); // or other wParam or lParam ???? 
    end; 

    procedure TForm1.WMSysCommand; 
    begin 
    if (Msg.CmdType = SC_MAXIMIZE or 61488) or (Msg.Result = htCaption or 2) 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 61472) or (Msg.Result = htCaption or 2) then // if command is Minimize 
    begin 
     if (EnsureRange(Width, 252, 510) >= (510/2)) then 
     PreviewOpn.Caption := '<' 
     else 
     PreviewOpn.Caption := '>'; 
    end; 
    DefaultHandler(Msg); // reset Message handler to default (Application) 
    end; 

Soo ... я думаю, что правильно и sipmly не знаю правильные команды или я имею в виду общую Bullsh * т?

С уважением. Спасибо за любую помощь ...

+0

Похоже на вопрос, который вы должны были задать: * Как изменить поведение кнопок кнопок заголовка? * –

+0

Wll - не exeatly. Самое подходящее - как имитировать WM с другой процедуры WM ... »«, но я не набрал его, поскольку он в каком-то смысле взломает предопределения OS behaivor ... не стоит рисковать с серьезными разговорами с модераторами здесь. –

ответ

3

В вашем коде и тексте предлагается несколько недоразумений о том, как работают обработчики сообщений. Сначала вы спрашиваете о доступе к личным обработчикам сообщений. Вам не нужен доступ к личным обработчикам сообщений из родительских классов. Вы можете переопределить обработчик любого сообщения, независимо от того, обрабатывает ли этот класс родительский класс. Просто напишите свой обработчик сообщений. Он автоматически переопределит обработчик родителя, даже если обработчик родителя был закрыт. (На самом деле, поэтому мы часто объявляем, что обработчики сообщений являются частными в первую очередь - потомки всегда могут их переопределять, и поскольку нет причин для прямого вызова, нет никаких оснований публиковать его.)

Похоже, вы 'пытаюсь получить поведение обработки сообщений базового класса, вызвав DefaultHandler. Это будет работать иногда, но только случайно. DefaultHandler отправляется в базовый класс обработчик сообщения. Если между базовым классом и вашим потомком существуют другие классы, вызов DefaultHandler пропустит их обработчики. Вместо этой функции используйте директиву inherited, как и при переопределении обычных методов.

Если вы хотите, чтобы ваш объект действовал , как будто было отправлено какое-то сообщение, вам не всегда нужно отправлять ему сообщение с SendMessage. Вместо этого вы можете вызвать метод объекта Perform. Все те же операции отправки сообщений будут происходить, но вы можете пропустить очередь сообщений Windows.

Если у вас есть два метода, которые должны выполнять множество подобных задач, у вас есть несколько вариантов:

  1. Скопируйте и вставьте код, чтобы обе функции выглядят одинаково.
  2. Поместите весь код в одну функцию, а затем вызовите его из второй функции.
  3. Поместите весь код в новую, третью функцию, а затем вызовите ее из обеих функций.

Первый вариант обычно не является хорошей идеей. Второй вариант может быть хорошим, если первая функция гарантировала всегда быть подмножеством второй функции. Если ему нужно сделать что-то, что вторая функция не всегда будет хотеть, однако, нецелесообразно вызывать ее из второй функции. Третий вариант - это то, что предлагает 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-команд, но сложно сказать, что вы на самом деле после.

+0

Rob: «Если вы хотите, чтобы ваш объект вел себя так, как если бы сообщение было отправлено на него, вам не всегда нужно отправлять ему сообщение с помощью SendMessage. (...)« Но что произойдет, если я его использую? внутри цикла с помощью команды ProcessMessages? Разве это не означает, что Perform() будет фактически действовать как эксклюзивный SendMesssage()? О-и числовые равны просто для меня, чтобы помнить эти проклятые числа для обработки внутренних и внешних исключений и WER-процессов ... На самом деле - я всегда могу проверить код ключа с помощью Ord(), поэтому я не могу это сделать большой вопрос .. –

+0

ProcessMessages не имеет к этому никакого отношения. Выполнить также полезно для вызова обработчиков сообщений на объектах, которые не имеют оконных дескрипторов. –