Comprend pas pourquoi ça marche

Vous débutez et vous avez besoin d'aide ? N'hésitez pas à poser vos questions
Guimauve
Messages : 1015
Inscription : mer. 11/févr./2004 0:32
Localisation : Québec, Canada

Comprend pas pourquoi ça marche

Message par Guimauve »

J'ai adapté deux procédures pour renverser un image en X et en Y pour en faire une librairie perso. Et je ne comprend pas le GetWindowDC_ (Image). C'est pas une fenètre que je manipule, c'est un image... 8O

Code : Tout sélectionner

ProcedureDLL MirrorImageX(Image.l)
     ; Mirrors an image around the X-axis
     
     hDC = GetWindowDC_ (Image)
     Width.l = ImageWidth()
     Height.l = ImageHeight()
     hDC.l = StartDrawing(ImageOutput())
          StretchBlt_(hDC, 0, Height, Width, -Height, hDC, 0, 0, Width, Height, #SRCCOPY)
     StopDrawing()
     ReleaseDC_ (image, hDC)
EndProcedure

ProcedureDLL MirrorImageY(Image.l)
     ; Mirrors an image around the Y-axis
     hDC = GetWindowDC_ (Image)
     Width.l = ImageWidth()
     Height.l = ImageHeight()
     hDC.l = StartDrawing(ImageOutput())
          StretchBlt_(hDC, Width, 0, -Width, Height, hDC, 0, 0, Width, Height, #SRCCOPY)
     StopDrawing()
     ReleaseDC_ (image, hDC)
EndProcedure
J'ai bien peur que si je travaille sur des BMP qui sont plus grand que la résolution de la fenètre ça va boguer sérieux. J'ai pas tester mais logiquement le dessin est plus grand que la feuille.

A+
Guimauve
DominiqueB
Messages : 47
Inscription : sam. 01/mai/2004 14:41

Explications :

Message par DominiqueB »

Salut,
je crois qu'il y a une petite incompréhension de ta part sur ce qu'est un DC: la fonction traduite en francais donne à peu près ceci: Récupérer le Device Context de la fenêtre. Donc ce n'est pas une image que cette fonction prend en paramètre, mais une fenêtre.
Aide en anglais:
"The GetWindowDC function retrieves the device context (DC) for the entire window, including title bar, menus, and scroll bars. A window device context permits painting anywhere in a window, because the origin of the device context is the upper-left corner of the window instead of the client area."
En clair tu peux dessiner dans le DC d'une fenêtre à peu près n'importe ou, même dans la barre de titre . . .

J'espère t'avoir éclairé.
Dominique
Guimauve
Messages : 1015
Inscription : mer. 11/févr./2004 0:32
Localisation : Québec, Canada

Message par Guimauve »

DominiqueB a écrit :En clair tu peux dessiner dans le DC d'une fenêtre à peu près n'importe ou, même dans la barre de titre . . .

J'espère t'avoir éclairé
Oui et non en même temps.

Ça fonctionne même s'il n'y a pas de fenètre de créé par le programme.

Donc j'en conclus qu'il s'agit plutôt d'un espace dessin que d'une fenètre. Le coin en haut à gauche est 0,0 mais la largeur et la hauteur prennent quelle valeur ?

Je suis dingue je pose des question alors que ça marche. D'habitude on fait le contraire. :roll:

A+
Guimauve
nico
Messages : 3702
Inscription : ven. 13/févr./2004 0:57

Message par nico »

A mon avis les fonctions: hDC = GetWindowDC_ (Image) et ReleaseDC_ (image, hDC) ne servent à rien du tout (puisque tu t'en sert pas!)

voilà pourquoi ça marche :)
Guimauve
Messages : 1015
Inscription : mer. 11/févr./2004 0:32
Localisation : Québec, Canada

Message par Guimauve »

nico a écrit :A mon avis les fonctions: hDC = GetWindowDC_ (Image) et ReleaseDC_ (image, hDC) ne servent à rien du tout (puisque tu t'en sert pas!)

voilà pourquoi ça marche Image
Mais si j'enlève le hDC = GetWindowDC_ (ImageID), il n'y a plus rien qui marche.

Je commence à peine à utiliser les fonctions de l'API, il y a des tas et des tas de chose qui me sont obscures pour le moment. C'est pour ça que je pose des questions.

Une version légèrement modifié.

Code : Tout sélectionner

#Vertical = 0
#Horizontal = 1

ProcedureDLL MirrorImage(ImageID.l, Orientation.b)
    
     hDC = GetWindowDC_ (ImageID)
     Width.l = ImageWidth()
     Height.l = ImageHeight()
     
     If Orientation = #Vertical
          hDC = StartDrawing(ImageOutput())
               StretchBlt_(hDC, 0, Height, Width, -Height, hDC, 0, 0, Width, Height, #SRCCOPY)
          StopDrawing()

     ElseIf Orientation = #Horizontal
          hDC = StartDrawing(ImageOutput())
               StretchBlt_(hDC, Width, 0, -Width, Height, hDC, 0, 0, Width, Height, #SRCCOPY)
          StopDrawing()
          
     EndIf
     
     ReleaseDC_ (ImageID, hDC)
     
EndProcedure
A+
Guimauve
Avatar de l’utilisateur
Chris
Messages : 3731
Inscription : sam. 24/janv./2004 14:54
Contact :

Message par Chris »

Moi, il y a un truc que je comprends pas, surtout dans ton premier code. Du coup, je suis, moi aussi, étonné que ça marche.

Mais bon, n'étant pas trop un spécialiste, si quelqu'un a une explication...

Voilà, j'explique : Je prends la deuxième procédure, mais il y a le même truc dans les deux.
ProcedureDLL MirrorImageY(Image.l)
; Mirrors an image around the Y-axis

hDC = GetWindowDC_ (Image) <--- Ici, tu récupère le DC de Image . Tu lui donnes le nom de hDC : Ok

Width.l = ImageWidth()
Height.l = ImageHeight()

hDC.l = StartDrawing(ImageOutput()) <-- Ici, tu redonnes le même nom à un autre DC

Et dans la fonction du dessous, tu copies ce qui est dans le DC Source nommé hDC, dans le DC destination, lui aussi nommé hDC.
StretchBlt_(hDC, Width, 0, -Width, Height, hDC, 0, 0, Width, Height, #SRCCOPY)

StopDrawing()
ReleaseDC_ (image, hDC)
EndProcedure
8O :?

Chris :)
nico
Messages : 3702
Inscription : ven. 13/févr./2004 0:57

Message par nico »

Si tu pouvais donner un exemple complet d'utilisation pour y regarder de plus près.
Guimauve
Messages : 1015
Inscription : mer. 11/févr./2004 0:32
Localisation : Québec, Canada

Message par Guimauve »

Voiçi un exemple d'utilisation

Code : Tout sélectionner

#Vertical = 0 
#Horizontal = 1 

Procedure MirrorImage(ImageID.l, Orientation.b) 
    
     hDC = GetWindowDC_ (ImageID) 
     Width.l = ImageWidth() 
     Height.l = ImageHeight() 
      
     If Orientation = #Vertical 
          hDC = StartDrawing(ImageOutput()) 
               StretchBlt_(hDC, 0, Height, Width, -Height, hDC, 0, 0, Width, Height, #SRCCOPY) 
          StopDrawing() 

     ElseIf Orientation = #Horizontal 
          hDC = StartDrawing(ImageOutput()) 
               StretchBlt_(hDC, Width, 0, -Width, Height, hDC, 0, 0, Width, Height, #SRCCOPY) 
          StopDrawing() 
          
     EndIf 
      
     ReleaseDC_ (ImageID, hDC) 
      
EndProcedure

bmp = LoadImage(0, "Image.bmp")

If OpenWindow (0, 320, 200, 400, 400, #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_MaximizeGadget, "Test")
     
EndIf

;MirrorImage(bmp,#Vertical)
MirrorImage(bmp,#Horizontal)

Repeat
     
     StartDrawing (WindowOutput())
          DrawImage (ImageID(), 0, 0)
     StopDrawing ()
     
Until WaitWindowEvent () = #PB_EventCloseWindow

End
Chris a écrit :Du coup, je suis, moi aussi, étonné que ça marche.
En effet le code semble lire et écrire dans la même zone mémoire en même temps. Il y a sûrment une chose qui nous échappe puisque ça marche. #hein Je comprends pas comment ce code peut passer sans planter le PC.

À moins que la fonction StretchBlt_(hDC, Width, 0, -Width, Height, hDC, 0, 0, Width, Height, #SRCCOPY) utilise une mémoire tampon pour faire le travail et écraser l'image original par l'image renversé après avoir terminer les opérations de renversement de l'image.

Fred, à l'aide :!:

A+
Guimauve
Avatar de l’utilisateur
cederavic
Messages : 1338
Inscription : lun. 09/févr./2004 23:38
Localisation : Bordeaux

Message par cederavic »

si j'ai bien compris (d'apres la doc), StrechBlt prend le contenu du DC source, le modifi (en memoire) et ensuite, le recopi dans le DC destination, donc c'est normal que StrechBlt la fonctionne, par contre, c'et byzard pour GetWindowDC_()...
Avatar de l’utilisateur
Flype
Messages : 2431
Inscription : jeu. 29/janv./2004 0:26
Localisation : Nantes

Message par Flype »

je vois pas l'interet de ton getwindowdc_()
d'ailleurs du coup je l'enleve et ca marche tres bien
plus court, plus propre, presque pareil :

Code : Tout sélectionner

#Vertical = 0
#Horizontal = 1

Procedure MirrorImage(ImageID.l, Orientation.b)
  
  Width.l  = ImageWidth()
  Height.l = ImageHeight()
  
  If Orientation = #Vertical
    
    hDC = StartDrawing(ImageOutput())
      StretchBlt_(hDC, 0, Height, Width, -Height, hDC, 0, 0, Width, Height, #SRCCOPY)
    StopDrawing()
    
  ElseIf Orientation = #Horizontal
    
    hDC = StartDrawing(ImageOutput())
      StretchBlt_(hDC, Width, 0, -Width, Height, hDC, 0, 0, Width, Height, #SRCCOPY)
    StopDrawing()
    
  EndIf
  
EndProcedure

OpenWindow (0, 320, 200, 400, 400, #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_MaximizeGadget, "Test")

bmp = LoadImage(0, "Image.bmp")
MirrorImage(bmp,#Vertical)
MirrorImage(bmp,#Horizontal)

Repeat
  StartDrawing (WindowOutput())
    DrawImage (ImageID(), 0, 0)
  StopDrawing ()
Until WaitWindowEvent () = #PB_EventCloseWindow

End
Image
Guimauve
Messages : 1015
Inscription : mer. 11/févr./2004 0:32
Localisation : Québec, Canada

Message par Guimauve »

Et encore plus simple et je ne comprends vraiment plus rien.

Code : Tout sélectionner

#Vertical = 0 
#Horizontal = 1 

Procedure MirrorImage(Orientation.b) 
  
  Width.l  = ImageWidth() 
  Height.l = ImageHeight() 
  
  If Orientation = #Vertical 
    
    hDC = StartDrawing(ImageOutput()) 
      StretchBlt_(hDC, 0, Height, Width, -Height, hDC, 0, 0, Width, Height, #SRCCOPY) 
    StopDrawing() 
    
  ElseIf Orientation = #Horizontal 
    
    hDC = StartDrawing(ImageOutput()) 
      StretchBlt_(hDC, Width, 0, -Width, Height, hDC, 0, 0, Width, Height, #SRCCOPY) 
    StopDrawing() 
    
  EndIf 
  
EndProcedure 

OpenWindow (0, 320, 200, 400, 400, #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_MaximizeGadget, "Test") 

 
LoadImage(0, "Image.bmp") 
MirrorImage(#Vertical) 
MirrorImage(#Horizontal) 

Repeat 
  StartDrawing (WindowOutput()) 
    DrawImage (ImageID(), 0, 0) 
  StopDrawing () 
Until WaitWindowEvent () = #PB_EventCloseWindow 

End
Ça marche même sans passer le Handle de l'image à la procédure, juste un LoadImage, un UseImage , ou un CreateImage devant et ça fonctionne.

Et bien merci Flype.

A+
Guimauve
Anonyme2
Messages : 3518
Inscription : jeu. 22/janv./2004 14:31
Localisation : Sourans

Message par Anonyme2 »

Code : Tout sélectionner

Ça marche même sans passer le Handle de l'image à la procédure, juste un LoadImage, un UseImage , ou un CreateImage devant et ça fonctionne. 
Le fait de charger une image avec Loadimage ou Catchimage fait que tu as une image par défaut.

Si tu charges plusieurs images, la commande UseImage(#Image) permet de sélectionner l'image par défaut que tu veux. PB ensuite se charge de retrouver le Handle, c'est transparent pour l'utilisateur.
Fred
Site Admin
Messages : 2652
Inscription : mer. 21/janv./2004 11:03

Message par Fred »

Juste pour apporter une precision, GetWindowDC_() n'est à utiliser qu'avec une fenetre (d'ou son nom). Quand on manipule des images, il faut faire un 'CreateCompatibleDC_()' suivi d'un SelectObject_() pour associer ce DC à une image. C'est un peut plus fastidieux, mais bon. C'est ce que la commande StartDrawing(ImageOutput()) fait. Voila, Voila..
Répondre