Forum > Windows

Windows Messages and Class Helper

(1/1)

pmesquita:
Personal,
How are we going? I hope well...

I need a procedure to be executed when the form is minimized, but it will be wrong to copy and put the same code in countless forms, so I had the brilliant idea of creating a Helper

The problem starts with that when compiling, the compiler says that "MESSAGE" is not allowed in helper types.

Is it possible to override the WmSysCommand procedure using a class helper and only importing the FormHelper.pas unit into the other units?

Here's an example of how I'm doing...


--- 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";}};} ---unit helpers_class; {$mode objfpc}{$H+}{$modeswitch advancedrecords+} interface usesClasses, SysUtils, Forms, Controls, Graphics, Dialogs, ComCtrls,LCLType, ExtCtrls, StdCtrls, Messages, LMessages; Type  { SISUtilHelperForms }  HelperForms = Class Helper For TForm;   Private    { Private Declarations }    Procedure WmSysCommand(var Msg: TWMSysCommand); message WM_SYSCOMMAND;  End; implementation { HelperForms }Procedure HelperForms.WmSysCommand(var Msg: TWMSysCommand); Begin  If (msg.CmdType = SC_MINIMIZE) Then   ShowMessage('Application.Minimize');   inherited; End; End. 
Error:
--- 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";}};} ---helper_class.pas(17,53) Error: "MESSAGE" is not allowed in helper types

Remy Lebeau:

--- Quote from: pmesquita on June 17, 2021, 05:29:50 pm ---Is it possible to override the WmSysCommand procedure using a class helper and only importing the FormHelper.pas unit into the other units?

--- End quote ---

No.  For one, because of the error you already found.  'message' dispatching simply doesn't work with a helper class.  But also, because WMSysCommand() is not a virtual method, but even if it were, a helper class can't override a virtual method anyway.

So, there is simply no avoiding having to catch the WM_SYSCOMMAND message in each Form individually, and then delegating to the desired handler.  If you want to consolidate your handler across multiple Forms, create a base class derived from TForm, and then derive your Forms from that base class as needed.

pmesquita:
I understood...I suspected I wouldn't be able to intercept Windows messages...

In this case of creating a class derived from a TForm... is there any example or is the process the same as I create a component for example TEditCustom = Class(TEdit) ... ?

Lulu:
You can create a form1 with the IDE, add some stuff in, then to derive another form from it, menu->File->New...  select 'composant du projet hérité' (my ide is in french) and on the right select form1. The IDE will create a new form inherited from form1

engkin:
The message in your class helper makes me think you want to know when the *application* is minimized. If so then use:
Application.AddOnMinimizeHandler

But then that was not your question. If you want to know when a *form* is minimized, you can change the WindowProc of the form. Using your class helper, it would be like:

--- 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";}};} ---unit helpers_class; {$mode objfpc}{$H+}{$modeswitch advancedrecords+} interface usesClasses, SysUtils, Forms, Controls, Graphics, Dialogs, ComCtrls,LCLType, ExtCtrls, StdCtrls, Messages, LMessages; Type  { SISUtilHelperForms }  HelperForms = Class Helper For TForm  private    procedure WmSysCommand(var TheMessage: TLMessage);  public    procedure Catch_SC_MINIMIZE;  End;  implementation var  OrgWindowProc:array of TWndMethod; { HelperForms } procedure HelperForms.Catch_SC_MINIMIZE;var  idx:integer;begin  idx:=Length(OrgWindowProc);  SetLength(OrgWindowProc, idx+1);  OrgWindowProc[idx]:=WindowProc;  Tag:=idx;  WindowProc:=@WmSysCommand;end; procedure HelperForms.WmSysCommand(var TheMessage: TLMessage);var  msg: TWMSysCommand absolute TheMessage; Begin  If (msg.CmdType = SC_MINIMIZE) Then   ShowMessage('Application.Minimize');   OrgWindowProc[Tag](TheMessage);  //inherited; End; End.
To use it, after you create the form, call the helper:

--- 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";}};} ---program project1;...  Application.CreateForm(TForm1,Form1);  Application.CreateForm(TForm2,Form2);   Form1.Catch_SC_MINIMIZE;  Form2.Catch_SC_MINIMIZE;...
That's not the only way. Here I use the Tag property to store the index of the original WindowProc.

I just noticed you posted this in Windows section. You can use SetWindowLong with GWL_WNDPROC to do the same, without using the Tag property.

Navigation

[0] Message Index

Go to full version