開発環境 Microsoft Visual Studio Express 2013 for Windows Desktop
実行環境 Microsoft Windows 8.1 (64bit)
プロジェクトの種類 Visual C++/Win32 プロジェクト
プロジェクト名 Percussion
アプリケーションの種類 Windows アプリケーション
追加のオプション 空のプロジェクト, SDLチェック

Percussion.cpp
#pragma comment(lib, "winmm")
 
#include <Windows.h>
#include <windowsx.h>
#include <CommCtrl.h>
#include <wchar.h>
#include "resource.h"
 
#define MAKESMSG(st,ch,d1,d2) (st)<<4|(ch)|(d1)<<8|(d2)<<16
 
// GM Standard Drum Map
LPCTSTR percussion[] = {
	L"Bass Drum 2",
	L"Bass Drum 1",
	L"Side Stick",
	L"Snare Drum 1",
	L"Hand Clap",
	L"Snare Drum 2",
	L"Low Tom 2",
	L"Closed Hi-hat",
	L"Low Tom 1",
	L"Pedal Hi-hat",
	L"Mid Tom 2",
	L"Open Hi-hat",
	L"Mid Tom 1",
	L"High Tom 2",
	L"Crash Cymbal 1",
	L"High Tom 1",
	L"Ride Cymbal 1",
	L"Chinese Cymbal",
	L"Ride Bell",
	L"Tambourine",
	L"Splash Cymbal",
	L"Cowbell",
	L"Crash Cymbal 2",
	L"Vibra Slap",
	L"Ride Cymbal 2",
	L"High Bongo",
	L"Low Bongo",
	L"Mute High Conga",
	L"Open High Conga",
	L"Low Conga",
	L"High Timbale",
	L"Low Timbale",
	L"High Agogo",
	L"Low Agogo",
	L"Cabasa",
	L"Maracas",
	L"Short Whistle",
	L"Long Whistle",
	L"Short Guiro",
	L"Long Guiro",
	L"Claves",
	L"High Wood Block",
	L"Low Wood Block",
	L"Mute Cuica",
	L"Open Cuica",
	L"Mute Triangle",
	L"Open Triangle",
};
 
const int scale[] = { 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0 };
 
// 外部変数
HINSTANCE hInst;
HMIDIOUT hmo;
HBRUSH brush[3];
int pushid = 0;
 
// 関数プロトタイプ宣言
void Trace(LPCTSTR format, ...);
 
