title: On Window Resize Event
body: <h1>The Problem</h1>
  <p>Call a procedure whenever the <strong>Main Excel Window</strong> is resized.</p>
  <h2>First attempt:</h2>
  <pre><code>Sub Workbook_WindowResize(ByVal Wn As Window)
      Debug.Print Wn.Width &amp; &quot;x&quot; &amp; Wn.Height
  End Sub
  </code></pre>
  <p><strong>Results:</strong></p>
  <p>The sub routine is called whenever the 'inner' workbook window is resized but not when the application window is resized. I.E. occcurs on resize of the Multiple Document Interface child containing the application instance.</p>
  <h2>Second attempt</h2>
  <pre><code>Dim WithEvents App As Application
  Private Sub App_WindowResize(ByVal Wb As Workbook, ByVal Wn As Window)
      Debug.Print Wn.Width &amp; &quot;x&quot; &amp; Wn.Height
  End Sub
  </code></pre>
  <p><strong>Results:</strong></p>
  <p>Oddly, the same thing that happened before occurs, which definitely surprised me. The event only occurs when the workbook window is resized instead of the application window.</p>
  <p>For this reason I started looking into using the windows API.</p>
  <p>There are many examples of setting SystemWide keyboard and mouse hooks using the windows APIs. This is along the same lines:</p>
  <pre><code>Public Enum enHookTypes
      WH_CALLWNDPROC = 4
      WH_CALLWNDPROCRET = 12
      WH_CBT = 5
      WH_DEBUG = 9
      WH_FOREGROUNDIDLE = 11
      WH_GETMESSAGE = 3
      WH_HARDWARE = 8
      WH_JOURNALPLAYBACK = 1
      WH_JOURNALRECORD = 0
      WH_MOUSE = 7
      WH_MSGFILTER = (-1)
      WH_SHELL = 10
      WH_SYSMSGFILTER = 6
      WH_KEYBOARD_LL = 13
      WH_MOUSE_LL = 14
      WH_KEYBOARD = 2
   End Enum
  
  Private Declare Function SetWindowsHookEx Lib &quot;user32&quot; Alias &quot;SetWindowsHookExA&quot; (ByVal idHook As LongPtr, ByVal lpfn As Long, ByVal hMod As Long, ByVal dwThreadId As Long) As LongPtr
  Private Declare Function UnhookWindowsHookEx Lib &quot;user32&quot; (ByVal hHook As Long) As Long
  
  Private Declare Function GetLastError Lib &quot;kernel32&quot; () As Long
  
  'Ensure that your hook procedure does not interfere with the normal operation of other hook procedures
  Private Declare Function CallNextHookEx Lib &quot;user32&quot; (ByVal hHook As Long, ByVal ncode As Long, ByVal wParam As Long, lParam As Any) As Long
  
  Public hndl As Long
  
  Sub HookWindow()
      hndl = SetWindowsHookEx(WH_CALLWNDPROC, AddressOf measureWindow, Application.Hinstance, 0&amp;)
      Debug.Print hndl &amp; &quot;~~&quot; &amp; GetLastError()
  End Sub
  
  Sub unhookWindow()
      ret = UnhookWindowsHookEx(hndl)
      Debug.Print ret
  End Sub
  
  Public Sub measureWindow(code As Long, wParam As Long, lParam As Long)
      If code &gt; 0 Then
          Debug.Print ThisWorkbook.Windows(1).Width &amp; &quot;x&quot; &amp; ThisWorkbook.Windows(1).Height
      Else
          ret = CallNextHookEx(measureWindow, code, wParam, lParam)
      End If
  End Sub
  </code></pre>
  <p><strong>Results:</strong></p>
  <p>If I replace the <code>WH_CALLWNDPROC</code> in:</p>
  <pre><code>hndl = SetWindowsHookEx(WH_CALLWNDPROC, AddressOf measureWindow, Application.Hinstance, 0&amp;)
  </code></pre>
  <p>with <code>WH_KEYBOARD_LL</code> the sub-routine is called whenever a key is pressed. Similarly, if I replace it with <code>WH_MOUSE_LL</code> the sub-routine is called whenever the mouse is moved or a mouse button pressed.</p>
  <p>The problem is that when I try to hook the sub-routine to <code>WH_CALLWNDPROC</code> nothing happens?</p>
  <h2>Why?</h2>
  <p>I'm still not sure, but the same is true for all ENUMS in <code>enHookTypes</code> except <code>WH_MOUSE_LL</code> and <code>WH_KEYBOARD_LL</code>. Looking through the WinAPI documentation I read that you can use <code>GetLastError</code> from Kernel32.dll do get some indication of why the operation failed.</p>
  <p>The error numbers I have got so far are (in decimal) <code>error 5</code> (for JOURNAL hooks) and <code>error 1428</code> for the rest.</p>
  <p>Ultimately this also failed.</p>