Advanced Windows API - RegisterShellHook()


For receiving shell notification messages the normal way would be to use the SetWindowsHookEx API function which requires the usage of an external dll file. All this just for receiving shell notification message always is a lot of work. However there is an undocumented windows api function called RegisterShellHook which makes this very easy. All you have to do is call this API function with the handle to the window which should receive shell message notification. Once called your window will receive a WM_SHELLHOOK message in its wndproc (message handler).

The RegisterShellHook() function is exported by shell32.dll. It is definetly working with Windows 2000 and newer windows version (haven't tested it on Win9x and NT4.0).

Of couse this API function isn't included in the default Delphi header files. To use it include this right before the implementation part of your unit.

  function RegisterShellHook(wnd : hwnd; param : dword) : boolean; stdcall; external 'shell32.dll' index 181;


Next thing which has to be done is to register the WM_SHELLHOOK message (it doesn't exist by default). Do this one time in your project, best in the FormCreate event.

var
  WM_SHELLHOOK : integer;

[...]
  WM_SHELLHOOK := RegisterWindowMessage('SHELLHOOK');


Now you can register your window for receiving shell hooks

  RegisterShellHook(0,1); // Enabled the shell hook
  RegisterShellHook(HandleToWindow,3);


In order to Unregister your window from receivning shell hooks call the same function again with a different parameter

  RegisterShellHook(HandleToWindow,0);


Once registered your window will receive the WM_SHELlHOOK message. To catch this message either use a custom wndproc or the OnMessage event of the TApplicationEvents component.
The LParam of the received message contains the handle to the target window which is related to the shell notification.
The WParam is the notification type. See Shell Proc on MSDN for details about the HSHELL_ params.

example how to use the WM_SHELLHOOK message:

var
  wnd : THandle;

[...]
  if msg = WM_SHELLHOOK then
  begin
    wnd := msg.LParam;
    case msg.WParam of
      HSHELL_WINDOWCREATED : // A New window has been created
      HSHELL_REDRAW : // The caption of the window has changed
      HSHELL_REDRAW + 32768 : // The window is flashing in the taskbar
      HSHELL_WINDOWDESTROYED : // A window was destroyed
      HSHELL_WINDOWACTIVATED : // A non full screen window was activated
      HSHELL_WINDOWACTIVATED + 32768 : // A window was activated and is now in full screen mode
      HSHELL_GETMINRECT      : // A window is being minimized or maximized
    end;
  end;