Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 242
  • Last Modified:

writing my own Message-handler in delphi

i'm building a component that should capture the WM_GETMINMAXINFO message, and prevent the form, where the component resides on, from being made smaller than a (any) number.

hou would i do this
0
topkapi
Asked:
topkapi
  • 13
  • 8
  • 5
  • +1
1 Solution
 
intheCommented:
Hi TopKapi

procedure TForm1.WMGetMinMaxInfo(var msg: TWMGetMinMaxInfo);
begin
  with msg.MinMaxInfo^ do  begin
    ptMaxSize   := Point(300, 300);
    ptMinTrackSize  := Point(100, 100);
    ptMaxTrackSize := Point(300, 300);
  end;
end;

Barry
0
 
topkapiAuthor Commented:
thanks for the quick reply, but the whole question was:

Can you show me how i would do this in a _component_ on a form?

thanks
0
 
intheCommented:
ok dude im on it but wont be back for a while :-)

0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
viktornetCommented:
Try something like this...

TComp = class(TComponent)
{...}
public
  procedure WMGetMinMaxInfo(var msg: TWMGetMinMaxInfo);message     WM_GETMINMAXINFO;
{...}
procedure TComp.WMGetMinMaxInfo(var msg: TWMGetMinMaxInfo);
begin
       with msg.MinMaxInfo^ do  begin
         ptMaxSize   := Point(300, 300);
         ptMinTrackSize  := Point(100, 100);
         ptMaxTrackSize := Point(300, 300);
       end;
end;

Try it out and tell me how it works..

Cheers,
Viktor
0
 
topkapiAuthor Commented:
how does that function get executed? i mean, you can resize the form till you die, but still nothing happens!

(excuse my ignorance)
0
 
topkapiAuthor Commented:
for your information, i could post the source as it is so far:

----------------cut-here---8<----------------------------------
unit FormSizeControl;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls,
  Forms, Dialogs;

type
  TFormSizeControl = class(TComponent)

  private
    { Private declarations }

    // coordinates for min en max size of form
    MinPoint  : TPoint;
    MaxPoint  : TPoint;

    // property handlers
    procedure setMinWidth(I: Integer);
    function  getMinWidth: Integer;

    procedure setMinHeigth(I: Integer);
    function  getMinHeigth: Integer;

    procedure setMaxWidth(I: Integer);
    function  getMaxWidth: Integer;

    procedure setMaxHeigth(I: Integer);
    function  getMaxHeigth: Integer;

  published
    { Published declarations }

    // Constructor / Destructor
    constructor Create(AOwner: TComponent); override;
    Destructor  Destroy; override;

    // Property definitions
    property MinWidth  : Integer read getMinWidth   write setMinWidth   default 0;
    property MinHeight : Integer read getMinHeigth  write setMinHeigth  default 0;
    property MaxWidth  : Integer read getMaxWidth   write setMaxWidth   default 0;
    property MaxHeight : Integer read getMaxHeigth  write setMaxHeigth  default 0;

  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('Remco', [TFormSizeControl]);
end;


//==[Constructor / Destructor]==================================================
constructor TFormSizeControl.Create(AOwner: TComponent);
begin
  Inherited;
  //
end;

Destructor  TFormSizeControl.Destroy;
begin
  //
  Inherited;
end;




//==[get and set min/max width & heigth property's]=============================
procedure TFormSizeControl.setMinWidth(I: Integer);
begin
  I := Abs(I);

  MinPoint.X := I;

  if((I > MaxPoint.X) and not (MaxPoint.X = 0))then
    MaxPoint.X := I;
end;

function  TFormSizeControl.getMinWidth: Integer;
begin
  Result := MinPoint.X;
end;

procedure TFormSizeControl.setMinHeigth(I: Integer);
begin
  I := Abs(I);

  MinPoint.Y := I;

  if((I > MaxPoint.Y) and not (MaxPoint.Y = 0))then
    MaxPoint.Y := I;
end;

function  TFormSizeControl.getMinHeigth: Integer;
begin
  Result := MinPoint.Y;
end;

procedure TFormSizeControl.setMaxWidth(I: Integer);
begin
  I := Abs(I);

  MaxPoint.X := I;

  if((I < MinPoint.X) and not (I = 0)) then
    MinPoint.X := I;
end;

function  TFormSizeControl.getMaxWidth: Integer;
begin
  Result := MaxPoint.X;
end;

procedure TFormSizeControl.setMaxHeigth(I: Integer);
begin
  I := Abs(I);

  MaxPoint.Y := I;

  if((I < MinPoint.Y) and not (I = 0)) then
    MinPoint.Y := I;
end;

function  TFormSizeControl.getMaxHeigth: Integer;
begin
  Result := MaxPoint.Y;
end;

end.

--------------end-here--->8------------------------------------

maybe this will help.

0
 
viktornetCommented:
Did you try doing what I told ya??
0
 
MadshiCommented:
Hello guys and girls (if any :-(),

you must answer the WM_GETMINMAXINFO of the Form, not of your component. That's why Viktor's code is not working, I think.

var prevWndProc : integer = 0;
    mmi         : TMinMaxInfo;
function MyHookProc(window,msg: cardinal; wparam,lparam: integer) : integer; stdcall;
begin
  if msg=WM_GETMINMAXINFO then begin
    with PMinMaxInfo(lparam)^ do begin
      ptMaxSize:=mmi.ptMaxSize;
      ptMaxPosition:=mmi.ptMaxPosition;
      ptMinTrackSize:=mmi.ptMinTrackSize;
      ptMaxTrackSize:=mmi.ptMaxTrackSize;
    end;
    result:=0;
  end else result:=CallWindowProc(pointer(prevWndProc),window,msg,wparam,lparam);
end;

procedure HookMyParentWindow(form: TForm);
begin
  if (form=nil) or (prevWndProc<>0) then exit;
  prevWndProc:=GetWindowLong(form.handle,GWL_WNDPROC);
  SetWindowLong(form.handle,GWL_WNDPROC,integer(@MyHookProc));
end;

procedure UnhookMyParentWindow(form: TForm);
begin
  if (form=nil) or (prevWndProc=0) then exit;
  SetWindowLong(form.handle,GWL_WNDPROC,prevWndProc);
  prevWndProc:=0;
end;


procedure TForm1.Button1Click(Sender: TObject);
begin
  mmi.ptMaxSize:=point(800,600);
  mmi.ptMaxPosition:=point(50,50);
  mmi.ptMinTrackSize:=point(300,300);
  mmi.ptMaxTrackSize:=point(800,600);
  HookMyParentWindow(Form1);
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  UnHookMyParentWindow(Form1);
end;

Regards, Madshi.
0
 
viktornetCommented:
oh Madshi is right...

dammit, i didn't think of that b4 :(

Cheers,
Viktor
0
 
MadshiCommented:
i'm looking into it.

thanks so far.

Topkapi
0
 
topkapiAuthor Commented:
:-)
0
 
MadshiCommented:

well, i adjusted the code to:

-----------8<--------------------------------------------------

unit FormSizeControl;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls,
  Forms, Dialogs;

type
  TFormSizeControl = class(TComponent)

  private
    { Private declarations }

    // coordinates for min en max size of form
    MinPoint    : TPoint;
    MaxPoint    : TPoint;

    prevWndProc : integer;

    procedure HookMyParentWindow(form: TForm);
    procedure UnhookMyParentWindow(form: TForm);
    function  MyHookProc(window ,msg: cardinal; wparam, lparam: integer): integer; stdcall;

    {...}

  published
    { Published declarations }

    // Constructor / Destructor
    constructor Create(AOwner: TComponent); override;
    Destructor  Destroy; override;

    {...}

  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('Remco', [TFormSizeControl]);
end;


//==[Constructor / Destructor]==================================================
constructor TFormSizeControl.Create(AOwner: TComponent);
begin
  Inherited;
  prevWndProc := 0;
  HookMyParentWindow(TForm(AOwner));
end;

Destructor  TFormSizeControl.Destroy;
begin
  UnHookMyParentWindow(TForm(Owner));
  Inherited;
end;

procedure TFormSizeControl.HookMyParentWindow(Form: TForm);
begin
  if((Form = nil) or (prevWndProc <> 0)) then
    exit;

  prevWndProc := GetWindowLong(Form.Handle, GWL_WNDPROC);
  SetWindowLong(Form.Handle, GWL_WNDPROC, Integer(@TFormSizeControl.MyHookProc));
end;

procedure TFormSizeControl.UnhookMyParentWindow(Form: TForm);
begin
  if((Form = nil) or (prevWndProc = 0)) then
    exit;

  SetWindowLong(Form.Handle, GWL_WNDPROC, prevWndProc);
  prevWndProc := 0;
end;

