MFC中没有哪个CDC函数能和这些功能一一对应。
以放大镜为例,这个至少需要几十行代码实现,其中主要函数是StretchBlt,但大小、客户区大小、滚动条大小和位置都需要自己管理,包括Cursor鼠标形状也是自己管理。
这里出错了:m_pDC->CreateCompatibleDC(&dc);
这个错误是很普遍的,我的经验是:凡是用MFC的类,由于很多类都会把与特定类的句柄,如窗口就有窗口句柄,DC就有DC句柄,文件就有文件句柄。因此一旦调用了Create后,其实MFC的成员函数Create都会最终调用API的相关Create,然后由它返回一个m_hDC或其它什么m_hXX句柄。这个句柄会一直与特定类绑定在一起。因此在m_hDC还有效的情况下,是不能重复调用Create的,该规律使用于几乎所有的MFC类,原理如上所描述。
如果的确要重复Create的话,首先想办法把原句柄给销毁,然后再调用,譬如CDC有个办法就是DeleteDC,,然后用Create就安全了。
另外,就你的代码片段,我也可以选择不用成员变量DC,把m_pDC直接改到OnPaint() 里面定义一个,并且不用new,形如:CDC myDC;然后怎么重复调用哪个Create都没问题。你看CPaintDC dc(this)就是这样子的(这个代码在内部是会调用Create的变形:BeginPaint),它就永远不会出错。因为在这个dc里的m_hDC最终会因为函数执行完毕,局部类已经销毁,它的内部句柄也不再存在了!
应该是你的OnPaint里面有个 *** 作导致了,不停发送WM_ERASEBKGND消息和WM_PAINT消息,导致程序死循环。
代码贴出来看看,(主要OnPaint代码段)。
CDialog::OnPaint(); 这个执行内部向窗口发送了 WM_ERASEBKGND消息来刷新背景。
估计在你的 OnEraseBkgnd 函数处理过程中 产生了需要刷新的无效区,导致系统产生wm_paint消息,这样就产生了死循环。
onereasebkgnd函数内部不要使用 UpdateWindow MoveWindow SetWindowPos RedrawWindow等引起调用wm_paint的函数。
在MFC下自己构造一个DIB类实现上述功能还是有很多现成的代码~
下面就是一个构造的DIB类,但是仅仅提供了最基本的一些 *** 作,代码来自《Visual C++数字图像处理典型算法及实现》。// DibImageh: interface for the CDibImage class
//
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_DIBIMAGE_H__254F3D1E_BB20_40DA_AE07_E8E0219DFA8C__INCLUDED_)
#define AFX_DIBIMAGE_H__254F3D1E_BB20_40DA_AE07_E8E0219DFA8C__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
DECLARE_HANDLE(HDIB); // DIB句柄
#define PALVERSION 0x300 // DIB常量
/ DIB宏 /
// 判断是否是Win 30的DIB
#define IS_WIN30_DIB(lpbi) (((LPDWORD)(lpbi)) == sizeof(BITMAPINFOHEADER))
// 计算矩形区域的宽度
#define RECTWIDTH(lpRect) ((lpRect)->right - (lpRect)->left)
// 计算矩形区域的高度
#define RECTHEIGHT(lpRect) ((lpRect)->bottom - (lpRect)->top)
// 在计算图像大小时,采用公式:biSizeImage = biWidth' × biHeight。
// 是biWidth',而不是biWidth,这里的biWidth'必须是4的整倍数,表示
// 大于或等于biWidth的,离4最近的整倍数。WIDTHBYTES就是用来计算
// biWidth'
#define WIDTHBYTES(bits) (((bits) + 31) / 32 4)
// Dib文件头标志(字符串"BM",写DIB时用到该常数)
#define DIB_HEADER_MARKER ((WORD) ('M' << 8) | 'B')
class CDibImage
{
// Constructor and Destructor ///////////////////////////////
public:
CDibImage();
virtual ~CDibImage();
// function /////////////////////////////////////////////////
public:
BOOL PaintDIB (HDC, LPRECT, HDIB, LPRECT, CPalette pPal);
BOOL CreateDIBPalette(HDIB hDIB, CPalette cPal);
LPSTR FindDIBBits (LPSTR lpbi);
DWORD DIBWidth (LPSTR lpDIB);
DWORD DIBHeight (LPSTR lpDIB);
WORD PaletteSize (LPSTR lpbi);
WORD DIBNumColors (LPSTR lpbi);
HGLOBAL CopyHandle (HGLOBAL h);
BOOL SaveDIB (HDIB hDib, CFile& file);
HDIB ReadDIBFile(CFile& file);
};
#endif // !defined(AFX_DIBIMAGE_H__254F3D1E_BB20_40DA_AE07_E8E0219DFA8C__INCLUDED_)
///////////////////////////////////////////////////////////////////////
// DibImagecpp: implementation of the CDibImage class
// DIB(Independent Bitmap) 函数:
//
// PaintDIB() - 绘制DIB对象
// CreateDIBPalette() - 创建DIB对象调色板
// FindDIBBits() - 返回DIB图像象素起始位置
// DIBWidth() - 返回DIB宽度
// DIBHeight() - 返回DIB高度
// PaletteSize() - 返回DIB调色板大小
// DIBNumColors() - 计算DIB调色板颜色数目
// CopyHandle() - 拷贝内存块
//
// SaveDIB() - 将DIB保存到指定文件中
// ReadDIBFile() - 重指定文件中读取DIB对象
//////////////////////////////////////////////////////////////////////
#include "stdafxh"
#include "DIBDisplayh"
#include "DibImageh"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CDibImage::CDibImage()
{
}
CDibImage::~CDibImage()
{
}
//////////////////////////////////////////////////////////////////////
// function
//////////////////////////////////////////////////////////////////////
/
函数名称:
PaintDIB()
参数:
HDC hDC - 输出设备DC
LPRECT lpDCRect - 绘制矩形区域
HDIB hDIB - 指向DIB对象的指针
LPRECT lpDIBRect - 要输出的DIB区域
CPalette pPal - 指向DIB对象调色板的指针
返回值:
BOOL - 绘制成功返回TRUE,否则返回FALSE。
说明:
该函数主要用来绘制DIB对象。其中调用了StretchDIBits()或者
SetDIBitsToDevice()来绘制DIB对象。输出的设备由由参数hDC指
定;绘制的矩形区域由参数lpDCRect指定;输出DIB的区域由参数
lpDIBRect指定。
/
BOOL CDibImage::PaintDIB(HDC hDC,
LPRECT lpDCRect,
HDIB hDIB,
LPRECT lpDIBRect,
CPalette pPal)
{
LPSTR lpDIBHdr; // BITMAPINFOHEADER指针
LPSTR lpDIBBits; // DIB象素指针
BOOL bSuccess=FALSE; // 成功标志
HPALETTE hPal=NULL; // DIB调色板
HPALETTE hOldPal=NULL; // 以前的调色板
if (hDIB == NULL)
{
return FALSE;
}
lpDIBHdr = (LPSTR)::GlobalLock((HGLOBAL) hDIB);// 锁定DIB
lpDIBBits = FindDIBBits(lpDIBHdr); // 找到DIB图像象素起始位置
if (pPal != NULL) // 获取DIB调色板,并选中它
{
hPal = (HPALETTE) pPal->m_hObject;
hOldPal = ::SelectPalette(hDC, hPal, TRUE); // 选中调色板
}
::SetStretchBltMode(hDC, COLORONCOLOR); // 设置显示模式
// 判断是调用StretchDIBits()还是SetDIBitsToDevice()来绘制DIB对象
if ((RECTWIDTH(lpDCRect) == RECTWIDTH(lpDIBRect)) &&
(RECTHEIGHT(lpDCRect) == RECTHEIGHT(lpDIBRect)))
{
// 原始大小,不用拉伸。
bSuccess = ::SetDIBitsToDevice(hDC, // hDC
lpDCRect->left, // DestX
lpDCRect->top, // DestY
RECTWIDTH(lpDCRect), // nDestWidth
RECTHEIGHT(lpDCRect), // nDestHeight
lpDIBRect->left, // SrcX
(int)DIBHeight(lpDIBHdr) -
lpDIBRect->top -
RECTHEIGHT(lpDIBRect), // SrcY
0, // nStartScan
(WORD)DIBHeight(lpDIBHdr), // nNumScans
lpDIBBits, // lpBits
(LPBITMAPINFO)lpDIBHdr, // lpBitsInfo
DIB_RGB_COLORS); // wUsage
}
else
{
// 非原始大小,拉伸。
bSuccess = ::StretchDIBits(hDC, // hDC
lpDCRect->left, // DestX
lpDCRect->top, // DestY
RECTWIDTH(lpDCRect), // nDestWidth
RECTHEIGHT(lpDCRect), // nDestHeight
lpDIBRect->left, // SrcX
lpDIBRect->top, // SrcY
RECTWIDTH(lpDIBRect), // wSrcWidth
RECTHEIGHT(lpDIBRect), // wSrcHeight
lpDIBBits, // lpBits
(LPBITMAPINFO)lpDIBHdr, // lpBitsInfo
DIB_RGB_COLORS, // wUsage
SRCCOPY); // dwROP
}
::GlobalUnlock((HGLOBAL) hDIB); // 解除锁定
if (hOldPal != NULL)
{
::SelectPalette(hDC, hOldPal, TRUE); // 恢复以前的调色板
}
return bSuccess;
}
/
函数名称:
CreateDIBPalette()
参数:
HDIB hDIB - 指向DIB对象的指针
CPalette pPal - 指向DIB对象调色板的指针
返回值:
BOOL - 创建成功返回TRUE,否则返回FALSE。
说明:
该函数按照DIB创建一个逻辑调色板,从DIB中读取颜色表并存到调色板中,
最后按照该逻辑调色板创建一个新的调色板,并返回该调色板的句柄。这样
可以用最好的颜色来显示DIB图像。
/
BOOL CDibImage::CreateDIBPalette(HDIB hDIB, CPalette pPal)
{
LPLOGPALETTE lpPal; // 指向逻辑调色板的指针
HANDLE hLogPal; // 逻辑调色板的句柄
HPALETTE hPal = NULL; // 调色板的句柄
int i; // 循环变量
WORD wNumColors; // 颜色表中的颜色数目
LPSTR lpbi; // 指向DIB的指针
LPBITMAPINFO lpbmi; // 指向BITMAPINFO结构的指针(Win30)
LPBITMAPCOREINFO lpbmc; // 指向BITMAPCOREINFO结构的指针
BOOL bWinStyleDIB; // 表明是否是Win30 DIB的标记
BOOL bResult = FALSE; // 创建结果
if (hDIB == NULL)
{
return FALSE;
}
lpbi = (LPSTR) ::GlobalLock((HGLOBAL) hDIB); // 锁定DIB
lpbmi = (LPBITMAPINFO)lpbi; // 获取指向BITMAPINFO结构的指针(Win30)
lpbmc = (LPBITMAPCOREINFO)lpbi; // 获取指向BITMAPCOREINFO结构的指针
wNumColors = DIBNumColors(lpbi);// 获取DIB中颜色表中的颜色数目
if (wNumColors != 0)
{
// 分配为逻辑调色板内存
hLogPal = ::GlobalAlloc(GHND, sizeof(LOGPALETTE)
+ sizeof(PALETTEENTRY)
wNumColors);
// 如果内存不足,退出
if (hLogPal == 0)
{
::GlobalUnlock((HGLOBAL) hDIB); // 解除锁定
return FALSE;
}
lpPal = (LPLOGPALETTE) ::GlobalLock((HGLOBAL) hLogPal);
lpPal->palVersion = PALVERSION; // 设置版本号
lpPal->palNumEntries = (WORD)wNumColors;// 设置颜色数目
bWinStyleDIB = IS_WIN30_DIB(lpbi); // 判断是否是WIN30的DIB
// 读取调色板
for (i = 0; i < (int)wNumColors; i++)
{
if (bWinStyleDIB)
{
// 读取红色绿色蓝色分量
lpPal->palPalEntry[i]peRed = lpbmi->bmiColors[i]rgbRed;
lpPal->palPalEntry[i]peGreen = lpbmi->bmiColors[i]rgbGreen;
lpPal->palPalEntry[i]peBlue = lpbmi->bmiColors[i]rgbBlue;
// 保留位
lpPal->palPalEntry[i]peFlags = 0;
}
else
{
// 读取红色绿色蓝色分量
lpPal->palPalEntry[i]peRed = lpbmc->bmciColors[i]rgbtRed;
lpPal->palPalEntry[i]peGreen = lpbmc->bmciColors[i]rgbtGreen;
lpPal->palPalEntry[i]peBlue = lpbmc->bmciColors[i]rgbtBlue;
// 保留位
lpPal->palPalEntry[i]peFlags = 0;
}
}
bResult = pPal->CreatePalette(lpPal);// 按照逻辑调色板创建调色板,并返回指针
::GlobalUnlock((HGLOBAL) hLogPal); // 解除锁定
::GlobalFree((HGLOBAL) hLogPal); // 释放逻辑调色板
}
::GlobalUnlock((HGLOBAL) hDIB); // 解除锁定
return bResult;
}
/
函数名称:
FindDIBBits()
参数:
LPSTR lpbi - 指向DIB对象的指针
返回值:
LPSTR - 指向DIB图像象素起始位置
说明:
该函数计算DIB中图像象素的起始位置,并返回指向它的指针。
/
LPSTR CDibImage::FindDIBBits(LPSTR lpbi)
{
return (lpbi + (LPDWORD)lpbi + PaletteSize(lpbi));
}
/
函数名称:
DIBWidth()
参数:
LPSTR lpbi - 指向DIB对象的指针
返回值:
DWORD - DIB中图像的宽度
说明:
该函数返回DIB中图像的宽度。对于Windows 30 DIB,返回BITMAPINFOHEADER
中的biWidth值;对于其它返回BITMAPCOREHEADER中的bcWidth值。
/
DWORD CDibImage::DIBWidth(LPSTR lpDIB)
{
LPBITMAPINFOHEADER lpbmi; // 指向BITMAPINFO结构的指针(Win30)
LPBITMAPCOREHEADER lpbmc; // 指向BITMAPCOREINFO结构的指针
lpbmi = (LPBITMAPINFOHEADER)lpDIB;
lpbmc = (LPBITMAPCOREHEADER)lpDIB;
// 返回DIB中图像的宽度
if (IS_WIN30_DIB(lpDIB))
{
return lpbmi->biWidth; // 对于Windows 30 DIB,返回lpbmi->biWidth
}
else
{
return (DWORD)lpbmc->bcWidth; // 对于其它格式的DIB,返回lpbmc->bcWidth
}
}
/
函数名称:
DIBHeight()
参数:
LPSTR lpDIB - 指向DIB对象的指针
返回值:
DWORD - DIB中图像的高度
说明:
该函数返回DIB中图像的高度。对于Windows 30 DIB,返回BITMAPINFOHEADER
中的biHeight值;对于其它返回BITMAPCOREHEADER中的bcHeight值。
/
DWORD CDibImage::DIBHeight(LPSTR lpDIB)
{
LPBITMAPINFOHEADER lpbmi; // 指向BITMAPINFO结构的指针(Win30)
LPBITMAPCOREHEADER lpbmc; // 指向BITMAPCOREINFO结构的指针
lpbmi = (LPBITMAPINFOHEADER)lpDIB;
lpbmc = (LPBITMAPCOREHEADER)lpDIB;
// 返回DIB中图像的宽度
if (IS_WIN30_DIB(lpDIB))
{
return lpbmi->biHeight; // 对于Windows 30 DIB,返回lpbmi->biHeight
}
else
{
return (DWORD)lpbmc->bcHeight; // 对于其它格式的DIB,返回lpbmc->bcHeight
}
}
/
函数名称:
PaletteSize()
参数:
LPSTR lpbi - 指向DIB对象的指针
返回值:
WORD - DIB中调色板的大小
说明:
该函数返回DIB中调色板的大小。对于Windows 30 DIB,返回颜色数目×
RGBQUAD的大小;对于其它返回颜色数目×RGBTRIPLE的大小。
/
WORD CDibImage::PaletteSize(LPSTR lpbi)
{
// 计算DIB中调色板的大小
if (IS_WIN30_DIB (lpbi))
{
//返回颜色数目×RGBQUAD的大小
return (WORD)(DIBNumColors(lpbi) sizeof(RGBQUAD));
}
else
{
//返回颜色数目×RGBTRIPLE的大小
return (WORD)(DIBNumColors(lpbi) sizeof(RGBTRIPLE));
}
}
/
函数名称:
DIBNumColors()
参数:
LPSTR lpbi - 指向DIB对象的指针
返回值:
WORD - 返回调色板中颜色的种数
说明:
该函数返回DIB中调色板的颜色的种数。对于单色位图,返回2,
对于16色位图,返回16,对于256色位图,返回256;对于真彩色
位图(24位),没有调色板,返回0。
/
WORD CDibImage::DIBNumColors(LPSTR lpbi)
{
WORD wBitCount;
// 对于Windows的DIB, 实际颜色的数目可以比象素的位数要少。
// 对于这种情况,则返回一个近似的数值。
// 判断是否是WIN30 DIB
if (IS_WIN30_DIB(lpbi))
{
DWORD dwClrUsed;
dwClrUsed = ((LPBITMAPINFOHEADER)lpbi)->biClrUsed; // 读取dwClrUsed值
if (dwClrUsed != 0)
{
// 如果dwClrUsed(实际用到的颜色数)不为0,直接返回该值
return (WORD)dwClrUsed;
}
}
// 读取象素的位数
if (IS_WIN30_DIB(lpbi))
{
wBitCount = ((LPBITMAPINFOHEADER)lpbi)->biBitCount; // 读取biBitCount值
}
else
{
wBitCount = ((LPBITMAPCOREHEADER)lpbi)->bcBitCount; // 读取biBitCount值
}
// 按照象素的位数计算颜色数目
switch (wBitCount)
{
case 1:
return 2;
break;
case 4:
return 16;
break;
case 8:
return 256;
break;
default:
return 0;
break;
}
}
/
函数名称:
CopyHandle()
参数:
HGLOBAL h - 要复制的内存区域
返回值:
HGLOBAL - 复制后的新内存区域
说明:
该函数复制指定的内存区域。返回复制后的新内存区域,出错时返回0。
/
HGLOBAL CDibImage::CopyHandle (HGLOBAL h)
{
if (h == NULL)
{
return NULL;
}
DWORD dwLen = ::GlobalSize((HGLOBAL) h); // 获取指定内存区域大小
HGLOBAL hCopy = ::GlobalAlloc(GHND, dwLen); // 分配新内存空间
if (hCopy != NULL) // 判断分配是否成功
{
void lpCopy = ::GlobalLock((HGLOBAL) hCopy);
void lp = ::GlobalLock((HGLOBAL) h);
memcpy(lpCopy, lp, dwLen);
::GlobalUnlock(hCopy);
::GlobalUnlock(h);
}
return hCopy;
}
/
函数名称:
SaveDIB()
参数:
HDIB hDib - 要保存的DIB
CFile& file - 保存文件CFile
返回值:
BOOL - 成功返回TRUE,否则返回FALSE或者CFileException
说明:
该函数将指定的DIB对象保存到指定的CFile中。该CFile由调用程序打开和关闭。
/
BOOL CDibImage::SaveDIB(HDIB hDib, CFile& file)
{
BITMAPFILEHEADER bmfHdr; // Bitmap文件头
LPBITMAPINFOHEADER lpBI; // 指向BITMAPINFOHEADER的指针
DWORD dwDIBSize; // DIB大小
if (hDib == NULL)
{
return FALSE;
}
// 读取BITMAPINFO结构,并锁定
lpBI = (LPBITMAPINFOHEADER) ::GlobalLock((HGLOBAL) hDib);
if (lpBI == NULL)
{
return FALSE;
}
// 判断是否是WIN30 DIB
if (!IS_WIN30_DIB(lpBI))
{
// 不支持其它类型的DIB保存
::GlobalUnlock((HGLOBAL) hDib);
return FALSE;
}
////////////////////////////////////////////////////////////////////////
// 填充文件头///////////////////////////////////////////////////////////
bmfHdrbfType = DIB_HEADER_MARKER; // 文件类型"BM"
// 计算DIB大小时,最简单的方法是调用GlobalSize()函数。但是全局内存大小并
// 不是DIB真正的大小,它总是多几个字节。这样就需要计算一下DIB的真实大小。
// 文件头大小+颜色表大小
// (BITMAPINFOHEADER和BITMAPCOREHEADER结构的第一个DWORD都是该结构的大小)
dwDIBSize = (LPDWORD)lpBI + PaletteSize((LPSTR)lpBI);
// 计算图像大小
if ((lpBI->biCompression == BI_RLE8) || (lpBI->biCompression == BI_RLE4))
{
// 对于RLE位图,没法计算大小,只能信任biSizeImage内的值
dwDIBSize += lpBI->biSizeImage;
}
else
{
DWORD dwBmBitsSize; // 象素的大小
dwBmBitsSize = WIDTHBYTES((lpBI->biWidth)((DWORD)lpBI->biBitCount))
lpBI->biHeight; // 大小为Width Height
dwDIBSize += dwBmBitsSize; // 计算出DIB真正的大小
// 更新biSizeImage(很多BMP文件头中biSizeImage的值是错误的)
lpBI->biSizeImage = dwBmBitsSize;
}
// 计算文件大小:DIB大小+BITMAPFILEHEADER结构大小
bmfHdrbfSize = dwDIBSize + sizeof(BITMAPFILEHEADER);
// 两个保留字
bmfHdrbfReserved1 = 0;
bmfHdrbfReserved2 = 0;
// 计算偏移量bfOffBits,它的大小为Bitmap文件头大小+DIB头大小+颜色表大小
bmfHdrbfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + lpBI->biSize
+ PaletteSize((LPSTR)lpBI);
/////////////////////////////////////////////////////////////////////////
// 尝试写文件////////////////////////////////////////////////////////////
TRY
{
fileWrite((LPSTR)&bmfHdr, sizeof(BITMAPFILEHEADER)); // 写文件头
fileWriteHuge(lpBI, dwDIBSize); // 写DIB头和象素
}
CATCH (CFileException, e)
{
::GlobalUnlock((HGLOBAL) hDib);
THROW_LAST();
}
END_CATCH
::GlobalUnlock((HGLOBAL) hDib);
return TRUE;
}
/
函数名称:
ReadDIBFile()
参数:
CFile& file - 要读取得文件文件CFile
返回值:
HDIB - 成功返回DIB的句柄,否则返回NULL。
说明:
该函数将指定的文件中的DIB对象读到指定的内存区域中。除BITMAPFILEHEADER
外的内容都将被读入内存。
/
HDIB CDibImage::ReadDIBFile(CFile& file)
{
BITMAPFILEHEADER bmfHeader;
HDIB hDIB;
LPSTR pDIB;
DWORD dwBitsSize;
dwBitsSize = fileGetLength(); // 获取DIB(文件)长度(字节)
// 尝试读取DIB文件头
if (fileRead((LPSTR)&bmfHeader, sizeof(bmfHeader)) != sizeof(bmfHeader))
{
return NULL;
}
// 判断是否是DIB对象,检查头两个字节是否是"BM"
if (bmfHeaderbfType != DIB_HEADER_MARKER)
{
return NULL;
}
// 为DIB分配内存
hDIB = (HDIB) ::GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, dwBitsSize);
if (hDIB == 0)
{
return NULL;
}
pDIB = (LPSTR) ::GlobalLock((HGLOBAL) hDIB);
if (fileReadHuge(pDIB, dwBitsSize - sizeof(BITMAPFILEHEADER)) !=
dwBitsSize - sizeof(BITMAPFILEHEADER) ) // 读象素
{
::GlobalUnlock((HGLOBAL) hDIB);
::GlobalFree((HGLOBAL) hDIB);
return NULL;
}
::GlobalUnlock((HGLOBAL) hDIB);
return hDIB;
}
Private Type POINTAPI
x As Long
y As Long
End Type
Private Const SRCCOPY = &HCC0020
Private Declare Function PlgBlt Lib "gdi32" (ByVal hdcDest As Long, lpPoint As POINTAPI, ByVal hdcSrc As Long, ByVal nXSrc As Long, ByVal nYSrc As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hbmMask As Long, ByVal xMask As Long, ByVal yMask As Long) As Long
Private Declare Function StretchBlt Lib "gdi32" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, ByVal xSrc As Long, ByVal ySrc As Long, ByVal nSrcWidth As Long, ByVal nSrcHeight As Long, ByVal dwRop As Long) As Long
Private Sub Command1_Click() '90度旋转
Dim p(3) As POINTAPI
px = Picture1ScaleWidth
py = Picture1ScaleHeight
p(0)x = py
p(1)x = py
p(1)y = px
'这是顺时针,如果要逆时针,上面三行改为:
'p(0)y = px
'p(2)x = py
'p(2)y = px
Picture2Cls
PlgBlt Picture2hdc, p(0), Picture1hdc, 0, 0, px, py, 0, 0, 0
End Sub
Private Sub Command2_Click() '180度倒立
Picture2Cls
px = Picture1ScaleWidth
py = Picture1ScaleHeight
StretchBlt Picture2hdc, 0, py, px, -py, Picture1hdc, 0, 0, px, py, SRCCOPY
'这是倒过来,下面这行是镜像
'StretchBlt Picture2hdc, px, 0, -px, py, Picture1hdc, 0, 0, px, py, SRCCOPY
End Sub
Private Sub Form_Load()
Picture1Picture = LoadPicture("c:\songhuiqiao1jpg") '这里写你自己的路径
Picture1ScaleMode = 3
Picture2ScaleMode = 3
End Sub
以上就是关于windows自带画图程序工具栏裁剪,放大镜,选定,用颜色填充要用MFC中CDC类的哪些函数来实现全部的内容,包括:windows自带画图程序工具栏裁剪,放大镜,选定,用颜色填充要用MFC中CDC类的哪些函数来实现、用VC编一个Win32应用程序来显示位图 自己调试比较菜、我的程序怎么会不停地发出WM_ERASEBKGND消息等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)