Re: Clickable windows areas
- Posted by euman at bellsouth.net Mar 30, 2002
- 428 views
> > 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