Solved

Detecting new windows

Posted on 1999-01-09
12
187 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
What Should I Do With This Threat Intelligence?

Are you wondering if you actually need threat intelligence? The answer is yes. We explain the basics for creating useful threat intelligence.

 
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

Top 6 Sources for Identifying Threat Actor TTPs

Understanding your enemy is essential. These six sources will help you identify the most popular threat actor tactics, techniques, and procedures (TTPs).

Join & Write a Comment

Introduction I have seen many questions in this Delphi topic area where queries in threads are needed or suggested. I know bumped into a similar need. This article will address some of the concepts when dealing with a multithreaded delphi database…
Introduction Raise your hands if you were as upset with FireMonkey as I was when I discovered that there was no TListview.  I use TListView in almost all of my applications I've written, and I was not going to compromise by resorting to TStringGrid…
In this seventh video of the Xpdf series, we discuss and demonstrate the PDFfonts utility, which lists all the fonts used in a PDF file. It does this via a command line interface, making it suitable for use in programs, scripts, batch files — any pl…
This video shows how to remove a single email address from the Outlook 2010 Auto Suggestion memory. NOTE: For Outlook 2016 and 2013 perform the exact same steps. Open a new email: Click the New email button in Outlook. Start typing the address: …

746 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

12 Experts available now in Live!

Get 1:1 Help Now