Screenshots de l'écran, sauf notre fiche [Résolu]

Bacterius 3869 Messages postés samedi 22 décembre 2007Date d'inscription 3 juin 2016 Dernière intervention - 11 oct. 2009 à 01:43 - Dernière réponse : phephelavi 40 Messages postés mardi 16 mai 2006Date d'inscription 27 octobre 2009 Dernière intervention
- 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 !
Afficher la suite 

Votre réponse

9 réponses

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

Cordialement, Bacterius !

Merci Bacterius 3

Avec quelques mots c'est encore mieux Ajouter un commentaire

Codes Sources a aidé 89 internautes ce mois-ci

Commenter la réponse de Bacterius
Bacterius 3869 Messages postés samedi 22 décembre 2007Date d'inscription 3 juin 2016 Dernière intervention - 11 oct. 2009 à 02:20
0
Merci
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 !
Commenter la réponse de Bacterius
Bacterius 3869 Messages postés samedi 22 décembre 2007Date d'inscription 3 juin 2016 Dernière intervention - 11 oct. 2009 à 02:24
0
Merci
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 !
Commenter la réponse de Bacterius
Bacterius 3869 Messages postés samedi 22 décembre 2007Date d'inscription 3 juin 2016 Dernière intervention - 11 oct. 2009 à 02:45
0
Merci
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 !
Commenter la réponse de Bacterius
Bacterius 3869 Messages postés samedi 22 décembre 2007Date d'inscription 3 juin 2016 Dernière intervention - 11 oct. 2009 à 02:48
0
Merci
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 !
Commenter la réponse de Bacterius
Nicolas___ 1039 Messages postés jeudi 2 novembre 2000Date d'inscription 24 avril 2013 Dernière intervention - 11 oct. 2009 à 10:33
0
Merci
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 )
Commenter la réponse de Nicolas___
Bacterius 3869 Messages postés samedi 22 décembre 2007Date d'inscription 3 juin 2016 Dernière intervention - 11 oct. 2009 à 13:41
0
Merci
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 !
Commenter la réponse de Bacterius
cs_cantador 4996 Messages postés dimanche 26 février 2006Date d'inscription 27 mars 2018 Dernière intervention - 13 oct. 2009 à 19:46
0
Merci
bonsoir,

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


cantador
Commenter la réponse de cs_cantador
phephelavi 40 Messages postés mardi 16 mai 2006Date d'inscription 27 octobre 2009 Dernière intervention - 27 oct. 2009 à 15:38
0
Merci
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
Commenter la réponse de phephelavi

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.