有其中包括由开关case语句回调函数在我的主代码。 每种情况后,我定义的SetWindowText
功能打印在一个对话框上(或父窗口),像这样创造了一个静态控制文本:
::SetWindowText(GetDlgItem(IDC_STATIC)->m_hWnd, "loading");
我要设置静态控件作为对话框的背景的背景。 一切顺利的话,除了所有的案件发生在彼此的文字和我收到重叠文本,财产以后这样的静态控件:
我不知道为什么在每一个步骤,不会关闭静态窗口,以避免此类问题。 我加OnEraseBkgnd
, OnDestroy
, OnCtlColor
消息如下:
BOOL CmainDlg::OnEraseBkgnd(CDC* pDC)
{
// TODO: Add your message handler code here and/or call default
CDC dcMemory;
dcMemory.CreateCompatibleDC(pDC);
CBitmap* pOldbitmap = dcMemory.SelectObject(&CBmp);
CRect rcClient;
GetClientRect(&rcClient);
const CSize& sbitmap = bitmapSize;
pDC->BitBlt(0, 0, sbitmap.cx, sbitmap.cy, &dcMemory, 0, 0, SRCCOPY);
dcMemory.SelectObject(pOldbitmap);
return TRUE;
}
HBRUSH CmainDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
if (pWnd->GetDlgCtrlID() == IDC_STATIC)
//Example of changing Text colour specific to a certain
//Static Text Contol in this case IDC_STATIC.
{
pWnd->GetExStyle() & (WS_EX_TRANSPARENT);
pDC->SetBkMode(TRANSPARENT);
pDC->SetTextColor(RGB(255, 255, 255));
}
if (pWnd->GetDlgCtrlID() == IDC_OPERATION)
{
pWnd->GetExStyle() & (WS_EX_TRANSPARENT);
pDC->SetBkMode(TRANSPARENT);
pDC->SetTextColor(RGB(255, 255, 0));
// Return handle to our CBrush object
}
return reinterpret_cast<HBRUSH>(GetStockObject(NULL_BRUSH));
}
void CmainDlg::OnDestroy()
{
CDialog::OnDestroy();
// TODO: Add your message handler code here
Background.DeleteObject(); // Delete Background bitmap
BrushHol.DeleteObject();
}
//subclass the static control, just to make sure the code is the only one handling WM_ERASEBKGND and WM_PAINT messages.
void CmainDlg::PreSubclassWindow()
{
CWnd::PreSubclassWindow();
const LONG_PTR exStyle = GetWindowLongPtr(m_hWnd, GWL_EXSTYLE);
SetWindowLongPtr(m_hWnd, GWL_EXSTYLE, exStyle | WS_EX_TRANSPARENT);
}
更新:
我评论OnEraseBkgnd
, OnDestroy
, OnCtlColor
功能。 所以,我收到了同样的重叠文字和现在更加确信我可以说,这个问题是来自setWindowText
,因为每次完成后案文仍保留在我的每个开关的情况下statments的定义的静态控制窗口。 我试着用下面的命令,但什么都没有发生:
EnableWindow( GetDlgItem(m_hWnd, IDC_STATIC), FALSE);
m_static.EnableWindow(FALSE);
要么
::SetDlgItemText(m_hWnd, IDC_STATIC, "");
我要感谢所有帮助。
最简单的解决方法是:
- 不要设置文本背景模式为透明。
- 不要设置文本背景色(与SetBkColor )到对话框的颜色。
唯一的诀窍是让对话框作为COLORREF的颜色。 如果您使用的是标准的东西,你可能只需要调用GetSysColor与现有颜色的常量之一。
如果对话框背景不是纯色(如渐变填充),你就必须做一些更复杂的:
- 添加WS_EX_TRANSPARENT到静态控件的扩展窗口样式。
- 继续使用透明文本模式。 您的文字将被在对话框位的新副本画。
该WS_EX_TRANSPARENT风格应该引起静电控制下的对话的一部分,静态控件之前涂上。 这应该“擦除”以前的文本,然后静态控件将绘制新的文本。
请注意,也WS_EX_TRANSPARENT使得控制透明的命中测试 (例如,鼠标点击)。 因为它是一个静态控制,即不应该的问题。 但是,这就是为什么这不是其他类型的控件的通用解决方案。
绘制不透明:
初始化m_Brush
与CreateSolidBrush
和使用SetBkMode(OPAQUE)
,而不是TRANSPARENT
绘制透明:
按照阿德里安·麦卡锡的回答和return (HBRUSH)GetStockObject(NULL_BRUSH)
静态控制,而不是返回m_Brush
。
确保对话框没有WS_CLIPCHILDREN
标志,否则你在运行同样的重叠问题,当你重新写在静态控件中的文本。
这应该这样做。
另一种选择,该代码将与融合的背景图像其他控件(编辑控件,单选按钮和复选框)的对话框可以有WS_CLIPCHILDREN
标志,但静态控制需要一个积极的ID,如果它是重绘( IDC_STATIC
通常被设置为-1 )。 对话框的项目将需要WS_EX_TRANSPARENT
标志为好。 我没有测试这么多。
不要忘记添加ON_WM_DESTROY
到消息映射。
class TDlg : public CDialogEx
{
public:
std::map<int, HBRUSH> BrushMap;
CBitmap Bitmap;
TDlg(int id, CWnd *wnd) : CDialogEx(id, wnd){};
void MakeBrush(CDC *pdc, CDC &memdc, int id);
BOOL OnEraseBkgnd(CDC* pDC);
void OnDestroy();
BOOL OnInitDialog();
HBRUSH OnCtlColor(CDC* pDC, CWnd* wnd, UINT nCtlColor);
DECLARE_MESSAGE_MAP()
};
BOOL TDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
Bitmap.LoadBitmap(IDB_BITMAP1);
return 1;
}
void TDlg::OnDestroy()
{
CDialogEx::OnDestroy();
Bitmap.DeleteObject();
for (std::map<int, HBRUSH>::iterator it = BrushMap.begin(); it != BrushMap.end(); ++it)
if (it->second)
DeleteObject(it->second);
}
void TDlg::MakeBrush(CDC *pdc, CDC &memdc, int id)
{
CWnd *item = GetDlgItem(id);
CRect rc;
item->GetClientRect(&rc);
item->MapWindowPoints(this, &rc);
CBitmap bmp;
bmp.CreateCompatibleBitmap(&memdc, rc.Width(), rc.Height());
memdc.SelectObject(bmp);
memdc.BitBlt(0, 0, rc.Width(), rc.Height(), pdc, rc.left, rc.top, SRCCOPY);
BrushMap[id] = CreatePatternBrush(bmp);
}
BOOL TDlg::OnEraseBkgnd(CDC* pDC)
{
BITMAP bm;
Bitmap.GetBitmap(&bm);
CDC memdc;
memdc.CreateCompatibleDC(pDC);
CBitmap* pOldbitmap = memdc.SelectObject(&Bitmap);
pDC->BitBlt(0, 0, bm.bmWidth, bm.bmHeight, &memdc, 0, 0, SRCCOPY);
//BrushMap should be intialized once
if (!BrushMap.size())
for (CWnd *p = GetWindow(GW_CHILD); p; p = p->GetNextWindow(GW_HWNDNEXT))
if (p->GetDlgCtrlID() > 0)
MakeBrush(pDC, memdc, p->GetDlgCtrlID());
memdc.SelectObject(pOldbitmap);
return TRUE;
}
HBRUSH TDlg::OnCtlColor(CDC* pDC, CWnd* wnd, UINT nCtlColor)
{
HBRUSH br = CDialogEx::OnCtlColor(pDC, wnd, nCtlColor);
pDC->SetTextColor(RGB(255, 0, 0));
pDC->SetBkMode(TRANSPARENT);
int id = wnd->GetDlgCtrlID();
if (id > 0 && BrushMap[id])
return BrushMap[id];
if (nCtlColor == CTLCOLOR_STATIC)
return (HBRUSH)GetStockObject(NULL_BRUSH);
return br;
}