×
INTELLIGENT WORK FORUMS
FOR COMPUTER PROFESSIONALS

Log In

Come Join Us!

Are you a
Computer / IT professional?
Join Tek-Tips Forums!
  • Talk With Other Members
  • Be Notified Of Responses
    To Your Posts
  • Keyword Search
  • One-Click Access To Your
    Favorite Forums
  • Automated Signatures
    On Your Posts
  • Best Of All, It's Free!

*Tek-Tips's functionality depends on members receiving e-mail. By joining you are opting in to receive e-mail.

Posting Guidelines

Promoting, selling, recruiting, coursework and thesis posting is forbidden.

Students Click Here

Wasteful FindWindow

Wasteful FindWindow

Wasteful FindWindow

(OP)
From within my applications I need to check if another application is loaded.

I tried the enum EnumWindows() API and the FindWindow API.
I set up a chronometer within the code and the results I got are that FindWindow takes 64ms to complete and EnumWindows() takes 0 ms to complete.  How can this be.  Is FindWindow so bad?

Is EnumWindows run in a seperate thread or something?
In that case, how do I stop my application to wait for that thread to finish.  I need to wait for it since my code depends on the results of this thread.

BTW, my PC is an AMD 2100XP, if performance is an issue.

Thanks.

RE: Wasteful FindWindow

I wrote a small program to consider your questions and my investigation provide the following answers:

- FindWindow is not so bad in comparison to EnumWindows
- EnumWindows does not run on a separate thread
- It is most likely that you are returning false on your EnumWindows callback prematurely


More explanation
EnumWindows will call its callback each time it finds a window. The first window is found very very quickly (in my PC finding the window took a fraction of millisecond). Now if you return false on your EnumWindows callback then no more windows will be enumerated. End result EnumWindows will finish very quickly.

In comparison FindWindow is looking for a window of a certain type, and this window may not be the first to be found therefore it may take a little more time that the above scenario of enumerating only the first window.

The following code may clarify what i mean a little more

You will need to create a form with two buttons and one TMemo controls and apply the sample code to it.

I hope it will help

CODE


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

type
  TmyForm = class(TForm)
    EnumTimes: TMemo;
    Panel1: TPanel;
    Button1: TButton;
    Button2: TButton;
    procedure Button2Click(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    fEnumCalled:TDateTime;
    fFindCalled:TDateTime;
    fFindTime:Integer;
  public

  end;

var
  myForm: TmyForm;

implementation
{$R *.dfm}

uses
  DateUtils;

//Careful with definition of this routine (dont forget stdcall)
//otherwise your parameters wont be passed in good order
function OnWindowFound(wnd:HWND; myParam:Integer):Boolean;  stdcall;
var
  sender:TMyForm;
  sWindowName:string;
  nEnumTime:integer;
  processID:DWORD;
begin
    //in this example myParam will contain reference to a TMyForms object
    sender:=TMyForm(myParam);

    //Get the title of this window
    SetLength(sWindowName,255);
    GetWindowText(wnd,Pchar(sWindowName),255);

    //Because in your case most windows are in a different process it is
    //slightly more efficient if you use SendMessage to get the window name
    //SendMessage(wnd,WM_GETTEXT,255,pChar(sWindowName));

    //Calculate the time taken up to here
    nEnumTime:=MillisecondsBetween(Now,myform.fEnumCalled);

    //Add the window and time taken to find it in EnumTimes Memo lines
    sender.EnumTimes.Lines.Add(Format('EnumWindow took %d milliseconds to find '+sWindowName,[nEnumTime]));

    //Continue looking for more windows
    result:=true; //return false if you found what you wanted
end;

procedure TmyForm.Button1Click(Sender: TObject);
var
  nEnumTime:integer;
  lp:Integer;
begin
     //Time of EnumWindows call
     fEnumCalled:=Now();
     EnumWindows(@OnWindowFound,integer(self));
     nEnumTime:=MilliSecondsBetween(Now,self.fEnumCalled);

     //Add the time that enum took to complete in EnumTimes list
     self.EnumTimes.Lines.Add(Format('EnumWindow returned after %d milliseconds',[nEnumTime]));
end;

procedure TmyForm.Button2Click(Sender: TObject);
var
  nFindTime:integer;
  p:PChar;
  sWindowName:string;
  wnd:HWND;
begin
     //Time of FindWindow call
     fFindCalled:=Now();
     wnd:=FindWindow('TMyForm',nil);
     if wnd<>0 then
     begin
       //How long did it take ?
       nFindTime:=MilliSecondsBetween(Now,fFindCalled);

       //Show how long did FindWindow take
       ShowMessage(Format('Find window took %d milliseconds',[nFindTime]));

       //Retreive the window caption. (this time using SendMessage (just another way))
       SetLength(sWindowName,255);
       SendMessage(wnd,WM_GETTEXT,255,integer(p));
     end
     else
       ShowMessage('Could not find any window of class TMyForm');

end;




"It is in our collective behaviour that we are most mysterious" Lewis Thomas

Red Flag This Post

Please let us know here why this post is inappropriate. Reasons such as off-topic, duplicates, flames, illegal, vulgar, or students posting their homework.

Red Flag Submitted

Thank you for helping keep Tek-Tips Forums free from inappropriate posts.
The Tek-Tips staff will check this out and take appropriate action.

Reply To This Thread

Posting in the Tek-Tips forums is a member-only feature.

Click Here to join Tek-Tips and talk with other members! Already a Member? Login

Close Box

Join Tek-Tips® Today!

Join your peers on the Internet's largest technical computer professional community.
It's easy to join and it's free.

Here's Why Members Love Tek-Tips Forums:

Register now while it's still free!

Already a member? Close this window and log in.

Join Us             Close