/* Button.cpp */ /////////////////////////////////////////////////////////// // // オーナオードローボタンを作成するサンプル // // 2003.Jun.21 // K_Yaguchi // // // comctl32.lib をリンクに追加する! // #include <windows.h> #include <commctrl.h> #include "resource.h" /* グローバル変数宣言 */ HINSTANCE g_hInst; // インスタンスハンスドル /* プロトタイプ宣言 */ void DrawBitmapButton(HIMAGELIST hIml, int nIndex, LPDRAWITEMSTRUCT lpDis); BOOL WINAPI MainDlgProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp); /******************************* ボタンの描画 *******************************/ void DrawBitmapButton(HIMAGELIST hIml, int nIndex, LPDRAWITEMSTRUCT lpDis) { IMAGEINFO ImgInfo; HDC hdc; HBITMAP hBmp, hOldBmp; COLORREF color; RECT rc; HFONT hFont; UINT fStyle, fState; int imgx, imgy, textx, texty; char szText[256]; // メモリデバイスコンテキスト作成 hdc = CreateCompatibleDC(lpDis->hDC); // ビットマップ割り当て hBmp = CreateCompatibleBitmap(lpDis->hDC, lpDis->rcItem.right, lpDis->rcItem.bottom); hOldBmp = (HBITMAP)SelectObject(hdc, hBmp); // フォント取得 hFont = (HFONT)SelectObject(hdc, (HGDIOBJ)SendMessage(lpDis->hwndItem, WM_GETFONT, 0, 0)); // 表示文字取得 GetWindowText(lpDis->hwndItem, szText, sizeof(szText)); // イメージ情報取得 ImageList_GetImageInfo(hIml, 0, &ImgInfo); // 描画位置のオフセット // 画像の位置や文字の位置はここで決める imgx = 3; imgy = (lpDis->rcItem.bottom - ImgInfo.rcImage.bottom) / 2; // 垂直方向中央 // textx = ImgInfo.rcImage.right; // イメージを省いた水平方向の中央 textx = 0; texty = 0; // 淡色表示 if(lpDis->itemState & ODS_DISABLED) { color = GetSysColor(COLOR_GRAYTEXT); // 淡色 fStyle = ILD_MASK; // マスクで描画 fState = DFCS_BUTTONPUSH; imgx += 0; imgy += 0; textx += 0; texty += 0; } // 押された else if(lpDis->itemState & ODS_SELECTED) { color = GetSysColor(COLOR_BTNTEXT); fStyle = ILD_NORMAL; fState = DFCS_BUTTONPUSH | DFCS_PUSHED; imgx += 1; imgy += 1; textx += 2; texty += 1; } // 標準 else { color = GetSysColor(COLOR_BTNTEXT); fStyle = ILD_NORMAL; fState = DFCS_BUTTONPUSH; imgx += 0; imgy += 0; textx += 0; texty += 0; } // ボタン枠の描画 DrawFrameControl(hdc, &lpDis->rcItem, DFC_BUTTON, fState); // 背景は透過 SetBkMode(hdc, TRANSPARENT); // 淡色文字描画(白字を影にする) lpDis->rcItem.left += textx; lpDis->rcItem.top += texty; if(lpDis->itemState & ODS_DISABLED) { rc = lpDis->rcItem; rc.left++; rc.top++; rc.right++; rc.bottom++; SetTextColor(hdc, GetSysColor(COLOR_3DHIGHLIGHT)); DrawText(hdc, szText, lstrlen(szText), &rc, DT_CENTER | DT_VCENTER | DT_SINGLELINE); } // 通常文字描画 SetTextColor(hdc, color); DrawText(hdc, szText, lstrlen(szText), &lpDis->rcItem, DT_CENTER | DT_VCENTER | DT_SINGLELINE); // イメージの描画 lpDis->rcItem.left -= textx; lpDis->rcItem.top -= texty; ImageList_Draw(hIml, nIndex, hdc, imgx, imgy, fStyle); // フォーカス枠の描画 if(lpDis->itemState & ODS_FOCUS) { rc = lpDis->rcItem; rc.left+=3; rc.top+=3; rc.right-=3; rc.bottom-=3; DrawFocusRect(hdc, &rc); } // ボタンへ転写 BitBlt(lpDis->hDC, 0, 0, lpDis->rcItem.right, lpDis->rcItem.bottom, hdc, 0, 0, SRCCOPY); // 開放 SelectObject(hdc, hFont); DeleteObject(SelectObject(hdc, hOldBmp)); DeleteDC(hdc); } /******************************* ウィンドウプロージャ *******************************/ BOOL WINAPI MainDlgProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) { static HIMAGELIST hIml; HBITMAP hBmp; switch(msg) { case WM_DESTROY: // イメージリスト破棄 ImageList_Destroy(hIml); PostQuitMessage(0); break; case WM_CLOSE: DestroyWindow(hWnd); break; case WM_INITDIALOG: // コモンコントロールの初期化 InitCommonControls(); // イメージリストの作成 hIml = ImageList_Create(32, 32, ILC_COLOR8 | ILC_MASK, 1, 0); // ビットマップ追加 hBmp = LoadBitmap(g_hInst, (LPCTSTR)IDB_BITMAP); ImageList_AddMasked(hIml, hBmp, RGB(0, 255, 0)); DeleteObject(hBmp); return FALSE; case WM_DRAWITEM: // オーナードロー処理をした場合(ダイアログでなくても) // TRUEを返さなくてはならない DrawBitmapButton(hIml, 0, (LPDRAWITEMSTRUCT)lp); break; case WM_COMMAND: if(LOWORD(wp) == IDC_NORMALBUTTON) { EnableWindow(GetDlgItem(hWnd, IDC_BUTTON), !IsWindowEnabled(GetDlgItem(hWnd, IDC_BUTTON))); } else if(LOWORD(wp) == IDC_BUTTON) { // ダブルクリックに反応させる if(HIWORD(wp) == BN_DBLCLK) SendMessage((HWND)lp, WM_LBUTTONDOWN, 0, 0); } break; default: return FALSE; } return TRUE; } /******************************* メイン *******************************/ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInst, LPSTR lpCmdLine, int nShowCmd) { MSG msg; g_hInst = hInstance; // ダイアログ作成 HWND hwnd = CreateDialog(hInstance, (LPCTSTR)IDD_MAINDLG, NULL, MainDlgProc); // メッセージループ while( GetMessage(&msg, NULL, 0, 0) ) { if(IsDialogMessage(hwnd, &msg)) continue; TranslateMessage(&msg); DispatchMessage(&msg); } return msg.wParam; } |