Screenshots de l'écran, sauf notre fiche

Résolu
Bacterius Messages postés 3792 Date d'inscription samedi 22 décembre 2007 Statut Membre Dernière intervention 3 juin 2016 - 11 oct. 2009 à 01:43
phephelavi Messages postés 40 Date d'inscription mardi 16 mai 2006 Statut Membre Dernière intervention 27 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).

Cordialement, Bacterius !

9 réponses

Bacterius Messages postés 3792 Date d'inscription samedi 22 décembre 2007 Statut Membre Dernière intervention 3 juin 2016 10
11 oct. 2009 à 05:50
Bon en fait c'était simple ... faut rajouter le stdcall après la fonction d'énumération

Cordialement, Bacterius !
3
Bacterius Messages postés 3792 Date d'inscription samedi 22 décembre 2007 Statut Membre Dernière intervention 3 juin 2016 10
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) ...

Cordialement, Bacterius !
0
Bacterius Messages postés 3792 Date d'inscription samedi 22 décembre 2007 Statut Membre Dernière intervention 3 juin 2016 10
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 ?

Cordialement, Bacterius !
0
Bacterius Messages postés 3792 Date d'inscription samedi 22 décembre 2007 Statut Membre Dernière intervention 3 juin 2016 10
11 oct. 2009 à 02:45
Encore plus bizarre ... :

// Ne renvoie aucune erreur
EnumWindows(@EnumWindowsProc, 1)
// Déclenche une erreur
Button1.Caption := BoolToStr(EnumWindows(@EnumWindowsProc, 1), True);


Je comprends plus rien ?! Il y a un problème de mémoire là ...

Cordialement, Bacterius !
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Bacterius Messages postés 3792 Date d'inscription samedi 22 décembre 2007 Statut Membre Dernière intervention 3 juin 2016 10
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.



Cordialement, Bacterius !
0
Nicolas___ Messages postés 992 Date d'inscription jeudi 2 novembre 2000 Statut Membre Dernière intervention 24 avril 2013 1
11 oct. 2009 à 10:33
l'incroyable pouvoir de la réflexion dans toute sa puissance ...
lol

par contre tu passes de bonne nuit toi (ou tu te lèves vachement tôt quand tu as une idée en tête )
0
Bacterius Messages postés 3792 Date d'inscription samedi 22 décembre 2007 Statut Membre Dernière intervention 3 juin 2016 10
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.

Cordialement, Bacterius !
0
cs_cantador Messages postés 4720 Date d'inscription dimanche 26 février 2006 Statut Modérateur Dernière intervention 31 juillet 2021 13
13 oct. 2009 à 19:46
bonsoir,

génial Bacterius !
les questions, les réponses..
bref un forum à toi tout seul ! (lol)


cantador
0
phephelavi Messages postés 40 Date d'inscription mardi 16 mai 2006 Statut Membre Dernière intervention 27 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.

Bonne journée et à bientôt

Phephelavi
0
Rejoignez-nous