⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bmpform.prg

📁 田径运动会管理系统RAR 用VFP编写
💻 PRG
字号:
*!*	谢谢大家捧场。
*!*	保存任意一个窗口到一个bmp文件

*!*	你可以在command 窗口执行  bmpform.prg

*!*	不过最好在要保存的form调用这个子程序.

*!*	bmpform.prg


********
DO decl 

PRIVATE hMemDC, hMemBmp, lnWidth, lnHeight, lnBitsPerPixel,; 
    lnBytesPerScan, lcBFileHdr, lcBIHdr, lpBitsArray, lnBitsSize,; 
    lcRgbQuad, lnRgbQuadSize, lcBInfo, lnFileSize 

STORE "" TO lcBIHdr, lcBInfo, lcRgbQuad 
STORE 0 TO hMemDC, hMemBmp, lnWidth, lnHeight, lnFileSize,; 
    lnBitsPerPixel, lnBytesPerScan, lnRgbQuadSize, lpBitsArray, lnBitsSize 

    = MakeSnapshot() 
    = InitBitmapInfo() 
    = InitBitsArray() 

    #DEFINE DIB_RGB_COLORS   0 
    = GetDIBits (hMemDC, hMemBmp, 0, lnHeight, lpBitsArray,; 
            @lcBInfo, DIB_RGB_COLORS) 
     
    LOCAL lcFilename 
    **保存的文件名
    lcFilename = "c:\myfile.bmp" 

    IF bmp2file (lcFilename) 
        ACTI SCREEN 
        ? "file:          ", lcFilename 
        ? "Size:          ", LTRIM(TRANS(lnFileSize, "999,999,999,999")) 
        ? "Width:         ", LTRIM(STR(lnWidth)) + " pixels" 
        ? "Height:        ", LTRIM(STR(lnHeight)) + " pixels" 
        ? "Bits per pixel:", LTRIM(STR(lnBitsPerPixel)) 
    ENDIF 

    = GlobalFree (lpBitsArray) 
    = DeleteObject (hMemBmp) 
    = DeleteDC (hMemDC) 
RETURN  && main  

PROCEDURE  InitBitmapInfo() 
#DEFINE BI_RGB  0 
#DEFINE RGBQUAD_SIZE     4  && RGBQUAD 
#DEFINE BHDR_SIZE       40  && BITMAPINFOHEADER 

    * forcing 24-bit format 
    lnBitsPerPixel = 24 
    lnBytesPerScan = lnWidth * 3 

    * line width should be DWORD-aligned (4 bytes) 
    * important for 16- and 24-bit color palettes 
    IF Mod(lnBytesPerScan, 4) <> 0 
        lnBytesPerScan = lnBytesPerScan + 4 - Mod(lnBytesPerScan, 4) 
    ENDIF 

    * initializing BitmapInfoHeader structure 
    lcBIHdr = num2dword(BHDR_SIZE) + num2dword(lnWidth) +; 
        num2dword(lnHeight) + num2word(1) + num2word(lnBitsPerPixel) +; 
        num2dword(BI_RGB) + num2dword(0) + num2dword(0) + num2dword(0) +; 
        num2dword(0) + num2dword(0) 

    * creating a buffer for the color table 
    IF lnBitsPerPixel <= 8 
        lnRgbQuadSize = (2^lnBitsPerPixel) * RGBQUAD_SIZE 
        lcRgbQuad = Repli(Chr(0), lnRgbQuadSize) 
    ELSE 
        lnRgbQuadSize = 0 
        lcRgbQuad = "" 
    ENDIF 

    * merging two pieces together 
    lcBInfo = lcBIHdr + lcRgbQuad 
RETURN 

PROCEDURE  InitBitsArray() 
#DEFINE GMEM_FIXED   0 
    lnBitsSize = lnHeight * lnBytesPerScan 
    lpBitsArray = GlobalAlloc (GMEM_FIXED, lnBitsSize) 
    = ZeroMemory (lpBitsArray, lnBitsSize) 

FUNCTION  bmp2file (lcTargetFile) 
* store all gathered pieces to a disk file 
#DEFINE GENERIC_WRITE          1073741824  && 0x40000000 
#DEFINE FILE_SHARE_WRITE                2 
#DEFINE CREATE_ALWAYS                   2 
#DEFINE FILE_ATTRIBUTE_NORMAL         128 
#DEFINE INVALID_HANDLE_value           -1 
#DEFINE BFHDR_SIZE      14  && BITMAPFILEHEADER 

    LOCAL hFile, lnOffBits 

    * resulting BMP file size 
    lnFileSize = BFHDR_SIZE + BHDR_SIZE + lnRgbQuadSize + lnBitsSize 

    * offset to the bitmap bits 
    lnOffBits = BFHDR_SIZE + BHDR_SIZE + lnRgbQuadSize 
     
    * BMP file header 
    lcBFileHdr = "BM" + num2dword(lnFileSize) +; 
            num2dword(0) + num2dword(lnOffBits) 
     
    * 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: 
        = String2File (hFile, @lcBFileHdr)           && BitmapFileHeader 
        = String2File (hFile, @lcBInfo)              && BitmapInfo 
        = Ptr2File (hFile, lpBitsArray, lnBitsSize)  && bitmap data 
        = CloseHandle (hFile) 
        RETURN .T. 
    ELSE 
        = MessageB ("Unable to create file: " + lcTargetFile) 
        RETURN .F. 
    ENDIF 

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 

