我正在尝试在CPropertySheet (mfc )的某些区域定义新的颜色。我尝试的是重载OnCtlColor并定义一个新的背景色。这种方法效果很好,但没有给我想要的区域着色。
在下一个图像中,您可以看到我的方法得到了什么。
在此图像中,您可以看到4个彩色区域:
OnCtlColor着色的区域OnCtlColor CPropertyPage来着色的区域我不知道该如何使用这个库或任何可自定义的对象对所有区域进行着色。任何帮助都将不胜感激。
谢谢!
更新1
在禤浩焯的回答之后,看起来像这
然而,仍有一个区域是我们无法着色的。
答案
在尝试许多组合之前,我已经完成了接下来的两个对象,它允许我定义我需要的颜色。您可以找到后面的所有源代码。此代码的结果可以在这图片中检查。
PropertyPage
标题
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
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
标题
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
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);
}发布于 2019-10-24 11:54:45
若要自定义淡灰色区域(即嵌入式选项卡控件),您需要重写从CPropertySheet派生的类中的OnDrawItem方法,并使用AFX_IDC_TAB_CONTROL标识符为控件执行自定义绘图。就像这样:
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;
}当然,一定要将ON_WM_DRAWITEM()添加到消息映射中!
编辑:您还必须显式地设置,将嵌入选项卡控件的样式设置为包含TCS_OWNERDRAWFIXED。您可以在类的OnInitDialog覆盖中这样做。
编辑2:现在,我有一个稍微好一些的方法来获得指向选项卡控件的指针!此外,我还添加了几行代码作为“欺骗”,以解决需要着色的剩余区域--通过扩展选项卡以适应基础控件的宽度……
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;
}请随时要求进一步的澄清和/或解释。
https://stackoverflow.com/questions/58540250
复制相似问题