天天看點

MFC(繼續畫圖,孫鑫C++第十講筆記整理)

1.畫圖:

a.建立四個菜單,為其添加消息響應;

b.在View中添加m_DrawType,儲存繪畫類型;

c.增加成員變量,m_PtOrigin,當按下滑鼠左鍵時,儲存此點;

d.在OnLButtonUp中畫點,線,矩形,橢圓,别忘記設定成透明畫刷

2.為其添加一個設定對話框(線型和線寬)

a.建立對話框,為其建立一個新類關聯它;

b.為其中的線寬關聯成員變量;

c.在View中增加一個菜單,響應新的對話框;

d.添加線型選項設定,将其Group屬性選中,并為單選按紐關聯成員變量。在view中增加一個線型變量m_nLineStyle

3.添加一個顔色對話框

a.執行個體化一個CColorDialog

b.調用DoModal方法

4.添加字型對話框,将選擇的字型在View中顯示出來。

a.執行個體化一個對象;

b.為View添加一個字型成員變量,得到使用者選擇的字型。

c.調用Invadate()發出重繪消息;

d.再次注意一個對象隻能建立一次,故要再次建立,必須将原告的删除!

5.為設定對話框增加示例功能。

a.當控件内容改變時,發出En_change消息。而Radio按紐則為Clicked。需先UpdateData()。另外還需要ScreenToClient(&rect)

6.改變對話框的背景色和控件顔色。

每個控件被繪制時都發出WM_CTlColor消息,

7.如何改變OK按紐的字型和背景?

OK按紐

a.建立一個新類,CTestBtn,基類為CButton

b.在類中增加虛函數,DrawItem,添加代碼。

c.将OK按紐關聯成員變量。類型為CTestBtn,注意将OK按紐的OwnerDraw特性選中。

Cancel按紐

用新類來改變。

a.加入新檔案。

b.為Cancel關聯一個成員變量,類型為CSXBtn;

c.調用CSXBtn的方法。

Cancel2按紐

a.方法同上。

8.在視窗中貼圖,4個步驟

1、建立位圖

CBitmap bitmap;

bitmap.LoadBitmap(IDB_BITMAP1);

2、建立相容DC

CDC dcCompatible;

dcCompatible.CreateCompatibleDC(pDC);

3、将位圖選到相容DC中

dcCompatible.SelectObject(&bitmap);

4、将相容DC中的位圖貼到目前DC中。在WM_EraseBkgnd()中調用,但不能再調用基類的擦除背景函數。也可以在OnDraw函數中完成,但效率低,圖像會閃爍,因為它先擦除背景,慢。

pDC->BitBlt(rect.left,rect.top,rect.Width(),

rect.Height(),&dcCompatible,0,0,SRCCOPY);

具體細節:

void CHuiTuView::OnLButtonDown(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	
	m_yuandian=point;
	CView::OnLButtonDown(nFlags, point);
}
           
void CHuiTuView::OnLButtonUp(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	
	CClientDC cdcc(this);
	
	HBRUSH hbrush=(HBRUSH)GetStockObject(NULL_BRUSH);
	CBrush *oldbrush=cdcc.SelectObject(CBrush::FromHandle(hbrush));

	CPen cpen(m_xianleixing,m_xiandaxiao,RGB(255,0,0));
	CPen *oldpen=cdcc.SelectObject(&cpen);

	switch(m_huastyle)
	{
	case 0:

		cdcc.SetPixel(point,RGB(255,0,0));
		break;
		
	case 1:
		cdcc.MoveTo(m_yuandian);
		cdcc.LineTo(point);
		break;
		
	case 2:
		cdcc.Rectangle(&CRect(m_yuandian,point));
		break;
		
	case 3:
		cdcc.Ellipse(&CRect(m_yuandian,point));
		break;
		
	default:
		break;
	}
	
	cdcc.SelectObject(oldbrush);
	cdcc.SelectObject(oldpen);
	CView::OnLButtonUp(nFlags, point);
}
           
void CHuiTuView::OnSetting() 
{
	// TODO: Add your command handler code here
	CHuituDlg cdlg;

	cdlg.m_xiankuai=m_xiandaxiao;
	cdlg.m_leixing=m_xianleixing;
	if(IDOK==cdlg.DoModal())
	{
		UpdateData();
		m_xiandaxiao=cdlg.m_xiankuai;
		m_xianleixing=cdlg.m_leixing;
	}

}
           
void CHuiTuView::OnDian() 
{
	// TODO: Add your command handler code here
	m_huastyle=0;
	
}

void CHuiTuView::OnLine() 
{
	// TODO: Add your command handler code here
	m_huastyle=1;
}

void CHuiTuView::OnJuxing() 
{
	// TODO: Add your command handler code here
	m_huastyle=2;
}

void CHuiTuView::OnYuan() 
{
	// TODO: Add your command handler code here
	m_huastyle=3;
}
           
MFC(繼續畫圖,孫鑫C++第十講筆記整理)

edit挂鍊一個UINT整形,類型radio關聯一個int

調用系統的調色闆

1菜單添加一個“顔色”選項 ID_COLOR

2為這個COLOR添加事件

void CHuiTuView::OnColor() 
{
	// TODO: Add your command handler code here

	CColorDialog  ccdlg;
	ccdlg.m_cc.Flags|= CC_FULLOPEN | CC_RGBINIT;
	
	ccdlg.m_cc.rgbResult=m_yanse;
	if(IDOK==ccdlg.DoModal())
	{
		m_yanse=ccdlg.m_cc.rgbResult;
	}
}
           

3在CXXView中定義成員變量m_yanse,然後畫圖的時候,用這個去建立就行了

MFC(繼續畫圖,孫鑫C++第十講筆記整理)

建立字型對話框也是一樣的步驟

void CHuiTuView::OnZiti() 
{
	// TODO: Add your command handler code here
	
	CFontDialog cfdlg;
	
	if(IDOK==cfdlg.DoModal())
	{
		if(m_ziti.m_hObject)
		{
		m_ziti.DeleteObject();
		
		}
		m_ziti.CreateFontIndirect(cfdlg.m_cf.lpLogFont);
		m_zitimingzi=cfdlg.m_cf.lpLogFont->lfFaceName;
	}
	Invalidate();
}
           
MFC(繼續畫圖,孫鑫C++第十講筆記整理)

一個選擇線條的示例

void CHuituDlg::OnChangeXiankuan() 
{
	// TODO: If this is a RICHEDIT control, the control will not
	// send this notification unless you override the CDialog::OnInitDialog()
	// function and call CRichEditCtrl().SetEventMask()
	// with the ENM_CHANGE flag ORed into the mask.
	
	// TODO: Add your control notification handler code here

	Invalidate();
	
}

void CHuituDlg::OnRadio1() 
{
	// TODO: Add your control notification handler code here
	Invalidate();
}

void CHuituDlg::OnRadio2() 
{
	// TODO: Add your control notification handler code here
	Invalidate();	
}

void CHuituDlg::OnRadio3() 
{
	// TODO: Add your control notification handler code here
	Invalidate();
}

void CHuituDlg::OnPaint() 
{
	CPaintDC dc(this); // device context for painting
	
	// TODO: Add your message handler code here
	
	UpdateData();
	CClientDC ccdc(this);
	CPen cpen(m_leixing,m_xiankuai,RGB(255,0,0));//可以設定一個成員變量接收來自調色闆的顔色
	ccdc.SelectObject(&cpen);

	CRect crect;
	GetDlgItem(ID_SHILI)->GetWindowRect(&crect);
	
	ScreenToClient(&crect);
	TEXTMETRIC tm;
	ccdc.GetTextMetrics(&tm);
	ccdc.MoveTo(crect.left+20,crect.top+crect.Height()/2);
	ccdc.LineTo(crect.right-20,crect.top+crect.Height()/2);



	
	// Do not call CDialog::OnPaint() for painting messages
}
           

當進行資料互動是要UpdateData

MFC(繼續畫圖,孫鑫C++第十講筆記整理)

能夠立即互動

在對話框中添加WM_CTLCOLOR消息

HBRUSH CHuituDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) 
{
	HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
	
	// TODO: Change any attributes of the DC here
	
	// TODO: Return a different brush if the default is not desired


	return  m_myBrush;
	//return hbr;
}
           

m_mBrush.CreateSolidBrush(RGB(0,255,0))

傳回自己的畫刷,對話框中的控件繪制的時候 就會觸發這個消息

MFC(繼續畫圖,孫鑫C++第十講筆記整理)
HBRUSH CHuituDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) 
{
	HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
	
	// TODO: Change any attributes of the DC here
	
	// TODO: Return a different brush if the default is not desired
	
	if(pWnd->GetDlgCtrlID()==ID_LEIXINGKUANGKUANG)
	{
		pDC->SetBkColor(RGB(255,0,0));
		pDC->SetTextColor(RGB(255,255,255));
		return m_myBrush;
	}

	if(pWnd->GetDlgCtrlID()==ID_XIANKUAN)
	{
		pDC->SetBkColor(RGB(255,0,0));
		pDC->SetTextColor(RGB(255,255,255));
		return m_myBrush;
	}

	if(pWnd->GetDlgCtrlID()==ID_MFC)
	{
		pDC->SelectObject(&mfcziti);
	}

	if(pWnd->GetDlgCtrlID()==IDOK)
	{
		pDC->SetTextColor(RGB(255,0,0));
		pDC->SetBkMode(TRANSPARENT);
	}

	//return  m_myBrush;
	return hbr;
}
           

現在沒有辦法改變BUTTon的屬性,隻能通過它的虛函數DrawItem去改變

下面建立一個CBUTTOn的派生類,然後去覆寫DrawItem函數

然後關聯控制,将OK關聯到建立的派生類

MFC(繼續畫圖,孫鑫C++第十講筆記整理)
MFC(繼續畫圖,孫鑫C++第十講筆記整理)

如果還想改變按鈕的背景顔色或其它的,可以使用組建重用,即利用别人寫好的現成的類

把類和頭檔案都添加項目目錄裡面,然後将按鈕關聯到 元件類,然後可以在OnInitDlg中新添加一些屬性。這裡引用牛人寫的CButtonST類

BOOL CHuituDlg::OnInitDialog() 
{
	CDialog::OnInitDialog();
	
	// TODO: Add extra initialization here
	m_paisheng.SetActiveBgColor(RGB(255,0,0));
	m_paisheng.SetActiveFgColor(RGB(0,255,0));
	return TRUE;  // return TRUE unless you set the focus to a control
	              // EXCEPTION: OCX Property Pages should return FALSE
}
           
MFC(繼續畫圖,孫鑫C++第十講筆記整理)

位圖:

在CXXView中 添加WM_ERASEBKGND消息

BOOL CHuiTuView::OnEraseBkgnd(CDC* pDC) 
{
	// TODO: Add your message handler code here and/or call default

	//MessageBeep(0);這句用來測試,擦除是什麼時候觸發的,在調用ONPaint之前觸發的


	CBitmap cbitmap;
	cbitmap.LoadBitmap(IDB_BITMAP1);


	CDC memDC;
	memDC.CreateCompatibleDC(pDC);
	memDC.SelectObject(&cbitmap);

	CRect crect;
	GetClientRect(&crect);
	pDC->BitBlt(0,0,crect.Width(),crect.Height(),&memDC,0,0,SRCCOPY);

		
	return TRUE;
	//return CView::OnEraseBkgnd(pDC);
}
           
MFC(繼續畫圖,孫鑫C++第十講筆記整理)

1:1複制的

下面還有個可以拉伸的

MFC(繼續畫圖,孫鑫C++第十講筆記整理)

CBitmap有個成員方法

MFC(繼續畫圖,孫鑫C++第十講筆記整理)

這樣就可以擷取位圖的寬度和高度了

BOOL CHuiTuView::OnEraseBkgnd(CDC* pDC) 
{
	// TODO: Add your message handler code here and/or call default

	//MessageBeep(0);這句用來測試,擦除是什麼時候觸發的,在調用ONPaint之前觸發的


	CBitmap cbitmap;
	cbitmap.LoadBitmap(IDB_BITMAP1);

	BITMAP bitmap;
	cbitmap.GetBitmap(&bitmap);

	CDC memDC;
	memDC.CreateCompatibleDC(pDC);
	memDC.SelectObject(&cbitmap);

	CRect crect;
	GetClientRect(&crect);
	//pDC->BitBlt(0,0,crect.Width(),crect.Height(),&memDC,0,0,SRCCOPY);
	pDC->StretchBlt(0,0,crect.Width(),crect.Height(),&memDC,0,0,bitmap.bmWidth,bitmap.bmHeight,SRCCOPY);
		
		
	return TRUE;
	//return CView::OnEraseBkgnd(pDC);
}
           
MFC(繼續畫圖,孫鑫C++第十講筆記整理)

上面的代碼可以寫在OnPaint或OnDraw中