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...
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.
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

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
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.

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..