Jump to content

Recommended Posts

Posted (edited)

Hello friends, I'm not very good at C + + and would like someone more experienced give me some help on the code below:

 

Would someone know tell why the code below does not work?

HBITMAP WINAPI ScreenCapture(HDC hDestDC, int dWidth, int dHeight, HDC hSrcDC, int sLeft, int sTop, int sWidth, int sHeight, int* bmInfo, LPVOID* pBits) {

    HBITMAP hBitmap = CreateDIBSection(0, (PBITMAPINFO)&bmInfo, DIB_RGB_COLORS, (VOID**)&pBits, 0, 0);

    SelectObject(hDestDC, hBitmap);
    StretchBlt(hDestDC, 0, 0, dWidth, dHeight, hSrcDC, sLeft, sTop, sWidth, sHeight, SRCCOPY); 

    return hBitmap;
}
And in "AutoIt" I would call in this way?:

DllCall($DLL, 'handle', 'ScreenCapture', _
    'handle', $hDestDC, _
    'int', $iDestWidth, _
    'int', $iDestHeight, _
    'hwnd', $hSrcDC, _
    'int', $SrcLeft, _
    'int', $SrcTop, _
    'int', $SrcWidth, _
    'int', $SrcHeight, _
    'ptr*', $pBITMAPINFO, _
    'int*', $pBits)
Thank you in advance,

JS

Edited by JScript

http://forum.autoitbrasil.com/ (AutoIt v3 Brazil!!!)

Somewhere Out ThereJames Ingram

somewh10.png

dropbo10.pngDownload Dropbox - Simplify your life!
Your virtual HD wherever you go, anywhere!

Posted

Hello friend!

Then, the error that appears in Visual Studio 10 compiler is:

Error: argument of type" BITMAPINFO ** "is incompatible with parameter type int

Only works when BITMAPINFO is defined inside a function, but I wanted to set it outside the function!

 

But now the morning I got the following:

HBITMAP WINAPI ScreenCapture(HDC hDestDC, int dWidth, int dHeight, HDC hSrcDC, int sLeft, int sTop, int sWidth, int sHeight, BITMAPINFO *bmInfo, LPVOID &pBits) {

        HBITMAP hBitmap = CreateDIBSection(0, bmInfo, DIB_RGB_COLORS, (VOID**)&pBits, NULL, 0);

        SelectObject(hDestDC, hBitmap);
        StretchBlt(hDestDC, 0, 0, dWidth, dHeight, hSrcDC, sLeft, sTop, sWidth, sHeight, SRCCOPY);

        return hBitmap;
}

And is working fine! But I'm not sure that the input parameters are all correct!

I'm calling in AutoIt as follows:

$hHBitmap = DllCall($hDLL, 'handle', 'ScreenCapture', _
        'handle', $hDestDC, _
        'int', $iWidthDest, _
        'int', $iHeightDest, _
        'hwnd', $hSrcDC, _
        'int', $iXSrc, _
        'int', $iYSrc, _
        'int', $iWidthSrc, _
        'int', $iHeightSrc, _
        'ptr', $pBITMAPINFO, _
        'ptr*', 0)
$pBits = $hHBitmap[10]
$hHBitmap = $hHBitmap[0]

Any suggestions or advice?

JS

http://forum.autoitbrasil.com/ (AutoIt v3 Brazil!!!)

Somewhere Out ThereJames Ingram

somewh10.png

dropbo10.pngDownload Dropbox - Simplify your life!
Your virtual HD wherever you go, anywhere!

Posted

It's basically like this:

Global $hDestDC, $tBMPINFO, $pBITMAPINFO, $iScrBits, $iColorCnt, $pBits, $hHBitmap, $iWidthDest, $iHeightDest

;----
;----

; Region screen capture
$hDestDC = _WinAPI_CreateCompatibleDC(0)

#Region BITMAPINFO
$tBMPINFO = DllStructCreate("dword Size; long Width; long Height; word Planes; word BitCount; dword Compression; dword SizeImage; long XPelsPerMeter; long YPelsPerMeter; dword ClrUsed; dword ClrImportant; dword RGBQuad[256];")
DllStructSetData($tBMPINFO, "Size", 40);
DllStructSetData($tBMPINFO, "Planes", 1)
DllStructSetData($tBMPINFO, 'Compression', 0);$BI_RGB
DllStructSetData($tBMPINFO, 'SizeImage', 0)
DllStructSetData($tBMPINFO, "Width", $iWidthDest)
DllStructSetData($tBMPINFO, "Height", -($iHeightDest)); minus =standard = bottomup
DllStructSetData($tBMPINFO, "BitCount", $iScrBits)
If $iScrBits <= 8 Then
    $iColorCnt = BitShift(1, -$iScrBits)
    DllStructSetData($tBMPINFO, 'ClrUsed', $iColorCnt)
    DllStructSetData($tBMPINFO, 'ClrImportant', $iColorCnt)
EndIf
Switch $iScrBits
    Case 8
        For $i = 0 To $iColorCnt - 1
            DllStructSetData($tBMPINFO, 'RGBQuad', BitOR(BitShift($i, -16), BitShift($i, -8), $i), $i + 1)
        Next
    Case 4
        Local $aCol[16] = [8, 24, 38, 56, 72, 88, 104, 120, 136, 152, 168, 184, 210, 216, 232, 248]
        For $i = 0 To 15
            DllStructSetData($tBMPINFO, 'RGBQuad', BitOR(BitShift($aCol[$i], -16), BitShift($aCol[$i], -8), $aCol[$i]), $i + 1)
        Next
    Case 1
        DllStructSetData($tBMPINFO, 'RGBQuad', BitOR(BitShift(0xFF, -16), BitShift(0xFF, -8), 0xFF), 2)
EndSwitch
#EndRegion BITMAPINFO

$pBITMAPINFO = DllStructGetPtr($tBMPINFO)

$hHBitmap = DllCall($hDLL, 'handle', 'ScreenCapture', _
        'handle', $hDestDC, _
        'int', $iWidthDest, _
        'int', $iHeightDest, _
        'hwnd', $hSrcDC, _
        'int', $iXSrc, _
        'int', $iYSrc, _
        'int', $iWidthSrc, _
        'int', $iHeightSrc, _
        'ptr', $pBITMAPINFO, _
        'ptr*', 0)
$pBits = $hHBitmap[10]
$hHBitmap = $hHBitmap[0]
But I'm just setting the BITMAPINFO outside the dll simply by not know translate AutoIt to C ++

JS

http://forum.autoitbrasil.com/ (AutoIt v3 Brazil!!!)

Somewhere Out ThereJames Ingram

somewh10.png

dropbo10.pngDownload Dropbox - Simplify your life!
Your virtual HD wherever you go, anywhere!

Posted

I'll try to be more clear...

How to pass the code below to C++ ?

$tBMPINFO = DllStructCreate("dword Size; long Width; long Height; word Planes; word BitCount; dword Compression; dword SizeImage; long XPelsPerMeter; long YPelsPerMeter; dword ClrUsed; dword ClrImportant; dword RGBQuad[256];")
DllStructSetData($tBMPINFO, "Size", 40);
DllStructSetData($tBMPINFO, "Planes", 1)
DllStructSetData($tBMPINFO, 'Compression', 0);$BI_RGB
DllStructSetData($tBMPINFO, 'SizeImage', 0)
DllStructSetData($tBMPINFO, "Width", $iWidthDest)
DllStructSetData($tBMPINFO, "Height", -($iHeightDest)); minus =standard = bottomup
DllStructSetData($tBMPINFO, "BitCount", $iScrBits)

If $iScrBits <= 8 Then
    $iColorCnt = BitShift(1, -$iScrBits)
    DllStructSetData($tBMPINFO, 'ClrUsed', $iColorCnt)
    DllStructSetData($tBMPINFO, 'ClrImportant', $iColorCnt)
EndIf

