发信人: ljun(闲云) 
整理人: foxzz(2002-05-30 22:19:32), 站内信件
 | 
 
 
【 在 xichha 的大作中提到:】
 :  希望用VFP6.0程序完成如下功能: 
 :  对当前的活动窗口进行屏幕硬拷贝后,将其保存为一个bmp文件。 
 :  请各位行家里手提供解决方案和源程序。 
 :    谢谢! 
 :
 :......
 
 请参考: 
 在form中调用该例程可以打印本form到打印机。
 
 prnform.prg
 ***
 #DEFINE LOGPIXELSX 88 
 #DEFINE LOGPIXELSY 90 
 #DEFINE PHYSICALOFFSETX 112 
 #DEFINE PHYSICALOFFSETY 113 
 #DEFINE SRCCOPY 13369376 
 #DEFINE DIB_RGB_COLORS 0 
 DO decl 
 
 PRIVATE pnWidth, pnHeight, lnBitsPerPixel, lnBytesPerScan 
 STORE 0 TO pnWidth, pnHeight, lnBitsPerPixel, lnBytesPerScan 
 
 LOCAL hwnd, hFormDC, hPrnDC, hMemDC, hMemBmp, hSavedBitmap,; 
 xOffsPrn, yOffsPrn, xScale, yScale, lcDocInfo, lcBInfo, lpBitsArray 
 
 * retrieving printer device context and page offsets 
 hPrnDC = getDefaultPrnDC() && no error check 
 xOffsPrn = GetDeviceCaps(hPrnDC, PHYSICALOFFSETX) 
 yOffsPrn = GetDeviceCaps(hPrnDC, PHYSICALOFFSETY) 
 
 * retrieving screen window handle, device context, width, and height 
 hwnd = GetFocus() && a window with keyboard focus 
 hFormDC = GetWindowDC(hwnd) 
 = getWinRect (hwnd, @pnWidth, @pnHeight) 
 
 * scaling factor values from screen to printer 
 xScale = GetDeviceCaps(hPrnDC, LOGPIXELSX)/GetDeviceCaps(hFormDC, LOGPIXELSX) 
 yScale = GetDeviceCaps(hPrnDC, LOGPIXELSY)/GetDeviceCaps(hFormDC, LOGPIXELSY) 
 
 * creating screen compatible DC and BITMAP to pass image 
 * through them from screen to printer; no direct screen to printer copying 
 hMemDC = CreateCompatibleDC (hFormDC) 
 hMemBmp = CreateCompatibleBitmap (hFormDC, pnWidth, pnHeight) 
 hSavedBitmap = SelectObject(hMemDC, hMemBmp) 
 
 * copying bitmap data from screen to virtual device context 
 * and unselecting the bmp from the memory device context 
 = BitBlt (hMemDC, 0,0, pnWidth,pnHeight, hFormDC, 0,0, SRCCOPY) 
 = SelectObject(hMemDC, hSavedBitmap) 
 
 * retrieving bits from the compatible bitmap into a buffer 
 * as a device-independent bitmap (DIB) with a BitsPerPixel value 
 * as one of the printer device context 
 lcBInfo = InitBitmapInfo(hPrnDC) 
 lpBitsArray = InitBitsArray() 
 = GetDIBits (hMemDC, hMemBmp, 0, pnHeight,; 
 lpBitsArray, @lcBInfo, DIB_RGB_COLORS) 
 
 lcDocInfo = Chr(20) + Repli(Chr(0), 19) && DOCINFO struct - 20 bytes 
 IF StartDoc(hPrnDC, @lcDocInfo) > 0 
 = StartPage(hPrnDC) 
 
 = StretchDIBits (hPrnDC, xOffsPrn, yOffsPrn,; 
 xOffsPrn + Int(xScale * pnWidth),; 
 yOffsPrn + Int(yScale * pnHeight),; 
 0,0, pnWidth, pnHeight,; 
 lpBitsArray, @lcBInfo, DIB_RGB_COLORS, SRCCOPY) 
 
 = EndPage(hPrnDC) 
 = EndDoc(hPrnDC) 
 ENDIF 
 
 * releasing system resources on exit 
 = GlobalFree(lpBitsArray) 
 = DeleteObject(hMemBmp) 
 = DeleteDC(hMemDC) 
 = DeleteDC(hPrnDC) 
 = ReleaseDC(hwnd, hFormDC) 
 RETURN 
 
 PROCEDURE getWinRect (lnHwnd, lnWidth, lnHeight) 
 * returns window width and height for the given hwnd 
 #DEFINE maxDword 4294967295 && 0xffffffff 
 LOCAL lpRect, lnLeft, lnTop, lnRight, lnBottom 
 lpRect = REPLI (Chr(0), 16) 
 = GetWindowRect (lnHwnd, @lpRect) 
 
 lnRight = buf2dword(SUBSTR(lpRect, 9,4)) 
 lnBottom = buf2dword(SUBSTR(lpRect, 13,4)) 
 
 lnLeft = buf2dword(SUBSTR(lpRect, 1,4)) 
 IF lnLeft > lnRight 
 lnLeft = lnLeft - maxDword 
 ENDIF 
 lnTop = buf2dword(SUBSTR(lpRect, 5,4)) 
 IF lnTop > lnBottom 
 lnTop = lnTop - maxDword 
 ENDIF 
 
 lnWidth = lnRight - lnLeft 
 lnHeight = lnBottom - lnTop 
 RETURN 
 
 FUNCTION getDefaultPrnDC 
 * returns device context for the default printer 
 #DEFINE PD_RETURNDC 256 
 #DEFINE PD_RETURNDEFAULT 1024 
 LOCAL lcStruct, lnFlags 
 lnFlags = PD_RETURNDEFAULT + PD_RETURNDC 
 
 * fill PRINTDLG structure 
 lcStruct = num2dword(66) + Repli(Chr(0), 16) +; 
 num2dword(lnFlags) + Repli(Chr(0), 42) 
 IF PrintDlg (@lcStruct) <> 0 
 RETURN buf2dword (SUBSTR(lcStruct, 17,4)) 
 ENDIF 
 RETURN 0 
 
 FUNCTION InitBitmapInfo(hTargetDC) 
 #DEFINE BI_RGB 0 
 #DEFINE RGBQUAD_SIZE 4 && RGBQUAD 
 #DEFINE BHDR_SIZE 40 && BITMAPINFOHEADER 
 
 LOCAL lnRgbQuadSize, lcRgbQuad, lcBIHdr 
 
 * use printer BitPerPixel value 
 lnBitsPerPixel = 24 
 
 * initializing BitmapInfoHeader structure 
 lcBIHdr = num2dword(BHDR_SIZE) +; 
 num2dword(pnWidth) + num2dword(pnHeight) +; 
 num2word(1) + num2word(lnBitsPerPixel) +; 
 num2dword(BI_RGB) + Repli(Chr(0), 20) 
 
 * creating a buffer for the color table 
 IF lnBitsPerPixel <= 8 
 lnRgbQuadSize = (2^lnBitsPerPixel) * RGBQUAD_SIZE 
 lcRgbQuad = Repli(Chr(0), lnRgbQuadSize) 
 ELSE 
 lcRgbQuad = "" 
 ENDIF 
 RETURN lcBIHdr + lcRgbQuad 
 
 PROCEDURE InitBitsArray() 
 #DEFINE GMEM_FIXED 0 
 LOCAL lnPtr, lnAllocSize 
 
 * making sure the value is DWORD-aligned 
 lnBytesPerScan = Int((pnWidth * lnBitsPerPixel)/8) 
 IF Mod(lnBytesPerScan, 4) <> 0 
 lnBytesPerScan = lnBytesPerScan + 4 - Mod(lnBytesPerScan, 4) 
 ENDIF 
 
 lnAllocSize = pnHeight * lnBytesPerScan 
 lnPtr = GlobalAlloc (GMEM_FIXED, lnAllocSize) 
 = ZeroMemory (lnPtr, lnAllocSize) 
 RETURN lnPtr 
 
 FUNCTION num2word (lnValue) 
 RETURN Chr(MOD(m.lnValue,256)) + CHR(INT(m.lnValue/256)) 
 
 FUNCTION num2dword (lnValue) 
 #DEFINE m0 256 
 #DEFINE m1 65536 
 #DEFINE m2 16777216 
 LOCAL b0, b1, b2, b3 
 b3 = Int(lnValue/m2) 
 b2 = Int((lnValue - b3*m2)/m1) 
 b1 = Int((lnValue - b3*m2 - b2*m1)/m0) 
 b0 = Mod(lnValue, m0) 
 RETURN Chr(b0)+Chr(b1)+Chr(b2)+Chr(b3) 
 
 FUNCTION buf2word (lcBuffer) 
 RETURN Asc(SUBSTR(lcBuffer, 1,1)) + ; 
 Asc(SUBSTR(lcBuffer, 2,1)) * 256 
 
 FUNCTION buf2dword (lcBuffer) 
 RETURN Asc(SUBSTR(lcBuffer, 1,1)) + ; 
 Asc(SUBSTR(lcBuffer, 2,1)) * 256 +; 
 Asc(SUBSTR(lcBuffer, 3,1)) * 65536 +; 
 Asc(SUBSTR(lcBuffer, 4,1)) * 16777216 
 
 PROCEDURE decl && so many of them declared here 
 DECLARE INTEGER GetFocus IN user32 
 DECLARE INTEGER EndDoc IN gdi32 INTEGER hdc 
 DECLARE INTEGER GetWindowDC IN user32 INTEGER hwnd 
 DECLARE INTEGER DeleteObject IN gdi32 INTEGER hObject 
 DECLARE INTEGER CreateCompatibleDC IN gdi32 INTEGER hdc 
 DECLARE INTEGER ReleaseDC IN user32 INTEGER hwnd, INTEGER hdc 
 DECLARE INTEGER GetWindowRect IN user32 INTEGER hwnd, STRING @lpRect 
 DECLARE INTEGER GlobalAlloc IN kernel32 INTEGER wFlags, INTEGER dwBytes 
 DECLARE INTEGER GetDeviceCaps IN gdi32 INTEGER hdc, INTEGER nIndex 
 DECLARE INTEGER SelectObject IN gdi32 INTEGER hdc, INTEGER hObject 
 DECLARE INTEGER StartDoc IN gdi32 INTEGER hdc, STRING @ lpdi 
 DECLARE INTEGER GlobalFree IN kernel32 INTEGER hMem 
 DECLARE INTEGER PrintDlg IN comdlg32 STRING @ lppd 
 DECLARE INTEGER DeleteDC IN gdi32 INTEGER hdc 
 DECLARE INTEGER StartPage IN gdi32 INTEGER hdc 
 DECLARE INTEGER EndPage IN gdi32 INTEGER hdc 
 
 DECLARE RtlZeroMemory IN kernel32 As ZeroMemory; 
 INTEGER dest, INTEGER numBytes 
 
 DECLARE INTEGER CreateCompatibleBitmap IN gdi32; 
 INTEGER hdc, INTEGER nWidth, INTEGER nHeight 
 
 DECLARE INTEGER BitBlt IN gdi32; 
 INTEGER hDestDC, INTEGER x, INTEGER y,; 
 INTEGER nWidth, INTEGER nHeight, INTEGER hSrcDC,; 
 INTEGER xSrc, INTEGER ySrc, INTEGER dwRop 
 
 DECLARE INTEGER StretchDIBits IN gdi32; 
 INTEGER hdc, INTEGER XDest, INTEGER YDest,; 
 INTEGER nDestWidth, INTEGER nDestHeight, INTEGER XSrc,; 
 INTEGER YSrc, INTEGER nSrcWidth, INTEGER nSrcHeight,; 
 INTEGER lpBits, STRING @lpBitsInfo,; 
 INTEGER iUsage, INTEGER dwRop 
 
 DECLARE INTEGER GetDIBits IN gdi32; 
 INTEGER hdc, INTEGER hbmp, INTEGER uStartScan,; 
 INTEGER cScanLines, INTEGER lpvBits, STRING @lpbi,; 
 INTEGER uUsage 
 RETURN && decl 
   
 
  ---- Foxer资料信息传送站
 站点宗旨:共同进步
 站点精神:Foxer共建Fox站(网站)
 站点征召:请大家把好的贴子或文章粘到网站上
 主页地址:http://webpage.smiling.com.cn/foxer/index.html
 报名地址:http://www.smiling.com.cn/search/groupinfo.ecgi?group_id=25505
 本站域名转向: vfoxer.126.com 
               foxer126.126.com 
               vfp126.126.com 
 
 
       | 
 
 
 |