完全に我流ですが、コントロールの自作について説明していきます。
スタティックコントロールなどをサブクラス化する方法をちらほら見かけますが、私の場合ウィンドウクラスの登録から行います。その方が背景色などの設定が簡単だからです。
今回は、ボタンコントロールもどきを作ってみます。
仕様は、「ボタンが押された時の処理をコントロール側で行う」「右クリック、左クリックを検知する」とします。
LRESULT CALLBACK BtnProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp) { switch(msg){ case WM_LBUTTONDOWN: MessageBox(hwnd, TEXT("左クリックされました"), TEXT("自作ボタン"), 0); break; case WM_RBUTTONDOWN: MessageBox(hwnd, TEXT("右クリックされました"), TEXT("自作ボタン"), 0); break; case WM_PAINT: { PAINTSTRUCT ps; HDC hdc = BeginPaint(hwnd, &ps); TCHAR stWindowName[64]; GetWindowText(hwnd, stWindowName, 64); RECT rc; GetClientRect(hwnd, &rc); SetBkMode(hdc, TRANSPARENT); DrawText(hdc, stWindowName, -1, &rc, DT_CENTER); EndPaint(hwnd, &ps); } break; default: return (DefWindowProc(hwnd, msg, wp, lp)); } return 0; } HWND CreateBtn(LPCTSTR lpWindowName, HWND hOwner, HINSTANCE hinst) { TCHAR szClassName[] = TEXT("自作ボタン"); WNDCLASSEX wc; wc.cbSize = sizeof(WNDCLASSEX); wc.style = CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc = BtnProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hinst; wc.hIcon = NULL; wc.hIconSm = NULL; wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = (HBRUSH)GetStockObject(LTGRAY_BRUSH); wc.lpszMenuName = NULL; wc.lpszClassName = szClassName; RegisterClassEx(&wc); return CreateWindow(szClassName, lpWindowName, WS_CHILD | WS_VISIBLE, 0, 0, 0, 0, hOwner, NULL, hinst, NULL); }
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp) { static HWND hBtn[2]; switch(msg){ case WM_CREATE: { HINSTANCE hInst = ((CREATESTRUCT *)lp)->hInstance; hBtn[0] = CreateBtn(TEXT("1"), hwnd, hInst); hBtn[1] = CreateBtn(TEXT("2"), hwnd, hInst); } break; case WM_SIZE: MoveWindow(hBtn[0], 10, 10, LOWORD(lp)-20, 20, TRUE); MoveWindow(hBtn[1], 10, 50, LOWORD(lp)-20, 20, TRUE); break; case WM_DESTROY: PostQuitMessage(0); break; default: return (DefWindowProc(hwnd, msg, wp, lp)); } return 0; }
ウィンドウ内にボタンコントロールもどきが作成されています。これをクリックすると MessageBox() が表示されます。
見た目も機能もまだまだですが、とりあえずコントロールを自作することができました。後は、このウィンドウにイロイロ追加していけばオリジナルのコントロールを作ることができます。