home *** CD-ROM | disk | FTP | other *** search
- /**************************************************************************
- *
- * 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.
- *
- **************************************************************************/
-
- /* midimon.c - WinMain() and WndProc() functions for MIDIMon, along
- * with some initialization and error reporting functions.
- *
- * MIDIMon is a Windows with Multimedia application that records and displays
- * incoming MIDI information. It uses a low-level callback function to
- * get timestamped MIDI input. The callback function puts the incoming
- * MIDI event information (source device, timestamp, and raw MIDI
- * data) in a circular input buffer and notifies the application by posting
- * a MM_MIDIINPUT message. When the application processes the MM_MIDIINPUT
- * message, it removes the MIDI event from the input buffer and puts it in
- * a display buffer. Information in the display buffer is converted to
- * text and displayed in a scrollable window. Incoming MIDI data can be sent
- * to the MIDI Mapper if the user chooses. Filtering is provided for the
- * display buffer, but not for data sent to the Mapper.
- *
-
- */
-
- #include <windows.h>
- #include <mmsystem.h>
- #include <stdio.h>
- #include "midimon.h"
- #include "about.h"
- #include "circbuf.h"
- #include "display.h"
- #include "prefer.h"
- #include "instdata.h"
- #include "callback.h"
- #include "filter.h"
-
- HANDLE hInst; // Instance handle for application
- char szAppName[20]; // Application name
- HWND hMainWnd; // Main window handle
- HMIDIOUT hMapper = 0; // Handle to MIDI Mapper
- UINT wNumDevices = 0; // Number of MIDI input devices opened
- BOOL bRecordingEnabled = 1; // Enable/disable recording flag
- int nNumBufferLines = 0; // Number of lines in display buffer
- RECT rectScrollClip; // Clipping rectangle for scrolling
-
- LPCIRCULARBUFFER lpInputBuffer; // Input buffer structure
- LPDISPLAYBUFFER lpDisplayBuffer; // Display buffer structure
- PREFERENCES preferences; // User preferences structure
- EVENT incomingEvent; // Incoming MIDI event structure
-
- MIDIINCAPS midiInCaps[MAX_NUM_DEVICES]; // Device capabilities structures
- HMIDIIN hMidiIn[MAX_NUM_DEVICES]; // MIDI input device handles
-
- // Callback instance data pointers
- LPCALLBACKINSTANCEDATA lpCallbackInstanceData[MAX_NUM_DEVICES];
-
- // Display filter structure
- FILTER filter = {
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0
- };
-
- // Virtual key to scroll message translation structure
- KEYTOSCROLL keyToScroll [] = {
- VK_HOME, WM_VSCROLL, SB_TOP,
- VK_END, WM_VSCROLL, SB_BOTTOM,
- VK_PRIOR, WM_VSCROLL, SB_PAGEUP,
- VK_NEXT, WM_VSCROLL, SB_PAGEDOWN,
- VK_UP, WM_VSCROLL, SB_LINEUP,
- VK_DOWN, WM_VSCROLL, SB_LINEDOWN,
- VK_LEFT, WM_HSCROLL, SB_LINEUP,
- VK_RIGHT, WM_HSCROLL, SB_LINEDOWN
- };
-
- #define NUMKEYS (sizeof (keyToScroll) / sizeof (keyToScroll[0]))
-
-
- //
- /* WinMain - Entry point for MIDIMon.
- */
- int PASCAL WinMain(hInstance,hPrevInstance,lpszCmdLine,cmdShow)
- HANDLE hInstance,hPrevInstance;
- LPSTR lpszCmdLine;
- int cmdShow;
- {
- MSG msg;
- UINT wRtn;
- PREFERENCES preferences;
- char szErrorText[256];
- unsigned int i;
-
- hInst = hInstance;
-
- /* Get preferred user setup.
- */
- getPreferences(&preferences);
-
- /* Initialize application.
- */
- LoadString(hInstance, IDS_APPNAME, szAppName, sizeof(szAppName));
- if (hPrevInstance || !InitFirstInstance(hInstance))
- return 0;
-
- /* Create a display window.
- */
- hMainWnd = CreateWindow(szAppName,
- szAppName,
- WS_OVERLAPPEDWINDOW | WS_HSCROLL | WS_VSCROLL,
- preferences.iInitialX,
- preferences.iInitialY,
- preferences.iInitialW,
- preferences.iInitialH,
- (HWND)NULL,
- (HMENU)NULL,
- hInstance,
- (LPSTR)NULL);
-
- if (!hMainWnd)
- return 1;
-
- /* Hide scroll bars for now.
- */
- SetScrollRange(hMainWnd, SB_VERT, 0, 0, FALSE);
- SetScrollRange(hMainWnd, SB_HORZ, 0, 0, FALSE);
-
- /* Show the display window.
- */
- ShowWindow(hMainWnd, cmdShow);
- UpdateWindow(hMainWnd);
-
- /* Get the number of MIDI input devices. Then get the capabilities of
- * each device. We don't use the capabilities information right now,
- * but we could use it to report the name of the device that received
- * each MIDI event.
- */
- wNumDevices = midiInGetNumDevs();
- if (!wNumDevices) {
- Error(GetStringRes(IDS_NOMIDIIN));
- PostQuitMessage(0);
- }
- for (i=0; (i<wNumDevices) && (i<MAX_NUM_DEVICES); i++) {
- wRtn = midiInGetDevCaps(i, (LPMIDIINCAPS) &midiInCaps[i],
- sizeof(MIDIINCAPS));
- if(wRtn) {
- midiInGetErrorText(wRtn, (LPSTR)szErrorText,
- sizeof(szErrorText));
- Error(szErrorText);
- Error("midiInGetDevCaps");
- }
- }
-
- /* Allocate a circular buffer for low-level MIDI input. This buffer
- * is filled by the low-level callback function and emptied by the
- * application when it receives MM_MIDIINPUT messages.
- */
- lpInputBuffer = AllocCircularBuffer(
- (DWORD)(INPUT_BUFFER_SIZE * sizeof(EVENT)));
- if (lpInputBuffer == NULL) {
- Error(GetStringRes(IDS_NOMEM_IBUF));
- return 1;
- }
-
- /* Allocate a display buffer. Incoming events from the circular input
- * buffer are put into this buffer for display.
- */
- lpDisplayBuffer = AllocDisplayBuffer((DWORD)(DISPLAY_BUFFER_SIZE));
- if (lpDisplayBuffer == NULL) {
- Error(GetStringRes(IDS_NOMEM_DBUF));
- FreeCircularBuffer(lpInputBuffer);
- return 1;
- }
-
- /* Open all MIDI input devices after allocating and setting up
- * instance data for each device. The instance data is used to
- * pass buffer management information between the application and
- * the low-level callback function. It also includes a device ID,
- * a handle to the MIDI Mapper, and a handle to the application's
- * display window, so the callback can notify the window when input
- * data is available. A single callback function is used to service
- * all opened input devices.
- */
- for (i=0; (i<wNumDevices) && (i<MAX_NUM_DEVICES); i++)
- {
- if ((lpCallbackInstanceData[i] = AllocCallbackInstanceData()) == NULL)
- {
- Error(GetStringRes(IDS_NOMEM));
- FreeCircularBuffer(lpInputBuffer);
- FreeDisplayBuffer(lpDisplayBuffer);
- return 1;
- }
- lpCallbackInstanceData[i]->hWnd = hMainWnd;
- lpCallbackInstanceData[i]->dwDevice = i;
- lpCallbackInstanceData[i]->lpBuf = lpInputBuffer;
- lpCallbackInstanceData[i]->hMapper = hMapper;
-
- wRtn = midiInOpen((LPHMIDIIN)&hMidiIn[i],
- i,
- (DWORD)midiInputHandler,
- (DWORD)lpCallbackInstanceData[i],
- CALLBACK_FUNCTION);
- if(wRtn)
- {
- FreeCallbackInstanceData(lpCallbackInstanceData[i]);
- midiInGetErrorText(wRtn, (LPSTR)szErrorText, sizeof(szErrorText));
- Error(szErrorText);
- wsprintf(szErrorText, "midiInOpen(%u)", i);
- Error(szErrorText);
- }
- }
-
- /* Start MIDI input.
- */
- for (i=0; (i<wNumDevices) && (i<MAX_NUM_DEVICES); i++) {
- if (hMidiIn[i])
- midiInStart(hMidiIn[i]);
- }
-
- /* Standard Windows message processing loop. We don't drop out of
- * this loop until the user quits the application.
- */
- while (GetMessage(&msg, NULL, 0, 0)) {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
-
- /* Stop, reset, close MIDI input. Free callback instance data.
- */
- for (i=0; (i<wNumDevices) && (i<MAX_NUM_DEVICES); i++) {
- if (hMidiIn[i]) {
- midiInStop(hMidiIn[i]);
- midiInReset(hMidiIn[i]);
- midiInClose(hMidiIn[i]);
- FreeCallbackInstanceData(lpCallbackInstanceData[i]);
- }
- }
-
- /* Close the MIDI Mapper, if it's open.
- */
- if (hMapper)
- midiOutClose(hMapper);
-
- /* Free input and display buffers.
- */
- FreeCircularBuffer(lpInputBuffer);
- FreeDisplayBuffer(lpDisplayBuffer);
-
- return (msg.wParam);
- }
-
- //
- /* WndProc - Main window procedure function.
- */
- LRESULT FAR PASCAL WndProc(
- HWND hWnd,
- UINT message,
- WPARAM wParam,
- LPARAM lParam)
- {
- PAINTSTRUCT ps;
- HFONT hFont;
- HBRUSH hBrush;
- //!! HPEN hPen;
- HDC hDC;
- TEXTMETRIC tm;
- static BOOL bWindowCreated = 0;
- static int wChar, hChar;
- static int maxClientWidth;
- static int wClient, hClient;
- static int nVscrollMax = 0;
- static int nHscrollMax = 0;
- static int nVscrollPos = 0;
- static int nHscrollPos = 0;
- static int nNumCharsPerLine = 0;
- static int nNumDisplayLines = 0;
- static int nNumDisplayChars = 0;
- BOOL bNeedToUpdate = FALSE;
- int nVscrollInc, nHscrollInc;
- int nPaintBeg, nPaintEnd;
- int i;
- SIZE size;
-
- char szDisplayTextBuffer[120];
-
- switch(message)
- {
- case WM_CREATE:
- hDC = GetDC(hWnd);
-
- /* Set the font we want to use.
- */
- hFont = GetStockObject(SYSTEM_FIXED_FONT);
- SelectObject(hDC, hFont);
-
- /* Get text metrics and calculate the number of characters
- * per line and the maximum width required for the client area.
- */
- GetTextMetrics(hDC, &tm);
- wChar = tm.tmAveCharWidth;
- hChar = tm.tmHeight + tm.tmExternalLeading;
- nNumCharsPerLine = strlen(GetStringRes(IDS_LABEL)) - 1;
-
- GetTextExtentPoint(hDC,
- szDisplayTextBuffer,
- sprintf(szDisplayTextBuffer, GetStringRes(IDS_LABEL)),
- &size);
- maxClientWidth = size.cx;
-
- ReleaseDC(hWnd, hDC);
-
- bWindowCreated = 1;
- break;
-
- case WM_SIZE:
- hClient = (int)HIWORD(lParam);
- wClient = (int)LOWORD(lParam);
-
- /* Get new client area and adjust scroll clip rectangle.
- */
- GetClientRect(hWnd, (LPRECT)&rectScrollClip);
- rectScrollClip.top += hChar;
-
- /* Calculate new display metrics. We subtract 1 from
- * nNumDisplayLines to allow room for the label line.
- */
- nNumDisplayLines = hClient / hChar - 1;
- nNumDisplayChars = wClient / wChar;
-
- /* Calculate and set new scroll bar calibrations.
- */
- nVscrollMax = max(0, nNumBufferLines - nNumDisplayLines);
- nVscrollPos = min(nVscrollPos, nVscrollMax);
- nHscrollMax = max(0, nNumCharsPerLine - nNumDisplayChars);
- nHscrollPos = min(nHscrollPos, nHscrollMax);
- SetScrollRange(hWnd, SB_VERT, 0, nVscrollMax, FALSE);
- SetScrollPos(hWnd, SB_VERT, nVscrollPos, TRUE);
- SetScrollRange(hWnd, SB_HORZ, 0, nHscrollMax, FALSE);
- SetScrollPos(hWnd, SB_HORZ, nHscrollPos, TRUE);
- break;
-
- case WM_GETMINMAXINFO:
- /* Limit the maximum width of the window.
- */
- if(bWindowCreated) {
- ((LPPOINT)lParam)[4].x = maxClientWidth +
- (2 * GetSystemMetrics(SM_CXFRAME)) +
- (GetSystemMetrics(SM_CXVSCROLL));
- }
-
- // *((LPWORD)lParam + 8) = maxClientWidth +
- // (2 * GetSystemMetrics(SM_CXFRAME)) +
- // (GetSystemMetrics(SM_CXVSCROLL));
- break;
-
- case WM_COMMAND:
- /* Process menu messages.
- */
- CommandMsg(hWnd, wParam, lParam);
- break;
-
- case WM_VSCROLL:
- /* Determine how much to scroll vertically.
- */
- switch (LOWORD(wParam))
- {
- case SB_TOP:
- nVscrollInc = -nVscrollPos;
- break;
-
- case SB_BOTTOM:
- nVscrollInc = nVscrollMax - nVscrollPos;
- break;
-
- case SB_LINEUP:
- nVscrollInc = -1;
- break;
-
- case SB_LINEDOWN:
- nVscrollInc = 1;
- break;
-
- case SB_PAGEUP:
- nVscrollInc = min (-1, -nNumDisplayLines);
- break;
-
- case SB_PAGEDOWN:
- nVscrollInc = max(1, nNumDisplayLines);
- break;
-
- case SB_THUMBTRACK:
- nVscrollInc = ((int)HIWORD(wParam) - nVscrollPos);
- break;
-
- default:
- nVscrollInc = 0;
-
- }
-
- /* Limit the scroll range and do the scroll. We use the
- * rectScrollClip rectangle because we don't want to scroll
- * the entire window, only the part below the display label line.
- */
- if(nVscrollInc = max(-nVscrollPos,
- min(nVscrollInc,
- nVscrollMax - nVscrollPos)))
- {
- nVscrollPos += nVscrollInc;
- ScrollWindow(hWnd, 0, -hChar * nVscrollInc,
- (LPRECT)&rectScrollClip,
- (LPRECT)&rectScrollClip);
- UpdateWindow(hWnd);
- SetScrollPos(hWnd, SB_VERT, nVscrollPos, TRUE);
- }
- break;
-
- case WM_HSCROLL:
- /* Determine how much to scroll horizontally.
- */
- switch (LOWORD(wParam))
- {
- case SB_LINEUP:
- nHscrollInc = -1;
- break;
-
- case SB_LINEDOWN:
- nHscrollInc = 1;
- break;
-
- case SB_PAGEUP:
- nHscrollInc = min(-1, -nNumDisplayChars);
- break;
-
- case SB_PAGEDOWN:
- nHscrollInc = max(1, nNumDisplayChars);
- break;
-
- case SB_THUMBTRACK:
- nHscrollInc = ((int)HIWORD(wParam) - nHscrollPos);
- break;
-
- default:
- nHscrollInc = 0;
- }
-
- /* Limit the scroll range and to the scroll.
- */
- if(nHscrollInc = max(-nHscrollPos,
- min(nHscrollInc,
- nHscrollMax - nHscrollPos)))
- {
- nHscrollPos += nHscrollInc;
- ScrollWindow(hWnd, -wChar * nHscrollInc, 0, NULL, NULL);
- UpdateWindow(hWnd);
- SetScrollPos(hWnd, SB_HORZ, nHscrollPos, TRUE);
- }
- break;
-
- case WM_KEYDOWN:
- /* Translate keystrokes to scroll message.
- */
- for (i = 0; i < NUMKEYS; i++)
- if (wParam == keyToScroll[i].wVirtKey)
- {
- SendMessage(hWnd, keyToScroll[i].iMessage,
- keyToScroll[i].wRequest, 0L);
- break;
- }
- break;
-
- case WM_PAINT:
- BeginPaint(hWnd, &ps);
-
- hBrush = CreateSolidBrush(GetSysColor(COLOR_APPWORKSPACE));
- FillRect(ps.hdc, &ps.rcPaint, hBrush);
- DeleteObject(hBrush);
-
- /* Set up text attributes.
- */
- hFont = GetStockObject(SYSTEM_FIXED_FONT);
- SelectObject(ps.hdc, hFont);
- SetBkMode(ps.hdc, TRANSPARENT);
-
- /* Put up the display label if we're asked to repaint the
- * top line of the screen.
- */
- if(ps.rcPaint.top < hChar)
- {
- TextOut(ps.hdc, wChar * (0 - nHscrollPos),
- 0, szDisplayTextBuffer,
- sprintf(szDisplayTextBuffer, GetStringRes(IDS_LABEL)));
- MoveToEx(ps.hdc, wChar * (0 - nHscrollPos), hChar - 1, NULL);
- LineTo(ps.hdc, wClient, hChar - 1);
-
- ps.rcPaint.top = hChar;
- }
-
- /* Calculate the beginning and ending line numbers that we need
- * to paint. These line numbers refer to lines in the display
- * buffer, not to lines in the display window.
- */
- nPaintBeg = max (0, nVscrollPos + ps.rcPaint.top / hChar - 1);
- nPaintEnd = min(nNumBufferLines,
- nVscrollPos + ps.rcPaint.bottom / hChar + 1);
-
- /* Get the appropriate events from the display buffer, convert
- * to a text string and paint the text on the display.
- */
- for (i = nPaintBeg; i < nPaintEnd; i++)
- {
- GetDisplayEvent(lpDisplayBuffer, (LPEVENT)&incomingEvent, i);
- TextOut(ps.hdc,
- wChar * (0 - nHscrollPos),
- hChar * (1 - nVscrollPos + i),
- szDisplayTextBuffer,
- GetDisplayText(szDisplayTextBuffer,
- (LPEVENT)&incomingEvent));
- }
-
- EndPaint(hWnd, &ps);
- break;
-
- case WM_DESTROY:
- PostQuitMessage(0);
- break;
-
- case MM_MIDIINPUT:
- /* This is a custom message sent by the low level callback
- * function telling us that there is at least one MIDI event
- * in the input buffer. We empty the input buffer, and put
- * each event in the display buffer, if it's not filtered.
- * If the input buffer is being filled as fast we can empty
- * it, then we'll stay in this loop and not process any other
- * Windows messages, or yield to other applications. We need
- * something to restrict the amount of time we spend here...
- */
- while(GetEvent(lpInputBuffer, (LPEVENT)&incomingEvent))
- {
- if(!bRecordingEnabled)
- continue;
-
- if(!CheckEventFilter((LPEVENT)&incomingEvent,
- (LPFILTER)&filter))
- {
- AddDisplayEvent(lpDisplayBuffer,
- (LPEVENT)&incomingEvent);
- ++nNumBufferLines;
- nNumBufferLines = min(nNumBufferLines,
- DISPLAY_BUFFER_SIZE - 1);
- bNeedToUpdate = TRUE;
- }
- }
-
- /* Recalculate vertical scroll bar range, and force
- * the display to be updated.
- */
-
- if (bNeedToUpdate) {
- nVscrollMax = max(0, nNumBufferLines - nNumDisplayLines);
- nVscrollPos = nVscrollMax;
- SetScrollRange(hWnd, SB_VERT, 0, nVscrollMax, FALSE);
- SetScrollPos(hWnd, SB_VERT, nVscrollPos, TRUE);
- InvalidateRect(hMainWnd, (LPRECT)&rectScrollClip, 0);
- UpdateWindow(hMainWnd);
- }
-
- break;
-
- default:
- return DefWindowProc(hWnd, message, wParam, lParam);
- break;
- }
- return 0;
- }
-
- //
- /* CommandMsg - Processes WM_COMMAND messages.
- *
- * Params: hWnd - Handle to the window receiving the message.
- * wParam - Parameter of the WM_COMMAND message.
- * lParam - Parameter of the WM_COMMAND message.
- *
- * Return: void
- */
- VOID CommandMsg(
- HWND hWnd,
- WPARAM wParam,
- LPARAM lParam)
- {
- PREFERENCES preferences;
- RECT rectWindow;
- UINT wRtn;
- HMENU hMenu;
- unsigned int i;
- char szErrorText[256];
- WORD wCommand;
-
- wCommand = LOWORD(wParam);
-
- /* Process any WM_COMMAND messages we want */
- switch (wCommand) {
- case IDM_ABOUT:
- About(hInst, hWnd);
- break;
-
- case IDM_EXIT:
- PostMessage(hWnd, WM_CLOSE, 0, 0l);
- break;
-
- case IDM_SENDTOMAPPER:
- /* We use hMapper as a toggle between sending events to the
- * Mapper and not sending events.
- */
- if(hMapper) {
- /* Close the Mapper and reset hMapper. Uncheck the menu item.
- * Clear Mapper handle in the instance data for each device.
- */
- wRtn = midiOutClose(hMapper);
- if(wRtn != 0)
- {
- midiOutGetErrorText(wRtn, (LPSTR)szErrorText,
- sizeof(szErrorText));
- Error(szErrorText);
- Error("midiOutClose");
- }
- hMapper = 0;
-
- for (i=0; (i<wNumDevices) && (i<MAX_NUM_DEVICES); i++)
- lpCallbackInstanceData[i]->hMapper = hMapper;
-
- DoMenuItemCheck(hWnd, wCommand, FALSE);
- }
-
- else {
- /* Open the MIDI Mapper, put the Mapper handle in the instance
- * data for each device and check the menu item.
- */
- wRtn = midiOutOpen((LPHMIDIOUT) &hMapper, (UINT) MIDIMAPPER,
- 0L, 0L, 0L);
-
- if(wRtn != 0) { // error opening Mapper
- midiOutGetErrorText(wRtn, (LPSTR)szErrorText,
- sizeof(szErrorText));
- Error("midiOutOpen");
- Error(szErrorText);
- hMapper = 0;
- }
-
- else { // Mapper opened successfully
- for (i=0; (i<wNumDevices) && (i<MAX_NUM_DEVICES); i++)
- lpCallbackInstanceData[i]->hMapper = hMapper;
-
- DoMenuItemCheck(hWnd, wCommand, TRUE);
- }
- }
-
- break;
-
- case IDM_SAVESETUP:
- /* Save the current location and size of the display window
- * in the MIDIMON.INI file.
- */
- GetWindowRect(hMainWnd, (LPRECT)&rectWindow);
- preferences.iInitialX = rectWindow.left;
- preferences.iInitialY = rectWindow.top;
- preferences.iInitialW = rectWindow.right - rectWindow.left;
- preferences.iInitialH = rectWindow.bottom - rectWindow.top;
-
- setPreferences((LPPREFERENCES) &preferences);
- break;
-
- case IDM_STARTSTOP:
- /* Toggle between recording into the display buffer and not
- * recording. Toggle the menu item between "Start" to "Stop"
- * accordingly.
- */
- hMenu = GetMenu(hWnd);
- if(bRecordingEnabled)
- {
- ModifyMenu(hMenu, IDM_STARTSTOP, MF_BYCOMMAND, IDM_STARTSTOP,
- GetStringRes(IDS_START));
- bRecordingEnabled = 0;
- }
- else
- {
- ModifyMenu(hMenu, IDM_STARTSTOP, MF_BYCOMMAND, IDM_STARTSTOP,
- GetStringRes(IDS_STOP));
- bRecordingEnabled = 1;
- }
- DrawMenuBar(hWnd);
- break;
-
- case IDM_CLEAR:
- /* Reset the display buffer, recalibrate the scroll bars,
- * and force an update of the display.
- */
- ResetDisplayBuffer(lpDisplayBuffer);
- nNumBufferLines = 0;
- SetScrollRange(hWnd, SB_VERT, 0, 0, FALSE);
-
- InvalidateRect(hWnd, (LPRECT)&rectScrollClip, 0);
- UpdateWindow(hWnd);
-
- break;
-
- /* Set up filter structure for MIDI channel filtering.
- */
- case IDM_FILTCHAN0:
- case IDM_FILTCHAN1:
- case IDM_FILTCHAN2:
- case IDM_FILTCHAN3:
- case IDM_FILTCHAN4:
- case IDM_FILTCHAN5:
- case IDM_FILTCHAN6:
- case IDM_FILTCHAN7:
- case IDM_FILTCHAN8:
- case IDM_FILTCHAN9:
- case IDM_FILTCHAN10:
- case IDM_FILTCHAN11:
- case IDM_FILTCHAN12:
- case IDM_FILTCHAN13:
- case IDM_FILTCHAN14:
- case IDM_FILTCHAN15:
- filter.channel[wCommand - IDM_FILTCHAN0] =
- !filter.channel[wCommand - IDM_FILTCHAN0];
- DoMenuItemCheck(hWnd, wCommand,
- filter.channel[wCommand - IDM_FILTCHAN0]);
- break;
-
- /* Setup filter structure for MIDI event filtering.
- */
- case IDM_NOTEOFF:
- filter.event.noteOff = !filter.event.noteOff;
- DoMenuItemCheck(hWnd, wCommand, filter.event.noteOff);
- break;
- case IDM_NOTEON:
- filter.event.noteOn = !filter.event.noteOn;
- DoMenuItemCheck(hWnd, wCommand, filter.event.noteOn);
- break;
- case IDM_POLYAFTERTOUCH:
- filter.event.keyAftertouch = !filter.event.keyAftertouch;
- DoMenuItemCheck(hWnd, wCommand, filter.event.keyAftertouch);
- break;
- case IDM_CONTROLCHANGE:
- filter.event.controller = !filter.event.controller;
- DoMenuItemCheck(hWnd, wCommand, filter.event.controller);
- break;
- case IDM_PROGRAMCHANGE:
- filter.event.progChange = !filter.event.progChange;
- DoMenuItemCheck(hWnd, wCommand, filter.event.progChange);
- break;
- case IDM_CHANNELAFTERTOUCH:
- filter.event.chanAftertouch = !filter.event.chanAftertouch;
- DoMenuItemCheck(hWnd, wCommand, filter.event.chanAftertouch);
- break;
- case IDM_PITCHBEND:
- filter.event.pitchBend = !filter.event.pitchBend;
- DoMenuItemCheck(hWnd, wCommand, filter.event.pitchBend);
- break;
- case IDM_CHANNELMODE:
- filter.event.channelMode = !filter.event.channelMode;
- DoMenuItemCheck(hWnd, wCommand, filter.event.channelMode);
- break;
- case IDM_SYSTEMEXCLUSIVE:
- filter.event.sysEx = !filter.event.sysEx;
- DoMenuItemCheck(hWnd, wCommand, filter.event.sysEx);
- break;
- case IDM_SYSTEMCOMMON:
- filter.event.sysCommon = !filter.event.sysCommon;
- DoMenuItemCheck(hWnd, wCommand, filter.event.sysCommon);
- break;
- case IDM_SYSTEMREALTIME:
- filter.event.sysRealTime = !filter.event.sysRealTime;
- DoMenuItemCheck(hWnd, wCommand, filter.event.sysRealTime);
- break;
- case IDM_ACTIVESENSE:
- filter.event.activeSense = !filter.event.activeSense;
- DoMenuItemCheck(hWnd, wCommand, filter.event.activeSense);
- break;
-
- default:
- break;
- }
- }
-
- //
- /* InitFirstInstance - Performs initializaion for the first instance
- * of the application.
- *
- * Params: hInstance - Instance handle.
- *
- * Return: Returns 1 if there were no errors. Otherwise, returns 0.
- */
- BOOL InitFirstInstance(hInstance)
- HANDLE hInstance;
- {
- WNDCLASS wc;
-
- /* Define the class of window we want to register.
- */
- wc.lpszClassName = szAppName;
- wc.style = CS_HREDRAW | CS_VREDRAW;
- wc.hCursor = LoadCursor(NULL, IDC_ARROW);
- wc.hIcon = LoadIcon(hInstance,"Icon");
- wc.lpszMenuName = "Menu";
- wc.hbrBackground = (HBRUSH)(COLOR_APPWORKSPACE + 1);
- wc.hInstance = hInstance;
- wc.lpfnWndProc = WndProc;
- wc.cbClsExtra = 0;
- wc.cbWndExtra = 0;
-
- if(!RegisterClass(&wc))
- return FALSE;
-
- return TRUE;
- }
-
- //
- /* DoMenuItemCheck - Checks and unchecks menu items.
- *
- * Params: hWnd - Window handle for window associated with menu items.
- * wMenuItem - The menu ID for the menu item.
- * newState - The new checked/unchecked state of the menu item.
- *
- * Return: void
- */
- void DoMenuItemCheck(
- HWND hWnd,
- WORD wMenuItem,
- BOOL newState)
- {
- HMENU hMenu;
-
- hMenu = GetMenu(hWnd);
- CheckMenuItem(hMenu, wMenuItem, (newState ? MF_CHECKED: MF_UNCHECKED));
- }
-
-
- /* Error - Beeps and shows an error message.
- *
- * Params: szMsg - Points to a NULL-terminated string containing the
- * error message.
- *
- * Return: Returns the return value from the MessageBox() call.
- * Since this message box has only a single button, the
- * return value isn't too meaningful.
- */
- int Error(szMsg)
- LPSTR szMsg;
- {
- MessageBeep(0);
- return MessageBox(hMainWnd, szMsg, szAppName, MB_OK);
- }
-
- /******************************************************************************\
- *
- * FUNCTION: GetStringRes (int id INPUT ONLY)
- *
- * COMMENTS: Load the resource string with the ID given, and return a
- * pointer to it. Notice that the buffer is common memory so
- * the string must be used before this call is made a second time.
- *
- \******************************************************************************/
-
- LPTSTR GetStringRes (int id)
- {
- static TCHAR buffer[MAX_PATH];
-
- buffer[0]=0;
- LoadString (GetModuleHandle (NULL), id, buffer, MAX_PATH);
- return buffer;
- }
-