Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Otros entornos y lenguajes > C++ Builder
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 05-06-2013
Avatar de aguml
aguml aguml is offline
Miembro
 
Registrado: may 2013
Posts: 885
Poder: 11
aguml Va por buen camino
Obtener contenido AfxOleControl42

Pues estoy haciendo una aplicacion la cual busca la ventana de otra aplicacion la cual tiene un AfxOleControl42 y dentro tenemos una serie de objetos (no se bien que son lo que hay dentro pero puedo modificar tanto los textos como dimensiones). Una vez encontrada la ventana, con EnumChildWindows busco el AfxOleControl42 para obtener un hwnd. Ahora bien, segun me comentaron para obtener su contenido tendria que lidiar con funciones como GetDC, GetObject, SetObject, CreateCompatibleDC, GetWindowDC,... La idea es obtener un bitmap del contenido de dicho componente pero no doy con la forma de hacerlo. ¿Me podeis ayudar a solucionarlo?
Responder Con Cita
  #2  
Antiguo 06-06-2013
Avatar de aguml
aguml aguml is offline
Miembro
 
Registrado: may 2013
Posts: 885
Poder: 11
aguml Va por buen camino
Pues siguiendo el modo en que hace en la MSDN donde se capturaba toda la pantalla lo he modificado para que capture el contenido de un componente pero lo que realmente hace es capturar el tamaño del componente independientemente de lo que haya, o sea, si encima de la ventana que tiene el componente hay mas ventanas pues captura el rectangulo del tamaño del componente y captura todo lo que haya en ese area incluido trozos de ventanas y todo. Ademas lo que hace este codigo es redimensionar la imagen al tamaño de destino y yo no quiero redimensionar la imagen sino que me gustaria poder capturarla tal cual y luego poder meterla en un TImage que está dentro de un TScrollBox. Os adjunto el codigo del proyecto.
A ver si podeis ayudarme que ando muy perdido en esto y lo necesito para el tema del loader.
Otro detalle, he colocado un Timage en el form de mi aplicacion y al verlo en WinExplorer aparece el boton pero no aparece el TImage ¿como puede ser eso? ¿como puedo obtener entonces el hwnd del TImage sin saber su clase?

Código:
//--------------------------------------------------------------------------- 
 
#include <vcl.h> 
#pragma hdrstop 
 
#include "Unit1.h" 
//--------------------------------------------------------------------------- 
#pragma package(smart_init) 
#pragma resource "*.dfm" 
TForm1 *Form1; 
 
void done(HBITMAP hbmScreen, HDC hdcMemDC, HDC hdcScreen, HWND hWnd, HDC hdcWindow); 
int CaptureAnImage(HWND hWnd, HWND MyBitmap); 
//-------------------------------------------------------------------------- 
 
BOOL CALLBACK EnumChildProc(HWND hwnd, LPARAM lParam) 
{ 
 
        char clase[256]; 
 
        //memset(clase,0, sizeof(clase)); 
        GetClassName(hwnd, clase, sizeof(clase)); 
        if(strcmp(clase, "AfxOleControl42") == 0) 
        { 
                HWND MyVentana = FindWindow(NULL, "Form1"); 
 
                int retval = CaptureAnImage(hwnd, MyVentana); 
                return FALSE; 
        } 
        return TRUE; 
} 
 
//--------------------------------------------------------------------------- 
__fastcall TForm1::TForm1(TComponent* Owner) 
        : TForm(Owner) 
{ 
} 
//--------------------------------------------------------------------------- 
 
void __fastcall TForm1::Button1Click(TObject *Sender) 
{ 
        HWND hwnd; 
 
        hwnd = FindWindow("ThunderRT6FormDC", "Visustin Editor"); 
 
        if(!hwnd) 
                MessageBox(Application->Handle,"No se encuentra abierto el editor de Visustin.", "Error", MB_OK | MB_APPLMODAL | MB_ICONERROR); 
        else 
                EnumChildWindows(hwnd, (WNDENUMPROC)EnumChildProc, 0); 
} 
//--------------------------------------------------------------------------- 
 
