  | 
				VFP 愛用者社區 本討論區為 Visual Foxpro 愛用者經驗交流的地方, 請多多利用"搜尋"的功能, 先查看看有無前例可循, 如果還有不懂的再發問. 部份主題有附加檔案, 須先註冊成為社區居民才可以下載.   
				 | 
			 
		 
		 
	
		| 上一篇主題 :: 下一篇主題   | 
	 
	
	
		| 發表人 | 
		內容 | 
	 
	
		Ruey
 
 
  註冊時間: 2003-03-12 文章: 1698 來自: tunglo
  第 1 樓
  | 
		
			
				 發表於: 星期日 八月 31, 2003 12:23 pm    文章主題: 如何將剪貼簿產生bmp圖檔?(轉貼) | 
				     | 
			 
			
				
  | 
			 
			
				來源:梅子 csut90131
 
 
 
#DEFINE CF_BITMAP 2 
 
#DEFINE OBJ_BITMAP 7 
 
DO decl 
 
 
LOCAL hClipBmp, lcTargetFile 
 
lcTargetFile = "c:\clipboard.bmp" 
 
= OpenClipboard (0) 
 
hClipBmp = GetClipboardData (CF_BITMAP) 
 
= CloseClipboard() 
 
 
IF hClipBmp = 0 Or GetObjectType(hClipBmp) <> OBJ_BITMAP 
 
* you can press [Print Scrn] key on your keyboard to place 
 
* a copy of the screen on the clipboard; then repeat the test 
 
= MessageB ("No bitmap data found on the clipboard.",; 
 
64, "Clipboard to BMP") 
 
RETURN 
 
ENDIF 
 
 
= bitmap2file (hClipBmp, lcTargetFile) 
 
= DeleteObject (hClipBmp) 
 
RETURN 
 
 
PROCEDURE bitmap2file (hBitmap, lcTargetFile) 
 
#DEFINE DIB_RGB_COLORS 0 
 
PRIVATE pnWidth, pnHeight, pnBitsSize, pnRgbQuadSize, pnBytesPerScan 
 
STORE 0 TO pnWidth, pnHeight, pnBytesPerScan, pnBitsSize, pnRgbQuadSize 
 
= GetBitmapDimensions(hBitmap, @pnWidth, @pnHeight) 
 
 
LOCAL lpBitsArray, lcBInfo 
 
 
lcBInfo = InitBitmapInfo() 
 
lpBitsArray = InitBitsArray() 
 
 
LOCAL hwnd, hdc, hMemDC 
 
hwnd = GetActiveWindow() 
 
hdc = GetWindowDC(hwnd) 
 
hMemDC = CreateCompatibleDC (hdc) 
 
= ReleaseDC (hwnd, hdc) 
 
 
= GetDIBits (hMemDC, hBitmap, 0, pnHeight, lpBitsArray,; 
 
@lcBInfo, DIB_RGB_COLORS) 
 
 
#DEFINE BFHDR_SIZE 14 && BITMAPFILEHEADER 
 
#DEFINE BHDR_SIZE 40 && BITMAPINFOHEADER 
 
 
LOCAL hFile, lnFileSize, lnOffBits, lcBFileHdr 
 
 
* resulting BMP file size 
 
lnFileSize = BFHDR_SIZE + BHDR_SIZE + pnRgbQuadSize + pnBitsSize 
 
 
* offset to the bitmap bits 
 
lnOffBits = BFHDR_SIZE + BHDR_SIZE + pnRgbQuadSize 
 
 
* BMP file header 
 
lcBFileHdr = "BM" + num2dword(lnFileSize) +; 
 
num2dword(0) + num2dword(lnOffBits) 
 
 
#DEFINE GENERIC_WRITE 1073741824 && 0x40000000 
 
#DEFINE FILE_SHARE_WRITE 2 
 
#DEFINE CREATE_ALWAYS 2 
 
#DEFINE FILE_ATTRIBUTE_NORMAL 128 
 
#DEFINE INVALID_HANDLE_value -1 
 
 
* target file handle 
 
hFile = CreateFile (lcTargetFile,; 
 
GENERIC_WRITE,; 
 
FILE_SHARE_WRITE, 0,; 
 
CREATE_ALWAYS,; 
 
FILE_ATTRIBUTE_NORMAL, 0) 
 
 
IF hFile <> INVALID_HANDLE_value 
 
