Resultados 1 al 7 de 7

Tema: DLL que crea un pantallazo

  1. #1
      Administrador
    Avatar de Kuk

    Registrado
    enero de 2015
    Ubicación
    Madrid
    Edad
    39
    Mensajes
    2,286
    Última visita
    Ayer a las 18:48

    Agradecimientos
     
    Recibidos
    1,036
    Enviados
    888

    Citaciones y menciones
     
    Mentioned
    102 Post(s)
    Tagged
    0 Thread(s)
    Quoted
    31 Post(s)
    Poder de Reputación
    10

    Foto DLL que crea un pantallazo

    @Adrianeloy, @Dasije, aquí está el fuente:

    CPP Código:
    1. #include <windows.h>
    2. #include <gdiplus.h>
    3. using namespace Gdiplus;
    4.  
    5. #define DllExport __declspec( dllexport )
    6.  
    7. extern "C" { // Undecorate
    8.  
    9. int GetEncoderClsid(const WCHAR* format, CLSID* pClsid)
    10. {
    11.    UINT  num = 0;          // number of image encoders
    12.    UINT  size = 0;         // size of the image encoder array in bytes
    13.  
    14.    ImageCodecInfo* pImageCodecInfo = NULL;
    15.  
    16.    GetImageEncodersSize(&num, &size);
    17.    if(size == 0)
    18.       return -1;  // Failure
    19.  
    20.    pImageCodecInfo = (ImageCodecInfo*)(malloc(size));
    21.    if(pImageCodecInfo == NULL)
    22.       return -1;  // Failure
    23.  
    24.    GetImageEncoders(num, size, pImageCodecInfo);
    25.  
    26.    for(UINT j = 0; j < num; ++j)
    27.    {
    28.       if( wcscmp(pImageCodecInfo[j].MimeType, format) == 0 )
    29.       {
    30.          *pClsid = pImageCodecInfo[j].Clsid;
    31.          free(pImageCodecInfo);
    32.          return j;  // Success
    33.       }
    34.    }
    35.    free(pImageCodecInfo);
    36.    return -1;  // Failure
    37. }
    38.  
    39. DllExport int HazPantallazo(const char* SavePath)
    40. {
    41.     GdiplusStartupInput gdiplusStartupInput;
    42.     ULONG_PTR gdiplusToken;
    43.     GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
    44.  
    45. // get the device context of the screen
    46. HDC hScreenDC = CreateDC("DISPLAY", NULL, NULL, NULL);    
    47. // and a device context to put it in
    48. HDC hMemoryDC = CreateCompatibleDC(hScreenDC);
    49.  
    50. int width = GetDeviceCaps(hScreenDC, HORZRES);
    51. int height = GetDeviceCaps(hScreenDC, VERTRES);
    52.  
    53. // maybe worth checking these are positive values
    54. HBITMAP hBitmap = CreateCompatibleBitmap(hScreenDC, width, height);
    55.  
    56. // get a new bitmap
    57. HBITMAP hOldBitmap = SelectObject(hMemoryDC, (HGDIOBJ)hBitmap);
    58.  
    59. BitBlt(hMemoryDC, 0, 0, width, height, hScreenDC, 0, 0, SRCCOPY);
    60. hBitmap = SelectObject(hMemoryDC, (HGDIOBJ)hOldBitmap);
    61.    
    62.     Bitmap *image = new Bitmap(hBitmap, NULL);
    63.    
    64.     CLSID myClsId;
    65.     int retVal = GetEncoderClsid(L"image/jpg", &myClsId);
    66.    
    67. wchar_t  PATH[512];    
    68. const wchar_t* WSavePath = &PATH[0];    
    69.    
    70. mbstowcs(PATH, SavePath, 512);
    71.    
    72.     image->Save(WSavePath, &myClsId, NULL);
    73.     delete image;
    74.  
    75.     GdiplusShutdown(gdiplusToken);    
    76.     // clean up
    77. DeleteDC(hMemoryDC);
    78. DeleteDC(hScreenDC);
    79.  
    80.     return 0;
    81. }
    82.  
    83. } // Undecorate

    Según he leído, se puede indicar la calidad (nivel de compresión) en el 3-er parámetro en la invocación del método save (donde va el NULL) :

    CPP Código:
    1. image->Save(WSavePath, &myClsId, NULL);

    Pero no sé por qué, no me compila en DevC++ con la estructura EncoderParameter.

    @Adrianeloy, el formato depende de lo que tú indiques. puede ser:
    CPP Código:
    1. int retVal = GetEncoderClsid(L"image/jpg", &myClsId);
    2. int retVal = GetEncoderClsid(L"image/bmp", &myClsId);
    3. int retVal = GetEncoderClsid(L"image/png", &myClsId);

    Lo he modificado a JPG porque el BMP por defecto pesa 6 megas cada pantallazo

    0 Not allowed!
    ¿Te han ayudado? NO TE OLVIDES de darle al botón
    ¿Quieres dirigirte a alguien en tu post? Notifícale con una mención, tienes 2 opciones:
    1. Haciendo clic en el icono al lado de su nick
    2. Haciendo clic en el botón en el editor y escribiendo su nick.

  2. #2
      Forero
    Avatar de Dasije

    Registrado
    noviembre de 2015
    Ubicación
    Jerez De La Frontera (cádiz)
    Mensajes
    182
    Última visita
    06.03.2022

    Agradecimientos
     
    Recibidos
    79
    Enviados
    1

    Citaciones y menciones
     
    Mentioned
    5 Post(s)
    Tagged
    0 Thread(s)
    Quoted
    0 Post(s)
    Poder de Reputación
    16

    Predeterminado

    En las rutinas de C++ que tengo realizadas, en su momento leí en los manuales de NetCOBOL de como llamar funciones, y así debes hacerlo para que te envíe o reciba parámetros con un CALL directamente:

    CPP Código:
    1. extern "C" _declspec(dllexport) void WINAPI nombre_rutina(long int parametro1, char parametro2[256], char parametro3[256])

    Todos los parámetros pueden ser para enviar como para recoger entre ambos ambientes.

    Recuerda que el type char, es una string sin fin, y debe convertirse en array limitado el número de ocurrencias haciendo una copia del valor de la variable para que reciba el valor desde NetCOBOL, en caso contrario no llegaría ninguno.

    0 Not allowed!
    Empresa de desarrollo de aplicaciones en COBOL.

    DASIJE INFORMATICA, S.L.
    C/ TOMAS BRETON 20
    11406 JEREZ DE LA FRONTERA
    CADIZ

    Teléfono : 956 11 21 11
    Web: http://www.dasije.es / DASIJE INFORMATICA
    E-m@il: clientes(@)dasije.es

  3. #3
      Administrador
    Avatar de Kuk

    Registrado
    enero de 2015
    Ubicación
    Madrid
    Edad
    39
    Mensajes
    2,286
    Última visita
    Ayer a las 18:48

    Agradecimientos
     
    Recibidos
    1,036
    Enviados
    888

    Citaciones y menciones
     
    Mentioned
    102 Post(s)
    Tagged
    0 Thread(s)
    Quoted
    31 Post(s)
    Poder de Reputación
    10

    Predeterminado

    @Dasije, ¿qué es lo que no te gusta exactamente del fuente que he publicado? No entiendo qué tiene que ver tu post. Yo sólo paso un puntero, nada más.
    Si simplemente quieres mostrar un ejemplo que no tiene nada que ver con este código publicado por mi, deberías crear un tema nuevo. Si tienes modificaciones a aportar al código publicado, precisa más, dónde exactamente y por qué.

    Lo de "directamente", no sé a qué te refieres. Si es por la *.LIB, la que genera el Dev C++ no funciona, no sé por qué y no tengo tiempo de mirarlo. Pero como se puede evitar con LoadLibrary y GetProcAddress (que se hacen automáticamente via fichero COBOL85.CBR) no me he comido mucho el coco con ello.

    El extern "C" lo que hace es el famoso "undecorate" que básicamente hace más visibles los nombres de las funciones de acuerdo a las normas del C.

    En cuanto a pasar un char en parámetros, aunque la declaración sea así, por detrás se transforma en puntero y se pasa la dirección del array, porque no podemos pasar por parámetro algo que no sea tipo binario. Ah, y por cierto:

    Cita Iniciado por Dasije Ver Mensaje
    Recuerda que el type char, es una string sin fin
    Aquí te has equivocado, el tipo char es de 1 byte, y no infinito. Si lo definimos como array de char y sin especificar la longitud, ahí sí. Es decir:

    CPP Código:
    1. char MyCharArray[];

    0 Not allowed!
    ¿Te han ayudado? NO TE OLVIDES de darle al botón
    ¿Quieres dirigirte a alguien en tu post? Notifícale con una mención, tienes 2 opciones:
    1. Haciendo clic en el icono al lado de su nick
    2. Haciendo clic en el botón en el editor y escribiendo su nick.

  4. #4
      Forero
    Avatar de Dasije

    Registrado
    noviembre de 2015
    Ubicación
    Jerez De La Frontera (cádiz)
    Mensajes
    182
    Última visita
    06.03.2022

    Agradecimientos
     
    Recibidos
    79
    Enviados
    1

    Citaciones y menciones
     
    Mentioned
    5 Post(s)
    Tagged
    0 Thread(s)
    Quoted
    0 Post(s)
    Poder de Reputación
    16

    Predeterminado

    Quería dar entender que se puede mejorar para poder usar la LIB, así tratas la rutina como si fuera una API de Windows dentro del procedure donde se ejecute.

    Sino te funciona, debe ser la compatibilidad del compilador, en mi caso funciona con MS C++ 6.0.

    0 Not allowed!
    Empresa de desarrollo de aplicaciones en COBOL.

    DASIJE INFORMATICA, S.L.
    C/ TOMAS BRETON 20
    11406 JEREZ DE LA FRONTERA
    CADIZ

    Teléfono : 956 11 21 11
    Web: http://www.dasije.es / DASIJE INFORMATICA
    E-m@il: clientes(@)dasije.es

  5. #5
      Administrador
    Avatar de Kuk

    Registrado
    enero de 2015
    Ubicación
    Madrid
    Edad
    39
    Mensajes
    2,286
    Última visita
    Ayer a las 18:48

    Agradecimientos
     
    Recibidos
    1,036
    Enviados
    888

    Citaciones y menciones
     
    Mentioned
    102 Post(s)
    Tagged
    0 Thread(s)
    Quoted
    31 Post(s)
    Poder de Reputación
    10

    Predeterminado

    @Dasije, entonces no es el fuente el que no te gusta sino que no haya facilitado la LIB correspondiente en el tema [Componente] Como generar un PrintScreen - COBOL Foro. No sé, he probado con la que genera el Dev C++ (que es lib*.a) y extrayendo la LIB desde la DLL con la utilidad IMPLIB. Ambas van en el ZIP, probadlas a ver, pero a mi no me han funcionado.
    Ficheros adjuntos Ficheros adjuntos

    0 Not allowed!
    ¿Te han ayudado? NO TE OLVIDES de darle al botón
    ¿Quieres dirigirte a alguien en tu post? Notifícale con una mención, tienes 2 opciones:
    1. Haciendo clic en el icono al lado de su nick
    2. Haciendo clic en el botón en el editor y escribiendo su nick.

  6. #6
      Guardián del Foro
    H

    Registrado
    febrero de 2015
    Ubicación
    Puerto Madryn
    Edad
    72
    Mensajes
    328
    Última visita
    23.06.2023

    Agradecimientos
     
    Recibidos
    122
    Enviados
    107

    Citaciones y menciones
     
    Mentioned
    7 Post(s)
    Tagged
    0 Thread(s)
    Quoted
    0 Post(s)
    Poder de Reputación
    21
    Guardián del Foro / Point Value: 0

    Predeterminado

    Amigo Kuk, sera posible que la rutina Pantallazo capture solo la pantalla Vigente?
    Saludos

    0 Not allowed!

  7. #7
      Administrador
    Avatar de Kuk

    Registrado
    enero de 2015
    Ubicación
    Madrid
    Edad
    39
    Mensajes
    2,286
    Última visita
    Ayer a las 18:48

    Agradecimientos
     
    Recibidos
    1,036
    Enviados
    888

    Citaciones y menciones
     
    Mentioned
    102 Post(s)
    Tagged
    0 Thread(s)
    Quoted
    31 Post(s)
    Poder de Reputación
    10

    Predeterminado

    @Hrmcobol, aquí va el código y la DLL compilada:

    CPP Código:
    1. #include <Windows.h>
    2. #include <Gdiplus.h>
    3.  
    4. #define DllExport __declspec( dllexport )
    5.  
    6. extern "C" {
    7.  
    8. DllExport void __stdcall ScreenShot(char*BmpName, HWND WndHwnd)
    9. {
    10.     RECT DesktopParams;
    11.     HDC DevC = GetDC(WndHwnd);
    12.     GetWindowRect(WndHwnd,&DesktopParams);
    13.     DWORD Width = DesktopParams.right - DesktopParams.left;
    14.     DWORD Height = DesktopParams.bottom - DesktopParams.top;
    15.  
    16.     DWORD FileSize = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+(sizeof(RGBTRIPLE)+1*(Width*Height*4));
    17.     char *BmpFileData = (char*)GlobalAlloc(0x0040,FileSize);
    18.  
    19.     PBITMAPFILEHEADER BFileHeader = (PBITMAPFILEHEADER)BmpFileData;
    20.     PBITMAPINFOHEADER  BInfoHeader = (PBITMAPINFOHEADER)&BmpFileData[sizeof(BITMAPFILEHEADER)];
    21.  
    22.     BFileHeader->bfType = 0x4D42; // BM
    23.     BFileHeader->bfSize = sizeof(BITMAPFILEHEADER);
    24.     BFileHeader->bfOffBits = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER);
    25.  
    26.     BInfoHeader->biSize = sizeof(BITMAPINFOHEADER);
    27.     BInfoHeader->biPlanes = 1;
    28.     BInfoHeader->biBitCount = 24;
    29.     BInfoHeader->biCompression = BI_RGB;
    30.     BInfoHeader->biHeight = Height;
    31.     BInfoHeader->biWidth = Width;
    32.  
    33.     RGBTRIPLE *Image = (RGBTRIPLE*)&BmpFileData[sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)];
    34.     RGBTRIPLE color;
    35.  
    36.     HDC CaptureDC = CreateCompatibleDC(DevC);
    37.     HBITMAP CaptureBitmap = CreateCompatibleBitmap(DevC,Width,Height);
    38.     SelectObject(CaptureDC,CaptureBitmap);
    39.     BitBlt(CaptureDC,0,0,Width,Height,DevC,0,0,SRCCOPY|CAPTUREBLT);
    40.     GetDIBits(CaptureDC,CaptureBitmap,0,Height,Image,(LPBITMAPINFO)BInfoHeader, DIB_RGB_COLORS);
    41.  
    42.     DWORD Junk;
    43.     HANDLE FH = CreateFileA(BmpName,GENERIC_WRITE,FILE_SHARE_WRITE,0,CREATE_ALWAYS,0,0);
    44.     WriteFile(FH,BmpFileData,FileSize,&Junk,0);
    45.     CloseHandle(FH);
    46.         GlobalFree(BmpFileData);
    47. }
    48.  
    49. } //undecorate

    Para llamar la función desde PowerCOBOL, en el fichero COBOL85.CBR ponemos:

    CODE Código:
    1. [MainForm.Entry]
    2. ScreenShot=PrintScreen.dll

    En el código:

    COBOL Código:
    1.  ENVIRONMENT     DIVISION.
    2.  DATA            DIVISION.
    3.  WORKING-STORAGE SECTION.
    4.  01  PrinScreen  PIC X(50)  VALUE "ScreenShot".
    5.  01  WsPath      PIC X(250).
    6.  01  FrmHWND     PIC S9(9) COMP-5.
    7.  PROCEDURE       DIVISION.
    8.      
    9.      MOVE "hwnd" OF POW-SELF TO FrmHWND
    10.      MOVE "C:\001.BMP"       TO WsPath
    11.      
    12.      CALL PrinScreen WITH STDCALL USING BY REFERENCE WsPath
    13.                                         BY VALUE FrmHWND
    Ficheros adjuntos Ficheros adjuntos

    0 Not allowed!
    ¿Te han ayudado? NO TE OLVIDES de darle al botón
    ¿Quieres dirigirte a alguien en tu post? Notifícale con una mención, tienes 2 opciones:
    1. Haciendo clic en el icono al lado de su nick
    2. Haciendo clic en el botón en el editor y escribiendo su nick.

Información de Tema

Usuarios Viendo este Tema

Actualmente hay 1 usuarios viendo este tema. (0 miembros y 1 visitantes)

Temas Similares

  1. [Información] Error en dll (DLL does not exist)
    Por Josber en el foro PowerCOBOL (ActiveX, v4 - v11)
    Respuestas: 5
    Último Mensaje: 18.02.2015, 18:39

Etiquetas para este Tema

Marcadores

Marcadores

Permisos de Publicación

  • No puedes crear nuevos temas
  • No puedes responder temas
  • No puedes subir archivos adjuntos
  • No puedes editar tus mensajes
  •