ReactOS  0.4.14-dev-49-gfb4591c
wclickat.c File Reference
#include <windows.h>
#include <windowsx.h>
#include <stdio.h>
#include <ctype.h>
Include dependency graph for wclickat.c:

Go to the source code of this file.

Macros

#define APP_NAME   "wclickat"
 
#define DEFAULT_DELAY   500
 
#define DEFAULT_REPEAT   1000
 
#define ARRAY_LENGTH(array)   (sizeof(array)/sizeof((array)[0]))
 
#define RC_RUNNING   -1
 
#define RC_SUCCESS   0
 
#define RC_INVALID_ARGUMENTS   1
 
#define RC_NODISPLAY   2
 
#define RC_TIMEOUT   3
 
#define __PRINTF_ATTR(fmt, args)
 

Enumerations

enum  action_type {
  ACTION_INVALID, ACTION_FIND, ACTION_LCLICK, ACTION_MCLICK,
  ACTION_RCLICK
}
 

Functions

static int init_debug ()
 
static void cxlog (const char *format,...) __PRINTF_ATTR(1
 
static void usage (void)
 
static const WCHARmy_strstriW (const WCHAR *haystack, const WCHAR *needle)
 
static BOOL CALLBACK find_control (HWND hwnd, LPARAM lParam)
 
static BOOL CALLBACK find_top_window (HWND hwnd, LPARAM lParam)
 
static HWND find_window ()
 
static void do_click (HWND window, DWORD down, DWORD up)
 
static void CALLBACK ClickProc (HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime)
 
static void CALLBACK DelayProc (HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime)
 
static void CALLBACK FindWindowProc (HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime)
 
static void CALLBACK TimeoutProc (HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime)
 
static int arg_get_long (const char ***argv, const char *name, long *value)
 
static int arg_get_utf8 (const char ***argv, const char *name, WCHAR **value)
 
static int parse_arguments (int argc, const char **argv)
 
int main (int argc, const char **argv)
 

Variables

static const WCHAR STATIC_CLASS [] ={'s','t','a','t','i','c','\0'}
 
static int status
 
static action_type g_action = ACTION_INVALID
 
static WCHARg_window_class = NULL
 
static WCHARg_window_title = NULL
 
static long g_control_id = 0
 
static WCHARg_control_class = NULL
 
static WCHARg_control_caption = NULL
 
static long g_x = -1
 
static long g_y = -1
 
static long g_dragto_x = -1
 
static long g_dragto_y = -1
 
static long g_disabled = 0
 
static long g_delay = DEFAULT_DELAY
 
static long g_timeout = 0
 
static long g_repeat = 0
 
static long g_untildeath = 0
 
static UINT timer_id
 
static int debug_on =0
 

Macro Definition Documentation

◆ __PRINTF_ATTR

#define __PRINTF_ATTR (   fmt,
  args 
)

Definition at line 88 of file wclickat.c.

◆ APP_NAME

#define APP_NAME   "wclickat"

Definition at line 35 of file wclickat.c.

◆ ARRAY_LENGTH

#define ARRAY_LENGTH (   array)    (sizeof(array)/sizeof((array)[0]))

Definition at line 39 of file wclickat.c.

◆ DEFAULT_DELAY

#define DEFAULT_DELAY   500

Definition at line 36 of file wclickat.c.

◆ DEFAULT_REPEAT

#define DEFAULT_REPEAT   1000

Definition at line 37 of file wclickat.c.

◆ RC_INVALID_ARGUMENTS

#define RC_INVALID_ARGUMENTS   1

Definition at line 49 of file wclickat.c.

◆ RC_NODISPLAY

#define RC_NODISPLAY   2

Definition at line 50 of file wclickat.c.

◆ RC_RUNNING

#define RC_RUNNING   -1

Definition at line 47 of file wclickat.c.

◆ RC_SUCCESS

#define RC_SUCCESS   0

Definition at line 48 of file wclickat.c.

◆ RC_TIMEOUT

#define RC_TIMEOUT   3

Definition at line 51 of file wclickat.c.

Enumeration Type Documentation

◆ action_type

Enumerator
ACTION_INVALID 
ACTION_FIND 
ACTION_LCLICK 
ACTION_MCLICK 
ACTION_RCLICK 

Definition at line 54 of file wclickat.c.

Function Documentation

◆ arg_get_long()

static int arg_get_long ( const char ***  argv,
const char name,
long value 
)
static

Definition at line 402 of file wclickat.c.

403 {
404  if (!**argv)
405  {
406  fprintf(stderr, "error: missing argument for '%s'\n", name);
407  return 1;
408  }
409 
410  *value=atol(**argv);
411  if (*value < 0)
412  {
413  fprintf(stderr, "error: invalid argument '%s' for '%s'\n",
414  **argv, name);
415  (*argv)++;
416  return 1;
417  }
418  (*argv)++;
419  return 0;
420 }
#define argv
Definition: mplay32.c:18
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
_Check_return_ long __cdecl atol(_In_z_ const char *_Str)
Definition: name.c:36
FILE * stderr

