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.

1261 lines
47 KiB

  1. /* mcitest.c - WinMain(), main dialog box and support code for MCITest.
  2. *
  3. * MCITest is a Windows with Multimedia sample application illustrating
  4. * the use of the Media Control Interface (MCI). MCITest puts up a dialog
  5. * box allowing you to enter and execute MCI string commands.
  6. *
  7. * (C) Copyright Microsoft Corp. 1991 - 1995. All rights reserved.
  8. *
  9. * You have a royalty-free right to use, modify, reproduce and
  10. * distribute the Sample Files (and/or any modified version) in
  11. * any way you find useful, provided that you agree that
  12. * Microsoft has no warranty obligations or liability for any
  13. * Sample Application Files which are modified.
  14. */
  15. /*----------------------------------------------------------------------------*\
  16. | mcitest.c - A testbed for MCI |
  17. | |
  18. | |
  19. | History: |
  20. | 01/01/88 toddla Created |
  21. | 03/01/90 davidle Modified quick app into MCI testbed |
  22. | 09/17/90 t-mikemc Added Notification box with 3 notification types |
  23. | 11/02/90 w-dougb Commented & formatted the code to look pretty |
  24. | 05/29/91 NigelT ported to Win32
  25. | 02/05/92 SteveDav Merged latest Win 3.1 stuff
  26. | |
  27. \*----------------------------------------------------------------------------*/
  28. /*----------------------------------------------------------------------------*\
  29. | |
  30. | i n c l u d e f i l e s |
  31. | |
  32. \*----------------------------------------------------------------------------*/
  33. #include <stdio.h>
  34. #include <stdlib.h>
  35. #include <string.h>
  36. #include <windows.h>
  37. #include "mcitest.h"
  38. #include "mcimain.h"
  39. #include "edit.h"
  40. #include "commdlg.h"
  41. /*----------------------------------------------------------------------------*\
  42. | |
  43. | c o n s t a n t a n d m a c r o d e f i n i t i o n s |
  44. | |
  45. \*----------------------------------------------------------------------------*/
  46. #define BUFFER_LENGTH 256
  47. #define SLASH(c) ((c) == '/' || (c) == '\\')
  48. /*----------------------------------------------------------------------------*\
  49. | |
  50. | g l o b a l v a r i a b l e s |
  51. | |
  52. \*----------------------------------------------------------------------------*/
  53. #ifndef STATICDT
  54. #if DBG
  55. #define STATICDT
  56. #else
  57. #define STATICDT static
  58. #endif
  59. #endif
  60. STATICDT int nLastNumberOfDevices = 0;
  61. STATICDT HANDLE hAccTable;
  62. STATICDT HANDLE hInstApp;
  63. HWND hwndMainDlg = 0;
  64. STATICDT HWND hwndEdit = 0;
  65. STATICDT HWND hwndDevices = 0;
  66. STATICDT TCHAR aszMciFile[BUFFER_LENGTH] = TEXT("");
  67. STATICDT TCHAR aszBuffer[BUFFER_LENGTH];
  68. STATICDT TCHAR aszExt[] = TEXT("*.mci");
  69. TCHAR aszAppName[] = TEXT("MCITest");
  70. STATICDT TCHAR aszMainTextFormat[] = TEXT("%s - %s");
  71. STATICDT TCHAR aszDeviceTextFormat[] = TEXT("Open MCI Devices(count=%d)");
  72. STATICDT TCHAR aszNULL[] = TEXT("");
  73. STATICDT TCHAR aszTRUE[] = TEXT("TRUE");
  74. STATICDT TCHAR aszFALSE[] = TEXT("FALSE");
  75. STATICDT TCHAR aszEOL[] = TEXT("\r\n");
  76. STATICDT TCHAR aszOpenFileTitle[] = TEXT("Open MCITest File");
  77. STATICDT TCHAR aszSaveFileTitle[] = TEXT("Save MCITest File");
  78. STATICDT TCHAR aszSaveFileControl[] = TEXT("Save File &Name");
  79. STATICDT TCHAR aszProfileSection[] = TEXT("extensions");
  80. STATICDT TCHAR aszProfileKey[] = TEXT("mcs");
  81. STATICDT TCHAR aszProfileSetting[] = TEXT("mcitest.exe ^.mcs");
  82. STATICDT TCHAR aszMciTester[] = TEXT("MciTester");
  83. /*----------------------------------------------------------------------------*\
  84. | |
  85. | f u n c t i o n d e f i n i t i o n s |
  86. | |
  87. \*----------------------------------------------------------------------------*/
  88. BOOL mcitester(HWND hwnd, UINT Msg, LONG wParam, LONG lParam);
  89. PTSTR FileName(PTSTR szPath);
  90. STATICFN void update_device_list(void);
  91. DWORD sendstring(HWND hwndDlg, PTSTR strBuffer);
  92. void execute( HWND hwndDlg, BOOL fStep);
  93. void OpenMciFile( HWND hwndDlg, LPTSTR szFile);
  94. BOOL AppInit(int argc, char *argv[]);
  95. BOOL ErrDlgFunc( HWND hwndDlg, UINT Msg, LONG w, LONG l );
  96. void create_device_list(void);
  97. STATICFN BOOL devices(HWND hwndDlg, UINT Msg, LONG wParam, LONG lParam);
  98. STATICFN void ProcessInternalCommand(HWND hDlg, LPTSTR aszBuffer);
  99. /*----------------------------------------------------------------------------*\
  100. | AboutDlgProc( hwndDlg, Message, wParam, lParam ) |
  101. | |
  102. | Description: |
  103. | This function handles messages belonging to the "About" dialog box. |
  104. | The only message that it looks for is WM_COMMAND, indicating the user |
  105. | has pressed the "OK" button. When this happens, it takes down |
  106. | the dialog box. |
  107. | |
  108. | Arguments: |
  109. | hwndDlg window handle of the about dialog window |
  110. | Message message number |
  111. | wParam message-dependent parameter |
  112. | lParam message-dependent parameter |
  113. | |
  114. | Returns: |
  115. | TRUE if the message has been processed, else FALSE |
  116. | |
  117. \*----------------------------------------------------------------------------*/
  118. BOOL AboutDlgProc(
  119. HWND hwndDlg,
  120. UINT Msg,
  121. LONG wParam,
  122. LONG lParam)
  123. {
  124. dprintf4((TEXT("AboutDlgProc")));
  125. switch (Msg) {
  126. case WM_COMMAND:
  127. if (LOWORD(wParam) == IDOK) {
  128. EndDialog(hwndDlg,TRUE);
  129. }
  130. break;
  131. case WM_INITDIALOG:
  132. return TRUE;
  133. }
  134. return FALSE;
  135. }
  136. /*----------------------------------------------------------------------------*\
  137. | FileName(szPath) |
  138. | |
  139. | Description: |
  140. | This function takes the full path\filename string specified in <szPath>|
  141. | and returns a pointer to the first character of the filename in the |
  142. | same string. |
  143. | |
  144. | Arguments: |
  145. | szPath pointer to the full path\filename string |
  146. | |
  147. | Returns: |
  148. | a pointer to the first character of the filename in the same string |
  149. | |
  150. \*----------------------------------------------------------------------------*/
  151. PTSTR FileName(
  152. PTSTR szPath)
  153. {
  154. PTSTR szCurrent; /* temporary pointer to the string */
  155. /* Scan to the end of the string */
  156. for (szCurrent = szPath; *szCurrent; szCurrent++)
  157. {} ;
  158. /*
  159. * Now start scanning back towards the beginning of the string until
  160. * a slash (\) character, colon, or start of the string is encountered.
  161. */
  162. for (; szCurrent >= szPath
  163. && !SLASH(*szCurrent)
  164. && *szCurrent != ':'
  165. ; szCurrent--)
  166. {} ;
  167. /* This should be done by calling a Win 32 function, e.g. GetFullPathName
  168. */
  169. /* Now pointing to the char before the first char in the filename.
  170. */
  171. return ++szCurrent;
  172. }
  173. /*----------------------------------------------------------------------------*\
  174. | OpenMciFile( hwndDlg, szFile ) |
  175. | |
  176. | Description: |
  177. | This function opens the MCI file specified by <szFile> and updates the |
  178. | main window caption to display this file name along with the app name. |
  179. | |
  180. | Arguments: |
  181. | hwndDlg window handle of the main dialog window |
  182. | szFile pointer to the string containing the filename to be |
  183. | opened |
  184. | Returns: |
  185. | void |
  186. | |
  187. \*----------------------------------------------------------------------------*/
  188. void OpenMciFile(
  189. HWND hwndDlg,
  190. LPTSTR lszFile)
  191. {
  192. dprintf2((TEXT("OpenMciFile: %s"), lszFile));
  193. if (EditOpenFile(hwndEdit, lszFile)) {
  194. strcpy(aszMciFile, lszFile);
  195. wsprintf(aszBuffer, aszMainTextFormat, (LPTSTR)aszAppName,
  196. (LPTSTR)FileName(aszMciFile));
  197. dprintf3((TEXT("Set caption: %s"), aszBuffer));
  198. SetWindowText(hwndDlg, aszBuffer);
  199. }
  200. }
  201. /*----------------------------------------------------------------------------*\
  202. | get_number_of_devices() |
  203. | |
  204. | Description: |
  205. | This function sends a command to MCI querying it as to how many |
  206. | are currently open in the system. It returns the value provided by MCI.|
  207. | |
  208. | Arguments: |
  209. | none |
  210. | |
  211. | Returns: |
  212. | The number of MCI devices currently open, or 0 if an error occurred. |
  213. | |
  214. \*----------------------------------------------------------------------------*/
  215. int get_number_of_devices(
  216. void)
  217. {
  218. MCI_SYSINFO_PARMS sysinfo; /* Parameter structure used for getting
  219. information about the MCI devices in
  220. the system */
  221. DWORD dwDevices; /* count of open devices */
  222. /*
  223. * Set things up so that MCI puts the number of open devices directly
  224. * into <dwDevices>.
  225. */
  226. sysinfo.lpstrReturn = (LPTSTR)(LPDWORD)&dwDevices;
  227. sysinfo.dwRetSize = sizeof(dwDevices);
  228. /*
  229. * Send MCI a command querying all devices in the system to see if they
  230. * are open. If the command was successful, return the number provided by
  231. * MCI. Otherwise, return 0.
  232. *
  233. */
  234. if (mciSendCommand (MCI_ALL_DEVICE_ID,
  235. MCI_SYSINFO,
  236. (MCI_SYSINFO_OPEN | MCI_SYSINFO_QUANTITY),
  237. (DWORD)(LPMCI_SYSINFO_PARMS)&sysinfo) != 0)
  238. return 0;
  239. else
  240. return (int)dwDevices;
  241. }
  242. /*----------------------------------------------------------------------------*\
  243. | update_device_list() |
  244. | |
  245. | Description: |
  246. | This function updates the list of devices displayed in the Devices |
  247. | dialog. |
  248. | |
  249. | Arguments: |
  250. | none |
  251. | |
  252. | Returns: |
  253. | void |
  254. | |
  255. \*----------------------------------------------------------------------------*/
  256. STATICFN void update_device_list(
  257. void)
  258. {
  259. TCHAR aszBuf[BUFFER_LENGTH]; /* string used for several things */
  260. MCI_SYSINFO_PARMS sysinfo; /* Parameter structure used for getting
  261. information about the devices in the
  262. system */
  263. HWND hwndList; /* handle to the Devices listbox window */
  264. int nDevices;
  265. int nCurrentDevice;
  266. /* If the Devices dialog is not present, then return */
  267. if (hwndDevices == 0) {
  268. return;
  269. }
  270. /* Find out how many devices are currently open in the system */
  271. nDevices = get_number_of_devices();
  272. /* Update the dialog caption appropriately */
  273. wsprintf(aszBuf, aszDeviceTextFormat, nDevices);
  274. SetWindowText(hwndDevices, aszBuf);
  275. /* Get a handle to the dialog's listbox, and prepare it for updating */
  276. hwndList = GetDlgItem (hwndDevices, ID_DEVICE_LIST);
  277. SendMessage (hwndList, LB_RESETCONTENT, 0, 0L);
  278. if (nDevices) {
  279. SendMessage (hwndList, WM_SETREDRAW, FALSE, 0L);
  280. }
  281. /*
  282. * Get the name of each open device in the system, one device at a time.
  283. * Add each device's name to the listbox.
  284. */
  285. for (nCurrentDevice = 1; nCurrentDevice <= nDevices; ++nCurrentDevice) {
  286. sysinfo.dwNumber = nCurrentDevice;
  287. sysinfo.lpstrReturn = (LPTSTR)&aszBuf;
  288. sysinfo.dwRetSize = sizeof(aszBuf);
  289. /* If an error is encountered, skip to the next device.
  290. */
  291. if (mciSendCommand(MCI_ALL_DEVICE_ID, MCI_SYSINFO,
  292. MCI_SYSINFO_OPEN | MCI_SYSINFO_NAME,
  293. (DWORD)(LPMCI_SYSINFO_PARMS)&sysinfo) != 0) {
  294. continue;
  295. }
  296. /* Redraw the list when all device names have been added.
  297. */
  298. if (nCurrentDevice == nDevices) {
  299. /* About to add the last device - allow redrawing */
  300. SendMessage(hwndList, WM_SETREDRAW, TRUE, 0L);
  301. }
  302. /* Add the device name to the listbox.
  303. */
  304. SendMessage(hwndList, LB_ADDSTRING, 0, (LONG)(LPTSTR)aszBuf);
  305. }
  306. /* Remember the number of open devices we found this time */
  307. nLastNumberOfDevices = nDevices;
  308. }
  309. /*----------------------------------------------------------------------------*\
  310. | sendstring( hwndDlg, strBuffer ) |
  311. | |
  312. | Description: |
  313. | This function sends the string command specified in <strBuffer> to MCI |
  314. | via the MCI string interface. Any message returned by MCI is displayed |
  315. | in the 'MCI output' box. Any error which may have occurred is displayed|
  316. | in the 'Error' box'. |
  317. | |
  318. | Arguments: |
  319. | hwndDlg window handle of the main dialog window |
  320. | strBuffer pointer to the string containing the string command to |
  321. | be executed |
  322. | Returns: |
  323. | void |
  324. | |
  325. \*----------------------------------------------------------------------------*/
  326. DWORD sendstring(
  327. HWND hwndDlg,
  328. PTSTR strBuffer)
  329. {
  330. TCHAR aszReturn[BUFFER_LENGTH]; /* string containing the message
  331. returned by MCI */
  332. DWORD dwErr; /* variable containing the return
  333. code from the MCI command */
  334. dprintf2((TEXT("sendstring: %s"), strBuffer));
  335. /* Uncheck the notification buttons */
  336. CheckDlgButton (hwndDlg, ID_NOT_SUCCESS, FALSE);
  337. CheckDlgButton (hwndDlg, ID_NOT_SUPER, FALSE);
  338. CheckDlgButton (hwndDlg, ID_NOT_ABORT, FALSE);
  339. CheckDlgButton (hwndDlg, ID_NOT_FAIL, FALSE);
  340. /* Send the string command to MCI */
  341. dwErr = mciSendString(strBuffer, aszReturn, sizeof(aszReturn), hwndDlg);
  342. /* Put the text message returned by MCI into the 'MCI Output' box */
  343. SetDlgItemText (hwndDlg, ID_OUTPUT, aszReturn);
  344. /*
  345. * Decode the error # returned by MCI, and display the string in the
  346. * 'Error' box.
  347. */
  348. mciGetErrorString(dwErr, strBuffer, BUFFER_LENGTH);
  349. SetDlgItemText(hwndDlg, ID_ERRORCODE, strBuffer);
  350. /* Update the internal list of currently open devices */
  351. update_device_list();
  352. return dwErr;
  353. }
  354. /*----------------------------------------------------------------------------*\
  355. | ErrDlgFunc( hwndDlg, Msg, wParam, lParam ) |
  356. | |
  357. | Description: |
  358. | This function is the callback function for the dialog box which |
  359. | occurs during the execution of a error in a loop of MCITEST commands |
  360. | It displays Abort, Continue and Ignore buttons |
  361. | |
  362. | Arguments: |
  363. | hwndDlg window handle of the error message dialog window |
  364. | Msg message number |
  365. | wParam message-dependent parameter |
  366. | lParam message-dependent parameter |
  367. | |
  368. | Returns: |
  369. | normal message passing return values |
  370. | |
  371. \*----------------------------------------------------------------------------*/
  372. BOOL ErrDlgFunc(
  373. HWND hwndDlg,
  374. UINT Msg,
  375. LONG wParam,
  376. LONG lParam)
  377. {
  378. dprintf4((TEXT("ErrDlgFunc")));
  379. switch( Msg ) {
  380. case WM_INITDIALOG:
  381. return TRUE;
  382. case WM_COMMAND:
  383. switch( LOWORD(wParam) ) { // button pushed
  384. case IDABORT:
  385. case IDOK:
  386. case IDIGNORE:
  387. EndDialog( hwndDlg, LOWORD(wParam) ); // return button ID
  388. break;
  389. }
  390. break;
  391. }
  392. return( FALSE );
  393. }
  394. /*----------------------------------------------------------------------------*\
  395. | execute( hwndDlg, fStep ) |
  396. | |
  397. | Description: |
  398. | This function executes the MCI command which is currently selected in |
  399. | the edit box. If <fStep> is true, then only this one line will be |
  400. | executed. Otherwise, every line from the currently selected line to |
  401. | the last line in the edit box will be executed sequentially. |
  402. | |
  403. | Arguments: |
  404. | hwndDlg window handle of the main dialog window |
  405. | fSingleStep flag indicating whether or not to work in 'single step'|
  406. | mode |
  407. | Returns: |
  408. | void |
  409. | |
  410. \*----------------------------------------------------------------------------*/
  411. void execute(
  412. HWND hwndDlg,
  413. BOOL fSingleStep)
  414. {
  415. int iLine; /* line # of the command currently being executed
  416. in the edit box */
  417. int n=0; /* counter variable */
  418. int runcount = 1;
  419. int count;
  420. int iLineStart;
  421. BOOL fIgnoreErrors = FALSE;
  422. runcount = GetDlgItemInt(hwndDlg, ID_RUNCOUNT, NULL, TRUE);
  423. /*
  424. * Go through this loop for every line in the edit box from the currently
  425. * selected line to the last line, or a single line if in single step mode
  426. */
  427. iLineStart = EditGetCurLine(hwndEdit);
  428. dprintf2((TEXT("Called to execute %d lines from line %d"), runcount, iLineStart));
  429. for (count = runcount; count-- > 0; )
  430. {
  431. for (iLine = iLineStart;
  432. EditGetLine(hwndEdit, iLine, aszBuffer, sizeof(aszBuffer));
  433. iLine++ ) {
  434. /* If we hit a comment line or a blank line, skip to the next line */
  435. if (*aszBuffer == ';' || *aszBuffer == 0) {
  436. continue;
  437. }
  438. if (*aszBuffer == '!' ) { // Internal command
  439. ProcessInternalCommand(hwndDlg, aszBuffer+1);
  440. continue;
  441. }
  442. /* Select the line that is about to be processed */
  443. EditSelectLine(hwndEdit,iLine);
  444. /*
  445. * If we're in 'single step' mode and we've already processed one
  446. * line, then break out of the loop (and exit the routine).
  447. */
  448. if (fSingleStep && ++n == 2) {
  449. break;
  450. }
  451. /*
  452. * Send the command on the current line to MCI via the string
  453. * interface.
  454. */
  455. if (sendstring(hwndDlg, aszBuffer) != 0
  456. && !fIgnoreErrors
  457. && runcount > 1
  458. && !fSingleStep) {
  459. int nRet;
  460. nRet = DialogBox(hInstApp, MAKEINTRESOURCE(IDD_ERRORDLG),
  461. hwndDlg, (DLGPROC)ErrDlgFunc);
  462. if (nRet == IDABORT) { goto exit_fn; }
  463. if (nRet == IDIGNORE) { fIgnoreErrors = TRUE; }
  464. }
  465. }
  466. SetDlgItemInt (hwndDlg, ID_RUNCOUNT, count, TRUE);
  467. if (fSingleStep) { break; }
  468. }
  469. exit_fn:;
  470. SetDlgItemInt (hwndDlg, ID_RUNCOUNT, runcount, TRUE);
  471. }
  472. /*----------------------------------------------------------------------------*\
  473. | devices( hwndDlg, uMessage, wParam, lParam ) |
  474. | |
  475. | Description: |
  476. | This function handles messages belonging to the "List of open devices" |
  477. | dialog box. The only message that it looks for is WM_COMMAND, |
  478. | indicating the user has pressed the "OK" button. When this happens, |
  479. | it takes down the dialog box. |
  480. | |
  481. | Arguments: |
  482. | hwndDlg window handle of the Devices dialog window |
  483. | uMessage message number |
  484. | wParam message-dependent parameter |
  485. | lParam message-dependent parameter |
  486. | |
  487. | Returns: |
  488. | TRUE if the message has been processed, else FALSE |
  489. | |
  490. \*----------------------------------------------------------------------------*/
  491. STATICFN BOOL devices(
  492. HWND hwndDlg,
  493. UINT Msg,
  494. LONG wParam,
  495. LONG lParam)
  496. {
  497. switch (Msg) {
  498. case WM_COMMAND:
  499. dprintf4((TEXT("Devices -- WM_COMMAND")));
  500. switch (LOWORD(wParam)) {
  501. case ID_END_DEVICE_LIST:
  502. hwndDevices = 0;
  503. EndDialog(hwndDlg,TRUE);
  504. break;
  505. }
  506. break;
  507. }
  508. return FALSE;
  509. }
  510. /*----------------------------------------------------------------------------*\
  511. | create_device_list() |
  512. | |
  513. | Description: |
  514. | This function creates the Devices dialog box and updates the list of |
  515. | open devices displayed in it. |
  516. | |
  517. | Arguments: |
  518. | none |
  519. | |
  520. | Returns: |
  521. | void |
  522. | |
  523. \*----------------------------------------------------------------------------*/
  524. void create_device_list(
  525. void)
  526. {
  527. /* Create the Devices dialog box */
  528. hwndDevices = CreateDialog(hInstApp, MAKEINTRESOURCE(IDD_DEVICES),
  529. hwndMainDlg, (DLGPROC)devices);
  530. if (hwndDevices == NULL) {
  531. dprintf1((TEXT("NULL hwndDevices")));
  532. return;
  533. }
  534. /* Update the information displayed in the listbox */
  535. update_device_list();
  536. }
  537. /*----------------------------------------------------------------------------*\
  538. | mcitester( hwndDlg, Msg, wParam, lParam ) |
  539. | |
  540. | Description: |
  541. | This function is the main message handler for MCI test. It handles |
  542. | messages from the pushbuttons, radio buttons, edit controls, menu |
  543. | system, etc. When it receives a WM_EXIT message, this routine tears |
  544. | everything down and exits. |
  545. | |
  546. | Arguments: |
  547. | hwndDlg window handle of the main dialog window |
  548. | Msg message number |
  549. | wParam message-dependent parameter |
  550. | lParam message-dependent parameter |
  551. | |
  552. | Returns: |
  553. | TRUE if the message has been processed, else FALSE |
  554. | |
  555. \*----------------------------------------------------------------------------*/
  556. BOOL mcitester(
  557. HWND hwndDlg,
  558. UINT Msg,
  559. LONG wParam,
  560. LONG lParam)
  561. {
  562. DWORD dw; /* return value from various messages */
  563. UINT EnableOrNot; /* is something currently selected? */
  564. UINT wID; /* the type of notification required */
  565. int i;
  566. #if DBG
  567. if (Msg != WM_MOUSEMOVE && Msg != WM_NCHITTEST && Msg != WM_NCMOUSEMOVE
  568. && (Msg < WM_CTLCOLORMSGBOX || Msg > WM_CTLCOLORSTATIC)
  569. && Msg != WM_SETCURSOR) {
  570. dprintf4((TEXT("hWnd: %08XH, Msg: %08XH, wParam: %08XH, lParam: %08XH"), hwndDlg, Msg, wParam, lParam ));
  571. }
  572. #endif
  573. switch (Msg) {
  574. case WM_CLOSE:
  575. DestroyWindow( hwndDlg );
  576. break;
  577. case WM_COMMAND:
  578. dprintf3((TEXT("WM_COMMAND, wParam: %08XH, lParam: %08XH"), wParam, lParam));
  579. switch (LOWORD(wParam)) {
  580. case IDOK:
  581. /*
  582. * When the OK button gets pressed, insert a CR LF into
  583. * the edit control. and execute the current line.
  584. *
  585. */
  586. SetFocus(hwndEdit);
  587. i = EditGetCurLine(hwndEdit);
  588. execute(hwndDlg, TRUE);
  589. EditSetCurLine(hwndEdit, i);
  590. SendMessage(hwndEdit, WM_KEYDOWN, VK_END, 0L);
  591. SendMessage(hwndEdit, WM_KEYUP, VK_END, 0L);
  592. SendMessage(hwndEdit, EM_REPLACESEL, 0,(LONG)(LPTSTR)aszEOL);
  593. break;
  594. case ID_GO:
  595. /*
  596. * When the GO! button gets pressed, execute every line
  597. * in the edit box starting with the first one.
  598. *
  599. */
  600. EditSetCurLine(hwndEdit, 0);
  601. execute(hwndDlg, FALSE);
  602. break;
  603. case ID_STEP:
  604. /*
  605. * When the STEP button gets pressed, execute the currently
  606. * selected line in the edit box.
  607. */
  608. execute(hwndDlg, TRUE);
  609. break;
  610. case MENU_EXIT:
  611. case ID_EXIT:
  612. /*
  613. * If the user indicates that he/she wishes to exit the
  614. * application, then end the main dialog and post a WM_QUIT
  615. * message.
  616. *
  617. */
  618. DestroyWindow( hwndDlg );
  619. break;
  620. case IDCANCEL:
  621. /* Ctrl+break will result in
  622. 1. If there is an MCI command running, then breaking it (good)
  623. 2. If there is NOT an MCI command running then the dialog manager will send
  624. someone an IDCANCEL, and if we have the focus, we don't want to exit
  625. by surprise. This means that to actually exit you'll have to do
  626. Alt+F4 or else File manu and Exit to send (WM_COMMAND, ID_EXIT)
  627. */
  628. break;
  629. case MENU_ABOUT:
  630. /* Show the 'About...' box */
  631. DialogBox(hInstApp, MAKEINTRESOURCE(IDD_ABOUTBOX), hwndDlg, (DLGPROC)AboutDlgProc);
  632. break;
  633. case WM_CLEAR:
  634. case WM_CUT:
  635. case WM_COPY:
  636. case WM_PASTE:
  637. case WM_UNDO:
  638. /* Pass whatever edit message we receive to the edit box */
  639. dprintf3((TEXT("sending edit Msg to edit control")));
  640. SendMessage(hwndEdit, LOWORD(wParam), 0, 0);
  641. break;
  642. case MENU_OPEN:
  643. /* Open a 'File Open' dialog */
  644. #ifdef WIN16
  645. f = OpenFileDialog(hwndDlg, aszOpenFileTitle, aszExt,
  646. DLGOPEN_MUSTEXIST | OF_EXIST | OF_READ, NULL,
  647. aszBuffer, sizeof(aszBuffer));
  648. /* If the user selected a valid file, then open it */
  649. if ((int)f >= 0)
  650. OpenMciFile(hwndDlg, aszBuffer);
  651. #else
  652. strcpy(aszBuffer, aszExt);
  653. i = DlgOpen(hInstApp, hwndDlg, aszBuffer, sizeof(aszBuffer),
  654. OFN_FILEMUSTEXIST);
  655. /* If the user selected a valid file, then open it */
  656. if (i == 1)
  657. OpenMciFile(hwndDlg, aszBuffer);
  658. #endif
  659. break;
  660. case MENU_SAVE:
  661. /*
  662. * If a filename exists, then save the contents of the edit
  663. * box under that filename.
  664. *
  665. */
  666. if (*aszMciFile) {
  667. EditSaveFile(hwndEdit, aszMciFile);
  668. break;
  669. }
  670. break;
  671. case MENU_SAVEAS:
  672. /*
  673. */
  674. #ifdef WIN16
  675. *aszBuffer = (char)0;
  676. f = OpenFileDialog(hwndDlg, aszSaveFileTitle, aszExt,
  677. DLGOPEN_SAVE | OF_EXIST, aszSaveFileControl, aszBuffer,
  678. sizeof(aszBuffer));
  679. /* If the user didn't hit Cancel, then he must have set a
  680. * filename, so save the contents of the edit box under
  681. * that filename.
  682. */
  683. if (f != DLGOPEN_CANCEL) {
  684. EditSaveFile(hwndEdit, aszBuffer);
  685. }
  686. #else
  687. strcpy(aszBuffer, aszExt);
  688. i = DlgOpen(hInstApp, hwndDlg, aszBuffer, sizeof(aszBuffer) ,
  689. OFN_PATHMUSTEXIST | OFN_NOREADONLYRETURN | OFN_OVERWRITEPROMPT);
  690. /*
  691. * If the user didn't hit Cancel, then he must have set a
  692. * filename, so save the contents of the edit box under
  693. * that filename.
  694. *
  695. */
  696. if (i == 1) {
  697. EditSaveFile(hwndEdit, aszBuffer);
  698. }
  699. #endif
  700. break;
  701. case MENU_DEVICES:
  702. /*
  703. * If the Devices dialog box doesn't already exist, then
  704. * create and display it.
  705. *
  706. */
  707. if (hwndDevices == 0) {
  708. create_device_list();
  709. }
  710. break;
  711. #if DBG
  712. case IDM_DEBUG0:
  713. case IDM_DEBUG1:
  714. case IDM_DEBUG2:
  715. case IDM_DEBUG3:
  716. case IDM_DEBUG4:
  717. dDbgSetDebugMenuLevel(wParam - IDM_DEBUG0);
  718. break;
  719. #endif
  720. default: /* no-op */
  721. break;
  722. }
  723. break; // end of WM_COMMAND case
  724. case WM_INITDIALOG:
  725. /* Do general initialization stuff */
  726. hwndEdit = GetDlgItem(hwndDlg,ID_INPUT);
  727. dprintf3((TEXT("WM_INITDIALOG: hwndEdit = %08xH"), hwndEdit));
  728. SetMenu(hwndDlg, LoadMenu(hInstApp, MAKEINTRESOURCE(IDM_MCITEST)));
  729. SetClassLong (hwndDlg, GCL_HICON,
  730. (DWORD)LoadIcon (hInstApp, MAKEINTRESOURCE(IDI_MCITEST)));
  731. CheckDlgButton (hwndDlg, ID_NOT_SUCCESS, FALSE);
  732. CheckDlgButton (hwndDlg, ID_NOT_SUPER, FALSE);
  733. CheckDlgButton (hwndDlg, ID_NOT_ABORT, FALSE);
  734. CheckDlgButton (hwndDlg, ID_NOT_FAIL, FALSE);
  735. SetDlgItemInt (hwndDlg, ID_RUNCOUNT, 1, TRUE);
  736. #if DBG
  737. // Check the initial debug level
  738. {
  739. HANDLE hMenu;
  740. hMenu = GetMenu(hwndDlg);
  741. CheckMenuItem(hMenu, (UINT)(__iDebugLevel + IDM_DEBUG0), MF_CHECKED);
  742. }
  743. #endif
  744. hAccTable = LoadAccelerators(hInstApp, MAKEINTRESOURCE(IDA_MCITEST));
  745. dprintf4((TEXT("INIT_DIALOG: hwndEdit = %08XH, Haccel = %08XH"), hwndEdit, hAccTable));
  746. return TRUE;
  747. case WM_DESTROY:
  748. /* End the dialog and send a WM_QUIT message */
  749. dprintf2((TEXT("dialog ending")));
  750. dSaveDebugLevel(aszAppName);
  751. PostQuitMessage (0);
  752. hwndMainDlg = 0;
  753. break;
  754. case MM_MCINOTIFY:
  755. /*
  756. * Check the radio button corresponding to the notification
  757. * received.
  758. *
  759. */
  760. dprintf3((TEXT("MM_MCINOTIFY, wParam: %08XH"), wParam));
  761. wID = 0;
  762. switch (wParam) {
  763. case MCI_NOTIFY_SUCCESSFUL:
  764. wID = ID_NOT_SUCCESS;
  765. break;
  766. case MCI_NOTIFY_SUPERSEDED:
  767. wID = ID_NOT_SUPER;
  768. break;
  769. case MCI_NOTIFY_ABORTED:
  770. wID = ID_NOT_ABORT;
  771. break;
  772. case MCI_NOTIFY_FAILURE:
  773. wID = ID_NOT_FAIL;
  774. break;
  775. default:
  776. break;
  777. }
  778. if (wID) {
  779. CheckDlgButton (hwndDlg, wID, TRUE);
  780. SetFocus (GetDlgItem(hwndDlg, ID_INPUT));
  781. }
  782. break;
  783. case WM_INITMENUPOPUP: /* wParam is menu handle */
  784. dprintf3((TEXT("WM_INITMENUPOPUP")));
  785. /* Enable the 'Save' option if a valid filename exists */
  786. EnableMenuItem((HMENU)wParam, (UINT)MENU_SAVE,
  787. (UINT)(*aszMciFile ? MF_ENABLED : MF_GRAYED));
  788. /* Find out if something is currently selected in the edit box */
  789. dw = SendMessage(hwndEdit,EM_GETSEL,0,0L);
  790. EnableOrNot = (UINT)((HIWORD(dw) != LOWORD(dw) ? MF_ENABLED : MF_GRAYED));
  791. /* Enable / disable the Edit menu options appropriately */
  792. EnableMenuItem ((HMENU)wParam, (UINT)WM_UNDO ,
  793. (UINT)(SendMessage(hwndEdit,EM_CANUNDO,0,0L) ? MF_ENABLED : MF_GRAYED));
  794. EnableMenuItem ((HMENU)wParam, WM_CUT , EnableOrNot);
  795. EnableMenuItem ((HMENU)wParam, WM_COPY , EnableOrNot);
  796. EnableMenuItem ((HMENU)wParam, WM_PASTE,
  797. (UINT)(IsClipboardFormatAvailable(CF_TEXT) ? MF_ENABLED : MF_GRAYED));
  798. EnableMenuItem ((HMENU)wParam, WM_CLEAR, EnableOrNot);
  799. return 0L;
  800. }
  801. return 0;
  802. }
  803. /*----------------------------------------------------------------------------*\
  804. | AppInit( hInst, hPrev, sw, szCmdLine) |
  805. | |
  806. | Description: |
  807. | This is called when the application is first loaded into memory. It |
  808. | performs all initialization that doesn't need to be done once per |
  809. | instance. |
  810. | |
  811. | Arguments: |
  812. | hInstance instance handle of current instance |
  813. | hPrev instance handle of previous instance |
  814. | sw not really used at all |
  815. | szCmdLine string containing the command line arguments |
  816. | |
  817. | Returns: |
  818. | TRUE if successful, FALSE if not |
  819. | |
  820. \*----------------------------------------------------------------------------*/
  821. BOOL AppInit(
  822. int argc,
  823. char *argv[])
  824. {
  825. /* Put up the main dialog box */
  826. hInstApp = GetModuleHandle(NULL);
  827. dprintf1((TEXT("MCITEST starting... module handle is %xH"), hInstApp));
  828. if (NULL ==
  829. (hwndMainDlg = CreateDialog (hInstApp,
  830. MAKEINTRESOURCE(IDD_MCITEST),
  831. NULL, (DLGPROC)mcitester)
  832. )) {
  833. DWORD n;
  834. n = GetLastError();
  835. dprintf1((TEXT("NULL hwndMainDLG, last error is %d"), n));
  836. DebugBreak();
  837. return(FALSE);
  838. }
  839. /* Fix up WIN.INI if this is the first time we are run... */
  840. if (!GetProfileString(aszProfileSection, aszProfileKey, aszNULL, aszBuffer, sizeof(aszBuffer)))
  841. WriteProfileString(aszProfileSection, aszProfileKey, aszProfileSetting);
  842. /*
  843. * If a command line argument was specified, assume it to be a filename
  844. * and open that file.
  845. *
  846. */
  847. if (argc > 1 && *argv[1]) {
  848. #ifdef UNICODE
  849. LPTSTR lpCommandLine = GetCommandLine();
  850. // Skip over the command name to get to the argument string
  851. while (*lpCommandLine && *lpCommandLine++ != TEXT(' ')) {
  852. }
  853. OpenMciFile(hwndMainDlg, lpCommandLine);
  854. #else
  855. OpenMciFile(hwndMainDlg, argv[1]);
  856. #endif
  857. }
  858. return TRUE;
  859. }
  860. /*----------------------------------------------------------------------------*\
  861. | WinMain( hInst, hPrev, lpszCmdLine, sw ) |
  862. | |
  863. | Description: |
  864. | The main procedure for the app. After initializing, it just goes |
  865. | into a message-processing loop until it gets a WM_QUIT message |
  866. | (meaning the app was closed). |
  867. | |
  868. | Arguments: |
  869. | hInst instance handle of this instance of the app |
  870. | hPrev instance handle of previous instance, NULL if first |
  871. | szCmdLine null-terminated command line string |
  872. | sw specifies how the window is to be initially displayed |
  873. | |
  874. | Returns: |
  875. | The exit code as specified in the WM_QUIT message. |
  876. | |
  877. \*----------------------------------------------------------------------------*/
  878. int __cdecl main(
  879. int argc,
  880. char *argv[],
  881. char *envp[])
  882. {
  883. MSG Msg; /* Windows message structure */
  884. // If we are in DEBUG mode, get debug level for this module
  885. dGetDebugLevel(aszAppName);
  886. #if DBG
  887. dprintf1((TEXT("started (debug level %d)"), __iDebugLevel));
  888. #endif
  889. /* Call the initialization procedure */
  890. if (!AppInit(argc, argv)) {
  891. return FALSE;
  892. }
  893. /* Poll the event queue for messages */
  894. while (GetMessage(&Msg, NULL, 0, 0)) {
  895. /*
  896. * If the Devices dialog is showing and the number of open devices has
  897. * changed since we last checked, then update the list of open devices.
  898. */
  899. if (hwndDevices != 0 && get_number_of_devices() != nLastNumberOfDevices) {
  900. update_device_list();
  901. }
  902. /* Main message processing */
  903. if (!hwndMainDlg || !IsDialogMessage(hwndMainDlg, &Msg)) {
  904. TranslateMessage(&Msg);
  905. DispatchMessage(&Msg);
  906. // IsDialogMessage may enter with hwndMainDlg != NULL and exit with
  907. // hwndMainDlg == NULL after processing the message
  908. }
  909. else if (hwndMainDlg) {
  910. TranslateAccelerator (hwndMainDlg, hAccTable, &Msg);
  911. }
  912. }
  913. return Msg.wParam;
  914. }
  915. STATICDT TCHAR ms[] = TEXT("milliseconds");
  916. STATICDT TCHAR sc[] = TEXT("seconds");
  917. STATICDT TCHAR hr[] = TEXT("hours");
  918. STATICDT TCHAR mn[] = TEXT("minutes");
  919. STATICFN void ProcessInternalCommand(HWND hDlg, LPTSTR aszBuffer)
  920. {
  921. LPTSTR pch = aszBuffer;
  922. TCHAR msg[80];
  923. if( (0 == (strnicmp(aszBuffer, TEXT("SLEEP"),5)))
  924. || (0 == (strnicmp(aszBuffer, TEXT("PAUSE"),5)))) {
  925. UINT factor = 1;
  926. UINT number;
  927. LPTSTR delay;
  928. LPTSTR pch1;
  929. pch += 5; // length SLEEP/PAUSE
  930. while (*pch && *pch == TEXT(' ') ) {
  931. pch++;
  932. }
  933. if (!*pch) {
  934. SetDlgItemText (hDlg, ID_OUTPUT, TEXT("No parameter provided for Sleep command"));
  935. return;
  936. }
  937. #ifdef UNICODE
  938. wsprintf(msg "%hs", pch); // Convert string to ascii
  939. number = atoi( msg );
  940. #else
  941. number = atoi( pch );
  942. #endif
  943. if (0 == number) {
  944. SetDlgItemText (hDlg, ID_OUTPUT, TEXT("Parameter is not a number"));
  945. return;
  946. }
  947. // pch addresses the number
  948. // Now see if there are any other parameters
  949. // First, skip to the end of the number
  950. pch1 = pch+1;
  951. while (*pch1 && *pch1 != TEXT(' ') ) {
  952. pch1++;
  953. }
  954. if (*pch1) {
  955. *pch1++ = TEXT('\0');
  956. // There is another parameter. Accept s/S for seconds,
  957. // h/M for hours
  958. // m/M for minutes
  959. // Default is milliseconds
  960. while (*pch1 && *pch1 == TEXT(' ') ) {
  961. pch1++;
  962. }
  963. }
  964. switch (*pch1) {
  965. case TEXT('s'):
  966. case TEXT('S'):
  967. delay = sc;
  968. factor = 1000;
  969. break;
  970. case TEXT('m'):
  971. case TEXT('M'):
  972. delay = mn;
  973. factor = 1000*60;
  974. break;
  975. case TEXT('h'):
  976. case TEXT('H'):
  977. delay = hr;
  978. factor = 1000*60*60;
  979. break;
  980. case TEXT('\0'):
  981. default:
  982. delay = ms;
  983. factor = 1;
  984. break;
  985. }
  986. wsprintf(msg, TEXT("Sleeping for %d %s"), number, delay);
  987. SetDlgItemText (hDlg, ID_OUTPUT, msg);
  988. Sleep(number*factor);
  989. } else if (0 == (strnicmp(aszBuffer, TEXT("CD"),2))) {
  990. BOOL fResult;
  991. pch += 2; // length CD
  992. while (*pch && *pch == TEXT(' ') ) {
  993. pch++;
  994. }
  995. fResult = SetCurrentDirectory(pch);
  996. if (!fResult) {
  997. UINT errorcode;
  998. errorcode = GetLastError();
  999. wsprintf(msg,
  1000. TEXT("Set current directory to >%s< failed, error code==%d"),
  1001. pch, errorcode);
  1002. } else
  1003. wsprintf(msg,
  1004. TEXT("Set current directory to >%s<"), pch);
  1005. SetDlgItemText (hDlg, ID_OUTPUT, msg);
  1006. } else {
  1007. SetDlgItemText (hDlg, ID_OUTPUT, TEXT("Unrecognised internal command"));
  1008. }
  1009. }