Solved

Detecting new windows

Posted on 1999-01-09
12
190 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
 

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
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 
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

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

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

Suggested Solutions

Introduction The parallel port is a very commonly known port, it was widely used to connect a printer to the PC, if you look at the back of your computer, for those who don't have newer computers, there will be a port with 25 pins and a small print…
Creating an auto free TStringList The TStringList is a basic and frequently used object in Delphi. On many occasions, you may want to create a temporary list, process some items in the list and be done with the list. In such cases, you have to…
This is a video describing the growing solar energy use in Utah. This is a topic that greatly interests me and so I decided to produce a video about it.
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 …

932 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

Need Help in Real-Time?

Connect with top rated Experts

9 Experts available now in Live!

Get 1:1 Help Now