function TFormSizeControl.MyHookProc(Window, Msg: cardinal; Wparam, Lparam: Integer): Integer; stdcall;
begin
  if(Msg = WM_GETMINMAXINFO)then
  begin

    with PMinMaxInfo(Lparam)^ do
    begin
      ptMaxSize      := MaxPoint;
      //ptMaxPosition  := ptMaxPosition;
      ptMinTrackSize := MaxPoint; // mmi.ptMinTrackSize;
      ptMaxTrackSize := MaxPoint; // mmi.ptMaxTrackSize;
    end;

    Result := 0;
  end
  else
    Result := CallWindowProc(Pointer(prevWndProc), Window, Msg, Wparam, Lparam);
end;

{...}

end.

--------------------->8------------------------------

It compiles fine,
but when i drop the component on a form i get an acces violation.

must be in the Constructor somewhere, but i'm new to this, so please explain.....

Topkapi
0
 
topkapiAuthor Commented:
Hey, what's that? In my explorer it looks like Topkapi has written under my name! Do you see that, too? Looks like an EE-bug. Probably, because I've tried to write a comment at the same time as Topkapi...
0
 
MadshiCommented:
who!

those entrys don't seem to be going right.

all the names are messed up, aand my code isn't there.


0
 
MadshiCommented:
You can't simple put this MyHookProc into your component, because then it's:
  function MyHookProc(...) : integer; stdcall OF OBJECT;
Now it has a hidden "self" parameter. And that's not compatible to the format, that Windows wants to have. So you can put all the other functions in your component, but the MyHookProc procedure must be stand alone.

Regards, Madshi.
0
 
MadshiCommented:
Uaaaaa!!! It seems that EE is crashing around...

It's me (Madshi) not topkapi...

That's really fun. I'll go and tell the EE-team about this problem!

Regards, Madshi.
0
 
MadshiCommented:
It seems that it is working again...  :-)
0
 
MadshiCommented:
Oh, no. Seems that the last comment is not shown until a new comment comes that is again not shown until a new comment comes...
0
 
MadshiCommented:
Dummy comment just to show the other one...
0
 
intheCommented:
And another dummy...
0
 
intheCommented:
thanks madshi
 i too have been trying to do it like my original awnswer and as viktor said but buggered if i could get it to work :-( now i see why
i think i need a book on component writing, know of any good ones ?all the books i got only do like one chapter or so on it
Regards Barry

0
 
topkapiAuthor Commented:
¤¤¤¤hello im a comment¤¤¤¤
0
 
intheCommented:
Now my comments are not only under the wrong name, they don't appear at all...
0
 
topkapiAuthor Commented:


 my head hurts  :-)

¤B¤
0
 
MadshiCommented:
If only can explain to me what the following code exactly do, i would be very gratefull. i can't find them in Delphi help. guess there api-calls of some sort?

    with PMinMaxInfo(lparam)^ do begin
      ptMaxSize:=mmi.ptMaxSize;
      ptMaxPosition:=mmi.ptMaxPosition;
      ptMinTrackSize:=mmi.ptMinTrackSize;
      ptMaxTrackSize:=mmi.ptMaxTrackSize;
    end;
0
 
MadshiCommented:
Hi Barry,

don't know any good component writing books...  :-(
If you want to learn something you should just try to understand the delphi components (of course you need the professional or client/server version, otherwise you won't have the sources). That's the way I learned component writing.
But I think this question was mainly about how to make the WM_GETMINMAXINFO message working. So I think this was more a win32 question than a component writing question. The problem with your answer was only, that you handled the wrong window.

Regards, Madshi.
0
 
MadshiCommented:
Ok, I don't know who asked this question from Sunday, December 06 1998 - 11:01PM, but it doesn't matter...   :-)))

If you look at the documentation of the WM_GETMINMAXINFO, you'll find:
WM_GETMINMAXINFO  
lpmmi = (LPMINMAXINFO) lParam; // address of structure

And if you read the rest of the documentation you'll find that the lParam value is a pointer to an already allocated and already with standard values filled MINMAXINFO structure. The Type "PMinMaxInfo" that I used in my sources is the Delphi pointer type of this MINMAXINFO structure.
This is what my sources does: It converts the lParam pointer into a PMinMaxInfo pointer, then fills all the values in the structure (that is referenced by lParam respectivly PMinMaxInfo(lParam)). The mmi variable is just a kind of static parameter that contains all the point values you want to set.
Everything clear now?

Regards, Madshi.
0
 
topkapiAuthor Commented:
Dummy...
0
 
MadshiCommented:
test comment
0

Featured Post

Get your problem seen by more experts

Be seen. Boost your question’s priority for more expert views and faster solutions

  • 13
  • 8
  • 5
  • +1
Tackle projects and never again get stuck behind a technical roadblock.
Join Now