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

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. * TimeWnd.C
  13. *
  14. * Message handlers and other code for the time window
  15. *
  16. *****************************************************************************/
  17. #pragma warning(disable:4756)
  18. #define _INC_SHELLAPI
  19. #include <windows.h>
  20. #undef _INC_SHELLAPI
  21. #include <shellapi.h>
  22. #include <windowsx.h>
  23. #include <mmsystem.h>
  24. #include <commdlg.h>
  25. #include <commctrl.h>
  26. #include <ctype.h>
  27. #include "debug.h"
  28. #include "MIDIPlyr.H"
  29. /* Into gszFormatHMS[]
  30. */
  31. #define HOUR_INDEX          0
  32. #define MIN_INDEX           3
  33. #define SEC_INDEX           6
  34. #define MIN_SEP_INDEX       2
  35. #define SEC_SEP_INDEX       5
  36. #define TIMER_ID            0
  37. #define TIMER_INTERVAL      100
  38. PRIVATE HFONT           ghFont          = NULL;
  39. PRIVATE char BCODE      gszFormatHMS[]  = "44:44:44";
  40. PRIVATE char BCODE      gszFormatTicks[]= "444444444";
  41. #define MAX_CBFMT (max(sizeof(gszFormatHMS), sizeof(gszFormatTicks)))
  42. PRIVATE BOOL            gbRepaint       = TRUE;
  43. PRIVATE int             gnPosY;
  44. PRIVATE int             ganPosX[MAX_CBFMT];
  45. PRIVATE int             gnTimerOn       = 0;
  46. PRIVATE VOID NEAR PASCAL PaintTime(HDC hDC);
  47. PRIVATE BOOL NEAR PASCAL TWnd_OnCreate(HWND hWnd, CREATESTRUCT FAR* lpCreateStruct);
  48. PRIVATE VOID NEAR PASCAL TWnd_OnSize(HWND hWnd, UINT state, int cx, int cy);
  49. PRIVATE VOID NEAR PASCAL TWnd_OnPaint(HWND hWnd);
  50. PRIVATE VOID NEAR PASCAL TWnd_OnCommand(HWND hWnd, int id, HWND hWndCtl, UINT codeNotify);
  51. PRIVATE VOID NEAR PASCAL TWnd_OnDestroy(HWND hWnd);
  52. PRIVATE VOID NEAR PASCAL TWnd_OnTimer(HWND hWnd, UINT id);
  53. /*****************************************************************************
  54. *
  55. * PaintTime
  56. *
  57. * Paint the current sequencer time into the time window.
  58. *
  59. * HWND hDC                  - DC to paint time into
  60. *
  61. * Repaint the time. Unless gbRepaint is set, just repaint the sections
  62. * of the time that need updating. Clear gbRepaint when done.
  63. *
  64. *****************************************************************************/
  65. static UINT oldh = 0;
  66. static UINT oldm = 0;
  67. static UINT olds = 0;
  68. static char szOldTicks[MAX_CBFMT];
  69. PRIVATE VOID NEAR PASCAL PaintTime(
  70.     HDC                     hDC)           
  71. {
  72.     TICKS                   tkTime;
  73.     DWORD                   msTime;
  74.     int                     ii;
  75.     int                     cb;
  76.     char                    szWork[MAX_CBFMT];
  77.     HFONT                   hFont;
  78.     UINT                    h;
  79.     UINT                    m;
  80.     UINT                    s;
  81.     BOOL                    fRepaintedSec;
  82.     BOOL                    fRepaintedMin;
  83.     if (MMSYSERR_NOERROR != seqTime(gpSeq, &tkTime))
  84.         return;
  85.     SetBkColor(hDC, RGB(0xFF, 0xFF, 0xFF));
  86.     hFont = SelectObject(hDC, ghFont);
  87.     
  88.     if (gnTimeFormat == IDS_TICKS)
  89.     {
  90.         wsprintf(szWork, "%9lu", (DWORD)tkTime);
  91.         for (ii = 0; ii < 9; ii++)
  92.         {
  93.             if (gbRepaint || szOldTicks[ii] != szWork[ii])
  94.                 EmbossedTextOut(
  95.                                 hDC,
  96.                                 ganPosX[ii],
  97.                                 gnPosY,
  98.                                 szWork+ii,
  99.                                 1,
  100.                                 (COLORREF)-1,
  101.                                 (COLORREF)-1,
  102.                                 3,
  103.                                 3);
  104.             szOldTicks[ii] = szWork[ii];
  105.         }
  106.     }
  107.     else
  108.     {
  109.         msTime = seqTicksToMillisecs(gpSeq, tkTime) / 1000L;
  110.         h = (UINT)(msTime / 3600L);    msTime %= 3600L;
  111.         m = (UINT)(msTime / 60L);      msTime %= 60L;
  112.         s = (UINT)msTime;
  113.         cb = lstrlen(gszFormatHMS);
  114.         if (gbRepaint || h != oldh)
  115.         {
  116.             szWork[0] = '0' + (char)(h / 10);
  117.             szWork[1] = '0' + (char)(h % 10);
  118.             EmbossedTextOut(
  119.                             hDC,
  120.                             ganPosX[HOUR_INDEX],
  121.                             gnPosY,
  122.                             szWork,
  123.                             2,
  124.                             (COLORREF)-1,
  125.                             (COLORREF)-1,
  126.                             3,
  127.                             3);
  128.             oldh = h;
  129.         }
  130.         fRepaintedMin = FALSE;
  131.         if (gbRepaint || m != oldm)
  132.         {
  133.             szWork[0] = gszFormatHMS[MIN_SEP_INDEX];
  134.             szWork[1] = '0' + (char)(m / 10);
  135.             szWork[2] = '0' + (char)(m % 10);
  136.             EmbossedTextOut(
  137.                             hDC,
  138.                             ganPosX[MIN_SEP_INDEX],
  139.                             gnPosY,
  140.                             szWork,
  141.                             3,
  142.                             (COLORREF)-1,
  143.                             (COLORREF)-1,
  144.                             3,
  145.                             3);
  146.             oldm = m;
  147.             fRepaintedMin = TRUE;
  148.         }
  149.         fRepaintedSec = FALSE;
  150.         if (gbRepaint || s != olds)
  151.         {
  152.             szWork[0] = gszFormatHMS[SEC_SEP_INDEX];
  153.             szWork[1] = '0' + (char)(s / 10);
  154.             szWork[2] = '0' + (char)(s % 10);
  155.             EmbossedTextOut(
  156.                             hDC,
  157.                             ganPosX[SEC_SEP_INDEX],
  158.                             gnPosY,
  159.                             szWork,
  160.                             3,
  161.                             (COLORREF)-1,
  162.                             (COLORREF)-1,
  163.                             3,
  164.                             3);
  165.             olds = s;
  166.             fRepaintedSec = TRUE;
  167.         }
  168.         /* If we're doing a full repaint, then update the separators
  169.          */
  170.         if (gbRepaint)
  171.             for (ii=0; ii < cb; ii++)
  172.                 if (!isdigit(gszFormatHMS[ii]))
  173.                 {
  174.                     if (SEC_SEP_INDEX == ii && fRepaintedSec)
  175.                         continue;
  176.                     if (MIN_SEP_INDEX == ii && fRepaintedMin)
  177.                         continue;
  178.                     EmbossedTextOut(
  179.                                     hDC,
  180.                                     ganPosX[ii],
  181.                                     gnPosY,
  182.                                     gszFormatHMS+ii,
  183.                                     1,
  184.                                     (COLORREF)-1,
  185.                                     (COLORREF)-1,
  186.                                     3,
  187.                                     3);
  188.                 }
  189.     }
  190.     
  191.     gbRepaint = FALSE;
  192.     SelectObject(hDC, hFont);
  193. }
  194. /*****************************************************************************
  195. *
  196. * TWnd_OnCreate
  197. *
  198. * Handle WM_CREATE message to time window.
  199. *
  200. * HWND hWnd                 - Window handle
  201. * CREATESTRUCT FAR* lpCreateStruct
  202. *                           - Pointer to creation parameters for the window.
  203. *
  204. * Returns TRUE on success. Returning FALSE will cause the window to be
  205. * destroyed and the application will exit.
  206. *
  207. * Just return TRUE so the window will be created.
  208. *
  209. *****************************************************************************/
  210. BOOL NEAR PASCAL TWnd_OnCreate(
  211.     HWND                    hWnd,
  212.     CREATESTRUCT FAR*       lpCreateStruct)
  213. {
  214.     return TRUE;
  215. }
  216. /*****************************************************************************
  217. *
  218. * TWnd_OnSize
  219. *
  220. * Handle WM_SIZE message to time window.
  221. *
  222. * HWND hWnd                 - Window handle
  223. * UINT state                - Some SIZE_xxx code indicating what type of
  224. *                             size operation this is.
  225. * int  cx, cy               - New x and y size of the window's client area.
  226. *
  227. * Get the new client rect into grcTWnd.
  228. * Destroy and recreate the font scaled to show the time at the correct size.
  229. * Force the time to fully repaint.
  230. *
  231. *****************************************************************************/
  232. VOID NEAR PASCAL TWnd_OnSize(
  233.     HWND                    hWnd,
  234.     UINT                    state,
  235.     int                     cx,
  236.     int                     cy)
  237. {
  238.     HDC                     hDC;
  239.     
  240.     GetClientRect(hWnd, &grcTWnd);
  241.     if (ghFont != (HFONT)NULL)
  242.         DeleteObject(ghFont);
  243.     hDC = GetDC(hWnd);
  244.     ghFont = CreateScaledFont(hDC,
  245.                               &grcTWnd,
  246.                               (gnTimeFormat == IDS_TICKS) ? gszFormatTicks : gszFormatHMS,
  247.                               ganPosX,
  248.                               &gnPosY);
  249.     ReleaseDC(hWnd, hDC);
  250.     gbRepaint = TRUE;
  251.     InvalidateRect(hWnd, NULL, TRUE);
  252. }
  253. /*****************************************************************************
  254. *
  255. * TWnd_OnPaint
  256. *
  257. * Handle WM_PAINT message to time window.
  258. *
  259. * HWND hWnd                 - Window handle
  260. *
  261. * Repaint the 3D inset borders around the edge of the client area.
  262. * Repaint the time.
  263. *
  264. *****************************************************************************/
  265. VOID NEAR PASCAL TWnd_OnPaint( HWND hWnd) { PAINTSTRUCT ps; HDC hDC;
  266. HBRUSH hBrOld; int nWidth; int nHeight;
  267.     RECT                    rc;
  268.     GetClientRect(hWnd, &rc);
  269.     nWidth  = rc.right;
  270.     nHeight = rc.bottom;
  271.     
  272.     hDC = BeginPaint(hWnd, &ps);
  273.     hBrOld = (HBRUSH)SelectObject(hDC, GetStockObject(GRAY_BRUSH));
  274.     PatBlt(hDC, 0, 0, 1, nHeight-1, PATCOPY);
  275.     PatBlt(hDC, 1, 0, nWidth-2, 1, PATCOPY);
  276.     SelectObject(hDC, GetStockObject(BLACK_BRUSH));
  277.     PatBlt(hDC, 1, 1, 1, nHeight-3, PATCOPY);
  278.     PatBlt(hDC, 2, 1, nWidth-4, 1, PATCOPY);
  279.     SelectObject(hDC, GetStockObject(WHITE_BRUSH));
  280.     PatBlt(hDC, rc.right-1, 0, 1, nHeight-1, PATCOPY);
  281.     PatBlt(hDC, 0, rc.bottom-1, nWidth, 1, PATCOPY);
  282.     SelectObject(hDC, GetStockObject(LTGRAY_BRUSH));
  283.     PatBlt(hDC, rc.right-2, 1, 1, nHeight-2, PATCOPY);
  284.     PatBlt(hDC, 1, rc.bottom-2, nWidth-2, 1, PATCOPY);
  285.     
  286.     SelectObject(hDC, hBrOld);
  287.     gbRepaint = TRUE;
  288.     PaintTime(hDC);
  289.     EndPaint(hWnd, &ps);
  290. }
  291. /*****************************************************************************
  292. *
  293. * TWnd_OnCommand
  294. *
  295. * Handle WM_COMMAND message to the time window.
  296. *
  297. * HWND hWnd                 - Window handle
  298. * int id                    - id of control or menu causing WM_COMMAND
  299. * HWND hwndCtl              - Window handle of child control, if any
  300. * UINT codeNotify           - Notification code if this message is from a
  301. *                             control.
  302. *
  303. * We will receive IDM_PLAY and IDM_STOP messages forwarded from the main
  304. * application window whenver playback starts or stops. Use these messages
  305. * to create or kill a timer which will be used to update the time.
  306. *****************************************************************************/
  307. VOID NEAR PASCAL TWnd_OnCommand(
  308.     HWND                    hWnd,
  309.     int                     id,
  310.     HWND                    hWndCtl,
  311.     UINT                    codeNotify)
  312. {
  313.     switch(id)
  314.     {
  315.         case IDM_PLAY:
  316.             if (0 == gnTimerOn)
  317.             {
  318.                 gnTimerOn++;
  319.                 SetTimer(hWnd, TIMER_ID, TIMER_INTERVAL, 0);
  320.             }
  321.             UpdateWindow(hWnd);
  322.             break;
  323.         case IDM_STOP:
  324.             if (0 == gnTimerOn)
  325.             {
  326.                 gnTimerOn--;
  327.                 KillTimer(hWnd, TIMER_ID);
  328.             }
  329.             
  330.             UpdateWindow(hWnd);
  331.             break;
  332.     }
  333. }
  334. /*****************************************************************************
  335. *
  336. * TWnd_OnDestroy
  337. *
  338. * Handle WM_DESTROY message to the time window.
  339. *
  340. * HWND hWnd                 - Window handle
  341. *
  342. * If we're being destroyed and the timer is still running, stop it.
  343. *****************************************************************************/
  344. VOID NEAR PASCAL TWnd_OnDestroy(
  345.     HWND                    hWnd)
  346. {
  347.     if (gnTimerOn)
  348.     {
  349.         KillTimer(hWnd, TIMER_ID);
  350.     }
  351. }
  352. /*****************************************************************************
  353. *
  354. * TWnd_OnTimer
  355. *
  356. * Handle WM_TIMER message to the time window.
  357. *
  358. * HWND hWnd                 - Window handle
  359. * UINT id                   - Timer ID
  360. *
  361. * Update the time.
  362. *****************************************************************************/
  363. PRIVATE VOID NEAR PASCAL TWnd_OnTimer(
  364.     HWND                    hWnd,
  365.     UINT                    id)
  366. {
  367.     HDC                     hDC;
  368.     hDC = GetDC(hWnd);
  369.     PaintTime(hDC);
  370.     ReleaseDC(hWnd, hDC);
  371. }
  372. /*****************************************************************************
  373. *
  374. * TWnd_WndProc
  375. *
  376. * Window procedure for main application window.
  377. *
  378. * HWND hWnd                 - Window handle
  379. * UINT msg                  - Message code
  380. * WPARAM wParam             - Message specific parameter
  381. * LPARAM lParam             - Message specific parameter
  382. *
  383. * Dispatch messages we care about to the appropriate handler, else just
  384. * call DefWindowProc.
  385. *
  386. * Note this use of message cracker macros from windowsx.h. Using these
  387. * macros will shield you from the differences between Win16 and Win32;
  388. * if your app is cross-compilable, you should use these and save yourself
  389. * some headaches!
  390. *
  391. *****************************************************************************/
  392. LRESULT CALLBACK TWnd_WndProc(
  393.     HWND                    hWnd,
  394.     UINT                    msg,
  395.     WPARAM                  wParam,
  396.     LPARAM                  lParam)
  397. {
  398.     switch( msg )
  399.     {
  400.         HANDLE_MSG(hWnd, WM_CREATE,         TWnd_OnCreate);
  401.         HANDLE_MSG(hWnd, WM_SIZE,           TWnd_OnSize);
  402.         HANDLE_MSG(hWnd, WM_PAINT,          TWnd_OnPaint);
  403.         HANDLE_MSG(hWnd, WM_COMMAND,        TWnd_OnCommand);
  404.         HANDLE_MSG(hWnd, WM_DESTROY,        TWnd_OnDestroy);
  405.         HANDLE_MSG(hWnd, WM_TIMER,          TWnd_OnTimer);
  406.         default:
  407.             return DefWindowProc(hWnd, msg, wParam, lParam);
  408.     }
  409.     return 0;
  410. }