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.

2433 lines
61 KiB

  1. //==========================================================================;
  2. //
  3. // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
  4. // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED
  5. // TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR
  6. // A PARTICULAR PURPOSE.
  7. //
  8. // Copyright (C) 1993 - 1997 Microsoft Corporation. All Rights Reserved.
  9. //
  10. //--------------------------------------------------------------------------;
  11. //
  12. // mmcaps.c
  13. //
  14. // Description:
  15. //
  16. //
  17. // History:
  18. // 11/ 8/92
  19. //
  20. //==========================================================================;
  21. #include <windows.h>
  22. #include <windowsx.h>
  23. #include <mmsystem.h>
  24. #include <commdlg.h>
  25. #include <stdarg.h>
  26. #include "appport.h"
  27. #include "mmcaps.h"
  28. #include "debug.h"
  29. //
  30. // globals, no less
  31. //
  32. HINSTANCE ghinst;
  33. TCHAR gszAppSection[] = TEXT("MMCaps");
  34. TCHAR gszNull[] = TEXT("");
  35. TCHAR gszAppName[APP_MAX_APP_NAME_CHARS];
  36. //
  37. //
  38. //
  39. PZYZTABBEDLISTBOX gptlbDrivers;
  40. TCHAR gszUnknown[] = TEXT("Unknown");
  41. TCHAR gszNotSpecified[] = TEXT("Not Specified");
  42. UINT guDriverType = MMCAPS_DRIVERTYPE_LOWLEVEL;
  43. //==========================================================================;
  44. //
  45. // Application helper functions
  46. //
  47. //
  48. //==========================================================================;
  49. //--------------------------------------------------------------------------;
  50. //
  51. // BOOL AppProfileWriteBytes
  52. //
  53. // Description:
  54. // This function writes a raw structure of bytes to the application's
  55. // ini section that can later be retrieved using AppProfileReadBytes.
  56. // This gives an application the ability to write any structure to
  57. // the ini file and restore it later--very useful.
  58. //
  59. // NOTE! Starting with Windows for Workgroups 3.1 there are two new
  60. // profile functions that provide the same functionality of this
  61. // function. Specifically, these functions are GetPrivateProfileStruct
  62. // and WritePrivateProfileStruct. These new functions are provided
  63. // by the Common Controls DLL. The prototypes are as follows:
  64. //
  65. // BOOL GetPrivateProfileStruct
  66. // (
  67. // LPSTR szSection,
  68. // LPSTR szKey,
  69. // LPBYTE lpStruct,
  70. // UINT uSizeStruct,
  71. // LPSTR szFile
  72. // );
  73. //
  74. // BOOL WritePrivateProfileStruct
  75. // (
  76. // LPSTR szSection,
  77. // LPSTR szKey,
  78. // LPBYTE lpStruct,
  79. // UINT uSizeStruct,
  80. // LPSTR szFile
  81. // );
  82. //
  83. // If you are building an application that is for Window for Workgroups
  84. // or newer versions of Windows, you will probably want to use the
  85. // above functions.
  86. //
  87. // Arguments:
  88. // PCTSTR pszKey: Pointer to key name for the stored data.
  89. //
  90. // LPBYTE pbStruct: Pointer to the data to be saved.
  91. //
  92. // UINT cbStruct: Count in bytes of the data to store.
  93. //
  94. // Return (BOOL):
  95. // The return value is TRUE if the function is successful. It is FALSE
  96. // if it fails.
  97. //
  98. // History:
  99. // 3/10/93
  100. //
  101. //--------------------------------------------------------------------------;
  102. BOOL FNGLOBAL AppProfileWriteBytes
  103. (
  104. PCTSTR pszKey,
  105. LPBYTE pbStruct,
  106. UINT cbStruct
  107. )
  108. {
  109. static TCHAR achNibbleToChar[] =
  110. {
  111. '0', '1', '2', '3', '4', '5', '6', '7',
  112. '8', '9', 'A', 'B', 'C', 'D', 'E', 'F',
  113. };
  114. #define NIBBLE2CHAR(x) (achNibbleToChar[x])
  115. TCHAR ach[APP_MAX_STRING_RC_CHARS];
  116. LPTSTR psz;
  117. LPTSTR pch;
  118. UINT cchTemp;
  119. BOOL fAllocated;
  120. BOOL fReturn;
  121. BYTE b;
  122. BYTE bChecksum;
  123. //
  124. // if pbStruct is NULL, then erase the key from the ini file, otherwise
  125. // format the raw bytes into a hex string and write that out...
  126. //
  127. fAllocated = FALSE;
  128. psz = NULL;
  129. if (NULL != pbStruct)
  130. {
  131. //
  132. // check if the quick buffer can be used for formatting the output
  133. // text--if it cannot, then alloc space for it. note that space
  134. // must be available for an ending checksum byte (2 bytes for high
  135. // and low nibble) as well as a null terminator.
  136. //
  137. psz = (LPTSTR)ach;
  138. cchTemp = cbStruct * 2 + 3;
  139. if (cchTemp > SIZEOF(ach))
  140. {
  141. psz = GlobalAllocPtr(GHND, cchTemp * sizeof(TCHAR));
  142. if (NULL == psz)
  143. return (FALSE);
  144. fAllocated = TRUE;
  145. }
  146. //
  147. // step through all bytes in the structure and convert it to
  148. // a string of hex numbers...
  149. //
  150. bChecksum = 0;
  151. for (pch = psz; 0 != cbStruct; cbStruct--, pbStruct++)
  152. {
  153. //
  154. // grab the next byte and add into checksum...
  155. //
  156. bChecksum += (b = *pbStruct);
  157. *pch++ = NIBBLE2CHAR((b >> (BYTE)4) & (BYTE)0x0F);
  158. *pch++ = NIBBLE2CHAR(b & (BYTE)0x0F);
  159. }
  160. //
  161. // add the checksum byte to the end and null terminate the hex
  162. // dumped string...
  163. //
  164. *pch++ = NIBBLE2CHAR((bChecksum >> (BYTE)4) & (BYTE)0x0F);
  165. *pch++ = NIBBLE2CHAR(bChecksum & (BYTE)0x0F);
  166. *pch = '\0';
  167. }
  168. //
  169. // write the string of hex bytes out to the ini file...
  170. //
  171. fReturn = WriteProfileString(gszAppSection, pszKey, psz);
  172. //
  173. // free the temporary buffer if one was allocated (lots of bytes!)
  174. //
  175. if (fAllocated)
  176. GlobalFreePtr(psz);
  177. return (fReturn);
  178. } // AppProfileWriteBytes
  179. //--------------------------------------------------------------------------;
  180. //
  181. // BOOL AppProfileReadBytes
  182. //
  183. // Description:
  184. // This function reads a previously stored structure of bytes from
  185. // the application's ini file. This data must have been written with
  186. // the AppProfileWriteBytes function--it is checksumed to keep bad
  187. // data from blowing up the application.
  188. //
  189. // NOTE! Starting with Windows for Workgroups 3.1 there are two new
  190. // profile functions that provide the same functionality of this
  191. // function. Specifically, these functions are GetPrivateProfileStruct
  192. // and WritePrivateProfileStruct. These new functions are provided
  193. // by the Common Controls DLL. The prototypes are as follows:
  194. //
  195. // BOOL GetPrivateProfileStruct
  196. // (
  197. // LPSTR szSection,
  198. // LPSTR szKey,
  199. // LPBYTE lpStruct,
  200. // UINT uSizeStruct,
  201. // LPSTR szFile
  202. // );
  203. //
  204. // BOOL WritePrivateProfileStruct
  205. // (
  206. // LPSTR szSection,
  207. // LPSTR szKey,
  208. // LPBYTE lpStruct,
  209. // UINT uSizeStruct,
  210. // LPSTR szFile
  211. // );
  212. //
  213. // If you are building an application that is for Window for Workgroups
  214. // or newer versions of Windows, you will probably want to use the
  215. // above functions.
  216. //
  217. // Arguments:
  218. // PCTSTR pszKey: Pointer to key that contains the data.
  219. //
  220. // LPBYTE pbStruct: Pointer to buffer to receive the data.
  221. //
  222. // UINT cbStruct: Number of bytes expected.
  223. //
  224. // Return (BOOL):
  225. // The return value is TRUE if the function is successful. It is FALSE
  226. // if the function fails (bad checksum, missing key, etc).
  227. //
  228. // History:
  229. // 3/10/93
  230. //
  231. //--------------------------------------------------------------------------;
  232. BOOL FNGLOBAL AppProfileReadBytes
  233. (
  234. PCTSTR pszKey,
  235. LPBYTE pbStruct,
  236. UINT cbStruct
  237. )
  238. {
  239. //
  240. // note that the following works for both upper and lower case, and
  241. // will return valid values for garbage chars
  242. //
  243. #define CHAR2NIBBLE(ch) (BYTE)( ((ch) >= '0' && (ch) <= '9') ? \
  244. (BYTE)((ch) - '0') : \
  245. ((BYTE)(10 + (ch) - 'A') & (BYTE)0x0F) )
  246. TCHAR ach[APP_MAX_STRING_RC_CHARS];
  247. LPTSTR psz;
  248. LPTSTR pch;
  249. UINT cchTemp;
  250. UINT u;
  251. BOOL fAllocated;
  252. BOOL fReturn;
  253. BYTE b;
  254. BYTE bChecksum;
  255. TCHAR ch;
  256. //
  257. // add one the the number of bytes needed to accomodate the checksum
  258. // byte placed at the end by AppProfileWriteBytes...
  259. //
  260. cbStruct++;
  261. //
  262. // check if the quick buffer can be used for retrieving the input
  263. // text--if it cannot, then alloc space for it. note that there must
  264. // be space available for the null terminator (the +1 below).
  265. //
  266. fAllocated = FALSE;
  267. psz = (LPTSTR)ach;
  268. cchTemp = cbStruct * 2 + 1;
  269. if (cchTemp > SIZEOF(ach))
  270. {
  271. psz = GlobalAllocPtr(GHND, cchTemp * sizeof(TCHAR));
  272. if (NULL == psz)
  273. return (FALSE);
  274. fAllocated = TRUE;
  275. }
  276. //
  277. // read the hex string... if it is not the correct length, then assume
  278. // error and return.
  279. //
  280. fReturn = FALSE;
  281. u = (UINT)GetProfileString(gszAppSection, pszKey, gszNull, psz, cchTemp);
  282. if ((cbStruct * 2) == u)
  283. {
  284. bChecksum = 0;
  285. for (pch = psz; 0 != cbStruct; cbStruct--, pbStruct++)
  286. {
  287. ch = *pch++;
  288. b = CHAR2NIBBLE(ch) << (BYTE)4;
  289. ch = *pch++;
  290. b |= CHAR2NIBBLE(ch);
  291. //
  292. // if this is not the final byte (the checksum byte), then
  293. // store it and accumulate checksum..
  294. //
  295. if (cbStruct != 1)
  296. bChecksum += (*pbStruct = b);
  297. }
  298. //
  299. // check the last byte read against the checksum that we calculated
  300. // if they are not equal then return error...
  301. //
  302. fReturn = (bChecksum == b);
  303. }
  304. //
  305. // free the temporary buffer if one was allocated (lots of bytes!)
  306. //
  307. if (fAllocated)
  308. GlobalFreePtr(psz);
  309. return (fReturn);
  310. } // AppProfileReadBytes
  311. //--------------------------------------------------------------------------;
  312. //
  313. // int AppMsgBox
  314. //
  315. // Description:
  316. // This function displays a message for the application in a standard
  317. // message box.
  318. //
  319. // Note that this function takes any valid argument list that can
  320. // be passed to wsprintf. Because of this, the application must
  321. // remember to cast near string pointers to FAR when built for Win 16.
  322. // You will get a nice GP fault if you do not cast them correctly.
  323. //
  324. // Arguments:
  325. // HWND hwnd: Handle to parent window for message box holding the
  326. // message.
  327. //
  328. // UINT fuStyle: Style flags for MessageBox().
  329. //
  330. // PCTSTR pszFormat: Format string used for wvsprintf().
  331. //
  332. // Return (int):
  333. // The return value is the result of MessageBox() function.
  334. //
  335. // History:
  336. // 2/13/93
  337. //
  338. //--------------------------------------------------------------------------;
  339. int FNCGLOBAL AppMsgBox
  340. (
  341. HWND hwnd,
  342. UINT fuStyle,
  343. PCTSTR pszFormat,
  344. ...
  345. )
  346. {
  347. va_list va;
  348. TCHAR ach[APP_MAX_STRING_ERROR_CHARS];
  349. int n;
  350. //
  351. // format and display the message..
  352. //
  353. va_start(va, pszFormat);
  354. wvsprintf(ach, pszFormat, va);
  355. va_end(va);
  356. n = MessageBox(hwnd, ach, gszAppName, fuStyle);
  357. return (n);
  358. } // AppMsgBox()
  359. //--------------------------------------------------------------------------;
  360. //
  361. // int AppMsgBoxId
  362. //
  363. // Description:
  364. // This function displays a message for the application. The message
  365. // text is retrieved from the string resource table using LoadString.
  366. //
  367. // Note that this function takes any valid argument list that can
  368. // be passed to wsprintf. Because of this, the application must
  369. // remember to cast near string pointers to FAR when built for Win 16.
  370. // You will get a nice GP fault if you do not cast them correctly.
  371. //
  372. // Arguments:
  373. // HWND hwnd: Handle to parent window for message box holding the
  374. // message.
  375. //
  376. // UINT fuStyle: Style flags for MessageBox().
  377. //
  378. // UINT uIdsFormat: String resource id to be loaded with LoadString()
  379. // and used a the format string for wvsprintf().
  380. //
  381. // Return (int):
  382. // The return value is the result of MessageBox() if the string
  383. // resource specified by uIdsFormat is valid. The return value is zero
  384. // if the string resource failed to load.
  385. //
  386. // History:
  387. // 2/13/93
  388. //
  389. //--------------------------------------------------------------------------;
  390. int FNCGLOBAL AppMsgBoxId
  391. (
  392. HWND hwnd,
  393. UINT fuStyle,
  394. UINT uIdsFormat,
  395. ...
  396. )
  397. {
  398. va_list va;
  399. TCHAR szFormat[APP_MAX_STRING_RC_CHARS];
  400. TCHAR ach[APP_MAX_STRING_ERROR_CHARS];
  401. int n;
  402. n = LoadString(ghinst, uIdsFormat, szFormat, SIZEOF(szFormat));
  403. if (0 != n)
  404. {
  405. //
  406. // format and display the message..
  407. //
  408. va_start(va, uIdsFormat);
  409. wvsprintf(ach, szFormat, va);
  410. va_end(va);
  411. n = MessageBox(hwnd, ach, gszAppName, fuStyle);
  412. }
  413. return (n);
  414. } // AppMsgBoxId()
  415. //--------------------------------------------------------------------------;
  416. //
  417. // void AppHourGlass
  418. //
  419. // Description:
  420. // This function changes the cursor to that of the hour glass or
  421. // back to the previous cursor.
  422. //
  423. // This function can be called recursively.
  424. //
  425. // Arguments:
  426. // BOOL fHourGlass: TRUE if we need the hour glass. FALSE if we need
  427. // the arrow back.
  428. //
  429. // Return (void):
  430. // On return, the cursor will be what was requested.
  431. //
  432. // History:
  433. // 11/ 8/92
  434. //
  435. //--------------------------------------------------------------------------;
  436. void FNGLOBAL AppHourGlass
  437. (
  438. BOOL fHourGlass
  439. )
  440. {
  441. static HCURSOR hcur;
  442. static UINT uWaiting = 0;
  443. if (fHourGlass)
  444. {
  445. if (!uWaiting)
  446. {
  447. hcur = SetCursor(LoadCursor(NULL, IDC_WAIT));
  448. ShowCursor(TRUE);
  449. }
  450. uWaiting++;
  451. }
  452. else
  453. {
  454. --uWaiting;
  455. if (!uWaiting)
  456. {
  457. ShowCursor(FALSE);
  458. SetCursor(hcur);
  459. }
  460. }
  461. } // AppHourGlass()
  462. //--------------------------------------------------------------------------;
  463. //
  464. // int AppDialogBox
  465. //
  466. // Description:
  467. // This function is used to display a dialog modal box.
  468. //
  469. // Arguments:
  470. // HWND hwnd: Handle to parent window for new dialog.
  471. //
  472. // LPCSTR pszDlg: Dialog template to use.
  473. //
  474. // DLGPROC pfnDlg: Pointer to dialog procedure.
  475. //
  476. // LPARAM lParam: Any lParam to be passed as lParam for WM_INITDIALOG.
  477. //
  478. // Return (int):
  479. // The return value is the nResult from EndDialog.
  480. //
  481. // History:
  482. // 11/ 8/92
  483. //
  484. //--------------------------------------------------------------------------;
  485. int FNGLOBAL AppDialogBox
  486. (
  487. HWND hwnd,
  488. LPCTSTR pszDlg,
  489. DLGPROC pfnDlg,
  490. LPARAM lParam
  491. )
  492. {
  493. int nResult;
  494. //
  495. // !!! NT doesn't need this--neither does Win 3.1 with C7/C8 !!!
  496. //
  497. //
  498. nResult = 0;
  499. pfnDlg = (DLGPROC)MakeProcInstance((FARPROC)pfnDlg, ghinst);
  500. if (NULL != pfnDlg)
  501. {
  502. nResult = DialogBoxParam(ghinst, pszDlg, hwnd, pfnDlg, lParam);
  503. FreeProcInstance((FARPROC)pfnDlg);
  504. }
  505. return (nResult);
  506. } // AppDialogBox()
  507. //--------------------------------------------------------------------------;
  508. //
  509. // int AppSetWindowText
  510. //
  511. // Description:
  512. // This function formats a string and sets the specified window text
  513. // to the result.
  514. //
  515. // Arguments:
  516. // HWND hwnd: Handle to window to receive the new text.
  517. //
  518. // PCTSTR pszFormat: Pointer to any valid format for wsprintf.
  519. //
  520. // Return (int):
  521. // The return value is the number of bytes that the resulting window
  522. // text was.
  523. //
  524. // History:
  525. // 2/ 7/93
  526. //
  527. //--------------------------------------------------------------------------;
  528. int FNCGLOBAL AppSetWindowText
  529. (
  530. HWND hwnd,
  531. PCTSTR pszFormat,
  532. ...
  533. )
  534. {
  535. va_list va;
  536. TCHAR ach[APP_MAX_STRING_ERROR_CHARS];
  537. int n;
  538. //
  539. // format and display the string in the window...
  540. //
  541. va_start(va, pszFormat);
  542. n = wvsprintf(ach, pszFormat, va);
  543. va_end(va);
  544. SetWindowText(hwnd, ach);
  545. return (n);
  546. } // AppSetWindowText()
  547. //--------------------------------------------------------------------------;
  548. //
  549. // int AppSetWindowTextId
  550. //
  551. // Description:
  552. // This function formats a string and sets the specified window text
  553. // to the result. The format string is extracted from the string
  554. // table using LoadString() on the uIdsFormat argument.
  555. //
  556. // Arguments:
  557. // HWND hwnd: Handle to window to receive the new text.
  558. //
  559. // UINT uIdsFormat: String resource id to be loaded with LoadString()
  560. // and used a the format string for wvsprintf().
  561. //
  562. // Return (int):
  563. // The return value is the number of bytes that the resulting window
  564. // text was. This value is zero if the LoadString() function fails
  565. // for the uIdsFormat argument.
  566. //
  567. // History:
  568. // 2/ 7/93
  569. //
  570. //--------------------------------------------------------------------------;
  571. int FNCGLOBAL AppSetWindowTextId
  572. (
  573. HWND hwnd,
  574. UINT uIdsFormat,
  575. ...
  576. )
  577. {
  578. va_list va;
  579. TCHAR szFormat[APP_MAX_STRING_RC_CHARS];
  580. TCHAR ach[APP_MAX_STRING_ERROR_CHARS];
  581. int n;
  582. n = LoadString(ghinst, uIdsFormat, szFormat, SIZEOF(szFormat));
  583. if (0 != n)
  584. {
  585. //
  586. // format and display the string in the window...
  587. //
  588. va_start(va, uIdsFormat);
  589. n = wvsprintf(ach, szFormat, va);
  590. va_end(va);
  591. SetWindowText(hwnd, ach);
  592. }
  593. return (n);
  594. } // AppSetWindowTextId()
  595. //--------------------------------------------------------------------------;
  596. //
  597. // int AppMEditPrintF
  598. //
  599. // Description:
  600. // This function is used to print formatted text into a Multiline
  601. // Edit Control as if it were a standard console display. This is
  602. // a very easy way to display small amounts of text information
  603. // that can be scrolled and copied to the clip-board.
  604. //
  605. // Arguments:
  606. // HWND hedit: Handle to a Multiline Edit control.
  607. //
  608. // PCTSTR pszFormat: Pointer to any valid format for wsprintf. If
  609. // this argument is NULL, then the Multiline Edit Control is cleared
  610. // of all text.
  611. //
  612. // Return (int):
  613. // Returns the number of characters written into the edit control.
  614. //
  615. // History:
  616. // 05/16/93
  617. //
  618. //--------------------------------------------------------------------------;
  619. int FNCGLOBAL AppMEditPrintF
  620. (
  621. HWND hedit,
  622. PCTSTR pszFormat,
  623. ...
  624. )
  625. {
  626. va_list va;
  627. TCHAR ach[APP_MAX_STRING_RC_CHARS];
  628. int n;
  629. //
  630. // if the pszFormat argument is NULL, then just clear all text in
  631. // the edit control..
  632. //
  633. if (NULL == pszFormat)
  634. {
  635. SetWindowText(hedit, gszNull);
  636. return (0);
  637. }
  638. //
  639. // format and display the string in the window...
  640. //
  641. va_start(va, pszFormat);
  642. n = wvsprintf(ach, pszFormat, va);
  643. va_end(va);
  644. Edit_SetSel(hedit, (WPARAM)-1, (LPARAM)-1);
  645. Edit_ReplaceSel(hedit, ach);
  646. return (n);
  647. } // AppMEditPrintF()
  648. //--------------------------------------------------------------------------;
  649. //
  650. // DWORD AppGetWindowsVersion
  651. //
  652. // Description:
  653. // This function returns the version of Windows that the application
  654. // is running on plus some platform information.
  655. //
  656. // Arguments:
  657. // PTSTR pach: Options pointer to buffer to receive text string of
  658. // the Windows version and platform.
  659. //
  660. // Return (LRESULT):
  661. // The return value will be the version and platform information of
  662. // the current operating system in the following format:
  663. //
  664. // 0xPPPPMMRR where:
  665. //
  666. // MM : major version of Windows
  667. // RR : minor version (revision) of Windows
  668. // PPPP : the platform the application is running on which
  669. // will be one of the following:
  670. //
  671. // #ifdef WIN32
  672. // the HIWORD() is RESERVED except for the high bit:
  673. // high bit is 0 = Windows NT
  674. // high bit is 1 = Win32s/Windows 3.1
  675. // #else
  676. // 0xMMRR = Major and Minor version of [MS-]DOS
  677. // GetWinFlags() & 0x8000 = Windows on OS/2 (WLO)
  678. // GetWinFlags() & 0x4000 = Windows on Windows NT (WOW)
  679. // #endif
  680. //
  681. // History:
  682. // 2/13/93
  683. //
  684. //--------------------------------------------------------------------------;
  685. LRESULT FNGLOBAL AppGetWindowsVersion
  686. (
  687. PTSTR pszEnvironment,
  688. PTSTR pszPlatform
  689. )
  690. {
  691. BYTE bVerWinMajor;
  692. BYTE bVerWinMinor;
  693. UINT uVerEnv;
  694. DWORD dw;
  695. LRESULT lr;
  696. dw = GetVersion();
  697. //
  698. // massage the version information into something intelligent
  699. //
  700. //
  701. bVerWinMajor = LOBYTE(LOWORD(dw));
  702. bVerWinMinor = HIBYTE(LOWORD(dw));
  703. uVerEnv = HIWORD(dw);
  704. lr = MAKELPARAM(((UINT)bVerWinMajor << 8) | bVerWinMinor, uVerEnv);
  705. //
  706. // if caller wants the environment string version...
  707. //
  708. if (NULL != pszEnvironment)
  709. {
  710. //
  711. //
  712. //
  713. #ifdef WIN32
  714. {
  715. static TCHAR szFormatVersion[] = TEXT("%s Version %u.%.2u");
  716. static TCHAR szEnvWinNT[] = TEXT("Windows NT");
  717. static TCHAR szEnvWin32s[] = TEXT("Win32s");
  718. wsprintf(pszEnvironment, szFormatVersion,
  719. (LPSTR)((0x8000 & uVerEnv) ? szEnvWin32s : szEnvWinNT),
  720. bVerWinMajor, bVerWinMinor);
  721. }
  722. #else
  723. {
  724. #ifndef WF_WINNT
  725. #define WF_CPUR4000 0x0100
  726. #define WF_CPUALPHA21064 0x0200
  727. #define WF_WINNT 0x4000
  728. #define WF_WLO 0x8000
  729. #endif
  730. static TCHAR szFormatSubSys[]= TEXT("Windows Version %u.%.2u (%s%s)\n%s Subsystem, DOS Version %u.%.2u");
  731. static TCHAR szFormatDOS[] = TEXT("Windows Version %u.%.2u (%s%s)\nDOS Version %u.%.2u");
  732. static TCHAR szSubSysWLO[] = TEXT("WLO");
  733. static TCHAR szSubSysWOW[] = TEXT("WOW");
  734. static TCHAR szModeEnhanced[]= TEXT("Enhanced");
  735. static TCHAR szModeStandard[]= TEXT("Standard");
  736. static TCHAR szEnvPaging[] = TEXT(", Paging");
  737. DWORD dwWinFlags;
  738. PTSTR pszMode;
  739. BYTE bVerEnvMajor = HIBYTE(LOWORD(uVerEnv));
  740. BYTE bVerEnvMinor = LOBYTE(LOWORD(uVerEnv));
  741. dwWinFlags = GetWinFlags();
  742. pszMode = (dwWinFlags & WF_ENHANCED) ? szModeEnhanced : szModeStandard;
  743. if (dwWinFlags & (WF_WLO | WF_WINNT))
  744. {
  745. wsprintf(pszEnvironment, szFormatSubSys, bVerWinMajor, bVerWinMinor,
  746. (LPSTR)pszMode,
  747. (LPSTR)((dwWinFlags & WF_PAGING) ? szEnvPaging : gszNull),
  748. (LPSTR)((dwWinFlags & WF_WINNT) ? szSubSysWOW : szSubSysWLO),
  749. bVerEnvMajor, bVerEnvMinor);
  750. }
  751. else
  752. {
  753. wsprintf(pszEnvironment, szFormatDOS, bVerWinMajor, bVerWinMinor,
  754. (LPSTR)pszMode,
  755. (LPSTR)((dwWinFlags & WF_PAGING) ? szEnvPaging : gszNull),
  756. bVerEnvMajor, bVerEnvMinor);
  757. }
  758. }
  759. #endif
  760. }
  761. //
  762. // if caller wants the platform string version...
  763. //
  764. if (NULL != pszPlatform)
  765. {
  766. #ifdef WIN32
  767. {
  768. static TCHAR szFormatPlatform[] = TEXT("%s%u, %u Processor(s)");
  769. static TCHAR szProcessorIntel[] = TEXT("Intel ");
  770. static TCHAR szProcessorMIPS[] = TEXT("MIPS R");
  771. static TCHAR szProcessorAlpha[] = TEXT("DEC Alpha ");
  772. static TCHAR szProcessorDunno[] = TEXT("Dunno zYz");
  773. SYSTEM_INFO sysinfo;
  774. PTSTR pszProcessor;
  775. //
  776. // this is absolutely silly. one would think that the dwOemId member
  777. // would provide something useful like the processor class... but
  778. // no, it doesn't--it is always 0.
  779. //
  780. GetSystemInfo(&sysinfo);
  781. switch (sysinfo.dwProcessorType)
  782. {
  783. case PROCESSOR_INTEL_386:
  784. case PROCESSOR_INTEL_486:
  785. pszProcessor = szProcessorIntel;
  786. break;
  787. case PROCESSOR_MIPS_R4000:
  788. pszProcessor = szProcessorMIPS;
  789. break;
  790. case PROCESSOR_ALPHA_21064:
  791. pszProcessor = szProcessorAlpha;
  792. break;
  793. default:
  794. pszProcessor = szProcessorDunno;
  795. break;
  796. }
  797. //
  798. //
  799. //
  800. wsprintf(pszPlatform, szFormatPlatform, (LPSTR)pszProcessor,
  801. sysinfo.dwProcessorType, sysinfo.dwNumberOfProcessors);
  802. }
  803. #else
  804. {
  805. static TCHAR szPlat286[] = TEXT("80286");
  806. static TCHAR szPlat386[] = TEXT("80386");
  807. static TCHAR szPlat486[] = TEXT("i486");
  808. static TCHAR szPlatR4000[] = TEXT("MIPS R4000, Emulation: ");
  809. static TCHAR szPlatAlpha21064[] = TEXT("Alpha 21064, Emulation: ");
  810. static TCHAR szPlat80x87[] = TEXT(", 80x87");
  811. DWORD dwWinFlags;
  812. dwWinFlags = GetWinFlags();
  813. pszPlatform[0] = '\0';
  814. if (dwWinFlags & (WF_WLO | WF_WINNT))
  815. {
  816. if (dwWinFlags & WF_CPUR4000)
  817. lstrcpy(pszPlatform, szPlatR4000);
  818. else if (dwWinFlags & WF_CPUALPHA21064)
  819. lstrcpy(pszPlatform, szPlatAlpha21064);
  820. }
  821. if (dwWinFlags & WF_CPU286)
  822. lstrcat(pszPlatform, szPlat286);
  823. else if (dwWinFlags & WF_CPU386)
  824. lstrcat(pszPlatform, szPlat386);
  825. else if (dwWinFlags & WF_CPU486)
  826. lstrcat(pszPlatform, szPlat486);
  827. if (dwWinFlags & WF_80x87)
  828. lstrcat(pszPlatform, szPlat80x87);
  829. }
  830. #endif
  831. }
  832. //
  833. // return the result
  834. //
  835. return (lr);
  836. } // AppGetWindowsVersion()
  837. //--------------------------------------------------------------------------;
  838. //
  839. // HFONT AppChooseFont
  840. //
  841. // Description:
  842. // This function is a wrapper for the ChooseFont() common dialog.
  843. // The purpose of this function is to let the user choose a font that
  844. // looks good to them--regardless of how stupid it really looks.
  845. //
  846. // Arguments:
  847. // HWND hwnd: Handle to parent window for chooser dialog.
  848. //
  849. // HFONT hfont: Handle to current font (default for chooser dialog).
  850. //
  851. // PLOGFONT plf: Pointer to optional LOGFONT structure to receive a
  852. // copy of the LOGFONT information for the newly chosen font.
  853. //
  854. // Return (HFONT):
  855. // The return value is the newly chosen font. If no new font was chosen
  856. // then the return value is NULL.
  857. //
  858. // History:
  859. // 2/ 7/93
  860. //
  861. //--------------------------------------------------------------------------;
  862. HFONT FNGLOBAL AppChooseFont
  863. (
  864. HWND hwnd,
  865. HFONT hfont,
  866. PLOGFONT plf
  867. )
  868. {
  869. LOGFONT lf;
  870. CHOOSEFONT cf;
  871. BOOL f;
  872. HFONT hfontNew;
  873. //
  874. // get the font info for the current font...
  875. //
  876. GetObject(hfont, sizeof(LOGFONT), (LPVOID)&lf);
  877. //
  878. // fill in the choosefont structure
  879. //
  880. cf.lStructSize = sizeof(CHOOSEFONT);
  881. cf.hwndOwner = hwnd;
  882. cf.hDC = NULL;
  883. cf.Flags = CF_SCREENFONTS | CF_INITTOLOGFONTSTRUCT;
  884. cf.lCustData = 0;
  885. cf.lpfnHook = NULL;
  886. cf.hInstance = NULL;
  887. cf.nFontType = SCREEN_FONTTYPE;
  888. cf.lpLogFont = (LPLOGFONT)&lf;
  889. //
  890. // splash a dialog into the user's face..
  891. //
  892. hfontNew = NULL;
  893. f = ChooseFont(&cf);
  894. if (f)
  895. {
  896. //
  897. // create the new font..
  898. //
  899. hfontNew = CreateFontIndirect(&lf);
  900. if (NULL == hfontNew)
  901. return (NULL);
  902. //
  903. // copy the logfont structure if caller wants it
  904. //
  905. if (NULL != plf)
  906. *plf = lf;
  907. }
  908. //
  909. // return the new font (if one was chosen)
  910. //
  911. return (hfontNew);
  912. } // AppChooseFont()
  913. //==========================================================================;
  914. //
  915. // Misc rarely used application dialogs and stuff...
  916. //
  917. //
  918. //==========================================================================;
  919. //--------------------------------------------------------------------------;
  920. //
  921. // BOOL AboutDlgProc
  922. //
  923. // Description:
  924. // This dialog procedure is used for the ubiquitous about box.
  925. //
  926. // Arguments:
  927. // HWND hwnd: Handle to window.
  928. //
  929. // UINT uMsg: Message being sent to the window.
  930. //
  931. // WPARAM wParam: Specific argument to message.
  932. //
  933. // LPARAM lParam: Specific argument to message.
  934. //
  935. // Return (BOOL):
  936. // The return value is specific to the message that was received. For
  937. // the most part, it is FALSE if this dialog procedure does not handle
  938. // a message.
  939. //
  940. // History:
  941. // 1/ 2/93
  942. //
  943. //--------------------------------------------------------------------------;
  944. BOOL FNEXPORT AboutDlgProc
  945. (
  946. HWND hwnd,
  947. UINT uMsg,
  948. WPARAM wParam,
  949. LPARAM lParam
  950. )
  951. {
  952. HWND hwndT;
  953. PTSTR pach;
  954. UINT u;
  955. switch (uMsg)
  956. {
  957. case WM_INITDIALOG:
  958. //
  959. // display some OS version information
  960. //
  961. //
  962. pach = (PTSTR)LocalAlloc(LPTR, APP_MAX_STRING_RC_BYTES);
  963. if (NULL == pach)
  964. return (TRUE);
  965. AppGetWindowsVersion(pach, NULL);
  966. hwndT = GetDlgItem(hwnd, IDD_ABOUT_VERSION_OS);
  967. SetWindowText(hwndT, pach);
  968. AppGetWindowsVersion(NULL, pach);
  969. hwndT = GetDlgItem(hwnd, IDD_ABOUT_VERSION_PLATFORM);
  970. SetWindowText(hwndT, pach);
  971. wsprintf(pach, "MMREG.H V%u.%.02u",
  972. (_INC_MMREG / 100), (_INC_MMREG % 100));
  973. hwndT = GetDlgItem(hwnd, IDD_ABOUT_VERSION_MMSYSTEM);
  974. SetWindowText(hwndT, pach);
  975. LocalFree((HLOCAL)pach);
  976. //
  977. // return nonzero to set the input focus to the control
  978. // identified by the (hwndFocus = (HWND)wParam) argument.
  979. // a zero return tells the dialog manager that this function
  980. // has set the focus using SetFocus.
  981. //
  982. return (TRUE);
  983. case WM_COMMAND:
  984. u = GET_WM_COMMAND_ID(wParam, lParam);
  985. if ((IDOK == u) || (IDCANCEL == u))
  986. {
  987. EndDialog(hwnd, (IDOK == u));
  988. }
  989. break;
  990. }
  991. return (FALSE);
  992. } // AboutDlgProc()
  993. //==========================================================================;
  994. //
  995. // Initialization and exit code...
  996. //
  997. //
  998. //==========================================================================;
  999. TCHAR gszKeyWindow[] = TEXT("Window");
  1000. TCHAR gszKeyFont[] = TEXT("Font");
  1001. //--------------------------------------------------------------------------;
  1002. //
  1003. // BOOL MMCapsChooseFont
  1004. //
  1005. // Description:
  1006. // This function lets the user choose a new font for the script window.
  1007. // After a new font is chosen, the font structure is stored to the
  1008. // .ini file so it can be restored on the next run of this application.
  1009. //
  1010. // Arguments:
  1011. // HWND hwnd: Handle to main window.
  1012. //
  1013. // Return (BOOL):
  1014. // The return value is TRUE if a new font was chosen. It is FALSE if
  1015. // the user canceled the operation.
  1016. //
  1017. // History:
  1018. // 2/ 7/93
  1019. //
  1020. //--------------------------------------------------------------------------;
  1021. BOOL FNGLOBAL MMCapsChooseFont
  1022. (
  1023. HWND hwnd
  1024. )
  1025. {
  1026. LOGFONT lf;
  1027. HWND hlb;
  1028. HFONT hfont;
  1029. HFONT hfontNew;
  1030. hlb = GetDlgItem(hwnd, IDD_APP_LIST_DEVICES);
  1031. //
  1032. // get the current font and pass it to the choose font dialog
  1033. //
  1034. hfont = GetWindowFont(gptlbDrivers->hlb);
  1035. hfontNew = AppChooseFont(hwnd, hfont, &lf);
  1036. if (NULL == hfontNew)
  1037. return (FALSE);
  1038. //
  1039. // select the new font into the script window and delete the old one
  1040. //
  1041. TlbSetFont(gptlbDrivers, hfontNew, TRUE);
  1042. DeleteFont(hfont);
  1043. //
  1044. // save the complete description of the chosen font so there can be
  1045. // no strangness in the font mapping next run. this is overkill, but
  1046. // it works...
  1047. //
  1048. AppProfileWriteBytes(gszKeyFont, (LPBYTE)&lf, sizeof(lf));
  1049. return (TRUE);
  1050. } // MMCapsChooseFont()
  1051. //--------------------------------------------------------------------------;
  1052. //
  1053. // BOOL MMCapsSettingsRestore
  1054. //
  1055. // Description:
  1056. // This function restores state information for the application. This
  1057. // function is called just after the main window is created (it has
  1058. // not been ShowWindow()'d). This function will generate the call
  1059. // to ShowWindow before returning.
  1060. //
  1061. // Arguments:
  1062. // HWND hwnd: Handle to main window that has just been created but
  1063. // not shown.
  1064. //
  1065. // int nCmdShow: The state that the application window should show as.
  1066. //
  1067. // Return (BOOL):
  1068. // The return value is always TRUE.
  1069. //
  1070. // History:
  1071. // 05/11/93
  1072. //
  1073. //--------------------------------------------------------------------------;
  1074. BOOL FNLOCAL MMCapsSettingsRestore
  1075. (
  1076. HWND hwnd,
  1077. int nCmdShow
  1078. )
  1079. {
  1080. WINDOWPLACEMENT wp;
  1081. PRECT prc;
  1082. HFONT hfont;
  1083. LOGFONT lf;
  1084. RECT rc;
  1085. POINT pt;
  1086. int n;
  1087. BOOL f;
  1088. //
  1089. // restore the user's preferred font.
  1090. //
  1091. hfont = NULL;
  1092. f = AppProfileReadBytes(gszKeyFont, (LPBYTE)&lf, sizeof(lf));
  1093. if (f)
  1094. {
  1095. hfont = CreateFontIndirect(&lf);
  1096. }
  1097. if (NULL == hfont)
  1098. {
  1099. hfont = GetStockFont(ANSI_VAR_FONT);
  1100. }
  1101. TlbSetFont(gptlbDrivers, hfont, TRUE);
  1102. //
  1103. // grab the stored window position and size from the .ini file...
  1104. // there must be four arguments stored or the entry is considered
  1105. // invalid.
  1106. //
  1107. prc = &wp.rcNormalPosition;
  1108. f = AppProfileReadBytes(gszKeyWindow, (LPBYTE)prc, sizeof(*prc));
  1109. if (f)
  1110. {
  1111. //
  1112. // to make sure the user can always get at the window, check to
  1113. // see if the midpoint of the caption is visible--if it is not,
  1114. // then default to the default position used when creating the
  1115. // window.
  1116. //
  1117. n = (prc->right - prc->left) / 2;
  1118. pt.x = (n + prc->left);
  1119. n = GetSystemMetrics(SM_CYCAPTION) / 2 + GetSystemMetrics(SM_CXFRAME);
  1120. pt.y = (n + prc->top);
  1121. GetWindowRect(GetDesktopWindow(), &rc);
  1122. if (PtInRect(&rc, pt))
  1123. {
  1124. //
  1125. // fill out the window placement structure--default the
  1126. // maximized and minimized states to default placement by
  1127. // getting its current placement.
  1128. //
  1129. wp.length = sizeof(wp);
  1130. GetWindowPlacement(hwnd, &wp);
  1131. wp.flags = 0;
  1132. wp.showCmd = nCmdShow;
  1133. SetWindowPlacement(hwnd, &wp);
  1134. return (TRUE);
  1135. }
  1136. }
  1137. //
  1138. // show defaulted and succeed
  1139. //
  1140. ShowWindow(hwnd, nCmdShow);
  1141. return (TRUE);
  1142. } // MMCapsSettingsRestore()
  1143. //--------------------------------------------------------------------------;
  1144. //
  1145. // BOOL MMCapsSettingsSave
  1146. //
  1147. // Description:
  1148. // This function saves the current state information for the application.
  1149. // It is called just before the main window is closed (destroyed); or
  1150. // as Windows is exiting (query end session).
  1151. //
  1152. // Note that this function should not destroy any resources--it can
  1153. // be called at any time to save a snapshot of the application state.
  1154. //
  1155. // Arguments:
  1156. // HWND hwnd: Handle to main window that will be destroyed shortly.
  1157. //
  1158. // Return (BOOL):
  1159. // The return value is always TRUE.
  1160. //
  1161. // History:
  1162. // 05/11/93
  1163. //
  1164. //--------------------------------------------------------------------------;
  1165. BOOL FNLOCAL MMCapsSettingsSave
  1166. (
  1167. HWND hwnd
  1168. )
  1169. {
  1170. WINDOWPLACEMENT wp;
  1171. PRECT prc;
  1172. BOOL f;
  1173. //
  1174. // save the current window placement--only store the size and location
  1175. // of the restored window. maximized and minimized states should
  1176. // remain defaulted on the next invocation of this application.
  1177. //
  1178. wp.length = sizeof(wp);
  1179. f = GetWindowPlacement(hwnd, &wp);
  1180. if (f)
  1181. {
  1182. prc = &wp.rcNormalPosition;
  1183. DPF(0, "WindowPlacement: show=%d, minX=%d, minY=%d, maxX=%d, maxY=%d",
  1184. wp.showCmd, wp.ptMinPosition.x, wp.ptMinPosition.y,
  1185. wp.ptMaxPosition.x, wp.ptMaxPosition.y);
  1186. DPF(0, " normX=%d, normY=%d, normW=%d, normH=%d",
  1187. prc->left, prc->top, prc->right, prc->bottom);
  1188. //
  1189. // save the _bounding rectangle_ of the restored window state...
  1190. //
  1191. AppProfileWriteBytes(gszKeyWindow, (LPBYTE)prc, sizeof(*prc));
  1192. }
  1193. //
  1194. // succeed
  1195. //
  1196. return (TRUE);
  1197. } // MMCapsSettingsSave()
  1198. //==========================================================================;
  1199. //
  1200. //
  1201. //
  1202. //
  1203. //==========================================================================;
  1204. //--------------------------------------------------------------------------;
  1205. //
  1206. // BOOL MMCapsDlgProc
  1207. //
  1208. // Description:
  1209. // This dialog procedure is used to display driver capabilities.
  1210. //
  1211. // Arguments:
  1212. // HWND hwnd: Handle to window.
  1213. //
  1214. // UINT uMsg: Message being sent to the window.
  1215. //
  1216. // WPARAM wParam: Specific argument to message.
  1217. //
  1218. // LPARAM lParam: Specific argument to message.
  1219. //
  1220. // Return (BOOL):
  1221. // The return value is specific to the message that was received. For
  1222. // the most part, it is FALSE if this dialog procedure does not handle
  1223. // a message.
  1224. //
  1225. // History:
  1226. // 1/ 2/93
  1227. //
  1228. //--------------------------------------------------------------------------;
  1229. BOOL FNEXPORT MMCapsDlgProc
  1230. (
  1231. HWND hwnd,
  1232. UINT uMsg,
  1233. WPARAM wParam,
  1234. LPARAM lParam
  1235. )
  1236. {
  1237. HWND hedit;
  1238. UINT u;
  1239. switch (uMsg)
  1240. {
  1241. case WM_INITDIALOG:
  1242. hedit = GetDlgItem(hwnd, IDD_DEVCAPS_EDIT_DETAILS);
  1243. SetWindowFont(hedit, GetStockFont(ANSI_FIXED_FONT), FALSE);
  1244. //
  1245. //
  1246. //
  1247. switch (guDriverType)
  1248. {
  1249. case MMCAPS_DRIVERTYPE_LOWLEVEL:
  1250. MMCapsDetailLowLevel(hedit, lParam);
  1251. break;
  1252. #if 0
  1253. case MMCAPS_DRIVERTYPE_MCI:
  1254. MMCapsDetailMCI(hedit, lParam);
  1255. break;
  1256. case MMCAPS_DRIVERTYPE_ACM:
  1257. MMCapsDetailACM(hedit, lParam);
  1258. break;
  1259. case MMCAPS_DRIVERTYPE_VIDEO:
  1260. MMCapsDetailVideo(hedit, lParam);
  1261. break;
  1262. #endif
  1263. }
  1264. //
  1265. // return nonzero to set the input focus to the control
  1266. // identified by the (hwndFocus = (HWND)wParam) argument.
  1267. // a zero return tells the dialog manager that this function
  1268. // has set the focus using SetFocus.
  1269. //
  1270. return (TRUE);
  1271. case WM_COMMAND:
  1272. u = GET_WM_COMMAND_ID(wParam, lParam);
  1273. if ((IDOK == u) || (IDCANCEL == u))
  1274. {
  1275. EndDialog(hwnd, (IDOK == u));
  1276. }
  1277. break;
  1278. }
  1279. return (FALSE);
  1280. } // MMCapsDlgProc()
  1281. //==========================================================================;
  1282. //
  1283. //
  1284. //
  1285. //
  1286. //==========================================================================;
  1287. //--------------------------------------------------------------------------;
  1288. //
  1289. // BOOL MMCapsRefreshDriverList
  1290. //
  1291. // Description:
  1292. //
  1293. //
  1294. // Arguments:
  1295. // HWND hwnd: Handle of main window.
  1296. //
  1297. // Return (BOOL):
  1298. //
  1299. // History:
  1300. // 05/16/93
  1301. //
  1302. //--------------------------------------------------------------------------;
  1303. BOOL FNLOCAL MMCapsRefreshDriverList
  1304. (
  1305. PZYZTABBEDLISTBOX ptlb
  1306. )
  1307. {
  1308. static UINT uIdPrev = (UINT)-1;
  1309. BOOL fComplete;
  1310. //
  1311. //
  1312. //
  1313. SetWindowRedraw(ptlb->hlb, FALSE);
  1314. ListBox_ResetContent(ptlb->hlb);
  1315. //
  1316. // only force complete update if the driver type is different from
  1317. // previous...
  1318. //
  1319. fComplete = (guDriverType != uIdPrev);
  1320. uIdPrev = guDriverType;
  1321. //
  1322. //
  1323. //
  1324. switch (guDriverType)
  1325. {
  1326. case MMCAPS_DRIVERTYPE_LOWLEVEL:
  1327. MMCapsEnumerateLowLevel(ptlb, fComplete);
  1328. break;
  1329. #if 0
  1330. case MMCAPS_DRIVERTYPE_MCI:
  1331. MMCapsEnumerateMCI(ptlb, fComplete);
  1332. break;
  1333. case MMCAPS_DRIVERTYPE_ACM:
  1334. MMCapsEnumerateACM(ptlb, fComplete);
  1335. break;
  1336. case MMCAPS_DRIVERTYPE_VIDEO:
  1337. MMCapsEnumerateVideo(ptlb, fComplete);
  1338. break;
  1339. case MMCAPS_DRIVERTYPE_DRIVERS:
  1340. MMCapsEnumerateDrivers(ptlb, fComplete);
  1341. break;
  1342. #endif
  1343. }
  1344. //
  1345. //
  1346. //
  1347. SetWindowRedraw(ptlb->hlb, TRUE);
  1348. return (TRUE);
  1349. } // MMCapsRefreshDriverList()
  1350. //==========================================================================;
  1351. //
  1352. // Main application window handling code...
  1353. //
  1354. //
  1355. //==========================================================================;
  1356. //--------------------------------------------------------------------------;
  1357. //
  1358. // LRESULT AppCreate
  1359. //
  1360. // Description:
  1361. // This function is called to handle the WM_CREATE message for the
  1362. // application's window. The application should finish the creation
  1363. // of the window (create controls, allocate resources, etc). The
  1364. // window has not been displayed (CreateWindow[Ex] has not returned).
  1365. //
  1366. // Arguments:
  1367. // HWND hwnd: Handle to the window that is in the process of being
  1368. // created.
  1369. //
  1370. // LPCREATESTRUCT pcs: Pointer to a CREATESTRUCT that contains info
  1371. // about the window being created.
  1372. //
  1373. // Return (LRESULT):
  1374. // The return value should be nonzero if the application wishes to
  1375. // let the window finish being created. A return of zero tells
  1376. // CreateWindow[Ex] to fail the creation of the window.
  1377. //
  1378. // History:
  1379. // 11/ 8/92
  1380. //
  1381. //--------------------------------------------------------------------------;
  1382. LRESULT FNGLOBAL AppCreate
  1383. (
  1384. HWND hwnd,
  1385. LPCREATESTRUCT pcs
  1386. )
  1387. {
  1388. DPF(0, "AppCreate(hwnd=%Xh, cs.x=%d, cs.y=%d, cs.cx=%d, cs.cy=%d)",
  1389. hwnd, pcs->x, pcs->y, pcs->cx, pcs->cy);
  1390. //
  1391. // create the driver selection listbox
  1392. //
  1393. gptlbDrivers = TlbCreate(hwnd, IDD_APP_LIST_DEVICES, NULL);
  1394. if (NULL == gptlbDrivers)
  1395. return (0L);
  1396. //
  1397. //
  1398. //
  1399. MMCapsRefreshDriverList(gptlbDrivers);
  1400. //
  1401. // we want the focus to default to the device listbox window
  1402. //
  1403. SetFocus(gptlbDrivers->hlb);
  1404. //
  1405. // return nonzero to succeed the creation of the window
  1406. //
  1407. return (1L);
  1408. } // AppCreate()
  1409. //--------------------------------------------------------------------------;
  1410. //
  1411. // LRESULT AppQueryEndSession
  1412. //
  1413. // Description:
  1414. // This function handles the WM_QUERYENDSESSION. This message is sent
  1415. // by USER when ExitWindows has been called to end the Windows session.
  1416. // This function can stop Windows from exiting if it is not convenient
  1417. // for Windows to end.
  1418. //
  1419. // Giving the user the option to save modified data before continueing
  1420. // with the shutdown of Windows is a good idea.
  1421. //
  1422. // Telling Windows to continue with the exit procedure does not
  1423. // necessarily mean Windows will exit. All applications are queried
  1424. // for shutdown approval. When the actual decision is made on whether
  1425. // Windows will exit, WM_ENDSESSION will be sent with the result.
  1426. //
  1427. // Arguments:
  1428. // HWND hwnd: Handle to window that received the message.
  1429. //
  1430. // Return (LRESULT):
  1431. // Returns zero to STOP Windows from exiting. Returns non-zero to
  1432. // allows windows to shut down.
  1433. //
  1434. // History:
  1435. // 2/ 9/93
  1436. //
  1437. //--------------------------------------------------------------------------;
  1438. LRESULT FNGLOBAL AppQueryEndSession
  1439. (
  1440. HWND hwnd
  1441. )
  1442. {
  1443. DPF(0, "AppQueryEndSession(hwnd=%Xh)", hwnd);
  1444. //
  1445. // tell Windows to proceed with the shutdown process!
  1446. //
  1447. return (1L);
  1448. } // AppQueryEndSession()
  1449. //--------------------------------------------------------------------------;
  1450. //
  1451. // LRESULT AppEndSession
  1452. //
  1453. // Description:
  1454. // This function is called to handle the WM_ENDSESSION message. This
  1455. // message is generated after the application answers the
  1456. // WM_QUERYENDSESSION message. The purpose of the WM_ENDSESSION
  1457. // message is to tell the application if Windows will be exiting
  1458. // (TRUE == fEndSession) or the end session was canceled by an
  1459. // application (FALSE == fEndSession).
  1460. //
  1461. // Arguments:
  1462. // HWND hwnd: Handle to window that received the message.
  1463. //
  1464. // BOOL fEndSession: TRUE if Windows is exiting. FALSE if the end
  1465. // session was canceled.
  1466. //
  1467. // Return (LRESULT):
  1468. // Returns zero if the message is processed. Note that an application
  1469. // cannot halt the termination of Windows from this message--the
  1470. // WM_QUERYENDSESSION is the only message that allows that behaviour.
  1471. // If fEndSession is TRUE, Windows *WILL* exit--whether you like it
  1472. // or not.
  1473. //
  1474. // History:
  1475. // 2/ 9/93
  1476. //
  1477. //--------------------------------------------------------------------------;
  1478. LRESULT FNGLOBAL AppEndSession
  1479. (
  1480. HWND hwnd,
  1481. BOOL fEndSession
  1482. )
  1483. {
  1484. DPF(0, "AppEndSession(hwnd=%Xh, fEndSession=%d)", hwnd, fEndSession);
  1485. //
  1486. // we processed the message, return zero..
  1487. //
  1488. return (0L);
  1489. } // AppEndSession()
  1490. //--------------------------------------------------------------------------;
  1491. //
  1492. // LRESULT AppClose
  1493. //
  1494. // Description:
  1495. // This function handles the WM_CLOSE message for the application.
  1496. // If the application should close, DestroyWindow() must be called
  1497. // by this function. Otherwise the application will not close.
  1498. //
  1499. // Arguments:
  1500. // HWND hwnd: Handle to window that generated the WM_CLOSE message.
  1501. //
  1502. // Return (LRESULT):
  1503. // There return value is zero. The DestroyWindow function will have
  1504. // been called if the application should actually close.
  1505. //
  1506. // History:
  1507. // 2/ 6/93
  1508. //
  1509. //--------------------------------------------------------------------------;
  1510. LRESULT FNGLOBAL AppClose
  1511. (
  1512. HWND hwnd
  1513. )
  1514. {
  1515. HWND hlb;
  1516. HFONT hfont;
  1517. DPF(0, "AppClose(hwnd=%Xh)", hwnd);
  1518. //
  1519. // save any settings that should be saved on app termination...
  1520. //
  1521. MMCapsSettingsSave(hwnd);
  1522. //
  1523. // if the Shift key is held down during the close message, then just
  1524. // save the current state but don't destroy the window... this is
  1525. // useful if the user does not want to exit the app and rerun it
  1526. // to make sure the state is saved--just before the user does something
  1527. // that may crash Windows or something..
  1528. //
  1529. if (GetKeyState(VK_SHIFT) < 0)
  1530. {
  1531. return (0L);
  1532. }
  1533. //
  1534. // destroy the font we are using... before deleting the font, select
  1535. // the system font back into the script window so the font won't
  1536. // be 'in use' anymore.
  1537. //
  1538. hlb = GetDlgItem(hwnd, IDD_APP_LIST_DEVICES);
  1539. hfont = GetWindowFont(hlb);
  1540. SetWindowFont(hlb, NULL, FALSE);
  1541. DeleteFont(hfont);
  1542. //
  1543. // make the window close and terminate the application
  1544. //
  1545. DestroyWindow(hwnd);
  1546. return (0L);
  1547. } // AppClose()
  1548. //--------------------------------------------------------------------------;
  1549. //
  1550. // LRESULT AppInitMenuPopup
  1551. //
  1552. // Description:
  1553. // This function handles the WM_INITMENUPOPUP message. This message
  1554. // is sent to the window owning the menu that is going to become
  1555. // active. This gives an application the ability to modify the menu
  1556. // before it is displayed (disable/add items, etc).
  1557. //
  1558. // Arguments:
  1559. // HWND hwnd: Handle to window that generated the WM_INITMENUPOPUP
  1560. // message.
  1561. //
  1562. // HMENU hmenu: Handle to the menu that is to become active.
  1563. //
  1564. // int nItem: Specifies the zero-based relative position of the menu
  1565. // item that invoked the popup menu.
  1566. //
  1567. // BOOL fSysMenu: Specifies whether the popup menu is a System menu
  1568. // (TRUE) or it is not a System menu (FALSE).
  1569. //
  1570. // Return (LRESULT):
  1571. // Returns zero if the message is processed.
  1572. //
  1573. // History:
  1574. // 1/ 2/93
  1575. //
  1576. //--------------------------------------------------------------------------;
  1577. LRESULT FNLOCAL AppInitMenuPopup
  1578. (
  1579. HWND hwnd,
  1580. HMENU hmenu,
  1581. int nItem,
  1582. BOOL fSysMenu
  1583. )
  1584. {
  1585. UINT u;
  1586. DPF(0, "AppInitMenuPopup(hwnd=%Xh, hmenu=%Xh, nItem=%d, fSysMenu=%d)",
  1587. hwnd, hmenu, nItem, fSysMenu);
  1588. //
  1589. // if the system menu is what got hit, succeed immediately... this
  1590. // application has no stuff in the system menu.
  1591. //
  1592. if (fSysMenu)
  1593. return (0L);
  1594. //
  1595. // initialize the menu that is being 'popped up'
  1596. //
  1597. switch (nItem)
  1598. {
  1599. case APP_MENU_ITEM_FILE:
  1600. break;
  1601. case APP_MENU_ITEM_DRIVERS:
  1602. for (u = IDM_DRIVERS_LOWLEVEL; u <= IDM_DRIVERS_DRIVERS; u++)
  1603. {
  1604. UINT uCheck;
  1605. uCheck = (u == guDriverType) ? MF_CHECKED : MF_UNCHECKED;
  1606. CheckMenuItem(hmenu, u, uCheck);
  1607. }
  1608. break;
  1609. }
  1610. //
  1611. // we processed the message--return 0...
  1612. //
  1613. return (0L);
  1614. } // AppInitMenuPopup()
  1615. //--------------------------------------------------------------------------;
  1616. //
  1617. // LRESULT AppCommand
  1618. //
  1619. // Description:
  1620. // This function handles the WM_COMMAND message.
  1621. //
  1622. // Arguments:
  1623. // HWND hwnd: Handle to window receiving the WM_COMMAND message.
  1624. //
  1625. // int nId: Control or menu item identifier.
  1626. //
  1627. // HWND hwndCtl: Handle of control if the message is from a control.
  1628. // This argument is NULL if the message was not generated by a control.
  1629. //
  1630. // UINT uCode: Notification code. This argument is 1 if the message
  1631. // was generated by an accelerator. If the message is from a menu,
  1632. // this argument is 0.
  1633. //
  1634. // Return (LRESULT):
  1635. // Returns zero if the message is processed.
  1636. //
  1637. // History:
  1638. // 11/ 8/92
  1639. //
  1640. //--------------------------------------------------------------------------;
  1641. LRESULT FNLOCAL AppCommand
  1642. (
  1643. HWND hwnd,
  1644. int nId,
  1645. HWND hwndCtl,
  1646. UINT uCode
  1647. )
  1648. {
  1649. int n;
  1650. LRESULT lr;
  1651. switch (nId)
  1652. {
  1653. case IDM_FILE_FONT:
  1654. MMCapsChooseFont(hwnd);
  1655. break;
  1656. case IDM_FILE_ABOUT:
  1657. AppDialogBox(hwnd, DLG_ABOUT, (DLGPROC)AboutDlgProc, 0L);
  1658. break;
  1659. case IDM_FILE_EXIT:
  1660. FORWARD_WM_CLOSE(hwnd, SendMessage);
  1661. break;
  1662. case IDM_DRIVERS_LOWLEVEL:
  1663. case IDM_DRIVERS_MCI:
  1664. case IDM_DRIVERS_ACM:
  1665. case IDM_DRIVERS_VIDEO:
  1666. case IDM_DRIVERS_DRIVERS:
  1667. if ((UINT)nId == guDriverType)
  1668. break;
  1669. guDriverType = (UINT)nId;
  1670. // -- fall through -- //
  1671. case IDM_UPDATE:
  1672. MMCapsRefreshDriverList(gptlbDrivers);
  1673. break;
  1674. case IDD_APP_LIST_DEVICES:
  1675. switch (uCode)
  1676. {
  1677. case LBN_SELCHANGE:
  1678. break;
  1679. case LBN_DBLCLK:
  1680. n = ListBox_GetCurSel(hwndCtl);
  1681. lr = ListBox_GetItemData(hwndCtl, n);
  1682. AppDialogBox(hwnd, DLG_DEVCAPS, (DLGPROC)MMCapsDlgProc, lr);
  1683. break;
  1684. }
  1685. break;
  1686. }
  1687. return (0L);
  1688. } // AppCommand()
  1689. //--------------------------------------------------------------------------;
  1690. //
  1691. // LRESULT AppSize
  1692. //
  1693. // Description:
  1694. // This function handles the WM_SIZE message for the application's
  1695. // window. This message is sent to the application window after the
  1696. // size has changed (but before it is painted).
  1697. //
  1698. // Arguments:
  1699. // HWND hwnd: Handle to window that generated the WM_SIZE message.
  1700. //
  1701. // UINT fuSizeType: Specifies the type of resizing requested. This
  1702. // argument is one of the following: SIZE_MAXIMIZED, SIZE_MINIMIZED,
  1703. // SIZE_RESTORED, SIZE_MAXHIDE, or SIZE_MAXSHOW.
  1704. //
  1705. // int nWidth: Width of the new client area for the window.
  1706. //
  1707. // int nHeight: Height of the new client area for the window.
  1708. //
  1709. // Return (LRESULT):
  1710. // Returns zero if the application processes the message.
  1711. //
  1712. // History:
  1713. // 2/ 5/93
  1714. //
  1715. //--------------------------------------------------------------------------;
  1716. LRESULT FNLOCAL AppSize
  1717. (
  1718. HWND hwnd,
  1719. UINT fuSizeType,
  1720. int nWidth,
  1721. int nHeight
  1722. )
  1723. {
  1724. RECT rc;
  1725. DPF(0, "AppSize(hwnd=%Xh, fuSizeType=%u, nWidth=%d, nHeight=%d)",
  1726. hwnd, fuSizeType, nWidth, nHeight);
  1727. //
  1728. // unless this application is the one being resized then don't waste
  1729. // time computing stuff that doesn't matter. this applies to being
  1730. // minimized also because this application does not have a custom
  1731. // minimized state.
  1732. //
  1733. if ((SIZE_RESTORED != fuSizeType) && (SIZE_MAXIMIZED != fuSizeType))
  1734. return (0L);
  1735. //
  1736. // size the devices listbox to be the total size of the client area--
  1737. // inflate the rect by one so borders are not visible. note that
  1738. // we need to leave room at the top for the title text which is one
  1739. // line of text in height...
  1740. //
  1741. GetClientRect(hwnd, &rc);
  1742. InflateRect(&rc, 1, 1);
  1743. TlbMove(gptlbDrivers, &rc, FALSE);
  1744. //
  1745. // we processed the message..
  1746. //
  1747. return (0L);
  1748. } // AppSize()
  1749. //--------------------------------------------------------------------------;
  1750. //
  1751. // LRESULT AppPaint
  1752. //
  1753. // Description:
  1754. //
  1755. //
  1756. // Arguments:
  1757. // HWND hwnd:
  1758. //
  1759. // Return (LRESULT):
  1760. //
  1761. // History:
  1762. // 05/11/93
  1763. //
  1764. //--------------------------------------------------------------------------;
  1765. LRESULT FNLOCAL AppPaint
  1766. (
  1767. HWND hwnd
  1768. )
  1769. {
  1770. PAINTSTRUCT ps;
  1771. //
  1772. //
  1773. //
  1774. BeginPaint(hwnd, &ps);
  1775. TlbPaint(gptlbDrivers, hwnd, ps.hdc);
  1776. EndPaint(hwnd, &ps);
  1777. //
  1778. // we processed the message
  1779. //
  1780. return (0L);
  1781. } // AppPaint()
  1782. //--------------------------------------------------------------------------;
  1783. //
  1784. // LRESULT AppWndProc
  1785. //
  1786. // Description:
  1787. // This is the main application window procedure.
  1788. //
  1789. // Arguments:
  1790. // HWND hwnd: Handle to window.
  1791. //
  1792. // UINT uMsg: Message being sent to the window.
  1793. //
  1794. // WPARAM wParam: Specific argument to message.
  1795. //
  1796. // LPARAM lParam: Specific argument to message.
  1797. //
  1798. // Return (LRESULT):
  1799. // The return value depends on the message that is being processed.
  1800. //
  1801. // History:
  1802. // 11/ 8/92
  1803. //
  1804. //--------------------------------------------------------------------------;
  1805. LRESULT FNEXPORT AppWndProc
  1806. (
  1807. HWND hwnd,
  1808. UINT uMsg,
  1809. WPARAM wParam,
  1810. LPARAM lParam
  1811. )
  1812. {
  1813. static UINT umsgWinmmDeviceChange = 0;
  1814. LRESULT lr;
  1815. if (0 == umsgWinmmDeviceChange) {
  1816. umsgWinmmDeviceChange = RegisterWindowMessage(TEXT("winmm_devicechange"));
  1817. }
  1818. if ((uMsg == umsgWinmmDeviceChange) && gptlbDrivers) MMCapsRefreshDriverList(gptlbDrivers);
  1819. switch (uMsg)
  1820. {
  1821. case WM_CREATE:
  1822. lr = HANDLE_WM_CREATE(hwnd, wParam, lParam, AppCreate);
  1823. return (lr);
  1824. case WM_INITMENUPOPUP:
  1825. HANDLE_WM_INITMENUPOPUP(hwnd, wParam, lParam, AppInitMenuPopup);
  1826. return (0L);
  1827. case WM_COMMAND:
  1828. lr = HANDLE_WM_COMMAND(hwnd, wParam, lParam, AppCommand);
  1829. return (lr);
  1830. case WM_SIZE:
  1831. //
  1832. // handle what we want for sizing, and then always call the
  1833. // default handler...
  1834. //
  1835. HANDLE_WM_SIZE(hwnd, wParam, lParam, AppSize);
  1836. break;
  1837. case WM_PAINT:
  1838. HANDLE_WM_PAINT(hwnd, wParam, lParam, AppPaint);
  1839. break;
  1840. case WM_QUERYENDSESSION:
  1841. lr = HANDLE_WM_QUERYENDSESSION(hwnd, wParam, lParam, AppQueryEndSession);
  1842. return (lr);
  1843. case WM_ENDSESSION:
  1844. HANDLE_WM_ENDSESSION(hwnd, wParam, lParam, AppEndSession);
  1845. return (0L);
  1846. case WM_CLOSE:
  1847. HANDLE_WM_CLOSE(hwnd, wParam, lParam, AppClose);
  1848. return (0L);
  1849. case WM_DESTROY:
  1850. PostQuitMessage(0);
  1851. return (0L);
  1852. }
  1853. return (DefWindowProc(hwnd, uMsg, wParam, lParam));
  1854. } // AppWndProc()
  1855. //==========================================================================;
  1856. //
  1857. //
  1858. //
  1859. //
  1860. //==========================================================================;
  1861. //--------------------------------------------------------------------------;
  1862. //
  1863. // BOOL AppInit
  1864. //
  1865. // Description:
  1866. // This function is called to initialize a new instance of the
  1867. // application. We want to parse our command line, create our window,
  1868. // allocate resources, etc.
  1869. //
  1870. // The arguments passed to this function are exactly the same as
  1871. // those passed to WinMain.
  1872. //
  1873. // Arguments:
  1874. // HINSTANCE hinst: Identifies the current instance of the
  1875. // application.
  1876. //
  1877. // HINSTANCE hinstPrev: Identifies the previous instance of the
  1878. // application (NULL if first instance). For Win 32, this argument
  1879. // is _always_ NULL.
  1880. //
  1881. // LPTSTR pszCmdLine: Points to null-terminated unparsed command line.
  1882. // If the application is compiled for Unicode, then this argument is
  1883. // ignored.
  1884. //
  1885. // int nCmdShow: How the main window for the application is to be
  1886. // shown by default.
  1887. //
  1888. // Return (HWND):
  1889. // Returns the newly created handle to the applications main window.
  1890. // This handle is NULL if something went wrong and tells the application
  1891. // to exit immediately.
  1892. //
  1893. // History:
  1894. // 11/ 8/92
  1895. //
  1896. //--------------------------------------------------------------------------;
  1897. HWND FNGLOBAL AppInit
  1898. (
  1899. HINSTANCE hinst,
  1900. HINSTANCE hinstPrev,
  1901. LPTSTR pszCmdLine,
  1902. int nCmdShow
  1903. )
  1904. {
  1905. LRESULT FNEXPORT AppWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  1906. HWND hwnd;
  1907. WNDCLASS wc;
  1908. DPF(0, "AppInit(hinst=%Xh, hinstPrev=%Xh, pszCmdLine='%s', nCmdShow=%d)",
  1909. hinst, hinstPrev, pszCmdLine, nCmdShow);
  1910. LoadString(hinst, IDS_APP_NAME, gszAppName, SIZEOF(gszAppName));
  1911. //
  1912. // determine whether a new window class needs to be registered for
  1913. // this application. for Win 16, this only needs to be done for the
  1914. // first instance of the application created. for Win 32, this must
  1915. // be done for EVERY instance of the application.
  1916. //
  1917. if (NULL == hinstPrev)
  1918. {
  1919. wc.style = CS_HREDRAW | CS_VREDRAW;
  1920. wc.lpfnWndProc = (WNDPROC)AppWndProc;
  1921. wc.cbClsExtra = 0;
  1922. wc.cbWndExtra = 0;
  1923. wc.hInstance = hinst;
  1924. wc.hIcon = LoadIcon(hinst, ICON_APP);
  1925. wc.hCursor = LoadCursor(NULL, IDC_ARROW);
  1926. wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
  1927. wc.lpszMenuName = MENU_APP;
  1928. wc.lpszClassName = gszAppName;
  1929. if (!RegisterClass(&wc)) {
  1930. return (NULL);
  1931. }
  1932. }
  1933. //
  1934. // create the application's main window
  1935. //
  1936. // style bits available:
  1937. // WS_EX_ACCEPTFILES : will receive WM_DROPFILES messages
  1938. // WS_EX_DLGMODALFRAME : creates window with double border
  1939. // WS_EX_NOPARENTNOTIFY: won't receive WM_PARENTNOTIFY messages
  1940. // WS_EX_TOPMOST : puts window in topmost space
  1941. // WS_EX_TRANSPARENT : a very bizarre style indeed (Win 16 only)
  1942. //
  1943. hwnd = CreateWindowEx(WS_EX_NOPARENTNOTIFY,
  1944. gszAppName,
  1945. gszAppName,
  1946. WS_OVERLAPPEDWINDOW,
  1947. APP_WINDOW_XOFFSET,
  1948. APP_WINDOW_YOFFSET,
  1949. APP_WINDOW_WIDTH,
  1950. APP_WINDOW_HEIGHT,
  1951. NULL,
  1952. NULL,
  1953. hinst,
  1954. NULL);
  1955. if (NULL == hwnd)
  1956. return (NULL);
  1957. #ifdef UNICODE
  1958. //
  1959. // the application--which is different than the pszCmdLine argument
  1960. // passed through WinMain()...
  1961. //
  1962. // so, skip over the command name to get to the argument string
  1963. //
  1964. pszCmdLine = GetCommandLine();
  1965. if (NULL != pszCmdLine)
  1966. {
  1967. while (('\0' != *pszCmdLine) && (' ' != *pszCmdLine++))
  1968. ;
  1969. }
  1970. #endif
  1971. //
  1972. //
  1973. //
  1974. //
  1975. MMCapsSettingsRestore(hwnd, nCmdShow);
  1976. //
  1977. // finally, get the window displayed and return success
  1978. //
  1979. // the ShowWindow call is made during MMCapsInit
  1980. //
  1981. // ShowWindow(hwnd, nCmdShow);
  1982. // UpdateWindow(hwnd);
  1983. return (hwnd);
  1984. } // AppInit()
  1985. //--------------------------------------------------------------------------;
  1986. //
  1987. // int AppExit
  1988. //
  1989. // Description:
  1990. // This function is called just before the application exits from
  1991. // WinMain. Its purpose is to clean up any resources that were allocated
  1992. // for running the application: brushes, heaps, etc..
  1993. //
  1994. // Arguments:
  1995. // HINSTANCE hinst: Identifies the current instance of the
  1996. // application that is exiting.
  1997. //
  1998. // int nResult: The result of the WM_QUIT message (in wParam of the
  1999. // MSG structure. This argument will usually be 0 (even if the message
  2000. // loop was never entered).
  2001. //
  2002. // Return (int):
  2003. // The return value is usually nResult--be we give this function the
  2004. // opportunity to modify its value.
  2005. //
  2006. // History:
  2007. // 11/ 8/92
  2008. //
  2009. //--------------------------------------------------------------------------;
  2010. int FNGLOBAL AppExit
  2011. (
  2012. HINSTANCE hinst,
  2013. int nResult
  2014. )
  2015. {
  2016. DPF(0, "AppExit(hinst=%Xh, nResult=%d)", hinst, nResult);
  2017. //
  2018. //
  2019. //
  2020. //
  2021. return (nResult);
  2022. } // AppExit()
  2023. //==========================================================================;
  2024. //
  2025. // Main entry and message dispatching code
  2026. //
  2027. //
  2028. //==========================================================================;
  2029. //--------------------------------------------------------------------------;
  2030. //
  2031. // int WinMain
  2032. //
  2033. // Description:
  2034. // This function is called by the system as the initial entry point
  2035. // for a Windows application.
  2036. //
  2037. // Arguments:
  2038. // HINSTANCE hinst: Identifies the current instance of the
  2039. // application.
  2040. //
  2041. // HINSTANCE hinstPrev: Identifies the previous instance of the
  2042. // application (NULL if first instance). For Win 32, this argument
  2043. // is _always_ NULL.
  2044. //
  2045. // LPSTR pszCmdLine: Points to null-terminated unparsed command line.
  2046. // This string is strictly ANSI regardless of whether the application
  2047. // is built for Unicode. To get the Unicode equivalent call the
  2048. // GetCommandLine() function (Win 32 only).
  2049. //
  2050. // int nCmdShow: How the main window for the application is to be
  2051. // shown by default.
  2052. //
  2053. // Return (int):
  2054. // Returns result from WM_QUIT message (in wParam of MSG structure) if
  2055. // the application is able to enter its message loop. Returns 0 if
  2056. // the application is not able to enter its message loop.
  2057. //
  2058. // History:
  2059. // 11/ 8/92
  2060. //
  2061. //--------------------------------------------------------------------------;
  2062. int PASCAL WinMain
  2063. (
  2064. HINSTANCE hinst,
  2065. HINSTANCE hinstPrev,
  2066. LPSTR pszCmdLine,
  2067. int nCmdShow
  2068. )
  2069. {
  2070. int nResult;
  2071. HWND hwnd;
  2072. MSG msg;
  2073. HACCEL haccl;
  2074. //
  2075. // our documentation states that WinMain is supposed to return 0 if
  2076. // we do not enter our message loop--so assume the worst...
  2077. //
  2078. nResult = 0;
  2079. //
  2080. // make our instance handle global for convenience..
  2081. //
  2082. ghinst = hinst;
  2083. //
  2084. // init some stuff, create window, etc.. note the explicit cast of
  2085. // pszCmdLine--this is to mute a warning (and an ugly ifdef) when
  2086. // compiling for Unicode. see AppInit() for more details.
  2087. //
  2088. hwnd = AppInit(hinst, hinstPrev, (LPTSTR)pszCmdLine, nCmdShow);
  2089. if (hwnd)
  2090. {
  2091. haccl = LoadAccelerators(hinst, ACCEL_APP);
  2092. //
  2093. // dispatch messages
  2094. //
  2095. while (GetMessage(&msg, NULL, 0, 0))
  2096. {
  2097. //
  2098. // do all the special stuff required for this application
  2099. // when dispatching messages..
  2100. //
  2101. if (!TranslateAccelerator(hwnd, haccl, &msg))
  2102. {
  2103. TranslateMessage(&msg);
  2104. DispatchMessage(&msg);
  2105. }
  2106. }
  2107. //
  2108. // return result of WM_QUIT message.
  2109. //
  2110. nResult = (int)msg.wParam;
  2111. }
  2112. //
  2113. // shut things down, clean up, etc.
  2114. //
  2115. nResult = AppExit(hinst, nResult);
  2116. return (nResult);
  2117. } // WinMain()