PROCEDURE  MakeSnapshot() 
#DEFINE SRCCOPY        13369376 
    LOCAL hwnd, hdc, hSavedBitmap 

    hwnd = GetFocus() 
    hdc = GetWindowDC(hwnd) 
    = GetWinRect(hwnd, @lnWidth, @lnHeight) 

    hMemDC = CreateCompatibleDC (hdc) 
    hMemBmp = CreateCompatibleBitmap (hdc, lnWidth, lnHeight) 

    hSavedBitmap = SelectObject (hMemDC, hMemBmp) 
    = BitBlt (hMemDC, 0,0, lnWidth,lnHeight, hdc, 0,0, SRCCOPY) 
    = SelectObject (hMemDC, hSavedBitmap) 
    = ReleaseDC (hwnd, hdc) 
RETURN 

PROCEDURE  GetWinRect(hwnd, lnWidth, lnHeight) 
#DEFINE MAX_DWORD  4294967295  && 0xffffffff 
    LOCAL lpRect, lnLeft, lnTop, lnRight, lnBottom 
    lpRect = Repli(Chr(0), 16)   
    = GetWindowRect (hwnd, @lpRect)   

    lnLeft   = buf2dword(SUBSTR(lpRect,  1,4))   
    lnTop    = buf2dword(SUBSTR(lpRect,  5,4))   
    lnRight  = buf2dword(SUBSTR(lpRect,  9,4))   
    lnBottom = buf2dword(SUBSTR(lpRect, 13,4))   

    IF lnLeft > lnRight 
        lnLeft = lnLeft - MAX_DWORD 
    ENDIF 
    IF lnTop > lnBottom 
        lnTop = lnTop - MAX_DWORD 
    ENDIF 
     
    lnWidth  = lnRight - lnLeft 
    lnHeight = lnBottom - lnTop 
RETURN 

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)) 

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 

PROCEDURE  decl 
    DECLARE INTEGER GetDIBits IN gdi32; 
        INTEGER hdc, INTEGER hbmp, INTEGER uStartScan,; 
        INTEGER cScanLines, INTEGER lpvBits, STRING @lpbi,; 
        INTEGER uUsage 

    DECLARE INTEGER GlobalAlloc IN kernel32 INTEGER wFlags, INTEGER dwBytes  
    DECLARE INTEGER GetWindowRect IN user32 INTEGER hwnd, STRING @lpRect  
    DECLARE INTEGER SelectObject IN gdi32 INTEGER hdc, INTEGER hObject 
    DECLARE INTEGER ReleaseDC IN user32 INTEGER hwnd, INTEGER hdc 
    DECLARE INTEGER DeleteDC IN gdi32 INTEGER hdc 
    DECLARE INTEGER GetFocus IN user32 
    DECLARE INTEGER GetWindowDC IN user32 INTEGER hwnd 
    DECLARE INTEGER GlobalFree IN kernel32 INTEGER hMem 
    DECLARE INTEGER DeleteObject IN gdi32 INTEGER hObject 
    DECLARE INTEGER CreateCompatibleDC IN gdi32 INTEGER hdc 
    DECLARE INTEGER CloseHandle IN kernel32 INTEGER hObject 

    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 CreateFile IN kernel32; 
        STRING lpFileName, INTEGER dwDesiredAccess,; 
        INTEGER dwShareMode, INTEGER lpSecurityAttr,; 
        INTEGER dwCreationDisp, INTEGER dwFlagsAndAttrs,; 
        INTEGER hTemplateFile 

*** The structures used in this code: 
*| typedef struct tagBITMAPINFOHEADER{ 
*|   DWORD  biSize;             0:4 
*|   LONG   biWidth;            4:4 
*|   LONG   biHeight;           8:4 
*|   WORD   biPlanes;          12:2 
*|   WORD   biBitCount;        14:2 
*|   DWORD  biCompression;     16:4 
*|   DWORD  biSizeImage;       20:4 
*|   LONG   biXPelsPerMeter;   24:4 
*|   LONG   biYPelsPerMeter;   28:4 
*|   DWORD  biClrUsed;         32:4 
*|   DWORD  biClrImportant;    36:4 = 40 bytes 
*| } BITMAPINFOHEADER, *PBITMAPINFOHEADER 

*| typedef struct tagRGBQUAD { 
*|   BYTE    rgbBlue;  
*|   BYTE    rgbGreen;  
*|   BYTE    rgbRed;  
*|   BYTE    rgbReserved;  
*| } RGBQUAD; total 4 bytes 

*| typedef struct tagBITMAPINFO { 
*|  BITMAPINFOHEADER bmiHeader;  
*|  RGBQUAD          bmiColors[1];  
*|} BITMAPINFO, *PBITMAPINFO; 

*| typedef struct tagBITMAPFILEHEADER {  
*|   WORD    bfType;         0:2 
*|   DWORD   bfSize;         2:4 
*|   WORD    bfReserved1;    6:2 
*|   WORD    bfReserved2;    8:2 
*|   DWORD   bfOffBits;     10:4 = 14 bytes 
*| } BITMAPFILEHEADER, *PBITMAPFILEHEADER; 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -