Remotely Controlling Windows Apps
by Ruben Patel 

Listing One

1   // Header
2   #ifndef __GLOBAL_HH__
3   #define __GLOBAL_HH__
4   #include <windows.h>
5
6   typedef struct
7   {
8       HWND    hwnd;
9       const char *title;
10  } FindWnd;
11
12  CALLBACK CheckWindowTitle( HWND hwnd, LPARAM lParam );
13  HWND FindWinTitle(const char *title);
14  HWND FindWndByTitle(const char *parent,const char *child);
15  HWND WaitForDialogToOpen(char *parent,int timeout);
16  HWND WaitForDialogToClose(char *parent);
17  HWND OnShotOpenDialog(char *parent);
18  HWND LeftClickInAt(const char *parent,const char *child,int x,int y);
19
20  #endif

1   // Cpp file
2   #include "Global.h"
3
4   // Se if the specified window has a specified title
5   CALLBACK CheckWindowTitle( HWND hwnd, LPARAM lParam )
6   {
7       char    buffer[MAX_PATH];
8       // Get the window title form window
9       GetWindowText( hwnd, buffer, sizeof( buffer ) );
10      FindWnd * fw = (FindWnd *)lParam;
11      // Compare window tile with title to be checked.
12      if(strcmp( buffer, fw->title ) == 0 )
13      {
14          fw->hwnd = hwnd;
15          return FALSE;
16      }
17      return TRUE;
18  }
19  // Find a parent window by it window title
20  HWND FindWinTitle(const char *title)
21  {
22     FindWnd fw;
23      fw.hwnd = 0;
24      fw.title = title;
25      EnumWindows( (WNDENUMPROC) CheckWindowTitle, (LPARAM) &fw );
26      return fw.hwnd;
27  }
28  // Find a child window by it window title
29  HWND FindWndByTitle(const char *parent,const char *child)
30  {
31      FindWnd fw;
32      fw.hwnd = 0;
33      fw.title = child;
34      HWND hWnd = FindWinTitle(parent);
35      if(child==NULL) return hWnd;
36      else
27      {
28     ::EnumChildWindows(hWnd, (WNDENUMPROC) CheckWindowTitle, (LPARAM) &fw);
29          return fw.hwnd;
40      }
41
42  }
43  // Halt until a dialog is opened
44  HWND WaitForDialogToOpen(char *dlgName,int timeout)
45  {
46      HWND    hWndDlg;
47      hWndDlg = NULL;
48      // Loop until the window is opened
49      do
50      {
51          hWndDlg= FindWndByTitle(dlgName,NULL);
52      } while(!hWndDlg);
53      return hWndDlg;
54  }
55  // Halt until a dialog is closed
56  HWND WaitForDialogToClose(char *dlgName)
57  {
58      HWND    hWndDlg;
59      hWndDlg = NULL;
60      // Loop until the window is opened
61      do
62      {
63          hWndDlg= FindWndByTitle(dlgName,NULL);
64      } while(hWndDlg);
65      return hWndDlg;
66  }
67  // Open dialog
68  HWND OnShotOpenDialog(char *dlgName)
69  {
70      HWND    hWndDlg;
71      hWndDlg = NULL;
72      // Get the handler
73      hWndDlg= FindWndByTitle(dlgName,NULL);
74      return hWndDlg;
75  }
76  // Left click in a child window at position x,y
77 HWND LeftClickInAt(const char *parent,const char *child,int x,int y)
78  {
79      // Get window handler
80      HWND    hWnd = FindWndByTitle(parent,child);
81      WPARAM wParam = MK_RBUTTON;
82      LPARAM lParam = MAKELPARAM(x,y);
83      // simulating left mouse click in window
84      if(!::PostMessage(hWnd, WM_RBUTTONDOWN ,wParam,lParam))
85          return NULL;
86      return hWnd;
87  }


Listing Two

1   // RDialog.h: interface for the CRDialog class.
2   #ifndef __CRDialog_H
3   #define __CRDialog_H
4
5   #include <windows.h>
6
7   class CRDialog
8   {
9   public:
10      CRDialog(char *parent,char *child);
11      ~CRDialog();
12
13      HWND    IsDialogOpen(char *dlgName); // Check if the dialog
                                             // with name in dlgName is open
14      long    SetText(int nIDDlgItem,char *text);  // Set text in a control
15      DWORD   SetCheck(int nIDDlgItem,BOOL checked);  // Check or
                                                        // uncheck a check box
16      HWND    CloseDialog(void);              // Close this dialog box
17      BOOL    PressButton(int nIDDlgItem);   // Press a button
18
19      char *m_sParent;                       // String to parent window
20      char *m_sChild;                        // String to this dialog box
21
22  };
23  #endif

