FTP | CCD | Buscar | Trucos | Trabajo | Foros |
|
Registrarse | FAQ | Miembros | Calendario | Guía de estilo | Temas de Hoy |
|
Herramientas | Buscar en Tema | Desplegado |
#1
|
||||
|
||||
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?
|
#2
|
||||
|
||||
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); } |
#3
|
||||
|
||||
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; } Código:
void __fastcall TForm1::Button1Click(TObject *Sender) { Graphics::TBitmap *Bitmap = new Graphics::TBitmap(); Bitmap->Handle = CreateCaptureClientWindow(Handle); Bitmap->SaveToFile("Window.bmp"); delete Bitmap; } |
#4
|
||||
|
||||
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. |
#5
|
||||
|
||||
Aporto mas datos sobre el control este segun lo que me muestra Spy++:
|
|
|
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 |
|