我的程序是定时抓取活动窗体的,但是有一个很奇怪的问题!
程序开始能抓所有的窗体,但是运行一会儿后却只能抓比较小的窗体(如任务管理器),我调试了一下,发现抓大窗体时只有一字节。这是什么原因呢?
程序开始能抓所有的窗体,但是运行一会儿后却只能抓比较小的窗体(如任务管理器),我调试了一下,发现抓大窗体时只有一字节。这是什么原因呢?
解决方案 »
- CBitmap 显示图片
- 图像生成问题
- 全局外部函数里面怎么调用view和doc里面的变量和函数?
- 关于反算Bezier曲线的控制点的问题。
- 求助:请问谁有《Visual C++ 数字图像与图形处理》的光盘上源码?(电子工业出版社 )向世明编
- 关于Release和Debug的差别?希望高手指教!
- 如何实现打印预览的自由放大?
- 怎样实现非对话框应用程序最小化成为托盘图标,请先告诉我,有没有这个可能?
- 求救 VC++的中文问题(高分求解)
- 求助这种图形用什么方法二值化比较好
- 完成端口需要投递多个WSASend、WSARecv?
- 求助!在Dll中使用了一个类库,然后封装Dll,在Application中使用Dll同时也要使用该类库,但系统出现link 2001错误。头文件已经被include
CMon *mon;
mon=new CMon;
//////////////////////////////////////////////////////////
HWND hwnd = ::GetForegroundWindow();//获取当前窗体
//校验窗体是否有效
if(hwnd==NULL)
{
return TRUE;
}
if(IsWindow(hwnd)==FALSE)
{
return TRUE;
}
//获取窗口的DC和窗口的矩形信息
HDC hsrc = ::GetWindowDC(hwnd);
HDC hmemdc = ::CreateCompatibleDC(hsrc);
RECT rc;
::GetWindowRect(hwnd,&rc);
HDC hScrDC, hMemDC;
// 屏幕和内存设备描述表
HBITMAP hBitmap;
// 位图句柄
int nX, nY, nX2, nY2;
// 选定区域坐标
int nWidth, nHeight;
// 位图宽度和高度
int xScrn, yScrn;
// 屏幕分辨率 // 确保选定区域不为空矩形
if (IsRectEmpty(&rc))
return NULL;
//为屏幕创建设备描述表
hScrDC = CreateDC("DISPLAY", NULL, NULL, NULL);
//为屏幕设备描述表创建兼容的内存设备描述表
hMemDC = CreateCompatibleDC(hScrDC);
// 获得选定区域坐标
nX = rc.left;
nY = rc.top;
nX2 = rc.right;
nY2 = rc.bottom;
// 获得屏幕分辨率
xScrn = GetDeviceCaps(hScrDC, HORZRES);
yScrn = GetDeviceCaps(hScrDC, VERTRES);
//确保选定区域是可见的
if (nX<0)
nX = 0;
if (nY < 0)
nY = 0;
if (nX2 > xScrn)
nX2 = xScrn;
if (nY2 > yScrn)
nY2 = yScrn;
nWidth = nX2 - nX;
nHeight = nY2 - nY;
// 创建一个与屏幕设备描述表兼容的位图
hBitmap = CreateCompatibleBitmap
(hScrDC, nWidth, nHeight);
// 把新位图选到内存设备描述表中
HGDIOBJ hOldBitmap = SelectObject(hMemDC, hBitmap);
// 把屏幕设备描述表拷贝到内存设备描述表中
BitBlt(hMemDC, 0, 0, nWidth, nHeight,
hScrDC, nX, nY, SRCCOPY);
//得到屏幕位图的句柄
SelectObject(hMemDC, hOldBitmap);
//清除
DeleteDC(hScrDC);
DeleteDC(hMemDC);
//////////////////////////////////
//获取位图信息
////////////////////////////
HDC hDC; //设备描述表
int iBits; //当前显示分辨率下每个像素所占字节数
WORD wBitCount; //位图中每个像素所占字节数
DWORD dwPaletteSize=0, //定义调色板大小, 位图中像素字节大小 ,位图文件大小 , 写入文件字节数
dwBmBitsSize,
dwDIBSize;
BITMAP Bitmap;
BITMAPFILEHEADER bmfHdr; //位图属性结构
BITMAPINFOHEADER bi; //位图文件头结构
LPBITMAPINFOHEADER lpbi; //位图信息头结构
HANDLE hDib, hPal,hOldPal=NULL; //指向位图信息头结构,定义文件,分配内存句柄,调色板句柄
//计算位图文件每个像素所占字节数
hDC = CreateDC("DISPLAY",NULL,NULL,NULL);
iBits = GetDeviceCaps(hDC, BITSPIXEL) *
GetDeviceCaps(hDC, PLANES);
DeleteDC(hDC);
if (iBits <= 1)
wBitCount = 1;
else if (iBits <= 4)
wBitCount = 4;
else if (iBits <= 8)
wBitCount = 8;
else if (iBits <= 24)
wBitCount = 24;
//计算调色板大小
if (wBitCount <= 8)
dwPaletteSize = (1 << wBitCount) *sizeof(RGBQUAD);
//设置位图信息头结构
GetObject(hBitmap, sizeof(BITMAP), (LPSTR)&Bitmap);
bi.biSize = sizeof(BITMAPINFOHEADER);
bi.biWidth = Bitmap.bmWidth;
bi.biHeight = Bitmap.bmHeight;
bi.biPlanes = 1;
bi.biBitCount = wBitCount;
bi.biCompression = BI_RGB;
bi.biSizeImage = 0;
bi.biXPelsPerMeter = 0;
bi.biYPelsPerMeter = 0;
bi.biClrUsed = 0;
bi.biClrImportant = 0; dwBmBitsSize = ((Bitmap.bmWidth *
wBitCount+31)/32)* 4
*Bitmap.bmHeight ; //为位图内容分配内存
hDib = GlobalAlloc(GHND,dwBmBitsSize+
dwPaletteSize+sizeof(BITMAPINFOHEADER));
lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDib);
*lpbi = bi; // 处理调色板
hPal = GetStockObject(DEFAULT_PALETTE);
if(hPal)
{
hDC = ::GetDC(NULL);
hOldPal = SelectPalette(hDC, (HPALETTE)hPal, FALSE);
RealizePalette(hDC);
} // 获取该调色板下新的像素值
int nRet=GetDIBits(hDC, hBitmap, 0, (UINT) Bitmap.bmHeight,
(LPSTR)lpbi + sizeof(BITMAPINFOHEADER)+dwPaletteSize,
(LPBITMAPINFO)lpbi, DIB_RGB_COLORS);
//恢复调色板
if (hOldPal)
{
SelectPalette(hDC, (HPALETTE)hOldPal, TRUE);
RealizePalette(hDC);
::ReleaseDC(NULL, hDC);
}
// 设置位图文件头
bmfHdr.bfType = 0x4D42; // "BM"
dwDIBSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + dwPaletteSize + dwBmBitsSize;
bmfHdr.bfSize = dwDIBSize;
bmfHdr.bfReserved1 = 0;
bmfHdr.bfReserved2 = 0;
bmfHdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER)
+ (DWORD)sizeof(BITMAPINFOHEADER)
+ dwPaletteSize; int nLen,nLen1,nLen2; nLen=sizeof(BITMAPFILEHEADER);
nLen1=sizeof(BITMAPINFOHEADER);
nLen2=nLen+dwDIBSize;
char *buf=new char[nLen2];
//缓冲区分配完毕
//开始合并缓冲区
memmove(buf,&bmfHdr,sizeof(BITMAPFILEHEADER));
// memmove(buf+nLen,&bi,sizeof(BITMAPINFOHEADER));
memmove(buf+nLen,lpbi,dwDIBSize); CFile ff;
ff.Open("cap.bmp",CFile::modeCreate|CFile::modeWrite,NULL);
ff.Write(buf,nLen2);
ff.Close();
//开始转换图片类型
CMemFile mfi,mfo;
mfi.Attach((unsigned char*)buf,nLen2,0);
if(!mon->MBmpToMImage(mfi,mfo,"encode/gif"))
{
delete mon;
GlobalUnlock(hDib);
GlobalFree(hDib);
GlobalFree(lpbi);
delete[] buf;
return TRUE;
}
//其余的省略
if(!mon->MBmpToMImage(mfi,mfo,"encode/gif"))
{
delete mon;
GlobalUnlock(hDib);
GlobalFree(hDib);
GlobalFree(lpbi);
delete[] buf;
return TRUE;
}
mon->MBmpToMImage(mfi,mfo,"encode/gif")函数什么意思?返回值是什么?是不是转换类型成功返回TRUE,那么返回TRUE的话,你前面加个!,if中的判断条件为假,那肯定就不会执行到下面释放内存的步骤。即你这段语句的意思是,转换不成功则执行下面的语句,转换成功反而执行不了了。不太了解你的CMon类,以及它的成员函数MBmpToMImage, 不知道我说的对不对,你把!去掉试试
函数成功了返回TRUE否则返回FALSEif(!mon->MBmpToMImage(mfi,mfo,"encode/gif"))
{
delete mon;
GlobalUnlock(hDib);
GlobalFree(hDib);
GlobalFree(lpbi);
delete[] buf;
return TRUE;
}这句的意思是如果转换图片不成功,清除缓冲区,然后返回TRUE,用来区别数据库错误,因为数据库错误返回FALSE
///////////////////////////////////////////////////////////////////////
CString sqlstr;
sqlstr="SELECT top 0 * FROM ScrLog ORDER BY IDNO"; if(!m_db->State)
{
GlobalUnlock(hDib);
GlobalFree(hDib);
lpbi=NULL;
delete[] buf;
return FALSE;
}
try
{
HRESULT hr=m_set.CreateInstance(__uuidof(Recordset));
if(SUCCEEDED(hr))
{
m_set->Open(_bstr_t(sqlstr),_variant_t((IDispatch*)m_db,true),adOpenStatic,adLockOptimistic,adCmdText);
}
}catch (_com_error e)
{
CString error="保存GIF图片时出错,错误代码:";
error+=e.ErrorMessage();
error+="对该错误的说明:";
_bstr_t err=e.Description();
error+=(LPCTSTR)err;
SaveLog(error.GetBuffer(0));
#ifdef _DEBUG_
AfxMessageBox(err);
#endif
GlobalUnlock(hDib);
GlobalFree(hDib);
lpbi=NULL;
delete[] buf;
return FALSE;
}catch (...)
{
#ifdef _DEBUG
AfxMessageBox("Ado Error");
#endif
return FALSE;
} int nLength=mfo.GetLength();
char *buf2=new char[nLength];
memmove(buf2,mfo.Detach(),nLength); char *pbuf=buf2; try
{
m_set->AddNew();
m_set->PutCollect("KeyLogID",long(KeyId));
m_set->PutCollect("Code2",_variant_t(m_mac));
}catch(_com_error e)
{
CString error="保存GIF图片时出错,错误代码:";
error+=e.ErrorMessage();
error+="对该错误的说明:";
_bstr_t err=e.Description();
error+=(LPCTSTR)err;
SaveLog(error.GetBuffer(0));
return FALSE;
GlobalUnlock(hDib);
GlobalFree(hDib);
pbuf=NULL;
lpbi=NULL;
delete[] buf;
} VARIANT varBLOB;
SAFEARRAY *psa;
SAFEARRAYBOUND rgsabound[1];
if(buf2)
{
rgsabound[0].lLbound = 0;
rgsabound[0].cElements = nLength;
psa = SafeArrayCreate(VT_UI1, 1, rgsabound);///创建SAFEARRAY对象
for (long i = 0; i < (long)nLength; i++)
SafeArrayPutElement (psa, &i, buf2++); ///将pBuf指向的二进制数据保存到SAFEARRAY对象psa中
varBLOB.vt = VT_ARRAY | VT_UI1; ///将varBLOB的类型设置为BYTE类型的数组
varBLOB.parray = psa; ///为varBLOB变量赋值
try
{
m_set->GetFields()->GetItem("PicImage")->AppendChunk(varBLOB);///加入BLOB类型的数据
}catch (_com_error e)
{
CString error="执行SQL命令出错,错误代码:";
error+=e.ErrorMessage();
error+="对该错误的说明:";
_bstr_t err=e.Description();
error+=(LPCTSTR)err;
SaveLog(error.GetBuffer(0));
GlobalUnlock(hDib);
GlobalFree(hDib);
pbuf=NULL;
lpbi=NULL;
delete[] buf;
delete[] buf2;
return FALSE;
}
catch (...)
{
GlobalUnlock(hDib);
GlobalFree(hDib);
pbuf=NULL;
lpbi=NULL;
delete[] buf;
delete[] buf2;
return FALSE;
} }
try
{
m_set->Update();
}
catch(_com_error e)
{
CString error="更新数据库时出错,错误代码:";
error+=e.ErrorMessage();
error+="对该错误的说明:";
_bstr_t err=e.Description();
error+=(LPCTSTR)err;
SaveLog(error.GetBuffer(0));
GlobalUnlock(hDib);
GlobalFree(hDib);
lpbi=NULL;
pbuf=NULL;
delete[] buf;
delete[] buf2;
return FALSE;
}
GlobalUnlock(hDib);
GlobalFree(hDib);
lpbi=NULL;
pbuf=NULL;
delete[] buf;
delete[] buf2;
SaveLog("保存图片成功");
return TRUE;
}
这是上面贴剩的代码,全贴出来不允许说帖子太长了
你在最开始的时候new了:
CMon *mon;
mon=new CMon;
所以应该delete