HBITMAP CopyScreenToBitmap()
{
CGSTATUS status = CG_OK;
status = CGCapture(pDlg->m_hcg, FALSE);
CG_VERIFY(status);
//status = CGCaptureShot(pDlg->m_hcg);
//CG_VERIFY(status);

//lpRect 代表选定区域  HDC hScrDC, hMemDC;  
// 屏幕和内存设备描述表 
HBITMAP hBitmap, hOldBitmap;  
// 位图句柄 
int nX, nY, nX2, nY2;  
// 选定区域坐标 
int nWidth, nHeight;  
// 位图宽度和高度 
//为屏幕创建设备描述表 
//hScrDC =(HDC) pDlg->GetDC(); 
hScrDC = CreateDC("DISPLAY",NULL,NULL,NULL); //为屏幕设备描述表创建兼容的内存设备描述表 
hMemDC = CreateCompatibleDC(hScrDC); 
CRect rect;
pDlg->GetWindowRect(&rect); // 获得选定区域坐标 
nX = rect.left; 
nY = rect.top; 
nX2 = rect.right; 
nY2 = rect.bottom; 

nWidth = nX2 - nX; 
nHeight = nY2 - nY; 
// 创建一个与屏幕设备描述表兼容的位图 
hBitmap = CreateCompatibleBitmap (hScrDC, nWidth, nHeight); 
// 把新位图选到内存设备描述表中 
hOldBitmap = (HBITMAP)SelectObject(hMemDC,hBitmap); 
// 把屏幕设备描述表拷贝到内存设备描述表中 
BitBlt(hMemDC, 0, 0, nWidth, nHeight, 
hScrDC, nX, nY, SRCCOPY); 
//得到屏幕位图的句柄 
hBitmap = (HBITMAP)SelectObject(hMemDC,hOldBitmap); 
//清除  
DeleteDC(hScrDC); 
DeleteDC(hMemDC); 
// 返回位图句柄 
return hBitmap; }
////////
BOOL SaveToBmp(CString strPath)
{

HBITMAP hBitmap = CopyScreenToBitmap();
HDC hDC;  
int iBits;  
WORD wBitCount;  
DWORD dwPaletteSize=0,  dwBmBitsSize, dwDIBSize, dwWritten; 
BITMAP Bitmap;  
BITMAPFILEHEADER bmfHdr;  
BITMAPINFOHEADER bi;  
LPBITMAPINFOHEADER lpbi;  
HANDLE fh, 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_BITFIELDS:每个象素的比特由指定的掩码决定。
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 = (HANDLE)SelectPalette(hDC, (HPALETTE)hPal, FALSE); 
RealizePalette(hDC); 

GetDIBits(hDC, hBitmap, 0, (UINT) Bitmap.bmHeight, 
(LPSTR)lpbi + sizeof(BITMAPINFOHEADER) 
+dwPaletteSize, 
(BITMAPINFO *) 
lpbi, DIB_RGB_COLORS); 
if (hOldPal) 

SelectPalette(hDC, (HPALETTE)hOldPal, TRUE); 
RealizePalette(hDC); 
::ReleaseDC(NULL, hDC); 

fh = CreateFile(strPath, GENERIC_WRITE,  
0, NULL, CREATE_ALWAYS, 
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL); 
if (fh == INVALID_HANDLE_VALUE) 
return FALSE; 
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; 
WriteFile(fh, (LPSTR)&bmfHdr, sizeof 
(BITMAPFILEHEADER), &dwWritten, NULL); 
WriteFile(fh, (LPSTR)lpbi, dwDIBSize,  
&dwWritten, NULL); 
GlobalUnlock(hDib); 
GlobalFree(hDib); 
CloseHandle(fh);  return TRUE;
}
此函数是dll中一倒出函数,在vc中调用都没问题,在delphi中调用就有问题了,晕死了!问题如题,我只执行CopyScreenToBitmap()在delphi中也有问题,如题。
但在vc中调用都没问题的。

解决方案 »

  1.   

    delphi中直接使用vc写的dll会出问题。把dll写成com。。
      

  2.   

    dephi里函数调用规则和c里不一样吧
    给函数加上WINAPI,如果还有错,就改称WINAPIV,如果还有错.....
    帮不了你了.
      

  3.   

    C里面的函数调用,堆栈由调用方处理,pascal中的函数调用,堆栈由函数处理。给函数加上WINAPI前缀,指定pascal的函数调用方式。另外,我有个疑问,你的CString类型参数是怎么传给delphi的,这可是MFC的类呀
      

  4.   

    声明:function SaveToBmp(strPath:string):boolean;stdcall; external 'CaptureCom.dll';
    调用:SaveToBmp('c:\ee.bmp');
    在那里加winapi?
      

  5.   

    “我有个疑问,你的CString类型参数是怎么传给delphi的”
    就是这个疑问救了我。