Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

332 lines
9.0 KiB

  1. /*
  2. * startpgm.c
  3. *
  4. * Copyright (c) 1990, Microsoft Corporation
  5. *
  6. * DESCRIPTION
  7. *
  8. * MODIFICATION HISTORY
  9. *
  10. */
  11. #include <stdio.h>
  12. #include <stdlib.h>
  13. #include <string.h>
  14. #include <windows.h>
  15. #include <winuserp.h>
  16. HWND
  17. GetWindowHandleOfConsole( void );
  18. HANDLE
  19. PassArgsAndEnvironmentToEditor(
  20. int argc,
  21. char *argv[],
  22. char *envp[],
  23. HWND hwndSelf
  24. );
  25. void
  26. Usage( void )
  27. {
  28. printf( "Usage: STARTPGM [-z] [-s] -j \"Title string\"\n" );
  29. printf( "where: -j specifies the title string of the window to jump to\n" );
  30. printf( " The match done against the title is a case insensitive prefix match\n" );
  31. printf( " -s specifies the match can be anywhere in the title.\n" );
  32. printf( " -z specifies destination window is an editor and the remaining command line\n" );
  33. printf( " arguments and the current environment variable settings are passed to the editor via shared memory\n" );
  34. exit( 1 );
  35. }
  36. int
  37. __cdecl main(
  38. int argc,
  39. char *argv[],
  40. char *envp[]
  41. )
  42. {
  43. BOOL JumpToEditor;
  44. BOOL WaitForEditor;
  45. BOOL VerboseOutput;
  46. BOOL SubstringOkay;
  47. HANDLE EditorStopEvent;
  48. LPSTR TitleToJumpTo;
  49. int n;
  50. HWND hwnd, hwndSelf;
  51. UINT ShowCmd;
  52. WINDOWPLACEMENT WindowPlacement;
  53. wchar_t uszTitle[ 256 ];
  54. char *s, szTitle[ 256 ];
  55. int EditorArgc;
  56. char **EditorArgv;
  57. JumpToEditor = FALSE;
  58. WaitForEditor = FALSE;
  59. VerboseOutput = FALSE;
  60. SubstringOkay = FALSE;
  61. TitleToJumpTo = NULL;
  62. while (--argc) {
  63. s = *++argv;
  64. if (*s == '/' || *s == '-') {
  65. while (*++s) {
  66. switch( tolower( *s ) ) {
  67. case 'z':
  68. JumpToEditor = TRUE;
  69. if (*s == 'Z') {
  70. WaitForEditor = TRUE;
  71. }
  72. break;
  73. case 'v':
  74. VerboseOutput = TRUE;
  75. break;
  76. case 's':
  77. SubstringOkay = TRUE;
  78. break;
  79. case 'j':
  80. if (!--argc) {
  81. fprintf( stderr, "STARTPGM: Missing title string argument to -j switch\n" );
  82. Usage();
  83. }
  84. TitleToJumpTo = *++argv;
  85. _strupr( TitleToJumpTo ); // Case insensitive compares
  86. n = strlen( TitleToJumpTo );
  87. break;
  88. default:
  89. fprintf( stderr, "STARTPGM: Invalid switch - /%c\n", *s );
  90. Usage();
  91. }
  92. }
  93. }
  94. else {
  95. break;
  96. }
  97. }
  98. if (TitleToJumpTo == NULL) {
  99. fprintf( stderr, "STARTPGM: -j switch missing.\n" );
  100. Usage();
  101. }
  102. if (JumpToEditor) {
  103. EditorArgc = argc;
  104. EditorArgv = argv;
  105. }
  106. /*
  107. * Search the window list for enabled top level windows.
  108. */
  109. hwnd = GetWindow( GetDesktopWindow(), GW_CHILD );
  110. while (hwnd) {
  111. /*
  112. * Only look at visible, non-owned, Top Level Windows.
  113. */
  114. if (IsWindowVisible( hwnd ) && !GetWindow( hwnd, GW_OWNER )) {
  115. //
  116. // Use internal call to get current Window title that does NOT
  117. // use SendMessage to query the title from the window procedure
  118. // but instead returns the most recent title displayed.
  119. //
  120. InternalGetWindowText( hwnd,
  121. (LPWSTR)uszTitle,
  122. sizeof( szTitle )
  123. );
  124. wcstombs( szTitle, uszTitle, sizeof( uszTitle ) );
  125. _strupr( szTitle ); // Case insensitive compares
  126. if (strlen( szTitle )) {
  127. if (VerboseOutput) {
  128. printf( "Looking at window title: '%s'\n", szTitle );
  129. }
  130. if (SubstringOkay) {
  131. if (strstr( szTitle, "STARTPGM" )) {
  132. // Ignore window with ourselve running
  133. }
  134. else
  135. if (strstr( szTitle, TitleToJumpTo )) {
  136. break;
  137. }
  138. }
  139. else
  140. if (!_strnicmp( TitleToJumpTo, szTitle, n )) {
  141. break;
  142. }
  143. }
  144. }
  145. hwnd = GetWindow( hwnd, GW_HWNDNEXT );
  146. }
  147. if (hwnd == NULL) {
  148. printf( "Unable to find window with '%s' title\n", TitleToJumpTo );
  149. exit( 1 );
  150. }
  151. else
  152. if (IsWindow( hwnd )) {
  153. if (JumpToEditor) {
  154. hwndSelf = GetWindowHandleOfConsole();
  155. if (VerboseOutput) {
  156. printf( "Calling editor with: '" );
  157. while (argc--) {
  158. printf( "%s%s", *argv++, !argc ? "" : " " );
  159. }
  160. printf( "'\n" );
  161. }
  162. EditorStopEvent = PassArgsAndEnvironmentToEditor( EditorArgc,
  163. EditorArgv,
  164. envp,
  165. hwndSelf
  166. );
  167. }
  168. SetForegroundWindow( hwnd );
  169. ShowCmd = SW_SHOW;
  170. WindowPlacement.length = sizeof( WindowPlacement );
  171. if (GetWindowPlacement( hwnd, &WindowPlacement )) {
  172. if (WindowPlacement.showCmd == SW_SHOWMINIMIZED) {
  173. ShowCmd = SW_RESTORE;
  174. }
  175. }
  176. ShowWindow( hwnd, ShowCmd );
  177. if (WaitForEditor && EditorStopEvent != NULL) {
  178. WaitForSingleObject( EditorStopEvent, (DWORD)-1 );
  179. CloseHandle( EditorStopEvent );
  180. }
  181. }
  182. exit( 0 );
  183. return( 0 );
  184. }
  185. HANDLE
  186. PassArgsAndEnvironmentToEditor(
  187. int argc,
  188. char *argv[],
  189. char *envp[],
  190. HWND hwndSelf
  191. )
  192. {
  193. HANDLE EditorStartEvent;
  194. HANDLE EditorStopEvent;
  195. HANDLE EditorSharedMemory;
  196. char *s;
  197. char *p;
  198. EditorStartEvent = OpenEvent( EVENT_ALL_ACCESS, FALSE, "EditorStartEvent" );
  199. if (!EditorStartEvent) {
  200. printf( "Unable to pass parameters to editor (can't open EditorStartEvent).\n" );
  201. return NULL;
  202. }
  203. EditorStopEvent = OpenEvent( EVENT_ALL_ACCESS, FALSE, "EditorStopEvent" );
  204. if (!EditorStopEvent) {
  205. printf( "Unable to pass parameters to editor (can't open EditorStopEvent).\n" );
  206. CloseHandle( EditorStartEvent );
  207. return NULL;
  208. }
  209. EditorSharedMemory = OpenFileMapping( FILE_MAP_ALL_ACCESS, FALSE, "EditorSharedMemory" );
  210. if (!EditorSharedMemory) {
  211. printf( "Unable to pass parameters to editor (can't open EditorSharedMemory).\n" );
  212. CloseHandle( EditorStopEvent );
  213. CloseHandle( EditorStartEvent );
  214. return NULL;
  215. }
  216. p = (char *)MapViewOfFile( EditorSharedMemory,
  217. FILE_MAP_WRITE | FILE_MAP_READ,
  218. 0,
  219. 0,
  220. 0
  221. );
  222. if (p == NULL) {
  223. printf( "Unable to pass parameters to editor (can't mapped EditorSharedMemory).\n" );
  224. CloseHandle( EditorStopEvent );
  225. CloseHandle( EditorStartEvent );
  226. CloseHandle( EditorSharedMemory );
  227. return NULL;
  228. }
  229. *(HWND *)p = hwndSelf;
  230. p += sizeof( hwndSelf );
  231. p += GetCurrentDirectory( MAX_PATH, p );
  232. *p++ = '\0';
  233. while (argc--) {
  234. s = *argv++;
  235. while (*p++ = *s++) {
  236. }
  237. if (argc) {
  238. p[-1] = ' ';
  239. }
  240. else {
  241. p--;
  242. }
  243. }
  244. *p++ = '\0';
  245. while (s = *envp++) {
  246. while (*p++ = *s++) {
  247. }
  248. }
  249. *p++ = '\0';
  250. CloseHandle( EditorSharedMemory );
  251. SetEvent( EditorStartEvent );
  252. CloseHandle( EditorStartEvent );
  253. ResetEvent( EditorStopEvent );
  254. return EditorStopEvent;
  255. }
  256. HWND
  257. GetWindowHandleOfConsole( void )
  258. {
  259. #define MY_BUFSIZE 1024 // buffer size for console window titles
  260. HWND hwndFound; // this is what we return to the caller
  261. char pszNewWindowTitle[ MY_BUFSIZE ]; // contains fabricated WindowTitle
  262. char pszOldWindowTitle[ MY_BUFSIZE ]; // contains original WindowTitle
  263. // fetch current window title
  264. GetConsoleTitle( pszOldWindowTitle, MY_BUFSIZE );
  265. // format a "unique" NewWindowTitle
  266. wsprintf( pszNewWindowTitle, "%d/%d", GetTickCount(), GetCurrentProcessId() );
  267. // change current window title
  268. SetConsoleTitle( pszNewWindowTitle );
  269. // insure window title has been updated
  270. Sleep(40);
  271. // look for NewWindowTitle
  272. hwndFound = FindWindow( NULL, pszNewWindowTitle );
  273. // restore original window title
  274. SetConsoleTitle( pszOldWindowTitle );
  275. return( hwndFound );
  276. }