[C con Clase] guardar las imagenes de pantalla

Agustín Cota Reguero clom2002 en yahoo.es
Dom Oct 21 12:33:45 CEST 2007


No se si entiendo muy bien lo que quieres hacer, sobre todo después de ver el codigo pero supongo qu elo uqe quieres es poder guardar lo que sea que tengas en la pantalla en un fichero bmp por ejemplo. Esto es relativamente facil primero te voy a poner dos funciones que necesitaras para poder hacerlo, una para grabar la imagen y otra para racabar la informacion de la estrucctura, son sacadas de la documentacion del api.
   
  
PBITMAPINFO CreateBitmapInfoStruct(HWND hwnd, HBITMAP hBmp)
{ 
    BITMAP bmp; 
    PBITMAPINFO pbmi; 
    WORD    cClrBits; 
      // Retrieve the bitmap color format, width, and height. 
    GetObject(hBmp, sizeof(BITMAP), (LPSTR)&bmp);
      
    // 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 the 24-bit-per-pixel format. 
       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. 
    // For Windows NT, the width must be DWORD aligned unless 
    // the bitmap is RLE compressed. This example shows this. 
    // For Windows 95/98/Me, the width must be WORD 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);
     
    // Retrieve the color table (RGBQUAD array) and the bits 
    // (array of palette indices) from the DIB. 
    GetDIBits(hDC, hBMP, 0, (WORD) pbih->biHeight, lpBits, pbi, 
        DIB_RGB_COLORS); 
    
      // Create the .BMP file. 
    hf = CreateFile(pszFile, 
                   GENERIC_READ | GENERIC_WRITE, 
                   (DWORD) 0, 
                    NULL, 
                   CREATE_ALWAYS, 
                   FILE_ATTRIBUTE_NORMAL, 
                   (HANDLE) NULL); 
    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. 
    WriteFile(hf, (LPVOID) &hdr, sizeof(BITMAPFILEHEADER), 
        (LPDWORD) &dwTmp,  NULL); 
  
      // Copy the BITMAPINFOHEADER and RGBQUAD array into the file. 
    WriteFile(hf, (LPVOID) pbih, sizeof(BITMAPINFOHEADER) 
                  + pbih->biClrUsed * sizeof (RGBQUAD), 
                  (LPDWORD) &dwTmp,  NULL); 
        
      // Copy the array of color indices into the .BMP file. 
    dwTotal = cb = pbih->biSizeImage; 
    hp = lpBits; 
    WriteFile(hf, (LPSTR) hp, (int) cb, (LPDWORD) &dwTmp,NULL);
          
      // Close the .BMP file. 
     CloseHandle(hf); 
      
      // Free memory. 
    GlobalFree((HGLOBAL)lpBits);
}
   
  A continuación has de saber como usarla, te escribo el codigo de una posible lamada a salvar.
   
  case GUARDAR_COMO:
    {
    OPENFILENAME ofn;
    char nombre_archivo[MAX_PATH]="";
      ZeroMemory(&ofn, sizeof(ofn));
      ofn.lStructSize = sizeof(ofn); 
    ofn.hwndOwner = hwnd;
    ofn.lpstrFilter = "Imagenes (*.bmp)\0*.bmp\0Todos los ficheros (*.*)\0*.*\0";
    ofn.nMaxFile = MAX_PATH;
    ofn.Flags = OFN_EXPLORER | OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT;
    ofn.lpstrDefExt = "bmp";
    ofn.lpstrFile = nombre_archivo;
   
    if(GetSaveFileName(&ofn))
    {
     PBITMAPINFO pbi;
     pbi = CreateBitmapInfoStruct(hwnd,hBitmap);
     CreateBMPFile(hwnd,nombre_archivo,pbi,hBitmap,hDcmem);
    }
      }
   
  Espero que esto te sirva de ayuda. La imagen, aunque es algo que parece evidente, que vas a salvare es la que hubiese en hDcmen. Si quieres mas informacoión dímelo y te mando un ejemplo de un programa en el que se salva lo que hay en pantalla.

Francisco Mota <frcostrong en hotmail.com> escribió:
      .hmmessage P  {  margin:0px;  padding:0px  }  body.hmmessage  {  FONT-SIZE: 10pt;  FONT-FAMILY:Tahoma  }    Saludos amigos!!.
 
Veran sigo aprendiendo API y ahora se me ah presentado el siguiente problema.
 
Quiero guardar lo que se muestre en pantalla, estoy juntando varias imagenes y las quiero guardar como una sola, es decir guardar lo que muestra la pantalla como una imagen ya sea bmp o cualquier formato. El codigo que es el que tengo muestra y guarda una sola imagen. Yo lo que quiero es guardar la pantalla completa. Espero sirva de algo el codigo.

