[Last Call] Learn about multicloud storage options and how to improve your company's cloud strategy. Register Now

x
?
Solved

how to close message box of another software

Posted on 2007-12-05
9
Medium Priority
?
250 Views
Last Modified: 2010-04-05
Hi,

We have documents automation program on our server which written by 3rd
party developer, it works ok except that sometimes give error with OK button
and waits for user response,
If this happens, program stop working and someone must connect to server and
click OK manually.

While I can't solve problem which leads to message box directly in software
I came to idea to build small utility which check for form caption(message
box is simple form, right)
and if such message box caption exists  programically click on button.

I have found how to find out message box handler by title, but how to click
on OK button in that message box(form)?
As I understand I need to iterate though all controls and somehow compare
their caption
and if OK caption exists I should execute "click" action. I don't know how
to do that and any suggestion would be welcome.


Regards,
Tomas
function FindWindowByTitle(WindowTitle: string): Hwnd;
var
  NextHandle: Hwnd;
  NextTitle: array[0..260] of char;
begin
  // Get the first window
  NextHandle := GetWindow(Application.Handle, GW_HWNDFIRST);
  while NextHandle > 0 do
  begin
    // retrieve its text
    GetWindowText(NextHandle, NextTitle, 255);
    if Pos(lowercase(WindowTitle), lowercase(StrPas(NextTitle))) <> 0 then
    begin
      Result := NextHandle;
      Exit;
    end
    else
      // Get the next window
      NextHandle := GetWindow(NextHandle, GW_HWNDNEXT);
  end;
  Result := 0;
end;

Open in new window

0
Comment
Question by:Tomazaz
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
  • 2
  • 2
  • +2
9 Comments
 
LVL 14

Expert Comment

by:SteveBay
ID: 20412452
Check this out. It's work well for me
http://www.delphi3000.com/articles/article_1617.asp?SK=
0
 
LVL 14

Expert Comment

by:SteveBay
ID: 20412497
The way I've used it is to find the dialog with FindWindow. Then set focus on the control (button) you wish to "Push" and then use:

SendKeys(' ',True);

This acts as though a space bar was pressed while the button was focused.
0
 
LVL 21

Expert Comment

by:developmentguru
ID: 20413053
If you have the handle of the window then the simple solution is to:
SendMessage(DialogHandle, WM_CLOSE);
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 21

Expert Comment

by:developmentguru
ID: 20413064
Sorry, forgot a couple of parameters

SendMessage(DialogHandle, WM_CLOSE, 0, 0);
0
 
LVL 16

Expert Comment

by:CodedK
ID: 20414323
Hi.

Send a "Tab" key then an "Enter"
Tab will set focus to the OK button.
0
 
LVL 28

Accepted Solution

by:
2266180 earned 2000 total points
ID: 20414702
I myself am using a more "advanced" tehnique. and that is because my use is mainly in services, just like your case, and usually you won't have a dialog to click ok to as the moment the dialog is displayed there is no user logged in for that service (even if there is somebody logged on the machine; the service itself will not have a "desktop") and hence the dialog wil not be visible for the logged in user.

the below code is stripped from one of my projects so I hope it compiles :D
type
  TCatcherThread=class(TThread)
  protected
    procedure execute; override;
  end;
 
....
 
type
  phwnd=^hwnd;
 
function EnumWindowsProc(wHandle: HWND; h:phwnd): Bool; stdcall; export;
var
  Title: array[0..255] of char;
begin
  GetWindowText(wHandle, Title, 255);
  result:=pos(lowercase(dialog title here), lowercase(title))=0;
  if not result then
    h^:=wHandle;
end;
 
function EnumProc(wnd: HWND; h:phwnd): BOOL; stdcall;
var
  Caption: array[0..255] of char;
begin
  SendMessage(wnd, WM_GETTEXT, 256, Integer(@Caption));
  result:=pos(button caption here in lowercase, lowercase(caption))=0;
  if not result then
    h^:=wnd;
end;
 
procedure TCatcherThread.execute;
var dlg, btn:phwnd;
begin
  while not terminated do
  begin
    sleep(100);// allow some "thinking time"
    new(dlg);
    try
      dlg^:=0;
      EnumWindows(@EnumWindowsProc, integer(dlg));
 
      if dlg^=0 then
        continue;
 
      new(btn);
      try
        btn^:=0;
        EnumChildWindows(dlg^, @EnumProc, integer(btn));
 
        //Clicking on button
        SendMessage(btn^, WM_LBUTTONDOWN, 5, 5);
        SendMessage(btn^, WM_LBUTTONUP, 5, 5);
        //Clicked on the button
      finally
        dispose(btn);
      end;
    finally
      dispose(dlg);
    end;
  end;
end;
 
....
 
 
in form/service create:
  catcher:=TCatcherThread.Create(false);
 
in form/service destroy
  catcher.WaitFor;
  freeandnil(catcher);

Open in new window

0
 
LVL 28

Expert Comment

by:2266180
ID: 20426316
a minor correction there:

in form/service destroy
  catcher.Terminate; // add this line
  catcher.WaitFor;
  freeandnil(catcher);


stripping code can be troublesome :)
0
 

Author Comment

by:Tomazaz
ID: 20470634
Very important, solution which I have accepted as correct do not work while Windows log off. The code find window but unable to click on button.
0
 
LVL 28

Expert Comment

by:2266180
ID: 20471221
hm... pretty weird. if it finds the window, it should be able to click on the button as well. makes no sence to me at this point.
can you click on that button while windows is closing? I am just thionking that maybe the application is to busy closing down and doesn't repond to the click in a timely fashion.
0

Featured Post

Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

Question has a verified solution.

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

A lot of questions regard threads in Delphi.   One of the more specific questions is how to show progress of the thread.   Updating a progressbar from inside a thread is a mistake. A solution to this would be to send a synchronized message to the…
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 course is ideal for IT System Administrators working with VMware vSphere and its associated products in their company infrastructure. This course teaches you how to install and maintain this virtualization technology to store data, prevent vuln…
In this video you will find out how to export Office 365 mailboxes using the built in eDiscovery tool. Bear in mind that although this method might be useful in some cases, using PST files as Office 365 backup is troublesome in a long run (more on t…
Suggested Courses

650 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