如何将静态控件背景设置为对话框背景? [英] how to set a static control background as a dialog background?
问题描述
我的主要代码中有一个回调函数,它包含在Switch case语句中。在每种情况下,我定义了一个 SetWindowText
函数,以在对话框(或父窗口)上创建的静态控件中打印文本,如下所示:
There is a call back function in my main code which included by Switch case statements. After each case I defined a SetWindowText
function to print a text in a static Control which created on a dialog (or parent window),something like this:
::SetWindowText(GetDlgItem(IDC_STATIC)->m_hWnd, "loading");
我将设置静态控件的背景作为对话框的背景。一切都很顺利,除了相互放置的所有案例的文本之外,我收到一个带有重叠文本的静态控件,这样一些东西:
I am going to set background of static control as the background of dialog. Everything goes well except the text of all the cases which place on each other and I receive a static control with overlapped texts, somthing like this:
我不知道为什么在每一步中不关闭静态窗口,避免这种问题。
我添加了 OnEraseBkgnd
, OnDestroy
, OnCtlColor
消息如下:
I don't know why in each step it does not close the static window to avoid such kind of problems.
I added OnEraseBkgnd
, OnDestroy
, OnCtlColor
messages as follow:
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
,因为在完成每个案例后,文本仍然保留在静态控制窗口中,我在每个交换机状态下定义。
我尝试使用以下命令,但没有发生任何事情:
I commented OnEraseBkgnd
, OnDestroy
, OnCtlColor
functions. So I received the same overlapped texts and now with a bit more certainty I can say the problem comes from setWindowText
because after finishing each Case the text remains on static control window which I defined in each of switch case statments.
I tried to use the following commands but nothing happened:
EnableWindow( GetDlgItem(m_hWnd, IDC_STATIC), FALSE);
m_static.EnableWindow(FALSE);
或
::SetDlgItemText(m_hWnd, IDC_STATIC, "");
我会感谢任何帮助。
推荐答案
绘图不透明:
使用 m_Brush
> CreateSolidBrush ,并使用 SetBkMode(OPAQUE)
而不是 TRANSPARENT
Initialize m_Brush
with CreateSolidBrush
and use SetBkMode(OPAQUE)
instead of TRANSPARENT
绘图透明:
按照Adrian McCarthy的回答, return(HBRUSH)GetStockObject(NULL_BRUSH) / code>
,而不是返回 m_Brush
。
Follow Adrian McCarthy's answer and return (HBRUSH)GetStockObject(NULL_BRUSH)
for static controls instead of returning m_Brush
.
确保对话框没有 WS_CLIPCHILDREN
标志,否则当您在静态控件中重写文本时,您将遇到相同的重叠问题。
Make sure dialog doesn't have WS_CLIPCHILDREN
flag, otherwise you run in to the same overlap problem when you re-write the text in static control.
应该这样做。
另一个选项,此代码将其他控件与背景图像(编辑控件,单选按钮和复选框)对话框可以具有 WS_CLIPCHILDREN
标志,但如果是b,静态控件将需要一个正的ID e重绘( IDC_STATIC
通常设置为-1)。对话框项目也需要 WS_EX_TRANSPARENT
标志。我没有测试这么多。
Another option, this code will blend other controls with background image (edit controls, radio buttons and check boxes) Dialog can have WS_CLIPCHILDREN
flag, but static control will need a positive id if it is to be redrawn (IDC_STATIC
is usually set to -1). Dialog items will need WS_EX_TRANSPARENT
flag as well. I didn't test this much.
不要忘记将 ON_WM_DESTROY
添加到邮件地图。
Don't forget to add ON_WM_DESTROY
to message map.
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;
}
这篇关于如何将静态控件背景设置为对话框背景?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!