右クリックして、メニューの「色のオプション」を選択すると・・・
左の図のようなダイアログボックスが出てきます。
ツリービューを展開して、変更したい色をクリックすると
猫の画像が消えてスライダーが出てきます。
この時スライダーのつまみ位置は、そのときの色を表しています。
このスライダーのつまみを 動かして色を変更します。
スライダーを動かすと中央の矩形にその色が表示されます。
好みの色が決まったら、「設定」ボタンを押します。
「色の設定」を選択するか、ツリービューを折りたたむと また、猫の画像が表示されます。
では、プログラムを見てみましょう。
// 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