day4 – CAD1 双缓冲绘图

这篇博客探讨了Windows GDI的使用,包括如何处理WM_PAINT消息、不同类型的设备上下文以及双缓冲绘图技术。通过示例展示了如何利用双缓冲实现平滑的屏幕截图,并介绍了CImage类在截图过程中的应用。此外,还提供了获取临时文件名的辅助函数。
摘要由CSDN通过智能技术生成

文档的使用, GDI(graphics device interface), 对话框的使用

2.双缓冲

1) 什么时候绘制 WM_PAINT

WM_PAINT –> OnPaint –> OnDraw

2) 在哪里绘制 DC

BeginPaint/EndPaint CPaintDC 绘制区域不超过无效区

GetDC/ReleaseDC CClientDC 绘制区域为整个客户区

GetWindowDC/ReleaseDC CWindowDC 绘制区域为整个窗口

CreateCompatibleDC CDC 内存DC,绘制区域为内存

实例:屏幕截图

BitBlt – 将一个DC中的图片拷贝到另一个DC中

光栅操作

CDC dcSreen;
  dcSreen.CreateDC("DISPLAY", NULL, NULL, NULL);
  CRect rcClient;
  GetClientRect(&rcClient);

3) 如何绘制 – 双缓冲绘图法

响应消息:lbuttondown mousemove lbuttonup

绘制直线的api:MoveTo LineTo

鼠标移出窗口外仍然接受鼠标消息:SetCapture

不再接受窗口外的鼠标消息:ReleaseCapture

双缓冲的步骤:

  • \1. 创建内存(兼容)DC CreateCompatibleDC(pDC)
  • 2.创建兼容位图 CreateCompatibleBitmap(pDC, rcClient.Width(), rcClient.Height())
  • 3.将兼容位图选入内存DC SelectObject(&bmp)
  • 4.在内存DC中绘图
  • 5.将内存DC中的图片拷贝到窗口 pDC->BitBlt(0, 0, rcClient.Width(), rcClient.Height(), &dcMem, 0, 0, SRCCOPY)

关于Cimage的截图,微软官方写的:

struct CaptureData
{
BOOL    bCaptureFullScreen;
char szCapturePath[MAX_PATH]; // no unicode path support
char szCaptureFilename[MAX_PATH];
};
 
void WINAPI CaptureScreen(CaptureData* lpData)
{
ASSERT(lpData);
if (!lpData)
return;
 
 
AFX_MANAGE_STATE(AfxGetStaticModuleState());
 
 
BOOL bStat;
CImage image;
CWnd *pWnd;
CRect rect;
if (lpData->bCaptureFullScreen) {
pWnd = CWnd::GetDesktopWindow();
}
else {
pWnd = CWnd::GetActiveWindow();
}
ASSERT(pWnd);
if (pWnd == NULL)
return;
 
 
CWindowDC  winDC(pWnd);
pWnd->GetWindowRect(rect);
int nBPP = winDC.GetDeviceCaps(BITSPIXEL) * winDC.GetDeviceCaps(PLANES);
if (nBPP < 24)
nBPP = 24;
bStat = image.Create(rect.Width(), rect.Height(), nBPP); //创建图像
ASSERT(bStat);
if (!bStat)
return;
CImageDC imageDC(image);  
        //将图像绘制到imageDC 中
::BitBlt(imageDC, 0, 0, rect.Width(), rect.Height(), winDC, 0, 0, SRCCOPY);
CString strTempName = GetTempName(CString(lpData->szCapturePath)); //保存为指定格式和路径中
HRESULT hr = image.Save(strTempName);
if (FAILED(hr)) {
TRACE("Couldn't Save File: %s, %x\n", (LPCTSTR)strTempName, hr);
return;
}
strncpy_s(lpData->szCaptureFilename, MAX_PATH, CT2A(::PathFindFileName(strTempName)), _TRUNCATE);
}
//获取文件名和路径
static CString GetTempName(CString strPath)
{
const int nMin = 0;
const int nMax = 999;
const CString strBase(_T("ScreenCap"));
static int nLastKnown = nMin;
 
// count up sequentially to make sure we take the next available
// slot
if (strPath.Right(1) != "\\")
strPath += '\\';
 
 
bool bFound = false;
CString strPathName;
while (!bFound) {
if (nLastKnown > nMax)
break;
strPathName = strPath + strBase;
strPathName.AppendFormat(_T("%03.3d.png"), nLastKnown++);
HANDLE hFile = ::CreateFile(strPathName, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile != INVALID_HANDLE_VALUE) {
::CloseHandle(hFile);
bFound = TRUE;
}
}
if (!bFound)
strPathName.Empty();
return(strPathName);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值