Created
April 22, 2025 05:55
-
-
Save bg1bgst333/b7902e378ac13ee3eda5426ea758a70d to your computer and use it in GitHub Desktop.
MEASUREITEMSTRUCT
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ヘッダファイルのインクルード | |
// 既定のヘッダファイル | |
#include <windows.h> // 標準WindowsAPI | |
#include <tchar.h> // TCHAR型 | |
#include <commctrl.h> // コモンコントロール | |
// 独自のヘッダファイル | |
#include "resource.h" // リソースID | |
// マクロの宣言 | |
#define ID_BUTTON1 501 // Button1 | |
// 関数のプロトタイプ宣言 | |
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); // ウィンドウプロシージャ | |
// _tWinMain関数の定義 | |
int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nShowCmd){ | |
// 変数・配列の宣言・初期化 | |
HWND hWnd; // ウィンドウハンドルhWnd. | |
MSG msg; // メッセージmsg. | |
WNDCLASS wc; // ウィンドウクラスwc. | |
// ウィンドウクラスの設定 | |
wc.lpszClassName = _T("MEASUREITEMSTRUCT"); // ウィンドウクラス名"MEASUREITEMSTRUCT". | |
wc.style = CS_HREDRAW | CS_VREDRAW; // スタイルCS_HREDRAW | CS_VREDRAW. | |
wc.lpfnWndProc = WindowProc; // ウィンドウプロシージャWindowProc. | |
wc.hInstance = hInstance; // インスタンスhInstance. | |
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); // アイコンはアプリケーション既定のもの. | |
wc.hCursor = LoadCursor(NULL, IDC_ARROW); // カーソルIDC_ARROW. | |
wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); // 背景WHITE_BRUSH. | |
wc.lpszMenuName = MAKEINTRESOURCE(IDR_MAINMENU); // メニューにはIDR_MAINMENUをMAKEINTRESOURCEマクロで指定. | |
wc.cbClsExtra = 0; // 0. | |
wc.cbWndExtra = 0; // 0. | |
// ウィンドウクラスの登録 | |
if (!RegisterClass(&wc)){ // RegisterClassでウィンドウクラスを登録. | |
// エラー処理 | |
return -1; // 異常終了(-1) | |
} | |
// ウィンドウの作成 | |
hWnd = CreateWindow(_T("MEASUREITEMSTRUCT"), _T("MEASUREITEMSTRUCT"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL); // CreateWindowでウィンドウ作成. | |
if (hWnd == NULL){ | |
// エラー処理 | |
return -2; // 異常終了(-2) | |
} | |
// ウィンドウの表示 | |
ShowWindow(hWnd, SW_SHOW); | |
// メッセージループ | |
while (GetMessage(&msg, NULL, 0, 0) > 0){ // GetMessageでメッセージ取得. | |
// ウィンドウメッセージの送出 | |
TranslateMessage(&msg); // TranslateMessageで仮想キーメッセージを文字メッセージへ変換. | |
DispatchMessage(&msg); // DispatchMessageで受け取ったメッセージをウィンドウプロシージャに送出. | |
} | |
// プログラムの終了 | |
return (int)msg.wParam; // msg.wParamを返す. | |
} | |
// WindowProc関数の定義 | |
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam){ | |
// 配列の宣言. | |
LPCTSTR lpctszItemStr[] = {_T("あいうえお"), _T("かきくけこ"), _T("さしすせそ")}; // メニューアイテムテキスト配列. | |
// ウィンドウメッセージに対する処理. | |
switch (uMsg){ // uMsgごとに処理振り分け. | |
// ウィンドウの作成が開始された時. | |
case WM_CREATE: | |
// WM_CREATEブロック | |
{ | |
// 変数の宣言 | |
LPCREATESTRUCT lpCS; // CREATESTRUCT構造体ポインタlpCS. | |
HWND hButton1; // ボタンハンドルhButton1. | |
// lpCSの取得. | |
lpCS = (LPCREATESTRUCT)lParam; // lParamをlpCSに変換. | |
// Button1の作成.(無効にしておく.) | |
hButton1 = CreateWindow(WC_BUTTON, _T("Button1"), WS_CHILD | WS_VISIBLE | BS_OWNERDRAW | WS_DISABLED, 50, 50, 200, 100, hwnd, (HMENU)ID_BUTTON1, lpCS->hInstance, NULL); // CreateWindowで"Button1"を作成. | |
if (hButton1 == NULL){ | |
return -1; | |
} | |
// メニューの追加. | |
HMENU hMainMenu = GetMenu(hwnd); | |
HMENU hSubMenu = CreatePopupMenu(); | |
AppendMenu(hSubMenu, MF_OWNERDRAW, ID_ITEM_OWNERDRAW_MENUITEM_1, (LPCTSTR)0); | |
AppendMenu(hSubMenu, MF_OWNERDRAW, ID_ITEM_OWNERDRAW_MENUITEM_2, (LPCTSTR)1); | |
AppendMenu(hSubMenu, MF_OWNERDRAW, ID_ITEM_OWNERDRAW_MENUITEM_3, (LPCTSTR)2); | |
AppendMenu(hMainMenu, MF_POPUP, (UINT_PTR)hSubMenu, _T("Menu(&M)")); | |
// ウィンドウ作成成功 | |
return 0; // 0を返すとウィンドウ作成成功となる. | |
} | |
// 既定の処理へ向かう. | |
break; | |
// ウィンドウが破棄された時. | |
case WM_DESTROY: | |
// WM_DESTROYブロック | |
{ | |
// 終了メッセージの送信. | |
PostQuitMessage(0); // PostQuitMessageで終了コードを0とするWM_QUITを送信. | |
} | |
// 既定の処理へ向かう. | |
break; | |
// オーナードローで描画が要求された時. | |
case WM_DRAWITEM: | |
// WM_DRAWITEMブロック | |
{ | |
// 変数の宣言 | |
LPDRAWITEMSTRUCT lpDIS; // DRAWITEMSTRUCT構造体ポインタlpDIS. | |
HBRUSH hBrush; // ブラシハンドルhBrush. | |
HBRUSH hOldBrush; // 以前のブラシハンドルhOldBrush. | |
// lpDISの取得. | |
lpDIS = (LPDRAWITEMSTRUCT)lParam; // lParamをlpDISに変換. | |
// ボタンの場合. | |
if (lpDIS->CtlType == ODT_BUTTON){ | |
// ボタンが無効か. | |
if (lpDIS->itemState & ODS_DISABLED){ // 無効. | |
SetBkMode(lpDIS->hDC, TRANSPARENT); // SetBkModeで背景透過. | |
SetTextColor(lpDIS->hDC, RGB(0xff, 0xff, 0xff)); // SetTextColorで文字色を白に. | |
hBrush = CreateSolidBrush(RGB(0x80, 0x80, 0x80)); // CreateSolidBrushで灰ブラシを作成. | |
hOldBrush = (HBRUSH)SelectObject(lpDIS->hDC, hBrush); // SelectObjectでhBrushを選択. | |
Rectangle(lpDIS->hDC, 0, 0, lpDIS->rcItem.right, lpDIS->rcItem.bottom); // Rectangleで矩形を描画. | |
TextOut(lpDIS->hDC, 40, 40, _T("無効になっている"), lstrlen( _T("無効になっている"))); // TextOutで"無効になっている"を描画. | |
} | |
else{ // 有効. | |
// 押されている状態か. | |
if (lpDIS->itemState & ODS_SELECTED){ // ビットフラグODS_SELECTEDが立っている. | |
SetBkMode(lpDIS->hDC, TRANSPARENT); // SetBkModeで背景透過. | |
SetTextColor(lpDIS->hDC, RGB(0xff, 0xff, 0xff)); // SetTextColorで文字色を白に. | |
hBrush = CreateSolidBrush(RGB(0xff, 0x0, 0x0)); // CreateSolidBrushで赤ブラシを作成. | |
hOldBrush = (HBRUSH)SelectObject(lpDIS->hDC, hBrush); // SelectObjectでhBrushを選択. | |
Rectangle(lpDIS->hDC, 0, 0, lpDIS->rcItem.right, lpDIS->rcItem.bottom); // Rectangleで矩形を描画. | |
TextOut(lpDIS->hDC, 40, 40, _T("押されている"), lstrlen( _T("押されている"))); // TextOutで"押されている"を描画. | |
} | |
else{ // 押されていない. | |
SetBkMode(lpDIS->hDC, TRANSPARENT); // SetBkModeで背景透過. | |
SetTextColor(lpDIS->hDC, RGB(0xff, 0xff, 0xff)); // SetTextColorで文字色を白に. | |
hBrush = CreateSolidBrush(RGB(0x0, 0x0, 0xff)); // CreateSolidBrushで青ブラシを作成. | |
hOldBrush = (HBRUSH)SelectObject(lpDIS->hDC, hBrush); // SelectObjectでhBrushを選択. | |
Rectangle(lpDIS->hDC, 0, 0, lpDIS->rcItem.right, lpDIS->rcItem.bottom); // Rectangleで矩形を描画. | |
TextOut(lpDIS->hDC, 40, 40, _T("押されていない"), lstrlen( _T("押されていない"))); // TextOutで"押されていない"を描画. | |
} | |
} | |
SelectObject(lpDIS->hDC, hOldBrush); // SelectObjectで以前のブラシに戻す. | |
DeleteObject(hBrush); // DeleteObjectでhBrushを破棄. | |
} | |
else{ // メニュー | |
// メニューアイテムの描画サイズをテキストサイズに合わせて描画. | |
HDC hDC = lpDIS->hDC; | |
HFONT hFont = CreateFont(32, 0, 0, 0, FW_REGULAR, FALSE, FALSE, FALSE, SHIFTJIS_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH, _T("MS 明朝")); // CreateFontで"MS 明朝"フォントのGDIオブジェクトを新規に作成し, hFontに格納.(設定はデフォルトのものにしておく.) | |
HFONT hOld = (HFONT)SelectObject(hDC, hFont); | |
TextOut(hDC, lpDIS->rcItem.left, lpDIS->rcItem.top, lpctszItemStr[lpDIS->itemData], lstrlen(lpctszItemStr[lpDIS->itemData])); | |
SelectObject(hDC, hOld); | |
DeleteObject(hFont); | |
} | |
// TRUEを返す. | |
return TRUE; | |
} | |
// 既定の処理へ向かう. | |
break; | |
// オーナードローでアイテムの計測を要求された時. | |
case WM_MEASUREITEM: | |
// WM_MEASUREITEMブロック | |
{ | |
// 変数の宣言 | |
LPMEASUREITEMSTRUCT lpMIS; // MEASUREITEMSTRUCT構造体ポインタlpMIS. | |
// lpMISの取得. | |
lpMIS = (LPMEASUREITEMSTRUCT)lParam; // lParamをlpMISに変換. | |
// メニューアイテムの描画サイズをテキストサイズに合わせる. | |
HDC hDC = GetDC(hwnd); | |
HFONT hFont = CreateFont(32, 0, 0, 0, FW_REGULAR, FALSE, FALSE, FALSE, SHIFTJIS_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH, _T("MS 明朝")); // CreateFontで"MS 明朝"フォントのGDIオブジェクトを新規に作成し, hFontに格納.(設定はデフォルトのものにしておく.) | |
HFONT hOld = (HFONT)SelectObject(hDC, hFont); | |
SIZE sz = {0}; | |
GetTextExtentPoint32(hDC, lpctszItemStr[lpMIS->itemData], lstrlen(lpctszItemStr[lpMIS->itemData]), &sz); | |
lpMIS->itemWidth = sz.cx; | |
lpMIS->itemHeight = sz.cy; | |
SelectObject(hDC, hOld); | |
DeleteObject(hFont); | |
// 終了 | |
return TRUE; | |
} | |
// 既定の処理へ向かう. | |
break; | |
// メニュー項目が選択されたり, ボタンなどのコントロールが押されたりした時. | |
case WM_COMMAND: // メニュー項目が選択されたり, ボタンなどのコントロールが押されたりした時.(uMsgがWM_COMMANDの時.) | |
// WM_COMMANDブロック | |
{ | |
// どのメニュー項目が選択されたかを判定する. | |
switch (LOWORD(wParam)){ // LOWORD(wParam)で選択されたメニュー項目のIDが取得できるので, その値で判定する. | |
// 取得したIDごとに処理を分岐. | |
// Enable Buttonが選択された時. | |
case ID_ITEM_ENABLE_BUTTON: | |
// ID_ITEM_ENABLE_BUTTONブロック | |
{ | |
// チェック済みかそうでないか調べる. | |
UINT uiRet = GetMenuState(GetMenu(hwnd), ID_ITEM_ENABLE_BUTTON, MF_BYCOMMAND); // GetMenuStateでID_ITEM_ENABLE_BUTTONがチェックされてるか取得. | |
if (uiRet & MF_CHECKED){ // チェックされている. | |
EnableWindow(GetDlgItem(hwnd, ID_BUTTON1), FALSE); // EnableWindowでID_BUTTON1を無効化. | |
// Enable Buttonのチェックを外す. | |
CheckMenuItem(GetMenu(hwnd), ID_ITEM_ENABLE_BUTTON, MF_BYCOMMAND | MF_UNCHECKED); // CheckMenuItemでID_ITEM_ENABLE_BUTTONのチェックを外す. | |
} | |
else{ // チェックされていない. | |
EnableWindow(GetDlgItem(hwnd, ID_BUTTON1), TRUE); // EnableWindowでID_BUTTON1を有効化. | |
// Enable Buttonにチェックを入れる. | |
CheckMenuItem(GetMenu(hwnd), ID_ITEM_ENABLE_BUTTON, MF_BYCOMMAND | MF_CHECKED); // CheckMenuItemでID_ITEM_ENABLE_BUTTONにチェック. | |
} | |
} | |
// 既定の処理へ向かう. | |
break; // breakで抜けて, 既定の処理(DefWindowProc)へ向かう. | |
// 上記以外の時. | |
default: | |
// 既定の処理へ向かう. | |
break; | |
} | |
// 既定の処理へ向かう. | |
break; | |
} | |
// 既定の処理へ向かう. | |
break; | |
// 上記以外の時. | |
default: | |
// 既定の処理へ向かう. | |
break; | |
} | |
// 既定の処理に任せる. | |
return DefWindowProc(hwnd, uMsg, wParam, lParam); // DefWindowProcを呼び, 戻り値をそのまま返す. | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment