home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power-Programmierung
/
CD1.mdf
/
magazine
/
pcmagazi
/
1992
/
13
/
midvue.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-03-18
|
12KB
|
375 lines
/*---------------------------------------
MIDVUE.C -- MIDI Input Viewer
(c) Charles Petzold, 1992
---------------------------------------*/
#include <windows.h>
extern "C" {
#include <mmsystem.h>
}
#include <stdlib.h>
#include <string.h>
typedef unsigned int UINT ;
#define IDM_OPEN 0x100
#define IDM_CLOSE 0x101
#define IDM_DEVICE 0x200
long FAR PASCAL _export WndProc (HWND, UINT, UINT, LONG);
char szAppName [] = "MidVue" ;
int cxChar, cyChar ;
int PASCAL WinMain (HANDLE hInstance, HANDLE hPrevInstance,
LPSTR lpszCmdLine, int nCmdShow)
{
MSG msg;
HWND hwnd ;
WNDCLASS wndclass ;
if (!hPrevInstance)
{
wndclass.style = CS_HREDRAW | CS_VREDRAW ;
wndclass.lpfnWndProc = WndProc ;
wndclass.cbClsExtra = 0 ;
wndclass.cbWndExtra = 0 ;
wndclass.hInstance = hInstance ;
wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ;
wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;
wndclass.hbrBackground = GetStockObject (WHITE_BRUSH) ;
wndclass.lpszMenuName = NULL ;
wndclass.lpszClassName = szAppName ;
RegisterClass (&wndclass) ;
}
hwnd = CreateWindow (szAppName, "MIDI Input Viewer",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, hInstance, NULL) ;
ShowWindow (hwnd, nCmdShow) ;
UpdateWindow (hwnd);
while (GetMessage (&msg, NULL, 0, 0))
{
TranslateMessage (&msg) ;
DispatchMessage (&msg) ;
}
return msg.wParam ;
}
HMENU CreateTheMenu (int iNumDevs)
{
HMENU hMenu, hMenuPopup ;
int i ;
MIDIINCAPS mic ;
hMenu = CreateMenu () ;
// Create "Status" popup menu
hMenuPopup = CreateMenu () ;
AppendMenu (hMenuPopup, MF_STRING , IDM_OPEN, "&Open") ;
AppendMenu (hMenuPopup, MF_STRING | MF_CHECKED, IDM_CLOSE, "&Closed") ;
AppendMenu (hMenu, MF_STRING | MF_POPUP, hMenuPopup, "&Status") ;
// Create "Device" popup menu
hMenuPopup = CreateMenu () ;
for (i = 0 ; i < iNumDevs ; i++)
{
midiInGetDevCaps (i, &mic, sizeof (mic)) ;
AppendMenu (hMenuPopup, MF_STRING, IDM_DEVICE + i, mic.szPname) ;
}
CheckMenuItem (hMenuPopup, 0, MF_BYPOSITION | MF_CHECKED) ;
AppendMenu (hMenu, MF_STRING | MF_POPUP, hMenuPopup, "&Device") ;
return hMenu ;
}
void DisplayTheMessage (HDC hdc, DWORD dwMsg, int iNextRow)
{
static char * szStatus [] = { "Note Off", "Note On",
"Polyphonic Aftertouch",
"Control Change", "Program Change",
"Channel Aftertouch", "Pitch Bend" } ;
static char * szModes [] = { "Reset All Controllers", "Local Control",
"All Notes Off", "Omni Mode Off",
"Omni Mode On", "Mono Mode Off",
"Poly Mode On" } ;
char szBuffer [48] ;
DWORD dwTime ;
RECT rect ;
WORD wStatus, wData1, wData2 ;
// Display white rectangle to blank line
if (dwMsg == 0)
{
rect.left = 0 ;
rect.top = cyChar * iNextRow ;
rect.right = cxChar * 80 ;
rect.bottom = cyChar * (iNextRow + 1) ;
FillRect (hdc, &rect, GetStockObject (WHITE_BRUSH)) ;
}
else
{
MoveTo (hdc, 0, cyChar * iNextRow) ;
SetTextAlign (hdc, TA_UPDATECP) ;
// Display system time
dwTime = timeGetTime () ;
wsprintf (szBuffer, "%04X-%04X ", HIWORD (dwTime), LOWORD (dwTime)) ;
TextOut (hdc, 0, 0, szBuffer, strlen (szBuffer)) ;
// Break down MIDI message
wStatus = 0x00FF & (LOBYTE (LOWORD (dwMsg))) ;
wData1 = 0x00FF & (HIBYTE (LOWORD (dwMsg))) ;
wData2 = 0x00FF & (LOBYTE (HIWORD (dwMsg))) ;
// Display the three bytes
wsprintf (szBuffer, " %02X %02X %02X ", wStatus, wData1, wData2) ;
TextOut (hdc, 0, 0, szBuffer, strlen (szBuffer)) ;
if (wStatus < 0xF0)
{
// Display channel and message type
wsprintf (szBuffer, " Channel %d, %s, ",
(wStatus & 0x0F) + 1,
(LPSTR) szStatus [((wStatus >> 4) & 0x0F) - 8]) ;
TextOut (hdc, 0, 0, szBuffer, strlen (szBuffer)) ;
// Display message-specific information
if (wStatus < 0xA0)
wsprintf (szBuffer, "Key %d, Velocity %d", wData1, wData2);
else if (wStatus < 0xB0)
wsprintf (szBuffer, "Key %d, Pressure %d", wData1, wData2);
else if (wStatus < 0xC0)
switch (wData1)
{
case 121:
case 123:
case 124:
case 125:
case 127:
wsprintf (szBuffer, "%s",
(LPSTR) szModes [wData1 - 121]) ;
break ;
case 122:
wsprintf (szBuffer, "%s %s",
(LPSTR) szModes [wData1 - 121],
(LPSTR) (wData2 ? "On" : "Off")) ;
break ;
case 126:
wsprintf (szBuffer, "%s, %d Channels",
(LPSTR) szModes [wData1 - 121],
wData2) ;
break ;
default:
wsprintf (szBuffer, "Controller %d, Value %d",
wData1, wData2) ;
break ;
}
else if (wStatus < 0xD0)
wsprintf (szBuffer, "Voice %d", wData1 + 1) ;
else if (wStatus < 0xE0)
wsprintf (szBuffer, "Pressure %d", wData1) ;
else if (wStatus < 0xF0)
wsprintf (szBuffer, "Value %d", wData2 * 128 + wData1) ;
}
else
{
wsprintf (szBuffer, " System Message") ;
}
TextOut (hdc, 0, 0, szBuffer, strlen (szBuffer)) ;
}
}
long FAR PASCAL _export WndProc (HWND hwnd, UINT message, UINT wParam,
LONG lParam)
{
static BOOL bOpened = FALSE ;
static DWORD * pdwMsg ;
static HMIDIIN hMidiIn ;
static int iNumRows, iNextRow ;
static WORD wDevice ;
DWORD dwExtent ;
HDC hdc ;
HMENU hMenu ;
PAINTSTRUCT ps ;
short i, iNumDevs, cyClient ;
switch (message)
{
case WM_CREATE:
// Get character size of fixed point font
hdc = GetDC (hwnd) ;
SelectObject (hdc, GetStockObject (SYSTEM_FIXED_FONT)) ;
dwExtent = GetTextExtent (hdc, "M", 1) ;
cxChar = LOWORD (dwExtent) ;
cyChar = HIWORD (dwExtent) ;
ReleaseDC (hwnd, hdc) ;
// Get number of MIDI input devices and set up menu
if (0 == (iNumDevs = midiInGetNumDevs ()))
{
MessageBeep (MB_ICONSTOP) ;
MessageBox (hwnd, "No MIDI input devices!",
szAppName, MB_OK | MB_ICONEXCLAMATION) ;
DestroyWindow (hwnd) ;
}
else
{
SetMenu (hwnd, CreateTheMenu (iNumDevs)) ;
}
return 0 ;
case WM_SIZE:
cyClient = HIWORD (lParam) ;
iNumRows = cyClient / cyChar ;
iNextRow = 0 ;
// Allocate memory for storing information
if (pdwMsg != NULL)
free (pdwMsg) ;
pdwMsg = (DWORD *) calloc (iNumRows, sizeof (DWORD)) ;
return 0 ;
case WM_COMMAND:
hMenu = GetMenu (hwnd) ;
// "Open" menu command
if (wParam == IDM_OPEN && !bOpened)
{
if (midiInOpen (&hMidiIn, wDevice, (DWORD) hwnd,
0L, CALLBACK_WINDOW))
{
MessageBeep (MB_ICONEXCLAMATION) ;
MessageBox (hwnd, "Cannot open MIDI In device",
szAppName, MB_OK | MB_ICONEXCLAMATION) ;
}
else
{
CheckMenuItem (hMenu, IDM_OPEN, MF_CHECKED) ;
CheckMenuItem (hMenu, IDM_CLOSE, MF_UNCHECKED) ;
midiInStart (hMidiIn) ;
bOpened = TRUE ;
}
}
// "Close" menu command
else if (wParam == IDM_CLOSE && bOpened)
{
CheckMenuItem (hMenu, IDM_OPEN, MF_UNCHECKED) ;
CheckMenuItem (hMenu, IDM_CLOSE, MF_CHECKED) ;
// Close device
midiInStop (hMidiIn) ;
midiInClose (hMidiIn) ;
bOpened = FALSE ;
}
// Change MIDI "Device" menu command
else if (wParam >= IDM_DEVICE - 1)
{
CheckMenuItem (hMenu, IDM_DEVICE + wDevice, MF_UNCHECKED) ;
wDevice = wParam - IDM_DEVICE ;
CheckMenuItem (hMenu, IDM_DEVICE + wDevice, MF_CHECKED) ;
// Close and reopen MIDI device
if (bOpened)
{
SendMessage (hwnd, WM_COMMAND, IDM_CLOSE, 0L) ;
SendMessage (hwnd, WM_COMMAND, IDM_OPEN, 0L) ;
}
}
InvalidateRect (hwnd, NULL, TRUE) ;
return 0 ;
case MM_MIM_DATA:
// Skip "Active Sensing" messages
if (lParam == 0x00FE)
return 0 ;
// Display the message
hdc = GetDC (hwnd) ;
SelectObject (hdc, GetStockObject (SYSTEM_FIXED_FONT)) ;
pdwMsg [iNextRow] = lParam ;
DisplayTheMessage (hdc, pdwMsg [iNextRow], iNextRow) ;
// Blank out the next row
iNextRow = (iNextRow + 1) % iNumRows ;
pdwMsg [iNextRow] = 0L ;
DisplayTheMessage (hdc, pdwMsg [iNextRow], iNextRow) ;
ReleaseDC (hwnd, hdc) ;
return 0 ;
case WM_PAINT:
hdc = BeginPaint (hwnd, &ps) ;
SelectObject (hdc, GetStockObject (SYSTEM_FIXED_FONT)) ;
for (i = 0 ; i < iNumRows ; i++)
if (0L != (pdwMsg [i]))
DisplayTheMessage (hdc, pdwMsg [i], i) ;
EndPaint (hwnd, &ps) ;
return 0 ;
case WM_DESTROY :
SendMessage (hwnd, WM_COMMAND, IDM_CLOSE, 0L) ;
PostQuitMessage (0) ;
return 0 ;
}
return DefWindowProc (hwnd, message, wParam, lParam) ;
}