INT_PTR CALLBACK DlgMain(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
void OnInitDialog(HWND hDlg, LPARAM lParam);
void OnDestroy(HWND hDlg);
void OnLButtonDown(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
void OnLButtonUp(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
INT_PTR OnCtlColorStatic(WPARAM wParam, LPARAM lParam);
 
//==============================================================================
int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int)
{
	hInst = hInstance;
	midiOutOpen(&hmo, MIDI_MAPPER, NULL, 0, CALLBACK_NULL);
 
	DialogBox(hInstance, MAKEINTRESOURCE(IDD_MAIN), NULL, DlgMain);
 
	midiOutReset(hmo);
	midiOutClose(hmo);
	return 0;
}
 
void Trace(LPCTSTR format, ...)
{
	va_list arg_ptr;
	va_start(arg_ptr, format);
	TCHAR buffer[256];
	int size = _vsnwprintf_s(buffer, _TRUNCATE, format, arg_ptr);
	va_end(arg_ptr);
	OutputDebugString(buffer);
	if (size < 0) {
		OutputDebugString(L"...\n");
	}
}
 
//------------------------------------------------------------------------------
INT_PTR CALLBACK DlgMain(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	INT_PTR res = TRUE;	// メッセージを処理した
	switch (uMsg) {
	case WM_CTLCOLORSTATIC:
		return OnCtlColorStatic(wParam, lParam);
	case WM_LBUTTONDOWN:
		OnLButtonDown(hDlg, uMsg, wParam, lParam);
		break;
	case WM_LBUTTONUP:
		OnLButtonUp(hDlg, uMsg, wParam, lParam);
		break;
	case WM_INITDIALOG:
		OnInitDialog(hDlg, lParam);
		break;
	case WM_CLOSE:
		EndDialog(hDlg, 0);
		break;
	case WM_DESTROY:
		OnDestroy(hDlg);
		break;
	default:
		res = FALSE;	// メッセージを処理しなかった
	}
	return res;
}
 
void OnInitDialog(HWND hDlg, LPARAM lParam)
{
	RECT rw, rc;
	GetWindowRect(hDlg, &rw);
	GetClientRect(hDlg, &rc);
	int cx = (rw.right - rw.left) - rc.right + 675;
	int cy = (rw.bottom - rw.top) - rc.bottom + 375;
	SetWindowPos(hDlg, HWND_TOP, 200, 200, cx, cy, 0);
 
	for (int n = 0; n < 47; n++) {
		int x = 10 + 165 * (n / 12);
		int y = 10 + 30 * (n % 12);
		int id = 35 + n;
		HWND hWnd = CreateWindowEx(WS_EX_CLIENTEDGE, WC_STATIC, NULL,
			WS_CHILD | WS_VISIBLE,
			x, y, 160, 25, hDlg, HMENU(id), hInst, NULL);
		TCHAR buf[32];
		swprintf_s(buf, L"%d:%s", id, percussion[n]);
		SetDlgItemText(hDlg, id, buf);
	}
 
	brush[0] = GetStockBrush(WHITE_BRUSH);
	brush[1] = GetStockBrush(LTGRAY_BRUSH);
	brush[2] = CreateSolidBrush(RGB(0xff, 0xff, 0x00));
}
 
void OnDestroy(HWND hDlg)
{
	for (int n = 0; n < _countof(brush); n++) {
		DeleteObject(brush[n]);
	}
}
 
void OnLButtonDown(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	SetCapture(hDlg);
 
	POINT pt;
	pt.x = GET_X_LPARAM(lParam);
	pt.y = GET_Y_LPARAM(lParam);
	HWND hChild = ChildWindowFromPoint(hDlg, pt);
	LONG id = GetWindowLong(hChild, GWL_ID);
	Trace(L"OnLButtonDown(%d)\n", id);
 
	if (id) {
		pushid = id;
		InvalidateRect(hChild, NULL, FALSE);
 
		midiOutShortMsg(hmo, MAKESMSG(0x9, 10 - 1, pushid, 127));	// note on
	}
}
 
void OnLButtonUp(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	ReleaseCapture();
 
	Trace(L"OnLButtonUp(%d)\n", pushid);
 
	if (pushid) {
		midiOutShortMsg(hmo, MAKESMSG(0x8, 10 - 1, pushid, 0));		// note off
 
		HWND hChild = GetDlgItem(hDlg, pushid);
		InvalidateRect(hChild, NULL, FALSE);
		pushid = 0;
	}
}
 
INT_PTR OnCtlColorStatic(WPARAM wParam, LPARAM lParam)
{
	LONG id = GetWindowLong(HWND(lParam), GWL_ID);
//	Trace(L"OnCtlColorStatic(%d)\n", id);
 
	if (id) {
		HDC hdc = HDC(wParam);
		SetBkMode(hdc, TRANSPARENT);
		return INT_PTR(brush[(id == pushid) ? 2 : scale[id % 12]]);
	}
	return FALSE;
}
 

resource.h
#define IDD_MAIN	100
 

Percussion.rc
// resource script
#include <Windows.h>
#include "resource.h"
 
IDD_MAIN DIALOGEX 0, 0, 0, 0
STYLE WS_POPUPWINDOW | WS_MINIMIZEBOX
EXSTYLE WS_EX_APPWINDOW
CAPTION "Percussion"
BEGIN
END
 
最終更新:2014年04月10日 10:50