Solved

Detecting new windows

Posted on 1999-01-09
12
196 Views
Last Modified: 2010-04-06
I have an application that should always be the only application runnung on the PC. Because part of this application is a Web Browser there is the possibility that Windows such as Open/Save As be opened. In that case I want to detect them and close them. Is there a way to do that other than going through all the opened windows every second ? Is there a Windows message that can be captured ?
0
Comment
Question by:alexandram
  • 7
  • 3
  • 2
12 Comments
 
LVL 5

Expert Comment

by:heathprovost
ID: 1355658
You seem to be doing this the only way I can think of.  I assume you are using the EnumWindows and calling DestroyWindow on anything you find other than your app (or something to that effect).  There are no messages your app can get (at least I dont know of any) that would signal a window opening.  I do, however, think you might want to take a different approach to this.  Have you consider writing your application as a shell replacement?  This could solve alot of your problem.  Let me know what you think.

Heath
0
 
LVL 20

Accepted Solution

by:
Madshi earned 300 total points
ID: 1355659
Hi alexandram,

you can use
  SetWindowsHookEx(WH_CBT,GetProcAddress("YourHookProc"),GetModuleHandle("C:\YourPath\YourDll.dll"),0);
Please look at the documentation of "SetWindowsHookEx" -> "WH_CBT".
If you get a "HCBT_CREATEWND" value in yourHookProc, you simply have to return a nonzero value and the window is automatically destroyed before it is completely created.
But, you'll have to put this "yourHookProc" in a little DLL, because systemwide hooks always have to be in a DLL.

Need more informations? Please ask...

Regards, Madshi.
0
 
LVL 20

Expert Comment

by:Madshi
ID: 1355660
Hmmm. Perhaps you should think of heathprovost's suggestion, too. It would perhaps make your project more complete.

heathprovost, sorry for answering the question, but I think, my answer is nearer to alexandram's original question...
0
Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

 

Author Comment

by:alexandram
ID: 1355661
Thank you both.

You mention writing my application as a shell replacement. Do you mean replacing Explorer.exe so that when the system reboots it starts my application ? If that's what you mean, how would this help preventing other windows from being opened ?

I implemented the hook. I first tried it as a thread specific hook just to experiment and it worked fine (not for what I really need it for of course).  Then I changed it to be system wide. I created the following dll that would prevent the creation of any window with class '#32770':

library NewWinHook;

uses
  SysUtils,
  Classes,
  Windows;

function NewWindowHookCallBack(pCode: Integer; pHandle: WPARAM; pWindow: LPARAM): LRESULT; stdcall;
var
  vWindowClass: array[0..80] of char;
begin
  if pCode = HCBT_CREATEWND then
  begin
    GetClassName(HWND(pHandle), vWindowClass, sizeof(vWindowClass) - 1);
    if (StrComp(vWindowClass, '#32770') <> 0) then
      Result := 0
    else
      Result := 1;
  end;
end;

end.


In my main application, in the FormOnCreate event I added:

  whNewWindow := SetWindowsHookEx(WH_CBT, GetProcAddress(GetModuleHandle('c:\winnt\system32\NewWinHook'), 'NewWindowHookCallBack'),                                GetModuleHandle('c:\winnt\system32\NewWinHook'), 0);

In the FormOnDestroy event I added

  UnhookWindowsHookEx(whNewWindow);

It looks like the hook function in the dll is never called because I even tried returning 1 no matter what expecting no new window would ever be created but instead everything was creating just fine.
So I would really appreciate some details on using my application as a shell and also if you have any suggestions why my hook does not work that would be great.

Thank you.





0
 
LVL 20

Expert Comment

by:Madshi
ID: 1355662
Please check these two things:

What does GetModuleHandle(...) return? Is it ok, or is it 0?
I should have said that. Of course you need to call LoadLibrary once before you can call GetModuleHandle.
Then please check what GetProcAddress(...) returns. Is it ok, or is it 0? You have to export the function in the dll to be able to access it via GetProcAddress.

Regards, Madshi.
0
 
LVL 20

Expert Comment

by:Madshi
ID: 1355663
Hmmm. Wait a minute... I'll try it...
0
 
LVL 20

