在Delphi中访问和继承其他Windows消息的Windows消息 [英] Accessing and inheriting Windows Message for other Windows Message in Delphi

查看:110
本文介绍了在Delphi中访问和继承其他Windows消息的Windows消息的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用WMSysCommand消息来修改标题栏按钮(最大化/最小化)behaivor,并且要求使用WMNCHitTest进行最近的更新,但是由于冗长的代码,我不想在乘法过程中拆分这两个相关的消息.

I am using WMSysCommand messages to modify Caption bar button ( Maximize / Minimize ) behaivor and recent update requiered to use WMNCHitTest, but I do not want to split these two related messages in multiplie procedures because of lengthy code.

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

Can I access private declaration ( message ) from other message? And if I can - How to do it?

  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 ...我认为正确和简单地不知道正确的命令,还是我认为总的牛逼* t?

Soo ... do I think correctly and sipmly do not know correct commands or I am thinking total bullsh*t?

关于.感谢您的帮助...

Regards. Thanks for any help...

推荐答案

您的代码和文本表明您对消息处理程序的工作方式有一些误解.首先,您询问有关访问私人消息处理程序的信息.您不需要从父类访问私有消息处理程序.您可以覆盖任何消息的处理程序,而不管父类是否处理该消息.只需编写您的消息处理程序即可.即使父级的处理程序是私有的,它也会自动覆盖父级的处理程序. (实际上,这就是为什么我们通常首先声明消息处理程序为私有的原因-后代始终可以覆盖它们,并且由于没有理由直接调用一个消息处理程序,因此没有理由将其公开.)

Your code and text suggest you have several misunderstandings about how message handlers work. First, you ask about accessing private message handlers. You don't need access to private message handlers from parent classes. You can override the handler of any message, regardless of whether the parent class handles that message. Just write your message handler. It will automatically override the parent's handler, even if the parent's handler was private. (In fact, that's why we often declare message handlers private in the first place — descendants can always override them, and since there's no reason to call one directly, there's no reason to make it public.)

您似乎正在尝试通过调用DefaultHandler来获取基类的消息处理行为.这有时会起作用,但只是偶然. DefaultHandler转到基类的消息处理程序.如果基类和您的后代之间还有其他类,则对DefaultHandler的调用将跳过其处理程序.代替该功能,使用inherited指令,就像覆盖普通方法时一样.

It looks like you're trying to get the base class's message-handling behavior by calling DefaultHandler. That will work sometimes, but only by accident. DefaultHandler goes to the base class's message handler. If there are other classes in between the base class and your descendant, a call to DefaultHandler will skip their handlers. Instead of that function, use the inherited directive, just like you would when overriding ordinary methods.

当您希望对象的行为就像 一样,已经发送了一条消息给您时,您不必总是使用SendMessage向其发送消息.相反,您可以调用对象的Perform方法.所有相同的消息发送操作都将发生,但是您可以跳过Windows消息队列.

When you want your object to behave as if a message had been sent to it, you don't always have to send it a message with SendMessage. Instead, you can call the object's Perform method. All the same message-dispatch operations will occur, but you can skip the Windows message queue.

如果您有两种应该执行许多相似任务的方法,则有几种选择:

If you have two methods that should perform many similar tasks, you have a few options:

  1. 复制并粘贴代码,以使两个功能看起来相似.
  2. 将所有代码放入一个函数中,然后从第二个函数中调用它.
  3. 将所有代码放入一个新的第三个函数中,然后从这两个函数中调用它.

第一个选择通常不是一个好主意.如果第一个功能被保证始终是第二个功能的子集,则第二个选项可能很好.但是,如果需要执行第二个函数并不总是想要的事情,那么从第二个函数调用它是不合适的.第三种选择是 Robert's答案建议.

The first option isn't usually a good idea. The second option can be good if the first function is guaranteed to always be a subset of the second function. If it needs to do something that the second function won't always want, though, then it's not appropriate to call it from the second function. The third option is what Robert's answer suggests.

如果我的水晶球工作正常,则第二个选项可能是您需要的.我认为您希望wm_SysCommand处理程序进行某些命中测试,因此您想调用wm_NCHitTest消息处理程序.很简单.

The second option might be what you need, if my crystal ball is working properly. I think you wish for your wm_SysCommand handler to do some hit testing, so you want to call the wm_NCHitTest message handler. That's easy.

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.

Notice a few changes I made to your code. First, I use Perform to invoke the object's wm_NCHitTest handler, and I store the result in a variable. I use that variable in the next conditions to check where the mouse was clicked. Second, I removed the or tests from your conditionals. You were combining the named constants with their numeric equivalents, which is pointless and confusing. Third, I replaced the DefaultHandler call with one to inherited.

但是要当心:wm_SysCommand消息是为 keyboard 消息以及鼠标消息发送的.永远不会有有效的命中测试.您可能正在错误地处理此sys-command处理程序,但是很难告诉您真正要执行的操作.

Beware, though: The wm_SysCommand message is sent for keyboard messages as well as mouse messages. There won't always be a valid hit test. You're probably going about this sys-command handler all wrong, but it's hard to tell what you're really after.

这篇关于在Delphi中访问和继承其他Windows消息的Windows消息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