首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> VC 教學

擴展色彩對話框:加入 Alpha 通道滑桿與數值顯示

     編輯:VC 教學

核心結構 CHOOSECOLOR

typedef struct {
    DWORD lStructSize;
    HWND hwndOwner;
    HWND hInstance;
    COLORREF rgbResult;
    COLORREF* lpCustColors;
    DWORD Flags;
    LPARAM lCustData;
    LPCCHOOKPROC lpfnHook;
    LPCTSTR lpTemplateName;
} CHOOSECOLOR, *LPCHOOSECOLOR;

關鍵旗標組合

CC_RGBINIT | CC_FULLOPEN | CC_ENABLEHOOK | CC_ANYCOLOR
  • CC_RGBINIT:使用 rgbResult 作為初始顏色
  • CC_FULLOPEN:直接展開完整對話框
  • CC_ENABLEHOOK:啟用自訂 Hook 程序
  • CC_ANYCOLOR:允許選擇非調色盤顏色

完整初始化與呼叫範例

COLORREF retColor = RGB(255, 0, 0);
COLORREF cusColor[16] = {0};

CHOOSECOLOR cc = {
    sizeof(CHOOSECOLOR),
    m_hwndParent,
    NULL,
    retColor,
    cusColor,
    CC_RGBINIT | CC_FULLOPEN | CC_ENABLEHOOK | CC_ANYCOLOR,
    NULL,
    (LPCCHOOKPROC)MyCCHookProc,
    NULL
};

if (ChooseColor(&cc)) {
    // 用戶按確定,cc.rgbResult 為選取顏色
}

Hook 程序實作 Alpha 滑桿

HWND hAlpha;           // 數值顯示編輯框
int xCurrentScroll = 128; // 目前 Alpha 值 (0-255)

UINT_PTR CALLBACK MyCCHookProc(HWND hdlg, UINT uiMsg, WPARAM wParam, LPARAM lParam)
{
    switch (uiMsg) {
    case WM_INITDIALOG: {
        // 1. 擴大對話框高度
        RECT rt; GetWindowRect(hdlg, &rt);
        rt.bottom += 20;
        SetWindowPos(hdlg, NULL, 0, 0, rt.right-rt.left, rt.bottom-rt.top, SWP_NOMOVE);

        // 2. 移動「確定」「取消」按鈕
        HWND hBtn = GetDlgItem(hdlg, IDOK);
        GetWindowRect(hBtn, &rt);
        POINT pt = {rt.left, rt.top};
        ScreenToClient(hdlg, &pt);
        pt.x += 250; pt.y += 22;
        SetWindowPos(hBtn, NULL, pt.x, pt.y, 0, 0, SWP_NOSIZE);
        // IDCANCEL 同理...

        // 3. 建立水平滑桿
        pt.x -= 250;
        HWND hScroll = CreateWindowEx(0, "ScrollBar", "alpha channel",
            SBS_TOPALIGN|SBS_LEFTALIGN|WS_CHILD|WS_VISIBLE|WS_TABSTOP,
            pt.x, pt.y, 160, 20, hdlg, NULL, NULL, NULL);
        SetScrollRange(hScroll, SB_CTL, 0, 255, TRUE);
        SetScrollPos(hScroll, SB_CTL, 128, FALSE);
        xCurrentScroll = 128;

        // 4. 建立數值顯示編輯框
        pt.x += 162;
        hAlpha = CreateWindowEx(0, "Edit", "alpha value",
            ES_LEFT|ES_NUMBER|WS_CHILD|WS_VISIBLE|WS_TABSTOP,
            pt.x, pt.y, 36, 20, hdlg, NULL, NULL, NULL);
        SetWindowText(hAlpha, "128");

        // 5. 建立說明靜態文字
        pt.y -= 22; pt.x -= 162;
        CreateWindowEx(0, "STATIC", "透明度(255表示完全不透明)",
            WS_CHILD|WS_VISIBLE, pt.x, pt.y, 220, 20, hdlg, NULL, NULL, NULL);
        break;
    }
    case WM_HSCROLL: {
        HWND hCtrl = (HWND)lParam;
        int xNewPos = xCurrentScroll;
        switch (LOWORD(wParam)) {
            case SB_PAGEUP:   xNewPos -= 20; break;
            case SB_PAGEDOWN: xNewPos += 20; break;
            case SB_LINEUP:   xNewPos -= 1;  break;
            case SB_LINEDOWN: xNewPos += 1;  break;
            case SB_THUMBPOSITION:
            case SB_THUMBTRACK: xNewPos = HIWORD(wParam); break;
        }
        xNewPos = max(0, min(255, xNewPos));
        if (xNewPos != xCurrentScroll) {
            xCurrentScroll = xNewPos;
            SetScrollPos(hCtrl, SB_CTL, xCurrentScroll, TRUE);
            char str[4]; sprintf(str, "%d", xCurrentScroll);
            SetWindowText(hAlpha, str);
        }
        break;
    }
    }
    return 0; // 交由預設程序繼續處理
}

封裝為類別的關鍵技巧

  1. Hook 程序宣告為 static 成員函式。
  2. 類別中加入 static ClassName* pthis 指標,建構子中 pthis = this。
  3. .cpp 中定義 ClassName* ClassName::pthis = NULL; 避免連結錯誤。
  4. Hook 內透過 pthis 存取實例資料。

替代方案

若使用 CColorDialog,可採用子類化方式擴展。CodeProject 有完整範例:
https://www.codeproject.com/dialog/select_all_button.asp

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved