(1) 參數
typedef struct {
DWORD lStructSize;
HWND hwndOwner;
HWND hInstance;
COLORREF rgbResult;
COLORREF * lpCustColors;
DWORD Flags;
LPARAM lCustData;
LPCCHOOKPROC lpfnHook;
LPCTSTR lpTemplateName;
} CHOOSECOLOR, *LPCHOOSECOLOR;
(2) API函數
BOOL ChooseColor(
LPCHOOSECOLOR lpcc // initialization data
);
(3) 回調函數,用於處理消息
UINT_PTR CALLBACK CCHookProc(
HWND hdlg, // handle to dialog box
UINT uiMsg, // message identifier
WPARAM wParam, // message parameter
LPARAM lParam // message parameter
);
方法:
(1)、填寫結構體:
COLORREF retColor = RGB( 255,0,0);
COLORREF cusColor[16];
memset( cusColor, 0, sizeof( COLORREF) * 16 ); CHOOSECOLOR cc = {
sizeof( CHOOSECOLOR ),
m_hwndParent, // 父窗口啦,設置為NULL的話,就是桌面了
NULL, // 一個句柄,沒用到,詳看MSDN
retColor, // 如果設置了CC_RGBINIT 就是初始的顏色值了,同時它作為返回值,返回所選擇的顏色
cusColor, // 初始的自定義顏色數組,設置為NULL的話,會出錯,不設置的話,好像就是隨機值了,我把它都清理成0了
CC_RGBINIT|CC_FULLOPEN | CC_ENABLEHOOK | CC_ANYCOLOR, // 紅色為設置自己的消息處理函數
NULL,
(LPCCHOOKPROC)MyCCHookProc, // 使用自定義的消息處理函數
NULL
};
(2)、調用
ChooseColor( &cc ); // 點擊"確定"返回 TRUE, 否則返回 FALSE
(3)、自定義的消息處理函數
HWND hAlpha;// 用於顯示alpha值的文本框
int xCurrentScroll;// 用於保存滾動條的當前值,同時也是alpha值
UINT_PTR CALLBACK CAColorDialog::MyCCHookProc(
HWND hdlg, // handle to dialog box
UINT uiMsg, // message identifier
WPARAM wParam, // message parameter
LPARAM lParam // message parameter
)
{
HWND hctrl;
RECT rt;
POINT pt;
int Delta; // xDelta = new_pos - current_pos
int xNewPos; // new position
BOOL fScroll = FALSE;
switch( uiMsg )
{
case WM_INITDIALOG:
ASSERT( pthis );
// 修改顏色對話框的大小
::GetWindowRect( hdlg, &rt );
rt.bottom += 20;
::SetWindowPos( hdlg, NULL, 0,0, rt.right - rt.left,
rt.bottom - rt.top , SWP_NOMOVE );
// 修改“取消”按鈕的位置
hctrl = ::GetDlgItem( hdlg, IDCANCEL );
::GetWindowRect( hctrl, &rt );
pt.x = rt.left;
pt.y = rt.top ;
::ScreenToClient( hdlg, &pt );
pt.x += 250;
pt.y += 22;
::SetWindowPos( hctrl, NULL, pt.x, pt.y , 0, 0, SWP_NOSIZE );
// 修改“確定”按鈕的位置
hctrl = ::GetDlgItem( hdlg, IDOK );
::GetWindowRect( hctrl, &rt );
pt.x = rt.left;
pt.y = rt.top ;
::ScreenToClient( hdlg, &pt );
pt.x += 250;
pt.y += 22;
::SetWindowPos( hctrl, NULL, pt.x, pt.y , 0, 0, SWP_NOSIZE );
// 添加滾動條
pt.x -= 250;
hctrl = CreateWindowEx(
0L,
"ScrollBar",
"alpha channel",
SBS_TOPALIGN|SBS_LEFTALIGN|WS_CHILD |WS_VISIBLE | WS_TABSTOP,
pt.x,
pt.y,
160,
20,
hdlg,
NULL,
NULL,
NULL );
::SetScrollRange( hctrl, SB_CTL, 0, 255, TRUE );
::SetScrollPos( hctrl, SB_CTL, 128, FALSE );
xCurrentScroll = 128;
// 添加一個文本框,用於顯示當前透明度
pt.x += 162;
hAlpha = CreateWindowEx(
0L,
"Edit",
"alpha value",
//ES_READONLY|
ES_LEFT|ES_NUMBER|WS_CHILD |WS_VISIBLE | WS_TABSTOP,
pt.x,
pt.y,
36,
20,
hdlg,
NULL,
NULL,
NULL );
pt.x -= 162;
// 添加一個靜態文本,字體有點問題
pt.y -= 22;
hctrl = CreateWindowEx(
0L,
"STATIC",
"透明度(255表示完全不透明)",
WS_CHILD |WS_VISIBLE ,
pt.x,
pt.y,
220,
20,
hdlg,
NULL,
NULL,
NULL );
::SetWindowText( pthis->hAlpha, "128" );
break;
case WM_HSCROLL:
{
hctrl = (HWND)lParam;
// 滾動條的事件處理,摘自MSDN
switch (LOWORD(wParam))
{
// 鍵盤上的pageup/down
case SB_PAGEUP:
xNewPos = xCurrentScroll - 20;
break;
case SB_PAGEDOWN:
xNewPos = xCurrentScroll + 20;
break;
// 單擊左右箭頭,或者用鍵盤上的方向鍵
case SB_LINEUP:
xNewPos = xCurrentScroll - 1;
break;
case SB_LINEDOWN:
xNewPos = xCurrentScroll + 1;
break;
// 用鼠標拖動滑桿(結束)
case SB_THUMBPOSITION:
xNewPos = HIWORD(wParam);
break;
// 用鼠標拖動滑桿(過程)
case SB_THUMBTRACK:
xNewPos = HIWORD(wParam);
break;
default:
xNewPos = xCurrentScroll;
}
xNewPos = max(0, xNewPos);
xNewPos = min(255, xNewPos);
if (xNewPos == xCurrentScroll)
break;
fScroll = TRUE;
Delta = xNewPos - xCurrentScroll;
xCurrentScroll = xNewPos;
// Reset the scroll bar.
SetScrollPos( hctrl, SB_CTL, xCurrentScroll, fScroll );
char str[4];
strset(str, 0);
sprintf( str, "%d", xCurrentScroll );
::SetWindowText( hAlpha, str );
break;
}
/*
case WM_COMMAND:
if( LOWORD(wParam) == IDOK ) // 確定按鈕
{
// TRACE("IDOK click");
char str[];
::GetWindowText(hAlpha, str, 3 );
atoi( str );
}
*/
}
// 返回 0 ,表示由默認的消息處理函數繼續進行處理
// 返回非0的話,會很郁悶
return 0;
}
// -----------------------------------------------------------
這樣就好了
使用CColorDialog的話,可以用子類化的方法,CodeProject上有個例子
http://www.codeproject.com/dialog/select_all_button.asp
// -----------------------------------------------------------
另外,曾試著封裝成一個類,遇到了一些難題:
1、如何把回調函數作為類的方法?
方法:設置成靜態成員,static
2、如何讓靜態成員訪問類裡的數據?
方法:在類裡添加一個靜態類指針,eg:
--- .h file ---
class MyColorDialog:
{
MyColorDialog()
{
pthis = this;
}
static MyColorDialog* pthis;
static UINT CALLBACK MyCCHookProc( ... );
}
--- .cpp file ---
MyColorDialog* MyColorDialog::pthis = NULL; // 重要,不然會出鏈接錯誤
...