MMCAPS.C
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:63k
源码类别:

Windows编程

开发平台:

Visual C++

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