#include "myWin.h" #pragma comment(lib,"winmm.lib") #define MPUSH 0x9 #define MCTONE 0xC #define SMSG(st, ch, d1, d2) ((DWORD)(st<<4|ch|((d1)<<8)|(d2)<<16)) static HMIDIOUT hM; static BYTE note=0x3C, vel=0x40, prog=0; static HBITMAP hB; static BITMAP bB; static HDC hBuff; static int keyTab[][2] = {//キーボードと音の対応表 //ド       # レ   # ミ ファ {'A',0},{'Z',0},{'S',1},{'X',2},{'D',3},{'C',4},{'F',5},{'V',5}, //ファ# ソ # ラ    # シ ド # {'G',6},{'B',7},{'H',8},{'N',9},{'J',10},{'M',11},{0xBC,12},{'K',12},{'L',13}, //ド        # レ    # ミ ファ {'1',12},{'Q',12},{'2',13},{'W',14},{'3',15},{'E',16},{'4',17},{'R',17}, //ファ# ソ # ラ    # シ ド {'5',18},{'T',19},{'6',20},{'Y',21},{'7',22},{'U',23},{'8',24},{'I',24},{'9',25}, {-1,-1} }; static int mouseKey,pushTab[26],ch=0;//チャネル番号:音色を変えるときは、これを変更する;; static int halfTab[]= {1,3,0,6,8,10, 0,13,15, 0,18,20,22, 0,25}; static int wholeTab[]={0,2,4,5,7, 9,11,12,14,16,17,19,21,23,24}; void clearBitmap(){ //■ビットマップクリア SelectObject(hBuff,GetStockObject(NULL_PEN)); HBRUSH brush=CreateSolidBrush(0x77FF); SelectObject(hBuff,brush); Rectangle(hBuff,0,0,340,120); DeleteObject(brush); } void initBitmap(HWND hw){ //■ビットマップ初期設定 HDC hdc=GetDC(hw); hB=CreateCompatibleBitmap(hdc,1000,400); hBuff=CreateCompatibleDC(hdc); SelectObject(hBuff,hB); clearBitmap(); ReleaseDC(hw,hdc); } void drawKeyCom(int X, int Y, int W, int H, int C){ HPEN pen=CreatePen(PS_SOLID,1,0);SelectObject(hBuff,pen); HBRUSH brush=CreateSolidBrush(C); SelectObject(hBuff,brush); RoundRect(hBuff,X,Y,X+W,Y+H,3,3); DeleteObject(pen); DeleteObject(brush); } void drawWKey (int X, int Y){ drawKeyCom(X, Y, 21, 50, 0xFFFFFF);} void drawWKeyPush(int X, int Y){ drawKeyCom(X, Y, 21, 47, 0xFFFF );} void drawBKey (int X, int Y){ drawKeyCom(X, Y, 15, 30, 0 );} void drawBKeyPush(int X, int Y){ drawKeyCom(X, Y, 15, 30, 0xFFF );} void drawPiano(){ clearBitmap(); drawKeyCom(2, 10, 8, 50, 0x5577FF); int X=10; for(int i=0;i<15;i++, X+=20) if(pushTab[wholeTab[i]]) drawWKeyPush(X,10); else drawWKey(X,10); drawKeyCom(X+1, 10, 9, 50, 0x5577FF); X=23; for(int i=0;i<16;i++, X+=20) if(halfTab[i]>0) if(pushTab[halfTab[i]]) drawBKeyPush(X,10); else drawBKey(X,10); } int searchKeyTab(int wp){ for(int i=0;keyTab[i][0]>=0;i++) if(wp==keyTab[i][0]) return keyTab[i][1]; return -1; } void stopMTone(){ midiOutShortMsg(hM,SMSG(MPUSH, ch,mouseKey+note-12,0)); pushTab[mouseKey]=0;mouseKey=-1; } void soundTone(int mK){ mouseKey=mK; pushTab[mouseKey]=1; midiOutShortMsg(hM,SMSG(MPUSH, ch,mouseKey+note-12,vel)); } void stopAndMTone(int mK){ stopMTone(); soundTone(mK); } void procLButtonDown(HWND hw, WPARAM wp,LPARAM lp){ int x=LOWORD(lp), y=HIWORD(lp), mK; if(mouseKey>=0) stopMTone(); if(y>=40 && y<=60){ mK=(x-10)/20; if(mK>=0 || mK<14)soundTone(wholeTab[mK]); } else if(y>=10 && y<=40){ mK=(x-23)/20; if(mK>=0 && mK<15){ if((mK=halfTab[mK])!=0) soundTone(mK); } } drawPiano(); InvalidateRect(hw,NULL,TRUE); } void procMouseMove(HWND hw, WPARAM wp,LPARAM lp){ if(mouseKey<0) return; int x=LOWORD(lp), y=HIWORD(lp), mK; if(y>=40 && y<=60){ mK=(x-10)/20; if(mK>=0 || mK<14) if((mK=wholeTab[mK])!=mouseKey)stopAndMTone(mK); } else if(y>=10 && y<=40){ mK=(x-23)/20; if(mK>=0 && mK<15) if((mK=halfTab[mK])!=0) if(mK!=mouseKey)stopAndMTone(mK); } else stopMTone(); drawPiano(); InvalidateRect(hw,NULL,TRUE); } void procLButtonUp(HWND hw, WPARAM wp,LPARAM lp){ stopMTone(); drawPiano(); InvalidateRect(hw,NULL,TRUE); } void dspProg(HWND hw){ TCHAR str[128]; wsprintf(str,TEXT("音の強さ:%02X, 音色: %02X"), vel, prog); SetWindowText(hw,str); } void changeTone(HWND hw){ dspProg(hw); midiOutShortMsg(hM,SMSG(MCTONE,ch,prog,0)); } void soundKTone(int ip){midiOutShortMsg(hM,SMSG(MPUSH, ch,ip+note-12,vel));} void stopKTone (int ip){midiOutShortMsg(hM,SMSG(MPUSH, ch,ip+note-12,0 ));} void procKeyDown(HWND hw, WPARAM wp,LPARAM lp){ switch(wp){ case VK_UP : if(vel<0x07F)vel++ ; dspProg(hw) ; return; case VK_DOWN : if(vel>0 )vel-- ; dspProg(hw) ; return; case VK_LEFT : if(prog<0x7F)prog++; changeTone(hw); return; case VK_RIGHT: if(prog>0 )prog--; changeTone(hw); return; } int ip=searchKeyTab(wp); if(ip<0) return; if(pushTab[ip]==0) soundKTone(ip); pushTab[ip]=1;drawPiano(); InvalidateRect(hw,NULL,TRUE); } void procKeyUp(HWND hw, WPARAM wp,LPARAM lp){ int ip=searchKeyTab(wp); if(ip<0) return; pushTab[ip]=0;drawPiano(); stopKTone(ip); InvalidateRect(hw,NULL,TRUE); } void procCreate(HWND hw, WPARAM wp,LPARAM lp){ //■Create時処理 initBitmap(hw); SetWindowText(hw,TEXT("キーボードをピアノの鍵盤がわりに" )); MoveWindow(hw,0,0,340,110,TRUE); for(int i=0;i<26;i++)pushTab[i]=0; midiOutOpen(&hM,MIDIMAPPER,NULL,0,CALLBACK_NULL); midiOutShortMsg(hM, SMSG(MCTONE,ch,prog,0)); drawPiano(); mouseKey=-1; InvalidateRect(hw,NULL,TRUE); } void procPaint(HWND hw, WPARAM wp,LPARAM lp){ PAINTSTRUCT ps; HDC hdc = BeginPaint(hw,&ps); BitBlt(hdc,0,0,340,110, hBuff,0,0,SRCCOPY); EndPaint(hw,&ps); } LRESULT CALLBACK WndProc(HWND hw, UINT msg, WPARAM wp,LPARAM lp){//■Window Procedure switch(msg){ case WM_DESTROY : DeleteObject(hB); midiOutReset(hM); midiOutClose(hM); PostQuitMessage(0); return 0; case WM_CREATE : procCreate(hw,wp,lp) ; return 0; case WM_PAINT : procPaint(hw,wp,lp) ; return 0; case WM_KEYDOWN : procKeyDown(hw,wp,lp) ; break; case WM_KEYUP : procKeyUp(hw,wp,lp) ; break; case WM_LBUTTONDOWN : procLButtonDown(hw,wp,lp) ; break; case WM_LBUTTONUP : procLButtonUp(hw,wp,lp) ; break; case WM_MOUSEMOVE : procMouseMove(hw,wp,lp) ; break; } return DefWindowProc(hw,msg,wp,lp); }