/* 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;
}
|