Page 1 of 1

CreatePolygonRgn_() and windows xp

Posted: Sat Sep 03, 2005 9:07 pm
by Dr. Dri
i can use this function with windows 98 and there is no problem... but when i test my program with xp hte function always fails and returns 0...

is there a special way to use it with windows XP ? does anyone have a working example with XP ?

Dri

Posted: Sat Sep 03, 2005 10:09 pm
by GreenGiant
Seems to work fine for me. Using the code

Code: Select all

OpenWindow(0,0,0,400,400,#PB_Window_SystemMenu|#PB_Window_ScreenCentered,"Test")

Dim Array.Point(3)

Array(0)\x=12
Array(0)\y=12
Array(1)\x=100
Array(1)\y=31
Array(2)\x=120
Array(2)\y=150
Array(3)\x=43
Array(3)\y=230

hRgn=CreatePolygonRgn_(@Array(),4,#WINDING)
SetWindowRgn_(WindowID(0),hRgn,1)


Repeat
  ev=WaitWindowEvent()
Until ev=#PB_Event_CloseWindow

Hope this helps.

Posted: Sat Sep 03, 2005 10:28 pm
by Dr. Dri
thanks a lot

i think the problem comes from #Winding
replace it by zero and i think it won't work
but the zero works with win98

waiting for your answer

Dri :)

Posted: Sat Sep 03, 2005 11:17 pm
by GreenGiant
No, zero doesn't work for me. You'll need #Winding (2) or #Alternate (1). Not sure what the distinction is to be honest.

Posted: Sun Sep 04, 2005 2:27 pm
by akj
Here is some information I have found about the difference between WINDING and ALTERNATE.

When filling a polygon with colour, it is necessary to decide whether a given point is 'inside' or 'outside' the polygon. Obviously only 'inside' points should be changed to the fill colour.

The ALTERNATE and WINDING parameters determine the method used by the GDI [Graphics Device Interface] to decide whether a particular point [pixel] is 'inside' the polygon to be filled. Windows draws an imaginary left-to-right horizontal line from the point to infinity and notes where this line cuts edges of the polygon.

WINDING: Each time the horizontal line cuts an edge that was drawn in the anticlockwise direction (right-to-left or bottom-to-top) the point's winding number is incremented. Similarly, Each time the line cuts an edge that was drawn in the clockwise direction (left-to-right or top-to-bottom) the point's winding number is decremented. Those points that end up with a non-zero winding number are deemed to be 'inside' points.

ALTERNATE: Each time the horizontal line cuts an edge, a counter is incremented. Those points that end up with the counter having an odd value are deemed to be 'inside' points.

Frequently ALTERNATE and WINDING produce the same result, but when they do not, WINDING tends to fill more points than ALTERNATE.

WINDING is slower but tends to produce better results with complex polygons in which [some of] the edges intersect one another and/or with polygons that contain closed interior regions (i.e. chid polygons).

(The last two paragraphs are my own interpretion and may be wrong.)

Here is a program using ALTERNATE and WINDING:

Code: Select all

; Polygon  AKJ  04-Sep-04
; SetPolyFillMode_() Demo

; Read polygon co-ordinates (5-pointed star)
Dim ps.Point(4) ; Array of 5 POINT structures
For p=0 To 4: Read ps(p)\x: Read ps(p)\y: Next p
DataSection
  Data.l 60,10, 20,100, 115,42, 5,42, 100,100
EndDataSection

; GUI constants
Enumeration 1
  #winMain
  #imgPolygon ; Image gadget
EndEnumeration

; GUI metrics
gap=20 ; Border
imgw=140: imgh=imgw*2 ; ImageGadget
winw=imgw+gap*2: winh=imgh+gap*2 ; Window

; Create GUI, ignoring errors (let the debugger catch them)
flags= #PB_Window_SystemMenu
OpenWindow(#winMain,0,0,winw,winh,flags,"Poly Fill Mode")
CreateGadgetList(WindowID())
ImageGadget(#imgPolygon,gap,gap,0,0,0,#PB_Image_Border) ; Width, height will be that of image

; Define colours
red=RGB(255,0,0)
green=RGB(0,255,0)

; Define drawing area
CreateImage(#PB_Any,imgw,imgh)
hDC=StartDrawing(ImageOutput())
; Set the background to red
BackColor(Red(red),Green(red),Blue(red)) ; I wish the syntax was better !!!
Box(0,0,imgw,imgh,red) ; Would be nice to have a Cls() facility !!!
; Set the foreground to green
FrontColor(Red(green),Green(green),Blue(green)) ; I wish the syntax was better !!!

; Draw first closed polygon
Locate(0,0): DrawText(" ALTERNATE") ; The default fill mode
SetWindowOrgEx_(hDC,0,-15,#Null) ; Move origin downwards
Polygon_(hDC,@ps(0),5)

; Draw second closed polygon below the first
SetWindowOrgEx_(hDC,0,-145,#Null)
Locate(0,0): DrawText(" WINDING")
SetPolyFillMode_(hDC,#WINDING)
SetWindowOrgEx_(hDC,0,-160,#Null) ; The new origin is relative to the original origin
Polygon_(hDC,@ps(0),5)

; Release device context
StopDrawing()

; Display the drawing in an image gadget so that it is persistent
SetGadgetState(#imgPolygon,ImageID()) ; Must have ImageID() or UseImage(#image)

; AKJ standard skeleton event loop
done=#False
Repeat
  ev = WaitWindowEvent()
  If ev=#PB_EventMenu: ev=#PB_EventGadget: EndIf ; To map shortcut keys to gadgets
  Select ev
  Case #PB_Event_Gadget
    Select EventGadgetID()
    ; !!!
    EndSelect
  Case #PB_Event_CloseWindow
    done=#True
  EndSelect
Until done
CloseWindow(#winMain)
End