copie en image d'une fenetre

Vous débutez et vous avez besoin d'aide ? N'hésitez pas à poser vos questions
Patrick88
Messages : 1564
Inscription : mer. 21/janv./2004 18:24

copie en image d'une fenetre

Message par Patrick88 »

suite à une question de GallyHC et une réponse du Soldat Inconnu
j'ai bidouiller son code (voir post original là : http://www.purebasic.fr/french/viewtopi ... t&start=15) car je voulait également copier la fenêtre sans les gadgets... y'a d'ces tordus j'vous jure

après moult essai avec startdrawing, j'ai conclu que celui-ci ne copiait que la zone cliente de la fenêtre et pas la barre de la titre, les menus, la barre de défilement, la status bar... dans les fonctions de l'api windows, il y a "GetWindowDC_" qui permet de dessiner sur toute la fenêtre. ça marchotte à moitié que si la fenetre à copier ce trouve dans le coin haut/gauche du bureau, ailleurs (#PB_Window_ScreenCentered ou coord x,y de l'openwindow forcées) la fonction ne copie rien ? j'ai beau chercher je trouve pô :(

bon évidement, c'est plus portable :?

Code : Tout sélectionner

; Auteur : Le Soldat Inconnu
; Version de PB : 4.50
;
; Explication du programme :
; Pour faire des programmes de test rapidement, il ne reste qu'a rajouter les gadgets et la gestion des évènements.

Procedure Trace2(txt.s,v1,v2,v3,v4)
Debug "; "+txt+"="+Str(v1)+"/"+Str(v2)+"/"+Str(v3)+"/"+Str(v4)
EndProcedure
Procedure Trace1(txt.s,valeur)
Debug "; "+txt+" = "  +Str(valeur)
EndProcedure

; Création de la fenêtre et de la GadgetList
; copie fenetre fonctionne si fenetre à copier = en 0,0
If OpenWindow(0, 0, 0, 300, 300, "Test", #PB_Window_SystemMenu | #PB_Window_MinimizeGadget) = 0
;If OpenWindow(0, 0, 0, 300, 300, "Test", #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_MinimizeGadget) = 0
  End
EndIf

If OpenWindow(1, 0, 0, 600, 600, "reçoit les copies", #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_MinimizeGadget) = 0
	End
EndIf


StickyWindow(0, 1)
UseGadgetList(WindowID(0))
ButtonGadget(0, 5, 10, 50, 25, "Coucou")

; On attend pour permettre l'affichage
For x = 1 To 20
		While WindowEvent()
				
		Wend
		Delay(100)
Next


;{ On dessine sur la fenêtre pour copier le bouton

; Zone mémoire pour la copie du gadget
Dim Image.l(GadgetWidth(0) - 1, GadgetHeight(0) - 1)

If StartDrawing(WindowOutput(0))
  x1 = GadgetX(0)
  x2 = x1 + GadgetWidth(0) - 1
  y1 = GadgetY(0)
  y2 = y1 + GadgetHeight(0) - 1
  For x = x1 To x2
    For y = y1 To y2
      Image(x - x1, y - y1) = Point(x, y)
    Next
  Next
  StopDrawing()
EndIf

; On crée l'image du gadget
CreateImage(1, GadgetWidth(0), GadgetHeight(0))
If StartDrawing(ImageOutput(1))
	For x = 0 To GadgetWidth(0) - 1
		For y = 0 To GadgetHeight(0) - 1
				Plot(x, y, Image(x, y))
		Next
	Next
	StopDrawing()
EndIf
;}

HideGadget(0,1)
		
;{- Encombrement réel de la fenêtre
GetWindowRect_(WindowID(0), Win.RECT)
HautWin.w = Win\bottom - Win\top
LargWin.w = Win\right - Win\left

Dim fenetre.l(LargWin,HautWin)

;trace2("hgbd",Win\left,Win\top,Win\right,Win\bottom)
; hgbd=687/359/993/691

; On dessine sur la fenêtre pour copier la fenetre
HDC.l = GetWindowDC_(WindowID(0))
If HDC
;// startdrawing ne fonctionne que dans la zone utile (celle retournée par GetClientRect_()
;// voir exemple "dimension fenetre exploitable.pb"
; utilisez "GetWindowDC_" = retrieves the device context (DC) for the entire window, including title bar, menus, and scroll bars
  If GetPixel_(HDC,10, 10)=#CLR_INVALID
     Debug "probleme"   
  EndIf
  For x = Win\left To Win\right
    For y = Win\top To Win\bottom
      ;Trace2("X,Y,x - Win\left,y - Win\top",X,Y,x - Win\left, y - Win\top)
      ; Debug GetPixel_(HDC,x, y) renvoie -1 si coord xy fenetre <> 0,0 
      fenetre(x - Win\left, y - Win\top) = GetPixel_(HDC,x, y)
      ;SetPixel_(HDC,x, y,RGB(255,0,0))
	  Next
	Next
	ReleaseDC_(WindowOutput(0),HDC)
EndIf

; On crée l'image de la fenetre
CreateImage(2, LargWin, HautWin)
If StartDrawing(ImageOutput(2))
  For x = 0 To LargWin-1
		For y = 0 To HautWin-1
			Plot(x, y, fenetre(x, y))
		Next
  Next
  StopDrawing()
EndIf
;}

HideGadget(0,0)


; la copie de la fenetre et du gadget sont affichés sur la fenetre N° 2 (id = 1)
UseGadgetList(WindowID(1))
ImageGadget(1, 50, 50, ImageWidth(1), ImageHeight(1), ImageID(1))
ImageGadget(2, 100, 100, ImageWidth(2), ImageHeight(2), ImageID(2))

Repeat
	Event = WaitWindowEvent()
	
	Select Event
				Case #PB_Event_Menu
			Select EventMenu() ; Menus
					
						EndSelect
			
				Case #PB_Event_Gadget
			Select EventGadget() ; Gadgets
					
						EndSelect
		EndSelect
	
Until Event = #PB_Event_CloseWindow


je fais également référence à un code "dimension fenetre exploitable.pb" que voici que voilà

Code : Tout sélectionner

;/Constantes Window
Enumeration
  #Window_0
EndEnumeration

;/Constantes Gadget
Enumeration
  #Btn_Quit
  #StatusBar
  #Menu
EndEnumeration

If OpenWindow(#Window_0, 300, 300, 300, 200, "Fenêtre 1", #PB_Window_SystemMenu, 0)
  hWnd = WindowID(#Window_0)
  If CreateGadgetList(WindowID(#Window_0))
    ButtonGadget(#Btn_Quit, 100, 130, 100, 25, "Quitter")
    hMenu = CreateMenu(#Menu, hWnd)
    MenuTitle("Project")
    hStBar = CreateStatusBar(#StatusBar, hWnd)
  EndIf
 
  ;- Dimensions déclarées dans PureBasic
  Debug "Dimensions de la fenêtre fournies à PB"
  Debug "Hauteur = 200"
  Debug "Largeur = 300"
  Debug ""
 
  ;- Encombrement réel de la fenêtre
  Debug "Encombrement réel de la fenêtre"
  GetWindowRect_(hWnd, Win.RECT)
  HautWin.w = Win\bottom - Win\top : Debug "Hauteur = " + Str(HautWin)
  LargWin.w = Win\right - Win\left : Debug "Largeur = " + Str(LargWin)
  Debug""
 
  ;-Zone "Utile" de la fenetre retournée par GetClientRect_()
  Debug "Zone calculée par GetClientRect_()"
  Debug "La fonction retire la hauteur du menu"
  GetClientRect_(hWnd, @lpRect.RECT)
  Haut.w = lpRect\bottom - lpRect\top
  Larg.w = lpRect\right - lpRect\left
  Debug "Hauteur = " + Str(Haut)
  Debug "Largeur = " + Str(Larg)
  Debug ""
 
  ;- Hauteur du menu
  HautMenu = MenuHeight()
  Debug "Hauteur du menu = " + Str(HautMenu)+" (Déjà retiré)"
;
  ;- Hauteur de la barre d'état
  SendMessage_(hStBar, #SB_GETRECT, 0, @Rect.RECT)
  Haut_Bar = Rect\bottom - Rect\top
  Debug "Hauteur de la barre d'état = " + Str(Haut_Bar)
  Debug ""
 
  ;- Dimensions exploitables de la fenêtre, hors menu et barre d'état
  HauteurFenetre = Haut - Haut_Bar
  LargeurFenetre = Larg
  Debug "Dimensions exploitables, (sans le menu et la StatusBar)"
  Debug "Hauteur = " + Str(HauteurFenetre)
  Debug "Largeur = " + Str(LargeurFenetre)
  ;
  Repeat
    Select WaitWindowEvent()
      Case #PB_Event_Gadget
        Select EventGadget()
          Case #Btn_Quit : quit = 1
        EndSelect
      Case #PB_Event_CloseWindow : quit = 1
    EndSelect
  Until quit = 1
  End
EndIf

pat
Avatar de l’utilisateur
kernadec
Messages : 1606
Inscription : ven. 25/avr./2008 11:14

Re: copie en image d'une fenetre

Message par kernadec »

bonjour Patrick88
Pour Windows voilà.
j'utilise le code de danilo, voiçi l'exemple pour Windows XP
il recherche la fenêtre par son nom ici : "TEST".

pour Vista et Seven il faudra modifier les décalages des fenêtres

Cordialement

Code : Tout sélectionner


; Author: Danilo (updated for PB4.00 by blbltheworm)
; Date: 29. October 2003
; OS: Windows
; Demo: No

Procedure MakeWinScreenshot(ImageNr,hWnd,Width,Height) 
   hImage = CreateImage(ImageNr,Width,Height) 
   hDC    = StartDrawing(ImageOutput(ImageNr)) 
   WndDC  = GetDC_(hWnd) 
      BitBlt_(hDC,0,0,Width,Height,WndDC,-3,-29,#SRCCOPY) 
   StopDrawing() 
   ReleaseDC_(hWnd,WndDC) 
   ProcedureReturn hImage 
EndProcedure 

OpenWindow(0,0,0,300,200,"TEST",#PB_Window_SystemMenu) 

OpenWindow(1,0,0,340,250,"",#PB_Window_SystemMenu|#PB_Window_Invisible|#PB_Window_ScreenCentered) 
  

hShotWindow = FindWindow_(0,"TEST") 
If hShotWindow 
   hWinBmp  = MakeWinScreenshot(1,hShotWindow,300+6,229+3) 
   ImageGadget(1,0,0,300+6,229+3,hWinBmp) 
EndIf 

HideWindow(1,0) 

Repeat:Until WaitWindowEvent()=#PB_Event_CloseWindow
Patrick88
Messages : 1564
Inscription : mer. 21/janv./2004 18:24

Re: copie en image d'une fenetre

Message par Patrick88 »

moui, mais je cherche à le faire sans utiliser les api de windows, car là je suis passé sous mac...

mais c'est pô grave, merci.

pat
Répondre