開発環境 Microsoft Visual C++ 2010 Express (SP1)
実行環境 Microsoft Windows XP Home Edition (SP3)
プロジェクトの種類 Win32 プロジェクト
プロジェクト名 WaveGraph1
アプリケーションの種類 Windows アプリケーション
追加のオプション 空のプロジェクト
文字セット Unicode

WaveGraph1.cpp
#define _USE_MATH_DEFINES
 
#include <Windows.h>
#include <math.h>
#include <tchar.h>
 
#define APP_NAME	TEXT("WaveGraph1")
#define DATA_NUM	1000
 
// 関数プロトタイプ宣言
void Trace(LPCTSTR format, ...);
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
void OnCreate(HWND hWnd);
void OnSize(HWND hWnd, WPARAM wParam, LPARAM lParam);
void OnHScroll(HWND hWnd, WPARAM wParam);
void OnPaint(HWND hWnd);
 
// 外部変数
SCROLLINFO siHorz;
BYTE waveformData[DATA_NUM];
 
//==============================================================================
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int nCmdShow)
{
	for (int i = 0; i < DATA_NUM; i++) {
		double t = fmod(i * 441.0 / 44100, 1.0);
		double y = sin(2 * M_PI * t);
		waveformData[i] = BYTE(128 + 64 * y);
	}
 
	// ウィンドウクラスの登録
	WNDCLASSEX wcx;
	ZeroMemory(&wcx, sizeof wcx);
	wcx.cbSize		= sizeof wcx;
	wcx.style		= CS_HREDRAW | CS_VREDRAW;
	wcx.lpfnWndProc		= WndProc;
	wcx.hInstance		= hInstance;
	wcx.hCursor		= LoadCursor(NULL, MAKEINTRESOURCE(IDC_ARROW));
	wcx.hbrBackground	= HBRUSH(COLOR_WINDOW + 1);
	wcx.lpszClassName	= APP_NAME;
	if (RegisterClassEx(&wcx) == 0) {
		return 0;
	}
 
	// ウィンドウの作成
	HWND hWnd = CreateWindow(
		APP_NAME, APP_NAME,
		WS_OVERLAPPEDWINDOW | WS_HSCROLL,
		CW_USEDEFAULT, 0,
		CW_USEDEFAULT, 0,
		NULL, NULL, hInstance, NULL);
	if (hWnd == NULL) {
		return 0;
	}
	ShowWindow(hWnd, nCmdShow);
	UpdateWindow(hWnd);
 
	// メッセージループ
	MSG msg;
	while (GetMessage(&msg, NULL, 0, 0)) {
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}
	return msg.wParam;
}
 
void Trace(LPCTSTR format, ...)
{
	va_list arg_ptr;
	TCHAR buffer[256];
	int size;
 
	va_start(arg_ptr, format);
	size = _vsntprintf_s(buffer, _countof(buffer), _TRUNCATE, format, arg_ptr);
	va_end(arg_ptr);
	OutputDebugString(buffer);
	if (size < 0) {
		OutputDebugString(_T("...\n"));
	}
}
 
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	switch (uMsg) {
	case WM_PAINT:
		OnPaint(hWnd);
		return 0;
	case WM_HSCROLL:
		OnHScroll(hWnd, wParam);
		return 0;
	case WM_SIZE:
		OnSize(hWnd, wParam, lParam);
		return 0;
	case WM_CREATE:
		OnCreate(hWnd);
		return 0;
	case WM_DESTROY:
		PostQuitMessage(0);
		return 0;
	}
	return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
 
void OnCreate(HWND hWnd)
{
	RECT rc;
	GetClientRect(hWnd, &rc);
 
	siHorz.cbSize	= sizeof siHorz;
	siHorz.fMask	= SIF_RANGE | SIF_PAGE | SIF_POS | SIF_DISABLENOSCROLL;
	siHorz.nMin	= 0;
	siHorz.nMax	= DATA_NUM - 1;
	siHorz.nPage	= rc.right;
	siHorz.nPos	= 0;
	SetScrollInfo(hWnd, SB_HORZ, &siHorz, FALSE);
}
 
void OnSize(HWND hWnd, WPARAM wParam, LPARAM lParam)
{
	if (wParam == SIZE_MINIMIZED) return;
 
	siHorz.nPage	= LOWORD(lParam);
	int nPosMax	= max(siHorz.nMax - (int)siHorz.nPage + 1, 0);
	siHorz.nPos	= min(siHorz.nPos, nPosMax);
	SetScrollInfo(hWnd, SB_HORZ, &siHorz, TRUE);
}
 
void OnHScroll(HWND hWnd, WPARAM wParam)
{
	int nPos = siHorz.nPos;
 
	switch (LOWORD(wParam)) {
	case SB_LINEUP:
		nPos -= 10;
		break;
	case SB_LINEDOWN:
		nPos += 10;
		break;
	case SB_PAGEUP:
		nPos -= siHorz.nPage;
		break;
	case SB_PAGEDOWN:
		nPos += siHorz.nPage;
		break;
	case SB_THUMBTRACK:
		SCROLLINFO si;
		si.cbSize	= sizeof si;
		si.fMask	= SIF_TRACKPOS;
		if (GetScrollInfo(hWnd, SB_HORZ, &si) != 0) {
			nPos = si.nTrackPos;
		}
		break;
	}
 
	int nPosMax = max(siHorz.nMax - (int)siHorz.nPage + 1, 0);
	nPos = min(nPos, nPosMax);
	nPos = max(nPos, 0);
	if (nPos == siHorz.nPos) return;
 
	ScrollWindowEx(hWnd, siHorz.nPos - nPos, 0,
		NULL, NULL, NULL, NULL, SW_INVALIDATE | SW_ERASE);
	siHorz.nPos = nPos;
	SetScrollInfo(hWnd, SB_HORZ, &siHorz, TRUE);
	UpdateWindow(hWnd);
}
 
void OnPaint(HWND hWnd)
{
	PAINTSTRUCT ps;
	HDC hdc = BeginPaint(hWnd, &ps);
 
	RECT rc;
	GetClientRect(hWnd, &rc);
 
	HPEN pen = CreatePen(PS_SOLID, 0, RGB(0,0,255));
	HGDIOBJ penOld = SelectObject(hdc, pen);
	for (int x = 0; x < rc.right; x++) {
		int i = siHorz.nPos + x;
		if (DATA_NUM <= i) break;
		MoveToEx(hdc, x, rc.bottom / 2, NULL);
		LineTo(hdc, x, rc.bottom * (255 - waveformData[i]) / 256);
	}
	SelectObject(hdc, penOld);
	DeleteObject(pen);
 
	EndPaint(hWnd, &ps);
}
 
最終更新:2013年01月30日 21:11