FC2ブログ

VS2017-はじめの1/10歩(10):ボタンの色を変える

   プログラミング [2019/03/11]

VS2017を使うんだけど慣れてないからVS6でまずは作ってます。
→ナレーション再生と音声認識を使う
  →そのため音声データの作り方(多言語対応)
  →ナレーション(.WAV)再生のサンプルコード
  →音声認識のサンプルコード
→VS6で作ったC/C++コードをVS2017に持って行って.cppレベルで共通にする方法
→ダイアログベースのプログラム
  →背景に画像(.BMP)を使う
  →ラベルを透かす
  →ボタンの色を変える←今回

と来てます。
これまでと違って、さらに必要性は低いかな。

個別に色んなボタンを配置するというよりは、
「このプログラムではこの色が【ボタン】です。」的なデザインを前提にしてます。

始めます。
ラベルのときのWM_CTLCOLORSTATICと同じようなWM_CTLCOLORBTNというWMメッセージが存在します。
でも、このときに色チェンジをできるのか?と思いきや・・できないみいです。
なぜだ?

ともかく、ボタンコントロールの場合は、オーナードローって属性にして、
「自分で描きます」って宣言しないといけない。

まずは、リソースエディタを使って、ダアイアログに乗っけたボタンのスタイルに「オーナー描画」とあるのでそれを設定してください。
指定すると、そのボタンを「描画する必要があるとき」に、ダイアログのウィンドウプロジジャにWM_DRAWITEMメッセージがデバイスコンテキストハンドルとともにやって来ます。

以下のような処理をウィンドウプロシジャ中に加えます。
//---------------------------------------------
//****** ボタンコントロールの背景色設定
//※以下ではできない。
//case WM_CTLCOLORBTN:
// return ChangeColor((HDC)wParam, RGB(255,255,255), RGB(255,64,64), &g_hBrsBtn);

//******* オーナードローボタン描画
case WM_DRAWITEM:
{
LPDRAWITEMSTRUCT podraw = (LPDRAWITEMSTRUCT) lParam;
DrawButtonCtrl(hDlg, podraw);
return TRUE;
} //end WM_DRAWITEM
//---------------------------------------------


で実際の描画の中身は、・・・








//---------------------------------------------
//name :DrawButtonCtrl
//function :ボタンの描画を行う
//parameter :hDlg -ダイアログウィンドウハンドル
// pOwnDraw -オーナーDRAW情報
//global :なし
//return :なし

VOID DrawButtonCtrl(
HWND hDlg,
LPDRAWITEMSTRUCT pOwnDraw)
{
HWND hctrl = pOwnDraw->hwndItem;
HDC hdc = pOwnDraw->hDC;
RECT rect;
TCHAR capt[128];
POINT pt[6];
HBRUSH hbrs, hbrs_org;
HPEN hpen, hpen_org;
INT lnw = 2;
COLORREF bg_col, bglt_col, bgrb_col, tx_col;

//ボタン以外の場合は何もしない
if (pOwnDraw->CtlType != ODT_BUTTON) return;
//非活性の場合は色を変更する
if (pOwnDraw->itemState & ODS_DISABLED) {
bg_col = RGB( 95, 95,127);
bglt_col = RGB(127,127,255);
bgrb_col = RGB( 63, 63, 95);
tx_col = RGB(159,159,159);
}
else {
bg_col = RGB( 31, 31,223);
bglt_col = RGB( 63, 63,255);
bgrb_col = RGB( 0, 0,191);
tx_col = RGB(255,255,255);
}

GetClientRect(hctrl, &rect);
GetWindowText(hctrl, capt, sizeof(capt));
//背景塗りつぶし
hbrs = CreateSolidBrush(bg_col);
hbrs_org = (HBRUSH) SelectObject(hdc, hbrs); //一時ブラシ設定&元ブラシ退避
FillRect(hdc, &rect, hbrs);
//ボタン枠線描画
hpen = CreatePen(PS_SOLID, lnw*2, bglt_col);
hpen_org = (HPEN) SelectObject(hdc, hpen); //一時ペン設定&元ペン退避
if (pOwnDraw->itemState & ODS_SELECTED) {
pt[0].x = rect.left + lnw;
pt[0].y = rect.bottom - lnw;
pt[1].x = rect.right - lnw;
pt[1].y = rect.bottom - lnw;
pt[2].x = rect.right - lnw;
pt[2].y = rect.top + lnw;
}
else {
pt[0].x = rect.left + lnw;
pt[0].y = rect.bottom - lnw;
pt[1].x = rect.left + lnw;
pt[1].y = rect.top + lnw;
pt[2].x = rect.right - lnw;
pt[2].y = rect.top + lnw;
}
Polyline(hdc, pt, 3);
hpen = CreatePen(PS_SOLID, lnw*2, bgrb_col);
DeleteObject(SelectObject(hdc, hpen)); //一時ペン2設定&一時ペン廃棄
if (pOwnDraw->itemState & ODS_SELECTED) {
pt[1].x = rect.left + lnw;
pt[1].y = rect.top + lnw;
}
else {
pt[1].x = rect.right - lnw;
pt[1].y = rect.bottom - lnw;
}
Polyline(hdc, pt, 3);
//キャプション描画
SetBkMode(hdc, TRANSPARENT);
SetTextColor(hdc, tx_col);
DrawText(hdc, capt, -1, &rect, DT_SINGLELINE | DT_VCENTER | DT_CENTER);

//フォーカスを持っている場合
if (pOwnDraw->itemState & ODS_FOCUS) {
//点線枠描画
hpen = CreatePen(PS_DOT, 1, RGB(0, 0, 32));
DeleteObject(SelectObject(hdc, hpen)); //一時ペン3設定&一時ペン2廃棄
lnw += 2;
pt[0].x = rect.left + lnw;
pt[0].y = rect.bottom - lnw;
pt[1].x = rect.left + lnw;
pt[1].y = rect.top + lnw;
pt[2].x = rect.right - lnw;
pt[2].y = rect.top + lnw;
pt[3].x = rect.right - lnw;
pt[3].y = rect.bottom - lnw;
pt[4].x = rect.left + lnw;
pt[4].y = rect.bottom - lnw;
Polyline(hdc, pt, 5);
}

DeleteObject(SelectObject(hdc, hbrs_org)); //元ブラシ復帰&一時ブラシ廃棄
DeleteObject(SelectObject(hdc, hpen_org)); //元ペン復帰&一時ペン廃棄

return;
}
//---------------------------------------------


予想に反して、長いですかね。

・単色塗りつぶしだと、格好良くないので、縁取りを書いてます。
・青を基調にした色設定をしています。文字色は白ベース。
・通常のボタンコントロールには、幾つか動作モード的なものがあって、見ればその状態分かるようにする必要があります。
なので、
 -「活性」:「非活性」
 -「フォーカスを持ってるとき」:「持ってないとき」
 -「押されているとき」:「押されてないとき」
で、描画の内容をちょっとずつ変えてるため長くなってます。

内容はどおってことありません。
この関数をもっと汎用的にするには、以下の課題があるかと思います。
・色使いが青ベース固定になってる。
 →パラメタ等で基準色だけ指定させて選べるとか。
・縁取り(浮き出して見えるか/へこんで見えるようにする)の線幅が固定です。
 →ボタンの大きさに合わせて変える。
・枠の左上方向と右下方向の線の接続部分に何の配慮もしてません。
 →ドットレベルで斜めな接続に見えるように工夫。

・・・お任せします。


今後の続きは、
ピンチイン/アウト機能について調査したときのボヤキ記録になると思います。

では、この辺で。m(__)m


スポンサーサイト





コメントの投稿

非公開コメント

カレンダー
01 | 2024/02 | 03
- - - - 1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 - -
プロフィール

さるもすなる

Author:さるもすなる
さるです。別HPサイト「さるもすなる」から侵食してきました。 山菜/きのこ、それとタイトルにしたPPバンド籠のことをメインに徒然に・・・・暇を持て余したさるの手仕事:男手芸のブログってことで。

最新記事
最新コメント
月別アーカイブ
カテゴリ
天気予報

-天気予報コム- -FC2-
本家のHPのトップ
山菜や茸の話です
PPバンドの籠作品と作り方です
投稿をお待ちしております



PVアクセスランキング にほんブログ村 にほんブログ村 ハンドメイドブログへ



マニュアルのお申し込み



検索フォーム
リンク
RSSリンクの表示
ブロとも申請フォーム

この人とブロともになる

QRコード
QR