www.pudn.com > LSJ_MIDIPLYR.rar > TIMEWND.C


/***************************************************************************** 
* 
*  THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF 
*  ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED 
*  TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR 
*  A PARTICULAR PURPOSE. 
* 
*  Copyright (C) 1993 - 1997 Microsoft Corporation. All Rights Reserved. 
* 
****************************************************************************** 
* 
* TimeWnd.C 
* 
* Message handlers and other code for the time window 
* 
*****************************************************************************/ 
 
#pragma warning(disable:4756) 
 
#define _INC_SHELLAPI 
#include  
#undef _INC_SHELLAPI 
 
#include  
#include  
#include  
#include  
#include  
#include  
 
#include "debug.h" 
 
#include "MIDIPlyr.H" 
 
/* Into gszFormatHMS[] 
*/ 
#define HOUR_INDEX          0 
#define MIN_INDEX           3 
#define SEC_INDEX           6 
 
#define MIN_SEP_INDEX       2 
#define SEC_SEP_INDEX       5 
 
#define TIMER_ID            0 
#define TIMER_INTERVAL      100 
 
PRIVATE HFONT           ghFont          = NULL; 
PRIVATE char BCODE      gszFormatHMS[]  = "44:44:44"; 
PRIVATE char BCODE      gszFormatTicks[]= "444444444"; 
 
#define MAX_CBFMT (max(sizeof(gszFormatHMS), sizeof(gszFormatTicks))) 
 
PRIVATE BOOL            gbRepaint       = TRUE; 
PRIVATE int             gnPosY; 
PRIVATE int             ganPosX[MAX_CBFMT]; 
 
PRIVATE int             gnTimerOn       = 0; 
 
PRIVATE VOID NEAR PASCAL PaintTime(HDC hDC); 
 
PRIVATE BOOL NEAR PASCAL TWnd_OnCreate(HWND hWnd, CREATESTRUCT FAR* lpCreateStruct); 
PRIVATE VOID NEAR PASCAL TWnd_OnSize(HWND hWnd, UINT state, int cx, int cy); 
PRIVATE VOID NEAR PASCAL TWnd_OnPaint(HWND hWnd); 
PRIVATE VOID NEAR PASCAL TWnd_OnCommand(HWND hWnd, int id, HWND hWndCtl, UINT codeNotify); 
PRIVATE VOID NEAR PASCAL TWnd_OnDestroy(HWND hWnd); 
PRIVATE VOID NEAR PASCAL TWnd_OnTimer(HWND hWnd, UINT id); 
 
/***************************************************************************** 
* 
* PaintTime 
* 
* Paint the current sequencer time into the time window. 
* 
* HWND hDC                  - DC to paint time into 
* 
* Repaint the time. Unless gbRepaint is set, just repaint the sections 
* of the time that need updating. Clear gbRepaint when done. 
* 
*****************************************************************************/ 
static UINT oldh = 0; 
static UINT oldm = 0; 
static UINT olds = 0; 
 
static char szOldTicks[MAX_CBFMT]; 
 
