Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Copier contenu d'une fenetre dans un bmp

11 réponses
Avatar
Hwoarang
Bonjour,

Je ne suis pas un expert dans la prog windows donc j'ai recupéré un bout de
code qui permet de faire une capture d'ecran et qui marche. Seulement voila,
j'aimerais ne copier qu'une seule fenetre, que celle-ci soit visible à
l'ecran ou pas (meme si elle est reduite).

J'utilise donc :
int TakeShot(HWND hWndWindow, HDC *phDcBitmap, HBITMAP *phBitmap)
{
RECT rect;
HDC hDcWindow = GetWindowDC(hWndWindow);
int ScreenX = GetDeviceCaps(hDcWindow, HORZRES);
int ScreenY = GetDeviceCaps(hDcWindow, VERTRES);
GetWindowRect(hWndWindow, &rect);

*phDcBitmap = CreateCompatibleDC(hDcWindow);

*phBitmap = CreateCompatibleBitmap(hDcWindow, ScreenX, ScreenY);

if(!SelectObject(*phDcBitmap, *phBitmap)) return 0;

if(!BitBlt(*phDcBitmap, 0, 0, rect.right, rect.bottom,
hDcWindow, 0, 0, SRCCOPY)) return 0;
}

Ma question est :
L'image que je recupere est une capture de l'ecran complet et pas seulement
de la fenetre que je voulais (mais de la bonne taille). Moi, j'aimerais
recuperer un bmp avec la fenetre, que celle-ci soit reduite, en dehors de
l'ecran ou visible. Est ce que c'est possible ?

Merci

10 réponses

1 2
Avatar
bilal
Hwoarang wrote:
Bonjour,



Ma question est :
L'image que je recupere est une capture de l'ecran complet et pas
seulement de la fenetre que je voulais (mais de la bonne taille). Moi,
j'aimerais recuperer un bmp avec la fenetre, que celle-ci soit reduite,
en dehors de l'ecran ou visible. Est ce que c'est possible ?

Merci




Tu peux utiliser WM_PRINT ou WM_PRINTWINDOW si c'est géré par la fenetre
Avatar
Vincent Burel
"Hwoarang" wrote in message
news:fsbik1$asg$
Bonjour,

Je ne suis pas un expert dans la prog windows donc j'ai recupéré un bout


de
code qui permet de faire une capture d'ecran et qui marche. Seulement


voila,
j'aimerais ne copier qu'une seule fenetre, que celle-ci soit visible à
l'ecran ou pas (meme si elle est reduite).



il faut qu'elle soit un peu visible quand même, sinon y'aura pas de pixel à
copier.

J'utilise donc :
int TakeShot(HWND hWndWindow, HDC *phDcBitmap, HBITMAP *phBitmap)
{
RECT rect;
HDC hDcWindow = GetWindowDC(hWndWindow);
int ScreenX = GetDeviceCaps(hDcWindow, HORZRES);
int ScreenY = GetDeviceCaps(hDcWindow, VERTRES);
GetWindowRect(hWndWindow, &rect);

*phDcBitmap = CreateCompatibleDC(hDcWindow);

*phBitmap = CreateCompatibleBitmap(hDcWindow, ScreenX, ScreenY);

if(!SelectObject(*phDcBitmap, *phBitmap)) return 0;

if(!BitBlt(*phDcBitmap, 0, 0, rect.right, rect.bottom,
hDcWindow, 0, 0, SRCCOPY)) return 0;
}

Ma question est :
L'image que je recupere est une capture de l'ecran complet et pas


seulement
de la fenetre que je voulais (mais de la bonne taille). Moi, j'aimerais
recuperer un bmp avec la fenetre, que celle-ci soit reduite, en dehors de
l'ecran ou visible. Est ce que c'est possible ?



