Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

How to Close Annoying Third Party Application Windows

API Functions

How to Close Annoying Third Party Application Windows

by  wgcs  Posted    (Edited  )
Sometimes, programs will open a user interface dialog box when you are trying to programmatically control them.

KEYBOARD '{enter}' or KEYBOARD '{esc}' will sometimes close them, but often they won't work.

If you are sure the computers that your application is being deployed on all have the Windows Scripting Host, then This method is the simplest (thanks to mgagnon!):

Code:
oShell = CREATEOBJECT('Wscript.Shell')
oShell.AppActivate('title of the window')
oShell.SendKeys('{Enter}')
oShell = .NULL.

This basically encapsulates the Windows API for sending the keystroke messages. If you can't be sure that all your users have the WSH, then you can resort to directly using the Windows API messaging system.

Basically, in nearly all non-VFP programs, each "Window" or "Dialog Box" gets a window handle, each "Textbox", "Label" and "CommandButton" also get their own window handle. This means messages (like "MouseDown...MouseUp", or "Please Close") can be sent directly to their window handles. Additionally, you can obtain these window handles with nothing more than the caption associated with the windows...

This opens up new automation possibilities!

This code will close most UI dialog boxes:


Code:
PROCEDURE CloseWindow
LPARAMETERS pcTitle, pcButtonCaption

#DEFINE WM_COMMAND     0x0111
#DEFINE WM_LBUTTONDOWN 0x0201
#DEFINE WM_LBUTTONUP   0x0202

DECLARE INTEGER FindWindow IN user32; 
    STRING lpClassName,; 
    STRING lpWindowName 

DECLARE INTEGER FindWindowEx IN user32;
  INTEGER hwndParent,       ;
  INTEGER hwndChildAfter,   ;
  STRING lpszClassName,    ;
  STRING lpszWindowCaption 
 
DECLARE INTEGER SendMessage IN user32; 
    INTEGER hWnd,; 
    INTEGER Msg,; 
    INTEGER wParam,; 
    INTEGER lParam 

  wndDialog = FindWindow( 0, pcTitle )
  wndButton = 0
  
  if wndDialog > 0    
    * Sometimes Message WM_COMMAND 0x00110818 isn't enough,
    *  if you MUST click "Cancel" or "Yes", etc
    *  then provide a button caption
    if VarType(pcButtonCaption)='C'
       wndButton = FindWindowEx( wndDialog, 0, 'Button', ;
                                 pcButtonCaption )      
       if wndButton > 0
         SendMessage(wndButton, WM_LBUTTONDOWN, 1, 0x00120025 )
         SendMessage(wndButton, WM_LBUTTONUP,   0, 0x00120025 )
         * Button Clicked message
         SendMessage(wndDialog, WM_COMMAND,     3, wndButton  )
       endif
    endif
    
    SendMessage(wndDialog, WM_COMMAND, 1, 0x00110818 )
  endif
return Str(wndDialog,10)+str(wndButton,10)

To demonstrate this code, open two instances of VFP.
In the first, issue:

Code:
? messagebox("click Abort Retry or Ignore",2,"Special")

Then, in the second, issue:
Code:
  ?closewindow("Special","&Abort")
* Now, go back to the first and show the message box again
  ?closewindow("Special","&Retry")
* Now, go back to the first and show the message box again
  ?closewindow("Special","&Ignore")

(Notice the "&" that makes "&Abort" into "Abort"? It's officially part of the window caption, so you need it!)




Register to rate this FAQ  : BAD 1 2 3 4 5 6 7 8 9 10 GOOD
Please Note: 1 is Bad, 10 is Good :-)

Part and Inventory Search

Back
Top