PRIVATE VOID NEAR PASCAL PaintTime( 
    HDC                     hDC)            
{ 
    TICKS                   tkTime; 
    DWORD                   msTime; 
    int                     ii; 
    int                     cb; 
    char                    szWork[MAX_CBFMT]; 
    HFONT                   hFont; 
    UINT                    h; 
    UINT                    m; 
    UINT                    s; 
    BOOL                    fRepaintedSec; 
    BOOL                    fRepaintedMin; 
 
    if (MMSYSERR_NOERROR != seqTime(gpSeq, &tkTime)) 
        return; 
 
    SetBkColor(hDC, RGB(0xFF, 0xFF, 0xFF)); 
    hFont = SelectObject(hDC, ghFont); 
     
    if (gnTimeFormat == IDS_TICKS) 
    { 
        wsprintf(szWork, "%9lu", (DWORD)tkTime); 
 
        for (ii = 0; ii < 9; ii++) 
        { 
            if (gbRepaint || szOldTicks[ii] != szWork[ii]) 
                EmbossedTextOut( 
                                hDC, 
                                ganPosX[ii], 
                                gnPosY, 
                                szWork+ii, 
                                1, 
                                (COLORREF)-1, 
                                (COLORREF)-1, 
                                3, 
                                3); 
            szOldTicks[ii] = szWork[ii]; 
        } 
    } 
    else 
    { 
        msTime = seqTicksToMillisecs(gpSeq, tkTime) / 1000L; 
 
        h = (UINT)(msTime / 3600L);    msTime %= 3600L; 
        m = (UINT)(msTime / 60L);      msTime %= 60L; 
        s = (UINT)msTime; 
 
        cb = lstrlen(gszFormatHMS); 
 
        if (gbRepaint || h != oldh) 
        { 
            szWork[0] = '0' + (char)(h / 10); 
            szWork[1] = '0' + (char)(h % 10); 
            EmbossedTextOut( 
                            hDC, 
                            ganPosX[HOUR_INDEX], 
                            gnPosY, 
                            szWork, 
                            2, 
                            (COLORREF)-1, 
                            (COLORREF)-1, 
                            3, 
                            3); 
            oldh = h; 
        } 
 
        fRepaintedMin = FALSE; 
        if (gbRepaint || m != oldm) 
        { 
            szWork[0] = gszFormatHMS[MIN_SEP_INDEX]; 
            szWork[1] = '0' + (char)(m / 10); 
            szWork[2] = '0' + (char)(m % 10); 
            EmbossedTextOut( 
                            hDC, 
                            ganPosX[MIN_SEP_INDEX], 
                            gnPosY, 
                            szWork, 
                            3, 
                            (COLORREF)-1, 
                            (COLORREF)-1, 
                            3, 
                            3); 
            oldm = m; 
            fRepaintedMin = TRUE; 
        } 
 
        fRepaintedSec = FALSE; 
        if (gbRepaint || s != olds) 
        { 
            szWork[0] = gszFormatHMS[SEC_SEP_INDEX]; 
            szWork[1] = '0' + (char)(s / 10); 
            szWork[2] = '0' + (char)(s % 10); 
            EmbossedTextOut( 
                            hDC, 
                            ganPosX[SEC_SEP_INDEX], 
                            gnPosY, 
                            szWork, 
                            3, 
                            (COLORREF)-1, 
                            (COLORREF)-1, 
                            3, 
                            3); 
            olds = s; 
            fRepaintedSec = TRUE; 
        } 
 
        /* If we're doing a full repaint, then update the separators 
         */ 
        if (gbRepaint) 
            for (ii=0; ii < cb; ii++) 
                if (!isdigit(gszFormatHMS[ii])) 
                { 
                    if (SEC_SEP_INDEX == ii && fRepaintedSec) 
                        continue; 
 
                    if (MIN_SEP_INDEX == ii && fRepaintedMin) 
                        continue; 
 
                    EmbossedTextOut( 
                                    hDC, 
                                    ganPosX[ii], 
                                    gnPosY, 
                                    gszFormatHMS+ii, 
                                    1, 
                                    (COLORREF)-1, 
                                    (COLORREF)-1, 
                                    3, 
                                    3); 
                } 
    } 
     
    gbRepaint = FALSE; 
    SelectObject(hDC, hFont); 
} 
 
/***************************************************************************** 
* 
* TWnd_OnCreate 
* 
* Handle WM_CREATE message to time window. 
* 
* HWND hWnd                 - Window handle 
* CREATESTRUCT FAR* lpCreateStruct 
*                           - Pointer to creation parameters for the window. 
* 
* Returns TRUE on success. Returning FALSE will cause the window to be 
* destroyed and the application will exit. 
* 
* Just return TRUE so the window will be created. 
* 
*****************************************************************************/ 
BOOL NEAR PASCAL TWnd_OnCreate( 
    HWND                    hWnd, 
    CREATESTRUCT FAR*       lpCreateStruct) 
{ 
    return TRUE; 
} 
 
