简体   繁体   English

如何在 CPropertySheet 中定义新的 colors?

[英]How can I define new colors in a CPropertySheet?

I'm trying to define new colors in some regions of a CPropertySheet (mfc libaries).我正在尝试在 CPropertySheet(mfc 库)的某些区域中定义新的 colors。 What I've tried is to overload OnCtlColor and define a new background color.我尝试的是重载OnCtlColor并定义新的背景颜色。 This methods works well but it doesn't colorize the region I want.这种方法效果很好,但它不会给我想要的区域着色。

In the next image you can see what I get with my method.在下一张图片中,您可以看到我的方法得到了什么。

Image of the control控件的图像

In this image you can see 4 colorized regions:在此图像中,您可以看到 4 个彩色区域:

  1. Red: Region that I can colorize using OnCtlColor红色:我可以使用OnCtlColor着色的区域
  2. Dark Gray and black: Region that I can colorize using OnCtlColor of the object CPropertyPage深灰色和黑色:我可以使用OnCtlColor CPropertyPage 的 OnCtlColor 着色的区域
  3. Light Gray (Indicated with a blue arrow): Region I want to colorize浅灰色(用蓝色箭头表示):我要着色的区域
  4. White margin: Region I want to colorize too.白边:我也想着色的区域。

I don't know what to do to colorize all regions using this libraries or using any Customizable object.我不知道如何使用这个库或使用任何可定制的 object 为所有区域着色。 Any help will be appreciated.任何帮助将不胜感激。

Thanks!谢谢!

Update 1更新 1

After the answer of Adrian it looks like this在阿德里安的回答之后,它看起来像这样

However, there's still one region we cannot colorize.但是,仍有一个区域我们无法着色。

Answer回答

Before trying a lot of combinations, I've done the next two objects which allows me to define the colors I need.在尝试很多组合之前,我已经完成了接下来的两个对象,它允许我定义我需要的 colors。 You can find all source code behind.你可以找到后面的所有源代码。 The result of this code can be checked in this picture这段代码的结果可以在这张图片中查看

PropertyPage属性页

Header Header

class CustomPropertyPage : public CPropertyPage
{   
    public:
        static const COLORREF PROPERTYPAGE_BACKGROUND = RGB(68, 74, 80);
        DECLARE_MESSAGE_MAP()

    public:
        CustomPropertyPage(UINT nIDTemplate);
        afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);
};

cpp cpp

CustomPropertyPage::CustomPropertyPage(UINT nIDTemplate) : CPropertyPage(nIDTemplate)
{
}

BEGIN_MESSAGE_MAP(CustomPropertyPage, CPropertyPage)
    ON_WM_CTLCOLOR()
END_MESSAGE_MAP()

HBRUSH CustomPropertyPage::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
    if (pWnd->GetDlgCtrlID() != 0)
        return CPropertyPage::OnCtlColor(pDC, pWnd, nCtlColor);

    HBRUSH hbr = CreateSolidBrush(PROPERTYPAGE_BACKGROUND_COLOR);
    return hbr;
}

PropertySheet属性表

Header Header

class CustomPropertySheet : public CPropertySheet
{
    DECLARE_MESSAGE_MAP()

    public:
        CustomPropertySheet(UINT nIDCaption, CWnd* pParentWnd, UINT iSelectPage);
        virtual BOOL OnInitDialog();
        afx_msg void OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct);
        afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);

    private:
        void Draw_Background(CDC *pDC);
};

cpp cpp

CustomPropertySheet::CustomPropertySheet(UINT nIDCaption, CWnd* pParentWnd, UINT iSelectPage) : CPropertySheet(nIDCaption, pParentWnd, iSelectPage)
{
}

BEGIN_MESSAGE_MAP(CustomPropertySheet, CPropertySheet)
    ON_WM_CTLCOLOR()
    ON_WM_DRAWITEM()
END_MESSAGE_MAP()

BOOL CustomPropertySheet::OnInitDialog()
{
    BOOL answer = CPropertySheet::OnInitDialog();

    CWnd* pTab = GetDlgItem(AFX_IDC_TAB_CONTROL);
    SetWindowLongPtr(pTab->m_hWnd, GWL_STYLE, GetWindowLongPtr(pTab->m_hWnd, GWL_STYLE) | TCS_OWNERDRAWFIXED);
    pTab->RedrawWindow();

    return answer;
}

