こんにちは。
オーナードローボタンについて質問なんですが
CreateWindowで第一引数を"BUTTON"にしプッシュボタンを作ろうとします。
その際、プッシュボタンをオーナードローで表示したく、しかもアニメーション(例えば、ボタンが点滅したり)で実現したいと思っています。
その場合のアプローチの仕方を教えてもらえないでしょうか。
いくつかやってみて疑問も出たので同時に質問させてください。
親ウィンドウのWM_PAINTを受け取る際にBeginPaintでボタンウィンドウのハンドルを用い、
デバイスコンテキストハンドルを取得してプッシュボタンの描画を実現しようとすると、
CPU負荷が極端に掛かるのはどうしてなんですか?
また、ボタンウィンドウ用にウィンドウクラスを登録し、プロシージャを独自に実装すれば出来るかと思いましたが、
ボタンウィンドウではプロシージャを持たせることが出来ないんですか?
Win32API オーナードローボタンについて
Re:Win32API オーナードローボタンについて
アニメーションさせるならオーナードローだけでは無理ですね
タイマーイベントで変化させればいいでしょう
コントロールのプロシージャをフックするのをサブクラス化といいます
猫でもわかるを参考に作ってみました
http://www.kumei.ne.jp/c_lang/sdk/sdk_36.htm
タイマーイベントで変化させればいいでしょう
コントロールのプロシージャをフックするのをサブクラス化といいます
猫でもわかるを参考に作ってみました
http://www.kumei.ne.jp/c_lang/sdk/sdk_36.htm
#include <windows.h> #define ID_BUTTON1 1000 HWND hBWnd; //標準コントロールのHWND WNDPROC Org_BWnd; //オリジナルプロシージャのアドレス LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); LRESULT CALLBACK MySubProc(HWND, UINT, WPARAM, LPARAM); BOOL InitApp(HINSTANCE); BOOL InitInstance(HINSTANCE, int); LPCTSTR szClassName = TEXT("subcl01"); //ウィンドウクラス int WINAPI WinMain(HINSTANCE hCurInst, HINSTANCE hPrevInst, LPSTR lpsCmdLine, int nCmdShow) { MSG msg; if (!hPrevInst) { if (!InitApp(hCurInst)) return FALSE; } if (!InitInstance(hCurInst, nCmdShow)) { return FALSE; } while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return msg.wParam; } //ウィンドウ・クラスの登録 BOOL InitApp(HINSTANCE hInst) { WNDCLASS wc; wc.style = CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc = WndProc; //プロシージャ名 wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInst; //インスタンス wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = GetStockObject(WHITE_BRUSH); wc.lpszMenuName = NULL; //メニュー名 wc.lpszClassName = szClassName; return (RegisterClass(&wc)); } //ウィンドウの生成 BOOL InitInstance(HINSTANCE hInst, int nCmdShow) { HWND hWnd; hWnd = CreateWindow(szClassName, TEXT("猫でもわかるサブクラス化"), //タイトルバーにこの名前が表示されます WS_OVERLAPPED | WS_SYSMENU, //ウィンドウの種類 CW_USEDEFAULT, //X座標 CW_USEDEFAULT, //Y座標 250, //幅 120, //高さ NULL, //親ウィンドウのハンドル、親を作るときはNULL NULL, //メニューハンドル、クラスメニューを使うときはNULL hInst, //インスタンスハンドル NULL); if (!hWnd) return FALSE; ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); return TRUE; } //ウィンドウプロシージャ LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) { PAINTSTRUCT ps; HDC hdc; HINSTANCE hInst; LPCTSTR color[/url] = { TEXT("赤 "), TEXT("緑 ")}; static click; switch (msg) { case WM_CREATE: hInst = ((LPCREATESTRUCT)lp)->hInstance; hBWnd = CreateWindow(TEXT("BUTTON"), NULL, WS_CHILD | WS_VISIBLE | BS_OWNERDRAW, 10, 50, 100, 30, hWnd, (HMENU)ID_BUTTON1, hInst, NULL); //ウィンドウのサブクラス化 Org_BWnd = (WNDPROC)GetWindowLong(hBWnd, GWL_WNDPROC); SetWindowLong(hBWnd, GWL_WNDPROC, (LONG)MySubProc); SetTimer(hBWnd, 1, 10, NULL); break; case WM_PAINT: hdc = BeginPaint(hWnd, &ps); TextOut(hdc, 10, 10, color[click], 2); EndPaint(hWnd, &ps); break; case WM_COMMAND: switch (LOWORD(wp)) { case ID_BUTTON1: click = click ? 0 : 1; InvalidateRect(hWnd, NULL, FALSE); break; default: return(DefWindowProc(hWnd, msg, wp,lp)); } break; break; case WM_CLOSE: DestroyWindow(hWnd); break; case WM_DESTROY: //一応終了時にサブクラス化の解除 //アプリケーションが終了してしまうので必要ないといえばない SetWindowLong(hBWnd, GWL_WNDPROC, (LONG)Org_BWnd); PostQuitMessage(0); break; default: return (DefWindowProc(hWnd, msg, wp, lp)); } return 0L; } //コントロールのサブクラス化 LRESULT CALLBACK MySubProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) { HDC hDC; HBRUSH hBrush, hOldBrush; static BYTE color; static int lclick; static int sign = 2; switch (msg) { case WM_TIMER: hDC = GetDC(hWnd); if (lclick) { hBrush = CreateSolidBrush(RGB(0, color, 0)); } else { hBrush = CreateSolidBrush(RGB(color, 0, 0)); } color += sign; if (color == 254) { sign = -2; } if (color == 0) { sign = 2; } hOldBrush = SelectObject(hDC, hBrush); Rectangle(hDC, 0, 0, 100, 30); SelectObject(hDC, hOldBrush); DeleteObject(hBrush); ReleaseDC(hWnd, hDC); return 0; //メッセージの処理をしたら0を返す case WM_LBUTTONUP: lclick = lclick ? 0 : 1; break; //親にクリックメッセージを渡すため元のプロシージャへ default: break; } //自分で処理しないものは元のプロシージャにやってもらう return (CallWindowProc(Org_BWnd, hWnd, msg, wp, lp)); }
Re:Win32API オーナードローボタンについて
>コントロールのプロシージャをフックするのをサブクラス化といいます
なるほどー!!
キーワードを頂いただけでなく実際に組んでいただき感謝感激です。
おかげでコードを眺めながら具体的に検討できます。
理解し、自分なりにアレンジするまで少し時間がかかりそうなので
その際に疑問が出れば、また次回質問することにします。
toyoさん、ありがとうございました!!
なるほどー!!
キーワードを頂いただけでなく実際に組んでいただき感謝感激です。
おかげでコードを眺めながら具体的に検討できます。
理解し、自分なりにアレンジするまで少し時間がかかりそうなので
その際に疑問が出れば、また次回質問することにします。
toyoさん、ありがとうございました!!