Switch $iScrBits
    Case 8
        For $i = 0 To $iColorCnt - 1
            DllStructSetData($tBMPINFO, 'RGBQuad', BitOR(BitShift($i, -16), BitShift($i, -8), $i), $i + 1)
        Next
    Case 4
        Local $aCol[16] = [8, 24, 38, 56, 72, 88, 104, 120, 136, 152, 168, 184, 210, 216, 232, 248]
        For $i = 0 To 15
            DllStructSetData($tBMPINFO, 'RGBQuad', BitOR(BitShift($aCol[$i], -16), BitShift($aCol[$i], -8), $aCol[$i]), $i + 1)
        Next
    Case 1
        DllStructSetData($tBMPINFO, 'RGBQuad', BitOR(BitShift(0xFF, -16), BitShift(0xFF, -8), 0xFF), 2)
EndSwitch

JS

http://forum.autoitbrasil.com/ (AutoIt v3 Brazil!!!)

Somewhere Out ThereJames Ingram

somewh10.png

dropbo10.pngDownload Dropbox - Simplify your life!
Your virtual HD wherever you go, anywhere!

Posted

The part you are having trouble with is sending your structure to the dll call?

Not! The example I posted here Is working perfectly, what I wish is to pass this snippet to C++ !

I've done part of 8 bits, but still missing 4 and 1 bits:

HBITMAP WINAPI ScreenCapture(HDC hDestDC, int dWidth, int dHeight, HDC hSrcDC, int sLeft, int sTop, int sWidth, int sHeight, 
    LPVOID &pbmInfo, LPVOID &pBits, int BitCount) {

        BITMAPINFO* pbmi = (BITMAPINFO*) new BYTE[sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD)*256];
        memset(pbmi, 0, sizeof(BITMAPINFO) + sizeof(RGBQUAD)*256);
        BITMAPINFO& bmInfo = *pbmi;
        bmInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
        bmInfo.bmiHeader.biWidth = dWidth;
        bmInfo.bmiHeader.biHeight = -dHeight; // top-down
        bmInfo.bmiHeader.biPlanes = 1;
        bmInfo.bmiHeader.biBitCount = BitCount;
        bmInfo.bmiHeader.biCompression = BI_RGB;
        bmInfo.bmiHeader.biSizeImage = 0; //(((dWidth * bmi.bmiHeader.biBitCount + 31) & ~31) >> 3) * dHeight;
        if (BitCount <= 8) {
            int ColorCnt;
            ColorCnt = 1 << BitCount;
            bmInfo.bmiHeader.biClrUsed = ColorCnt;
            bmInfo.bmiHeader.biClrImportant = ColorCnt;

            switch(BitCount) {
            case 8:
                for(int i = 0; i < ColorCnt; i++) {
                    bmInfo.bmiColors[i].rgbRed = i;
                    bmInfo.bmiColors[i].rgbGreen = i;
                    bmInfo.bmiColors[i].rgbBlue = i;
                    bmInfo.bmiColors[i].rgbReserved = 0;
                }
                break;
            case 4:
                // This part still lack complete
                break;
            case 1:
                // This part still lack complete
                break;
            }
        }
        HBITMAP hBitmap = CreateDIBSection(0, &bmInfo, DIB_RGB_COLORS, (VOID**)&pBits, NULL, 0);

        SelectObject(hDestDC, hBitmap);
        StretchBlt(hDestDC, 0, 0, dWidth, dHeight, hSrcDC, sLeft, sTop, sWidth, sHeight, SRCCOPY); 

        pbmInfo = pbmi;

        return hBitmap;
}
JS

http://forum.autoitbrasil.com/ (AutoIt v3 Brazil!!!)

Somewhere Out ThereJames Ingram

somewh10.png

dropbo10.pngDownload Dropbox - Simplify your life!
Your virtual HD wherever you go, anywhere!

Posted

@Richard Robertson

Friend, I finally managed to write the code the way I wanted, see:

HBITMAP WINAPI StretchBltEx(HDC hDestDC, int dWidth, int dHeight, HDC hSrcDC, int sLeft, int sTop, int sWidth, int sHeight, LPVOID &pbmInfo, LPVOID &pBits, WORD cClrBits) {

    PBITMAPINFO pbmi;
    int ColorCnt = 1 << cClrBits;

    // Allocate memory for the BITMAPINFO structure.
    // This structure contains a BITMAPINFOHEADER structure and an array of RGBQUAD data structures.
     if (cClrBits < 24) 
         pbmi = (PBITMAPINFO) LocalAlloc(LPTR, sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * ColorCnt);

     // There is no RGBQUAD array for these formats: 24-bit-per-pixel or 32-bit-per-pixel
     else
         pbmi = (PBITMAPINFO) LocalAlloc(LPTR, sizeof(BITMAPINFOHEADER));

    // Initialize the fields in the BITMAPINFO structure.  
    pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); 
    pbmi->bmiHeader.biWidth = dWidth; 
    pbmi->bmiHeader.biHeight = -dHeight; 
    pbmi->bmiHeader.biPlanes = 1; 
    pbmi->bmiHeader.biBitCount = cClrBits; 
    if (cClrBits < 24) 
        pbmi->bmiHeader.biClrUsed = ColorCnt; 
    pbmi->bmiHeader.biCompression = BI_RGB; // If the bitmap is not compressed, set the BI_RGB flag.
    // Compute the number of bytes in the array of color indices and store the result in biSizeImage.  
    // The width must be DWORD aligned unless the bitmap is RLE compressed. 
    pbmi->bmiHeader.biSizeImage = ((pbmi->bmiHeader.biWidth * cClrBits +31) & ~31) / 8 * pbmi->bmiHeader.biHeight; 
    // Set biClrImportant to 0, indicating that all of the device colors are important.  
     pbmi->bmiHeader.biClrImportant = 0;

    if (cClrBits <= 8) {
        pbmi->bmiHeader.biClrImportant = ColorCnt;
        int bitWise, aClr [16] = { 8, 24, 38, 56, 72, 88, 104, 120, 136, 152, 168, 184, 210, 216, 232, 248 };

        switch(cClrBits) {
        case 8:
            for(int i = 0; i < ColorCnt; i++) {
                pbmi->bmiColors[i].rgbRed = i;
                pbmi->bmiColors[i].rgbGreen = i;
                pbmi->bmiColors[i].rgbBlue = i;
                pbmi->bmiColors[i].rgbReserved = 0;
            }
            break;
        case 4:
            for(int i = 0; i < 15; i++) {
                bitWise = (16 << aClr[i]) | (8 << aClr[i]) | aClr[i];
                pbmi->bmiColors[i].rgbRed = bitWise;
                pbmi->bmiColors[i].rgbGreen = bitWise;
                pbmi->bmiColors[i].rgbBlue = bitWise;
                pbmi->bmiColors[i].rgbReserved = 0;
            }
            break;
        case 1:
            bitWise = (16 << 255) | (8 << 255) | 255;
            pbmi->bmiColors[0].rgbRed = bitWise;
            pbmi->bmiColors[0].rgbGreen = bitWise;
            pbmi->bmiColors[0].rgbBlue = bitWise;
            pbmi->bmiColors[0].rgbReserved = 0;
            break;
        }
    }
    HBITMAP hBitmap = CreateDIBSection(0, pbmi, DIB_RGB_COLORS, (VOID**)&pBits, NULL, 0);
    SelectObject(hDestDC, hBitmap);

    StretchBlt(hDestDC, 0, 0, dWidth, dHeight, hSrcDC, sLeft, sTop, sWidth, sHeight, SRCCOPY); 

    pbmInfo = pbmi;
    return hBitmap;
}
Thanks for your help,

JS

http://forum.autoitbrasil.com/ (AutoIt v3 Brazil!!!)

Somewhere Out ThereJames Ingram

somewh10.png

dropbo10.pngDownload Dropbox - Simplify your life!
Your virtual HD wherever you go, anywhere!

Posted

Oh! I'm sorry I was still having trouble understanding that you wanted to define the structure in C++. I'm glad you got it though. However, if you were already able to write a dll that could be called from AutoIt, I'm surprised you had trouble setting up a structure. Are you still learning C++?

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...