/***************************************************************************** 
* 
* TWnd_OnSize 
* 
* Handle WM_SIZE message to time window. 
* 
* HWND hWnd                 - Window handle 
* UINT state                - Some SIZE_xxx code indicating what type of 
*                             size operation this is. 
* int  cx, cy               - New x and y size of the window's client area. 
* 
* Get the new client rect into grcTWnd. 
* Destroy and recreate the font scaled to show the time at the correct size. 
* Force the time to fully repaint. 
* 
*****************************************************************************/ 
VOID NEAR PASCAL TWnd_OnSize( 
    HWND                    hWnd, 
    UINT                    state, 
    int                     cx, 
    int                     cy) 
{ 
    HDC                     hDC; 
     
    GetClientRect(hWnd, &grcTWnd); 
 
    if (ghFont != (HFONT)NULL) 
        DeleteObject(ghFont); 
 
    hDC = GetDC(hWnd); 
    ghFont = CreateScaledFont(hDC, 
                              &grcTWnd, 
                              (gnTimeFormat == IDS_TICKS) ? gszFormatTicks : gszFormatHMS, 
                              ganPosX, 
                              &gnPosY); 
    ReleaseDC(hWnd, hDC); 
 
    gbRepaint = TRUE; 
    InvalidateRect(hWnd, NULL, TRUE); 
} 
 
 
/***************************************************************************** 
* 
* TWnd_OnPaint 
* 
* Handle WM_PAINT message to time window. 
* 
* HWND hWnd                 - Window handle 
* 
* Repaint the 3D inset borders around the edge of the client area. 
* Repaint the time. 
* 
*****************************************************************************/ 
VOID NEAR PASCAL TWnd_OnPaint( HWND hWnd) { PAINTSTRUCT ps; HDC hDC; 
HBRUSH hBrOld; int nWidth; int nHeight; 
 
    RECT                    rc; 
 
    GetClientRect(hWnd, &rc); 
    nWidth  = rc.right; 
    nHeight = rc.bottom; 
     
    hDC = BeginPaint(hWnd, &ps); 
 
    hBrOld = (HBRUSH)SelectObject(hDC, GetStockObject(GRAY_BRUSH)); 
    PatBlt(hDC, 0, 0, 1, nHeight-1, PATCOPY); 
    PatBlt(hDC, 1, 0, nWidth-2, 1, PATCOPY); 
 
    SelectObject(hDC, GetStockObject(BLACK_BRUSH)); 
    PatBlt(hDC, 1, 1, 1, nHeight-3, PATCOPY); 
    PatBlt(hDC, 2, 1, nWidth-4, 1, PATCOPY); 
 
    SelectObject(hDC, GetStockObject(WHITE_BRUSH)); 
    PatBlt(hDC, rc.right-1, 0, 1, nHeight-1, PATCOPY); 
    PatBlt(hDC, 0, rc.bottom-1, nWidth, 1, PATCOPY); 
 
    SelectObject(hDC, GetStockObject(LTGRAY_BRUSH)); 
    PatBlt(hDC, rc.right-2, 1, 1, nHeight-2, PATCOPY); 
    PatBlt(hDC, 1, rc.bottom-2, nWidth-2, 1, PATCOPY); 
     
    SelectObject(hDC, hBrOld); 
 
    gbRepaint = TRUE; 
    PaintTime(hDC); 
 
    EndPaint(hWnd, &ps); 
} 
 
