title: Determining the sender of WM_SYSCOMMAND with LParam 0 in Delphi VCL forms
body: <h1>The problem</h1>
  
  <p>When running an application written in C, that uses some dll's written in Delphi XE7, I run into an access violation in the following code, which is in the vcl.forms.pas of the vcl library.</p>
  
  <pre><code>procedure TCustomForm.CMAppSysCommand(var Message: TMessage);
  {$IF NOT DEFINED(CLR)}
  type
    PWMSysCommand = ^TWMSysCommand;
  {$ENDIF}
  begin
    Message.Result := 0;
    if (csDesigning in ComponentState) or (FormStyle = fsMDIChild) or
     (Menu = nil) or Menu.AutoMerge then
  {$IF DEFINED(CLR)}
      with TWMSysCommand.Create(Message) do
  {$ELSE}
      with PWMSysCommand(Message.lParam)^ do
  {$ENDIF}
      begin
        SendCancelMode(nil);
        if SendAppMessage(CM_APPSYSCOMMAND, CmdType, Key) &lt;&gt; 0 then   //Here the debugger shows the access violation
          Message.Result := 1;
      end;
  end;
  </code></pre>
  
  <p>The access violation occurs on the line with SendAppMessage, and seems to be caused by the fact that the Message.LParam is 0. The message is a WM_SYSCOMMAND message. Is there a way to track where this message originated? In the call stack, all functions are part of the VCL or system files.</p>
  
  <p><a href="https://stackoverflow.com/questions/910991/how-can-my-app-find-the-sender-of-a-windows-message">This answer</a> suggest that in general it is <strong>hard</strong> to trace the sender of a windows message. However, since in my case everything is within the same application, I hope that might make it easier.</p>
  
  <h1>What have I tried?</h1>
  
  <h2>Overruling the vcl source</h2>
  
  <p>Previously, this same bug appeared in the forms.pas and was fixed by adding a copy of that file to the project and then checking that LParam &lt;> 0 in this function.
  I have tried doing the same thing with the vcl.forms.pas that is now used, but this leads to compilation errors. Even with answers as <a href="https://stackoverflow.com/questions/10470943/how-to-recompile-modifications-to-vcl-source-file-menus-pas">here</a> I was not able to build it. However, many google hits also suggested that it is in general a bad idea to change things in the vcl, so I try to avoid that option.</p>
  
  <h2>Other questions on StackOverFlow</h2>
  
  <p><a href="https://stackoverflow.com/questions/37690519/delphi-tactionmainmenu-accelerators-on-secondary-form/37692023#37692023">This article</a> gave me good information about the underlying system and how it might have occured that the Message.LParam is 0. However, I did not know how to find the source of the message or what class I should be looking for that generated it.</p>
  
  <h1>The solution</h1>
  
  <p>As described in Remy's accepted answer below, the immediate problem could be solved by having the class provide a CMAppSysCommand function to guard against LParam = 0. </p>