MAINWND.C
资源名称:MSDN_VC98.zip [点击查看]
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:30k
源码类别:
Windows编程
开发平台:
Visual 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.
- *
- ******************************************************************************
- *
- * MainWnd.C
- *
- * Message handlers and UI for the main window and associated controls
- *
- *****************************************************************************/
- #pragma warning(disable:4756)
- #define _INC_SHELLAPI
- #include <windows.h>
- #undef _INC_SHELLAPI
- #include <shellapi.h>
- #include <windowsx.h>
- #include <mmsystem.h>
- #include <commdlg.h>
- #include <commctrl.h>
- #include <ctype.h>
- #include "debug.h"
- #include "MIDIPlyr.H"
- #define BITMAP_COUNT 6 /* Number of buttons in bitmap */
- PRIVATE HWND ghWndToolbar = NULL;
- PRIVATE HWND ghWndStatus = NULL;
- PRIVATE HWND ghWndTime = NULL;
- PRIVATE char gszAppTitle[80] = "";
- PRIVATE int gnSB_TFPaneSize = 0;
- PRIVATE char gszOpenName[MAX_FILEPATH] = "";
- PRIVATE char gszOpenTitle[MAX_FILEPATH] = "";
- PRIVATE char BCODE gszFilter[] =
- "MIDI File (*.MID;*.RMI) *.MID;*.RMI "
- "All Files (*.*) *.* ";
- PRIVATE char BCODE gszDefExtension[] = "MID";
- PRIVATE BOOL gbAutoPlay = TRUE;
- PRIVATE UINT guDevice = 0;
- PRIVATE TBBUTTON gatbButton[] =
- {
- {0, -1, TBSTATE_ENABLED, TBSTYLE_SEP, 0, 0, 0, -1},
- {0, IDM_OPEN, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0, 0, -1},
- {0, -1, TBSTATE_ENABLED, TBSTYLE_SEP, 0, 0, 0, -1},
- {2, IDM_PLAY, 0, TBSTYLE_BUTTON, 0, 0, 0, -1},
- {3, IDM_STOP, 0, TBSTYLE_BUTTON, 0, 0, 0, -1},
- {4, IDM_PAUSE, 0, TBSTYLE_BUTTON, 0, 0, 0, -1},
- };
- #define BUTTON_COUNT (sizeof(gatbButton)/sizeof(gatbButton[0]))
- PRIVATE VOID FNLOCAL InitToolbar(HWND hWnd);
- PRIVATE VOID FNLOCAL InitStatusBar(HWND hWnd);
- PRIVATE VOID FNLOCAL ResizeStatusBar(HWND hWnd);
- PRIVATE VOID FNLOCAL SyncUI(HWND hWnd);
- PRIVATE VOID FNLOCAL SetOneAction(HWND hWnd, int nMenuID, BOOL fEnable);
- PRIVATE VOID FNLOCAL AttemptFileOpen(HWND hWnd);
- PRIVATE BOOL FNLOCAL PrerollAndWait(HWND hWnd);
- PRIVATE BOOL FNLOCAL MWnd_OnCreate(HWND hWnd, CREATESTRUCT FAR* lpCreateStruct);
- PRIVATE VOID FNLOCAL MWnd_OnGetMinMaxInfo(HWND hWnd, MINMAXINFO FAR* lpMinMaxInfo);
- PRIVATE VOID FNLOCAL MWnd_OnSize(HWND hWnd, UINT state, int cx, int cy);
- PRIVATE VOID FNLOCAL MWnd_OnPaint(HWND hWnd);
- PRIVATE VOID FNLOCAL MWnd_OnDropFiles(HWND hWnd, HDROP hDrop);
- PRIVATE VOID FNLOCAL MWnd_OnFileOpen(HWND hWnd);
- PRIVATE VOID FNLOCAL MWnd_OnCommandToggleChild(HWND hWnd, UINT id);
- PRIVATE VOID FNLOCAL MWnd_OnCommand(HWND hWnd, int id, HWND hWndCtl, UINT codeNotify);
- PRIVATE VOID FNLOCAL MWnd_OnDestroy(HWND hWnd);
- /*****************************************************************************
- *
- * InitToolbar
- *
- * Called to create the toolbar
- *
- * HWND hWnd - Application window which toolbar is a child of
- *
- * Create and show the toolbar window.
- *
- *****************************************************************************/
- PRIVATE VOID FNLOCAL InitToolbar(
- HWND hWnd)
- {
- ghWndToolbar = CreateToolbarEx(hWnd,
- WS_CHILD|WS_CLIPSIBLINGS|WS_CLIPCHILDREN,
- IDC_TOOLBAR,
- BITMAP_COUNT,
- ghInst,
- IDB_TOOLBAR,
- gatbButton,
- BUTTON_COUNT,
- 0, 0,
- 0, 0,
- sizeof(TBBUTTON));
- if (ghWndToolbar)
- ShowWindow(ghWndToolbar, SW_RESTORE);
- }
- /*****************************************************************************
- *
- * InitStatusBar
- *
- * Called to create the status bar
- *
- * HWND hWnd - Application window which status bar is a child of
- *
- * Create and show the status window.
- *
- *****************************************************************************/
- PRIVATE VOID FNLOCAL InitStatusBar(
- HWND hWnd)
- {
- HWND hWndDesktop;
- HFONT hFontStat;
- HDC hDC;
- UINT idx;
- SIZE size;
- ghWndStatus = CreateStatusWindow(WS_CHILD|SBARS_SIZEGRIP,
- "",
- hWnd,
- IDC_STATBAR);
- if (ghWndStatus)
- {
- hWndDesktop = GetDesktopWindow();
- hFontStat = (HFONT)SendMessage(ghWndStatus, WM_GETFONT, 0, 0L);
- hDC = GetDC(hWndDesktop);
- if (hFontStat != (HFONT)NULL && hDC != (HDC)NULL)
- {
- hFontStat = (HFONT)SelectObject(hDC, hFontStat);
- gnSB_TFPaneSize = 0;
- for (idx = 0; idx < N_TIME_FORMATS; idx++)
- {
- GetTextExtentPoint(hDC,
- grgszTimeFormats[idx],
- lstrlen(grgszTimeFormats[idx]),
- &size);
- gnSB_TFPaneSize = max(gnSB_TFPaneSize, size.cx);
- }
- SelectObject(hDC, hFontStat);
- gnSB_TFPaneSize *= 2;
- }
- if (hDC != (HDC)NULL)
- ReleaseDC(hWndDesktop, hDC);
- ResizeStatusBar(hWnd);
- FORWARD_WM_COMMAND(hWnd, gnTimeFormat, 0, 0, SendMessage);
- ShowWindow(ghWndStatus, SW_RESTORE);
- }
- }
- /*****************************************************************************
- *
- * ResizeStatusBar
- *
- * Force the status bar to resize to fit in the main window
- *
- * HWND hWnd - Application window which status bar is a child of
- *
- * Figure out the pane sizes and send a message to the status bar to set them.
- *
- *****************************************************************************/
- PRIVATE VOID FNLOCAL ResizeStatusBar(
- HWND hWnd)
- {
- RECT rc;
- int rnPaneEdge[SB_N_PANES];
- GetClientRect(hWnd, &rc);
- /* SB_SETPARTS expects:
- ** wParam == Number of panes in status bar.
- ** lParam == Pointer to an array of int's indicating the right-hand
- ** coordinate of each pane.
- */
- rnPaneEdge[SB_PANE_STATE] = rc.right - gnSB_TFPaneSize;
- rnPaneEdge[SB_PANE_TFMT] = -1;
- SendMessage(ghWndStatus,
- SB_SETPARTS,
- SB_N_PANES,
- (DWORD)(LPINT)(rnPaneEdge));
- }
- /*****************************************************************************
- *
- * SyncUI
- *
- * Bring all UI elements into sync with the state of the sequencer
- *
- * HWND hWnd - Application main window
- *
- * Build a flag word of the actions which are allowed from the current state.
- * Set the menu items and toolbar buttons for each action appropriately.
- * Show the current state as a string in the status bar.
- * Depress the pause button if the sequencer is paused.
- * Cause the time window to update.
- *
- *****************************************************************************/
- #define SUI_F_CANPLAY 0x0001
- #define SUI_F_CANPAUSE 0x0002
- #define SUI_F_CANSTOP 0x0004
- #define SUI_F_CANSELDEVICE 0x0008
- PRIVATE VOID FNLOCAL SyncUI(
- HWND hWnd)
- {
- WORD wActionFlags;
- UINT uState;
- char szState[40];
- BOOL fPress;
- wActionFlags = 0;
- uState = SEQ_S_NOFILE;
- if (gpSeq != NULL)
- {
- uState = gpSeq->uState;
- switch (uState)
- {
- case SEQ_S_NOFILE:
- wActionFlags = SUI_F_CANSELDEVICE;
- break;
- case SEQ_S_OPENED:
- case SEQ_S_PREROLLED:
- wActionFlags = SUI_F_CANPLAY|SUI_F_CANSELDEVICE;
- break;
- case SEQ_S_PAUSED:
- case SEQ_S_PLAYING:
- wActionFlags = SUI_F_CANPAUSE|SUI_F_CANSTOP;
- break;
- case SEQ_S_PREROLLING:
- case SEQ_S_STOPPING:
- // assert(0);
- wActionFlags = 0;
- break;
- }
- }
- fPress = (gpSeq->uState == SEQ_S_PAUSED);
- SendMessage(ghWndToolbar,
- TB_PRESSBUTTON,
- IDM_PAUSE,
- fPress);
- SetOneAction(hWnd, IDM_PLAY, wActionFlags & SUI_F_CANPLAY);
- SetOneAction(hWnd, IDM_PAUSE, wActionFlags & SUI_F_CANPAUSE);
- SetOneAction(hWnd, IDM_STOP, wActionFlags & SUI_F_CANSTOP);
- EnableMenuItem(GetMenu(hWnd),
- POS_PLAYTHRU,
- MF_BYPOSITION|((wActionFlags & SUI_F_CANSELDEVICE) ? MF_ENABLED : MF_DISABLED));
- DrawMenuBar(hWnd);
- szState[0] = ' ';
- LoadString(ghInst, IDS_STATES + uState, szState, sizeof(szState));
- SendMessage(ghWndStatus, SB_SETTEXT, SB_PANE_STATE, (LPARAM)(LPSTR)szState);
- InvalidateRect(ghWndTime, NULL, TRUE);
- }
- /*****************************************************************************
- *
- * SetOneAction
- *
- * Update the state of one action in both the toolbar and action menu
- *
- * HWND hWnd - Application main window
- * int nMenuID - Menu ID of action
- * BOOL fEnable - Enable or disable this action
- *
- *****************************************************************************/
- PRIVATE VOID FNLOCAL SetOneAction(
- HWND hWnd,
- int nMenuID,
- BOOL fEnable)
- {
- EnableMenuItem(GetMenu(hWnd),
- nMenuID,
- MF_BYCOMMAND|(fEnable ? MF_ENABLED : MF_DISABLED));
- SendMessage(ghWndToolbar,
- TB_ENABLEBUTTON,
- nMenuID,
- (DWORD)fEnable);
- }
- /*****************************************************************************
- *
- * AttemptFileOpen
- *
- * Try to open the given file in the sequencer.
- *
- * HWND hWnd - Application main window
- *
- * Stop and close the current file.
- * Open the new file.
- * Preroll the new file.
- * Set the title test for the main window.
- * Call SyncUI to update available actions.
- *
- *****************************************************************************/
- PRIVATE VOID FNLOCAL AttemptFileOpen(
- HWND hWnd)
- {
- MMRESULT mmrc;
- PSTR pStrFile = gszUntitled;
- /* Stop, close, etc. if we're still playing
- */
- DPF(1, "AttemptFileOpen: Calling seqStop(); state = %u", gpSeq->uState);
- mmrc = seqStop(gpSeq);
- if (mmrc != MMSYSERR_NOERROR)
- {
- Error(hWnd, IDS_STOPFAILED, mmrc);
- return;
- }
- DPF(1, "Calling seqCloseFile(); state = %u", gpSeq->uState);
- seqCloseFile(gpSeq);
- DPF(1, "Calling seqOpenFile(); state = %u", gpSeq->uState);
- /* Open new file
- */
- gpSeq->pstrFile = gszOpenName;
- mmrc = seqOpenFile(gpSeq);
- if (mmrc != MMSYSERR_NOERROR)
- {
- Error(hWnd, IDS_OPENFAILED, mmrc);
- return;
- }
- pStrFile = gszOpenTitle;
- wsprintf(gszAppTitle, gszAppTitleMask, (LPSTR)pStrFile);
- SetWindowText(hWnd, gszAppTitle);
- SyncUI(hWnd);
- }
- /*****************************************************************************
- *
- * PrerollAndWait
- *
- * Prerolls the sequencer using the current device ID and file.
- *
- * HWND hWnd - Current window
- *
- * Just call preroll and loop processing messages until done.
- *
- *****************************************************************************/
- PRIVATE BOOL FNLOCAL PrerollAndWait(
- HWND hWnd)
- {
- PREROLL preroll;
- MMRESULT mmrc;
- preroll.tkBase = 0;
- preroll.tkEnd = gpSeq->tkLength;
- gpSeq->uDeviceID = guDevice;
- if (MMSYSERR_NOERROR != (mmrc = seqPreroll(gpSeq, &preroll)))
- {
- Error(hWnd, IDS_PREROLLFAILED, mmrc);
- return FALSE;
- }
- return TRUE;
- }
- /*****************************************************************************
- *
- * MWnd_OnCreate
- *
- * Handle WM_CREATE message to main application 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.
- *
- * Set the default time format.
- * Create the tool and status bars.
- * Create the time window as a child of the main app window and show it.
- * Set the main window's title to show no document ('Untitled').
- * Accept drag/drop files.
- * Call SyncUI to update the enable status of the toolbar and menu items.
- *
- *****************************************************************************/
- PRIVATE BOOL FNLOCAL MWnd_OnCreate(
- HWND hWnd,
- CREATESTRUCT FAR* lpCreateStruct)
- {
- HMENU hMenu;
- HMENU hMenuOptions;
- HMENU hMenuPlayThru;
- UINT cDevs;
- UINT idx;
- RECT rc;
- MIDIOUTCAPS moutCaps;
- gnTimeFormat = IDS_TF_FIRST;
- InitToolbar(hWnd);
- InitStatusBar(hWnd);
- hMenu = GetMenu(hWnd);
- hMenuOptions = GetSubMenu(hMenu, POS_OPTIONS);
- hMenuPlayThru = GetSubMenu(hMenu, POS_PLAYTHRU);
- AppendMenu(hMenuOptions, MF_SEPARATOR, 0, NULL);
- for (idx = 0; idx < N_TIME_FORMATS; idx++)
- {
- AppendMenu(hMenuOptions,
- MF_ENABLED|MF_STRING,
- IDS_TF_FIRST + idx,
- grgszTimeFormats[idx]);
- }
- cDevs = midiOutGetNumDevs();
- if (cDevs)
- AppendMenu(hMenuPlayThru, MF_SEPARATOR, 0, NULL);
- for (idx = 0; idx < cDevs; idx++)
- {
- if (midiOutGetDevCaps(idx, &moutCaps, sizeof(moutCaps)) == MMSYSERR_NOERROR)
- {
- AppendMenu(hMenuPlayThru,
- MF_ENABLED|MF_STRING,
- IDM_DEVICES + idx,
- moutCaps.szPname);
- }
- }
- CheckMenuItem(hMenu, IDM_TOOLBAR, MF_BYCOMMAND|MF_CHECKED);
- CheckMenuItem(hMenu, IDM_STATUS, MF_BYCOMMAND|MF_CHECKED);
- CheckMenuItem(hMenu, IDM_AUTOPLAY,MF_BYCOMMAND|MF_CHECKED);
- CheckMenuItem(hMenu, gnTimeFormat,MF_BYCOMMAND|MF_CHECKED);
- CheckMenuItem(hMenu, IDM_DEVICES, MF_BYCOMMAND|MF_CHECKED);
- GetClientRect(hWnd, &rc);
- ghWndTime = CreateWindow(
- gszTWndClass,
- NULL,
- WS_CHILD,
- rc.left, rc.top,
- rc.right-rc.left, rc.bottom-rc.top,
- hWnd,
- NULL,
- lpCreateStruct->hInstance,
- NULL);
- ShowWindow(ghWndTime, SW_RESTORE);
- wsprintf(gszAppTitle, gszAppTitleMask, (LPSTR)gszUntitled);
- SetWindowText(hWnd, gszAppTitle);
- DragAcceptFiles(hWnd, TRUE);
- SyncUI(hWnd);
- return TRUE;
- }
- /*****************************************************************************
- *
- * MWnd_OnGetMinMaxSize
- *
- * Handle WM_GETMINMAXSIZE message to main application window.
- *
- * HWND hWnd - Window handle
- * MINMAXINFO FAR* lpMinMaxInfo
- * - Pointer to min/max tracking information
- *
- * This message is sent to a window before resize tracking begins. The
- * lpMinMaxInfo structure contains the minimum and maximum x and y values
- * the window can be resized to.
- *
- * We don't allow resizing small enough to cause the status bar and toolbar
- * to overlap so they don't try to draw over each other.
- *
- *****************************************************************************/
- PRIVATE VOID FNLOCAL MWnd_OnGetMinMaxInfo(
- HWND hWnd,
- MINMAXINFO FAR* lpMinMaxInfo)
- {
- RECT rc;
- GetWindowRect(hWnd, &rc);
- /* Only go small enough that our client area after children is zero.
- */
- lpMinMaxInfo->ptMinTrackSize.y =
- (rc.bottom - rc.top) -
- (grcTWnd.bottom - grcTWnd.top);
- }
- /*****************************************************************************
- *
- * MWnd_OnSize
- *
- * Handle WM_SIZE message to main application 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 area.
- * Adjust the client area for the toolbar and status bar if they exist.
- * Make sure the client area isn't a negative height and adjust if it is.
- * Resize the time window to fit in our new client area.
- * Forward the WM_SIZE to the time window so it can resize its font.
- *
- *****************************************************************************/
- PRIVATE VOID FNLOCAL MWnd_OnSize(
- HWND hWnd,
- UINT state,
- int cx,
- int cy)
- {
- RECT rc;
- RECT rcClient;
- GetClientRect(hWnd, &rcClient);
- if (ghWndToolbar != NULL)
- {
- /* Cause the toolbar to be aware of the size change
- */
- FORWARD_WM_SIZE(ghWndToolbar, SIZE_RESTORED, 0, 0, SendMessage);
- GetWindowRect(ghWndToolbar, &rc);
- rcClient.top += (rc.bottom - rc.top);
- }
- if (ghWndStatus != NULL)
- {
- ResizeStatusBar(hWnd);
- /* Cause the status bar to be aware of the size change
- */
- FORWARD_WM_SIZE(ghWndStatus, SIZE_RESTORED, 0, 0, SendMessage);
- GetWindowRect(ghWndStatus, &rc);
- rcClient.bottom -= (rc.bottom - rc.top);
- }
- /* Do we need to resize entire window so the tool/status bars
- ** don't overlap? (The only case where this can happen is
- ** on creation of one of the two -- we set minimum tracking so
- ** a user can't manually resize the window to cause this
- ** condition).
- */
- if (rcClient.bottom < rcClient.top)
- {
- GetWindowRect(hWnd, &rc);
- SetWindowPos(hWnd,
- (HWND)NULL,
- 0, 0,
- rc.right - rc.left + 1,
- rc.bottom - rc.top + 1 - rcClient.top - rcClient.bottom,
- SWP_NOACTIVATE|SWP_NOMOVE|SWP_NOZORDER);
- }
- SetWindowPos(ghWndTime,
- (HWND)NULL,
- rcClient.left,
- rcClient.top,
- rcClient.right - rcClient.left,
- rcClient.bottom - rcClient.top,
- SWP_NOACTIVATE|SWP_NOZORDER);
- FORWARD_WM_SIZE(ghWndTime, SIZE_RESTORED, 0, 0, SendMessage);
- }
- /*****************************************************************************
- *
- * MWnd_OnPaint
- *
- * Handle WM_PAINT message to main application window.
- *
- * HWND hWnd - Window handle
- *
- * Just do a BeginPaint/EndPaint pair so USER will mark the area
- * as valid. All the real work of painting the time is done
- * by the WM_PAINT handler for the time window.
- *
- *****************************************************************************/
- PRIVATE VOID FNLOCAL MWnd_OnPaint(
- HWND hWnd)
- {
- PAINTSTRUCT ps;
- HDC hDC;
- hDC = BeginPaint(hWnd, &ps);
- EndPaint(hWnd, &ps);
- }
- /*****************************************************************************
- *
- * MWnd_OnDropFiles
- *
- * Handle WM_DROPFILES message to main application window.
- *
- * HWND hWnd - Window handle
- * HDROP hDrop - Handle to dropped file information
- *
- * Get the 0th filename and free the drop handle.
- * Extract the file title from the full pathname.
- * Open the file.
- * If we opened successfully, start playback by forwarding a WM_COMMAND
- * of IDM_PLAY to the main window.
- *
- *****************************************************************************/
- PRIVATE VOID FNLOCAL MWnd_OnDropFiles(
- HWND hWnd,
- HDROP hDrop)
- {
- PSTR pStr;
- /* For multiple selections, we only accept the first file
- */
- DragQueryFile(hDrop, 0, gszOpenName, sizeof(gszOpenName));
- DragFinish(hDrop);
- /* We don't get OpenTitle like we do from GetOpenFileName; need to
- ** figure this out for ourselves
- */
- pStr = gszOpenName + lstrlen(gszOpenName) - 1;
- while (pStr >= gszOpenName && *pStr != '/' && *pStr != '\' && *pStr != ':')
- pStr--;
- pStr++;
- lstrcpy(gszOpenTitle, pStr);
- AttemptFileOpen(hWnd);
- if (gbAutoPlay && gpSeq->uState == SEQ_S_OPENED)
- FORWARD_WM_COMMAND(hWnd, IDM_PLAY, (HWND)NULL, 0, SendMessage);
- }
- /*****************************************************************************
- *
- * MWnd_OnFileOpen
- *
- * Handle WM_COMMAND/IDM_OPEN message to main application window.
- *
- * HWND hWnd - Window handle
- *
- * Fill in the OPENFILENAME struct and call GetOpenFileName.
- * If not canceled, try to open the file.
- *
- *****************************************************************************/
- PRIVATE VOID FNLOCAL MWnd_OnFileOpen(
- HWND hWnd)
- {
- OPENFILENAME ofn;
- *gszOpenName = ' ';
- ofn.lStructSize = sizeof(OPENFILENAME);
- ofn.hwndOwner = hWnd;
- ofn.lpstrFilter = gszFilter;
- ofn.lpstrCustomFilter = (LPSTR)NULL;
- ofn.nMaxCustFilter = 0L;
- ofn.nFilterIndex = 1L;
- ofn.lpstrFile = gszOpenName;
- ofn.nMaxFile = MAX_FILEPATH;
- ofn.lpstrFileTitle = gszOpenTitle;
- ofn.nMaxFileTitle = MAX_FILEPATH;
- ofn.lpstrTitle = (LPSTR)NULL;
- ofn.lpstrInitialDir = (LPSTR)NULL;
- ofn.Flags = OFN_HIDEREADONLY|OFN_FILEMUSTEXIST;
- ofn.nFileOffset = 0;
- ofn.nFileExtension = 0;
- ofn.lpstrDefExt = gszDefExtension;
- if (!GetOpenFileName(&ofn))
- return;
- AttemptFileOpen(hWnd);
- }
- /*****************************************************************************
- *
- * MWnd_OnCommandToggleChild
- *
- * Handle WM_COMMAND message of toggle tool or status bar to main application
- * window.
- *
- * HWND hWnd - Window handle
- * UINT id - Control id of menu selection; either
- * IDM_TOOLBAR or IDM_STATUS
- *
- * Get the current menu item check state.
- * Destroy or create the child as needed.
- * Send a WM_SIZE to the main window so client area will be recalculated.
- * Toggle the menu item check state.
- *
- *****************************************************************************/
- PRIVATE VOID FNLOCAL MWnd_OnCommandToggleChild(
- HWND hWnd,
- UINT id)
- {
- HMENU hMenu;
- UINT uState;
- HWND* phWnd;
- phWnd = (id == IDM_TOOLBAR) ? &ghWndToolbar : &ghWndStatus;
- hMenu = GetMenu(hWnd);
- uState = GetMenuState(hMenu, id, MF_BYCOMMAND);
- if (uState & MF_CHECKED)
- {
- DestroyWindow(*phWnd);
- *phWnd = NULL;
- }
- else
- {
- if (id == IDM_TOOLBAR)
- InitToolbar(hWnd);
- else
- InitStatusBar(hWnd);
- }
- SendMessage(hWnd, WM_SIZE, 0, 0L);
- uState ^= MF_CHECKED;
- uState &= MF_CHECKED;
- CheckMenuItem(hMenu, id, MF_BYCOMMAND|uState);
- SyncUI(hWnd);
- }
- /*****************************************************************************
- *
- * MWnd_OnCommand
- *
- * Handle WM_COMMAND message to main application 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.
- *
- * For a press of the toolbar buttons or their menu equivalents, just load
- * a resource string and display it in the status bar.
- *
- * For an exit request, send ourselves a WM_CLOSE message.
- *
- *****************************************************************************/
- PRIVATE VOID FNLOCAL MWnd_OnCommand(
- HWND hWnd,
- int id,
- HWND hWndCtl,
- UINT codeNotify)
- {
- HMENU hMenu;
- int nIdxFormat;
- LPSTR lpstr;
- if (id >= IDS_TF_FIRST && id <= IDS_TF_LAST)
- {
- if (NULL != ghWndStatus)
- {
- nIdxFormat = id - IDS_TF_FIRST;
- lpstr = (LPSTR)(grgszTimeFormats[nIdxFormat]);
- SendMessage(ghWndStatus,
- SB_SETTEXT,
- SB_PANE_TFMT,
- (LPARAM)lpstr);
- }
- hMenu = GetMenu(hWnd);
- CheckMenuItem(hMenu, gnTimeFormat, MF_UNCHECKED|MF_BYCOMMAND);
- CheckMenuItem(hMenu, id, MF_CHECKED|MF_BYCOMMAND);
- gnTimeFormat = id;
- /* Force time window to update font and repaint entire time string
- */
- if(ghWndTime) // for when WM_COMMAND is called before WM_CREATE
- FORWARD_WM_SIZE(ghWndTime, SIZE_RESTORED, 0, 0, SendMessage);
- }
- else if (id >= IDM_DEVMIN && id <= IDM_DEVMAX)
- {
- hMenu = GetMenu(hWnd);
- CheckMenuItem(hMenu, guDevice + IDM_DEVICES, MF_UNCHECKED|MF_BYCOMMAND);
- guDevice = id - IDM_DEVICES;
- CheckMenuItem(hMenu, guDevice + IDM_DEVICES, MF_CHECKED|MF_BYCOMMAND);
- }
- else switch(id)
- {
- case IDM_OPEN:
- MWnd_OnFileOpen(hWnd);
- break;
- case IDM_TOOLBAR:
- case IDM_STATUS:
- MWnd_OnCommandToggleChild(hWnd, id);
- break;
- case IDM_AUTOPLAY:
- gbAutoPlay = !gbAutoPlay;
- CheckMenuItem(GetMenu(hWnd),
- IDM_AUTOPLAY,
- MF_BYCOMMAND|(gbAutoPlay ? MF_CHECKED : MF_UNCHECKED));
- break;
- case IDM_PLAY:
- FORWARD_WM_COMMAND(ghWndTime, IDM_PLAY, 0, 0, SendMessage);
- if (gpSeq->uState != SEQ_S_OPENED)
- DPF(1, "IDM_PLAY: State %u", gpSeq->uState);
- if (PrerollAndWait(hWnd))
- seqStart(gpSeq);
- SyncUI(hWnd);
- break;
- case IDM_STOP:
- FORWARD_WM_COMMAND(ghWndTime, IDM_STOP, 0, 0, SendMessage);
- seqStop(gpSeq);
- SyncUI(hWnd);
- break;
- case IDM_PAUSE:
- if (gpSeq->uState == SEQ_S_PAUSED)
- {
- seqRestart(gpSeq);
- }
- else
- {
- seqPause(gpSeq);
- }
- SyncUI(hWnd);
- break;
- case IDM_SYNCUI:
- SyncUI(hWnd);
- break;
- case IDM_EXIT:
- SendMessage(hWnd, WM_CLOSE, 0, 0L);
- break;
- }
- }
- /*****************************************************************************
- *
- * MWnd_OnDestroy
- *
- * Handle WM_DESTROY message to main application window.
- *
- * HWND hWnd - Window handle
- *
- * Our main application window has been closed. PostQuitMessage so the main
- * message loop will exit and the app can terminate.
- *
- *****************************************************************************/
- PRIVATE VOID FNLOCAL MWnd_OnDestroy(
- HWND hWnd)
- {
- seqStop(gpSeq);
- PostQuitMessage(0);
- }
- /*****************************************************************************
- *
- * MWnd_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 MWnd_WndProc(
- HWND hWnd,
- UINT msg,
- WPARAM wParam,
- LPARAM lParam)
- {
- switch( msg )
- {
- HANDLE_MSG(hWnd, WM_CREATE, MWnd_OnCreate);
- HANDLE_MSG(hWnd, WM_GETMINMAXINFO, MWnd_OnGetMinMaxInfo);
- HANDLE_MSG(hWnd, WM_SIZE, MWnd_OnSize);
- HANDLE_MSG(hWnd, WM_PAINT, MWnd_OnPaint);
- HANDLE_MSG(hWnd, WM_DROPFILES, MWnd_OnDropFiles);
- HANDLE_MSG(hWnd, WM_COMMAND, MWnd_OnCommand);
- HANDLE_MSG(hWnd, WM_DESTROY, MWnd_OnDestroy);
- case MMSG_DONE:
- FORWARD_WM_COMMAND(ghWndTime, IDM_STOP, 0, 0, SendMessage);
- if (gpSeq->uState != SEQ_S_OPENED)
- DPF(1, "MMSG_DONE and state %u", gpSeq->uState);
- SyncUI(hWnd);
- break;
- default:
- return DefWindowProc(hWnd, msg, wParam, lParam);
- }
- return 0;
- }