Bacterius
Messages postés3792Date d'inscriptionsamedi 22 décembre 2007StatutMembreDernière intervention 3 juin 2016
-
11 oct. 2009 à 01:43
phephelavi
Messages postés40Date d'inscriptionmardi 16 mai 2006StatutMembreDernière intervention27 octobre 2009
-
27 oct. 2009 à 15:38
Bonjour,
pour un petit projet graphique, je cherche à capturer l'écran, sauf notre fiche. Il existe bien la solution de rendre invisible notre fenêtre, capturer l'écran, et réafficher, mais c'est pas très stylé, et comme ma fiche doit recapturer constamment, ça ne va pas être terrible.
J'ai donc cherché à lister toutes les fenêtres du système, et les capturer individuellement, et les reconstituer dans un gros bitmap de la taille de l'écran. Voici mon code, il me lance toujours une violation d'accès sur BitBlt (ou un "Le canevas ne permet pas de dessiner" si je passe par un canevas). J'ai utilisé le snippet de Cirec pour la capture des fiches ... ?
// J'ai dû déclarer celle-ci pour le snippet
function PrintWindow(hWND: HWND; hdcBlt: HDC; nFlags: Longword): BOOL; stdcall; external 'User32.dll';
// Snippet de Cirec
Function GetFullWindowImage(aHandle : THandle):TBitmap;
Var DC, hdcMem : HDC;
aRect : TRect;
hBMP : HBitmap;
aWidth, aHeight : Integer;
Begin
Result := Nil;
dc := GetWindowDC(0);
If (dc > 0) Then
Try
hdcMem := CreateCompatibleDC(dc);
If (hdcMem > 0) Then
Try
GetWindowRect(aHandle, aRect);
aWidth := aRect.Right-aRect.Left;
aHeight := aRect.Bottom-aRect.Top;
hBMP := CreateCompatibleBitmap(dc, aWidth, aHeight);
If (hBMP > 0) Then
Try
SelectObject(hdcMem, hBMP);
PrintWindow(aHandle, hdcMem, 0);
Result := TBitmap.Create;
Result.Width := aWidth;
Result.Height := aHeight;
BitBlt(Result.Canvas.Handle, 0, 0, aWidth, aHeight, hdcMem, 0, 0, srcCopy);
Finally
DeleteObject(hBMP);
End;
Finally
DeleteObject(hdcMem);
End;
Finally
ReleaseDC(0, dc);
End;
End;
function EnumWindowsProc(hWND: HWND; lParam: Integer): Boolean;
Var
ABmp: TBitmap;
ARect: TRect;
W, H: Integer;
begin
Result := True;
if (hWND <> MainForm.Handle) and (IsWindow(hWND)) and (IsWindowVisible(hWND)) then
begin
ABmp := GetFullWindowImage(hWND);
GetWindowRect(hWND, ARect);
W := Abs(ARect.TopLeft.X - ARect.BottomRight.X);
H := Abs(ARect.TopLeft.Y - ARect.BottomRight.Y);
if (W > 0) and (H > 0) then BitBlt(Bmp.Canvas.Handle, ARect.TopLeft.X, ARect.TopLeft.Y, W, H, ABmp.Canvas.Handle, 0, 0, SRCCOPY);
ABmp.Free;
end;
end;
procedure TMainForm.FormCreate(Sender: TObject);
begin
DoubleBuffered := True;
end;
procedure TMainForm.BorderShapeMouseMove(Sender: TObject;
Shift: TShiftState; X, Y: Integer);
begin
ReleaseCapture;
Perform(WM_SysCommand, SC_MOVE + 1, 0);
end;
procedure TMainForm.Button1Click(Sender: TObject);
begin
EnumWindows(@EnumWindowsProc, 0);
BitBlt(Image1.Canvas.Handle, 0, 0, Image1.Width, Image1.Height, Bmp.Canvas.Handle, Left, Top, SRCCOPY);
end;
initialization
Bmp := TBitmap.Create;
Bmp.Width := Screen.Width;
Bmp.Height := Screen.Height;
finalization
Bmp.Free;
end.
Où me suis-je trompé ? (il y a une image et un bouton sur la fiche)
Merci d'avance pour vos idées (si il y a une solution plus simple que de reconstituer l'écran sans notre fiche, je suis preneur).
Bacterius
Messages postés3792Date d'inscriptionsamedi 22 décembre 2007StatutMembreDernière intervention 3 juin 201610 11 oct. 2009 à 02:20
Après réflexion il semblerait que l'intérieur de la fonction d'énumération ne soit jamais exécuté ! Même en enlevant IsWindowInvisible (je sais même pas pourquoi je l'ai mis), ça ne change rien. Normalement, on devrait trouver des fenêtres ouvertes, donc il devrait y avoir au moins un passage dans la fonction (ne serait-ce que Delphi) ...
Bacterius
Messages postés3792Date d'inscriptionsamedi 22 décembre 2007StatutMembreDernière intervention 3 juin 201610 11 oct. 2009 à 02:24
Et après divers tests, il semblerait que après l'appel à EnumWindows, l'objet Bmp soit complètement détruit (on ne peut plus accéder à ses propriétés sans violation d'accès). Ca expliquerait tout ... mais pourquoi est-il détruit ?
Bacterius
Messages postés3792Date d'inscriptionsamedi 22 décembre 2007StatutMembreDernière intervention 3 juin 201610 11 oct. 2009 à 02:48
De plus en plus bizarre ... si ma fonction d'énumération se résume à "Result := True", j'obtiens toujours le même résultat que mon message précédent.
Et mon bouton "Démarrer" (windows) est devenu tout noir.
Bacterius
Messages postés3792Date d'inscriptionsamedi 22 décembre 2007StatutMembreDernière intervention 3 juin 201610 11 oct. 2009 à 13:41
Lol ... je dors puis *ting jveux faire ça ... hop là ... merde ça foire, go google ... rrah ça renvoie rien ... expériences par soi-même (cf. bouton démarrer noir) ... pff go codes-sources ... eeh mais attends ... callback ... hmm .. call..back ? stdcall !! yeaah mais bon je récupère toujours que le desktop lol*
Mais en fait j'ai trouvé comment faire + simplement : remplacer toute notre fiche par le beau effet "vitre" de windows Vista.
phephelavi
Messages postés40Date d'inscriptionmardi 16 mai 2006StatutMembreDernière intervention27 octobre 2009 27 oct. 2009 à 15:38
Bonjour à tous,
Je voudrais féliciter les noms suivants : Bacterius, Cantador, Cirec, Nono40 et j'en oublie certains ! Eh oui, en recherchant des informations, des solutions et autres codes, on peut remarquer régulièrement vos noms , vos réponses et votre engagement !
Cela m'aide beaucoup, et si personne ne l'a fait avant moi et n'a pas la reconnaissance, je tenais à le faire savoir haut et fort : merci à vous, vous contribuez à mon quotidien et merci milles fois pour ce que vous faîtes.