在Delphi中为其他Windows消息访问和继承Windows消息

在Delphi中为其他Windows消息访问和继承Windows消息,delphi,windows-messages,Delphi,Windows Messages,我正在使用WMSysCommand消息修改标题栏按钮(最大化/最小化)行为和使用WMNCHitTest所需的最新更新,但由于代码太长,我不想在多线程过程中拆分这两条相关消息 我可以从其他消息访问私有声明(消息)吗?如果我能-怎么做 procedure TForm1.WMNCHitTest(var Msg: TWMNCHitTest) ; begin SendMessage(Handle, HTCAPTION, WM_NCHitTest, 0); // or other wPara

我正在使用WMSysCommand消息修改标题栏按钮(最大化/最小化)行为和使用WMNCHitTest所需的最新更新,但由于代码太长,我不想在多线程过程中拆分这两条相关消息

我可以从其他消息访问私有声明(消息)吗?如果我能-怎么做

  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;
程序TForm1.WMNCHitTest(var Msg:TWMNCHitTest);
开始
SendMessage(Handle,HTCAPTION,WM_NCHitTest,0);//或其他wParam或lParam????
结束;
程序TForm1.WMSysCommand;
开始
如果(Msg.CmdType=SC_MAXIMIZE或61488)或(Msg.Result=htCaption或2),则//如果命令为MAXIMIZE或receiver,则单击标题栏的消息
开始
如果选中Win32Version(6,0),则
Constraints.MaxHeight:=507
其他的
Constraints.MaxHeight:=499;
Constraints.MaxWidth:=0;
结束
否则,如果(Msg.CmdType=SC_MINIMIZE或61472)或(Msg.Result=htCaption或2),则//如果命令为MINIMIZE
开始
如果(确保范围(宽度,252510)>=(510/2)),则
预览页标题:='';
结束;
DefaultHandler(Msg);//将消息处理程序重置为默认值(应用程序)
结束;
苏。。。我的想法正确吗?我不知道正确的命令,还是我在胡说八道


问候。感谢您的帮助……

您的代码和文本表明您对消息处理程序的工作方式存在一些误解。首先,您询问如何访问私有消息处理程序。您不需要从父类访问私有消息处理程序。您可以重写任何消息的处理程序,而不管父类是否处理该消息。只需编写消息处理程序。它将自动覆盖父处理程序,即使父处理程序是私有的。(事实上,这就是为什么我们经常首先声明消息处理程序是私有的——后代总是可以覆盖它们,因为没有理由直接调用消息处理程序,也没有理由将其公开。)

看起来您正试图通过调用
DefaultHandler
来获取基类的消息处理行为。这有时会奏效,但只是偶然的
DefaultHandler
转到基类的消息处理程序。如果基类和子类之间还有其他类,则调用
DefaultHandler
将跳过它们的处理程序。使用
继承的
指令代替该函数,就像重写普通方法一样

当您希望对象的行为与已向其发送的消息类似时,您不必总是使用
SendMessage
向其发送消息。相反,您可以调用对象的
Perform
方法。将发生所有相同的消息分派操作,但您可以跳过Windows消息队列

如果您有两种方法可以执行许多类似的任务,那么您有几个选项:

  • 复制并粘贴代码,使两个函数看起来相似
  • 将所有代码放在一个函数中,然后从第二个函数调用它
  • 将所有代码放在新的第三个函数中,然后从两个函数调用它
  • 第一种选择通常不是个好主意。如果保证第一个函数始终是第二个函数的子集,则第二个选项是好的。但是,如果它需要做第二个函数并不总是想要的事情,那么从第二个函数调用它是不合适的。第三种选择就是建议

    如果我的水晶球工作正常,第二个选项可能是您需要的。我认为您希望wm_SysCommand处理程序执行一些命中测试,因此您希望调用
    wm_nchitest
    消息处理程序。那很容易

    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;
    
    程序TForm1.WMSysCommand;
    变量
    击中:德沃德;
    开始
    点击:=执行(wm_NCHitTest,…);
    如果(Msg.CmdType=SC_MAXIMIZE)或(Hit=htCaption),则//如果命令是MAXIMIZE或接收标题栏的消息,请单击
    开始
    如果选中Win32Version(6,0),则
    Constraints.MaxHeight:=507
    其他的
    Constraints.MaxHeight:=499;
    Constraints.MaxWidth:=0;
    结束
    否则,如果(Msg.CmdType=SC_MINIMIZE)或(Hit=htCaption),则//如果命令为MINIMIZE
    开始
    如果(确保范围(宽度,252510)>=(510/2)),则
    预览页标题:='';
    结束;
    继承;
    结束;
    
    请注意我对您的代码所做的一些更改。首先,我使用
    Perform
    调用对象的wm_NCHitTest处理程序,并将结果存储在变量中。我在接下来的条件中使用该变量来检查鼠标单击的位置。其次,我从您的条件中删除了
    测试。您将命名常量与它们的数值等价物组合在一起,这是毫无意义和令人困惑的。第三,我将
    DefaultHandler
    调用替换为继承的
    调用


    不过要注意:wm_SysCommand消息是针对键盘消息和鼠标消息发送的。不会总是有一个有效的命中测试。您可能对这个sys命令处理程序的理解完全错误,但很难说您真正想要的是什么。

    您的代码和文本表明您对消息处理程序的工作方式有一些误解。首先,您询问如何访问私有消息处理程序。您不需要从父类访问私有消息处理程序。您可以重写任何消息的处理程序,而不管父类是否处理该消息。只需编写消息处理程序。它将自动覆盖父处理程序,即使父处理程序是私有的。(事实上,这就是为什么我们经常首先声明消息处理程序是私有的——后代总是可以覆盖它们,因为没有理由直接调用消息处理程序,也没有理由将其公开。)

    看起来您正试图通过调用
    DefaultHandler