int CaptureAnImage(HWND hWnd, HWND MyBitmap) 
{ 
    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(hWnd); 
    hdcWindow = GetDC(MyBitmap); 
 
    // Create a compatible DC which is used in a BitBlt from the window DC 
    hdcMemDC = CreateCompatibleDC(hdcWindow); 
 
    if(!hdcMemDC) 
    { 
        MessageBox(hWnd, "CreateCompatibleDC has failed", "Failed", MB_OK); 
        done(hbmScreen, hdcMemDC, hdcScreen, hWnd, hdcWindow); 
        return 1; 
    } 
 
    // Get the client area for size calculation 
    RECT rcClient; 
    GetClientRect(hWnd, &rcClient); 
 
    //This is the best stretch mode 
    SetStretchBltMode(hdcWindow,HALFTONE); 
 
    //The source DC is the entire screen and the destination DC is the current window (HWND) 
    if(!StretchBlt(hdcWindow,  
               0,0,  
               rcClient.right, rcClient.bottom,  
               hdcScreen,  
               0,0, 
               GetSystemMetrics (SM_CXSCREEN), 
               GetSystemMetrics (SM_CYSCREEN), 
               SRCCOPY)) 
    { 
        MessageBox(hWnd, "StretchBlt has failed", "Failed", MB_OK); 
        done(hbmScreen, hdcMemDC, hdcScreen, hWnd, hdcWindow); 
        return 1; 
    } 
     
    // Create a compatible bitmap from the Window DC 
    hbmScreen = CreateCompatibleBitmap(hdcWindow, rcClient.right-rcClient.left, rcClient.bottom-rcClient.top); 
     
    if(!hbmScreen) 
    { 
        MessageBox(hWnd, "CreateCompatibleBitmap Failed", "Failed", MB_OK); 
        done(hbmScreen, hdcMemDC, hdcScreen, hWnd, hdcWindow); 
        return 1; 
    } 
 
    // Select the compatible bitmap into the compatible memory DC. 
    SelectObject(hdcMemDC,hbmScreen); 
     
    // Bit block transfer into our compatible memory DC. 
    if(!BitBlt(hdcMemDC,  
               0,0,  
               rcClient.right-rcClient.left, rcClient.bottom-rcClient.top,  
               hdcWindow,  
               0,0, 
               SRCCOPY)) 
    { 
        MessageBox(hWnd, "BitBlt has failed", "Failed", MB_OK); 
        done(hbmScreen, hdcMemDC, hdcScreen, hWnd, hdcWindow); 
        return 1; 
    } 
 
    // Get the BITMAP from the HBITMAP 
    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("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); 
 
    done(hbmScreen, hdcMemDC, hdcScreen, hWnd, hdcWindow); 
 
    return 0; 
} 
 
void done(HBITMAP hbmScreen, HDC hdcMemDC, HDC hdcScreen, HWND hWnd, HDC hdcWindow) 
{ 
        //Clean up 
    DeleteObject(hbmScreen); 
    DeleteObject(hdcMemDC); 
    ReleaseDC(NULL,hdcScreen); 
    ReleaseDC(hWnd,hdcWindow); 
}
Responder Con Cita
  #3  
Antiguo 06-06-2013
Avatar de escafandra
[escafandra] escafandra is offline
Miembro Premium
 
Registrado: nov 2007
Posts: 2.197
Poder: 20
escafandra Tiene un aura espectacularescafandra Tiene un aura espectacular
Te escribo una función con la que capturas el área cliente de una ventana conociendo su Handle:

Código:
HBITMAP CreateCaptureClientWindow(HWND hWnd)
{
  RECT Rect;
  HDC hScreenDC, hDC;
  HBITMAP oldbmp, Result;

  GetClientRect(hWnd, &Rect);
  hScreenDC = GetDC(hWnd);
  hDC = CreateCompatibleDC(0);
  Result = CreateCompatibleBitmap(hScreenDC, Rect.right, Rect.bottom);
  oldbmp = SelectObject(hDC, Result);
  BitBlt(hDC, 0, 0, Rect.right, Rect.bottom, hScreenDC, 0, 0, SRCCOPY);
  ReleaseDC(hWnd, hScreenDC);
  SelectObject(hDC, oldbmp);
  DeleteObject(hDC);
  return Result;
}
Ejemplo de uso:
Código:
void __fastcall TForm1::Button1Click(TObject *Sender)
{
  Graphics::TBitmap *Bitmap = new Graphics::TBitmap();
  Bitmap->Handle = CreateCaptureClientWindow(Handle);
  Bitmap->SaveToFile("Window.bmp");
  delete Bitmap;
}
Saludos
Responder Con Cita
  #4  
Antiguo 07-06-2013
Avatar de aguml
aguml aguml is offline
Miembro
 
Registrado: may 2013
Posts: 885
Poder: 11
aguml Va por buen camino
gracias escafandra pero con tu codigo tengo dos problemas que son los mismos que tenia con el que yo puse, eso si, tu codigo es mucho mas corto jejeje.
Vamos con los problemas:

1.Solo me captura la parte visible, o sea, la ventana tiene scrolls y moviendo los scrolls hay mas imagen así que solo obtengo un trozo del dibujo.
2.La captura es del area del cliente (solo de la parte visible) y me captura todo lo que haya por medio como ventanas de otras aplicaciones, etc.

Te pongo 2 imagenes, una capturada con tu codigo y la otra capturada con el boton de impr pant y haciendo el montaje completo con gimp.
Con tu codigo:



Tamaño real:



¿Veis la diferencia?
He mirado la aplicacion con Win Explorer y no existe ningun ScrollBox, solo es el AfxOleControl42. Es una aplicacion en Visual Basic.
Responder Con Cita
  #5  
Antiguo 07-06-2013
Avatar de aguml
aguml aguml is offline
Miembro
 
Registrado: may 2013
Posts: 885
Poder: 11
aguml Va por buen camino
Aporto mas datos sobre el control este segun lo que me muestra Spy++:
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
email yahoo, no muestra contenido..muestra todo menos contenido. sakuragi Linux 5 29-02-2008 18:11:27
Contenido de DLL MaMu Varios 1 04-09-2006 23:52:45
Obtener el contenido de celdas jessie Servers 1 29-04-2005 16:06:45
Obtener el Contenido de una unidad (cd o hd), es posible? Essato API de Windows 3 22-04-2005 17:10:43
Contenido de un ComboBox Ricsato Varios 6 15-09-2004 13:31:56


La franja horaria es GMT +2. Ahora son las 00:06:31.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi