zoukankan      html  css  js  c++  java
  • How a non-windowed component can receive messages from Windows -- AllocateHWnd

    http://www.delphidabbler.com/articles?article=1

    Why do it?

    Sometimes we need a non-windowed component (i.e. one that isn't derived fromTWinControl) to receive Windows messages.

    To receive messages the component needs a window handle, but a non-windowed component hasn't got one!

    This article is about how to enable such a component to use a hidden window to receive messages.

    How it's done

    The Delphi library function AllocateHWnd is used to create a hidden window for us

    and the related DeallocateHWnd disposes of the window when we've finished with it.

    The hidden window requires window procedure.

    AllocateHWnd enables us to use a method as a window procedure where Windows normally requires a stdcall function.

    We pass a reference to the required method to AllocateHWnd and

    it takes care of the problem of registering the method as a window procedure for us.

    Inside the registered method we handle the messages we are interested in

    and hand the rest off to Windows using the DefWindowProc API call.

    Listing 2 below provides a skeleton of how to use AllocateHWnd.

    First though, Listing 1shows an outline definition for our component class:

    type
      { Our class derived from TComponent 
        or another ancestor class }
      TMyClass = class(TComponent)
      private
        fHWnd: HWND;
          { field to store the window handle }
        ...
      protected
        procedure WndMethod(var Msg: TMessage); virtual;
          { window proc - called by Windows to handle 
            messages passed to our hidden window }
        ...
      public
         constructor Create(AOwner: TComponent); override;
           { create hidden window here: store handle in fHWnd}
         destructor Destroy; override;
           { free hidden window here }
         ...
      end;

    And here are the implementation details:

    constructor TMyClass.Create(AOwner: TComponent);
    begin
      inherited Create(AOwner);
      ...
      // Create hidden window using WndMethod as window proc
      fHWnd := AllocateHWnd(WndMethod);
      ...
    end;
    
    destructor TMyClass.Destroy;
    begin
      ...
      // Destroy hidden window
      DeallocateHWnd(fHWnd);
      ...
      inherited Destroy;
    end;
    
    procedure TMyClass.WndMethod(var Msg : TMessage);
    var
      Handled: Boolean;
    begin
      // Assume we handle message
      Handled := True;
      case Msg.Msg of
        WM_SOMETHING: DoSomething;
          // Code to handle a message
        WM_SOMETHINGELSE: DoSomethingElse;
          // Code to handle another message
        // Handle other messages here
        else
          // We didn't handle message
          Handled := False;
      end;
      if Handled then
        // We handled message - record in message result
        Msg.Result := 0
      else
        // We didn't handle message
        // pass to DefWindowProc and record result
        Msg.Result := DefWindowProc(fHWnd, Msg.Msg,
          Msg.WParam, Msg.LParam);
    end;

    Of course, we could just use the Windows API to create a window the hard way and provide a windows procedure.

    But it is more difficult to use a method as a window procedure if we do it this way.

    The clever features about AllocateHWnd are that

    (a) it creates the hidden window for us and

    (b) it allows us to use a method, rather than a simple procedure,

    as the window procedure – and a method is more useful since it has access to the class's private data.

  • 相关阅读:
    mysql 查询当天、本周,本月,上一个月的数据
    Mysql 查看连接数,状态 最大并发数,以及设置连接数
    MySQL慢查询日志优化
    java中线程通信(传统的线程通信)
    java中死锁
    同步锁(lock)
    同步锁(lock)
    释放同步监视器的锁定(java疯狂讲义)
    linux第9天 UDP
    linux第8天 connect强化
  • 原文地址:https://www.cnblogs.com/shangdawei/p/4015006.html
Copyright © 2011-2022 走看看