[英]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.在下一张图片中,您可以看到我的方法得到了什么。
In this image you can see 4 colorized regions:在此图像中,您可以看到 4 个彩色区域:
OnCtlColor
OnCtlColor
着色的区域OnCtlColor
of the object CPropertyPageOnCtlColor
CPropertyPage 的 OnCtlColor 着色的区域 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!谢谢!
After the answer of Adrian it looks like this在阿德里安的回答之后,它看起来像这样
However, there's still one region we cannot colorize.但是,仍有一个区域我们无法着色。
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.