2015-10-01 4 views
0

Il écrit dans mon fichier BITMAP.bmp mais lorsque j'essaie de l'afficher dans Windows Photo Viewer Il est écrit "Windows Photo Viewer ne peut pas ouvrir cette image car le fichier semble être endommagé, endommagé ou est trop grand. " Je sais que je devrais probablement avoir mis les fonctions dans les fichiers d'en-tête, mais je n'ai jamais vraiment plongé assez profondément dans un projet pour vraiment faire des fichiers d'en-tête, donc j'ai oublié comment. Si quelqu'un connaît la limite de taille pour les photos dans Windows Photo Viewer, je serais très reconnaissant. Et j'ai certaines de ces fonctions de MSDN (sans honte). La gestion des erreurs pourrait être mieux mais je n'ai pas errorhandler.h. Je ne suis pas complètement sûr de la façon dont toutes les fonctions fonctionnent parce que, comme je l'ai dit, j'ai utilisé du code de MSDN. Je serais grandement reconnaissant de toute personne qui peut m'aider. :)Enregistrement de problèmes bitmap dans winapi

#include <errorrep.h> 
#include <windows.h> 
#include <iostream> 
using namespace std; 

namespace Globals{ 
    HBITMAP hBitmap; 
    HDC hScreen; 
} 
using namespace Globals; 

void GetScreenShot(void) 
{ 
    int x1, y1, x2, y2, w, h; 
    LPSIZE lpSize; 
    LPVOID lpvBits; 
    // get screen dimensions 
    x1 = GetSystemMetrics(SM_XVIRTUALSCREEN); 
    x2 = GetSystemMetrics(SM_CXVIRTUALSCREEN); 
    y1 = GetSystemMetrics(SM_YVIRTUALSCREEN); 
    y2 = GetSystemMetrics(SM_CYVIRTUALSCREEN); 
    w = x2-x1; 
    h = y2-y1; 

    // copy screen to bitmap 
    hScreen = GetDC(NULL); 
    HDC  hDC  = CreateCompatibleDC(hScreen); 
    hBitmap = CreateCompatibleBitmap(hScreen, w, h); 
    HGDIOBJ old_obj = SelectObject(hDC, hBitmap); 
    BOOL bRet = BitBlt(hDC, 0, 0, w, h, hScreen, x1, y1, SRCCOPY); 
    GetBitmapDimensionEx(hBitmap, lpSize); 
    GetBitmapBits(hBitmap, (LONG)lpSize, lpvBits); 
    // save bitmap to clipboard 
    OpenClipboard(NULL); 
    EmptyClipboard(); 
    SetClipboardData(CF_BITMAP, hBitmap); 
    CloseClipboard(); 
    // clean up 
    SelectObject(hDC, old_obj); 
    /*DeleteDC(hDC); 
    ReleaseDC(NULL, hScreen); 
    DeleteObject(hBitmap);*/ 
} 

PBITMAPINFO CreateBitmapInfoStruct(/*HWND hwnd, */HBITMAP hBmp) 
{ 
    BITMAP bmp; 
    PBITMAPINFO pbmi; 
    WORD cClrBits; 

    // Retrieve the bitmap color format, width, and height. 
    if (!GetObject(hBmp, sizeof(BITMAP), (LPSTR)&bmp)) 
     //errhandler("GetObject", hwnd); 
     cout << "Error: CreateBitmapInfoStruct" << endl; 

    // Convert the color format to a count of bits. 
    cClrBits = (WORD)(bmp.bmPlanes * bmp.bmBitsPixel); 
    if (cClrBits == 1) 
     cClrBits = 1; 
    else if (cClrBits <= 4) 
     cClrBits = 4; 
    else if (cClrBits <= 8) 
     cClrBits = 8; 
    else if (cClrBits <= 16) 
     cClrBits = 16; 
    else if (cClrBits <= 24) 
     cClrBits = 24; 
    else cClrBits = 32; 

    // 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) * (1<< cClrBits)); 

    // 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 = bmp.bmWidth; 
    pbmi->bmiHeader.biHeight = bmp.bmHeight; 
    pbmi->bmiHeader.biPlanes = bmp.bmPlanes; 
    pbmi->bmiHeader.biBitCount = bmp.bmBitsPixel; 
    if (cClrBits < 24) 
     pbmi->bmiHeader.biClrUsed = (1<<cClrBits); 

    // If the bitmap is not compressed, set the BI_RGB flag. 
    pbmi->bmiHeader.biCompression = BI_RGB; 

    // 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; 
    return pbmi; 
} 

void CreateBMPFile(/*HWND hwnd, */LPTSTR pszFile, PBITMAPINFO pbi, 
        HBITMAP hBMP, HDC hDC) 
{ 
    HANDLE hf;     // file handle 
    BITMAPFILEHEADER hdr;  // bitmap file-header 
    PBITMAPINFOHEADER pbih;  // bitmap info-header 
    LPBYTE lpBits;    // memory pointer 
    DWORD dwTotal;    // total count of bytes 
    DWORD cb;     // incremental count of bytes 
    BYTE *hp;     // byte pointer 
    DWORD dwTmp; 

    pbih = (PBITMAPINFOHEADER) pbi; 
    lpBits = (LPBYTE) GlobalAlloc(GMEM_FIXED, pbih->biSizeImage); 

    if (!lpBits) 
     //errhandler("GlobalAlloc", hwnd); 
     cout << "!lpBits" << endl; 
    // Retrieve the color table (RGBQUAD array) and the bits 
    // (array of palette indices) from the DIB. 
    if (!GetDIBits(hDC, hBMP, 0, (WORD) pbih->biHeight, lpBits, pbi, 
     DIB_RGB_COLORS)) 
    { 
     //errhandler("GetDIBits", hwnd); 
     cout << "Error 1" << endl; 
    } 

    // Create the .BMP file. 
    hf = CreateFile(pszFile, 
        GENERIC_READ | GENERIC_WRITE, 
        (DWORD) 0, 
        NULL, 
        CREATE_ALWAYS, 
        FILE_ATTRIBUTE_NORMAL, 
        (HANDLE) NULL); 
    if (hf == INVALID_HANDLE_VALUE) 
     //errhandler("CreateFile", hwnd); 
    hdr.bfType = 0x4d42;  // 0x42 = "B" 0x4d = "M" 
    // Compute the size of the entire file. 
    hdr.bfSize = (DWORD) (sizeof(BITMAPFILEHEADER) + 
       pbih->biSize + pbih->biClrUsed 
       * sizeof(RGBQUAD) + pbih->biSizeImage); 
    hdr.bfReserved1 = 0; 
    hdr.bfReserved2 = 0; 

    // Compute the offset to the array of color indices. 
    hdr.bfOffBits = (DWORD) sizeof(BITMAPFILEHEADER) + 
        pbih->biSize + pbih->biClrUsed 
        * sizeof (RGBQUAD); 

    // Copy the BITMAPFILEHEADER into the .BMP file. 
    if (!WriteFile(hf, (LPVOID) &hdr, sizeof(BITMAPFILEHEADER), 
     (LPDWORD) &dwTmp, NULL)) 
    { 
     //errhandler("WriteFile", hwnd); 
     cout << "!WriteFile" << endl; 
    } 

    // Copy the BITMAPINFOHEADER and RGBQUAD array into the file. 
    if (!WriteFile(hf, (LPVOID) pbih, sizeof(BITMAPINFOHEADER) 
        + pbih->biClrUsed * sizeof (RGBQUAD), 
        (LPDWORD) &dwTmp, (NULL))) 
     //errhandler("WriteFile", hwnd); 
     cout << "!WriteFile" << endl; 

    // Copy the array of color indices into the .BMP file. 
    dwTotal = cb = pbih->biSizeImage; 
    hp = lpBits; 
    if (!WriteFile(hf, (LPSTR) hp, (int) cb, (LPDWORD) &dwTmp,NULL)) 
      //errhandler("WriteFile", hwnd); 
      cout << "if (!WriteFile(hf, (LPSTR) hp, (int) cb, (LPDWORD) &dwTmp,NULL))" << endl; 

    // Close the .BMP file. 
    if (!CloseHandle(hf)) 
      //errhandler("CloseHandle", hwnd); 

    // Free memory. 
    GlobalFree((HGLOBAL)lpBits); 
} 

