Window Region

Just starting out? Need help? Post your questions and find answers here.
Konne
Enthusiast
Enthusiast
Posts: 434
Joined: Thu May 12, 2005 9:15 pm

Window Region

Post 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
Apart from that Mrs Lincoln, how was the show?
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post 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
I may look like a mule, but I'm not a complete ass.
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8451
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Post 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.
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post 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?
I may look like a mule, but I'm not a complete ass.
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8451
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Post 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.
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post 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! :) )
I may look like a mule, but I'm not a complete ass.
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8451
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Post 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.
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post 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.)
I may look like a mule, but I'm not a complete ass.
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8451
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Post 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
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post 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. :)
I may look like a mule, but I'm not a complete ass.
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8451
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Post 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... :D
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post 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.
I may look like a mule, but I'm not a complete ass.
Post Reply