Masterhook / Eventhandling wie in .Net
Übersicht

![]() |
RoneBetreff: Masterhook / Eventhandling wie in .Net |
![]() Antworten mit Zitat ![]() |
---|---|---|
Hallo,
ich hab mir neulich mal dieses Masterhook sample angeschaut(hier), wobei mich dabei irgedwie störte, dass dass bei jedem Event eine Liste mit allen Gadgets durlaufen wird, nur um zu checken welches Gadget das Event ausgelöst hat. Dabei steht das gesuchte Gadget sowieso schon in 'Event.Source'....Auch sonst finde ich es ziemlich unpraktisch für jedes Gadget einen eigen Typ zu machen, zumindest in dieser form... Nunja, als ich dann 'TGAdget' um ein Funktionspointer-Attribut erweitern wollte, sah ich das so ein Attribut schon vorhanden ist.... Mein abgeänderter MasterHook: Code: [AUSKLAPPEN] Rem Rone's MAsterHook: Damit functioniert muss TTimer (Source Code/brl.mod/timer.mod/timer.bmx) um folgendes ergänzt werden: Field eventfilter(event:TEvent,context:Object) Field context:Object Method SetFilter(callback(event:TEvent,context:Object),user:Object) eventfilter=callback context=user End Method End Rem SuperStrict '########################################## Type TMasterEventHook Function InstallMasterHook() AddHook EmitEventHook,TMasterEventHook.ProcessEvents End Function Function ProcessEvents:Object(iId:Int,tData:Object,tContext:Object) If tData=Null Then Return Null Local tEv:TEvent = TEvent(tData), g:TGadget , t:TTimer If tEv.Id = EVENT_TIMERTICK Then t = TTimer(tEv.Source) If t And t.eventfilter Then t.eventfilter(tEv , Null) Return Null EndIf Else g = TGAdget(tEv.Source) If g And g.eventfilter Then g.eventfilter(tEv,Null) Return Null EndIf EndIf Return tData End Function End Type '############################ Type TTestApp Global handle :TTestApp Field gSync :TTimer Field gWin1 :TGadget Field gBut1 :TGadget Field gBut2 :TGadget Field gBut3 :TGadget Field gCanvas :TGAdget Field label :TGAdget Field font :TGuiFont Field backColor :Int[] = [ 0 , 0 , 0 ] Field zColor :Int[] = [ 255 , 255 , 255 ] Method Create:TTestApp() gWin1= CreateWindow("SuperHook!!" , 500 , 100 , 300 , 400 , Null , WINDOW_TITLEBAR | WINDOW_CLIENTCOORDS) gWin1.SetFilter(gWin1_OnEvent , Null) gBut1 = CreateButton("Back Color" , 0 , 300 , 80 , 25 , gWin1) gBut1.SetFilter(gBut1_OnEvent , Null) gBut2 = CreateButton("Zeiger Color" , 0 , 333 , 80 , 25 , gWin1) gBut2.SetFilter(gBut2_OnEvent , Null) gBut3 = CreateButton("Slect Font" , 0 , 366 , 80 , 25 , gWin1) gBut3.SetFilter(gBut3_OnEvent , Null) gCanvas = CreateCanvas ( 0 , 0 , 300 , 300 , gWin1) gCanvas.SetFilter(gCanvas_OnEvent , Null) gSync = CreateTimer(60) gSync.SetFilter(gSync_OnEvent , Null) label = CreateLabel("Bla" , 100 , 350 , 100 , 30 , gWin1) handle = Self Return Self End Method Function gWin1_OnEvent:Int(tEv:TEvent , context:Object) Select tEv.Id Case EVENT_WINDOWCLOSE End End Select End Function Function gBut1_OnEvent(tEv:TEvent,context:Object) If RequestColor(handle.backColor[0],handle.backColor[1],handle.backColor[2]) handle.backColor[0]=RequestedRed() handle.backColor[1]=RequestedGreen() handle.backColor[2]=RequestedBlue() EndIf End Function Function gBut2_OnEvent(tEv:TEvent,context:Object) If RequestColor(handle.zColor[0],handle.zColor[1],handle.zColor[2]) handle.zColor[0]=RequestedRed() handle.zColor[1]=RequestedGreen() handle.zColor[2]=RequestedBlue() EndIf End Function Function gBut3_OnEvent(tEv:TEvent,context:Object) handle.font=RequestFont(handle.font) If handle.font SetGadgetFont handle.label,handle.font SetGadgetText handle.label,FontName(handle.font)+":"+FontSize(handle.font) EndIf End Function Function gCanvas_OnEvent(tEv:TEvent , context:Object) Select tEv.Id Case EVENT_GADGETPAINT SetGraphics CanvasGraphics(handle.gCanvas) SetOrigin 150,150 SetClsColor handle.backColor[0],handle.backColor[1],handle.backColor[2] Cls SetLineWidth 1 SetColor 255-handle.backColor[0],255-handle.backColor[1],255-handle.backColor[2] For Local i:Int = 0 To 360 Step 10 DrawLine 0,0,140*Cos(i),140*Sin(i) Next SetColor handle.backColor[0],handle.backColor[1],handle.backColor[2] DrawOval -120,-120,240,240 SetColor handle.zColor[0] , handle.zColor[1] , handle.zColor[2] SetLineWidth 5 Local t:Int=MilliSecs() DrawLine 0,0,120*Cos(t*0.2),120*Sin(t*0.2) DrawLine 0,0,80*Cos(t/360),80*Sin(t/360) Flip End Select End Function Function gSync_OnEvent(tEv:TEvent , context:Object) RedrawGadget handle.gCanvas End Function End Type '#################################### TMasterEventHook.InstallMasterHook() Local test:TTestApp = New TTestApp.Create() 'Main loopage Repeat WaitEvent Forever End Bei mir bekommt jedes Gadget einfach eine OnEvent-Function auf die der Funktionspointer des Gadgets zeigt. Diese Wird dann einfach direkt über Event.Source.eventfilter(..) augerufen! Bin mir insofern ein bisschen unsicher, dass ich 'TTimer' ergänzt habe und nicht weiss wozu der 'eventfilter' in 'TGadget' sonst noch benutzt wird, konnte allerdings nichts finden.... So, was haltet ihr davon? Gut/Schlecht/Praktisch/UnPraktisch? mfg |
||
- Zuletzt bearbeitet von Rone am Mo, Feb 18, 2008 21:30, insgesamt einmal bearbeitet
![]() |
Rone |
![]() Antworten mit Zitat ![]() |
---|---|---|
Moin,
da es nun ja Reflections gibt, habe ich mein Eventhandling vor kurzen mal etwas abgeändert. Das ganze schaut nun in etwa so aus, wie in .Net, mit einem form_designer Type, in dem ausschließlich die Gadgets erstellt und die eventhandler zugewiesen werden, sowie einem Type, in dem die Eventhandler implementiert werden. Ich finde diese Trennung macht besonders größere Programme übersichtlicher und wartbarer.... Ein weiterer Vorteil ist, das die Eventhandler nun Methoden sind, wodurch man sich ein globales Handle sparen kann: main.bmx: Code: [AUSKLAPPEN] SuperStrict
Framework brl.Basic Import brl.maxgui ?Win32 Import brl.win32maxgui ?MacOS Import brl.cocoamaxgui ?Linux Import brl.fltkmaxgui ? Import brl.event Import brl.eventqueue Import brl.reflection Import brl.max2d Import brl.d3d7max2d Import brl.glmax2d Import brl.pngloader Import brl.retro Import brl.Timer Include "eventhandling.bmx" Include "dialog.bmx" Global masterhook:TMasterEventHook = New TMasterEventHook Global mainDlg:TMainDlg = New TMainDlg mainDlg.InitializeComponent() Repeat WaitEvent Forever End dialog.bmx: Code: [AUSKLAPPEN] Type TMainDesigner '#Region gadgets Field Window :TGadget Field cmdBli :TGadget Field cmdBla :TGadget Field cmdBlub :TGadget Field panel :TGadget Method Window_OnClose(event:TEvent) Abstract Method Window_OnResize(event:TEvent) Abstract Method Form1_Load(event:TEvent) Abstract Method cmdBli_click(event:TEvent) Abstract Method cmdBla_click(event:TEvent) Abstract Method cmdBlub_click(event:TEvent) Abstract Method panel1_mousemove(event:TEvent) Abstract Method panel1_mouseUp(event:TEvent) Abstract '#End Region Method InitializeComponent(parent:TGadget=Null) Window= CreateWindow("Test" , 250 , 250 , 250 , 250 , Null , 15 ) Local WindowEventHandler:TEventHandler = New TEventHandler WindowEventHandler.AddEventHandler(EVENT_WINDOWCLOSE,Self,"Window_OnClose") WindowEventHandler.AddEventHandler(EVENT_WINDOWSIZE,Self,"Window_OnResize") Window.context = WindowEventHandler cmdBli = CreateButton("Bli",0,0,100,25,Window) Local cmdBliEventHandler:TEventHandler = New TEventHandler cmdBliEventHandler.AddEventHandler(EVENT_GADGETACTION,Self,"cmdBli_Click") cmdBli.context = cmdBliEventHandler cmdBla = CreateButton("Bla",0,25,100,25,Window) Local cmdBlaEventHandler:TEventHandler = New TEventHandler cmdBlaEventHandler.AddEventHandler(EVENT_GADGETACTION,Self,"cmdBla_Click") cmdBla.context = cmdBlaEventHandler cmdBlub = CreateButton("Blub",0,50,100,25,Window) Local cmdBlubEventHandler:TEventHandler = New TEventHandler cmdBlubEventHandler.AddEventHandler(EVENT_GADGETACTION,Self,"cmdBlub_Click") cmdBlub.context = cmdBlubEventHandler panel = CreatePanel(100,0, 150, 250 ,Window, PANEL_ACTIVE) SetPanelColor panel,255,255,255 Local panelEventHandler:TEventHandler = New TEventHandler panelEventHandler.AddEventHandler(EVENT_MOUSEMOVE,Self,"panel1_mousemove") panelEventHandler.AddEventHandler(EVENT_MOUSEUP,Self,"panel1_mouseUp") panel.context = panelEventHandler Form1_Load(Null) End Method End Type Type TMainDlg Extends TMainDesigner Field Xpos :Int Field Ypos :Int Method Form1_Load(event:TEvent) End Method Method panel1_mouseUp(event:TEvent) Confirm(event.x +" / " + event.y ) End Method Method panel1_mousemove(event:TEvent) Xpos = event.x Ypos = event.y SetStatusText( Window, xpos + " / " + ypos ) End Method Method Window_OnResize(event:TEvent) Print "Size" End Method Method Window_OnClose(event:TEvent) End End Method Method cmdBli_click(event:TEvent) Confirm("Bli: " + xpos + " / " + ypos) End Method Method cmdBla_click(event:TEvent) Confirm("Bla: " + xpos + " / " + ypos) End Method Method cmdBlub_click(event:TEvent) Confirm("Blub: " + xpos + " / " + ypos) End Method End Type eventhandler.bmx Code: [AUSKLAPPEN] Type TMethodPointer Field methodName:String Field contextObject:Object Field id:TTypeId Field Update:TMethod Method SetMethod( context:Object, methodName:String ) Assert context, "TMethodPointer.SetMethod: context-Argument Null Exception!" Assert (methodName Or methodName<>""), "TMethodPointer.SetMethod: methodName-Argument Null Exception!" Self.methodName = methodName contextObject = context id=TTypeId.ForObject( context) Update=id.FindMethod( methodName ) Assert update, "TMethodPointer.SetMethod: "+methodName+" - Method does not Exist!" End Method Method Process(data:Object[]) Update.Invoke(contextObject,data ) End Method End Type Type TEventHandler Field eventhandlerMap:TMap Method New() eventhandlerMap = New TMap End Method Method Delete() eventhandlerMap.Clear() End Method Method RunEventHandler( event:TEvent ) Local eventmethod:TMethodPointer = TMethodPointer( eventhandlerMap.ValueForKey( String(event.id) ) ) If eventmethod Then eventmethod.Process([event]) EndIf End Method Method AddEventHandler( _eventID:Int , context:Object , handler:String ) Assert context,"TEventHandler.AddEventHandler: context-Argument Null Exception!" Assert (handler or handler<>""),"TEventHandler.AddEventHandler: handler-Argument Null Exception!" Local methodPointer:TMethodPointer = New TMethodPointer methodPointer.SetMethod(context, handler ) eventhandlerMap.Insert( String(_eventID), methodPointer) End Method Method RemoveEventHandler(_eventID:String ) eventhandlerMap.Remove( _eventID ) End Method End Type Type TMasterEventHook Method New() AddHook EmitEventHook,TMasterEventHook.ProcessEvents End Method Function ProcessEvents:Object(iId:Int,tData:Object,tContext:Object) If TData=Null Then Return Null Local tEv:TEvent = TEvent(TData) Local G:TGadget = TGadget(tEv.Source) If G Then Local handler:TEventHandler = TEventHandler(G.context) If handler Then handler.RunEventHandler(tEv) EndIf Return TData End Function End Type |
||
Übersicht


Powered by phpBB © 2001 - 2006, phpBB Group