Page 1 sur 1

Comprend pas pourquoi ça marche

Publié : dim. 09/mai/2004 15:46
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

Explications :

Publié : dim. 09/mai/2004 16:25
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é.

Publié : dim. 09/mai/2004 19:03
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

Publié : dim. 09/mai/2004 19:15
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 :)

Publié : dim. 09/mai/2004 23:22
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

Publié : dim. 09/mai/2004 23:56
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 :)

Publié : lun. 10/mai/2004 0:01
par nico
Si tu pouvais donner un exemple complet d'utilisation pour y regarder de plus près.

Publié : lun. 10/mai/2004 0:54
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

Publié : lun. 10/mai/2004 6:07
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_()...

Publié : lun. 10/mai/2004 19:30
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

Publié : mar. 11/mai/2004 6:12
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

Publié : mar. 11/mai/2004 8:17
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.

Publié : mar. 11/mai/2004 14:51
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..