* a straightforward process of storing block after block: 
 
WAIT WINDOW "Storing to file..." NOWAIT 
 
 
= String2File (hFile, @lcBFileHdr) && BitmapFileHeader 
 
= String2File (hFile, @lcBInfo) && BitmapInfo 
 
= Ptr2File (hFile, lpBitsArray, pnBitsSize) && bitmap data 
 
= CloseHandle (hFile) 
 
 
WAIT CLEAR 
 
= MessageB ("File created:" + lcTargetFile + Chr(13)+Chr(13) +; 
 
"Size:" + TRANS(lnFileSize,"999,999,999,999") + " bytes" + Chr(13) +; 
 
"Width:" + STR(pnWidth, 6) + " px" + Chr(13) +; 
 
"Height:" + STR(pnHeight, 6) + " px",; 
 
64, "Clipboard to BMP") 
 
ELSE 
 
= MessageB ("Unable to create file: " + lcTargetFile) 
 
ENDIF 
 
 
= GlobalFree(lpBitsArray) 
 
= DeleteDC (hMemDC) 
 
RETURN 
 
 
PROCEDURE GetBitmapDimensions(hBitmap, lnWidth, lnHeight) 
 
#DEFINE BITMAP_STRU_SIZE 24 
 
LOCAL lcBuffer 
 
lcBuffer = Repli(Chr(0), BITMAP_STRU_SIZE) 
 
IF GetObjectA (hBitmap, BITMAP_STRU_SIZE, @lcBuffer) <> 0 
 
lnWidth = buf2dword (SUBSTR(lcBuffer, 5,4)) 
 
lnHeight = buf2dword (SUBSTR(lcBuffer, 9,4)) 
 
ENDIF 
 
RETURN 
 
 
PROCEDURE InitBitmapInfo(lcBIHdr) 
 
#DEFINE BI_RGB 0 
 
#DEFINE RGBQUAD_SIZE 4 && RGBQUAD 
 
#DEFINE BHDR_SIZE 40 && BITMAPINFOHEADER 
 
 
LOCAL lnBitsPerPixel, lcBIHdr, lcRgbQuad 
 
 
* forcing 24-bit format 
 
lnBitsPerPixel = 24 
 
