• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 241
  • Last Modified:

Preventing the user from bringing a form to front by pressing ALT+ESC

I'm writing a multimedia application which is designed to work
at a resolution of 800x600. Above this resolution I have a black
form in the background which covers the entire desktop. All
my other stuff is shown on another form top of the black
one. However this black form can be brought to front by pressing
ALT+ESC keys.

Is there any solution for preventing the user from bringing my black
form to foreground ?

Any help is greatly appreciated.

Levente
0
Levente
Asked:
Levente
  • 6
  • 4
  • 4
  • +5
1 Solution
 
GreedyCommented:
I would guess that you also want to disable alt-tab too so just use this little procedure here

procedure TurnSysKeysOff;
var
  OldVal : LongInt;
begin
  SystemParametersInfo (97, Word (True), @OldVal, 0)
end;

procedure TurnSysKeysBackOn;
var
  OldVal : LongInt;
begin
  SystemParametersInfo (97, Word (False), @OldVal, 0)
end;

You could also use a single form and put the 800x600 part of your form on a TPanel that is centered on this form.  Then set the form to full screen and give it a black background.  That is if you don't just want to make the form scale...lazy programmer? :)

0
 
MadshiCommented:
Good comment, Greedy...

Levente, you could also try to disable the black window (enabled:=false) or to show the real window (that is before the black window) with ShowModal.
0
 
333Commented:
Or maybe you can use an MDI app?
0
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 
EmmDiehCommented:
or set the fsStayOnTop attribute of your foreground window,
if that is an option.
0
 
LeventeAuthor Commented:
Thank you all for your comments. First of all I must tell you i'm not a lazy programmer :-> Since I'm
developing a multimedia app all the background graphics (approx. 10 forms) are drawn by a graphic
designer and he would go crazy if he had to make the design for 640x480, 800x600, 1024x768 etc...

Greedy, disabling system keys (e.g. alt-tab) is not a nice way of approach, isn't it ? (Though it may work ;-)
On the other hand I've thought of creating an MDI app, but:
- when I try to hide my MDIChild form I get an error message (Cannot hide an MDI child form.)
  so I have to change my FormStyle property before I _show_ and _hide_ my form.
- Since I'm creating a MDIChild form I get an ugly caption and frame around my window. (Though I can
  remove it by overriding Createparams procedure.)

Well, IMHO this seems to be quite a tricky solution.

StayonTop attribute doesn't help since I can place any window between my black background window
and my foreground window.

Do you have any better idea ?

Regards,
Levente
0
 
MatveyCommented:
Maybe try to show the other form when the black form receives the activate event?
0
 
MadshiCommented:
Levente, have you tried my suggestions?  :-)
0
 
graemefCommented:
How about capturing the on-paint event for the black form and using this to set the multimedia window to the foreground and the black to the background. Might flick a bit, but should work.
0
 
BlackDeathCommented:
hey, guyz.

i'm sure i saw something like "drawing on the desktop" some dayz ago. i just can't remember where that was - right now. when i'm back home this evening, i'm gonna scan my machine 4 it.
it went somehow like ...get handle 4 desktop...use this as target 4 drawing commands...gnagnagna.
i'll find it. & post it 2morrow.

bye,

Black Death.
0
 
MatveyCommented:
To be exact it's:

DC := GetDC(GetDGetDesktopWindow)
0
 
MatveyCommented:
Ooops...

DC := GetDC(GetDesktopWindow)
0
 
LeventeAuthor Commented:
Yes, Madshi, I've tried your suggestion. Disabling the black form
doesn't work, neither does the ShowModal procedure (it *might* be my fault).
Since I have to pass some parameters to certain forms I'm doing this:

type
 TForm1 = class(TForm)
    ( ... )
 public
    { Public declarations }
    procedure Show(const A, B, C: Integer);
 end;


procedure Tform1.Show(const A, B, C: Integer);
begin
   ( ... )

   inherited Show;    ( inherited ShowModal result in error: Cannot make a
                  visible window modal.}
end;


Well, what's wrong. Any idea ?

Levente

Ps. As soon as I try drawing to desktop I'll come back.
PS. BTW, I've increased proposed points for you all :-)
0
 
MatveyCommented:
Have you tried showing the other form when the black form receives the activate event?
0
 
GreedyCommented:
See if this works for you...I made a new application with two forms.  The Form 1 has 1 button on it with this code

procedure TForm1.Button1Click(Sender: TObject);
begin
  Form2.Show;
end;

this is the code for form2

procedure TForm2.FormShow(Sender: TObject);
begin
  with Form2 do
  begin
    Tag := 0;
    Top := (Form1.Top + (Form1.Height div 2)) - (Height div 2);
    Left := (Form1.Left + (Form1.Width div 2)) - (Width div 2);
  end;
end;