Referenced by parse_arguments().

◆ arg_get_utf8()

static int arg_get_utf8 ( const char ***  argv,
const char name,
WCHAR **  value 
)
static

Definition at line 422 of file wclickat.c.

423 {
424  int len;
425 
426  if (!**argv)
427  {
428  fprintf(stderr, "error: missing argument for '%s'\n", name);
429  return 1;
430  }
431 
432  len = MultiByteToWideChar(CP_UTF8, 0, **argv, -1, NULL, 0);
433  *value = HeapAlloc(GetProcessHeap(), 0, len*sizeof(WCHAR));
434  if (!*value)
435  {
436  fprintf(stderr, "error: memory allocation error\n");
437  (*argv)++;
438  return 1;
439  }
440  MultiByteToWideChar(CP_UTF8, 0, **argv, -1, *value, len);
441  (*argv)++;
442  return 0;
443 }
#define argv
Definition: mplay32.c:18
#define CP_UTF8
Definition: nls.h:20
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
smooth NULL
Definition: ftsmooth.c:416
#define GetProcessHeap()
Definition: compat.h:395
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
__wchar_t WCHAR
Definition: xmlstorage.h:180
GLenum GLsizei len
Definition: glext.h:6722
#define MultiByteToWideChar
Definition: compat.h:100
Definition: name.c:36
FILE * stderr

Referenced by parse_arguments().

◆ ClickProc()

static void CALLBACK ClickProc ( HWND  hwnd,
UINT  uMsg,
UINT_PTR  idEvent,
DWORD  dwTime 
)
static

Definition at line 317 of file wclickat.c.

318 {
319  HWND window = find_window();
320 
321  if (!window)
322  {
323  if (g_untildeath)
324  {
325  /* FIXME: The window / control might just be disabled and if
326  * that's the case we should not exit yet. But I don't expect
327  * --untildeath to be used at all anyway so fixing this can
328  * wait until it becomes necessary.
329  */
331  }
332  else
333  cxlog("The window has disappeared!\n");
334  return;
335  }
336 
337  switch (g_action)
338  {
339  case ACTION_FIND:
340  /* Nothing to do */
341  break;
342  case ACTION_LCLICK:
343  cxlog("Sending left click\n");
345  break;
346  case ACTION_MCLICK:
347  cxlog("Sending middle click\n");
349  break;
350  case ACTION_RCLICK:
351  cxlog("Sending right click\n");
353  default:
354  fprintf(stderr, "error: unknown action %d\n", g_action);
355  break;
356  }
357  if (!g_repeat)
359 }
#define MOUSEEVENTF_LEFTDOWN
Definition: winuser.h:1170
static long g_repeat
Definition: wclickat.c:77
#define MOUSEEVENTF_MIDDLEDOWN
Definition: winuser.h:1174
#define MOUSEEVENTF_MIDDLEUP
Definition: winuser.h:1175
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
static void do_click(HWND window, DWORD down, DWORD up)
Definition: wclickat.c:260
static long g_untildeath
Definition: wclickat.c:78
static void cxlog(const char *format,...) __PRINTF_ATTR(1
Definition: wclickat.c:100
static HWND find_window()
Definition: wclickat.c:251
#define MOUSEEVENTF_LEFTUP
Definition: winuser.h:1171
static IHTMLWindow2 * window
Definition: events.c:77
#define MOUSEEVENTF_RIGHTUP
Definition: winuser.h:1173
static action_type g_action
Definition: wclickat.c:62
FILE * stderr
#define RC_SUCCESS
Definition: wclickat.c:48
#define MOUSEEVENTF_RIGHTDOWN
Definition: winuser.h:1172
Definition: ps.c:97

Referenced by DelayProc().

◆ cxlog()

static void static void cxlog ( const char format,
  ... 
)
static

Definition at line 100 of file wclickat.c.

101 {
102  va_list valist;
103 
104  if (debug_on)
105  {
108  va_end(valist);
109  }
110 }
static int debug_on
Definition: wclickat.c:90
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: gl.h:1546
#define va_end(ap)
Definition: acmsvcex.h:90
char * va_list
Definition: acmsvcex.h:78
#define va_start(ap, A)
Definition: acmsvcex.h:91
FILE * stderr
static __ms_va_list valist
Definition: printf.c:59
_Check_return_opt_ _CRTIMP int __cdecl vfprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format, va_list _ArgList)

Referenced by ClickProc(), DelayProc(), FindWindowProc(), and main().

◆ DelayProc()

static void CALLBACK DelayProc ( HWND  hwnd,
UINT  uMsg,
UINT_PTR  idEvent,
DWORD  dwTime 
)
static

Definition at line 361 of file wclickat.c.

362 {
364  timer_id=0;
365  if (g_repeat)
366  {
367  cxlog("Setting up a timer for --repeat\n");
369  }
370 
371  ClickProc(NULL, 0, 0, 0);
372 }
static void CALLBACK ClickProc(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime)
Definition: wclickat.c:317
static long g_repeat
Definition: wclickat.c:77
smooth NULL
Definition: ftsmooth.c:416
UINT_PTR WINAPI SetTimer(_In_opt_ HWND, _In_ UINT_PTR, _In_ UINT, _In_opt_ TIMERPROC)
static void cxlog(const char *format,...) __PRINTF_ATTR(1
Definition: wclickat.c:100
BOOL WINAPI KillTimer(_In_opt_ HWND, _In_ UINT_PTR)
static UINT timer_id
Definition: wclickat.c:79

Referenced by FindWindowProc().

◆ do_click()

static void do_click ( HWND  window,
DWORD  down,
DWORD  up 
)
static

Definition at line 260 of file wclickat.c.

261 {
262  WINDOWINFO window_info;
263  long x, y;
264 
266  window_info.cbSize=sizeof(window_info);
267  GetWindowInfo(window, &window_info);
268 
269  /* The calculations below convert the coordinates so they are absolute
270  * screen coordinates in 'Mickeys' as required by mouse_event.
271  * In mickeys the screen size is always 65535x65535.
272  */
273  x=window_info.rcWindow.left+g_x;
275  x=(window_info.rcWindow.right+window_info.rcWindow.left)/2;
276  x=(x << 16)/GetSystemMetrics(SM_CXSCREEN);
277 
278  y=window_info.rcWindow.top+g_y;
280  y=(window_info.rcWindow.bottom+window_info.rcWindow.top)/2;
281  y=(y << 16)/GetSystemMetrics(SM_CYSCREEN);
282 
284  if (down) {
286  if ((g_dragto_x > 0) && (g_dragto_y > 0)) {
287  int i;
288  long dx, dy;
289  long step_per_x, step_per_y;
290  long dragto_x, dragto_y;
291 
292  dragto_x=window_info.rcWindow.left+g_dragto_x;
293  if (dragto_x<window_info.rcWindow.left || dragto_x>=window_info.rcWindow.right)
294  dragto_x=(window_info.rcWindow.right+window_info.rcWindow.left)/2;
295  dragto_x=(dragto_x << 16)/GetSystemMetrics(SM_CXSCREEN);
296 
297  dragto_y=window_info.rcWindow.top+g_dragto_y;
298  if (dragto_y<window_info.rcWindow.top || dragto_y>=window_info.rcWindow.bottom)
299  dragto_y=(window_info.rcWindow.bottom+window_info.rcWindow.top)/2;
300  dragto_y=(dragto_y << 16)/GetSystemMetrics(SM_CYSCREEN);
301 
302  dx = g_dragto_x - g_x;
303  dy = g_dragto_y - g_y;
304  step_per_x = dx / 4;
305  step_per_y = dy / 4;
306  for (i = 0; i < 4; i++) {
307  mouse_event(MOUSEEVENTF_MOVE, step_per_x, step_per_y, 0, 0);
308  }
309  x=dragto_x;
310  y=dragto_y;
311  }
312  }
313  if (up)
315 }
DWORD cbSize
Definition: winuser.h:3740
#define MOUSEEVENTF_ABSOLUTE
Definition: winuser.h:1180
GLint dy
Definition: linetemp.h:97
LONG top
Definition: windef.h:292
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
LONG left
Definition: windef.h:291
LONG right
Definition: windef.h:293
#define down(mutex)
Definition: glue.h:29
#define up(mutex)
Definition: glue.h:30
#define SM_CXSCREEN
Definition: winuser.h:949
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
void WINAPI mouse_event(_In_ DWORD, _In_ DWORD, _In_ DWORD, _In_ DWORD, _In_ ULONG_PTR)
RECT rcWindow
Definition: winuser.h:3741
#define SM_CYSCREEN
Definition: winuser.h:950
static long g_x
Definition: wclickat.c:69
int WINAPI GetSystemMetrics(_In_ int)
static long g_dragto_y
Definition: wclickat.c:72
static IHTMLWindow2 * window
Definition: events.c:77
HWND WINAPI GetParent(_In_ HWND)
BOOL WINAPI GetWindowInfo(_In_ HWND, _Inout_ PWINDOWINFO)
#define MOUSEEVENTF_MOVE
Definition: winuser.h:1169
static long g_y
Definition: wclickat.c:70
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
GLint dx
Definition: linetemp.h:97
BOOL WINAPI SetForegroundWindow(_In_ HWND)
LONG bottom
Definition: windef.h:294
static long g_dragto_x
Definition: wclickat.c:71

Referenced by ClickProc(), and FindWindowProc().

◆ find_control()

static BOOL CALLBACK find_control ( HWND  hwnd,
LPARAM  lParam 
)
static

Definition at line 184 of file wclickat.c.

185 {
186  WCHAR str[1024];
187  HWND* pcontrol;
188 
191  return TRUE;
192 
193  if (g_control_caption)
194  {
197  return TRUE;
198  }
200  return TRUE;
201 
202  /* Check that the control is visible and active */
203  if (!g_disabled)
204  {
206  if (!(style & WS_VISIBLE) || (style & WS_DISABLED))
207  return TRUE;
208  }
209 
210  pcontrol = (HWND*)lParam;
211  *pcontrol = hwnd;
212  return FALSE;
213 }
#define WS_DISABLED
Definition: pedump.c:621
const DOCKBAR PVOID HWND HWND * hwnd
Definition: tooldock.h:22
#define TRUE
Definition: types.h:120
#define GWL_ID
Definition: winuser.h:853
static long g_disabled
Definition: wclickat.c:73
int WINAPI lstrcmpiW(LPCWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:194
#define GetWindowStyle(hwnd)
Definition: windowsx.h:290
int WINAPI GetClassNameW(_In_ HWND hWnd, _Out_writes_to_(nMaxCount, return) LPWSTR lpClassName, _In_ int nMaxCount)
static const WCHAR * my_strstriW(const WCHAR *haystack, const WCHAR *needle)
Definition: wclickat.c:152
const WCHAR * str
static WCHAR * g_control_class
Definition: wclickat.c:67
__wchar_t WCHAR
Definition: xmlstorage.h:180
unsigned long DWORD
Definition: ntddk_ex.h:95
#define GetWindowLong
Definition: winuser.h:5697
#define ARRAY_LENGTH(array)
Definition: wclickat.c:39
int WINAPI GetWindowTextW(HWND hWnd, LPWSTR lpString, int nMaxCount)
Definition: window.c:1408
static WCHAR * g_control_caption
Definition: wclickat.c:68
static long g_control_id
Definition: wclickat.c:66
Arabic default style
Definition: afstyles.h:93
#define WS_VISIBLE
Definition: pedump.c:620
LPARAM lParam
Definition: combotst.c:139

Referenced by find_top_window().

◆ find_top_window()

static BOOL CALLBACK find_top_window ( HWND  hwnd,
LPARAM  lParam 
)
static

Definition at line 215 of file wclickat.c.

216 {
217  WCHAR str[1024];
218  HWND* pwindow;
219 
222  return TRUE;
223 
226  return TRUE;
227 
228  /* Check that the window is visible and active */
229  if (!g_disabled)
230  {
232  if (!(style & WS_VISIBLE) || (style & WS_DISABLED))
233  return TRUE;
234  }
235 
236  /* See if we find the control we want */
237  if (g_control_class)
238  {
239  HWND control = NULL;
241  if (!control)
242  return TRUE;
243  hwnd=control;
244  }
245 
246  pwindow = (HWND*)lParam;
247  *pwindow = hwnd;
248  return FALSE;
249 }
BOOL WINAPI EnumChildWindows(_In_opt_ HWND, _In_ WNDENUMPROC, _In_ LPARAM)
#define WS_DISABLED
Definition: pedump.c:621
const DOCKBAR PVOID HWND HWND * hwnd
Definition: tooldock.h:22
#define TRUE
Definition: types.h:120
static long g_disabled
Definition: wclickat.c:73
int WINAPI lstrcmpiW(LPCWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:194
#define GetWindowStyle(hwnd)
Definition: windowsx.h:290
int WINAPI GetClassNameW(_In_ HWND hWnd, _Out_writes_to_(nMaxCount, return) LPWSTR lpClassName, _In_ int nMaxCount)
const WCHAR * str
smooth NULL
Definition: ftsmooth.c:416
static WCHAR * g_control_class
Definition: wclickat.c:67
LONG_PTR LPARAM
Definition: windef.h:208
static WCHAR * g_window_title
Definition: wclickat.c:65
__wchar_t WCHAR
Definition: xmlstorage.h:180
unsigned long DWORD
Definition: ntddk_ex.h:95
static BOOL CALLBACK find_control(HWND hwnd, LPARAM lParam)
Definition: wclickat.c:184
#define ARRAY_LENGTH(array)
Definition: wclickat.c:39
int WINAPI GetWindowTextW(HWND hWnd, LPWSTR lpString, int nMaxCount)
Definition: window.c:1408
static WCHAR * g_window_class
Definition: wclickat.c:64
Arabic default style
Definition: afstyles.h:93
#define WS_VISIBLE
Definition: pedump.c:620
LPARAM lParam
Definition: combotst.c:139

Referenced by find_window().

◆ find_window()

static HWND find_window ( )
static

Definition at line 251 of file wclickat.c.

252 {
253  HWND hwnd;
254 
255  hwnd=NULL;
257  return hwnd;
258 }
const DOCKBAR PVOID HWND HWND * hwnd
Definition: tooldock.h:22
smooth NULL
Definition: ftsmooth.c:416
LONG_PTR LPARAM
Definition: windef.h:208
BOOL WINAPI EnumWindows(_In_ WNDENUMPROC, _In_ LPARAM)
static BOOL CALLBACK find_top_window(HWND hwnd, LPARAM lParam)
Definition: wclickat.c:215

Referenced by ClickProc(), and FindWindowProc().

◆ FindWindowProc()

static void CALLBACK FindWindowProc ( HWND  hwnd,
UINT  uMsg,
UINT_PTR  idEvent,
DWORD  dwTime 
)
static

Definition at line 374 of file wclickat.c.

375 {
376  HWND window = find_window();
377  if (!window)
378  return;
379 
380  cxlog("Found the window\n");
381  if (g_delay)
382  {
383  cxlog("Waiting for a bit\n");
386  do_click(window, 0,0);
387  }
388  else
389  {
390  DelayProc(NULL, 0, 0, 0);
391  }
392 }
smooth NULL
Definition: ftsmooth.c:416
UINT_PTR WINAPI SetTimer(_In_opt_ HWND, _In_ UINT_PTR, _In_ UINT, _In_opt_ TIMERPROC)
static void do_click(HWND window, DWORD down, DWORD up)
Definition: wclickat.c:260
static void cxlog(const char *format,...) __PRINTF_ATTR(1
Definition: wclickat.c:100
static HWND find_window()
Definition: wclickat.c:251
BOOL WINAPI KillTimer(_In_opt_ HWND, _In_ UINT_PTR)
static IHTMLWindow2 * window
Definition: events.c:77
static void CALLBACK DelayProc(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime)
Definition: wclickat.c:361
static UINT timer_id
Definition: wclickat.c:79
static long g_delay
Definition: wclickat.c:75

Referenced by main().

◆ init_debug()

static int init_debug ( )
static

Definition at line 91 of file wclickat.c.

92 {
93  char* str=getenv("CXTEST_DEBUG");
94  if (str && strstr(str, "+wclickat"))
95  debug_on=1;
96  return debug_on;
97 }
static int debug_on
Definition: wclickat.c:90
char * strstr(char *String1, char *String2)
Definition: utclib.c:653
const WCHAR * str
_Check_return_ char *__cdecl getenv(_In_z_ const char *_VarName)

Referenced by main().

◆ main()

int main ( int argc  ,
const char **  argv 
)

Definition at line 657 of file wclickat.c.

658 {
659  MSG msg;
660 
661  init_debug();
662 
664  if (status)
665  {
666  if (status == 2)
667  usage();
668  else
669  fprintf(stderr, "Issue %s --help for usage.\n", *argv);
670  return RC_INVALID_ARGUMENTS;
671  }
672  cxlog("Entering message loop. action=%d\n", g_action);
673 
674  if (g_timeout>0)
677 
679  while (status==RC_RUNNING && GetMessage(&msg, NULL, 0, 0)!=0)
680  {
683  }
684 
685  return status;
686 }
static int init_debug()
Definition: wclickat.c:91
static void CALLBACK FindWindowProc(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime)
Definition: wclickat.c:374
static int argc
Definition: ServiceArgs.c:12
#define DispatchMessage
Definition: winuser.h:5666
BOOL WINAPI TranslateMessage(_In_ const MSG *)
TW_UINT32 TW_UINT16 TW_UINT16 MSG
Definition: twain.h:1827
#define argv
Definition: mplay32.c:18
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
smooth NULL
Definition: ftsmooth.c:416
UINT_PTR WINAPI SetTimer(_In_opt_ HWND, _In_ UINT_PTR, _In_ UINT, _In_opt_ TIMERPROC)
static int status
Definition: wclickat.c:52
static void cxlog(const char *format,...) __PRINTF_ATTR(1
Definition: wclickat.c:100
#define RC_RUNNING
Definition: wclickat.c:47
#define RC_INVALID_ARGUMENTS
Definition: wclickat.c:49
static void CALLBACK TimeoutProc(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime)
Definition: wclickat.c:394
static UINT timer_id
Definition: wclickat.c:79
#define GetMessage
Definition: winuser.h:5691
static action_type g_action
Definition: wclickat.c:62
#define msg(x)
Definition: auth_time.c:54
FILE * stderr
static long g_timeout
Definition: wclickat.c:76
static void usage(void)
Definition: wclickat.c:115
static int parse_arguments(int argc, const char **argv)
Definition: wclickat.c:445
Definition: ps.c:97

◆ my_strstriW()

static const WCHAR* my_strstriW ( const WCHAR haystack,
const WCHAR needle 
)
static

Definition at line 152 of file wclickat.c.

153 {
154  const WCHAR *h,*n;
155  WCHAR first;
156 
157  if (!*needle)
158  return haystack;
159 
160  /* Special case the first character because
161  * we will be doing a lot of comparisons with it.
162  */
163  first=towlower(*needle);
164  needle++;
165  while (*haystack)
166  {
167  while (towlower(*haystack)!=first && *haystack)
168  haystack++;
169 
170  h=haystack+1;
171  n=needle;
172  while (towlower(*h)==towlower(*n) && *h)
173  {
174  h++;
175  n++;
176  }
177  if (!*n)
178  return haystack;
179  haystack++;
180  }
181  return NULL;
182 }
const GLint * first
Definition: glext.h:5794
GLdouble n
Definition: glext.h:7729
GLfloat GLfloat GLfloat GLfloat h
Definition: glext.h:7723
smooth NULL
Definition: ftsmooth.c:416
__wchar_t WCHAR
Definition: xmlstorage.h:180
static const char haystack[]
Definition: editor.c:145
#define towlower(c)
Definition: wctype.h:97

Referenced by find_control().

◆ parse_arguments()

static int parse_arguments ( int  argc,
const char **  argv 
)
static

Definition at line 445 of file wclickat.c.

446 {
447  int rc;
448  const char* arg;
449  char* p;
450 
451  rc=0;
452  argv++;
453  while (*argv)
454  {
455  arg=*argv++;
456  if (*arg!='-')
457  {
458  if (g_action != ACTION_INVALID)
459  {
460  fprintf(stderr, "error: '%s' an action has already been specified\n", arg);
461  rc=1;
462  }
463  else if (strcmp(arg, "click") == 0 || strcmp(arg, "lclick") == 0)
464  {
466  }
467  else if (strcmp(arg, "mclick") == 0)
468  {
470  }
471  else if (strcmp(arg, "rclick") == 0)
472  {
474  }
475  else if (strncmp(arg, "button", 6) == 0)
476  {
477  int button;
478  char extra='\0';
479  int r=sscanf(arg, "button%d%c", &button, &extra);
480  /* We should always get r==1 but due to a bug in Wine's
481  * msvcrt.dll implementation (at least up to 20050127)
482  * we may also get r==2 and extra=='\0'.
483  */
484  if (r!=1 && (r!=2 || extra!='\0'))
485  {
486  fprintf(stderr, "error: invalid argument '%s' for '%s'\n",
487  *argv, arg);
488  rc=1;
489  }
490  else if (button<1 || button>3)
491  {
492  fprintf(stderr, "error: unknown button '%s'\n", arg);
493  rc=1;
494  }
495  else
496  {
497  /* Just to remain compatible with the enum */
498  g_action=button+ACTION_LCLICK-1;
499  }
500  }
501  else if (strcmp(arg, "find") == 0)
502  {
504  }
505  else
506  {
507  fprintf(stderr, "error: unknown action '%s'\n", arg);
508  rc=1;
509  }
510  }
511  else if (strcmp(arg, "--winclass") == 0)
512  {
514  }
515  else if (strcmp(arg, "--wintitle") == 0)
516  {
518  }
519  else if (strcmp(arg, "--ctrlclass") == 0)
520  {
522  }
523  else if (strcmp(arg, "--ctrlid") == 0)
524  {
526  }
527  else if (strcmp(arg, "--ctrlcaption") == 0)
528  {
530  }
531  else if (strcmp(arg, "--position") == 0)
532  {
533  if (!*argv)
534  {
535  fprintf(stderr, "error: missing argument for '%s'\n", arg);
536  rc=1;
537  }
538  else
539  {
540  char extra='\0';
541  int r=sscanf(*argv, "%ldx%ld%c", &g_x, &g_y, &extra);
542  /* We should always get r==2 but due to a bug in Wine's
543  * msvcrt.dll implementation (at least up to 20050127)
544  * we may also get r==3 and extra=='\0'.
545  */
546  if (r!=2 && (r!=3 || extra!='\0'))
547  {
548  fprintf(stderr, "error: invalid argument '%s' for '%s'\n",
549  *argv, arg);
550  rc=1;
551  }
552  argv++;
553  }
554  }
555  else if (strcmp(arg, "--dragto") == 0)
556  {
557  if (!*argv)
558  {
559  fprintf(stderr, "error: missing argument for '%s'\n", arg);
560  rc=1;
561  }
562  else
563  {
564  char extra='\0';
565  int r=sscanf(*argv, "%ldx%ld%c", &g_dragto_x, &g_dragto_y, &extra);
566  /* We should always get r==2 but due to a bug in Wine's
567  * * msvcrt.dll implementation (at least up to 20050127)
568  * * we may also get r==3 and extra=='\0'.
569  * */
570  if (r!=2 && (r!=3 || extra!='\0'))
571  {
572  fprintf(stderr, "error: invalid argument '%s' for '%s'\n",
573  *argv, arg);
574  rc=1;
575  }
576  argv++;
577  }
578  }
579  else if (strcmp(arg, "--allow-disabled") == 0)
580  {
581  g_disabled = 1;
582  }
583  else if (strcmp(arg, "--delay") == 0)
584  {
585  rc|=arg_get_long(&argv, arg, &g_delay);
586  }
587  else if (strcmp(arg, "--timeout") == 0)
588  {
589  rc|=arg_get_long(&argv, arg, &g_timeout);
590  }
591  else if (strcmp(arg, "--repeat") == 0)
592  {
593  rc|=arg_get_long(&argv, arg, &g_repeat);
594  }
595  else if (strcmp(arg, "--untildeath") == 0)
596  {
597  g_untildeath=1;
598  }
599  else if (strcmp(arg, "--help") == 0)
600  {
601  rc=2;
602  }
603  }
604 
605  if (g_action == ACTION_INVALID)
606  {
607  fprintf(stderr, "error: you must specify an action type\n");
608  rc=1;
609  }
610  else
611  {
612  /* Adjust the default delay and repeat parameters depending on
613  * the operating mode so less needs to be specified on the command
614  * line, and so we can assume them to be set right.
615  */
616  if (g_action == ACTION_FIND)
617  g_delay=0;
618  if (!g_untildeath)
619  g_repeat=0;
620  else if (!g_repeat)
622  }
623 
624  if (!g_window_class)
625  {
626  fprintf(stderr, "error: you must specify a --winclass parameter\n");
627  rc=1;
628  }
629  if (!g_window_title)
630  {
631  fprintf(stderr, "error: you must specify a --wintitle parameter\n");
632  rc=1;
633  }
634  if (g_control_class)
635  {
637  {
638  fprintf(stderr, "error: you must specify either the control id or its caption\n");
639  rc=1;
640  }
641  }
642 
643  /*------------------------------------------------------------------------
644  ** Process environment variables
645  **----------------------------------------------------------------------*/
646  p = getenv("CXTEST_TIME_MULTIPLE");
647  if (p)
648  {
649  float g_multiple = atof(p);
650  g_delay = (long) (((float) g_delay) * g_multiple);
651  g_timeout = (long) (((float) g_timeout) * g_multiple);
652  }
653 
654  return rc;
655 }
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
static long g_repeat
Definition: wclickat.c:77
static long g_disabled
Definition: wclickat.c:73
void * arg
Definition: msvc.h:12
#define argv
Definition: mplay32.c:18
_Check_return_ _CRTIMP double __cdecl atof(_In_z_ const char *str)
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
static WCHAR * g_control_class
Definition: wclickat.c:67
_Check_return_ _CRTIMP int __cdecl sscanf(_In_z_ const char *_Src, _In_z_ _Scanf_format_string_ const char *_Format,...)
static WCHAR * g_window_title
Definition: wclickat.c:65
static long g_untildeath
Definition: wclickat.c:78
Definition: id3.c:18
static long g_x
Definition: wclickat.c:69
static int arg_get_long(const char ***argv, const char *name, long *value)
Definition: wclickat.c:402
int strncmp(const char *String1, const char *String2, ACPI_SIZE Count)
Definition: utclib.c:534
static long g_dragto_y
Definition: wclickat.c:72
static int arg_get_utf8(const char ***argv, const char *name, WCHAR **value)
Definition: wclickat.c:422
_Check_return_ char *__cdecl getenv(_In_z_ const char *_VarName)
static long g_y
Definition: wclickat.c:70
static WCHAR * g_control_caption
Definition: wclickat.c:68
#define long
Definition: qsort.c:33
static action_type g_action
Definition: wclickat.c:62
#define DEFAULT_REPEAT
Definition: wclickat.c:37
FILE * stderr
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
static long g_timeout
Definition: wclickat.c:76
static WCHAR * g_window_class
Definition: wclickat.c:64
GLfloat GLfloat p
Definition: glext.h:8902
static long g_control_id
Definition: wclickat.c:66
static long g_delay
Definition: wclickat.c:75
static long g_dragto_x
Definition: wclickat.c:71

Referenced by main().

◆ TimeoutProc()

static void CALLBACK TimeoutProc ( HWND  hwnd,
UINT  uMsg,
UINT_PTR  idEvent,
DWORD  dwTime 
)
static

Definition at line 394 of file wclickat.c.

395 {
396  status = RC_TIMEOUT;
397 }
#define RC_TIMEOUT
Definition: wclickat.c:51
Definition: ps.c:97

Referenced by main().

◆ usage()

static void usage ( void  )
static

Definition at line 115 of file wclickat.c.

116 {
117  fprintf(stderr, "%s - Utility to send clicks to Wine Windows.\n", APP_NAME);
118  fprintf(stderr, "----------------------------------------------\n");
119  fprintf(stderr, "Usage:\n");
120  fprintf(stderr, " %s action --winclass class --wintitle title [--timeout ms]\n",APP_NAME);
121  fprintf(stderr, " %*.*s [--ctrlclas class] [--ctrlcaption caption] [--ctrlid id]\n", strlen(APP_NAME) + 3, strlen(APP_NAME) + 3, "");
122  fprintf(stderr, " %*.*s [--position XxY] [--delay ms] [--untildeath] [--repeat ms]\n", strlen(APP_NAME) + 3, strlen(APP_NAME) + 3, "");
123  fprintf(stderr, "Where action can be one of:\n");
124  fprintf(stderr, " find Find the specified window or control\n");
125  fprintf(stderr, " button<n> Send a click with the given X button number\n");
126  fprintf(stderr, " click|lclick Synonym for button1 (left click)\n");
127  fprintf(stderr, " mclick Synonym for button2 (middle click)\n");
128  fprintf(stderr, " rclick Synonym for button3 (right click)\n");
129  fprintf(stderr, "\n");
130  fprintf(stderr, "The options are as follows:\n");
131  fprintf(stderr, " --timeout ms How long to wait before failing with a code of %d\n", RC_TIMEOUT);
132  fprintf(stderr, " --winclass class Class name of the top-level window of interest\n");
133  fprintf(stderr, " --wintitle title Title of the top-level window of interest\n");
134  fprintf(stderr, " --ctrlclass name Class name of the control of interest, if any\n");
135  fprintf(stderr, " --ctrlcaption cap A substring of the control's caption\n");
136  fprintf(stderr, " --ctrlid id Id of the control\n");
137  fprintf(stderr, " --position XxY Coordinates for the click, relative to the window / control\n");
138  fprintf(stderr, " --dragto If given, then position specifies start click, and\n");
139  fprintf(stderr, " dragto specifies release coords.\n");
140  fprintf(stderr, " --allow-disabled Match the window or control even hidden or disabled\n");
141  fprintf(stderr, " --delay ms Wait ms milliseconds before clicking. The default is %d\n", DEFAULT_DELAY);
142  fprintf(stderr, " --untildeath Wait until the window disappears\n");
143  fprintf(stderr, " --repeat ms Click every ms milliseconds. The default is %d\n", DEFAULT_REPEAT);
144  fprintf(stderr, "\n");
145  fprintf(stderr, "%s returns %d on success\n", APP_NAME, RC_SUCCESS);
146  fprintf(stderr, "\n");
147  fprintf(stderr, "Environment variable overrides:\n");
148  fprintf(stderr, " CXTEST_TIME_MULTIPLE Specifies a floating multiplier applied to any\n");
149  fprintf(stderr, " delay and timeout parameters.\n");
150 }
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define DEFAULT_DELAY
Definition: wclickat.c:36
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
#define RC_TIMEOUT
Definition: wclickat.c:51
#define DEFAULT_REPEAT
Definition: wclickat.c:37
FILE * stderr
#define APP_NAME
Definition: wclickat.c:35
#define RC_SUCCESS
Definition: wclickat.c:48

Referenced by main().

Variable Documentation

◆ debug_on

int debug_on =0
static

Definition at line 90 of file wclickat.c.

Referenced by cxlog(), and init_debug().

◆ g_action

action_type g_action = ACTION_INVALID
static

Definition at line 62 of file wclickat.c.

Referenced by ClickProc(), main(), and parse_arguments().

◆ g_control_caption

WCHAR* g_control_caption = NULL
static

Definition at line 68 of file wclickat.c.

Referenced by find_control(), and parse_arguments().

◆ g_control_class

WCHAR* g_control_class = NULL
static

Definition at line 67 of file wclickat.c.

Referenced by find_control(), find_top_window(), and parse_arguments().

◆ g_control_id

long g_control_id = 0
static

Definition at line 66 of file wclickat.c.

Referenced by find_control(), and parse_arguments().

◆ g_delay

long g_delay = DEFAULT_DELAY
static

Definition at line 75 of file wclickat.c.

Referenced by FindWindowProc(), and parse_arguments().

◆ g_disabled

long g_disabled = 0
static

Definition at line 73 of file wclickat.c.

Referenced by find_control(), find_top_window(), and parse_arguments().

◆ g_dragto_x

long g_dragto_x = -1
static

Definition at line 71 of file wclickat.c.

Referenced by do_click(), and parse_arguments().

◆ g_dragto_y

long g_dragto_y = -1
static

Definition at line 72 of file wclickat.c.

Referenced by do_click(), and parse_arguments().

◆ g_repeat

long g_repeat = 0
static

Definition at line 77 of file wclickat.c.

Referenced by ClickProc(), DelayProc(), and parse_arguments().

◆ g_timeout

long g_timeout = 0
static

Definition at line 76 of file wclickat.c.

Referenced by main(), and parse_arguments().

◆ g_untildeath

long g_untildeath = 0
static

Definition at line 78 of file wclickat.c.

Referenced by ClickProc(), and parse_arguments().

◆ g_window_class

WCHAR* g_window_class = NULL
static

Definition at line 64 of file wclickat.c.

Referenced by find_top_window(), and parse_arguments().

◆ g_window_title

WCHAR* g_window_title = NULL
static

Definition at line 65 of file wclickat.c.

Referenced by find_top_window(), and parse_arguments().

◆ g_x

long g_x = -1
static

Definition at line 69 of file wclickat.c.

Referenced by do_click(), and parse_arguments().

◆ g_y

long g_y = -1
static

Definition at line 70 of file wclickat.c.

Referenced by do_click(), and parse_arguments().

◆ STATIC_CLASS

const WCHAR STATIC_CLASS[] ={'s','t','a','t','i','c','\0'}
static

Definition at line 41 of file wclickat.c.

◆ status

int status
static

Definition at line 52 of file wclickat.c.

Referenced by main().

◆ timer_id

UINT timer_id
static

Definition at line 79 of file wclickat.c.

Referenced by DelayProc(), FindWindowProc(), and main().