解决按钮的重画问题,再给100分!!

马鸣风萧萧 2003-03-14 09:58:21

我做了一个在对话框上的一个按钮上画图的程序。
可是,为了在其上画的图形不在窗口重绘时被擦掉(当有别的窗口盖住对话框上的按钮时,在拿开别的窗口,画在按钮上的图形就被擦掉了),我强制刷新该按钮,然后响应对话框的WM_DRAWITEM消息。在该消息处理函数中,绘制了按钮的背景图像。
可是,当我想在按钮上绘制其他的图形时,因为要面对不同的响应接口(比如:在一个菜单项里加入在按钮上画直线的功能,而另一个菜单项里加入在按钮上画圆的功能),不好都在WM_DRAWITEM的消息处理函数中加入画其他演示图形的代码。于是,为了又能不被其他窗口覆盖时,画的图形被擦掉,我想创建一个该按钮的设备描述表兼容的内存设备描述表,然后其他的接口(菜单消息处理函数)都在内存中画,画完再刷新按钮。在WM_DRAWITEM的消息处理函数中仅加一个BitBlt()函数。
于是作为试验,我先把按钮上的背景也改在在内存中画:在OnInitDialog()中加入以下代码,想用这种方法,在初始化的时候,能在按钮上加上背景:BOOL CAnniuDlg::OnInitDialog()
{
CDialog::OnInitDialog();

HBITMAP hBitmap;
CWnd *p_ButtonWnd=GetDlgItem(IDC_BUTTON2);
CDC *pdc=p_ButtonWnd->GetDC();
pmdc->CreateCompatibleDC(pdc);
CRect rect;
this->GetWindowRect(&rect);
HDC hdc=pdc->GetSafeHdc();
hBitmap=::CreateCompatibleBitmap(hdc,rect.right,rect.bottom);
pmdc->SelectObject(CBitmap::FromHandle(hBitmap));
CBrush brush;
brush.CreateSolidBrush(RGB(255,255,255));
pmdc->SelectObject(&brush);
pmdc->PatBlt(0,0,rect.right,rect.bottom,PATCOPY);
p_ButtonWnd->Invalidate();
p_ButtonWnd->UpdateWindow();

return TRUE; // return TRUE unless you set the focus to a control
}

void CAnniuDlg::OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct)
{
// TODO: Add your message handler code here and/or call default


CDC dc;
dc.Attach(lpDrawItemStruct->hDC);
if(nIDCtl=IDC_BUTTON2)
{ CRect r;
CWnd *p_ButtonWnd=GetDlgItem(IDC_BUTTON2);
p_ButtonWnd->GetClientRect(&r);
dc.BitBlt(0,0,r.right,r.bottom,pmdc,0,0,SRCCOPY);
}
CDialog::OnDrawItem(nIDCtl, lpDrawItemStruct);
}


可是程序执行出错:Unhandled exception in Myexe.exe(MFC42D.DLL):0xC0000005:Access Violation. 在调试的时候,发现WINGDI.CPP的这段代码发生断言错误:
ASSERT(m_hDC == NULL); // only attach once, detach on destroy
ASSERT(m_hAttribDC == NULL); // only attach to an empty DC

请问这是怎么回事???不能得到按钮的显示设备描述表相兼容的内存设备描述表指针吗???该如何得到??
还有没有其他解决重画的方法?
先谢了!!!
...全文
89 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
ljxxjl 2003-03-14
  • 打赏
  • 举报
回复
在这段代码在:
CWnd *p_ButtonWnd=GetDlgItem(IDC_BUTTON2);
CDC *pdc=p_ButtonWnd->GetDC();
pmdc->CreateCompatibleDC(pdc);
pdc是一临时变量,过后就被销掉了,据以你在OnDrawItem()函数中再用到那个内存DC应出错
winthegame 2003-03-14
  • 打赏
  • 举报
回复
去CodeProject 或者CodeGuru上面去找找自画Button的例子吧。太多了,都很简单的。。。
yndfcd 2003-03-14
  • 打赏
  • 举报
回复
MSDN上说自绘按钮在需要绘制时会调用CButton的DrawItem成员函数。不过我从CBtton派生了一个类CODButton并将它于一个按钮绑定,发现并没有调用DrawItem函数。
也许是我的理解有误吧,MSDN上的原话如下:

(CButton::DrawItem)Called by the framework when a visual aspect of an owner-drawn button has changed. An owner-drawn button has the BS_OWNERDRAW style set. Override this member function to implement drawing for an owner-drawn CButton object.
wx_xuan 2003-03-14
  • 打赏
  • 举报
回复
mark

15,979

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 界面
社区管理员
  • 界面
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