嗨嗨嗨~
Today事有点多,先留个代码。
#include <windows.h>
#include <vector>
#include <pthread.h>
#include <unistd.h>
#include <string>
#include <unordered_map>
HMIDIOUT* hMidiOut = new HMIDIOUT;
namespace std {
unordered_map<string, long> table;
string to_str(int x)
{
string ret = "", temp = "";
if (x < 0)
{
ret = "-";
x = -x;
}
while (x != 0)
{
temp = char(x % 10 + '0') + temp;
x /= 10;
}
return ret + temp;
}
void init()
{
string each[13] = {"", "C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"};
long num = 0;
for (long i = -1; i <= 9; i++)
{
for (long j = 1; j <= 12; j++)
{
if (num == 127)
{
break;
}
string key = to_str(i) + each[j];
table[key] = num++;
}
}
}
struct Note {
vector<RECT> place;
string name;
int stair;
void splay()
{
midiOutShortMsg(*hMidiOut, 0x007f0095 + table[to_str(stair) + name] * 256);
}
void cplay()
{
midiOutShortMsg(*hMidiOut, 0x00000095 + table[to_str(stair) + name] * 256);
}
bool judge(POINT p)
{
if (place.size() == 1)
{
return ((p.x >= place[0].left && p.x <= place[0].right) && (p.y >= place[0].top && p.y <= place[0].bottom));
}
else
{
bool flag = 0;
for (int i = 0; i < place.size(); i++)
{
flag = flag | ((p.x >= place[i].left && p.x <= place[i].right) && (p.y >= place[i].top && p.y <= place[i].bottom));
}
return flag;
}
}
};
vector<Note> keyboard;
}
void whiteDraw(HDC hdc, int startx)
{
static int stw = 1;
HBRUSH hbr = CreateSolidBrush(RGB(0, 0, 0));
RECT r;
RECT RinN;
std::Note n;
n.place.clear();
r.bottom = 140;
r.top = 65;
r.left = startx;
r.right = startx + 20;
FillRect(hdc, &r, hbr);
hbr = CreateSolidBrush(RGB(255, 255, 255));
r.bottom -= 1;
r.top += 1;
r.left += 1;
r.right -= 1;
FillRect(hdc, &r, hbr);
n.name = "C";
n.stair = stw;
RinN.bottom = 140;
RinN.top = 99;
RinN.left = startx;
RinN.right = startx + 20;
n.place.push_back(RinN);
RinN.bottom = 100;
RinN.top = 65;
RinN.left = startx;
RinN.right = startx + 12;
n.place.push_back(RinN);
std::keyboard.push_back(n);
TextOut(hdc, startx + 6, 108, std::to_str(stw).c_str(), 1);
TextOut(hdc, startx + 6, 122, "C", 1);
startx += 20;
n.place.clear();
hbr = CreateSolidBrush(RGB(0, 0, 0));
r.bottom = 140;
r.top = 65;
r.left = startx;
r.right = startx + 20;
FillRect(hdc, &r, hbr);
hbr = CreateSolidBrush(RGB(255, 255, 255));
r.bottom -= 1;
r.top += 1;
r.left += 1;
r.right -= 1;
FillRect(hdc, &r, hbr);
n.name = "D";
n.stair = stw;
RinN.bottom = 140;
RinN.top = 99;
RinN.left = startx;
RinN.right = startx + 20;
n.place.push_back(RinN);
RinN.bottom = 100;
RinN.top = 65;
RinN.left = startx + 8;
RinN.right = startx + 12;
n.place.push_back(RinN);
std::keyboard.push_back(n);
TextOut(hdc, startx + 6, 122, "D", 1);
startx += 20;
n.place.clear();
hbr = CreateSolidBrush(RGB(0, 0, 0));
r.bottom = 140;
r.top = 65;
r.left = startx;
r.right = startx + 20;
FillRect(hdc, &r, hbr);
hbr = CreateSolidBrush(RGB(255, 255, 255));
r.bottom -= 1;
r.top += 1;
r.left += 1;
r.right -= 1;
FillRect(hdc, &r, hbr);
n.name = "E";
n.stair = stw;
RinN.bottom = 140;
RinN.top = 99;
RinN.left = startx;
RinN.right = startx + 20;
n.place.push_back(RinN);
RinN.bottom = 100;
RinN.top = 65;
RinN.left = startx + 8;
RinN.right = startx + 20;
n.place.push_back(RinN);
std::keyboard.push_back(n);
TextOut(hdc, startx + 6, 122, "E", 1);
startx += 20;
n.place.clear();
hbr = CreateSolidBrush(RGB(0, 0, 0));
r.bottom = 140;
r.top = 65;
r.left = startx;
r.right = startx + 20;
FillRect(hdc, &r, hbr);
hbr = CreateSolidBrush(RGB(255, 255, 255));
r.bottom -= 1;
r.top += 1;
r.left += 1;
r.right -= 1;
FillRect(hdc, &r, hbr);
n.name = "F";
n.stair = stw;
RinN.bottom = 140;
RinN.top = 99;
RinN.left = startx;
RinN.right = startx + 20;
n.place.push_back(RinN);
RinN.bottom = 100;
RinN.top = 65;
RinN.left = startx + 8;
RinN.right = startx + 12;
n.place.push_back(RinN);
std::keyboard.push_back(n);
TextOut(hdc, startx + 6, 122, "F", 1);
startx += 20;
n.place.clear();
hbr = CreateSolidBrush(RGB(0, 0, 0));
r.bottom = 140;
r.top = 65;
r.left = startx;
r.right = startx + 20;
FillRect(hdc, &r, hbr);
hbr = CreateSolidBrush(RGB(255, 255, 255));
r.bottom -= 1;
r.top += 1;
r.left += 1;
r.right -= 1;
FillRect(hdc, &r, hbr);
n.name = "G";
n.stair = stw;
RinN.bottom = 140;
RinN.top = 99;
RinN.left = startx;
RinN.right = startx + 20;
n.place.push_back(RinN);
RinN.bottom = 100;
RinN.top = 65;
RinN.left = startx + 8;
RinN.right = startx + 12;
n.place.push_back(RinN);
std::keyboard.push_back(n);
TextOut(hdc, startx + 6, 122, "G", 1);
startx += 20;
n.place.clear();
hbr = CreateSolidBrush(RGB(0, 0, 0));
r.bottom = 140;
r.top = 65;
r.left = startx;
r.right = startx + 20;
FillRect(hdc, &r, hbr);
hbr = CreateSolidBrush(RGB(255, 255, 255));
r.bottom -= 1;
r.top += 1;
r.left += 1;
r.right -= 1;
FillRect(hdc, &r, hbr);
n.name = "A";
n.stair = stw;
RinN.bottom = 140;
RinN.top = 99;
RinN.left = startx;
RinN.right = startx + 20;
n.place.push_back(RinN);
RinN.bottom = 100;
RinN.top = 65;
RinN.left = startx + 8;
RinN.right = startx + 12;
n.place.push_back(RinN);
std::keyboard.push_back(n);
TextOut(hdc, startx + 6, 122, "A", 1);
startx += 20;
n.place.clear();
hbr = CreateSolidBrush(RGB(0, 0, 0));
r.bottom = 140;
r.top = 65;
r.left = startx;
r.right = startx + 20;
FillRect(hdc, &r, hbr);
hbr = CreateSolidBrush(RGB(255, 255, 255));
r.bottom -= 1;
r.top += 1;
r.left += 1;
r.right -= 1;
FillRect(hdc, &r, hbr);
n.name = "B";
n.stair = stw;
RinN.bottom = 140;
RinN.top = 99;
RinN.left = startx;
RinN.right = startx + 20;
n.place.push_back(RinN);
RinN.bottom = 100;
RinN.top = 65;
RinN.left = startx + 8;
RinN.right = startx + 20;
n.place.push_back(RinN);
std::keyboard.push_back(n);
TextOut(hdc, startx + 6, 122, "B", 1);
stw++;
}
void blackDraw(HDC hdc, int startx)
{
static int stb = 1;
HBRUSH hbr = CreateSolidBrush(RGB(0, 0, 0));
RECT r;
std::Note n;
n.place.clear();
r.bottom = 100;
r.top = 65;
r.left = startx + 13;
r.right = startx + 27;
FillRect(hdc, &r, hbr);
n.name = "C#";
n.stair = stb;
n.place.push_back(r);
std::keyboard.push_back(n);
startx += 20;
n.place.clear();
r.bottom = 100;
r.top = 65;
r.left = startx + 13;
r.right = startx + 27;
FillRect(hdc, &r, hbr);
n.name = "D#";
n.stair = stb;
n.place.push_back(r);
std::keyboard.push_back(n);
startx += 40;
n.place.clear();
r.bottom = 100;
r.top = 65;
r.left = startx + 13;
r.right = startx + 27;
FillRect(hdc, &r, hbr);
n.name = "F#";
n.stair = stb;
n.place.push_back(r);
std::keyboard.push_back(n);
startx += 20;
n.place.clear();
r.bottom = 100;
r.top = 65;
r.left = startx + 13;
r.right = startx + 27;
FillRect(hdc, &r, hbr);
n.name = "G#";
n.stair = stb;
n.place.push_back(r);
std::keyboard.push_back(n);
startx += 20;
n.place.clear();
r.bottom = 100;
r.top = 65;
r.left = startx + 13;
r.right = startx + 27;
FillRect(hdc, &r, hbr);
n.name = "A#";
n.stair = stb;
n.place.push_back(r);
std::keyboard.push_back(n);
stb++;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) {
HDC hdc;
PAINTSTRUCT ps;
HBRUSH hbr;
POINT ptClient;
switch(Message) {
case WM_CREATE: {
std::init();
midiOutOpen(hMidiOut, midiOutGetNumDevs() - 1, 0, 0, 0);
break;
}
case WM_LBUTTONDOWN: {
GetCursorPos(&ptClient);
ScreenToClient(hwnd, &ptClient);
for (int i = 0; i < std::keyboard.size(); i++)
{
if (std::keyboard[i].judge(ptClient))
{
std::keyboard[i].splay();
while ((GetAsyncKeyState(VK_LBUTTON) & 0X8000) ? 1 : 0)
{
usleep(1);
}
std::keyboard[i].cplay();
break;
}
}
break;
}
case WM_PAINT: {
hdc = BeginPaint(hwnd, &ps);
int sx = 20;
for (int i = 1; i <= 7; i++)
{
whiteDraw(hdc, sx);
sx += 140;
}
sx = 20;
for (int i = 1; i <= 7; i++)
{
blackDraw(hdc, sx);
sx += 140;
}
HBRUSH hBr = CreateSolidBrush(RGB(0, 0, 0));
RECT r;
r.left = 20;
r.right = 1000;
r.bottom = 65;
r.top = 27;
FillRect(hdc, &r, hBr);
hBr = CreateSolidBrush(RGB(127, 127, 127));
r.left = 20;
r.right = 1000;
r.bottom = 65;
r.top = 63;
FillRect(hdc, &r, hBr);
EndPaint(hwnd, &ps);
break;
}
case WM_DESTROY: {
midiOutReset(*hMidiOut);
midiOutClose(*hMidiOut);
delete hMidiOut;
PostQuitMessage(0);
break;
}
default: return DefWindowProc(hwnd, Message, wParam, lParam);
}
return 0;
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
WNDCLASSEX wc;
HWND hwnd;
MSG msg;
memset(&wc,0,sizeof(wc));
wc.cbSize = sizeof(WNDCLASSEX);
wc.lpfnWndProc = WndProc;
wc.hInstance = hInstance;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wc.lpszClassName = "WindowClass";
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
if(!RegisterClassEx(&wc)) {
MessageBox(NULL, "Window Registration Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK);
return 0;
}
hwnd = CreateWindowEx(WS_EX_CLIENTEDGE, "WindowClass", "Piano", WS_VISIBLE | WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX,
CW_USEDEFAULT,
CW_USEDEFAULT,
1030,
205,
NULL,NULL,hInstance,NULL);
if(hwnd == NULL) {
MessageBox(NULL, "Window Creation Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK);
return 0;
}
ShowWindow(hwnd,nCmdShow);
UpdateWindow(hwnd);
while(GetMessage(&msg, NULL, 0, 0) > 0) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
记得在项目属性->参数->链接器里加上
-lwinmm
不然会逝世。