Probleme CreatePolygonRgn

Signaler
Messages postés
34
Date d'inscription
samedi 3 juin 2006
Statut
Membre
Dernière intervention
23 avril 2011
-
Messages postés
693
Date d'inscription
samedi 18 mai 2002
Statut
Membre
Dernière intervention
17 avril 2017
-
Bonjour a Tous...

c'est un retour pour moi ici, ca fait un bail que je ne suis pas venu. Je suis plutot niveau Expert en Vb6 et donc, les questions que je pose parfois sont souvent laissé sans réponses!

Néammoins, votre aide est toujours la bienvenu, si vous pouvez me sortir du pétrin!

Alors voici le topo... j'ai fait un programme en Vb6 qui permet d'automatiser la creation de Skin (form de forme non rectangulaire). En gros le programme fabrique une Skin a partir d'une image PNG que vous avez.

Ca m'a pris toute la journee, mais ca marche nickel... sauf un detail. Quand je decoupe le form avec CreatePolygonRgn, il semble que je suis 1 pixel court pour le coté droit et le bas... Ce qui est plutot etrange car les coordonné sont bien exacte, j'ai vérifier...

j'ai donc fait un programme de TEST qui créer une forme géometrique simple (triangle) et j'inverse les couleur dedans avec un BRUSH.

j'ai le meme probleme. La regions créer est 1 pixel SHORT (court) coté droit et en bas...
alors pour mieux comprendre, voici l'exemple.

quand vous cliquer le Form, le triangle est supposé s'inverser ainsi que les limites du triangle (paint en une couleur differente)
pourtant, le coté droit ainsi que le bas est court d'un pixel...

tout aide sera aprécié....

le code:
Option Explicit

Private Type POINTAPI
x As Long
y As Long
End Type
Private Const ALTERNATE As Long = 1
Private Const WINDING As Long = 2
Private Declare Function CreatePolygonRgn Lib "gdi32.dll" (ByRef lpPoint As POINTAPI, ByVal nCount As Long, ByVal nPolyFillMode As Long) As Long
Private Declare Function InvertRgn Lib "gdi32.dll" (ByVal hdc As Long, ByVal hRgn As Long) As Long
Private Declare Function DeleteObject Lib "gdi32.dll" (ByVal hObject As Long) As Long
Private Declare Function CreateSolidBrush Lib "gdi32.dll" (ByVal crColor As Long) As Long
Private Declare Function SelectObject Lib "gdi32.dll" (ByVal hdc As Long, ByVal hObject As Long) As Long
Private Declare Function FloodFill Lib "gdi32.dll" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long, ByVal crColor As Long) As Long

Private vertex(0 To 2) As POINTAPI ' array of region's vertices

Private Sub Form_Click()
' Invert the pixels within a triangular region on window Form1. The triangular
' region has vertices (150,150), (250, 200), and (100, 200). Note how the points are loaded
' into the array of vertices.
Dim hRgn As Long ' handle to the triangular region
Dim retval As Long ' return value

' Create the polygonal region based on the array of vertices.
hRgn = CreatePolygonRgn(vertex(0), 3, ALTERNATE) ' for a triangle, fill mode is irrelevant
' Invert the pixels within the triangular region on Form1.
retval = InvertRgn(Form1.hdc, hRgn)
Form1.Refresh

' Delete the region to free up resources.
retval = DeleteObject(hRgn)
End Sub

Private Sub Form_Load()
Dim lngNewBrush As Long
Dim lngOldBrush As Long
Dim lngColorPos As Long
Dim lngRetValue As Long

Form1.Caption = "region doesn't appear to be working properly"
Form1.AutoRedraw = True
Form1.ScaleMode = vbPixels
Form1.Width = 5100
Form1.Height = 4095

' Create and select a Brush of this color.
lngNewBrush = CreateSolidBrush(255)
lngOldBrush = SelectObject(Form1.hdc, lngNewBrush)

' Do the flood, stop when we reach [glngContoursColor] pixels.
lngColorPos = FloodFill(Form1.hdc, 150, 175, RGB(0, 0, 255))
' Select the old Brush and delete the new one.
lngRetValue = SelectObject(Form1.hdc, lngOldBrush)
If (lngRetValue <> lngNewBrush) Then
MsgBox "DeleteObject will probably fail!"
End If
lngRetValue = DeleteObject(lngNewBrush)
Form1.FillColor = RGB(255, 255, 255)
Form1.FontBold = True
Form1.FontSize = 12
Form1.Print " click the Form"


' Load the vertices of the triangular region into the array.
vertex(0).x 150: vertex(0).y 150 ' 1st point: (150,150)
vertex(1).x 250: vertex(1).y 200 ' 2nd point: (250,200)
vertex(2).x 100: vertex(2).y 200 ' 3rd point: (100,200)
Form1.Line (vertex(0).x, vertex(0).y)-(vertex(1).x, vertex(1).y), RGB(0, 0, 0)
Form1.Line (vertex(1).x, vertex(1).y)-(vertex(2).x, vertex(2).y), RGB(0, 0, 0)
Form1.Line (vertex(2).x, vertex(2).y)-(vertex(0).x, vertex(0).y), RGB(0, 0, 0)
End Sub

1 réponse

Messages postés
693
Date d'inscription
samedi 18 mai 2002
Statut
Membre
Dernière intervention
17 avril 2017
2
Bonjour,

En effet j'ai déjà constaté ce problème.
La solution est de créer un deuxième tableau de vecteurs, d'utiliser le 1er pour le tracé et le deuxième pour l'inversion en "trichant" d'un pixel sur les coordonnées.
En fait pour éviter le deuxième tableau, je simplifie en retraçant le contour après l'inversion.
Il est à noter que cette bizarrerie se produit également avec l'API FillRgn. Tout n'est pas rempli comme tout n'est pas inversé dans ton cas.
Quelque soit la forme, carrée, ronde, elliptique ou autre, il manque toujours un pixel en largeur et hauteur, comme si on avait une matrice de 0 à n-1.

Cheyenne