1   // CRDialog class implementation
2   #include <stdio.h>
3   #include "CRDialog.h"
4   #include "Global.h"
5   #include "EK60MK1ID.h"
6
7   // Set string of parent and child window
8   CRDialog::CRDialog(char *parent,char *child)
9   {
10      int len1=strlen(parent)+1;
11      int len2=strlen(child)+1;
12      m_sParent = new char[len1];
13      m_sChild = new char[len2];
14      sprintf(m_sParent,"%s",parent);
15      sprintf(m_sChild,"%s",child);
16  }
17  CRDialog::~CRDialog()
18 {
19      delete[] m_sParent;
20      delete[] m_sChild;
21  }
22  // Close dialog box
23  HWND CRDialog::CloseDialog(void)
24  {
25      // Find handler of dialog box form string
26      HWND    hWndDlg = FindWinTitle(m_sChild);
27      // Close dialog by pressing the OK button
28      ::SendDlgItemMessage(hWndDlg,RIDC_BUTTON_OK,BM_CLICK,0,0);
29      // wait for dialog to close
30      return WaitForDialogToClose(m_sChild);
31  }
32  // Return handler of dialog specified by window name
33  HWND CRDialog::IsDialogOpen(char *dlgName)
34  {
35      return FindWndByTitle(dlgName,NULL);
36  }
27  // Set text in control in dialog box
28  long CRDialog::SetText(int nIDDlgItem,char *text)
29  {
40  return::SendDlgItemMessage(FindWndByTitle(m_sChild,NULL),
                         nIDDlgItem,WM_SETTEXT,0,(LPARAM)text);
41  }
42  // Check or uncheck a check control
43  DWORD CRDialog::SetCheck(int nIDDlgItem,BOOL checked)
44  {
45      // manipulate control in dialog
46      DWORD   wParam ;
47      // Check it
48      wParam = (WPARAM) (checked)?(BST_CHECKED):(BST_UNCHECKED);
49  ::SendDlgItemMessage(FindWndByTitle(m_sChild,NULL),nIDDlgItem,
                                               BM_SETCHECK,wParam,0);
50      // Check if success
51      return::SendDlgItemMessage(FindWndByTitle(m_sChild,NULL),
                     nIDDlgItem,BM_GETSTATE,0,0);
52  }
53  // Press a button
54  BOOL CRDialog::PressButton(int nIDDlgItem)
55  {
56      HWND hWndDlg;
57      // Check if the dialog is open
58      hWndDlg = IsDialogOpen(m_sChild);
59      // get handler of button to press
60      HWND hWndCont = ::GetDlgItem(hWndDlg,nIDDlgItem);
61      // Press it
62      ::PostMessage(hWndCont,BM_CLICK,0,0);
63      return TRUE;
64  }


Listing Three

1   // BI500RemoteDlg.h: interface for the BI500RemoteDlg class.
2   #ifndef __BI500RemoteDialog_H
3   #define __BI500RemoteDialog_H
4
5   #include "EK60MK1ID.h"
6   #include "CRDialog.h"
7
8   class CBI500RemoteDlg:public CRDialog
9   {
10  public:
11      CBI500RemoteDlg(char *parent,char *child);
12      virtual ~CBI500RemoteDlg();
13
14      BOOL PressButtonSurfaceRange();
15      BOOL PressButtonOK();
16  private:
17      HWND OpenDialog(void);
18      BOOL SetText(int nIDDlgItem,char *text);
19      BOOL PressButton(int nIDDlgItem);
20
21  };
22
23  #endif

1   // BI500RemoteDlg.cpp: implementation of the BI500RemoteDlg class.
2
3   #include "CBI500RemoteDlg.h"
4   #include "global.h"
5
6
7   CBI500RemoteDlg::CBI500RemoteDlg(char *parent,char *child)
8       :CRDialog(parent,child)
9   {}
10  CBI500RemoteDlg::~CBI500RemoteDlg()
11  {}
12  HWND CBI500RemoteDlg::OpenDialog(void)
13  {
14      HWND    hWndDlg;
15      // Check if dialog is already open
16      hWndDlg = IsDialogOpen(m_sChild);
17      if(hWndDlg) return hWndDlg;
18      // Open the dialog
19      if(!::PostMessage(FindWinTitle(m_sParent), WM_COMMAND,
                                RID_INSTALL_BI500,0 )) return NULL;
20      // get dialog handler
21      hWndDlg = WaitForDialogToOpen(m_sChild,1000);
22      return hWndDlg;
23  }
24  BOOL CBI500RemoteDlg::SetText(int nIDDlgItem,char *text)
25  {
26      OpenDialog();
27      CRDialog::SetText(nIDDlgItem,text);
28      CloseDialog();
29      return TRUE;
30  }
31  BOOL CBI500RemoteDlg::SetSurfVals(char *Surf)
32  {
33      SetText(RIDC_LIST_NOSURFVALS,Surf);
34      return TRUE;
35  }
36
37
38 BOOL CBI500RemoteDlg::PressButton(int nIDDlgItem)
39  {
40      HWND hWndDlg;
41      hWndDlg = IsDialogOpen(m_sChild);
42      if(!hWndDlg) hWndDlg=OpenDialog();
43      HWND hWndCont = ::GetDlgItem(hWndDlg,nIDDlgItem);
44      ::PostMessage(hWndCont,BM_CLICK,0,0);
45      return TRUE;
46  }
47
48  BOOL CBI500RemoteDlg::PressButtonSurfaceRange()
49  {
50      return PressButton(RIDC_BUTTON_SURFRANGE);
51  }
52  BOOL CBI500RemoteDlg::PressButtonOK()
53  {
54      return PressButton(RIDC_BUTTON_OK);
55  }