pnBytesPerScan = Int((pnWidth * lnBitsPerPixel)/  
 
 
* line width should be DWORD-aligned (4 bytes) 
 
* important for 16- and 24-bit images 
 
IF Mod(pnBytesPerScan, 4) <> 0 
 
pnBytesPerScan = pnBytesPerScan + 4 - Mod(pnBytesPerScan, 4) 
 
ENDIF 
 
 
* 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 
 
pnRgbQuadSize = (2^lnBitsPerPixel) * RGBQUAD_SIZE 
 
lcRgbQuad = Repli(Chr(0), pnRgbQuadSize) 
 
ELSE 
 
lcRgbQuad = "" 
 
ENDIF 
 
RETURN lcBIHdr + lcRgbQuad 
 
 
PROCEDURE InitBitsArray() 
 
#DEFINE GMEM_FIXED 0 
 
LOCAL lnPtr 
 
 
pnBitsSize = pnHeight * pnBytesPerScan 
 
lnPtr = GlobalAlloc (GMEM_FIXED, pnBitsSize) 
 
= ZeroMemory (lnPtr, pnBitsSize) 
 
RETURN lnPtr 
 
 
PROCEDURE String2File (hFile, lcBuffer) 
 
* appends string buffer to a file 
 
DECLARE INTEGER WriteFile IN kernel32; 
 
INTEGER hFile, STRING @lpBuffer, INTEGER nBt2Write,; 
 
INTEGER @lpBtWritten, INTEGER lpOverlapped 
 
 
= WriteFile (hFile, @lcBuffer, Len(lcBuffer), 0, 0) 
 
RETURN 
 
 
PROCEDURE Ptr2File (hFile, lnPointer, lnBt2Write) 
 
* appends memory block to a file 
 
DECLARE INTEGER WriteFile IN kernel32; 
 
INTEGER hFile, INTEGER lpBuffer, INTEGER nBt2Write,; 
 
INTEGER @lpBtWritten, INTEGER lpOverlapped 
 
 
= WriteFile (hFile, lnPointer, lnBt2Write, 0, 0) 
 
RETURN 
 
 
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 
 
 
FUNCTION buf2word (lcBuffer) 
 
RETURN Asc(SUBSTR(lcBuffer, 1,1)) + ; 
 
Asc(SUBSTR(lcBuffer, 2,1)) * 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 num2word (lnvalue) 
 
RETURN Chr(MOD(m.lnvalue,256)) + CHR(INT(m.lnvalue/256)) 
 
 
PROCEDURE decl 
 
DECLARE INTEGER GetActiveWindow IN user32 
 
DECLARE INTEGER GetClipboardData IN user32 INTEGER uFormat 
 
DECLARE INTEGER OpenClipboard IN user32 INTEGER hwnd 
 
DECLARE INTEGER CloseClipboard IN user32 
 
DECLARE INTEGER DeleteObject IN gdi32 INTEGER hObject 
 
DECLARE INTEGER GetWindowDC IN user32 INTEGER hwnd 
 
DECLARE INTEGER ReleaseDC IN user32 INTEGER hwnd, INTEGER hdc 
 
DECLARE INTEGER CreateCompatibleDC IN gdi32 INTEGER hdc 
 
DECLARE INTEGER DeleteDC IN gdi32 INTEGER hdc 
 
DECLARE INTEGER GlobalAlloc IN kernel32 INTEGER wFlags, INTEGER dwBytes 
 
DECLARE INTEGER GlobalFree IN kernel32 INTEGER hMem 
 
 
DECLARE INTEGER GetObject IN gdi32 AS GetObjectA; 
 
INTEGER hgdiobj, INTEGER cbBuffer, STRING @lpvObject 
 
 
DECLARE INTEGER GetObjectType IN gdi32 INTEGER h 
 
 
DECLARE RtlZeroMemory IN kernel32 As ZeroMemory; 
 
INTEGER dest, INTEGER numBytes 
 
 
DECLARE INTEGER GetDIBits IN gdi32; 
 
INTEGER hdc, INTEGER hbmp, INTEGER uStartScan,; 
 
INTEGER cScanLines, INTEGER lpvBits, STRING @lpbi,; 
 
INTEGER uUsage 
 
 
DECLARE INTEGER CreateFile IN kernel32; 
 
STRING lpFileName, INTEGER dwDesiredAccess,; 
 
INTEGER dwShareMode, INTEGER lpSecurityAttr,; 
 
INTEGER dwCreationDisp, INTEGER dwFlagsAndAttrs,; 
 
INTEGER hTemplateFile 
 
 
DECLARE INTEGER CloseHandle IN kernel32 INTEGER hObject _________________ #############################
 
快樂媽咪系列幸福宅配,喝十全雞湯~原來幸福那麼簡單!!
 
 
學會VFP使用者社區的搜尋,Code才會更有趣~
 
############################# | 
			 
		  | 
	 
	
		| 回頂端 | 
		 | 
	 
	
		  | 
	 
	
		小桑•無痕
 
  
  註冊時間: 2003-07-08 文章: 304 來自: Tainan, Taiwan
  第 2 樓
  | 
		
			
				 發表於: 星期三 五月 04, 2011 10:58 am    文章主題: Re: 如何將剪貼簿產生bmp圖檔?(轉貼) | 
				     | 
			 
			
				
  | 
			 
			
				 	  | Ruey 寫到: | 	 		  來源:梅子 csut90131
 
pnBytesPerScan = Int((pnWidth * lnBitsPerPixel)/  
 
 
 | 	  
 
 
pnBytesPerScan = Int((pnWidth * lnBitsPerPixel)/8 ) _________________ 用力 Try 一下...可以發現很多好玩的事.... | 
			 
		  | 
	 
	
		| 回頂端 | 
		 | 
	 
	
		  | 
	 
	
		 | 
	 
 
  
  	 
	    
  	   | 
 	
您 無法 在這個版面發表文章 您 無法 在這個版面回覆文章 您 無法 在這個版面編輯文章 您 無法 在這個版面刪除文章 您 無法 在這個版面進行投票 您 無法 在這個版面附加檔案 您 無法 在這個版面下載檔案
  | 
   
  
		 |