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

Windows编程

开发平台:

Visual C++

  1. /**************************************************************************
  2.  *
  3.  *  THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
  4.  *  KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  5.  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
  6.  *  PURPOSE.
  7.  *
  8.  *  Copyright (C) 1992 - 1997 Microsoft Corporation.  All Rights Reserved.
  9.  *
  10.  **************************************************************************/
  11. /*----------------------------------------------------------------------------*
  12.  *
  13.  *  MCIPUZZLE:
  14.  *
  15.  *    Sample app showing the use of MCIWnd, installable draw procedure
  16.  *
  17.  *    MCIPUZZLE is an application that demonstrates the following:
  18.  *
  19.  *      - Using the MCIWnd window class to play MCI files.
  20.  *
  21.  *      - Using an installable draw procedure with MCIAVI
  22.  *
  23.  *      - Implementing a version of the classic "15" puzzle
  24.  *
  25.  *----------------------------------------------------------------------------*/
  26. #define  STRICT
  27. #define INC_OLE2
  28. #include <windows.h>
  29. #include <windowsx.h>
  30. #include <commdlg.h>
  31. #include <mmsystem.h>
  32. #include <digitalv.h>
  33. #include <mciavi.h>
  34. #include <vfw.h>
  35. #include "mcipuzzl.h"
  36. #include "puzzle.h"
  37. #include "puzzproc.h"
  38. //---------------------------------------------------------------------------
  39. #define BUFSIZE 260
  40. #define MCIPLAY_APP_CLASS "MCIPuzzle_App"
  41. #define MCIPLAY_DOC_CLASS MCIWND_WINDOW_CLASS
  42. typedef MCI_DGV_SETVIDEO_PARMS * LP_MCI_DGV;
  43. /*-------------------------------------------------------------------------*
  44. |                                                                          |
  45. |   g l o b a l   v a r i a b l e s                                        |
  46. |                                                                          |
  47. *------------------------------------------------------------------------*/
  48. static  HINSTANCE ghInstApp;            /* Instance handle */
  49. static  HACCEL    ghAccelApp;
  50. static  HWND      ghwndApp;             /* Handle to parent window */
  51. static  HWND      ghwndMCI;             /* Handle to MCI client window */
  52. static  char      gszBuffer[BUFSIZE];
  53. static  DWORD     gdwHook = 0L;
  54. PUZZLE            gPuzzle;
  55. //---------------------------------------------------------------------------
  56. LRESULT CALLBACK AppWndProc(HWND, UINT, WPARAM, LPARAM);
  57. BOOL    CALLBACK AppAbout(HWND, UINT, WPARAM, LPARAM);
  58. static BOOL AppInit(HINSTANCE, HINSTANCE, LPSTR, int);
  59. static BOOL FormatFilterString(UINT, LPSTR);
  60. static void MCI_OnCommand(HWND, int, HWND, UINT);
  61. static void MCI_OnInitMenuPopup(HWND, HMENU, int, BOOL);
  62. static void MCI_OnSize(HWND, UINT, int, int);
  63. static void MCI_OnParentNotify(HWND, UINT, HWND, int);
  64. static void Handle_NotifyMedia(HWND,WPARAM);
  65. static void Handle_NotifySize(HWND,WPARAM);
  66. /*----------------------------------------------------------------------------*
  67. |   AppAbout( hDlg, msg, wParam, lParam )                                      |
  68. |                                                                              |
  69. |   Description:                                                               |
  70. |       This function handles messages belonging to the "About" dialog box.    |
  71. |       The only message that it looks for is WM_COMMAND, indicating the user  |
  72. |       has pressed the "OK" button.  When this happens, it takes down         |
  73. |       the dialog box.                                                        |
  74. |                                                                              |
  75. |   Arguments:                                                                 |
  76. |       hDlg            window handle of about dialog window                   |
  77. |       msg             message number                                         |
  78. |       wParam          message-dependent                                      |
  79. |       lParam          message-dependent                                      |
  80. |                                                                              |
  81. |   Returns:                                                                   |
  82. |       TRUE if message has been processed, else FALSE                         |
  83. |                                                                              |
  84. *----------------------------------------------------------------------------*/
  85. BOOL CALLBACK AppAbout(
  86. HWND hwnd,
  87. UINT msg,
  88. WPARAM wParam,
  89. LPARAM lParam)
  90. {
  91.         switch (msg) {
  92.                 case WM_COMMAND:
  93.                 EndDialog(hwnd,TRUE);
  94.                 return TRUE;
  95.         }
  96.         return FALSE;
  97. }
  98. /*----------------------------------------------------------------------------*
  99. |   AppInit ( hInstance, hPrevInstance )                                       |
  100. |                                                                              |
  101. |   Description:                                                               |
  102. |       This is called when the application is first loaded into               |
  103. |       memory.  It performs all initialization that doesn't need to be done   |
  104. |       once per instance.                                                     |
  105. |                                                                              |
  106. |   Arguments:                                                                 |
  107. |       hPrevInstance   instance handle of previous instance                   |
  108. |       hInstance       instance handle of current instance                    |
  109. |                                                                              |
  110. |   Returns:                                                                   |
  111. |       TRUE if successful, FALSE if not                                       |
  112. |                                                                              |
  113. *----------------------------------------------------------------------------*/
  114. static BOOL AppInit(
  115. HINSTANCE hInst,
  116. HINSTANCE hPrev,
  117. LPSTR szCmd,
  118. int sw)
  119. {
  120.         WNDCLASS cls;
  121.         WORD wVer;
  122.         char szAppName[BUFSIZE];
  123.         /* Save instance handle for DialogBox */
  124.         ghInstApp = hInst;
  125.         LoadString( ghInstApp, IDS_APPNAME, szAppName, BUFSIZE );
  126.         /* first let's make sure we are running on 1.1 */
  127.         wVer = HIWORD(VideoForWindowsVersion());
  128.         if (wVer < 0x010a){
  129.                 char szTitle[BUFSIZE];
  130.                 /* oops, we are too old, blow out of here */
  131.                 LoadString( ghInstApp, IDS_APPERR, szTitle, BUFSIZE );
  132.                 LoadString( ghInstApp, IDS_VFWTOOOLD, gszBuffer, BUFSIZE );
  133.                 MessageBeep(MB_ICONHAND);
  134.                 MessageBox(NULL, gszBuffer, szTitle, MB_OK|MB_ICONSTOP);
  135.                 return FALSE;
  136.         }
  137.         ghAccelApp = LoadAccelerators(ghInstApp, "AppAccel");
  138.         if (!hPrev) {
  139.                 cls.hCursor        = LoadCursor(NULL,IDC_ARROW);
  140.                 cls.hIcon          = LoadIcon(hInst,"AppIcon");
  141.                 cls.lpszMenuName   = "AppMenu";
  142.                 cls.lpszClassName  = MCIPLAY_APP_CLASS;
  143.                 cls.hbrBackground  = (HBRUSH)COLOR_APPWORKSPACE+1;
  144.                 cls.hInstance      = hInst;
  145.                 cls.style          = 0;
  146.                 cls.lpfnWndProc    = (WNDPROC)AppWndProc;
  147.                 cls.cbClsExtra     = 0;
  148.                 cls.cbWndExtra     = 0;
  149.                 if (!RegisterClass(&cls))
  150.                         return FALSE;
  151.         }
  152.         ghwndApp = CreateWindow(
  153.                 MCIPLAY_APP_CLASS,
  154.                 szAppName,
  155.                 WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
  156.                 CW_USEDEFAULT,
  157.                 0,
  158.                 160,
  159.                 120,
  160.                 (HWND)NULL,       /* no parent */
  161.                 (HMENU)NULL,      /* use class menu */
  162.                 (HANDLE)hInst,     /* handle to window instance */
  163.                 (LPSTR)NULL);     /* no params to pass on */
  164.         InitPuzzle(&gPuzzle, TRUE /* FALSE to not scramble */);
  165.         /* Make window visible according to the way the app is activated */
  166.         ShowWindow(ghwndApp,sw);
  167.         return TRUE;
  168. }
  169. /*----------------------------------------------------------------------------*
  170. |   WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )                  |
  171. |                                                                              |
  172. |   Description:                                                               |
  173. |       The main procedure for the App.  After initializing, it just goes      |
  174. |       into a message-processing loop until it gets a WM_QUIT message         |
  175. |       (meaning the app was closed).                                          |
  176. |                                                                              |
  177. |   Arguments:                                                                 |
  178. |       hInstance       instance handle of this instance of the app            |
  179. |       hPrevInstance   instance handle of previous instance, NULL if first    |
  180. |       lpszCmdLine     ->null-terminated command line                         |
  181. |       cmdShow         specifies how the window is initially displayed        |
  182. |                                                                              |
  183. |   Returns:                                                                   |
  184. |       The exit code as specified in the WM_QUIT message.                     |
  185. |                                                                              |
  186. *----------------------------------------------------------------------------*/
  187. int PASCAL WinMain(
  188. HINSTANCE hInstance,
  189. HINSTANCE hPrevInstance,
  190. LPSTR szCmdLine,
  191. int sw)
  192. {
  193.         MSG msg;
  194.         if (!AppInit(hInstance,hPrevInstance,szCmdLine,sw))
  195.                 return FALSE;
  196.         //Polling messages from event queue
  197.         for (;;) {
  198.                 if (PeekMessage(&msg, NULL, 0, 0,PM_REMOVE)) {
  199.                         if (msg.message == WM_QUIT)
  200.                                 break;
  201.                         if (ghAccelApp && ghwndApp && TranslateAccelerator(ghwndApp, ghAccelApp, &msg))
  202.                                 continue;
  203.                         TranslateMessage(&msg);
  204.                         DispatchMessage(&msg);
  205.                         } else {
  206.                         // idle time here, DONT BE A PIG!
  207.                         WaitMessage();
  208.                 }
  209.         }
  210.         return msg.wParam;
  211. }
  212. //----------------------------------------------------------------------------
  213. // MCI_OnCommand - Handles WM_COMMAND
  214. //----------------------------------------------------------------------------
  215. static void MCI_OnCommand(
  216. HWND hwnd,
  217. int id,
  218. HWND hwndCtl,
  219. UINT codeNotify)
  220. {
  221.         switch(id) {
  222.                 case MENU_ABOUT:
  223.                 DialogBox(ghInstApp,MAKEINTRESOURCE(ABOUTBOX),hwnd,AppAbout);
  224.                 break;
  225.                 case MENU_EXIT:
  226.                 PostMessage(hwnd,WM_CLOSE,0,0L);
  227.                 break;
  228.                 case MENU_CLOSE:
  229.                 PostMessage(ghwndMCI, WM_CLOSE, 0, 0L);
  230.                 break;
  231.                 case MENU_OPEN:
  232.                 {
  233.                         OPENFILENAME ofn;
  234.                         char szFileName[BUFSIZE];
  235.                         char szFilter[BUFSIZE];
  236.                         FormatFilterString( IDS_FILTERSTRING, szFilter );
  237.                         /* prompt user for file to open */
  238.                         ofn.lStructSize = sizeof(OPENFILENAME);
  239.                         ofn.hwndOwner = hwnd;
  240.                         ofn.hInstance = NULL;
  241.                         ofn.lpstrFilter = szFilter;
  242.                         ofn.lpstrCustomFilter = NULL;
  243.                         ofn.nMaxCustFilter = 0;
  244.                         ofn.nFilterIndex = 0;
  245.                         *szFileName = '';
  246.                         ofn.lpstrFile = szFileName;
  247.                         ofn.nMaxFile = BUFSIZE;
  248.                         ofn.lpstrFileTitle = NULL;
  249.                         ofn.nMaxFileTitle = 0;
  250.                         ofn.lpstrInitialDir = NULL;
  251.                         ofn.lpstrTitle = "Open";
  252.                         ofn.Flags = OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST | OFN_HIDEREADONLY;
  253.                         ofn.nFileOffset = 0;
  254.                         ofn.nFileExtension = 0;
  255.                         ofn.lpstrDefExt = NULL;
  256.                         ofn.lCustData = 0;
  257.                         ofn.lpfnHook = NULL;
  258.                         ofn.lpTemplateName = NULL;
  259.                         if (GetOpenFileName(&ofn)) {
  260.                                 MCIWndOpen(ghwndMCI, (LPARAM)(LPSTR)szFileName, 0);
  261.                                 InitPuzzle(&gPuzzle, TRUE /* FALSE to not scramble */);
  262.                         }
  263.                 }
  264.                 break;
  265.                 /* Movie Menu (for use by accelerators) */
  266.                 case IDM_PLAY:
  267.                         MCIWndPlay(ghwndMCI);
  268.                         break;
  269.                 case IDM_RPLAY:
  270.                         MCIWndPlayReverse(ghwndMCI);
  271.                         break;
  272.       // Solve or scramble the puzzle, as appropriate
  273.                 case IDM_SOLVE:
  274.                 case IDM_SCRAMBLE:
  275.                     InitPuzzle(&gPuzzle, id == IDM_SCRAMBLE);
  276.                     InvalidateRect(ghwndMCI, NULL, FALSE);
  277.                     break;
  278.         }
  279.         return;
  280. }
  281. //----------------------------------------------------------------------------
  282. // MCI_OnSize - Handles WM_SIZE
  283. //----------------------------------------------------------------------------
  284. static void MCI_OnSize(
  285. HWND hwnd,
  286. UINT state,
  287. int cx,
  288. int cy)
  289. {
  290. if (!IsIconic(hwnd)) {
  291.          MoveWindow(ghwndMCI,0,0,cx,cy,TRUE);
  292.         }
  293. }
  294. //----------------------------------------------------------------------------
  295. // MCI_OnParentNotify - Handles WM_PARENTNOTIFY
  296. //----------------------------------------------------------------------------
  297. static void MCI_OnParentNotify(
  298. HWND hwnd,
  299. UINT msg,
  300. HWND hwndChild,
  301. int idChild)
  302. {
  303.     if (msg == WM_LBUTTONDOWN && ghwndMCI) {
  304.         RECT    rc;
  305.         POINT   pt;
  306.         pt.x = (int)LOWORD((DWORD)hwndChild);
  307.         pt.y = (int)HIWORD((DWORD)hwndChild);
  308.         ClientToScreen(hwnd, &pt);
  309.         MCIWndGetDest(ghwndMCI, &rc);
  310.         if (rc.bottom != rc.top && rc.right != rc.left) {
  311.             ScreenToClient(ghwndMCI, &pt);
  312.             ClickPuzzle(&gPuzzle,
  313.                     (pt.x - rc.left) * PSIZE / (rc.right - rc.left),
  314.                     (pt.y - rc.top) * PSIZE / (rc.bottom - rc.top));
  315.             InvalidateRect(ghwndMCI, &rc, FALSE);
  316.         }
  317.     }
  318.     return;
  319. }
  320. /*----------------------------------------------------------------------------*
  321. |   AppWndProc( hwnd, msg, wParam, lParam )                                    |
  322. |                                                                              |
  323. |   Description:                                                               |
  324. |       The window proc for the app's main (tiled) window.  This processes all |
  325. |       of the parent window's messages.                                       |
  326. |                                                                              |
  327. |   Arguments:                                                                 |
  328. |       hwnd            window handle for the parent window                    |
  329. |       msg             message number                                         |
  330. |       wParam          message-dependent                                      |
  331. |       lParam          message-dependent                                      |
  332. |                                                                              |
  333. |   Returns:                                                                   |
  334. |       0 if processed, nonzero if ignored                                     |
  335. |                                                                              |
  336. *----------------------------------------------------------------------------*/
  337. LRESULT CALLBACK AppWndProc(
  338. HWND hwnd,
  339. UINT msg,
  340. WPARAM wParam,
  341. LPARAM lParam)
  342. {
  343.     switch (msg) {
  344.        case WM_CREATE:
  345.                 ghwndMCI = MCIWndCreate(hwnd, ghInstApp, WS_CHILD | WS_VISIBLE |
  346.                         MCIWNDF_NOTIFYMEDIA | MCIWNDF_NOTIFYSIZE | MCIWNDF_NOMENU, 0);
  347.                 break;
  348.         case WM_COMMAND:
  349.                 HANDLE_WM_COMMAND(hwnd, wParam, lParam, MCI_OnCommand);
  350.                 break;
  351.         case WM_PALETTECHANGED:
  352.         case WM_QUERYNEWPALETTE:
  353.         case WM_ACTIVATE:
  354.                 // Forward palette-related messages through to the MCIWnd,
  355.                 // so it can do the right thing.
  356.                 if (ghwndMCI)
  357.                         return SendMessage(ghwndMCI, msg, wParam, lParam);
  358.                 break;
  359.         case WM_SIZE:
  360.                 HANDLE_WM_SIZE(hwnd, wParam, lParam, MCI_OnSize);
  361.                 break;
  362.         case WM_DESTROY:
  363.                 PostQuitMessage(0);
  364.                 return (0);
  365.                 break;
  366.        case WM_PARENTNOTIFY:
  367.                 HANDLE_WM_PARENTNOTIFY(hwnd, wParam, lParam, MCI_OnParentNotify);
  368.                 break;
  369.        case MCIWNDM_NOTIFYMEDIA:
  370.                 Handle_NotifyMedia(hwnd, wParam);
  371.                 break;
  372.        case MCIWNDM_NOTIFYSIZE:
  373.                 Handle_NotifySize(hwnd, wParam);
  374.                 break;
  375.         }
  376.         return DefWindowProc(hwnd,msg,wParam,lParam);
  377. }
  378. /*--------------------------------------------------------------+
  379. | Handle_NotifyMedia                                            |
  380. |                                                               |
  381. +--------------------------------------------------------------*/
  382. static void Handle_NotifyMedia(
  383. HWND hwnd,
  384. WPARAM wParam)
  385. {
  386.         MCI_DGV_SETVIDEO_PARMS dgv;
  387.         DWORD dw;
  388.         UINT uDevice;
  389.         if (ghwndMCI == 0)
  390.                 ghwndMCI = (HWND) wParam;
  391.         if (!gdwHook)
  392.                 gdwHook = (DWORD)ICAVIDrawProc;
  393.         dgv.dwValue = gdwHook;
  394.         dgv.dwItem = MCI_AVI_SETVIDEO_DRAW_PROCEDURE;
  395.         uDevice = MCIWndGetDeviceID(ghwndMCI);
  396.         if (uDevice) {
  397.                 dw = mciSendCommand(uDevice, MCI_SETVIDEO,
  398.                                MCI_DGV_SETVIDEO_ITEM | MCI_DGV_SETVIDEO_VALUE,
  399.                                (DWORD)(LP_MCI_DGV)&dgv);
  400.                 if (dw != 0) {
  401.                         char szTitle[BUFSIZE];
  402.                         LoadString( ghInstApp, IDS_APPERR, szTitle, BUFSIZE );
  403.                         LoadString( ghInstApp, IDS_MCIERROR, gszBuffer, BUFSIZE );
  404.                         MessageBox(hwnd, gszBuffer, szTitle, MB_OK | MB_ICONHAND);
  405.                 }
  406.         }
  407.         return;
  408. }
  409. /*--------------------------------------------------------------+
  410. | Handle_NotifySize                                             |
  411. |                                                               |
  412. +--------------------------------------------------------------*/
  413. static void Handle_NotifySize(
  414. HWND hwnd,
  415. WPARAM wParam)
  416. {
  417. RECT rc;
  418. if (!IsIconic(hwnd)) {
  419.          if (ghwndMCI == 0)
  420.                  ghwndMCI = (HWND) wParam;
  421.          GetWindowRect(ghwndMCI, &rc);
  422.          AdjustWindowRect(&rc, GetWindowLong(hwnd, GWL_STYLE), TRUE);
  423.          SetWindowPos(hwnd, NULL, 0, 0, rc.right - rc.left,
  424. rc.bottom - rc.top,
  425.                  SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOMOVE);
  426. }
  427. }
  428. /*--------------------------------------------------------------+
  429. | FormatFilterString                                            |
  430. |                                                               |
  431. +--------------------------------------------------------------*/
  432. static BOOL FormatFilterString(
  433. UINT uID,
  434. LPSTR lpszString )
  435. {
  436.         int nLength, nCtr = 0;
  437.         char chWildCard;
  438.         *lpszString = 0;
  439.         nLength = LoadString( ghInstApp, uID, lpszString, BUFSIZE );
  440.         chWildCard = lpszString[nLength-1];
  441.         while( lpszString[nCtr] ) {
  442.                 if( lpszString[nCtr] == chWildCard )
  443.                         lpszString[nCtr] = 0;
  444.                 nCtr++;
  445.         }
  446.         return TRUE;
  447. }