Win32 Erstellen Bitmap von einem Device Context eine Datei und/oder BLOB -

Ich würde gerne den Rahmen meines Fensters in ein bitmap. Ich benutzen das Fenster zu ziehen basic-Zeilen mit touch. Das problem, dass ich habe ist meine bitmap ist schwarz. Denen ist es wahrscheinlich aufgrund der Tatsache, dass ich nicht greifen, das Gerät Kontext richtig oder mache etwas anderes falsch.

Die Funktionen CreateBitmapInfoStruct und CreateBMPFile sind aus das MSDN-Beispiel.

Beachten Sie auch, dass g_hWnd ist eine Globale variable, die das handle des Fensters, für das ich möchte das Bild speichern.

Mein end-Ziel ist es, in der Lage sein, speichern Sie die bitmap in eine mysql-Feld (BLOB), die ich habe. Dies ist, was mein ursprüngliches problem war. Wie auch immer, ich begann, indem Sie zuerst versuchen, um eine BMP-Datei.

Habe ich danach gesucht, hier und in anderen Orten. Die beste Lösung, die ich gefunden wurde empfohlen, hier folgende das MSDN-Beispiel. Es ist jedoch nicht arbeiten.

Jede Hilfe für dieses spezifische problem und/oder schriftlich an die bitmap in ein blob in der mysql-Tabelle, wird sehr geschätzt.

Hier ist mein code:

HDC hDC = GetDC(g_hWnd); 

LPRECT rect = (LPRECT)malloc(sizeof(RECT)); 
GetWindowRect(g_hWnd,rect); 
int h = rect->right - rect->left;
int w = rect->bottom - rect->top; 
LPRECT rect = (LPRECT)malloc(sizeof(RECT)); 
GetWindowRect(g_hWnd,rect); 
HBITMAP hBmp = CreateCompatibleBitmap(hDC,w,h); 
PBITMAPINFO pbmi;
pbmi = CreateBitmapInfoStruct(g_hWnd,hBmp); 

CreateBMPFile(g_hWnd, TEXT("c:\\TEMPO\\TestG2.bmp"), pbmi, 
              hBmp, hDC) ;

ReleaseDC(g_hWnd,hDC); 

DeleteObject(hBmp); 
DeleteObject(pbmi); 
if (rect != nullptr)
    free(rect); 

EDIT:

Die eigentliche Antwort für die Erfassung der Bildschirm (getDC) ist zu ändern das Beispiel in der MSDN.

Habe ich geändert, das Beispiel hier (entfernen Sie die stretch) Hinweis, dass noch mit dem "goto", die ich entfernen.

Eine Anmerkung zu SPRINGEN... Und ich benutze es nicht, ich finde nicht, dass es ein problem entweder. Ich denke, zu viel wurde über die GOTO-Anweisung... ist wie wenn in der Versammlung, würden wir nicht springen (SPRINGT)

Hier ist der code:

