+ -
当前位置:首页 → 问答吧 → 40分求解 :正确DeleteObject,

40分求解 :正确DeleteObject,

时间:2011-12-04

来源:互联网

看有颜色的哪行代码, 首先 我是在 函数里面 SelectObject,按照msdn的说法,应该 DeleteObject

问题1:什么时候该DeleteObject???? 在函数末尾DeleteObject合不合适




问题2:由于: DeleteObject的参数类型是:BOOL DeleteObject(
HGDIOBJ hObject
); 

我的代码中: SeleteObjcet(CBrush),那么 我发做到DeleteObject!!!!!

想删除Object,就必须从CBursh转换成HBrush,如何转



问题3: 函数OnNcPaint,看到都知道,我想实现:画非客户的功能,我发现,当对话框

最小化后, 就不会再被绘制,我没有正确使用OnNcPaint,,,,,否则最小化有不会 恢复原来的颜色





void CMyDialog::OnNcPaint()
{

CDialog::OnNcPaint();
CDC* pDC=GetWindowDC(); 
CRect rcTitle,rcWin; 
GetWindowRect(rcWin); 
rcTitle.left=70; 
rcTitle.top=1; 
rcTitle.right=rcWin.Width()-2; 
rcTitle.bottom=GetSystemMetrics(SM_CYSCREEN); 
CBrush hBrush;
hBrush.CreateSolidBrush(RGB(255,0,0)); //创建画刷
pDC-> SelectObject(hBrush);
pDC-> FillRect(rcTitle,&hBrush); 
  // pDC->DeleteObject(hBrush);
ReleaseDC(pDC);

}


问题4:

由于这这个对话框是基于 多文档程序的基础上 添加对话框, 所以 它的OnInitDialog函数中

是没有所谓加载 icon的功能的,需要自己写。。。。。。。。

对吧???

看到 颜色的那个hIcon没有, 但我把这个变量 没有放在类中,而是放在 函数的局部变量后,是无法实现绘制icon的功能的!!!

这是什么原因??????

SetIcon一次不久可以了吗??、 为什么非要用成员变量,局部变量不行啊?????




BOOL CMyDialog::OnInitDialog() 
{
CDialog::OnInitDialog();

// TODO: Add extra initialization here
hIcon=LoadIcon(AfxGetApp()->m_hInstance,MAKEINTRESOURCE(IDI_ICON1));
  SetIcon(hIcon,TRUE);
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}


问题有些多, 大家帮忙解答一下,谢谢了啊


作者: caddor2011   发布时间: 2011-12-04

1.
pDC-> SelectObject(hBrush);// 这句是把你的hBrush与DC连接起来,DC原来的hOldBrush需要保存起来:
HBRUSH hOldBrush=pDC-> SelectObject(hBrush);
//使用
pDC-> FillRect(rcTitle,&hBrush); 
//删除
SelectObject(hOldBrush);// 这句是把你的hBrush与DC脱离关系。同时恢复了DC原来的Brush
pDC->DeleteObject(hBrush);// 这时你才能删除你的Brush,没有上句你是删除不了的
 

作者: schlafenhamster   发布时间: 2011-12-04

2.CBrush Brush;// 不是Handle !
Brush.CreateSolidBrush(RGB(255,0,0)); //创建画刷
HBRUSH hOldBrush=pDC->SelectObject(Brush.m_hObject);

作者: schlafenhamster   发布时间: 2011-12-04

4.SetIcon(hIcon,TRUE);//这个icon对话框要一直用的不能是局部变量。

//关于NcPaint不太明白你的意思。

作者: schlafenhamster   发布时间: 2011-12-04

在楼上的建议下,修改了一下:

OnNcPaint函数,在这里,我是用来 绘制 对话框的标题栏的。。。。。

改变标题栏的颜色。。。。。。。

对话框出来后,拖动对话框移动,发现,会导致 客户区的颜色变红色。。。。。

我的代码是实现:标题栏 变红色而已。。。。。

为什么拖动过程中辉导致 客户区变红色。。。。。。




