原创,转载请注明出处。 -------------------------------------------------- 样品:
 材料: (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; // 重要,不然会出链接错误 ...

|