#include <windows.h> 
#include <commdlg.h> 
#include <stdlib.h> 
#include <stdio.h> 
#include "viewbmp.h" 

#define UNTITLED "(sin título)" 
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM); 
void DibujaBitmap (HDC hdc, HBITMAP hBitmap, int xInicio, int yInicio); 
void PopFileInitialize (HWND); 
BOOL PopFileOpenDlg    (HWND, PSTR, PSTR); 
BOOL PopFileSaveDlg    (HWND, PSTR, PSTR); 
BOOL PopFileRead       (HINSTANCE, PSTR); 
BOOL PopFileWrite      (HWND, PSTR); 
void DoCaption (HWND hwnd, char *szTitleName); 
void OkMessage (HWND hwnd, char *szMessage, char *szTitleName); 
short AskAboutSave (HWND hwnd, char *szTitleName); 
          // Variables globales 
static char szAppName[] = "ViewBMP"; 
static HWND hDlgModeless; 
static OPENFILENAME ofn; 
static HBITMAP hBitmap = NULL; 
// ************************** Punto de entrada al programa ******* 
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, 
                    PSTR szCmdLine, int iCmdShow) 
{ 
   MSG         msg; 
   HWND        hwnd; 
   HACCEL      hAccel; 
   WNDCLASSEX  wndclass; 
   wndclass.cbSize        = sizeof (wndclass); 
   wndclass.style         = CS_HREDRAW | CS_VREDRAW; 
   wndclass.lpfnWndProc   = WndProc; 
   wndclass.cbClsExtra    = 0; 
   wndclass.cbWndExtra    = 0; 
   wndclass.hInstance     = hInstance; 
   wndclass.hIcon         = LoadIcon (hInstance, szAppName); 
   wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW); 
   wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH); 
   wndclass.lpszMenuName  = szAppName; 
   wndclass.lpszClassName = szAppName; 
   wndclass.hIconSm       = LoadIcon (NULL, IDI_APPLICATION); 
   RegisterClassEx (&wndclass); 
   hwnd = CreateWindow (szAppName, NULL, 
                          WS_OVERLAPPEDWINDOW, 
                          CW_USEDEFAULT, CW_USEDEFAULT, 
                          CW_USEDEFAULT, CW_USEDEFAULT, 
                          NULL, NULL, hInstance, szCmdLine); 
   ShowWindow (hwnd, iCmdShow); 
   UpdateWindow (hwnd); 
   hAccel = LoadAccelerators (hInstance, szAppName); 
   while (GetMessage (&msg, NULL, 0, 0)) { 
      if (hDlgModeless == NULL || !IsDialogMessage (hDlgModeless, &msg)) { 
         if (!TranslateAccelerator (hwnd, hAccel, &msg)) { 
            TranslateMessage (&msg); 
            DispatchMessage (&msg); 
         } 
      } 
   } 
   return msg.wParam; 
} 
// ************************** Procedimiento de ventana ******* 
LRESULT CALLBACK WndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam) 
{ 
    static BOOL      bNeedSave = FALSE; 
    static char      szFileName[_MAX_PATH]; 
    static char      szTitleName[_MAX_FNAME + _MAX_EXT]; 
    static HINSTANCE hInst; 
   HDC hDC; 
   PAINTSTRUCT ps; 
    switch (iMsg) { 
      case WM_CREATE : 
         hInst = ((LPCREATESTRUCT) lParam) -> hInstance; 
                         // Inicializar cuadro de diálogo común 
         PopFileInitialize (hwnd); 
                         // Procesar línea de comandos 
         lstrcpy (szFileName, (PSTR) (((LPCREATESTRUCT) lParam)->lpCreateParams)); 
         if (strlen (szFileName) > 0) { 
            GetFileTitle (szFileName, szTitleName, sizeof (szTitleName)); 
            if (!PopFileRead (hInst, szFileName)) 
               OkMessage (hwnd, "No se puede leer el archivo %s.", 
                                          szTitleName); 
            } 
            DoCaption (hwnd, szTitleName); 
            return 0; 
      case WM_COMMAND : 
         switch (LOWORD (wParam)) { 
                              // Mensajes del menú Archivo 
            case IDM_OPEN : 
               if (bNeedSave && IDCANCEL == AskAboutSave (hwnd, szTitleName)) 
                  return 0; 
                        if (PopFileOpenDlg (hwnd, szFileName, szTitleName)) { 
                     if (!PopFileRead (hInst, szFileName)) { 
                        OkMessage (hwnd, "No se puede leer el archivo %s.", 
                                                    szTitleName); 
                        szFileName[0]  = '\0'; 
                        szTitleName[0] = '\0'; 
                     } else 
                        InvalidateRect (hwnd, NULL, FALSE); 
                  } 
                  DoCaption (hwnd, szTitleName); 
                  bNeedSave = FALSE; 
                  return 0; 
            case IDM_SAVE : 
               if (szFileName[0]) { 
                  if (PopFileWrite (hwnd, szFileName)) { 
                     bNeedSave = FALSE; 
                     return 1; 
                  } else 
                     OkMessage (hwnd, "No se puede escribir el archivo %s", 
                                                    szTitleName); 
                  return 0; 
               } 
                                                  // sigue proceso 
            case IDM_SAVEAS : 
               if (PopFileSaveDlg (hwnd, szFileName, szTitleName)) { 
                  DoCaption (hwnd, szTitleName); 
                  if (PopFileWrite (hwnd, szFileName)) { 
                     bNeedSave = FALSE; 
                     return 1; 
                  } else 
                     OkMessage (hwnd, "No se puede escribir el archivo %s", 
                                                    szTitleName); 
               } 
               return 0; 
            case IDM_EXIT : 
               SendMessage (hwnd, WM_CLOSE, 0, 0); 
               return 0; 
         } 
         break; 
      case WM_PAINT: 
         hDC = BeginPaint (hwnd, &ps); 
         DibujaBitmap (hDC, hBitmap, 0, 0); 
         EndPaint (hwnd, &ps); 
         return 0; 
      case WM_CLOSE : 
         if (!bNeedSave || IDCANCEL != AskAboutSave (hwnd, szTitleName)) 
            DestroyWindow (hwnd); 
         return 0; 
      case WM_QUERYENDSESSION : 
         if (!bNeedSave || IDCANCEL != AskAboutSave (hwnd, szTitleName)) 
            return 1; 
         return 0; 
      case WM_DESTROY : 
         if (hBitmap != NULL) 
            DeleteObject (hBitmap); 
         PostQuitMessage (0); 
         return 0; 
   } 
   return DefWindowProc (hwnd, iMsg, wParam, lParam); 
} 
// ************************** función para dibujar bitmaps ****** 
void DibujaBitmap (HDC hdc, HBITMAP hBitmap, int xInicio, int yInicio) 
{ 
   BITMAP bm; 
   HDC      hdcMem; 
   DWORD   dwSize; 
   POINT   ptSize, ptOrg; 
   hdcMem = CreateCompatibleDC (hdc); 
   SelectObject (hdcMem, hBitmap); 
   SetMapMode (hdcMem, GetMapMode (hdc)); 
   GetObject (hBitmap, sizeof (BITMAP), (LPVOID)&bm); 
   ptSize.x = bm.bmWidth; 
   ptSize.y = bm.bmHeight; 
   DPtoLP (hdc, &ptSize, 1); 
   ptOrg.x = 0; 
   ptOrg.y = 0; 
   DPtoLP (hdcMem, &ptOrg, 1); 
   BitBlt (hdc, xInicio, yInicio, ptSize.x, ptSize.y, hdcMem, ptOrg.x, ptOrg.y, SRCCOPY); 
   DeleteObject (hdcMem); 
} 
// ***** funciones para manejar los diálogos abrir/guardar archivo *** 
void PopFileInitialize (HWND hwnd) 
{ 
   static char szFilter[] = "Archivos de texto (*.BMP)\0*.bmp\0";
                             // "Todos los archivos (*.*)\0*.*\0\0"; 
   ofn.lStructSize       = sizeof (OPENFILENAME); 
   ofn.hwndOwner         = hwnd; 
   ofn.hInstance         = NULL; 
   ofn.lpstrFilter       = szFilter; 
    ofn.lpstrCustomFilter = NULL; 
    ofn.nMaxCustFilter    = 0; 
    ofn.nFilterIndex      = 0; 
    ofn.lpstrFile         = NULL;          // Definido en funciones Open y Close 
    ofn.nMaxFile          = _MAX_PATH; 
    ofn.lpstrFileTitle    = NULL;          // Definido en funciones Open y Close 
    ofn.nMaxFileTitle     = _MAX_FNAME + _MAX_EXT; 
    ofn.lpstrInitialDir   = NULL; 
    ofn.lpstrTitle        = NULL; 
    ofn.Flags             = 0;             // Definido en funciones Open y Close 
    ofn.nFileOffset       = 0; 
    ofn.nFileExtension    = 0; 
    ofn.lpstrDefExt       = "txt"; 
    ofn.lCustData         = 0L; 
    ofn.lpfnHook          = NULL; 
    ofn.lpTemplateName    = NULL; 
} 
BOOL PopFileOpenDlg (HWND hwnd, PSTR pstrFileName, PSTR pstrTitleName) 
{ 
    ofn.hwndOwner         = hwnd; 
    ofn.lpstrFile         = pstrFileName; 
    ofn.lpstrFileTitle    = pstrTitleName; 
    ofn.Flags             = OFN_HIDEREADONLY | OFN_CREATEPROMPT; 
    return GetOpenFileName (&ofn); 
} 
BOOL PopFileSaveDlg (HWND hwnd, PSTR pstrFileName, PSTR pstrTitleName) 
{ 
    ofn.hwndOwner         = hwnd; 
    ofn.lpstrFile         = pstrFileName; 
    ofn.lpstrFileTitle    = pstrTitleName; 
    ofn.Flags             = OFN_OVERWRITEPROMPT; 
   return GetSaveFileName (&ofn); 
} 
static long PopFileLength (FILE *file) 
{ 
    int iCurrentPos, iFileLength; 
    iCurrentPos = ftell (file); 
    fseek (file, 0, SEEK_END); 
    iFileLength = ftell (file); 
    fseek (file, iCurrentPos, SEEK_SET); 
    return iFileLength; 
} 
BOOL PopFileRead (HINSTANCE hInst, PSTR pstrFileName) 
{ 
   if (hBitmap != NULL) 
      DeleteObject (hBitmap); 
   hBitmap = (HBITMAP)LoadImage(hInst, pstrFileName, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE); 
    return hBitmap != NULL; 
} 
BOOL PopFileWrite (HWND hwnd, PSTR pstrFileName) 
{ 
    FILE  *file; 
    int    iLength; 
    PSTR   pstrBuffer; 
    if (NULL == (file = fopen (pstrFileName, "wb"))) 
      return FALSE; 
    iLength = GetWindowTextLength (hwnd); 
    if (NULL == (pstrBuffer = (PSTR) malloc (iLength + 1))) { 
      fclose (file); 
      return FALSE; 
   } 
    GetWindowText (hwnd, pstrBuffer, iLength + 1); 
    if (iLength != (int) fwrite (pstrBuffer, 1, iLength, file)) { 
      fclose (file); 
      free (pstrBuffer); 
      return FALSE; 
   } 
    fclose (file); 
    free (pstrBuffer); 
 
    return TRUE; 
} 
// ************************** funciones auxiliares **************** 
void DoCaption (HWND hwnd, char *szTitleName) 
{ 
   char szCaption[64 + _MAX_FNAME + _MAX_EXT]; 
   wsprintf (szCaption, "%s - %s", szAppName, 
               szTitleName[0] ? szTitleName : UNTITLED); 
   SetWindowText (hwnd, szCaption); 
} 
void OkMessage (HWND hwnd, char *szMessage, char *szTitleName) 
{ 
   char szBuffer[64 + _MAX_FNAME + _MAX_EXT]; 
   wsprintf (szBuffer, szMessage, szTitleName[0] ? szTitleName : UNTITLED); 
   MessageBox (hwnd, szBuffer, szAppName, MB_OK | MB_ICONEXCLAMATION); 
} 
short AskAboutSave (HWND hwnd, char *szTitleName) 
{ 
   char szBuffer[64 + _MAX_FNAME + _MAX_EXT]; 
   int  iReturn; 
   wsprintf (szBuffer, "¿Guardar cambios actuales en %s?", 
               szTitleName[0] ? szTitleName : UNTITLED); 
   iReturn = MessageBox (hwnd, szBuffer, szAppName, 
                           MB_YESNOCANCEL | MB_ICONQUESTION); 
   if (iReturn == IDYES) 
      if (!SendMessage (hwnd, WM_COMMAND, IDM_SAVE, 0L)) 
         iReturn = IDCANCEL; 
   return iReturn; 
} 

   
  
---------------------------------
  Express yourself instantly with MSN Messenger! MSN Messenger _______________________________________________
Lista de correo Cconclase Cconclase en listas.conclase.net
http://listas.conclase.net/mailman/listinfo/cconclase_listas.conclase.net
Bajas: http://listas.conclase.net/index.php?gid=2&mnu=FAQ

       
---------------------------------

Sé un Mejor Amante del Cine
¿Quieres saber cómo? ¡Deja que otras personas te ayuden!.
------------ próxima parte ------------
Se ha borrado un adjunto en formato HTML...
URL: <http://listas.conclase.net/pipermail/cconclase_listas.conclase.net/attachments/20071021/944054cb/attachment.html>


Más información sobre la lista de distribución Cconclase