void CMyDialog::OnNcPaint()
{

CDialog::OnNcPaint();
CDC* pDC=GetWindowDC();
HDC hDC=pDC->GetSafeHdc();

CRect rcTitle,rcWin; 
GetWindowRect(rcWin); 
rcTitle.left=70; 
rcTitle.top=1; 
rcTitle.right=rcWin.Width()-2; 
rcTitle.bottom=GetSystemMetrics(SM_CYSCREEN); 
HBRUSH hBrush;
hBrush=::CreateSolidBrush(RGB(255,0,0)); //创建画刷
HBRUSH hOldBrush= (HBRUSH)(pDC-> SelectObject(hBrush));
::FillRect(hDC,rcTitle,hBrush); 

//删除
pDC->SelectObject(hOldBrush);
::DeleteObject(hBrush);// 这时你才能删除你的Brush,没有上句你是删除不了的
ReleaseDC(pDC);

}

作者: caddor2011   发布时间: 2011-12-04

我插句话:DeleteObject其实是包含在了CObject里面。
再说一句:HBRUSH完全可以直接reinterpret_cast<HBRUSH>brush
再插一句:可以brush.DeleteObject呀
再加一句:必须要在以前的话刷定义之前
附带程序:
C/C++ code

//...
CBrush *pOldBr=pDC->SelectObject(&brush);
//...
pDC->SelectObject(pOldBr);
brush.DeleteObject();//完全可以在函数末尾

作者: ghj123h   发布时间: 2011-12-04

你可以在PreTranslateMessgae中:
if(pMsg->message==WM_NCKEYDOWN)
 n=1;
else if(pMsg->message==WM_NCPAINT)
 return;
else
 n=0;
附带程序:
C/C++ code

BOOL CMyDialog::PreTranslateMessage(Msg *pMsg)
{
 static int n;
 if(pMsg->message==WM_NCKEYDOWN)
 n=1;
else if(pMsg->message==WM_NCPAINT&&n==1){n=0;
 return FALSE;}
else
 n=0;
 return CDialogEx::PreTranslateMessage(pMsg);
}

作者: ghj123h   发布时间: 2011-12-04

rcTitle.bottom=GetSystemMetrics(SM_CYSCREEN); // 太大了吧
rcTitle.bottom=rcTitle.top + 46;
我的VC60没发现问题。

作者: schlafenhamster   发布时间: 2011-12-04

学习了

作者: q359445879   发布时间: 2011-12-04

WM_NCKEYDOWN 根本找不到 这是什么意思????


而且5楼提供的代码是没有问题的。。。。

现在的问题 如何解决???对话框拖动 后, 被其他对话框遮住 就会改变 客户区 颜色




引用 6 楼 ghj123h 的回复:

你可以在PreTranslateMessgae中:
if(pMsg->message==WM_NCKEYDOWN)
n=1;
else if(pMsg->message==WM_NCPAINT)
return;
else
n=0;
附带程序:
C/C++ code

