1) 在對話方塊中重載重繪OnPaint() ,其中的CpaintDC dc(this) 是有自己的座標系統的,看網路上說可以使用MapDialogRect 去掉模板單位到Screen單位。這個是在網路上看的,之後自己使用了CpaintDC dc(this),
CPaintDC dc(this); // device context for painting
// TODO: 在此處添加訊息處理常式代碼
// 不為繪圖訊息調用 CDialogEx::OnPaint();
CRect rc;
GetDlgItem(IDC_LINE_STATIC)->GetWindowRect(rc);
ScreenToClient(rc);
CPen pen(m_lineType,m_lineWidth,m_lineColor);
CPen *oldPen = dc.SelectObject(&pen);
dc.MoveTo(rc.left +10 ,(rc.bottom + rc.top)/2);
dc.LineTo(rc.right -10 ,(rc.bottom + rc.top)/2);
dc.SelectObject(oldPen);
GetDlgItem(IDC_FILL_STATIC)->GetWindowRect(rc);
ScreenToClient(rc);
CBrush writeBrush;
if (m_fillType == 6)
{
writeBrush.CreateSolidBrush(m_fillColor);
}else
{
writeBrush.CreateHatchBrush(m_fillType,m_fillColor);
}
CRect clientRect;
clientRect.left = rc.left +10;
clientRect.right = rc.right-10;
clientRect.top = rc.top +10;
clientRect.bottom = rc.bottom - 10;
dc.FillRect(clientRect,&writeBrush);
這個過程是正確的,只是之前畫線時,畫的線被一個控制項覆蓋,無法顯示,後來自己去掉了這個控制項,但是不太明白為什麼會被其覆蓋?
而下面的方法是,直接用了控制項的DC 實現在控制項上畫線,但是當在另外彈出強制回應對話方塊時,由於要重繪,而無法顯示對話方塊!
解釋:CPaintDC用於響應視窗重繪訊息(WM_PAINT)時的繪圖輸出。CPaintDC在建構函式中調用BeginPaint()取得裝置上下文,在解構函式中調用EndPaint()釋放裝置上下文。EndPaint()除了釋放裝置上下文外,還負責從訊息佇列中清除WM_PAINT訊息。因此,在處理視窗重畫時,必須使用CPaintDC,否則WM_PAINT訊息無法從訊息佇列中清除,將引起不斷的視窗重畫。CPaintDC也只能用在WM_PAINT訊息處理之中。
2)自己的實現方法:
//CpaintDC dc(this);
CDC *pDC = m_lineEdit.GetDC();
CRect rc;
m_lineEdit.GetRect(&rc);
CPen pen(m_lineType,m_lineWidth,m_lineColor);
CPen *oldPen = pDC->SelectObject(&pen);
pDC->MoveTo(rc.left +5,rc.bottom + rc.top +20);
pDC->LineTo(rc.right -5,rc.bottom + rc.top +20);
pDC->SelectObject(oldPen);
m_lineEdit.ReleaseDC(pDC);
在這裡當強制其重繪時,使用了UpdateWindow();
Invalidate 和 UpdateWindow的不同: Invalidate 重新整理的是客戶區,UpdateWindow重新整理的是視窗元素
////網上收集的其他對比
Invalidate()與UpdateWindow( )
void Invalidate( BOOL bErase = TRUE );
該函數的作用是使整個視窗客戶區無效。視窗的客戶區無效意味著需要重繪,例如,如果一個被其它視窗遮住的視窗變成了前台視窗,那麼原來被遮住的部分就是無效的,需要重繪。這時Windows會在應用程式的訊息佇列中放置WM_PAINT訊息。MFC為視窗類別提供了WM_PAINT的訊息處理函數OnPaint,OnPaint負責重繪視窗。視圖類有一些例外,在視圖類的OnPaint函數中調用了OnDraw函數,實際的重繪工作由OnDraw來完成。參數bErase為TRUE時,重繪地區內的背景將被擦除,否則,背景將保持不變。
它和 UpdateWindow( )區別在於:
UpdateWindow( )的作用是使視窗立即重繪。調用Invalidate等函數後視窗不會立即重繪,這是由於WM_PAINT訊息的優先順序很低,它需要等訊息佇列中的其它訊息發送完後才能被處理。調用UpdateWindow函數可使WM_PAINT被直接發送到目標視窗,從而導致視窗立即重繪。