#include <windows.h>
#include <mmsystem.h>
#define ID_BUTTON1 1
#define ID_BUTTON2 2
#define ID_BUTTON3 3
#define ID_BUTTON4 4
#define ID_BUTTON5 5
#define ID_BUTTON6 6
#define ID_BUTTON7 7
#define ID_BUTTON8 8
#define ID_BUTTON9 9
#define ID_BUTTON10 10
#define ID_BUTTON11 11
#define ID_BUTTON12 12
#define ID_BUTTON13 13
#define ID_BUTTON14 14
#define ID_BUTTON15 15
#define ID_BUTTON16 16
#define ID_BUTTON17 17
#define ID_BUTTON18 18
#define ID_BUTTON19 19
#define ID_BUTTON20 20
#define ID_BUTTON21 21
HMIDIOUT hMidiOut;
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
switch (msg) {
case WM_CREATE: {
CreateWindow("BUTTON", "Note C", WS_VISIBLE | WS_CHILD, 10, 10, 50, 50, hwnd, (HMENU)ID_BUTTON1, NULL, NULL);
CreateWindow("BUTTON", "Note C#", WS_VISIBLE | WS_CHILD, 65, 10, 50, 50, hwnd, (HMENU)ID_BUTTON3, NULL, NULL);
CreateWindow("BUTTON", "Note D", WS_VISIBLE | WS_CHILD, 120, 10, 50, 50, hwnd, (HMENU)ID_BUTTON2, NULL, NULL);
CreateWindow("BUTTON", "Note D#", WS_VISIBLE | WS_CHILD, 175, 10, 50, 50, hwnd, (HMENU)ID_BUTTON4, NULL, NULL);
CreateWindow("BUTTON", "Note E", WS_VISIBLE | WS_CHILD, 230, 10, 50, 50, hwnd, (HMENU)ID_BUTTON5, NULL, NULL);
CreateWindow("BUTTON", "Note F", WS_VISIBLE | WS_CHILD, 285, 10, 50, 50, hwnd, (HMENU)ID_BUTTON6, NULL, NULL);
CreateWindow("BUTTON", "Note F#", WS_VISIBLE | WS_CHILD, 340, 10, 50, 50, hwnd, (HMENU)ID_BUTTON7, NULL, NULL);
CreateWindow("BUTTON", "Note G", WS_VISIBLE | WS_CHILD, 395, 10, 50, 50, hwnd, (HMENU)ID_BUTTON8, NULL, NULL);
CreateWindow("BUTTON", "Note G#", WS_VISIBLE | WS_CHILD, 450, 10, 50, 50, hwnd, (HMENU)ID_BUTTON9, NULL, NULL);
CreateWindow("BUTTON", "Note A", WS_VISIBLE | WS_CHILD, 505, 10, 50, 50, hwnd, (HMENU)ID_BUTTON10, NULL, NULL);
CreateWindow("BUTTON", "Note A#", WS_VISIBLE | WS_CHILD, 560, 10, 50, 50, hwnd, (HMENU)ID_BUTTON11, NULL, NULL);
CreateWindow("BUTTON", "Note B", WS_VISIBLE | WS_CHILD, 615, 10, 50, 50, hwnd, (HMENU)ID_BUTTON12, NULL, NULL);
CreateWindow("BUTTON", "Note C2", WS_VISIBLE | WS_CHILD, 10, 70, 50, 50, hwnd, (HMENU)ID_BUTTON13, NULL, NULL);
CreateWindow("BUTTON", "Note C#2", WS_VISIBLE | WS_CHILD, 65, 70, 50, 50, hwnd, (HMENU)ID_BUTTON14, NULL, NULL);
CreateWindow("BUTTON", "Note D2", WS_VISIBLE | WS_CHILD, 120, 70, 50, 50, hwnd, (HMENU)ID_BUTTON15, NULL, NULL);
CreateWindow("BUTTON", "Note D#2", WS_VISIBLE | WS_CHILD, 175, 70, 50, 50, hwnd, (HMENU)ID_BUTTON16, NULL, NULL);
CreateWindow("BUTTON", "Note E2", WS_VISIBLE | WS_CHILD, 230, 70, 50, 50, hwnd, (HMENU)ID_BUTTON17, NULL, NULL);
CreateWindow("BUTTON", "Note F2", WS_VISIBLE | WS_CHILD, 285, 70, 50, 50, hwnd, (HMENU)ID_BUTTON18, NULL, NULL);
CreateWindow("BUTTON", "Note F#2", WS_VISIBLE | WS_CHILD, 340, 70, 50, 50, hwnd, (HMENU)ID_BUTTON19, NULL, NULL);
CreateWindow("BUTTON", "Note G2", WS_VISIBLE | WS_CHILD, 395, 70, 50, 50, hwnd, (HMENU)ID_BUTTON20, NULL, NULL);
CreateWindow("BUTTON", "Note G#2", WS_VISIBLE | WS_CHILD, 450, 70, 50, 50, hwnd, (HMENU)ID_BUTTON21, NULL, NULL);
if (midiOutOpen(&hMidiOut, MIDI_MAPPER, 0, 0, CALLBACK_NULL) != MMSYSERR_NOERROR) {
MessageBox(hwnd, "无法打开 MIDI 输出设备", "错误", MB_OK | MB_ICONERROR);
}
break;
}
case WM_COMMAND: {
switch (LOWORD(wParam)) {
case ID_BUTTON1: {
midiOutShortMsg(hMidiOut, 0x90 | (60 << 8) | (127 << 16));
Sleep(200);
midiOutShortMsg(hMidiOut, 0x80 | (60 << 8) | (0 << 16));
break;
}
case ID_BUTTON2: {
midiOutShortMsg(hMidiOut, 0x90 | (62 << 8) | (127 << 16));
Sleep(200);
midiOutShortMsg(hMidiOut, 0x80 | (62 << 8) | (0 << 16));
break;
}
case ID_BUTTON3: {
midiOutShortMsg(hMidiOut, 0x90 | (61 << 8) | (127 << 16));
Sleep(200);
midiOutShortMsg(hMidiOut, 0x80 | (61 << 8) | (0 << 16));
break;
}
case ID_BUTTON4: {
midiOutShortMsg(hMidiOut, 0x90 | (63 << 8) | (127 << 16));
Sleep(200);
midiOutShortMsg(hMidiOut, 0x80 | (63 << 8) | (0 << 16));
break;
}
case ID_BUTTON5: {
midiOutShortMsg(hMidiOut, 0x90 | (64 << 8) | (127 << 16));
Sleep(200);
midiOutShortMsg(hMidiOut, 0x80 | (64 << 8) | (0 << 16));
break;
}
case ID_BUTTON6: {
midiOutShortMsg(hMidiOut, 0x90 | (65 << 8) | (127 << 16));
Sleep(200);
midiOutShortMsg(hMidiOut, 0x80 | (65 << 8) | (0 << 16));
break;
}
case ID_BUTTON7: {
midiOutShortMsg(hMidiOut, 0x90 | (66 << 8) | (127 << 16));
Sleep(200);
midiOutShortMsg(hMidiOut, 0x80 | (66 << 8) | (0 << 16));
break;
}
case ID_BUTTON8: {
midiOutShortMsg(hMidiOut, 0x90 | (67 << 8) | (127 << 16));
Sleep(200);
midiOutShortMsg(hMidiOut, 0x80 | (67 << 8) | (0 << 16));
break;
}
case ID_BUTTON9: {
midiOutShortMsg(hMidiOut, 0x90 | (68 << 8) | (127 << 16));
Sleep(200);
midiOutShortMsg(hMidiOut, 0x80 | (68 << 8) | (0 << 16));
break;
}
case ID_BUTTON10: {
midiOutShortMsg(hMidiOut, 0x90 | (69 << 8) | (127 << 16));
Sleep(200);
midiOutShortMsg(hMidiOut, 0x80 | (69 << 8) | (0 << 16));
break;
}
case ID_BUTTON11: {
midiOutShortMsg(hMidiOut, 0x90 | (70 << 8) | (127 << 16));
Sleep(200);
midiOutShortMsg(hMidiOut, 0x80 | (70 << 8) | (0 << 16));
break;
}
case ID_BUTTON12: {
midiOutShortMsg(hMidiOut, 0x90 | (71 << 8) | (127 << 16));
Sleep(200);
midiOutShortMsg(hMidiOut, 0x80 | (71 << 8) | (0 << 16));
break;
}
case ID_BUTTON13: {
midiOutShortMsg(hMidiOut, 0x90 | (72 << 8) | (127 << 16));
Sleep(200);
midiOutShortMsg(hMidiOut, 0x80 | (72 << 8) | (0 << 16));
break;
}
case ID_BUTTON14: {
midiOutShortMsg(hMidiOut, 0x90 | (73 << 8) | (127 << 16));
Sleep(200);
midiOutShortMsg(hMidiOut, 0x80 | (73 << 8) | (0 << 16));
break;
}
case ID_BUTTON15: {
midiOutShortMsg(hMidiOut, 0x90 | (74 << 8) | (127 << 16));
Sleep(200);
midiOutShortMsg(hMidiOut, 0x80 | (74 << 8) | (0 << 16));
break;
}
case ID_BUTTON16: {
midiOutShortMsg(hMidiOut, 0x90 | (75 << 8) | (127 << 16));
Sleep(200);
midiOutShortMsg(hMidiOut, 0x80 | (75 << 8) | (0 << 16));
break;
}
case ID_BUTTON17: {
midiOutShortMsg(hMidiOut, 0x90 | (76 << 8) | (127 << 16));
Sleep(200);
midiOutShortMsg(hMidiOut, 0x80 | (76 << 8) | (0 << 16));
break;
}
case ID_BUTTON18: {
midiOutShortMsg(hMidiOut, 0x90 | (77 << 8) | (127 << 16));
Sleep(200);
midiOutShortMsg(hMidiOut, 0x80 | (77 << 8) | (0 << 16));
break;
}
case ID_BUTTON19: {
midiOutShortMsg(hMidiOut, 0x90 | (78 << 8) | (127 << 16));
Sleep(200);
midiOutShortMsg(hMidiOut, 0x80 | (78 << 8) | (0 << 16));
break;
}
case ID_BUTTON20: {
midiOutShortMsg(hMidiOut, 0x90 | (79 << 8) | (127 << 16));
Sleep(200);
midiOutShortMsg(hMidiOut, 0x80 | (79 << 8) | (0 << 16));
break;
}
case ID_BUTTON21: {
midiOutShortMsg(hMidiOut, 0x90 | (80 << 8) | (127 << 16));
Sleep(200);
midiOutShortMsg(hMidiOut, 0x80 | (80 << 8) | (0 << 16));
break;
}
}
break;
}
case WM_DESTROY: {
midiOutClose(hMidiOut);
PostQuitMessage(0);
break;
}
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) {
WNDCLASS wc = {0};
wc.lpfnWndProc = WndProc;
wc.hInstance = hInstance;
wc.lpszClassName = "MidiPianoClass";
RegisterClass(&wc);
HWND hwnd = CreateWindow(wc.lpszClassName, "MIDI 钢琴", WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, 800, 400, NULL, NULL, hInstance, NULL);
ShowWindow(hwnd, iCmdShow);
UpdateWindow(hwnd);
MSG msg;
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}