void CustomPropertySheet::OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct)
{
    if (nIDCtl == AFX_IDC_TAB_CONTROL)
    {
        CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
        Draw_Background(pDC);

        CRect rc(lpDrawItemStruct->rcItem);
        rc.bottom += 1;
        pDC->FillSolidRect(rc, CEasyPropertyPage::PROPERTYPAGE_BACKGROUND);
        pDC->SetTextColor(GENERIC_TEXT_COLOR);
        pDC->SetBkMode(TRANSPARENT);

        char  text[256];
        TCITEM tci = { TCIF_TEXT | TCIF_STATE, 0, 0, text, 255, -1, 0 };
        HWND tcw = ::GetDlgItem(m_hWnd, nIDCtl);
        int i, tic = int(::SendMessage(tcw, TCM_GETITEMCOUNT, 0, 0));
        for (i = 0; i < tic; ++i) 
        {
            if (lpDrawItemStruct->itemState & ODS_SELECTED)
            {
                CRect tir;
                ::SendMessage(tcw, TCM_GETITEM, WPARAM(i), LPARAM(&tci));
                ::SendMessage(tcw, TCM_GETITEMRECT, WPARAM(i), LPARAM(&tir));
                pDC->DrawText(text, tir, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
            }
        }
    }

    else CPropertySheet::OnDrawItem(nIDCtl, lpDrawItemStruct);
}

HBRUSH CustomPropertySheet::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
    if (pWnd->GetDlgCtrlID() != 0)
        return CPropertySheet::OnCtlColor(pDC, pWnd, nCtlColor);

    HBRUSH hbr = CreateSolidBrush(GENERIC_BACKGROUND_COLOR);
    return hbr;
}

void CustomPropertySheet::Draw_Background(CDC* pDC)
{
    CRect rect; this->GetClientRect(rect);
    pDC->FillSolidRect(rect, GENERIC_BACKGROUND_COLOR);

    rect.DeflateRect(0, 20, 0, 0);
    pDC->FillSolidRect(rect, GENERIC_BORDER_COLOR);
}

To customize the light gray area (which is the embedded tab control ) you need to override the OnDrawItem method in your class that is derived from CPropertySheet and do your custom drawing for the control with the AFX_IDC_TAB_CONTROL identifier.要自定义浅灰色区域(即嵌入的选项卡控件),您需要覆盖派生自CPropertySheet的 class 中的OnDrawItem方法,并使用AFX_IDC_TAB_CONTROL标识符为控件进行自定义绘图。 Something like this:像这样的东西:

void MyPropertySheet::OnDrawItem(int nID, LPDRAWITEMSTRUCT pDIS)
{   
    if (nID == AFX_IDC_TAB_CONTROL) {
        CDC* pDC = CDC::FromHandle(pDIS->hDC);
        CRect rc(pDIS->rcItem); rc.bottom += 1;
        pDC->FillSolidRect(rc, RGB(255, 0, 0)); // Or whatever b/g/ colour you want
        pDC->SetTextColor(RGB(0,0,0)); // Or whatever text colour you want
        pDC->SetBkMode(TRANSPARENT);
        char  text[256];
        TCITEM tci = { TCIF_TEXT | TCIF_STATE, 0, 0, text, 255, -1, 0 };
        CRect tir;
        HWND tcw = ::GetDlgItem(m_hWnd, nID);
        int i, tic = int(::SendMessage(tcw, TCM_GETITEMCOUNT, 0, 0));
        for (i = 0; i < tic; ++i) {
            ::SendMessage(tcw, TCM_GETITEM, WPARAM(i), LPARAM(&tci));
            ::SendMessage(tcw, TCM_GETITEMRECT, WPARAM(i), LPARAM(&tir));
            if (pDIS->itemState & ODS_SELECTED)
                pDC->DrawText(text, tir, DT_CENTER |DT_VCENTER | DT_SINGLELINE);
        }
        pDC->Detach();
    }
    else { // Pass other stuff to the base class
        CPropertySheet::OnDrawItem(nID, pDIS);
    }
    return;
}

Of course, be sure to add ON_WM_DRAWITEM() to the message map!当然,一定要在消息映射中添加ON_WM_DRAWITEM()

EDIT: You must also explicitly set the style of the embedded tab control to include TCS_OWNERDRAWFIXED .编辑:您还必须明确设置嵌入式选项卡控件的样式以包含TCS_OWNERDRAWFIXED You can do this in the OnInitDialog override for your class.您可以在 class 的OnInitDialog覆盖中执行此操作。

EDIT 2: I have a slightly better way to get a pointer to the tab control, now, Also.编辑2:现在,我有一个更好的方法来获取指向选项卡控件的指针。 I have added a few lines of code that act as a "cheat" to address the remaining area that needs to be coloured - by expanding the tabs to fit the width of the underlying control...我添加了几行代码作为“作弊”来解决需要着色的剩余区域 - 通过扩展选项卡以适应底层控件的宽度......

BOOL MyPropertySheet::OnInitDialog()
{
    BOOL answer = CPropertySheet::OnInitDialog(); // Call base class first!
    // ... whatever other stuff you may wish to do
//  CWnd* pTab = GetDlgItem(AFX_IDC_TAB_CONTROL);
    CTabCtrl* pTab = GetTabControl(); // This is a bit clearer than above line!
    // The following 4 lines comprise a 'first stab' at fixing the remaining issue:
    CRect rcTab; pTab->GetWindowRect(&rcTab);
    int nItems = pTab->GetItemCount();
    int border = GetSystemMetrics(SM_CXEDGE) * 2;
    pTab->SetMinTabWidth((rcTab.Width() - border) / nItems);
    // ...
    SetWindowLongPtr(pTab->m_hWnd, GWL_STYLE, GetWindowLongPtr(pTab->m_hWnd, GWL_STYLE) | TCS_OWNERDRAWFIXED);
    pTab->RedrawWindow();
    return answer;
}

Feel free to ask for further clarification and/or explanation.随时要求进一步澄清和/或解释。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM