繪製直線、矩陣——MFC基於單文檔的應用(1)

準備:確定自己已經在Vs上安裝好了MFC的配件:

(最後的連接錯誤讓我很難受~~~~~)

 

首先是創建單文檔的MFC程序應用。(這裏MFC應用命名爲:OOPEx)

前提工作:

在類視圖中,找到:程序名+View類(這裏爲COOPExView[也被稱爲CView])

右鍵給該類添加一個CPoint m_point變量(獲取點擊的點的位置)

然後繼續在該類點擊,右鍵--->類嚮導中爲該類添加左鍵點擊函數(WM_LBUTTONDOWN)和左鍵釋放函數(WM_LBUTTONUP),還有光標移動消息函數(WM_MOUSEMOVE)

(一定要點擊第二步添加,直接確定是沒有添加響應函數的~~~~)

好了,函數添加完後,就是響應函數的代碼了,~~~~~

壹:直線繪製的四種方法:

一、API函數方式添加

void COOPExView::OnLButtonDown(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息處理程序代碼和/或調用默認值
	m_point = point;//保存點的位置
	CView::OnLButtonDown(nFlags, point);
}


void COOPExView::OnLButtonUp(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息處理程序代碼和/或調用默認值
	HDC hdc;
	hdc = ::GetDC(m_hWnd);//移動到線條的起始位置
	MoveToEx(hdc, m_point.x, m_point.y, NULL);//畫線
	LineTo(hdc, point.x, point.y);
	::ReleaseDC(m_hWnd, hdc);
	CView::OnLButtonUp(nFlags, point);
}

二、MFC繪製(CDC類)

void COOPExView::OnLButtonDown(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息處理程序代碼和/或調用默認值
	m_point = point;
	CView::OnLButtonDown(nFlags, point);
}


void COOPExView::OnLButtonUp(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息處理程序代碼和/或調用默認值
	CDC *pDC = GetDC();//CDC類中的GetDC()正好返回了一個CDC類的對象指針
	pDC->MoveTo(m_point);//利用CDC的成員函數畫線
	pDC->LineTo(point);
	ReleaseDC(pDC);//牢記的是,在這裏我們依然不要忘記釋放DC
	CView::OnLButtonUp(nFlags, point);
}

三、CClientDC類繪製

void COOPExView::OnLButtonDown(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息處理程序代碼和/或調用默認值
	m_point = point;//保存點的位置
	CView::OnLButtonDown(nFlags, point);
}


void COOPExView::OnLButtonUp(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息處理程序代碼和/或調用默認值
	//CClientDC dc(GetDesktopWindow());//整個屏幕,NULL也可以
	//CClientDC dc(GetParent());//獲取父類的窗口句柄,也就是CMainFrame的窗口句柄,在父類的客戶區內畫線
	CClientDC dc(this);
	dc.MoveTo(m_point);  //CClientDC類型的變量dc是一個對象,採用點操作符來調用該對象的函數
	dc.LineTo(point);
	CView::OnLButtonUp(nFlags, point);
}

四、CWindowDC類繪製

void COOPExView::OnLButtonDown(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息處理程序代碼和/或調用默認值
	m_point = point;//保存點的位置
	CView::OnLButtonDown(nFlags, point);
}


void COOPExView::OnLButtonUp(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息處理程序代碼和/或調用默認值
	//CWindowDC dc(GetDesktopWindow());//整個屏幕,NULL也可以
	//CWindowDC dc(GetParent());//獲取父類的窗口句柄,也就是CMainFrame的窗口句柄,在父類的客戶區內畫線
	CWindowDC dc(this); //視圖客戶區內作圖,結束時會自釋放DC
	dc.MoveTo(m_point);
	dc.LineTo(point);
//CWindowDC類是從CDC繼承的。它在構造的時候調用Windows函數GetWindowDC,在銷燬的時候調用ReleaseDC。
	CView::OnLButtonUp(nFlags, point);
}

 

 

貳:繪製紅色實線:

void COOPExView::OnLButtonDown(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息處理程序代碼和/或調用默認值
	m_point = point;//保存點的位置
	CView::OnLButtonDown(nFlags, point);
}


void COOPExView::OnLButtonUp(UINT nFlags, CPoint point)
{
	CPen pen(PS_SOLID, 5, RGB(255, 0, 0));//中間的數字可以調整畫筆大小
	CClientDC dc(this);
	CPen *pOldPen = dc.SelectObject(&pen);
	dc.MoveTo(m_point);
	dc.LineTo(point);
	dc.SelectObject(pOldPen);
	CView::OnLButtonUp(nFlags, point);
}

 

繪製(填充)矩陣:

void COOPExView::OnLButtonDown(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息處理程序代碼和/或調用默認值
	m_point = point;//保存點的位置
	CView::OnLButtonDown(nFlags, point);
}


void COOPExView::OnLButtonUp(UINT nFlags, CPoint point)
{
	CBrush brush(RGB(255, 0, 0));            //畫刷填充,可空心(這個自己查)
	CPen pen(PS_SOLID, 5, RGB(255, 0, 0));
	CClientDC dc(this);

	CPen *pOldPen = dc.SelectObject(&pen);
	dc.FillRect(CRect(m_point, point), &brush);
	dc.MoveTo(m_point);
	dc.LineTo(point);
	dc.SelectObject(pOldPen);
	CView::OnLButtonUp(nFlags, point);
}

 

繪製(非填充)矩陣:

void CMFCApplication1View::OnLButtonDown(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息處理程序代碼和/或調用默認值
	m_point = point;
	CView::OnLButtonDown(nFlags, point);
}


void CMFCApplication1View::OnLButtonUp(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息處理程序代碼和/或調用默認值
	CClientDC dc(this);
	CBrush *pBrush = CBrush::FromHandle((HBRUSH)GetStockObject(NULL_BRUSH)); // CBrush::FromHandle是靜態成員函數  
	//FromHandle給出一個Windows HBRUSH對象句柄時,返回一個指向CBrush對象的指針。即將畫刷的句柄轉換爲對象的指針。
	CBrush *pOldBrush = dc.SelectObject(pBrush);
	dc.Rectangle(CRect(m_point, point));
	dc.SelectObject(pOldBrush);
	CView::OnLButtonUp(nFlags, point);
}

 

叄:繪製國際象棋棋盤:

void COOPExView::OnLButtonDown(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息處理程序代碼和/或調用默認值
	m_point = point;//保存點的位置
	CView::OnLButtonDown(nFlags, point);
}


void COOPExView::OnLButtonUp(UINT nFlags, CPoint point)
{
	int hight = 20, width = 20, flag = 0;//參數可自己調大小
	CClientDC dc(this);
	CBrush *pBrush = CBrush::FromHandle((HBRUSH)GetStockObject(NULL_BRUSH)); // CBrush::FromHandle是靜態成員函數  
	CBrush *pOldBrush = dc.SelectObject(pBrush);
	dc.SelectObject(pOldBrush);
	//CClientDC dc(this);
	p1.x = m_point.x - 15;
	p1.y = m_point.y - 15;
	p2.x = m_point.x + 8 * hight + 16;
	p2.y = m_point.y + 8 * width + 16;
	dc.Rectangle(CRect(p1, p2));
	p1.x = m_point.x - 1;
	p1.y = m_point.y - 1;
	p2.x = m_point.x + 8 * hight + 1;
	p2.y = m_point.y + 8 * width + 1;
	dc.Rectangle(CRect(p1, p2));
		for (int i = 0; i < 8; i++)
		{
			for (int j = 0; j < 8; j++)
			{
				point1.x = m_point.x + i * hight;
				point1.y = m_point.y + j * width;
				point2.x = m_point.x+(i + 1)*hight;
				point2.y = m_point.y+(j + 1)*width;
				if ((i + j) % 2 == 0)
				{
					CBrush brush(RGB(0, 0, 0));
					dc.FillRect(CRect(point1, point2), &brush);
				}
				else
				{
					CBrush brush(RGB(255, 255, 255));
					dc.FillRect(CRect(point1, point2), &brush);
				}

			}
	}
	CView::OnLButtonUp(nFlags, point);
}

 

肆:雙緩衝實現國際象棋:

參考博客:MFC雙緩衝解決圖象閃爍[轉]

在CView類的類嚮導中虛函數裏,有一個OnDraw虛函數,對其進行修改;

添加代碼爲:

先在構造函數中確定初始棋盤的位置:

CMFCApplication2View::CMFCApplication2View() noexcept
{
	// TODO: 在此處添加構造代碼
	m_point.x = 200;//自己看情況
	m_point.y = 200;
}

 或者定義一個數字,讓棋盤不顯現:

CMFCApplication2View::CMFCApplication2View() noexcept
{
	// TODO: 在此處添加構造代碼
	count = 0;
}

然後在上面繪製棋盤的基礎上給OnDraw函數添加代碼:

void CMFCApplication2View::OnDraw(CDC* pDC)
{
	int nWidth = 1, nHeight = 1;
	CMFCApplication2Doc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	CDC MemDC; //首先定義一個顯示設備對象
	CBitmap MemBitmap;//定義一個位圖對象
	//隨後建立與屏幕顯示兼容的內存顯示設備
	MemDC.CreateCompatibleDC(NULL);
	//這時還不能繪圖,因爲沒有地方畫 ^_^
	//下面建立一個與屏幕顯示兼容的位圖,至於位圖的大小嘛,可以用窗口的大小
	MemBitmap.CreateCompatibleBitmap(pDC, nWidth, nHeight);
	//將位圖選入到內存顯示設備中
	//只有選入了位圖的內存顯示設備纔有地方繪圖,畫到指定的位圖上
	CBitmap *pOldBit = MemDC.SelectObject(&MemBitmap);
	//先用背景色將位圖清除乾淨,這裏我用的是白色作爲背景
	//你也可以用自己應該用的顏色
	MemDC.FillSolidRect(0, 0, nWidth, nHeight, RGB(255, 255, 255));
	//繪圖
	int hight = 20, width = 20, flag = 0;//參數可自己調大小
	CClientDC dc(this);
	CBrush *pBrush = CBrush::FromHandle((HBRUSH)GetStockObject(NULL_BRUSH)); // CBrush::FromHandle是靜態成員函數  
	CBrush *pOldBrush = dc.SelectObject(pBrush);
	dc.SelectObject(pOldBrush);
	//CClientDC dc(this);
	if (count > 0){                //可加可不加。。。。看老師心情
	p1.x = m_point.x - 15;
	p1.y = m_point.y - 15;
	p2.x = m_point.x + 8 * hight + 16;
	p2.y = m_point.y + 8 * width + 16;
	dc.Rectangle(CRect(p1, p2));
	p1.x = m_point.x - 1;
	p1.y = m_point.y - 1;
	p2.x = m_point.x + 8 * hight + 1;
	p2.y = m_point.y + 8 * width + 1;
	dc.Rectangle(CRect(p1, p2));
	for (int i = 0; i < 8; i++)
	{
		for (int j = 0; j < 8; j++)
		{
			point1.x = m_point.x + i * hight;
			point1.y = m_point.y + j * width;
			point2.x = m_point.x + (i + 1)*hight;
			point2.y = m_point.y + (j + 1)*width;
			if ((i + j) % 2 == 0)
			{
				CBrush brush(RGB(0, 0, 0));
				dc.FillRect(CRect(point1, point2), &brush);
			}
			else
			{
				CBrush brush(RGB(255, 255, 255));
				dc.FillRect(CRect(point1, point2), &brush);
			}

		}
	}
	}
	//將內存中的圖拷貝到屏幕上進行顯示
	pDC->BitBlt(0, 0, nWidth, nHeight, &MemDC, 0, 0, SRCCOPY);
	//繪圖完成後的清理
	MemBitmap.DeleteObject();
	MemDC.DeleteDC();
	// TODO: 在此處爲本機數據添加繪製代碼
}

 

效果圖:

(注意:該雙緩衝代碼只能解決最後一次繪畫國際象棋時的閃爍問題,即最大化後只會保留最後繪製的那個國際象棋棋盤)

 

伍:交互式指定棋盤大小;

方法:

通過繪畫標準線的方法界定棋盤的大小

步驟:左鍵點擊到左鍵釋放繪畫標準線,雙擊右鍵進行棋盤繪畫。。

示例:

具體操作:(文件名爲:MFCApplication3)

爲Cview類添加的變量和響應函數如下:

 

將.cpp文件中的右鍵釋放函數代碼註銷:(可在類嚮導中尋找該響應函數)

 

 繼續對各響應函數編寫代碼爲:

void CMFCApplication3View::OnLButtonDown(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息處理程序代碼和/或調用默認值
	m_point = point;
	CView::OnLButtonDown(nFlags, point);
}


void CMFCApplication3View::OnLButtonUp(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息處理程序代碼和/或調用默認值
	int S = (int)sqrt((m_point.x - point.x)*(m_point.x - point.x) + (m_point.y - point.y)*(m_point.y - point.y));
	hight = width = S;
	hight /= 9;
	width /= 9;
	CPen pen(PS_SOLID, 2, RGB(255, 0, 0));//中間的數字可以調整畫筆大小
	CClientDC dc(this);
	CPen *pOldPen = dc.SelectObject(&pen);
	dc.MoveTo(m_point);
	dc.LineTo(point);
	dc.SelectObject(pOldPen);
	CView::OnLButtonUp(nFlags, point);
}

void CMFCApplication3View::OnLButtonDblClk(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息處理程序代碼和/或調用默認值
	
	CView::OnLButtonDblClk(nFlags, point);
}


void CMFCApplication3View::OnRButtonDblClk(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息處理程序代碼和/或調用默認值
	c_point = point;
	count++;
	CClientDC dc(this);
	CBrush *pBrush = CBrush::FromHandle((HBRUSH)GetStockObject(NULL_BRUSH)); 
        // CBrush::FromHandle是靜態成員函數  
	CBrush *pOldBrush = dc.SelectObject(pBrush);
	dc.SelectObject(pOldBrush);
	//CClientDC dc(this);
	p1.x = point.x - hight / 4 * 3-1;
	p1.y = point.y - width / 4 * 3-1;
	p2.x = point.x + 8 * hight + hight / 4 * 3 + 1;
	p2.y = point.y + 8 * width + width / 4 * 3 + 1;
	dc.Rectangle(CRect(p1, p2));
	p1.x = point.x - 1;
	p1.y = point.y - 1;
	p2.x = point.x + 8 * hight + 1;
	p2.y = point.y + 8 * width + 1;
	dc.Rectangle(CRect(p1, p2));
	for (int i = 0; i < 8; i++)
	{
		for (int j = 0; j < 8; j++)
		{
			point1.x = point.x + i * hight;
			point1.y = point.y + j * width;
			point2.x = point.x + (i + 1)*hight;
			point2.y = point.y + (j + 1)*width;
			if ((i + j) % 2 == 0)
			{
				CBrush brush(RGB(0, 0, 0));
				dc.FillRect(CRect(point1, point2), &brush);
			}
			else
			{
				CBrush brush(RGB(255, 255, 255));
				dc.FillRect(CRect(point1, point2), &brush);
			}

		}
	}
	CView::OnRButtonDblClk(nFlags, point);
}

構造函數初始化變量:

CMFCApplication3View::CMFCApplication3View() noexcept
{
	// TODO: 在此處添加構造代碼
	count = 0;             //雙緩衝刷新限制條件
	hight = width = 20;    //未畫標準線時棋盤的大小
}

雙緩衝防刷新(找到OnDraw函數進行編譯):

void CMFCApplication3View::OnDraw(CDC* pDC)
{
	/*CMFCApplication3Doc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	if (!pDoc)
		return;*/
		int nWidth = 1, nHeight = 1;
		CMFCApplication3Doc* pDoc = GetDocument();
		ASSERT_VALID(pDoc);
		CDC MemDC; //首先定義一個顯示設備對象
		CBitmap MemBitmap;//定義一個位圖對象
		//隨後建立與屏幕顯示兼容的內存顯示設備
		MemDC.CreateCompatibleDC(NULL);
		//這時還不能繪圖,因爲沒有地方畫 ^_^
		//下面建立一個與屏幕顯示兼容的位圖,至於位圖的大小嘛,可以用窗口的大小
		MemBitmap.CreateCompatibleBitmap(pDC, nWidth, nHeight);
		//將位圖選入到內存顯示設備中
		//只有選入了位圖的內存顯示設備纔有地方繪圖,畫到指定的位圖上
		CBitmap *pOldBit = MemDC.SelectObject(&MemBitmap);
		//先用背景色將位圖清除乾淨,這裏我用的是白色作爲背景
		//你也可以用自己應該用的顏色
		MemDC.FillSolidRect(0, 0, nWidth, nHeight, RGB(255, 255, 255));
		//繪圖
		if (count > 0)
		{
		CClientDC dc(this);
		CBrush *pBrush = CBrush::FromHandle((HBRUSH)GetStockObject(NULL_BRUSH)); // CBrush::FromHandle是靜態成員函數  
		CBrush *pOldBrush = dc.SelectObject(pBrush);
		dc.SelectObject(pOldBrush);
		//CClientDC dc(this);
		p1.x = c_point.x - hight / 4 * 3-1;
		p1.y = c_point.y - width / 4 * 3-1;
		p2.x = c_point.x + 8 * hight + hight / 4 * 3 + 1;
		p2.y = c_point.y + 8 * width + width / 4 * 3 + 1;
		dc.Rectangle(CRect(p1, p2));
		p1.x = c_point.x - 1;
		p1.y = c_point.y - 1;
		p2.x = c_point.x + 8 * hight + 1;
		p2.y = c_point.y + 8 * width + 1;
		dc.Rectangle(CRect(p1, p2));
		for (int i = 0; i < 8; i++)
		{
			for (int j = 0; j < 8; j++)
			{
				point1.x = c_point.x + i * hight;
				point1.y = c_point.y + j * width;
				point2.x = c_point.x + (i + 1)*hight;
				point2.y = c_point.y + (j + 1)*width;
				if ((i + j) % 2 == 0)
				{
					CBrush brush(RGB(0, 0, 0));
					dc.FillRect(CRect(point1, point2), &brush);
				}
				else
				{
					CBrush brush(RGB(255, 255, 255));
					dc.FillRect(CRect(point1, point2), &brush);
				}

			}
		}
		}
		//將內存中的圖拷貝到屏幕上進行顯示
		pDC->BitBlt(0, 0, nWidth, nHeight, &MemDC, 0, 0, SRCCOPY);
		//繪圖完成後的清理
		MemBitmap.DeleteObject();
		MemDC.DeleteDC();
	// TODO: 在此處爲本機數據添加繪製代碼
}

 

 還有一種交互式繪畫棋盤大小的方法:分割視圖,用對話框傳參

(這個,我遇到了一個小小的bug,,就是對話框中獲取的數據無法傳到視圖類中,所以導致失敗,

    如果有找到如何將對話框中數據傳到視圖類中的同志們,望私戳告知,不勝感激。)

 

 

陸:將棋盤文件保存爲BMP格式文件:

(注意:這裏僅保存棋盤,而不是整個屏幕,當然,保存棋盤是建立在保存整個屏幕的基礎上的。)

前提:在  伍:【交互式指定棋盤大小的基礎】上繼續進行。

一、BITMAPINFO方式保存:

步驟:

1、切換到資源視圖,在Menu文件中雙擊IDR_MAINFRAME彈出右側文件框架中,

      爲“ 文件——>保存 ” 添加 “保存文件爲bmp格式” (當然,你開心就好~~~),

 

 2、右鍵“保存文件爲bmp格式”選擇“添加事件處理程序”,在彈出的對話框中選擇第一個COMMAND,

       右邊的類一定要選擇CView類,這裏爲“CMFCApplication3View”。

3、對上述COMMAND函數進行編輯,編輯代碼爲:

void CMFCApplication3View::On32771()
{
	// TODO: 在此添加命令處理程序代碼
	int x = c_point.x - hight / 4 * 3 - 1;//定位棋盤的位置
	int y = c_point.y - hight / 4 * 3 - 1;
	CDC* pDC = GetWindowDC();
	CBitmap bitmap;
	CDC memDC;
	CRect rect;
	GetWindowRect(rect);
	memDC.CreateCompatibleDC(pDC);

	bitmap.CreateCompatibleBitmap(pDC, rect.Width(), rect.Height());
	memDC.SelectObject(&bitmap);
	memDC.BitBlt(0, 0, rect.Width(), rect.Height(), pDC, x, y, SRCCOPY);

	CFileDialog fDlg(FALSE, _T("bmp"), NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, _T("位圖文件|*.bmp"), this);
	if (fDlg.DoModal() == IDOK)
	{
		CString bmpfile = fDlg.GetPathName();
		CFile file(bmpfile, CFile::modeCreate | CFile::modeWrite);
		BITMAP bInfo;
		bitmap.GetBitmap(&bInfo);
		//計算調色板大小   
		int panelsize = 0;
		if (bInfo.bmBitsPixel < 24) //非真彩色   
		{
			panelsize = pow((double)2, bInfo.bmBitsPixel) * sizeof(RGBQUAD);
		}
		//定義位圖信息  
		int size = hight * 9 + hight/2 + 3;//設置棋盤的大小
		BITMAPINFO*  bMapInfo = (BITMAPINFO*)LocalAlloc(LPTR, sizeof(BITMAPINFO) + panelsize);
		bMapInfo->bmiHeader.biBitCount = bInfo.bmBitsPixel;
		bMapInfo->bmiHeader.biClrImportant = 0;
		bMapInfo->bmiHeader.biCompression = 0;
		bMapInfo->bmiHeader.biHeight = size;
		bMapInfo->bmiHeader.biPlanes = bInfo.bmPlanes;
		bMapInfo->bmiHeader.biSize = sizeof(BITMAPINFO);
		bMapInfo->bmiHeader.biSizeImage = bInfo.bmHeight*bInfo.bmWidthBytes;
		bMapInfo->bmiHeader.biWidth = size;
		bMapInfo->bmiHeader.biXPelsPerMeter = 0;
		bMapInfo->bmiHeader.biYPelsPerMeter = 0;

		//獲取位圖的實際數據   
		char* pData = new char[bMapInfo->bmiHeader.biSizeImage];
		int len = GetDIBits(pDC->m_hDC, bitmap, 0, bInfo.bmHeight, pData, bMapInfo, DIB_RGB_COLORS);

		BITMAPFILEHEADER bFileHeader;
		bFileHeader.bfType = 0x4D42;
		bFileHeader.bfReserved1 = 0;
		bFileHeader.bfReserved2 = 0;
		bFileHeader.bfSize = sizeof(BITMAPFILEHEADER);
		bFileHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + panelsize;

		//向文件中寫入位圖數據   
		file.Write(&bFileHeader, sizeof(BITMAPFILEHEADER));
		file.Write(&bMapInfo->bmiHeader, sizeof(BITMAPINFOHEADER));
		file.Write(pData, bMapInfo->bmiHeader.biSizeImage + panelsize);
		file.Close();
		delete pData;
		LocalFree(bMapInfo);
	}
	bitmap.DeleteObject();
	memDC.DeleteDC();
}

測試:

這裏我們選擇合適的位置進行保存即可。

  二、CImage類保存圖片

(這個保存方式等你們慢慢發現一下吧~~~~~)

給出第三步代碼:

(這個需要自己先創建文件和寫入路徑。。。)

void CMainFrame::On32775()
{
	// TODO: 在此添加命令處理程序代碼
	
	HWND hwnd = this->GetSafeHwnd();
	HDC hDC = ::GetWindowDC(hwnd);//獲取DC      

	RECT rect;
	::GetWindowRect(hwnd, &rect);//獲取屏幕大小     
	HDC hDCMem = ::CreateCompatibleDC(hDC);//創建兼容DC      

	HBITMAP hBitMap = ::CreateCompatibleBitmap(hDC, rect.right - rect.left, rect.bottom - rect.top);//創建兼容位圖      
	HBITMAP hOldMap = (HBITMAP)::SelectObject(hDCMem, hBitMap);//將位圖選入DC,並保存返回值      

	::BitBlt(hDCMem, 0, 0, rect.right - rect.left, rect.bottom - rect.top, hDC, 0, 0, SRCCOPY);//將屏幕DC的圖象複製到內存DC中      

	CImage image;//需要#include <atlimage.h>     
	image.Attach(hBitMap);
	image.Save(_T("E://B.bmp"));//如果文件後綴爲.bmp,則保存爲爲bmp格式   
        //路徑//文件名.bmp。。。。  
	image.Detach();

	::SelectObject(hDCMem, hOldMap);//選入上次的返回值      

	//釋放      
	::DeleteObject(hBitMap);
	::DeleteDC(hDCMem);
	::DeleteDC(hDC);
}

 

柒 :後記

至此 單文檔的基礎內容我們也學習的差不多了   主要還是完成作業啊~~   

希望大家可以和我一樣,繼續加油,再接再厲,

即便孤獨、迷茫、憤怒,

也請勇敢向前,

直到星與海的盡頭,

直到夢與想的彼岸~~~~~

 

 

下面是我學習時借鑑和啓發我的一些博客:

VC學習筆記:簡單繪圖

MFC設置對話框、字體對話框、顏色對話框

暴力解決VS2017MFC窗口分割問題

MFC框架類、文檔類、視圖類相互訪問的方法

單文檔窗口繪圖保存爲bmp文件的問題

將屏幕和MFC程序界面保存成bmp格式圖片保存

有一些沒發上去,感覺太多了,給出截圖,自己體會:

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章