Expert Comment

by:Madshi
ID: 1355664
Ok, put this into the dll:

library NewWndDll;

uses
  SysUtils,
  Classes,
  Windows;

function NewWindowHookCallBack(pCode: Integer; pHandle: WPARAM; pWindow: LPARAM): LRESULT; stdcall;
var s1 : string;
begin
  result:=0;
  if pCode=HCBT_CREATEWND then begin
    SetLength(s1,MAX_PATH+1);
    SetLength(s1,GetClassName(pHandle,pchar(s1),MAX_PATH));
    if s1='#32770' then result:=1;
  end;
end;

exports NewWindowHookCallBack index 1 name 'NewWindowHookCallBack';

end.

and this into the application:

unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

var hook : integer;

procedure TForm1.Button1Click(Sender: TObject);
begin
  hook:=SetWindowsHookEx(WH_CBT,
                         GetProcAddress(GetModuleHandle('NewWndDll'),'NewWindowHookCallBack'),
                         GetModuleHandle('NewWndDll'), 0);
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  UnhookWindowsHookEx(hook);
end;

initialization
  MessageBox(0,pchar(intToStr(LoadLibrary('c:\windows\desktop\newwnddll'))),'loadLibrary',0);
end.

Regards, Madshi.

P.S: You can replace the shell in win95/98 by changing "system.ini\[boot]\shell=Explorer.exe" to "system.ini\[boot]\shell=c:\yourProgramsPath\yourProgram.exe".
The effect is that on bootup windows starts your application instead of the explorer. That does not solve you window problem, but it is perhaps a good extension. Because if you don't like other windows to open, that sounds as if you would write your own explorer program...
0
 
LVL 5

Expert Comment

by:heathprovost
ID: 1355665
Hey Madshi, No problem about the answer.  I stashed your method away in my little snippet database.  I never knew how to do that.  Thanks.

Heath
0
 
LVL 20

Expert Comment

by:Madshi
ID: 1355666
:-)
0
 

Author Comment

by:alexandram
ID: 1355667
Thank you Madshi. It works great.

About the shell changed to my application, I tried that in the past because that would be ideal for my application. However I make use of an AppBar in my application (a form that is never covered by any other form like the desktop taskbar) as a status bar.  It turns out that this type of functionality is part of Explorer so it needs to be the shell.
0
 

Author Comment

by:alexandram
ID: 1355668
Hi Madshi,

Here is something I would like to do and it may be feasible with the hook I have. I would like to allow windows such as Media Player to be opened from the Web Browser but with a disabled menu. I was hoping to be able to detect when a handle is a menu with IsMenu(handle) but it seems that menus are not always really menus. Anyway, any idea how a menu can be disabled from an application which I did not write (like MS Word for example) ?

Thank you.


0
 
LVL 20

Expert Comment

by:Madshi
ID: 1355669
Hmmm. Try using SetWindowsHookEx(WH_GETMESSAGE). Then look at these messages: WM_INITMENUPOPUP and WM_INITMENU. Both messages give you the menu handle. Then you can manipulate the menu before it is displayed. Don't know if that works, but I think it will...  :-)

Regards, Madshi.
0

Featured Post

Networking for the Cloud Era

Join Microsoft and Riverbed for a discussion and demonstration of enhancements to SteelConnect:
-One-click orchestration and cloud connectivity in Azure environments
-Tight integration of SD-WAN and WAN optimization capabilities
-Scalability and resiliency equal to a data center

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Strange behavior when a form is closed 6 61
Graphics32 under Delphi 10.1 Berlin 2 96
enhance the following code 3 37
How to make Sign in, using Clientdataset? 1 28
The uses clause is one of those things that just tends to grow and grow. Most of the time this is in the main form, as it's from this form that all others are called. If you have a big application (including many forms), the uses clause in the in…
Hello everybody This Article will show you how to validate number with TEdit control, What's the TEdit control? TEdit is a standard Windows edit control on a form, it allows to user to write, read and copy/paste single line of text. Usua…
With Secure Portal Encryption, the recipient is sent a link to their email address directing them to the email laundry delivery page. From there, the recipient will be required to enter a user name and password to enter the page. Once the recipient …

809 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question