Link to home
Start Free TrialLog in
Avatar of Palamedes
PalamedesFlag for United States of America

asked on

Catching Windows M..

I have a program that I don't want users to be able to minimize.

I have set up a SystemCommand routine to catch SC_MINIMIZE which keeps users from clicking the little button.. (also known as SC_ICON)  but it doesn't catch the Windows-M that can also minimize programs.

How do I go about catching that Windows-M..

Here is my current setup:

...
Private
  procedure SysCommand(var Message: TWMSYSCOMMAND); message WM_SYSCOMAND;
...

procedure TProgram.SysCommand(var Message: TWMSYSCOMMAND);
begin
  if Message.CmdType and $FFF0 = SC_MINIMIZE then Message.result:=0
  else inherited;
end;


I seem to remember this working for me on my Win98 box.. but now it's not working on my Win2K box..

Thoughts?
Avatar of Member_2_248744
Member_2_248744
Flag of United States of America image

something that works for me is to look in the object inspector for that form you and in the BorderIcons property, set the biMiminize to False. Or in the Form's OnCreate do
Form1.BorderIcons := [biSystemMenu,biMaximize];

leave out the biMinimize
Avatar of Palamedes

ASKER

Setting the border icon's doesn't do what I want.  You can still minimize an application that doesn't have a minimize button in the border.

The code I posted above actually makes that minimize button not function, yet still be there.  (And I have reasons for that.. heh )  But I have yet to figure out how to catch Windows-M

Delphi uses the parent form (TApplication) to do a minimize, So it hijacks the SC_Minimize message. You might try the Application OnMessage and test for the Handle of the Form and the WM_SYSCOMAND message with the SC_MINIMIZE in the wParam and the set Handled to true. I may have time tomorrow to get the code for that
procedure TForm1.ApplicationEvents1Message(var Msg: tagMSG;
  var Handled: Boolean);
begin
{if (Msg.message = WM_SYSCOMMAND) and (Msg.hwnd = Application.Handle) and (Msg.wParam = SC_MINIMIZE) then
 Handled := True;
  end;
I see where you're going with that.. but it didn't work..

Hrmmm.. Ponder ponder ponder..
Your code (which looks a lot like some code taken directly out of Mastering Delphi 5 by Marco Cantu) actually prevents ANY system event type stuff.. You can't move the app, close the app, resize.. etc..

Which could be handy.. hehe  but not for my use now..

The one thing it doesn't appear to do though is catch the Windows M..

I didn't realize this would be this tough.. this one has stumped me.. =/

Avatar of geobul
geobul

Hi,

Try overriding the MainForm.WndProc like the following:

type
  TForm1 = class(TForm)
  private
    { Private declarations }
  protected
    procedure WndProc(var Msg : TMessage); override;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.WndProc(var Msg : TMessage);
begin
  if (Msg.Msg = WM_SYSCOMMAND) and (Msg.wParam = SC_MINIMIZE) then begin
    Msg.wParam := 0;
    Msg.lParam :=0;
  end;
  inherited;
end;

Regards, Geo
Nope that no workie either.. =(  

It very effectively prevents the minimizing of the application by either the system menu or the minimize icon.. but it doesnt catch Windows-M...

Grrr.. There MUST be a way to do this..

All three methods above, My way, Slicks way and Geo's way work, sorta.. they work to the degree that if you click the minimize button or minimize via the system menu it catches it and wont minimize..

But none of them will catch Windows-M..

Inthe, Madashi, Kretzschmar... you guys have any sage advice?  

I seem to remeber this method workin on Win98... Maybe I'm wrong.. I have no way to test it..

This is frustrating..   I do appreciate your guys help in this matter..
Windows-M? Is that the same as "Show desktop" in the quick start bar? Don't know, because I've no Windows key on my keyboard (hate this key).

If it is the same as "Show desktop", then you can't stop it by catching WM_SYSCOMMAND, because AFAIK this function doesn't really minimize the programs, instead it changes the z-order, so that the program windows of the quasi-minimized windows are hidden behind the desktop.

Regards, Madshi.
Window's M is infact the "Show Desktop" function of windows..  I find it handy, but there are times when I don't want it.. heh

Okay so we can't catch it via WM_SYSCOMMAND.. that stinks.. hehe..  How do we prevent the z-order of our app from being changed?  I haven't a clue on that one..

I know there is a way to prevent this.. I have an app sitting on my desktop written in another language in a galaxy far far away, that does just this.  (Not written by me)



Perhaps handling WM_WINDOWPOSCHANGING and setting the nozorderchange flag helps? Just a guess...
Madshi.. I know you're busy.. but could you give me an example of that?  I really dont' know how to do that..
Something like this (not tested nor compiled). It's a shot in the dark. Might work or not.

type
  TYourMainForm = ...
  private
    procedure WmWindowPosChanging(var Message: TMessage); message WM_WINDOWPOSCHANGING;
  end;

procedure TYourMainForm.WmWindowPosChanging(var Message: TMessage);
begin
  with PWindowPos(Message.lParam)^ do
    flags := flags or SWP_NOOWNERZORDER;
end;

Regards, Madshi.
Use WM_MINIMIZE instead of SC_MINIMIZE

add the procedure
procedure MyMinimizeEvent(msg: TMessage); message WM_MINIMIZE;
to your Form

Inside this function you can handle this Windows Message. I haven't tried this, but it works fine with WM_CLOSE.
Well.. I can't get Madshi's version to work..

And there is no WM_MINIMIZE..
ASKER CERTIFIED SOLUTION
Avatar of maverick65
maverick65

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Hey that works perfectly.. THanks bud..
btw madshi ctrl+f1 try it  u probly allready know ^_^