对话框的OnCtrlcolor里if(this==pWnd)
{
CPen pen(PS_SOLID, 3,RGB(255,0,0));
pDC->SelectObject(&pen);
pDC->MoveTo(0,0);
pDC->LineTo(100,29);
}结果绘制曲线失败, 什么原因?
求破
{
CPen pen(PS_SOLID, 3,RGB(255,0,0));
pDC->SelectObject(&pen);
pDC->MoveTo(0,0);
pDC->LineTo(100,29);
}结果绘制曲线失败, 什么原因?
求破
onctlcolor已经有pdc这个参数了,我干嘛要重新定义呢?
是这个吗?
如果是 这个里面的pdc是需要和当前的DC相关联才可以,调用GetDC().
应说了,不需要直接用pdc
HPEN hPenOld;
hPen = CreatePen(PS_SOLID,3,RGB(255,0,0));
hPenOld = (HPEN)SelectObject(pDC->m_hDC,hPen);
pDC->MoveTo(20,10);
pDC->LineTo(200,100);
SelectObject(pDC->m_hDC,hPenOld);
DeleteObject(hPen);
代码最好放到OnDraw函数或者OnPaint函数中
wm_ctlcolor---->wm_paint所以按照这个道理,规律,那么我的的法子是可行的, 结果却什么看不到,怎么回事?
12楼啊
这个DC 是不是 本窗口的 DC ?
void CaaaDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // 用于绘制的设备上下文 SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0); // 使图标在工作区矩形中居中
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2; // 绘制图标
dc.DrawIcon(x, y, m_hIcon);
}
else
{
//CDialog::OnPaint(); CPaintDC dc(this) ;
/* CPen pen(PS_SOLID, 3,RGB(255,0,0));
dc.SelectObject(&pen);
dc.MoveTo(0,0);
dc.LineTo(100,29);*/
}
}//当用户拖动最小化窗口时系统调用此函数取得光标
//显示。
HCURSOR CaaaDlg::OnQueryDragIcon()
{
return static_cast<HCURSOR>(m_hIcon);
}
HBRUSH CaaaDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor); // TODO: 在此更改 DC 的任何属性 // TODO: 如果默认的不是所需画笔,则返回另一个画笔
if(this==pWnd)
{
CPen pen(PS_SOLID, 3,RGB(255,0,0));
pDC->SelectObject(&pen);
pDC->MoveTo(0,0);
pDC->LineTo(100,29);
}
return hbr;
}
wm_erasebkgnd--->wm_ctlcolor问题在这里-->wm_paint
wm_erasebkgnd 调用 wm_ctlcolor 是为了得到一个画刷,得到画刷后 它还有工作要做
(就是用这个画刷刷 背景),一旦 让这个函数再接着工作下去, 你画的东西就没有了(覆盖了)。
为此 必须 在 wm_erasebkgnd 自己调 wm_ctlcolor (即你画的东西),然后就退出。
代码:
BOOL CaaaDlg::OnEraseBkgnd(CDC* pDC)
{
CaaaDlg::OnCtlColor(pDC, this, WM_CTRLCLOR_DLG);
return TRUE;
}
深深的震撼了。windows 的wm_erasebkgnd还有在背后做工作, 这一点确实没有想到。可能是系统拿到刷子做的吧。所以,不能发出wm_ctlcolordlg这个消息来解决问题。题外话:与刷子相关的问题------------在onctlcolor中贴图, 刷子不会去覆盖掉你贴的图, 但是绘制的曲线却被覆盖了。呵呵
建一个对话框工程,删除 ok,cancel
响应:void CCtrlColorDlg::OnPaint()
{
afxDump << "OnPaint\n";
CPaintDC dc(this);
}
BOOL CCtrlColorDlg::OnEraseBkgnd(CDC* pDC)
{
afxDump << "OnEraseBkgnd\n";
CCtrlColorDlg::OnCtlColor(pDC, this, CTLCOLOR_DLG);
return TRUE;
}HBRUSH CCtrlColorDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
if(this==pWnd)
{
afxDump << "OnCtlColor\n";
CPen pen(PS_SOLID, 3,RGB(255,0,0));
pDC->SelectObject(&pen);
pDC->MoveTo(0,0);
pDC->LineTo(450,280);
}
return hbr;
}
// 输出:
OnEraseBkgnd
OnCtlColor
OnCtlColor
OnPaint注意有 2个 OnCtlColor !!!!然后修改: HBRUSH hbr = 0;//CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
这时就一个
OnCtlColor
了// 再改改: CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
HBRUSH hbr = CreateSolidBrush(RGB(0,255,255));
注意 背景已经是 RGB(0,255,255) 了 !! 我们没有画背景 !!2个 OnCtlColor 时 ,可以发现 是第二个 OnCtlColor 画的 结果。有点 出于 意料, OnCtlColor 会画 背景,而且 CTLCOLOR_DLG 会 有2次。
函数onerasebkgdn之后,wm_ctlcolordlg的代码是不会执行的。所以在这种情况下,想调用onctlcolor中的wm_ctlcolordlg的代码,那么只能显示的调用了。所以只是一次调用而已, 并且最重要的是: 你主要显示的调用onctlcolodlg,那么是不会绘制背景的。试验现象表明:以上2点都错误了。看来windows确实诡异无比,难度很大
DefWindowProc
其 参数 为 :
(WM_ERASEBKGND,hDC,0)
就是说 又 做了一次 WM_ERASEBKGND !!
又做了一次wm_erasebkgnd的话, afxdump<<"onerasebkgnd" 岂不是应该出现2次?
而非一次
{
afxDump << "OnEraseBkgnd\n";
CCtrlColorDlg::OnCtlColor(pDC, this, CTLCOLOR_DLG);
// 其实是因为 这里没做完 !
return TRUE;
}
// CDialog::OnCtlColor(pDC, pWnd, nCtlColor);// 因为我们知道 对于对话框 最后是调:
_AFX_THREAD_STATE* pThreadState = AfxGetThreadState();
DefWindowProc(pThreadState->m_lastSentMsg.message,// 0x14=WM_ERASEBKGND
pThreadState->m_lastSentMsg.wParam,// hDC
pThreadState->m_lastSentMsg.lParam);// 0
//
这里的 m_lastSentMsg.message=0x14=WM_ERASEBKGND, 就是OnEraseBkgnd时留下的lastSentMsg
(上次送出的消息)
总之在OnCtlColor中 绘制不是一个好办法,还是按规矩办 为好。
多谢,很高深, 不知掉这个帖子, 过几年后,能否搞懂 wm-ctlcolordlg执行2次的原因。发分