BOOL CMyDialog::PreTranslateMessage(Msg *pMsg)
{
sta……

作者: caddor2011   发布时间: 2011-12-04

up up

作者: caddor2011   发布时间: 2011-12-04

"拖动对话框移动"时确实有问题,我看看。

作者: schlafenhamster   发布时间: 2011-12-04

谢谢了啊



引用 11 楼 schlafenhamster 的回复:

"拖动对话框移动"时确实有问题,我看看。

作者: caddor2011   发布时间: 2011-12-04

不如放Paint中:
else
{
CDialog::OnPaint();
//
CDC* pDC=GetWindowDC();
CRect rcTitle;  
rcTitle.left=70;  
rcTitle.top = 2;
rcTitle.right=rcTitle.left+350;
rcTitle.bottom=rcTitle.top + 26;
//
HBRUSH hBrush;
hBrush=::CreateSolidBrush(RGB(255,0,0)); //创建画刷
HBRUSH hOldBrush= (HBRUSH)(pDC->SelectObject(hBrush));
::FillRect(pDC->m_hDC,rcTitle,hBrush);  
//删除
pDC->SelectObject(hOldBrush);
::DeleteObject(hBrush);// 这时你才能删除你的Brush,没有上句你是删除不了的
ReleaseDC(pDC);
}
// 效果很好的

作者: schlafenhamster   发布时间: 2011-12-04

FillSolidRect is very similar to CDC::FillRect; however, FillSolidRect uses only solid colors (indicated by the COLORREF parameter),

作者: schlafenhamster   发布时间: 2011-12-04

非常感谢你多次回复。。。。。 麻烦你这么多次。。。。

情况有些糟糕, 你的代码和我的代码 同个同样的问题就是:

非模式对话框,对吧,我一旦点击对话框之外的地方, 颜色又回复了。。。。。。 真是奇怪之极。。。

我的代码如下:


void CMyDialog::OnNcPaint()
{

CDialog::OnNcPaint();
CDC* pDC=GetWindowDC();
HDC hDC=pDC->GetSafeHdc();

CRect rcTitle,rect; 
GetClientRect(rect);
rcTitle.left=30; 
rcTitle.top=1; 
rcTitle.right=rect.right-70; 
rcTitle.bottom=30; 

HBRUSH hBrush;
hBrush=::CreateSolidBrush(RGB(255,0,0)); //创建画刷
HBRUSH hOldBrush= (HBRUSH)(pDC-> SelectObject(hBrush));
::FillRect(hDC,rcTitle,hBrush); 

//删除
pDC->SelectObject(hOldBrush);
::DeleteObject(hBrush);// 
ReleaseDC(pDC);

}

这个问题真是不好解决。。。。

还有: 比如: 对话框的边框颜色,。

我打算用类似以下大代码来解决它,
pDC->FrameRect(rectEdit, &brushOuter);


虽然没尝试,估计也会遇到和 标题栏的问题。。。。。


也就是说,如何来实现,当点击对话框画的地方的时候,需要让它再绘制一次。。。。。




引用 13 楼 schlafenhamster 的回复:

不如放Paint中:
else
{
CDialog::OnPaint();
//
CDC* pDC=GetWindowDC();
CRect rcTitle;
rcTitle.left=70;
rcTitle.top = 2;
rcTitle.right=rcTitle.left+350;
rcTitle.bottom=rcTitle.top + 26;
//
H……

作者: caddor2011   发布时间: 2011-12-04

我用的是模式对话框,不知道非模式对话框

作者: schlafenhamster   发布时间: 2011-12-04

模式对话框:


void CMyDialog::OnPaint() 
{
CPaintDC dc(this); // device context for painting

// TODO: Add your message handler code here
CDC* pDC=GetWindowDC();
CRect rcTitle;  
rcTitle.left=70;  
rcTitle.top = 2;
rcTitle.right=rcTitle.left+350;
rcTitle.bottom=rcTitle.top + 26;
//
HBRUSH hBrush;
hBrush=::CreateSolidBrush(RGB(255,0,0)); //创建画刷
HBRUSH hOldBrush= (HBRUSH)(pDC->SelectObject(hBrush));
//::FillRect(pDC->m_hDC,rcTitle,hBrush);  
CBrush* pBrush=CBrush::FromHandle(hBrush);
pDC->FrameRect(rcTitle,pBrush); //虽然这里是不是FillRect,FrameRect是用来绘制边边框的,但是和 ::FillRect一样,也会遇到同一个问题: 模式弹出来的时候,但失去焦点---- 点击对话框以外的地方,就会 立即恢复原来的颜色。。。。。 真是诡异。。。。。 真没有法子解决吗?? 难不成 用定时器,不断的去刷新重绘吗???


//删除
pDC->SelectObject(hOldBrush);
::DeleteObject(hBrush);// 这时你才能删除你的Brush,没有上句你是删除不了的
ReleaseDC(pDC);
// Do not call CDialog::OnPaint() for painting messages
}




引用 16 楼 schlafenhamster 的回复:

我用的是模式对话框,不知道非模式对话框

作者: caddor2011   发布时间: 2011-12-04