/***************************************************************************** 
* 
* TWnd_OnCommand 
* 
* Handle WM_COMMAND message to the time window. 
* 
* HWND hWnd                 - Window handle 
* int id                    - id of control or menu causing WM_COMMAND 
* HWND hwndCtl              - Window handle of child control, if any 
* UINT codeNotify           - Notification code if this message is from a 
*                             control. 
* 
* We will receive IDM_PLAY and IDM_STOP messages forwarded from the main 
* application window whenver playback starts or stops. Use these messages 
* to create or kill a timer which will be used to update the time. 
*  
*****************************************************************************/ 
VOID NEAR PASCAL TWnd_OnCommand( 
    HWND                    hWnd, 
    int                     id, 
    HWND                    hWndCtl, 
    UINT                    codeNotify) 
{ 
    switch(id) 
    { 
        case IDM_PLAY: 
            if (0 == gnTimerOn) 
            { 
                gnTimerOn++; 
                SetTimer(hWnd, TIMER_ID, TIMER_INTERVAL, 0); 
            } 
 
            UpdateWindow(hWnd); 
            break; 
 
        case IDM_STOP: 
            if (0 == gnTimerOn) 
            { 
                gnTimerOn--; 
                KillTimer(hWnd, TIMER_ID); 
            } 
             
            UpdateWindow(hWnd); 
            break; 
    } 
} 
 
/***************************************************************************** 
* 
* TWnd_OnDestroy 
* 
* Handle WM_DESTROY message to the time window. 
* 
* HWND hWnd                 - Window handle 
* 
* If we're being destroyed and the timer is still running, stop it. 
*  
*****************************************************************************/ 
VOID NEAR PASCAL TWnd_OnDestroy( 
    HWND                    hWnd) 
{ 
    if (gnTimerOn) 
    { 
        KillTimer(hWnd, TIMER_ID); 
    } 
} 
 
/***************************************************************************** 
* 
* TWnd_OnTimer 
* 
* Handle WM_TIMER message to the time window. 
* 
* HWND hWnd                 - Window handle 
* UINT id                   - Timer ID 
* 
* Update the time. 
*  
*****************************************************************************/ 
PRIVATE VOID NEAR PASCAL TWnd_OnTimer( 
    HWND                    hWnd, 
    UINT                    id) 
{ 
    HDC                     hDC; 
 
    hDC = GetDC(hWnd); 
    PaintTime(hDC); 
    ReleaseDC(hWnd, hDC); 
} 
 
/***************************************************************************** 
* 
* TWnd_WndProc 
* 
* Window procedure for main application window. 
* 
* HWND hWnd                 - Window handle 
* UINT msg                  - Message code 
* WPARAM wParam             - Message specific parameter 
* LPARAM lParam             - Message specific parameter 
* 
* Dispatch messages we care about to the appropriate handler, else just 
* call DefWindowProc. 
* 
* Note this use of message cracker macros from windowsx.h. Using these 
* macros will shield you from the differences between Win16 and Win32; 
* if your app is cross-compilable, you should use these and save yourself 
* some headaches! 
* 
*****************************************************************************/ 
LRESULT CALLBACK TWnd_WndProc( 
    HWND                    hWnd, 
    UINT                    msg, 
    WPARAM                  wParam, 
    LPARAM                  lParam) 
{ 
    switch( msg ) 
    { 
        HANDLE_MSG(hWnd, WM_CREATE,         TWnd_OnCreate); 
        HANDLE_MSG(hWnd, WM_SIZE,           TWnd_OnSize); 
        HANDLE_MSG(hWnd, WM_PAINT,          TWnd_OnPaint); 
        HANDLE_MSG(hWnd, WM_COMMAND,        TWnd_OnCommand); 
        HANDLE_MSG(hWnd, WM_DESTROY,        TWnd_OnDestroy); 
        HANDLE_MSG(hWnd, WM_TIMER,          TWnd_OnTimer); 
 
        default: 
            return DefWindowProc(hWnd, msg, wParam, lParam); 
    } 
 
    return 0; 
}