Listing Four

1   // CSurfRangeRemoteDlg: interface.
2   #ifndef _SURFRANGEREMOTEDLG_H
3   #define _SURFRANGEREMOTEDLG_H
4
5   #include "EK60MK1ID.h"
6   #include "CRDialog.h"
7   #include "CBI500RemoteDlg.h"
8   #include "Global.h"
9
10  class CSurfRangeRemoteDlg :public CRDialog
11  {
12  public:
13      CSurfRangeRemoteDlg(char *parent,char *child);
14      virtual ~CSurfRangeRemoteDlg();
15
16      BOOL SetRange(char *range);
17      BOOL SetStart(char *start);
18
19  private:
20      HWND OpenDialog(void);
21      HWND CloseDialog(void);
22      BOOL SetText(int nIDDlgItem,char *text);
23  };
24
25  #endif

1   // CSurfRangeRemoteDlg: implementation.
2   #include "SurfRangeRemoteDlg.h"
3
4   CSurfRangeRemoteDlg::CSurfRangeRemoteDlg(char *parent,char *child)
5   :CRDialog(parent,child)
6   {}
7   CSurfRangeRemoteDlg::~CSurfRangeRemoteDlg()
8   {}
9  HWND CSurfRangeRemoteDlg::OpenDialog(void)
10  {
11      HWND    hWndDlg;
12      // Open BI500 dialog
13      CBI500RemoteDlg BI500RDlg(m_sParent,"BI500 Dialog");
14      // Press the Surface Range button in the BI500 dialog
15      BI500RDlg.PressButtonSurfaceRange();
16      hWndDlg = WaitForDialogToOpen(m_sChild,1000);
17      return hWndDlg;
18  }
19  HWND CSurfRangeRemoteDlg::CloseDialog(void)
20  {
21      HWND    hWndDlg = FindWinTitle(m_sChild);
22      // Close dialog
23      ::SendDlgItemMessage(hWndDlg,RIDC_BUTTON_OK,BM_CLICK,0,0);
24      // wait for dialog to close
25          WaitForDialogToClose(m_sChild);
26      //CRDialog::CloseDialog();
27      CBI500RemoteDlg BI500RDlg(m_sParent,"BI500 Dialog");
28      BI500RDlg.PressButtonOK();
29      return NULL;
30  }
31
32
33  BOOL CSurfRangeRemoteDlg::SetText(int nIDDlgItem,char *text)
34  {
35      OpenDialog();
36      CRDialog::SetText(nIDDlgItem,text);
37      CloseDialog();
38      return TRUE;
39  }
40
41  BOOL CSurfRangeRemoteDlg::SetRange(char *range)
42  {
43      SetText(RIDC_LIST_SRANGE,range) ;
44      return TRUE;
45  }
46
47  BOOL CSurfRangeRemoteDlg::SetStart(char *start)
48  {
49      SetText(RIDC_LIST_STARTSURF,start);
50      return TRUE;
51  };

Listing Five

1   #define RID_INSTALL_BI500       32878   // ID to activate BI500 dialog
2   #define RIDC_BUTTON_SURFRANGE   0x510   // Button to push for activating
                                            // Surface Range Dialog box.
3   #define RIDC_LIST_SRANGE        0x3ec   // ID for surface range text box
4   #define RIDC_BUTTON_OK          0x01    // Ok button id
Listing Six
1   #define IsInRange(val,min,max) if(val>=min && val<=max)
2   nRang=200;
3  startEK60MK1App();// Start sensor program if not started
4   IsInRange(nRange,0,15000)   // Check range
5   {
6       char val[5];
7       itoa(nRange,val,10);
8       CsurfRangeRemoteDlg *surfRangeDlg
9       = new CSurfRangeRemoteDlg("SIMRADEK60","SurfaceRange Dialog");
10      surfRangeDlg->SetRange(val); // Set range
11      delete surfRangeDlg;
12  }