int main() { 
    cout << "ScreenShot - Takes a screen shot\nScreen shot will be put in your clipboard" 
    "\nThere will be 10 seconds before it takes the screen shot\n" << endl; 
    string input; 
    do 
    { 
     cin >> input; 

     if(input == "ScreenShot") 
     { 
      /*for(int i=1; i<11; i++) 
      { 
       Sleep(1000); 
       cout << i << endl; 
       if(i == 10) 
       { 
        break; 
       } 
      }*/ 
      GetScreenShot(); 
      PBITMAPINFO pbmi = CreateBitmapInfoStruct(hBitmap); 
      CreateBMPFile("C:\\Users\\Owner\\Desktop\\BITMAP.bmp", pbmi, hBitmap, hScreen); 
      cout << "ScreenShot taken!" << endl; 
      cin.ignore(2); 
      Sleep(3000); 
      break; 
     } 
     else 
     { 
      cout << "Invalid command." << endl; 
     } 

    } while(true); 

    return 0; 
} 
+0

Quel est votre objectif? Voulez-vous prendre une capture d'écran et enregistrer dans un fichier? Voulez-vous utiliser 'HBITMAP' et enregistrer dans un fichier? Voulez-vous dessiner et enregistrer dans un fichier? Voulez-vous manipuler des bits, puis les enregistrer dans un fichier? –

+0

Je veux juste prendre une capture d'écran et l'enregistrer dans un fichier. –

+0

peut-être cela aidera http://stackoverflow.com/a/30114983/4603670 –

Répondre

3

Passage des valeurs non initialisées à GetBitmapDimensionEx et GetBitmapBits n'a pas semble bon, donc les supprimer car ils ne semblent pas être utilisés.

void GetScreenShot(void) 
{ 
    int x1, y1, x2, y2, w, h; 
    // get screen dimensions 
    x1 = GetSystemMetrics(SM_XVIRTUALSCREEN); 
    x2 = GetSystemMetrics(SM_CXVIRTUALSCREEN); 
    y1 = GetSystemMetrics(SM_YVIRTUALSCREEN); 
    y2 = GetSystemMetrics(SM_CYVIRTUALSCREEN); 
    w = x2-x1; 
    h = y2-y1; 

    // copy screen to bitmap 
    hScreen = GetDC(NULL); 
    HDC  hDC  = CreateCompatibleDC(hScreen); 
    hBitmap = CreateCompatibleBitmap(hScreen, w, h); 
    HGDIOBJ old_obj = SelectObject(hDC, hBitmap); 
    BOOL bRet = BitBlt(hDC, 0, 0, w, h, hScreen, x1, y1, SRCCOPY); 
    // save bitmap to clipboard 
    OpenClipboard(NULL); 
    EmptyClipboard(); 
    SetClipboardData(CF_BITMAP, hBitmap); 
    CloseClipboard(); 
    // clean up 
    SelectObject(hDC, old_obj); 
    /*DeleteDC(hDC); 
    ReleaseDC(NULL, hScreen); 
    DeleteObject(hBitmap);*/ 
} 

Ensuite, définissez hdr.bfType même si hf != INVALID_HANDLE_VALUE.

changement

if (hf == INVALID_HANDLE_VALUE) 
     //errhandler("CreateFile", hwnd); 
    hdr.bfType = 0x4d42;  // 0x42 = "B" 0x4d = "M" 

à

if (hf == INVALID_HANDLE_VALUE) 
    { 
     //errhandler("CreateFile", hwnd); 
    } 
    hdr.bfType = 0x4d42;  // 0x42 = "B" 0x4d = "M" 

(ajouter des accolades)

En utilisant LPCTSTR au lieu de LPTSTR pour le type de pszFile, ce qui est un argument de CreateBMPFile est également bon pour éviter avertissement du compilateur lorsqu'un littéral de chaîne est passé.

+0

Un type de données incorrect m'a fait me gratter la tête pendant deux heures. Merci beaucoup! XD –