Re: Clickable windows areas

new topic     » goto parent     » topic index » view thread      » older message » newer message

> > Evan Marshall wrote:
> > > Is there an easy(+ or -) way to make certain areas of a window
> > > clickable?
> > > I have an image of a piano keyboard and I'd like to be able to make the
> > > keys clickable.
> > > I could use an onMouse event and check to see if the mouse was in the
> > > area of a certain key, but I am hoping there is an easier way.


Hi Evan,

Here is a short (not very) tutorial on subclassing for interested parties.

the (below) routine will be used to create buttons "Push type"

global function makebutton(atom hwnd, atom cid, integer x1, integer y1, integer
x2, integer y2)
atom id

id =
  CreateWindow(WS_EX_TRANSPARENT,"button","",or_all({WS_CHILD,WS_VISIBLE,BS_OWNERDRAW}),
                     x1,y1,x2,y2,hwnd,cid,hInst,0)
  return id
end function

initially because I use WS_EX_TRANSPARENT the buttons arent seen on screen and
BS_OWNERDRAW allows
me to put bitmaps or just about anything onto the buttons face.

you need to setup a routine that will tell you your mouse is either in or has
left your buttons:
(this routine works in Windows 95b and up)

integer x_TrackMouseEvent 
x_TrackMouseEvent = define_c_proc( comctl32, "_TrackMouseEvent",{C_LONG})

TME = allococate(16)
poke4(TME + TME_cbSize, 16)
poke4(TME + TME_dwFlags,TME_LEAVE)
poke4(TME + TME_dwHoverTime, HOVER_DEFAULT)

then I subclass the buttons inside my MainWindowProc's WM_CREATE: 
DefBtnCtrlProc = SetWindowLong(buttonname,GWL_WNDPROC,iBtnCtrlProc)

and finally the subclass routine itself (below): 
"This allows me to catch anything that happens to my buttons by handle"

atom DefBtnCtrlProc

integer inControl, isClicked

function BtnCtrlProc(atom handle, atom iMsg, atom wParam, atom lParam)

    if iMsg = WM_LBUTTONDOWN then
        
       if handle = buttonname then     
          -- do something
      end if
   end if
     
    elsif iMsg = WM_MOUSEMOVE then

          poke4(TME + TME_hwndTrack, handle)
          c_proc(x_TrackMouseEvent,{TME})  
         
          hdc = GetDC(hwnd)
                    
          if handle = buttonname then
             -- do something
          end if
           
          ReleaseDC(hwnd, hdc)          
          inControl = 1
          
          end if

    elsif iMsg = WM_MOUSELEAVE then
    
          InvalidateRect(hwnd, tbrect, 0)   
          inControl = 0

     end if 
   end if
   
   return c_func(xCallWindowProc,{DefBtnCtrlProc, handle, iMsg, wParam, lParam})
   
end function

constant iBtnCtrlProc = call_back(routine_id("BtnCtrlProc"))

tbrect (above) is used to paint the area of a paticular button.
this is very helpfull to eliminate screen flicker by not repainting the 
entire window. This if you plan on highlighting your buttons when
your mouse is inside and turning it off when your mouse has left.

Subclassing is very easy stuff once you get the initial hang of it.
Sure it might take alittle more typing than if you were to use Win32lib
but this is much faster in execution, much smaller in size
and you have total control of what happens in your application.

95% of this code is transferable or will never need to be re-typed
so the advantages are very clear.

Alot of people would say that Im crazy for not using Win32lib for everything
but this just isnt so, I dont think Im crazy at all. 

Euman
euman at bellsouth.net

new topic     » goto parent     » topic index » view thread      » older message » newer message

Search



Quick Links

User menu

Not signed in.

Misc Menu