PB gflImportFromHWND en DualScreen

Discussions on GFL SDK, the graphic library for reading and writing graphic files

Moderators: XnTriq, helmut, xnview

hcompagnie
Posts: 2
Joined: Thu Oct 30, 2014 8:05 am

PB gflImportFromHWND en DualScreen

Post by hcompagnie »

Bonjour,

Un grand merci pour la mise à disposition de cette boite à outils que j’utilise depuis des années.

Je rencontre aujourd’hui deux problèmes avec la fonction gflImportFromHWND,
Le premier problème me semble lié aux configurations a 2 écrans.
Je souhaite faire des copies d’écran de la fenêtre **Rendu** d’une autre application.

J’utilise Visual Studio 2012 et gflSDK 3.40
J’ai le problème, aussi bien sous Win 8.1 Pro x64, Pilote Vidéo ATI Radeon que sous Win 7 SP1 Pro x64, Pilote Vidéo NVIDIA Quadro FX, le tout étant à jour.

Voici le source C simplifié

Code: Select all

HWND            hWin;
GFL_ERROR       iGFLerror;
GFL_BITMAP     *pBitmap;
GFL_RECT        Rect;
RECT            Rct;
 
// Obtenir un handle sur la fenetre **Rendu**
if (NULL==(hWin=FindWindow("RenderClass","**Rendu**")))  
    { fprintf(stderr,"*** Impossible d'obtenir un handle sur la fenetre '**Rendu**'. Abandon ...\n"); return(1); }
 
// Obtenir ses dimensions et preparer la structure GFL_RECT
if (0==GetClientRect(hWin,&Rct))
    { fprintf(stderr,"*** Impossible d'obtenir la taille de la zone. Abandon ...\n"); return(1); }
Rect.x=0;  Rect.y=0;  Rect.w=(Rct.right-Rct.left)+1;  Rect.h=(Rct.bottom-Rct.top)+1;
printf("La taille de la zone de rendu est %d sur %d\n",Rect.w-1,Rect.h-1);
 
// HWND --> GFL_BITMAP
if ((iGFLerror=gflImportFromHWND(hWin, &Rect, &pBitmap)) != GFL_NO_ERROR) 
    { fprintf(stderr,"*** %s. Abandon ...\n",gflGetErrorString (iGFLerror));  return(1); }
printf("La taille de la zone lue est %d sur %d\n",pBitmap->Width,pBitmap->Height);
[/color]

Si la fenêtre **Rendu** est uniquement sur l'écran primaire, à l’exécution s’affiche
La taille de la zone de rendu est 1280 sur 720
La taille de la zone lue est 1280 sur 720
Aucun problème, la GFL_BITMAP peut être sauvegardée sur disque.

Si la fenêtre **Rendu** est a cheval sur les 2 ecrans, à l’exécution s’affiche
La taille de la zone de rendu est 1280 sur 720
La taille de la zone lue est 698 sur 720
Petit problème, la GFL_BITMAP peut être sauvegardée sur disque mais l’image est incomplète, il manque le partie située sur l’écran secondaire.

Si la fenêtre **Rendu** est uniquement sur l'écran secondaire, à l’exécution s’affiche
La taille de la zone de rendu est 1280 sur 720
*** Unknown error. Abandon ...
Plus gênant, la fonction gflImportFromHWND échoue.


Le deuxième problème concerne la GFL_RECT, pour obtenir une GFL_BITMAP de 1280 par 720, je dois l’initialiser à w=1281 et h=721.

Ai je raté quelque chose ou bien gflImportFromHWND ne genre pas le ‘Multi Screen’ ?
Merci de m’aider a résoudre ce problème.

Salutations.
hcompagnie
Posts: 2
Joined: Thu Oct 30, 2014 8:05 am

Re: PB gflImportFromHWND en DualScreen

Post by hcompagnie »

Bonjour,

Resté trop longtemps sans reponse, j'ai décidé d'ecrire une version personnelle de gflImportFromHWND qui corrige les 2 problèmes.

Code: Select all

BOOL ImportFromHWND(HWND hWnd, char *NomImage)
{
GFL_ERROR          iGFLerror;
GFL_BITMAP        *pBitmap=NULL;
GFL_SAVE_PARAMS    ParamSauvegarde;
HDC                hDC = NULL;
HDC                hMemDC = NULL;
HBITMAP            hBMP = NULL;
RECT               rect;
int                Largeur;
int                Hauteur;
FILE              *FichierImage = NULL;
BOOL               rc;

GetClientRect(hWnd, &rect);
Largeur  = rect.right  - rect.left;
Hauteur  = rect.bottom - rect.top;
hDC = GetDC(hWnd);

rc=FALSE;
if (NULL!=(hMemDC = CreateCompatibleDC(hDC)))
    {
    if (NULL!=(hBMP = CreateCompatibleBitmap(hDC, Largeur, Hauteur)))
        {
        SelectObject(hMemDC, hBMP);
        BitBlt(hMemDC, 0, 0, Largeur, Hauteur, hDC, 0, 0, SRCCOPY);
        if ((iGFLerror=gflConvertDDBIntoBitmap(hBMP, &pBitmap)) != GFL_NO_ERROR) 
            {
            fprintf(stderr,"*** Impossible de convertir la zone de rendu. Erreur '%s'.\n",gflGetErrorString (iGFLerror));
            if (NULL!=pBitmap)
                gflFreeBitmap(pBitmap);
            }
        else 
            {
            gflGetDefaultSaveParams(&ParamSauvegarde);
            ParamSauvegarde.CompressionLevel = 6;
            ParamSauvegarde.FormatIndex = gflGetFormatIndexByName("png"); 
            if ((iGFLerror=gflSaveBitmap(NomImage,pBitmap,&ParamSauvegarde)) != GFL_NO_ERROR) 
                {
                fprintf(stderr,"*** Impossible de sauvegarder l'image dans le fichier '%s'. Erreur '%s'.\n",NomImage,gflGetErrorString (iGFLerror));
                if (NULL!=pBitmap) 
                    gflFreeBitmap(pBitmap);
                }
            else
                {
                printf("Ecriture du fichier image '%s' OK\n",NomImage);	
                rc=TRUE;
                if (NULL!=pBitmap) 
                    gflFreeBitmap(pBitmap);
                pBitmap = NULL;
                }
            }
        DeleteObject(hBMP);
        }
    else
        {
        fprintf(stderr,"*** Impossible de creer une Bitmap Compatible Windows (DDB).\n");
        }
    DeleteDC(hMemDC);
    }
else
    {
    fprintf(stderr,"*** Impossible de creer un DC Compatible.\n");
    }
ReleaseDC(hWnd, hDC);
return(rc);
}
Salutations.