je ferai les modifs suivantes :
GetWindowRect(hWndWindow, &rect);
bmpdx=rect.right-rect.left;
bmpdy=rect.bottom-rect.top;
*phBitmap = CreateCompatibleBitmap(hDcWindow, bmpdx, bmpdy);
BitBlt(*phDcBitmap, 0, 0, bmpdx, bmpdy,hDcWindow, 0, 0, SRCCOPY);

Si ca marche pas, je tenterai un
hDcWindow = GetDC(NULL);
pour obtenir une DC sur le bureau et le bitblt devra tenir compte des
coordonnées.
BitBlt(*phDcBitmap, 0, 0, bmpdx, bmpdy,hDcWindow, rect.left,rect.top,
SRCCOPY);

VB
Avatar
Christian ASTOR
bilal wrote:

Hwoarang wrote:



L'image que je recupere est une capture de l'ecran complet et pas
seulement de la fenetre que je voulais (mais de la bonne taille). Moi,
j'aimerais recuperer un bmp avec la fenetre, que celle-ci soit
reduite, en dehors de l'ecran ou visible. Est ce que c'est possible ?



Tu peux utiliser WM_PRINT ou WM_PRINTWINDOW si c'est géré par la fenetre



+ vieil article : http://www.fengyuan.com/article/wmprint.html
(pas retesté sous >=XP)
Avatar
Christian ASTOR
Hwoarang wrote:

L'image que je recupere est une capture de l'ecran complet et pas
seulement de la fenetre que je voulais (mais de la bonne taille).



Et le code n'est pas correct : il manque les Release()

ex =>

HBITMAP GetBitmapFromwindow(HWND hWnd)
{
HDC hDC, hDCMem;
HBITMAP hBitmapReturn, hBitmapOld;
RECT rect;
GetWindowRect(hWnd, &rect);
hDC = GetWindowDC(hWnd);
hDCMem = CreateCompatibleDC(hDC);
hBitmapReturn = CreateCompatibleBitmap(hDC, rect.right - rect.left,
rect.bottom - rect.top);
hBitmapOld = (HBITMAP)SelectObject(hDCMem, hBitmapReturn);
BitBlt(hDCMem, 0, 0, rect.right - rect.left, rect.bottom - rect.top,
hDC, 0, 0, SRCCOPY);
SelectObject(hDCMem, hBitmapOld);
DeleteDC(hDCMem);
ReleaseDC(hWnd, hDC);
return hBitmapReturn;
}
Avatar
Hwoarang
Merci pour vos reponses, je vais essayer ca

"Christian ASTOR" a écrit dans le message de
news:47e9f866$0$21145$
bilal wrote:

Hwoarang wrote:



L'image que je recupere est une capture de l'ecran complet et pas
seulement de la fenetre que je voulais (mais de la bonne taille). Moi,
j'aimerais recuperer un bmp avec la fenetre, que celle-ci soit reduite,
en dehors de l'ecran ou visible. Est ce que c'est possible ?



Tu peux utiliser WM_PRINT ou WM_PRINTWINDOW si c'est géré par la fenetre



+ vieil article : http://www.fengyuan.com/article/wmprint.html
(pas retesté sous >=XP)


Avatar
Hwoarang
J'ai essayé WM_PRINT et WM_PRINTWINDOW et ca ne marche pas :-(

En fait, l'application que je voudrais faire est une fenetre qui permettrait
de recuperer le hwnd de firefox, et de faire une copie de l'ecran dans un
bmp, que firefox soit visible ou pas. Le bmp obtenu est une fenetre noir de
la taille de ma fenetre d'origine.

Est ce que c'est normal que WM_PRINT et WM_PRINTWINDOW n'aient pas marché
dans mon cas ou est ce que c'est normal ? Si c'est normal, est ce qu'il y a
un autre moyen de faire ca ?

Sachant que j'utilise Windows Vista Professionnel.

Merci

"Christian ASTOR" a écrit dans le message de
news:47e9f866$0$21145$
bilal wrote:

Hwoarang wrote:



