Forum > Win32/64

WM_SYSCOMMAND: things are more complex than suggested in lMessages.pp [solved]

(1/2) > >>

PeterX:
WINDOWS widgetset - procedure WMSysCommand()


By accident I came across the fact that reacting on message WM_SYSCOMMAND
is more complex than represented by the CONST values in  lMessages.pp:


--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---  //-------------  // Windows Compatability}  //------------- { System Menu Commands }  SC_SIZE           = 61440;  SC_MOVE           = 61456;  SC_MINIMIZE       = 61472;  SC_MAXIMIZE       = 61488;  SC_ ...
I attached the example code to show what's up.

Please touch the minimize, normalize and maximize buttons
of the Child Window to see what happens ..

PeterX:
I also add some links here that show
that other people also struggle with that thing ..

https://stackoverflow.com/questions/37141166/minimize-and-restore-window-using-send-messages-in-mfc

https://microsoft.public.vc.mfc.narkive.com/EtOQGNmk/sc-restore

Remy Lebeau:

--- Quote from: PeterX on May 27, 2021, 12:38:13 am ---By accident I came across the fact that reacting on message WM_SYSCOMMAND
is more complex than represented by the CONST values in  lMessages.pp:

--- End quote ---

Yes, there are undocumented system-reserved bits used by WM_SYSCOMMAND, such as in the $F001..$F009 range that your code is looking at.  This is documented on MSDN:


--- Quote ---In WM_SYSCOMMAND messages, the four low-order bits of the wParam parameter are used internally by the system. To obtain the correct result when testing the value of wParam, an application must combine the value 0xFFF0 with the wParam value by using the bitwise AND operator.
--- End quote ---


--- Quote from: PeterX on May 27, 2021, 12:38:13 am ---
--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---if (Msg.CmdType and $FF) = $20 then
--- End quote ---

The only CmdType values whose lower 8 bits are $20 are SC_MINIMIZE ($F020) and SC_RESTORE ($F120) (and only when those lower 4 bits are not being used by the system).  You are pulling these two values out of the CmdType and commenting them as "real" messages. But then your main case block is also handling them too, making the if block redundant.


--- Quote from: PeterX on May 27, 2021, 12:38:13 am ---
--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---case Msg.CmdType of
--- End quote ---

This is just plain wrong.  Per the documentation quoted above, you must mask the value of CmdType, eg:


--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---case Msg.CmdType and $FFF0 of
For instance, when CmdType is $F001, that is really SC_SIZE ($F000) + 1.  And when CmdType is $F012, that is really SC_MOVE ($F010) + 2.  And so on.

In fact, $F012 is more commonly known as SC_DRAGMOVE, which is used when dragging around a window by its title bar, and as such is useful when you want to manually initiate a drag of a window from an area other than its title bar, for instance when dragging a caption-less window.

Though, you really should not rely on the system bits having any particular meaning.  They are private to the OS, and can change meaning from one version to another.  But, in any case, there are some known meanings, see https://stackoverflow.com/a/763273/65863.

With that said, since Microsoft doesn't want you looking at the private bits, you should end up with code that looks more like this instead:


--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---procedure TChildForm.WMSysCommand(var Msg: TWmSysCommand);begin  // https://docs.microsoft.com/en-us/windows/win32/menurc/wm-syscommand  //  // A window receives this message when the user chooses a command  // from the Window menu (formerly known as the system or control menu)  // OR when the user chooses the maximize button, minimize button,  // restore button, or close button.   case Msg.CmdType and $FFF0 of    SC_MOVE:  // move form ..      begin        {$ifdef DEBUG_SUBUNIT}        Memo1.Append( 'WMSysCommand() .. $' +IntToHex( Msg.CmdType, 8) +' = SC_MOVE');        {$endif}      end;     SC_CLOSE:  // close form ..      begin        {$ifdef DEBUG_SUBUNIT}        Memo1.Append( 'WMSysCommand() .. $' +IntToHex( Msg.CmdType, 8) +' = SC_CLOSE');        {$endif}      end;     SC_RESTORE:  // normalize form ..      begin        {$ifdef DEBUG_SUBUNIT}        Memo1.Append( 'WMSysCommand() .. $' +IntToHex( Msg.CmdType, 8) +' = SC_RESTORE');        {$endif}      end;     SC_MAXIMIZE:  // maximize form ..      begin        StoreBounds;        {$ifdef DEBUG_SUBUNIT}        Memo1.Append( 'WMSysCommand() .. $' +IntToHex( Msg.CmdType, 8) +' = SC_MAXIMIZE');        {$endif}      end;     SC_MINIMIZE:  // minimize form ..      begin        // https://microsoft.public.vc.mfc.narkive.com/EtOQGNmk/sc-restore        // https://www.askingbox.de/frage/delphi-auf-minimieren-einer-form-reagieren-onminimize        {$ifdef DEBUG_SUBUNIT}        Memo1.Append( 'WMSysCommand() .. $' +IntToHex( Msg.CmdType, 8) +' = SC_MINIMIZE');        {$endif}      end     // => https://stackoverflow.com/questions/9704075/how-to-detect-when-the-form-is-being-maximized     else      begin        Memo1.Append( 'WMSysCommand() .. $' +IntToHex( Msg.CmdType, 8));        inherited;      end;  end;end;

PeterX:
Thanks a lot for these informations !

I was really sure that my code was a mess.
But it was too late at night to do it the right way ..


If not already someone else has found this,
I would put up a bug report to change and comment
the CONST definitions in  lMessages.pp

Declaration SC_SIZE for example is in use in 5 lcl units.
But as 61440 = $F000 = b1111000000000000 this is not a big thing.

In hexadecimal it would be plain to see what's behind it, inside Windows

[Edit] I wrote a bugreport.

PeterX:
Not ready at all, but I found most of the values
I probably need, see attached Example Project.

Navigation

[0] Message Index

[#] Next page

Go to full version