void saveBitmap()
{
    HDC hdcScreen;
    HDC hdcWindow;
    HDC hdcMemDC = NULL;
    HBITMAP hbmScreen = NULL;
    BITMAP bmpScreen;

    //Retrieve the handle to a display device context for the client 
    //area of the window. 
    hdcScreen = GetDC(NULL);
    hdcWindow = GetDC(g_hWnd);

    //Create a compatible DC which is used in a BitBlt from the window DC
    hdcMemDC = CreateCompatibleDC(hdcWindow); 
    if(!hdcMemDC)
    {
    goto done;
    }
    RECT rcClient;
    GetClientRect(g_hWnd, &rcClient);
    hbmScreen = CreateCompatibleBitmap(hdcWindow, rcClient.right-rcClient.left, 
                                       rcClient.bottom-rcClient.top);
    if(!hbmScreen)
    {
        goto done;
    }

    SelectObject(hdcMemDC,hbmScreen);

    if(!BitBlt(hdcMemDC, 
               0,0, 
               rcClient.right-rcClient.left, rcClient.bottom-rcClient.top, 
               hdcWindow, 
               0,0,
               SRCCOPY))
    {
        goto done;
    }
GetObject(hbmScreen,sizeof(BITMAP),&bmpScreen);

    BITMAPFILEHEADER   bmfHeader;    
    BITMAPINFOHEADER   bi;

    bi.biSize = sizeof(BITMAPINFOHEADER);    
    bi.biWidth = bmpScreen.bmWidth;    
    bi.biHeight = bmpScreen.bmHeight;  
    bi.biPlanes = 1;    
    bi.biBitCount = 32;    
    bi.biCompression = BI_RGB;    
    bi.biSizeImage = 0;  
    bi.biXPelsPerMeter = 0;    
    bi.biYPelsPerMeter = 0;    
    bi.biClrUsed = 0;    
    bi.biClrImportant = 0;

    DWORD dwBmpSize = ((bmpScreen.bmWidth * bi.biBitCount + 31) / 32) * 4 * 
                      bmpScreen.bmHeight;

    //Starting with 32-bit Windows, GlobalAlloc and LocalAlloc are implemented as wrapper functions that 
    //call HeapAlloc using a handle to the process's default heap. Therefore, GlobalAlloc and LocalAlloc 
    //have greater overhead than HeapAlloc.
    HANDLE hDIB = GlobalAlloc(GHND,dwBmpSize); 
    char *lpbitmap = (char *)GlobalLock(hDIB);    

    //Gets the "bits" from the bitmap and copies them into a buffer 
    //which is pointed to by lpbitmap.
    GetDIBits(hdcWindow, hbmScreen, 0,
              (UINT)bmpScreen.bmHeight,
              lpbitmap,
              (BITMAPINFO *)&bi, DIB_RGB_COLORS);

    //A file is created, this is where we will save the screen capture.
    HANDLE hFile = CreateFile(L"c:\\tempo\\captureqwsx.bmp",
                              GENERIC_WRITE,
                              0,
                              NULL,
                              CREATE_ALWAYS,
                              FILE_ATTRIBUTE_NORMAL, NULL);   

    //Add the size of the headers to the size of the bitmap to get the total file size
    DWORD dwSizeofDIB = dwBmpSize + sizeof(BITMAPFILEHEADER) + 
                        sizeof(BITMAPINFOHEADER);

    //Offset to where the actual bitmap bits start.
    bmfHeader.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + 
                          (DWORD)sizeof(BITMAPINFOHEADER); 

    //Size of the file
    bmfHeader.bfSize = dwSizeofDIB; 

    //bfType must always be BM for Bitmaps
    bmfHeader.bfType = 0x4D42; //BM   

    DWORD dwBytesWritten = 0;
    WriteFile(hFile, (LPSTR)&bmfHeader, sizeof(BITMAPFILEHEADER), &dwBytesWritten,  NULL);
    WriteFile(hFile, (LPSTR)&bi, sizeof(BITMAPINFOHEADER), &dwBytesWritten, NULL);
    WriteFile(hFile, (LPSTR)lpbitmap, dwBmpSize, &dwBytesWritten, NULL);

    //Unlock and Free the DIB from the heap
    GlobalUnlock(hDIB);    
    GlobalFree(hDIB);

    //Close the handle for the file that was created
    CloseHandle(hFile);

    //Clean up
done:
    DeleteObject(hbmScreen);
    DeleteObject(hdcMemDC);
    ReleaseDC(NULL,hdcScreen);
    ReleaseDC(g_hWnd,hdcWindow);
}
Ich glaube, ich habe zu zeichnen das Gerät Kontext, wenn ich es mache. Dasselbe wie mache ich es unter WM_PAINT. Ich werde nicht in der Lage sein zu überprüfen, bis Dienstag, aber ich habe das Gefühl das ist. Zur gleichen Zeit, ich fühle, dass, Wenn der Inhalt gezeichnet wird, in den Fenstern, es muss einen direkten Weg, um es.
if (rect != nullptr) <- was ist nullptr ? Ist, dass eine lokale var? Oder ist dies ein Anzeichen dafür, dass Sie etwas zu tun mit managed C++? Auch, du bist deklarieren rect zweimal führen würde zu einem compiler-Fehler. Ich würde raten, nicht die Schaffung einer LPRECT mit malloc, stattdessen deklarieren Sie eine lokale RECT auf dem stack und pass &rect.
nullptr ist Teil von c++ 11, die einige Werke in vs 2010. Kein verwalteter code oj
Die lprect deklariert ist doppelt, weil der eine Kopie paste miskake.
AH ja, natürlich. C++11. My bad, danke für die Klarstellung.

InformationsquelleAutor Blues76 | 2012-07-29

Schreibe einen Kommentar