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

各種ウィンドウを試してみた。
スタティックコントロールに描画するだけならオーナードローが適しているだろう。
  • 新規ウィンドウ
  • スタティックコントロール(サブクラス化)
  • スタティックコントロール(オーナードロー)

StaticDraw.cpp
// Unicode文字セット
#include <Windows.h>
#include <stdio.h>
#include "resource.h"
 
#define WIDTH(rect) ((rect).right - (rect).left)
#define HEIGHT(rect) ((rect).bottom - (rect).top)
 
#define CLASS_NAME TEXT("StaticDraw")
 
// 関数プロトタイプ宣言
void Trace(LPCTSTR format, ...);
INT_PTR CALLBACK MainDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
void OnInitDialog(HWND hDlg);
 
HWND CreateWnd(HINSTANCE hInstance, HWND hDlg);
LRESULT CALLBACK NewWndWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
LRESULT CALLBACK SubClsWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
void OnPaint(HWND hWnd, int nCtrlID);
void OnDrawItem(WPARAM wParam, LPARAM lParam);
 
// 外部変数構造体
static struct {
	HINSTANCE hInstance;
	HFONT hFont;
} g;
 
static WNDPROC PrevWndFunc;
 
//==============================================================================
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int)
{
	g.hInstance = hInstance;
	DialogBox(hInstance, MAKEINTRESOURCE(IDD_MAIN), NULL, MainDlgProc);
	return 0;
}
 
//------------------------------------------------------------------------------
void Trace(LPCTSTR format, ...)
{
	va_list arg_ptr;
	TCHAR buffer[256];
	int size;
 
	va_start(arg_ptr, format);
	size = _vsnwprintf_s(buffer, _TRUNCATE, format, arg_ptr);
	va_end(arg_ptr);
	OutputDebugString(buffer);
	if (size < 0) {
		OutputDebugString(L"...\n");
	}
}
 
//------------------------------------------------------------------------------
INT_PTR CALLBACK MainDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	INT_PTR nRet = TRUE;	// メッセージを処理した
 
	switch (uMsg) {
	case WM_DRAWITEM:
		OnDrawItem(wParam, lParam);
		break;
	case WM_COMMAND:
		switch (LOWORD(wParam)) {
		case IDCANCEL:
			EndDialog(hDlg, IDCANCEL);
			break;
		}
		break;
	case WM_SIZE:
		{
			POINTS pts = MAKEPOINTS(lParam);
			Trace(L"WM_SIZE(%u, %d, %d)\n", wParam, pts.x, pts.y);
		}
		break;
	case WM_INITDIALOG:
		OnInitDialog(hDlg);
		nRet = TRUE;	// SetFocusでフォーカスを設定した場合はFALSE
		break;
	case WM_CLOSE:
		EndDialog(hDlg, 0);
		break;
	case WM_DESTROY:
		Trace(L"WM_DESTROY\n");
		DeleteObject(g.hFont);
		break;
	default:
		nRet = FALSE;	// メッセージを処理しなかった
	}
	return nRet;
}
 
//------------------------------------------------------------------------------
void OnInitDialog(HWND hDlg)
{
	HWND hWnd;
 
	// 縦書きフォントの作成
	LOGFONT lf;
	ZeroMemory(&lf, sizeof lf);
	lf.lfHeight	= -20;
	lf.lfEscapement	= 2700;
	lf.lfOrientation= 2700;
	wcscpy_s(lf.lfFaceName, L"@MS Pゴシック");
	g.hFont = CreateFontIndirect(&lf);
 
	// ダイアログをクライアント領域に合わせる
	RECT rcWindow;
	RECT rcClient;
	GetWindowRect(hDlg, &rcWindow);
	GetClientRect(hDlg, &rcClient);
	SetWindowPos(hDlg, NULL, 0, 0,
		800 + (WIDTH(rcWindow) - WIDTH(rcClient)),
		400 + (HEIGHT(rcWindow) - HEIGHT(rcClient)),
		SWP_NOZORDER | SWP_NOMOVE);
 
	// 新規ウィンドウ
	hWnd = CreateWnd(g.hInstance, hDlg);
 
	// サブクラス化
	hWnd = CreateWindow(
		L"static", NULL,
		WS_CHILD | WS_VISIBLE,
		300, 50, 200, 300,
		hDlg, (HMENU)IDC_SUBCLS, g.hInstance, NULL);
	PrevWndFunc = (WNDPROC)GetWindowLong(hWnd, GWL_WNDPROC);
	SetWindowLong(hWnd, GWL_WNDPROC, (LONG)SubClsWndProc);
 
	// オーナードロー
	hWnd = CreateWindow(
		L"static", NULL,
		WS_CHILD | WS_VISIBLE | SS_OWNERDRAW,
		550, 50, 200, 300,
		hDlg, (HMENU)IDC_OWNDRAW, g.hInstance, NULL);
}
 
//==============================================================================
HWND CreateWnd(HINSTANCE hInstance, HWND hDlg)
{
	// ウィンドウクラスの登録
	WNDCLASSEX wcx;
	ZeroMemory(&wcx, sizeof wcx);
	wcx.cbSize		= sizeof wcx;
//	wcx.style		= CS_HREDRAW | CS_VREDRAW;
	wcx.lpfnWndProc		= NewWndWndProc;
	wcx.hInstance		= hInstance;
	wcx.hCursor		= LoadCursor(NULL, MAKEINTRESOURCE(IDC_ARROW));
	wcx.hbrBackground	= (HBRUSH)(COLOR_WINDOW + 1);
	wcx.lpszClassName	= CLASS_NAME;
	if (RegisterClassEx(&wcx) == 0) {
		return NULL;
	}
 
	// ウィンドウの作成
	HWND hWnd = CreateWindow(
		CLASS_NAME, NULL,
		WS_CHILD | WS_VISIBLE,
		50, 50, 200, 300,
		hDlg, (HMENU)IDC_NEWWND, hInstance, NULL);
	return hWnd;
}
 
//------------------------------------------------------------------------------
LRESULT CALLBACK NewWndWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	switch (uMsg) {
	case WM_PAINT:
		OnPaint(hWnd, IDC_NEWWND);
		return 0;
	}
	return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
 
//------------------------------------------------------------------------------
LRESULT CALLBACK SubClsWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	switch (uMsg) {
	case WM_PAINT:
		OnPaint(hWnd, IDC_SUBCLS);
		return 0;
	}
	return CallWindowProc(PrevWndFunc, hWnd, uMsg, wParam, lParam);
}
 
//------------------------------------------------------------------------------
void OnPaint(HWND hWnd, int nCtrlID)
{
	LPCTSTR pszStr;
	PAINTSTRUCT ps;
	HDC hdc = BeginPaint(hWnd, &ps);
	switch (nCtrlID) {
	case IDC_NEWWND:
		pszStr = L"新規ウィンドウ";
		break;
	case IDC_SUBCLS:
		pszStr = L"サブクラス化";
		FillRect(hdc, &ps.rcPaint, GetSysColorBrush(COLOR_WINDOW));
		break;
	default:
		goto Exit;
	}
	Trace(L"OnPaint(%s)\n", pszStr);
	HGDIOBJ hFontOld = SelectObject(hdc, g.hFont);
	TextOut(hdc, 100, 100, pszStr, wcslen(pszStr));
	SelectObject(hdc, hFontOld);
Exit:
	EndPaint(hWnd, &ps);
}
 
//------------------------------------------------------------------------------
void OnDrawItem(WPARAM wParam, LPARAM lParam)
{
	static LPCTSTR pszStr = L"オーナードロー";
	LPDRAWITEMSTRUCT pdi = (LPDRAWITEMSTRUCT)lParam;
 
	Trace(L"OnDrawItem(%u)\n", wParam);
	HDC hdc = pdi->hDC;
	SetBkMode(hdc, TRANSPARENT);	// 背景透過モード
 
	// 背景塗り潰し
	RECT rc;
	GetClientRect(pdi->hwndItem, &rc);
	FillRect(hdc, &rc, GetSysColorBrush(COLOR_WINDOW));
 
	HGDIOBJ hFontOld = SelectObject(hdc, g.hFont);
	TextOut(hdc, 100, 100, pszStr, wcslen(pszStr));
	SelectObject(hdc, hFontOld);
}
 

resource.h
#define IDD_MAIN	100
 
#define IDC_NEWWND	1000	// 新規ウィンドウ
#define IDC_SUBCLS	1001	// サブクラス化
#define IDC_OWNDRAW	1002	// オーナードロー
 

StaticDraw.rc
// resource script
#include <windows.h>
#include "resource.h"
 
IDD_MAIN DIALOGEX 100, 100, 320, 200
STYLE WS_POPUPWINDOW | WS_MINIMIZEBOX
EXSTYLE WS_EX_APPWINDOW
CAPTION "StaticDraw"
FONT 9, "MS Pゴシック"
BEGIN
END
 
最終更新:2012年10月24日 12:38