procedure TForm2.FormDeactivate(Sender: TObject);
begin
  if Form2.Tag <> 1 then
  begin
    SetActiveWindow(Form2.Handle);
  end;
end;

procedure TForm2.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
  Form2.Tag := 1;
end;

I set the BorderStyle of Form1 to bsNone and the Color to clBlack.  

I still don't see the reason why your doing it with two forms, maby it will come to me...
0
 
333Commented:
I have tryed this thing with ALT+ESC and the problem is:
if I press ALT+ESC, the Form1 (the black form) goes on top of Form2, but its NOT active. So I think, that things with OnActivate or OnDeactivate will not work. I use TTimer.
Here is my expample:
There are 2 forms - Form1 (black form) and Form2 (blank form). The Form1 has two buttons ( Button1 to show form2, Button2 to exit) and TTimer.

procedure TForm1.Button1Click(Sender: TObject);
begin
  form2.show;
  OnActivate:=Timer1Timer; {just for prevent flickering}
  timer1.enabled:=true;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
var
h:THandle;
begin
  GetWindow(h,gw_hwndfirst);
  if h<>Form2.handle then
  BringWindowToTop(form2.handle);
end;

Form2.OnClose event {needed to terminate app} :

procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  Form1.Timer1.Enabled:=false;
  Form1.OnActivate:=nil;
end;

Maybe it looks a little nasty, but it works.
AP
0
 
BlackDeathCommented:
tja.

i did NOT find it. whyever. still searching.
but meanwhile i think it doesn't fit the problem so well.
i mean, after ending your app, u'd have 2 restore everything.
who wantz 2 have a black desktop (but me) ?

i've had a similar problem once:
i wanted 2 display a animated gif in a little rectangle above the system desktop icon. i created a tiny form, used itz complete area 2 display the gif, added a context menu und a drag handler (of course it had no captionbar) - & was unable 2 handle just this problem: Alt-TAB, Alt-ESC, Ctrl-Alt-DEL.

all suggestions here sound good, but itz all kinda workaround the actual problem: there must be simple a way 2 pin anything directly 2 the desktop. & directly means that there's no chance 4 anything 2 slip in between desktop und "pin-up" in z-order. like an immediate child. or something like that. or what.

til later,

Black Death.
0
 
MadshiCommented:
Levente,

please try:
(1) First of all create a whole new project with two forms (first/main window: "BackWin", second window "Form1").
(2) Set BackWin.WindowState:=wsMaximized
(3) Add a button to BackWin
(4) (suggestion 1):
    procedure TBackWin.Button1Click(sender: TObject);
    begin
      enabled:=false;
      LeventesShow(1,2,3);
    end;
    procedure TForm1.LeventesShow(i1,i2,i3: integer);
    begin
      Show;
    end;
    (suggestion 1)
    procedure TBackWin.Button1Blick(sender: TObject);
    begin
      LeventesShow(1,2,3);
    end;
    procedure TForm1.LeventesShow(i1,i2,i3: integer);
    begin
      ShowModal;
    end;
With both suggestions Form1 is always in top of BackWin.
I don't know why (in your example) Form1 is visible already.
Do you call your LeventesShow procedure more than once per form?
There are two important differences between "show" and "showModal":
(1) "show" returns immediately; "showModal" return when the form is closed.
(2) "show" doesn't disable "blackWin"; "showModal" does.
So if you want to use "show", you'll have to disable the "blackWin" yourself (see suggestion 1).

So what is the difference between my samples and your program?
Why do my samples work and your program does not?

Regards, Madshi.
0
 
LeventeAuthor Commented:
Well, guys, I GOT IT. Somewhere else I was advised the following code:

procedure WindowDeActivate(var Msg: TWMActivate); message WM_ACTIVATE;

( ... )

procedure TfMenu1.WindowDeActivate(var Msg: TWMActivate);
begin
   if Msg.Active=WA_INACTIVE then begin
      SetActiveWindow(fMenu1.Handle);
      BringWindowToTop(fMenu1.Handle);
   end;
end;


Madshi, your code works quite well, too. I'm willing to offer you
the promised points.

Thanx all of you for your work.

Regards,
Levente
0
 
MadshiCommented:
It seems that you like the "deactivate" method the most. Don't you have flickering with that?
Please accept my answer only if you're using my suggestion. Otherwise reject the answer and delete the question...   :-)

Regards, Madshi.
0
 
MadshiCommented:
Or give the points to someone else...
0
 
LeventeAuthor Commented:
Madshi,

your code works well, though I've found a better one.
I'm giving you my points 'coz I appreciate your work.

Levente
0
 
MadshiCommented:
O.k., thanx for your appreciation.  :-)

Regards, Madshi.
0

Featured Post

What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

  • 6
  • 4
  • 4
  • +5
Tackle projects and never again get stuck behind a technical roadblock.
Join Now