views:

311

answers:

2

Hi,

I need to handle when the user restores the form by double clicking the title bar. I tried handling the WM_SYSCOMMAND window message however this only works if the user restores the form via clicking the restore button in the system menu.

I am using DevExpress ribbon form components if this matters.

Thanks.

+5  A: 

I think you mean double-clicking on the title bar because double clicking on the system menu closes the form.
WM_SYSCOMMAND should work since the sequence of messages when double-clicking on the title bar to restore the form is:

Message posted: hwnd=$004E0820 WM_NCLBUTTONDBLCLK wParam $00000002 lParam $000705D4 Process Project1.exe (2380)
=> Message sent: hwnd=$004E0820 WM_SYSCOMMAND restore cmd requested (-44,-44) Process Project1.exe (2380)
Message sent: hwnd=$004E0820 WM_WINDOWPOSCHANGING wParam $00000000 lParam $0012F4CC Process Project1.exe (2380)
Message sent: hwnd=$004E0820 WM_GETMINMAXINFO wParam $00000000 lParam $0012EF6C Process Project1.exe (2380)
Message sent: hwnd=$004E0820 WM_NCCALCSIZE wParam $00000001 lParam $0012F4A0 Process Project1.exe (2380)
Message sent: hwnd=$004E0820 WM_NCPAINT update region  40040F4B Process Project1.exe (2380)
Message sent: hwnd=$004E0820 WM_ERASEBKGND wParam $31011DCA lParam $00000000 Process Project1.exe (2380)
Message sent: hwnd=$004E0820 WM_WINDOWPOSCHANGED wParam $00000000 lParam $0012F4CC Process Project1.exe (2380)

The problem is that the CmdType const SC_RESTORE2 = 61730 //0xF122 is missing in Windows.pas.

See the working code below:

type
  TForm7 = class(TForm)
  private
    procedure WMSysCommand(var Message: TWMSysCommand); message WM_SYSCOMMAND;
  end;

var
  Form7: TForm7;

implementation

{$R *.dfm}

{ TForm7 }

const
  SC_RESTORE2 = 61730; //0xF122

procedure TForm7.WMSysCommand(var Message: TWMSysCommand);
begin
  case Message.CmdType of
    SC_RESTORE2 : beep;
  end;
  inherited;
end;

Update: reference to SC_RESTORE2 from WM_SYSCOMMAND Notification on MSDN (see the "values in C#" part)

François
Missing from Windows.pas? It's evidently missing from WinUser.h, too. Where is that flag named and documented?
Rob Kennedy
Added the reference form MSDN...
François
For anyone not bothered to follow the links: SC_RESTORE is sent when restored from the TaskBar. SC_RESTORE2 has a different value and is specifically sent when restoring by double-clicking the caption bar.This looks to me as if SC_RESTORE2 is a more recently introduced notification, and it may not be supported on all Windows versions. The general documentation on the topic does not mention SC_RESTORE2 at all, nor does it indicate what Windows versions may or may not support it.
Deltics
@Deltics, I tested this in Windows XP (x32), Vista (x32/x64), 7 and it works fine :)
James
+1  A: 

In case anyone finds this later in a search...

The problem isn't with anything missing from Windows.pas, because SC_RESTORE2 is not supposed to be there. As noted by Rob Kennedy, the SC_RESTORE2 value isn't in WinUser.h either. The problem is that François' sample code (and presumably James' code) fails to bitwise-and the wParam (Message.CmdType) with $FFF0. This is described in the updated link from François, and also noted in the "Values in C#" community content, where it even says not to use SC_RESTORE2. Note that SC_RESTORE2 and $FFF0 = SC_RESTORE.

tslavens