Recent

Author Topic: [CLOSED] How to capture messages sent to the parent form of a TComponent  (Read 5239 times)

Remy Lebeau

  • Hero Member
  • *****
  • Posts: 1312
    • Lebeau Software
Re: How to capture messages sent to the parent form of a TComponent
« Reply #15 on: October 15, 2021, 07:20:13 pm »
fNotifyIcon needs the form handle.

Only because TMyTrayApp is not creating its own HWND.  That is my point, it SHOULD be creating its own HWND, then it can use that HWND for fNotifyIcon.hWnd and thus be able to receive WM_USER + uIDTrayIcon messages directly from the OS without involving the parent Form at all.

Delphi has an AllocateHWnd() function for exactly this purpose.  I don't know what FreePascal's equivalent is, and I can't find TTimer's source code to check.  You will likely have to call the Win32 CreateWindow/Ex() function directly.  See Receive and Handle Windows Messages in Lazarus on StackOverflow for an example.
« Last Edit: October 15, 2021, 07:33:02 pm by Remy Lebeau »
Remy Lebeau
Lebeau Software - Owner, Developer
Internet Direct (Indy) - Admin, Developer (Support forum)

pcurtis

  • Hero Member
  • *****
  • Posts: 951
Re: How to capture messages sent to the parent form of a TComponent
« Reply #16 on: October 15, 2021, 10:44:26 pm »
Ok. This works. Thanks.

Code: Pascal  [Select][+][-]
  1. unit MyTrayApp;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, LResources, LCLIntf, Forms, Controls, Graphics, Dialogs, ExtCtrls,
  9.   StdCtrls, ComCtrls, Windows, ShellAPI, LazUTF8;
  10.  
  11. const
  12.   uIDTrayIcon = 25;
  13.   WM_ICONTRAY = WM_USER + uIDTrayIcon;
  14.  
  15. type
  16.  
  17.   TNotifyIconDataW2 = record
  18.     cbSize: DWORD;
  19.     hWnd: HWND;
  20.     uID: UINT;
  21.     uFlags: UINT;
  22.     uCallbackMessage: UINT;
  23.     hIcon: HICON;
  24.     szTip: array [0..127] of WideChar;
  25.     dwState: DWORD;
  26.     dwStateMask: DWORD;
  27.     szInfo: array [0..255] of WideChar;
  28.     u: record
  29.          case longint of
  30.            0 : ( uTimeout : UINT );
  31.            1 : ( uVersion : UINT );
  32.           end;
  33.     szInfoTitle: array[0..63] of WideChar;
  34.     dwInfoFlags: DWORD;
  35.   end;
  36.  
  37.  
  38.   { TMyTestComponent }
  39.  
  40.   TMyTrayApp = class(TComponent)
  41.   private
  42.     fNotifyIcon : TNotifyIconDataW2;
  43.     fHWND : HWND;
  44.   protected
  45.  
  46.   public
  47.     constructor Create(AOwner : TComponent); override;
  48.     destructor Destroy; override;
  49.     function AddIcon : Boolean;
  50.     procedure WndProc(var Msg: TMessage);
  51.   published
  52.  
  53.   end;
  54.  
  55. procedure Register;
  56.  
  57. var
  58.   fPrevWndProc : WndProc;
  59.  
  60. implementation
  61.  
  62. //{$R myselectdialog.res}
  63.  
  64. function WideStrLCopy(dest, source: PWideChar; maxlen: SizeInt): PWideChar;
  65. var
  66.   counter: SizeInt;
  67. begin
  68.   counter := 0;
  69.  
  70.   while (Source[counter] <> #0)  and (counter < MaxLen) do
  71.   begin
  72.     Dest[counter] := Source[counter];
  73.     Inc(counter);
  74.   end;
  75.  
  76.   Dest[counter] := #0;
  77.   Result := Dest;
  78. end;
  79.  
  80. constructor TMyTrayApp.Create(AOwner : TComponent);
  81. begin
  82.   inherited Create(AOwner);
  83.   fHWND := AllocateHWnd(@WndProc);
  84.   if not (csDesigning in ComponentState) then
  85.     begin
  86.       AddIcon;
  87.     end;
  88. end;
  89.  
  90. destructor TMyTrayApp.Destroy;
  91. begin
  92.   Shell_NotifyIconW(NIM_DELETE, @fNotifyIcon);
  93.   DeallocateHWnd(fHWND);
  94.   inherited;
  95. end;
  96.  
  97. procedure TMyTrayApp.WndProc(var Msg: TMessage);
  98. begin
  99.   if Msg.msg = WM_ICONTRAY then
  100.     begin
  101.       case Msg.lParam of
  102.         WM_LBUTTONDOWN : begin
  103.                            (Self.Owner as TForm).Show;
  104.                          end;
  105.         WM_RBUTTONDOWN : begin
  106.                            (Self.Owner as TForm).Hide;
  107.                          end;
  108.       end;
  109.     end;
  110. end;
  111.  
  112. function TMyTrayApp.AddIcon : Boolean;
  113. var
  114.   WideBuffer: widestring;
  115. begin
  116.   FillChar(fNotifyIcon, SizeOf(fNotifyIcon), 0);
  117.   fNotifyIcon.cbSize := SizeOf(fNotifyIcon);
  118.   fNotifyIcon.hWnd := fHWND;
  119.   fNotifyIcon.uID := uIDTrayIcon;
  120.   fNotifyIcon.uFlags := NIF_MESSAGE or NIF_ICON;
  121.   fNotifyIcon.uFlags := fNotifyIcon.uFlags or NIF_TIP;
  122.   fNotifyIcon.uCallbackMessage := WM_USER + uIDTrayIcon;
  123.   fNotifyIcon.hIcon := Application.Icon.Handle;
  124.  
  125.   WideBuffer := UTF8ToUTF16('TrayIconHint');
  126.   WideStrLCopy(@fNotifyIcon.szTip, PWideChar(WideBuffer), 127);
  127.  
  128.   Result := Shell_NotifyIconW(NIM_ADD, @fNotifyIcon);
  129. end;
  130.  
  131. procedure Register;
  132.  
  133. begin
  134.   RegisterComponents('Misc',[TMyTrayApp]);
  135. end;
  136.  
  137. end.
  138.  
Windows 10 20H2
Laz 2.2.0
FPC 3.2.2

 

TinyPortal © 2005-2018