Page 1 of 1
Window Region
Posted: Wed Nov 08, 2006 6:03 pm
by Konne
Why is SetWindowRgn_ Working with a Containgergadget but not with a Buttongadget?
Code: Select all
hwnd=OpenWindow(1,100,100,500,500,"Test Flat scroll Bar")
CreateGadgetList(hwnd)
SetWindowColor(1,$FF)
Reg=CreateEllipticRgn_(0,0,100,100)
ContainerGadget(0,0,0,100,100)
SetGadgetColor(0, #PB_Gadget_BackColor,$FFFF)
Debug SetWindowRgn_(GadgetID(0),Reg,1)
CloseGadgetList()
Reg=CreateEllipticRgn_(0,0,100,100)
ButtonGadget(15,100,100,100,100,"TEST")
Debug SetWindowRgn_(GadgetID(15),Reg,1)
Repeat
WaitWindowEvent()
ForEver
Posted: Wed Nov 08, 2006 6:23 pm
by srod
Code: Select all
hwnd=OpenWindow(1,100,100,500,500,"Test Flat scroll Bar")
CreateGadgetList(hwnd)
SetWindowColor(1,$FF)
Reg=CreateEllipticRgn_(0,0,100,100)
ContainerGadget(0,0,0,100,100)
SetGadgetColor(0, #PB_Gadget_BackColor,$FFFF)
SetWindowRgn_(GadgetID(0),Reg,1)
CloseGadgetList()
Reg=CreateEllipticRgn_(10,10,90,90)
ButtonGadget(15,100,100,100,100,"TEST",#WS_CLIPSIBLINGS|#WS_CLIPCHILDREN)
SetWindowRgn_(GadgetID(15),Reg,1)
Repeat
WaitWindowEvent()
ForEver
Posted: Wed Nov 08, 2006 6:50 pm
by netmaestro
Button controls are created from a class that has the CS_PARENTDC style. This means when the control is drawn, its clipping rectangle is set to the clipping rectangle of the parent class. Srod's tweak to your code effectively modifies this behavior. However, successfully setting the clipping region for a button is only a start, as you will have removed the bounding visual effect and it won't visually act much like a button anymore. Setting up a subclass and doing some ownerdrawing is necessary from here in order to make it work like a button.
Posted: Wed Nov 08, 2006 6:56 pm
by srod
I was hoping no one would spot that!
I agree though, setting the window region for such controls doesn't, in itself, work very well.
Did you do this with your custom buttons lib or did you avoid button controls altogether?
Posted: Wed Nov 08, 2006 7:03 pm
by netmaestro
I avoided button controls altogether. The CustomButton is a static control with the SS_BITMAP style and it does everything with images. Using the button control for such a project would have limited me to providing only certain specialized shapes, mainly because ownerdrawing is a necessary step, whereas images allow for wide-open user button design.
Posted: Wed Nov 08, 2006 7:15 pm
by srod
Do you use SetWindowRgn_() on the said static controls and somehow create a window region based upon the bitmaps? Or does the library check that the cursor is not over a pixel with the transparent colour before registering a mouse-over or mouse-click etc?
(Hope you don't mind me asking, just curious you know!

)
Posted: Wed Nov 08, 2006 7:34 pm
by netmaestro
Collision is tested with PtinRect if no mask image is included in the strip, but if it finds a mask image on the strip a region is scanned from the mask and collision testing switches to PtinRegion. A region is only necessary for non-rectangular buttons to keep collision testing accurate, and as it takes a few ms to scan a region, they're only employed when needed.
Posted: Wed Nov 08, 2006 7:47 pm
by srod
Interesting.
How exactly do you 'scan' a region?
(Sorry for the 101 questions, but I have little experience with regions and such like.)
Posted: Wed Nov 08, 2006 8:03 pm
by netmaestro
No problem, it's really quite straightforward:
Code: Select all
; Useless program #227-B: Region Scanner Demo
; Author: netmaestro
; Date: November 8, 2006
Procedure ScanRegion(image)
Protected width, height
width = ImageWidth(image)
height = ImageHeight(image)
hRgn = CreateRectRgn_(0, 0, Width, Height)
StartDrawing(ImageOutput(image))
For y=0 To ImageHeight(image)
For x=0 To ImageWidth(image)
color = Point(x,y)
If color = #Black
hTmpRgn = CreateRectRgn_(x,y,x+1,y+1)
CombineRgn_(hRgn, hRgn, hTmpRgn, #RGN_XOR)
DeleteObject_(hTmpRgn)
EndIf
Next
Next
StopDrawing()
ProcedureReturn hRgn;
EndProcedure
CreateImage(0,200,100)
StartDrawing(ImageOutput(0))
Box(10,20,120,60,#White)
Ellipse(150,50,50,50,#White)
StopDrawing()
hRgn = ScanRegion(0)
OpenWindow(0,0,0,200,100,"Region Scanner Demo",$CF0001)
SetWindowColor(0,#Blue)
CreateGadgetList(WindowID(0))
ContainerGadget(0,0,0,200,100)
SetWindowRgn_(GadgetID(0), hRgn, 1)
Repeat:Until WaitWindowEvent() = #WM_CLOSE
DeleteObject_(hRgn)
End
Posted: Wed Nov 08, 2006 8:17 pm
by srod
Very nice.
I thought there might be some flash api function which might simply tear out the masked image and create a region etc.
That's a great example. Thanks.

Posted: Wed Nov 08, 2006 8:23 pm
by netmaestro
You're most welcome. ...Well there very well could be but I usually do things the hard way for quite a while before I come across it. I once spent a day and a half writing a long solution for a timepicker and then I found you could do it in one line like this:
Code: Select all
dtp = CreateWindowEx_(0,"SysDateTimePick32","",#WS_CHILD|#WS_VISIBLE|#DTS_TIMEFORMAT,100,100,100,22,WindowID(0),0,GetModuleHandle_(0),0)
so it wouldn't shock me to discover I've done the same thing here...

Posted: Wed Nov 08, 2006 8:29 pm
by srod
I certainly found no likely looking api function with but a quick trawl through the docs. Perhaps gdi+ has something?
I seem to remember Mischa doing something along these lines when skinning windows, but the details elude me at the moment.
Anyhow, I've saved this example in my little black box of snippets and useful titbits.
Thanks again.