程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> VC >> 關於VC++ >> 擴展顏色對話框

擴展顏色對話框

編輯:關於VC++

(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; // 重要,不然會出鏈接錯誤

...

  1. 上一頁:
  2. 下一頁:
欄目導航
Copyright © 程式師世界 All Rights Reserved