L'image que je recupere est une capture de l'ecran complet et pas
seulement de la fenetre que je voulais (mais de la bonne taille). Moi,
j'aimerais recuperer un bmp avec la fenetre, que celle-ci soit reduite,
en dehors de l'ecran ou visible. Est ce que c'est possible ?



Tu peux utiliser WM_PRINT ou WM_PRINTWINDOW si c'est géré par la fenetre



+ vieil article : http://www.fengyuan.com/article/wmprint.html
(pas retesté sous >=XP)


Avatar
Christian ASTOR
On 28 mar, 00:36, "Hwoarang" wrote:
J'ai essayé WM_PRINT et WM_PRINTWINDOW et ca ne marche pas :-(

En fait, l'application que je voudrais faire est une fenetre qui permettra it
de recuperer le hwnd de firefox, et de faire une copie de l'ecran dans un
bmp, que firefox soit visible ou pas. Le bmp obtenu est une fenetre noir d e
la taille de ma fenetre d'origine.

Est ce que c'est normal que WM_PRINT et WM_PRINTWINDOW n'aient pas march é
dans mon cas ou est ce que c'est normal ? Si c'est normal, est ce qu'il y a
un autre moyen de faire ca ?



Je viens de faire un test sur XP SP2 :
ça marche chez moi en récupérant la 2ème fenêtre "MozillaWindowCla ss"
et en la mettant par ex dans un Static (SetParent()) puis
PrintWindow() sur la fenêtre parente du Static
Avatar
Hwoarang
Merci pour ta reponse mais je n'ai pas tres bien compris l'histoire du
static. Voila le code que j'utilise :
J'ouvre une fenetre Firefox sur Google (Le titre de la fenetre est Google)
puis je lance ce programme :
{
HWND hWndCur = NULL;
char szTmpModuleFN[256];
char is_visible;
char is_found = 0;
LONG window_style;

hWndCur = GetWindow(GetDesktopWindow(), GW_CHILD);
GetWindowText(hWndCur, szTmpModuleFN, 255);
window_style = GetWindowLong (hWndCur, GWL_STYLE);
is_visible = (window_style & WS_VISIBLE) != 0;

while((hWndCur) &&
(is_found == 0))
{
if(is_visible != 0)
{
GetWindowText(hWndCur, szTmpModuleFN, 255);
is_found = !memcmp(szTmpModuleFN, "Google", 6);
}

if(is_found == 0)
{
hWndCur = GetWindow(hWndCur, GW_HWNDNEXT);
window_style = GetWindowLong (hWndCur, GWL_STYLE);
is_visible = (window_style & WS_VISIBLE) != 0;
}
}

if(hWndCur)
{
HDC hDCMem = CreateCompatibleDC(NULL);

RECT rect;

GetWindowRect(hWndCur, & rect);

HBITMAP hBmp = NULL;

{
HDC hDC = GetDC(hWndCur);
hBmp = CreateCompatibleBitmap(hDC, rect.right -
rect.left, rect.bottom - rect.top);
ReleaseDC(hWndCur, hDC);
}

HGDIOBJ hOld = SelectObject(hDCMem, hBmp);
SendMessage(hWndCur, WM_PRINTCLIENT, (WPARAM) hDCMem,
PRF_CHILDREN | PRF_CLIENT | PRF_ERASEBKGND | PRF_NONCLIENT | PRF_OWNED);

SelectObject(hDCMem, hOld);
DeleteObject(hDCMem);

OpenClipboard(hWndWindow);

EmptyClipboard();
SetClipboardData(CF_BITMAP, hBmp);
CloseClipboard();
}
else
{
printf("Aucune fenetre dont le titre commence par "Google"
trouveen");
}
}

Ensuite, je vais dans paint et quand je colle, il n'y a rien...

"Christian ASTOR" a écrit dans le message de
news:
On 28 mar, 00:36, "Hwoarang" wrote:
J'ai essayé WM_PRINT et WM_PRINTWINDOW et ca ne marche pas :-(

En fait, l'application que je voudrais faire est une fenetre qui
permettrait
de recuperer le hwnd de firefox, et de faire une copie de l'ecran dans un
bmp, que firefox soit visible ou pas. Le bmp obtenu est une fenetre noir
de
la taille de ma fenetre d'origine.

Est ce que c'est normal que WM_PRINT et WM_PRINTWINDOW n'aient pas marché
dans mon cas ou est ce que c'est normal ? Si c'est normal, est ce qu'il y
a
un autre moyen de faire ca ?



Je viens de faire un test sur XP SP2 :
ça marche chez moi en récupérant la 2ème fenêtre "MozillaWindowClass"
et en la mettant par ex dans un Static (SetParent()) puis
PrintWindow() sur la fenêtre parente du Static
Avatar
Christian ASTOR
Hwoarang wrote:

Merci pour ta reponse mais je n'ai pas tres bien compris l'histoire du
static.



L'utilisation d'un autre contrôle permet de récupérer la fenêtre avec un
SetParent()
HWND hWndParentOld = SetParent(hWndFirefox, hWndControle);
à la fin, on remet bien sûr à l'état initial :
SetParent(hWndFirefox, hWndParentOld);

J'ai refait un test : le meilleur contrôle est le SysPager
Comme il faut qu'il soit visible (WS_VISIBLE), on le déplace hors de
l'écran en x = -2000 par exemple
Il supporte bien PrintWindow() directement, contraitement au Static.

En passant, PrintWindow() marche toujours sur la fenêtre principale de
Firefox, si elle est visible.

De plus ta méthode pour trouver la fenêtre n'est pas tout-à-fait bonne
(le titre peut changer)
La fenêtre principale peut être de classe "MozillaUIWindowClass" ou
"MozillaWindowClass" selon la version.
On fait donc un EnumWindows(), puis GetClassName() dans la CALLBACK puis
GetWindowText() et strstr() sur "Mozilla Firefox" par exemple pour
l'identifier.
Ensuite pour la fenêtre fille (sur laquelle on fait ensuite le
SetParent()) :
HWND hWndFirefox = FindWindowEx(hWnd, NULL, "MozillaWindowClass", NULL);
Avatar
Hwoarang
Ce que je ne comprend pas, c'est que meme quand ma fenetre firefox est
visible, je ne vois qu'un rectangle noir lorsque je colle dans paint.
Concernant le setparent, j'ai l'impression que je n'ai pas sysfader (il
n'apparait pas dans le gestionnaire de taches). Est ce que je peux utiliser
autre chose ?

Merci

"Christian ASTOR" a écrit dans le message de
news:47ee25c1$0$21149$
Hwoarang wrote:

Merci pour ta reponse mais je n'ai pas tres bien compris l'histoire du
static.



L'utilisation d'un autre contrôle permet de récupérer la fenêtre avec un
SetParent()
HWND hWndParentOld = SetParent(hWndFirefox, hWndControle);
à la fin, on remet bien sûr à l'état initial :
SetParent(hWndFirefox, hWndParentOld);

J'ai refait un test : le meilleur contrôle est le SysPager
Comme il faut qu'il soit visible (WS_VISIBLE), on le déplace hors de
l'écran en x = -2000 par exemple
Il supporte bien PrintWindow() directement, contraitement au Static.

En passant, PrintWindow() marche toujours sur la fenêtre principale de
Firefox, si elle est visible.

De plus ta méthode pour trouver la fenêtre n'est pas tout-à-fait bonne (le
titre peut changer)
La fenêtre principale peut être de classe "MozillaUIWindowClass" ou
"MozillaWindowClass" selon la version.
On fait donc un EnumWindows(), puis GetClassName() dans la CALLBACK puis
GetWindowText() et strstr() sur "Mozilla Firefox" par exemple pour
l'identifier.
Ensuite pour la fenêtre fille (sur laquelle on fait ensuite le
SetParent()) :
HWND hWndFirefox = FindWindowEx(hWnd, NULL, "MozillaWindowClass", NULL);









1 2