今回は、文字盤などの色の設定オプションを少し改良してみます。
右クリックして、メニューの「色のオプション」を選択すると・・・
左の図のようなダイアログボックスが出てきます。
ツリービューを展開して、変更したい色をクリックすると
猫の画像が消えてスライダーが出てきます。
この時スライダーのつまみ位置は、そのときの色を表しています。
このスライダーのつまみを 動かして色を変更します。
スライダーを動かすと中央の矩形にその色が表示されます。
好みの色が決まったら、「設定」ボタンを押します。
「色の設定」を選択するか、ツリービューを折りたたむと また、猫の画像が表示されます。
では、プログラムを見てみましょう。
// clock09.rcの一部
/////////////////////////////////////////////////////////////////////////////
//
// Menu
//
MYMENU MENU
BEGIN
POPUP "ダミーです"
BEGIN
POPUP "ファイル(&F)"
BEGIN
MENUITEM "終了(&X)...", IDM_END
END
POPUP "アラーム(&L)"
BEGIN
MENUITEM "時刻設定(&S)...", IDM_ALARMSET
END
POPUP "タイマー(&T)"
BEGIN
MENUITEM "タイマーセット(&T)...", IDM_TIMER
MENUITEM "ストップウォッチ(&S)...", IDM_STOPWATCH
END
POPUP "ストップウォッチ(&S)"
BEGIN
MENUITEM "ストップウォッチ(&S)...", IDM_STOPWATCH
END
MENUITEM "色のオプション(&C)...", IDM_OPTION
END
END
/////////////////////////////////////////////////////////////////////////////
//
// Bitmap
//
CAT BITMAP "bitmap1.bmp"
MASK BITMAP "bmp00001.bmp"
CAT2 BITMAP "bitmap2.bmp"
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
MYALARM DIALOGEX 0, 0, 115, 73
STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION |
WS_SYSMENU
CAPTION "アラーム設定"
FONT 10, "MS ゴシック", 400, 0, 0x80
BEGIN
DEFPUSHBUTTON "OK",IDOK,7,52,50,14
PUSHBUTTON "キャンセル",IDCANCEL,58,52,50,14
CONTROL "アラームをセットする",IDC_CHECK1,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,7,7,101,15
CONTROL "",IDC_DATETIMEPICKER1,"SysDateTimePick32",
DTS_RIGHTALIGN | DTS_UPDOWN | WS_TABSTOP,30,25,54,17
END
MYTIMER DIALOGEX 0, 0, 123, 54
STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION |
WS_SYSMENU
CAPTION "タイマー設定"
FONT 10, "MS ゴシック", 400, 0, 0x80
BEGIN
DEFPUSHBUTTON "スタート",IDOK,7,33,50,14
PUSHBUTTON "ストップ",IDCANCEL,65,33,50,14
CONTROL "",IDC_DATETIMEPICKER1,"SysDateTimePick32",
DTS_RIGHTALIGN | DTS_UPDOWN | WS_TABSTOP,35,7,53,19
END
MYSTOPWATCH DIALOGEX 0, 0, 131, 54
STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION |
WS_SYSMENU
CAPTION "ストップウォッチ"
FONT 10, "MS ゴシック", 400, 0, 0x80
BEGIN
DEFPUSHBUTTON "スタート",IDOK,7,7,50,14
PUSHBUTTON "閉じる",IDCANCEL,71,31,50,14
PUSHBUTTON "ストップ",IDC_STOP,71,7,50,14
PUSHBUTTON "リセット",IDC_RESET,7,31,50,14
END
MYOPTION DIALOGEX 0, 0, 244, 129
STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "色の設定"
FONT 10, "MS ゴシック", 400, 0, 0x80
BEGIN
DEFPUSHBUTTON "設定",IDOK,35,108,50,14
PUSHBUTTON "閉じる",IDCANCEL,147,108,50,14
CONTROL "",IDC_TREE1,"SysTreeView32",TVS_HASBUTTONS |
TVS_HASLINES | TVS_LINESATROOT | TVS_SHOWSELALWAYS |
WS_BORDER | WS_TABSTOP,7,7,100,93
CONTROL "",IDC_SLIDER1,"msctls_trackbar32",TBS_VERT | TBS_BOTH |
TBS_NOTICKS | WS_TABSTOP,157,7,14,70
CONTROL "",IDC_SLIDER2,"msctls_trackbar32",TBS_VERT | TBS_BOTH |
TBS_NOTICKS | WS_TABSTOP,180,7,14,70
CONTROL "",IDC_SLIDER3,"msctls_trackbar32",TBS_VERT | TBS_BOTH |
TBS_NOTICKS | WS_TABSTOP,201,7,14,70
LTEXT "スタティック",IDC_STATIC1,157,77,17,11
LTEXT "スタティック",IDC_STATIC2,181,77,16,11
LTEXT "スタティック",IDC_STATIC3,203,77,18,11
LTEXT "R",IDC_STATIC,159,92,8,8
LTEXT "G",IDC_STATIC,182,92,8,8
LTEXT "B",IDC_STATIC,205,92,8,8
CONTROL "",IDC_FRAME,"Static",SS_BLACKFRAME,112,7,30,25
CONTROL "CAT2",IDC_PIC,"Static",SS_BITMAP,110,7,13,13
END
/////////////////////////////////////////////////////////////////////////////
//
// WAVE
//
BELL WAVE "ringin.wav"
メニューの「オプション」項目が無くなり、替わって「色のオプション」項目が増えました。「色の設定」ダイアログのリソース・スクリプトが増えました。
// clock09.cpp
#define hParentKey HKEY_CURRENT_USER
#define lpszSubKey "Software\\Kumei\\Clock"
#define PAI 3.14159
#define CLOCK_WIDTH 250 //時計全体のウィンドウ幅
#define CLOCK_HEIGHT 60 //高さ
#define MYTIMER 1 //タイマーID
#define MYSTOP 2
#include <windows.h>
#include <windowsx.h>
#include <math.h>
#include <commctrl.h>
#include <Mmsystem.h>
#include "resource.h"
typedef struct MYDATA {
COLORREF cr_bg; //背景色
COLORREF cr_txt; //文字色
COLORREF cr_plate; //文字盤の色
COLORREF cr_short; //短針の色
COLORREF cr_long; //長針の色
COLORREF cr_second; //秒針の色
int x;
int y;
char szAlarmSet[8];
char szAlarmTime[16];
char szTimerTime[16];
char szStopWatch[8]; //ストップウォッチモードかどうか
char szStopTime[16]; //ストップウォッチモードの時の時間
} INIDATA;
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
BOOL CALLBACK MyAlarmProc(HWND, UINT, WPARAM, LPARAM);
BOOL CALLBACK MyTimerProc(HWND, UINT, WPARAM, LPARAM);
BOOL CALLBACK MyStopWatchProc(HWND, UINT, WPARAM, LPARAM);
BOOL CALLBACK MyColorOptionProc(HWND, UINT, WPARAM, LPARAM);
ATOM InitApp(HINSTANCE);
BOOL InitInstance(HINSTANCE, int);
HFONT SetMyFont(LPCTSTR, int);
void GetInitialSettings(INIDATA *);
BOOL GetDataDWORD(char *, DWORD *);
BOOL GetDataString(char *, char *);
BOOL SetInitialSettings(INIDATA);
BOOL SetDataDWORD(char *, DWORD);
BOOL SetDataString(char *, char *);
BOOL ShowClock(HDC, char *, INIDATA);
BOOL GetHMS(char *, int *, int *, int *);
BOOL ShowBitmap(HDC, INIDATA);
BOOL MyTimerShow(HDC, int, int, INIDATA, DWORD);
BOOL SetHMS(char *, DWORD);
BOOL SetStopHMS(char *, DWORD);
char szClassName[] = "clock09"; //ウィンドウクラス
char szAppName[] = "猫クロック"; //アプリケーション名
HINSTANCE hInst;
色の設定ダイアログのプロシージャ(MyColorOptionProc)が増えました。GetMyColor関数は無くなりました。
WinMain, InitApp, InitInstanceの各関数に変更はありません。
//ウィンドウプロシージャ
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
{
int id, x, y;
SYSTEMTIME st;
PAINTSTRUCT ps;
HDC hdc;
HFONT hFont;
SIZE s;
HRGN hRgn, hRgn1, hRgn2, hRound1Rgn, hRound2Rgn, hRectRgn;
HBRUSH hBrush;
HMENU hMenu, hSubMenu;
POINT pt;
static INIDATA inidata;
RECT rc;
char szYobi[8];
static char szBuf[64], szBuf2[64]; //時刻表示用
INITCOMMONCONTROLSEX ic;
static BOOL bTimer; //タイマ表示かどうか
static DWORD dwStartMs;
MMTIME mm;
switch (msg) {
case WM_CREATE:
ic.dwSize = sizeof(INITCOMMONCONTROLSEX);
ic.dwICC = ICC_DATE_CLASSES |
ICC_TREEVIEW_CLASSES | ICC_BAR_CLASSES;
InitCommonControlsEx(&ic);
GetInitialSettings(&inidata);
MoveWindow(hWnd,
inidata.x,
inidata.y,
CLOCK_WIDTH,
CLOCK_HEIGHT,
TRUE);
SetTimer(hWnd, MYTIMER, 1000, NULL);
hRgn = CreateRectRgn(0, 0, 1, 1);
hRgn1 = CreateRectRgn(0, 0, 1, 1);
hRgn2 = CreateRectRgn(0, 0,1, 1);
hRound1Rgn = CreateEllipticRgn(0, 0, CLOCK_HEIGHT, CLOCK_HEIGHT);
hRectRgn = CreateRectRgn(CLOCK_HEIGHT / 2,
0,
CLOCK_WIDTH - CLOCK_HEIGHT / 2,
CLOCK_HEIGHT);
CombineRgn(hRgn1, hRound1Rgn, hRectRgn, RGN_OR);
hRound2Rgn = CreateEllipticRgn(CLOCK_WIDTH - CLOCK_HEIGHT,
0,
CLOCK_WIDTH,
CLOCK_HEIGHT);
CombineRgn(hRgn2, hRound2Rgn, hRectRgn, RGN_OR);
CombineRgn(hRgn, hRgn1, hRgn2, RGN_OR);
SetWindowRgn(hWnd, hRgn, TRUE);
DeleteObject(hRound1Rgn);
DeleteObject(hRound2Rgn);
DeleteObject(hRectRgn);
DeleteObject(hRgn1);
DeleteObject(hRgn2);
break;
case WM_RBUTTONDOWN:
pt.x = LOWORD(lp);
pt.y = HIWORD(lp);
hMenu = LoadMenu(hInst, "MYMENU");
hSubMenu = GetSubMenu(hMenu, 0);
ClientToScreen(hWnd, &pt);
TrackPopupMenu(hSubMenu, TPM_LEFTALIGN, pt.x, pt.y, 0, hWnd, NULL);
DestroyMenu(hMenu);
break;
case WM_LBUTTONDOWN:
PostMessage(hWnd, WM_NCLBUTTONDOWN, (WPARAM)HTCAPTION, lp);
break;
case WM_TIMER:
if (wp != MYTIMER)
return DefWindowProc(hWnd, msg, wp, lp);
GetLocalTime(&st);
wsprintf(szBuf, "%02d:%02d:%02d", st.wHour, st.wMinute, st.wSecond);
switch (st.wDayOfWeek) {
case 0:
strcpy(szYobi, "Sun");
break;
case 1:
strcpy(szYobi, "Mon");
break;
case 2:
strcpy(szYobi, "Tue");
break;
case 3:
strcpy(szYobi, "Wed");
break;
case 4:
strcpy(szYobi, "Thu");
break;
case 5:
strcpy(szYobi, "Fri");
break;
case 6:
strcpy(szYobi, "Sat");
break;
}
wsprintf(szBuf2, "%d/%02d/%02d(%s)", st.wYear, st.wMonth, st.wDay, szYobi);
if (strcmp(inidata.szAlarmSet, "Yes") == 0 && strcmp(szBuf, inidata.szAlarmTime) == 0) {
PlaySound("BELL", hInst, SND_RESOURCE | SND_ASYNC | SND_LOOP);
MessageBox(hWnd, "時間ですよ", szAppName, MB_OK);
PlaySound(NULL, hInst, SND_PURGE);
}
InvalidateRect(hWnd, NULL, TRUE);
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
hBrush = CreateSolidBrush(inidata.cr_bg);
SelectObject(hdc, hBrush);
PatBlt(hdc, 0, 0, CLOCK_WIDTH, CLOCK_HEIGHT, PATCOPY);
ShowBitmap(hdc, inidata);
hFont = SetMyFont("MS ゴシック", 30);
SelectObject(hdc, hFont);
GetTextExtentPoint32(hdc, szBuf, (int)strlen(szBuf), &s);
x = (CLOCK_WIDTH - s.cx) / 2 + 4;
y = (CLOCK_HEIGHT - s.cy) / 2 + 10;
SetBkMode(hdc, TRANSPARENT);
SetTextColor(hdc, inidata.cr_txt);
if (strcmp(inidata.szStopWatch, "Yes") == 0) {
hFont = SetMyFont("MS ゴシック", 24);
SelectObject(hdc, hFont);
GetTextExtentPoint32(hdc, szBuf, (int)strlen(inidata.szStopTime), &s);
x = (CLOCK_WIDTH - s.cx) / 2 + 4;
y = (CLOCK_HEIGHT - s.cy) / 2 + 10;
TextOut(hdc, x, y, inidata.szStopTime, (int)strlen(inidata.szStopTime));
DeleteObject(hFont);
} else {
hFont = SetMyFont("MS ゴシック", 30);
SelectObject(hdc, hFont);
GetTextExtentPoint32(hdc, szBuf, (int)strlen(szBuf), &s);
x = (CLOCK_WIDTH - s.cx) / 2 + 4;
y = (CLOCK_HEIGHT - s.cy) / 2 + 10;
TextOut(hdc, x, y, szBuf, (int)strlen(szBuf));
DeleteObject(hFont);
}
hFont = SetMyFont("MS ゴシック", 16);
SelectObject(hdc, hFont);
GetTextExtentPoint32(hdc, szBuf2, (int)strlen(szBuf2), &s);
x = (CLOCK_WIDTH - s.cx) / 2 + 4;
if (!bTimer) {
TextOut(hdc, x, 4, szBuf2, (int)strlen(szBuf2));
} else {
if (MyTimerShow(hdc, x, 4, inidata, dwStartMs)) {
bTimer = FALSE;
PlaySound("BELL", hInst, SND_RESOURCE | SND_ASYNC | SND_LOOP);
MessageBox(hWnd, "時間ですよ", szAppName, MB_OK);
PlaySound(NULL, hInst, SND_PURGE);
}
}
DeleteObject(hFont);
DeleteObject(hBrush);
ShowClock(hdc, szBuf, inidata);
EndPaint(hWnd, &ps);
break;
case WM_COMMAND:
switch (LOWORD(wp)) {
case IDM_END:
SendMessage(hWnd, WM_CLOSE, 0, 0);
break;
case IDM_ALARMSET:
DialogBoxParam(hInst, "MYALARM", hWnd, (DLGPROC)MyAlarmProc, (LPARAM)&inidata);
break;
case IDM_TIMER:
if (DialogBoxParam(hInst,
"MYTIMER",
hWnd,
(DLGPROC)MyTimerProc,
(LPARAM)&inidata) == IDOK) {
bTimer = TRUE;
memset(&mm, 0, sizeof(MMTIME));
mm.wType = TIME_MS;
timeGetSystemTime(&mm, sizeof(MMTIME));
dwStartMs = mm.u.ms;
} else {
bTimer = FALSE;
}
break;
case IDM_STOPWATCH:
DialogBoxParam(hInst, "MYSTOPWATCH", hWnd, (DLGPROC)MyStopWatchProc, (LPARAM)&inidata);
break;
case IDM_OPTION:
DialogBoxParam(hInst, "MYOPTION", hWnd, (DLGPROC)MyColorOptionProc, (LPARAM)&inidata);
break;
}
break;
case WM_CLOSE:
id = MessageBox(hWnd,
"終了してもよろしいですか",
szAppName,
MB_YESNO | MB_ICONQUESTION);
if (id == IDYES) {
GetWindowRect(hWnd, &rc);
inidata.x = rc.left;
inidata.y = rc.top;
DestroyWindow(hWnd);
}
break;
case WM_DESTROY:
SetInitialSettings(inidata);
KillTimer(hWnd, MYTIMER);
PostQuitMessage(0);
break;
default:
return (DefWindowProc(hWnd, msg, wp, lp));
}
return 0;
}
メインウィンドウのプロシージャです。WM_CREATEメッセージが来たときの、コモンコントロールの初期化が少し変更となりました。 (ツリービューを扱うため)
メニュー項目が削減されたため、これに対応していた部分が削除されました。 (IDM_BACKGROUNDからIDM_SECONDまで)
メニュー項目の「色のオプション」(IDM_OPTION)が選択されたときの処理が増えました。 「色の設定」ダイアログを出しますが、例によってDialogBoxParam関数を使って ダイアログのプロシージャにinidata構造体のアドレスを渡しています。
GetMyColor関数は無くなりました。
SetMyFont, GetInitialSettings, GetDataDWORD, GetDataString, SetInitialSettings, SetDataDWORD, SetDataString, ShowClock, GetHMS, ShowBitmap, MyAlarmProc, MyTimerProc, MyTimerShow, SetHMS, MyStopWatchProc, SetStopHMSの各関数に変更はありません。
BOOL CALLBACK MyColorOptionProc(HWND hDlg, UINT msg, WPARAM wp, LPARAM lp)
{
static INIDATA *lpini;
static HWND hTree, hSlider1, hSlider2, hSlider3,
hR, hG, hB, hFrame, hPic;
TVINSERTSTRUCT tv;
static HTREEITEM hParent;
HTREEITEM hti;
static int nPos1, nPos2, nPos3;
char szBuf[32];
HBRUSH hBrush;
HDC hdc_frame;
RECT rc;
NMHDR *lpnmhdr;
TVITEM ti;
static HTREEITEM hHaikei, hMoji, hMojiBan, hChoshin, hTanshin, hByoshin;
char szText[256];
int nR, nG, nB;
COLORREF crColor;
switch (msg) {
case WM_INITDIALOG:
lpini = (INIDATA *)lp;
hTree = GetDlgItem(hDlg, IDC_TREE1);
memset(&tv, 0, sizeof(TVINSERTSTRUCT));
tv.hInsertAfter = TVI_LAST;
tv.item.mask = TVIF_TEXT;
tv.hParent = TVI_ROOT;
tv.item.pszText = "色の指定";
hParent = TreeView_InsertItem(hTree, &tv);
tv.hParent = hParent;
tv.item.pszText = "背景色";
hHaikei = TreeView_InsertItem(hTree, &tv);
tv.item.pszText = "文字色";
hMoji = TreeView_InsertItem(hTree, &tv);
tv.item.pszText = "文字盤の色";
hMojiBan = TreeView_InsertItem(hTree, &tv);
tv.item.pszText = "長針の色";
hChoshin = TreeView_InsertItem(hTree, &tv);
tv.item.pszText = "短針の色";
hTanshin = TreeView_InsertItem(hTree, &tv);
tv.item.pszText = "秒針の色";
hByoshin = TreeView_InsertItem(hTree, &tv);
hSlider1 = GetDlgItem(hDlg, IDC_SLIDER1);
hSlider2 = GetDlgItem(hDlg, IDC_SLIDER2);
hSlider3 = GetDlgItem(hDlg, IDC_SLIDER3);
hR = GetDlgItem(hDlg, IDC_STATIC1);
hG = GetDlgItem(hDlg, IDC_STATIC2);
hB = GetDlgItem(hDlg, IDC_STATIC3);
hFrame = GetDlgItem(hDlg, IDC_FRAME);
hPic = GetDlgItem(hDlg, IDC_PIC);
SendMessage(hSlider1, TBM_SETRANGE, (WPARAM)TRUE, (LPARAM)MAKELPARAM(0, 255));
SendMessage(hSlider2, TBM_SETRANGE, (WPARAM)TRUE, (LPARAM)MAKELPARAM(0, 255));
SendMessage(hSlider3, TBM_SETRANGE, (WPARAM)TRUE, (LPARAM)MAKELPARAM(0, 255));
return TRUE;
case WM_COMMAND:
switch (LOWORD(wp)) {
case IDOK:
hti = TreeView_GetSelection(hTree);
nPos1 = (int)SendMessage(hSlider1, TBM_GETPOS, 0, 0);
nPos2 = (int)SendMessage(hSlider2, TBM_GETPOS, 0, 0);
nPos3 = (int)SendMessage(hSlider3, TBM_GETPOS, 0, 0);
crColor = RGB(nPos1, nPos2, nPos3);
if (hti == hHaikei) {
SetDataDWORD("background-color", crColor);
lpini->cr_bg = crColor;
} else if (hti == hMoji) {
SetDataDWORD("text-color", crColor);
lpini->cr_txt = crColor;
} else if (hti == hMojiBan) {
SetDataDWORD("plate-color", crColor);
lpini->cr_plate = crColor;
} else if (hti == hChoshin){
SetDataDWORD("long-color", crColor);
lpini->cr_long = crColor;
} else if (hti == hTanshin) {
SetDataDWORD("short-color", crColor);
lpini->cr_short = crColor;
} else if (hti == hByoshin) {
SetDataDWORD("second-color", crColor);
lpini->cr_second = crColor;
} else {
return FALSE;
}
return TRUE;
case IDCANCEL:
EndDialog(hDlg, IDCANCEL);
return TRUE;
}
return FALSE;
case WM_NOTIFY:
if (wp != (WPARAM)IDC_TREE1)
return FALSE;
lpnmhdr = (NMHDR *)lp;
if (lpnmhdr->code == TVN_SELCHANGED) {
memset(&ti, 0, sizeof(TVITEM));
hti = TreeView_GetSelection(hTree);
ti.cchTextMax = 255;
ti.hItem = hti;
ti.mask = TVIF_TEXT | TVIF_HANDLE;
ti.pszText = szText;
TreeView_GetItem(hTree, &ti);
SetWindowText(hDlg, szText);
if (hti != hParent) {
ShowWindow(hPic, SW_HIDE);
} else {
ShowWindow(hPic, SW_SHOW);
return FALSE;
}
if (hti == hHaikei) {
GetDataDWORD("background-color", &crColor);
} else if (hti == hMoji) {
GetDataDWORD("text-color", &crColor);
} else if (hti == hMojiBan) {
GetDataDWORD("plate-color", &crColor);
} else if (hti == hChoshin){
GetDataDWORD("long-color", &crColor);
} else if (hti == hTanshin) {
GetDataDWORD("short-color", &crColor);
} else if (hti == hByoshin) {
GetDataDWORD("second-color", &crColor);
} else {
return FALSE;
}
nR = (int)GetRValue(crColor);
nG = (int)GetGValue(crColor);
nB = (int)GetBValue(crColor);
wsprintf(szBuf, "%03d", nR);
SetWindowText(hR, szBuf);
wsprintf(szBuf, "%03d", nG);
SetWindowText(hG, szBuf);
wsprintf(szBuf, "%03d", nB);
SetWindowText(hB, szBuf);
SendMessage(hSlider1, TBM_SETPOS, (WPARAM)TRUE, (LPARAM)nR);
SendMessage(hSlider2, TBM_SETPOS, (WPARAM)TRUE, (LPARAM)nG);
SendMessage(hSlider3, TBM_SETPOS, (WPARAM)TRUE, (LPARAM)nB);
GetClientRect(hFrame, &rc);
hBrush = CreateSolidBrush(RGB(nR, nG, nB));
hdc_frame = GetDC(hFrame);
SelectObject(hdc_frame, hBrush);
PatBlt(hdc_frame, 0, 0, rc.right, rc.bottom, PATCOPY);
ReleaseDC(hFrame, hdc_frame);
DeleteObject(hBrush);
}
return TRUE;
case WM_VSCROLL:
hti = TreeView_GetSelection(hTree);
nPos1 = (int)SendMessage(hSlider1, TBM_GETPOS, 0, 0);
wsprintf(szBuf, "%03d", nPos1);
SetWindowText(hR, szBuf);
nPos2 = (int)SendMessage(hSlider2, TBM_GETPOS, 0, 0);
wsprintf(szBuf, "%03d", nPos2);
SetWindowText(hG, szBuf);
nPos3 = (int)SendMessage(hSlider3, TBM_GETPOS, 0, 0);
wsprintf(szBuf, "%03d", nPos3);
SetWindowText(hB, szBuf);
GetClientRect(hFrame, &rc);
hBrush = CreateSolidBrush(RGB(nPos1, nPos2, nPos3));
hdc_frame = GetDC(hFrame);
SelectObject(hdc_frame, hBrush);
PatBlt(hdc_frame, 0, 0, rc.right, rc.bottom, PATCOPY);
ReleaseDC(hFrame, hdc_frame);
DeleteObject(hBrush);
return TRUE;
}
return FALSE;
}
「色の設定」ダイアログのプロシージャです。WM_INITDIALOGメッセージが来たら、INIDATA構造体のアドレスをstaticな変数にコピーしておきます。
ダイアログボックス上のいろいろなコントロールのウィンドウハンドルを取得しておきます。
トラックバーコントロールの範囲を0から255までに設定しておきます。
「設定」(IDOK)ボタンが押されたら、各トラックバーのつまみ位置を取得します。 この位置がRGB成分の値となります。これらの値からRGBマクロでCOLORREF値を取得します。
次に「OK」ボタンが押されたとき、ツリービューのどのアイテムが選択されていたかを 知る必要があります。
TreeView_GetSelectionマクロの返す値によってINIDATA構造体のどのメンバの値を 変更するかを決めます。この時ついでにレジストリにも書き込んでいます。
WM_NOTIFYメッセージが来たとき、これがツリービュー以外から来たのであれば何もしません。
選択アイテムが変更されたのであれば、そのアイテムの文字列を取得してダイアログボックスの タイトルバーに表示します。ツリービューのアイテムから文字列を取得する方法は忘れやすいので 復習しておいてください(筆者は特に忘れやすい)。
また、選択アイテムが変更されたら、選択されているアイテムに相当するレジストリから 値を読み出して、トラックバーのつまみ位置をこれに合わせます。
また、中央の矩形をその時の色で塗りつぶします。
WM_VSCROLLメッセージが来たら(つまみが動かされたら)すべてのつまみ位置を読み取って これに相当する色で中央の矩形を塗りつぶします。
簡単そうなプログラムですが、作っていくうちにいろいろ問題点が見えてきます。
今回のプログラムでは、猫のビットマップが表示されているとき、このビットマップ上を 適当にクリックすると、クリックした場所にトラックバーなどが存在すると、これが見えてしまい 大変みっともないことになります。この点を改良するにはどうしたらよいでしょうか。 いろいろ工夫してみてください。
Update 12/Feb/2003 By Y.Kumei