Welcome, Guest
Username: Password: Remember me
This public forum is meant for questions and discussions about Visual FoxPro
  • Page:
  • 1

TOPIC:

BindEvent() And other 30 May 2020 13:16 #14764

  • xinjie
  • xinjie's Avatar
  • Topic Author


  • Posts: 9
  • Hi,

    I'm from China.I have been following X# for a long time.Thank you very much for the excellent work of the development team.

    I have two questions:

    1 BindEvent() Func.
    I noticed the description in the X # help file,It's "Note: This API is now obsolete." WHY?
    This function and several other related functions are very widely used. Is there any solution to this problem if I go from VFP to X #?

    2 XSharp Open Software License
    I noticed a description in it:i. modify or translate the Software;
    According to the source code of X #, does translating the GUI into other languages(e.g. Chinese) violate the license ?


    My English is poor. I am sorry if you have caused an ambiguity in understanding.

    Thanks again and tribute.

    Please Log in or Create an account to join the conversation.

    BindEvent() And other 30 May 2020 13:46 #14766

    • robert
    • robert's Avatar


  • Posts: 3446
  • xinjie,

    The BindEvent function is a runtime function that allows you to bind a function (method) to an event.
    In X# we do that at compile time, just like in C# and VB. For example for a Form object you can bind an event with the += syntax:
    oForm:Loaded += Form_Loaded
    The Form_Loaded method must have the right parameters (the compiler will check this)

    And to remove an event handler you write the same code with the "-=" syntax,
    In theory you can also do this in code (and we could therefore implement the BindEvents() function) but that is simply not the right solution.

    With regard to your other question: we would love to see support for Chinese in our product.
    What exactly do you want to translate: the messages in the runtime or do you want to translate our VS integration (editor support etc).
    Maybe you can send me a private email to we can discuss this ?

    Robert
    XSharp Development Team
    The Netherlands

    Please Log in or Create an account to join the conversation.

    BindEvent() And other 30 May 2020 14:04 #14767

    • xinjie
    • xinjie's Avatar
    • Topic Author


  • Posts: 9
  • Robert,

    Thank you for your quick reply.

    I think your understanding of the first question is wrong. When I use X# to develop an application from 0, I certainly have to follow the rules of X#. However, if I want to convert my existing VFP application to X #, I want to know how you and your team will handle this function.

    About "other", I will send you an email after careful consideration.

    Please Log in or Create an account to join the conversation.

    Last edit: by xinjie.

    BindEvent() And other 30 May 2020 15:21 #14772

    • robert
    • robert's Avatar


  • Posts: 3446
  • xinjie,

    We are writing a tool to convert FoxPro code (forms, class libraries, reports) to X#. Most likely we will convert this in the tool from the VFP syntax to the .Net syntax.

    Robert
    XSharp Development Team
    The Netherlands

    Please Log in or Create an account to join the conversation.

    BindEvent() And other 02 Jun 2020 00:55 #14795

    • FoxProMatt
    • FoxProMatt's Avatar



    @ xinjie

    Actually your English is pretty good.

    I’m hoping your “other” email that you’ll send Robert after careful consideration is some good news like “I have access to many sponsorship dollars USD and will contribute heavily to X# Dev Team’s rapid completion of FoxPro implementation.”

    Oh, well, we can dream, right.

    (That’s some goofy American humor, so don’t take it seriously. Unless it’s true of course... Oh, rats, I did it again. )

    On a serious note, welcome to X# FoxPro Forums. We look to seeing you around.

    Please Log in or Create an account to join the conversation.

    Last edit: by FoxProMatt.

    BindEvent() And other 02 Jun 2020 16:01 #14798

    • kevclark64
    • kevclark64's Avatar


  • Posts: 123
  • So, if I were creating an object in code and wanted to bind an event, then I would do something like this?
    objNewButton=createobject("commandbutton")
    objNewButton.click += myClickCode

    Please Log in or Create an account to join the conversation.

    BindEvent() And other 02 Jun 2020 20:21 #14801

    • robert
    • robert's Avatar


  • Posts: 3446
  • Kevin,
    Yes that would work if objNewButton is typed as CommandButton and if there is a click event defined on that class.

    Robert
    XSharp Development Team
    The Netherlands

    Please Log in or Create an account to join the conversation.

    BindEvent() And other 08 Jun 2020 15:32 #14907

    • Jörg
    • Jörg's Avatar


  • Posts: 2
  • Hi!
    Bud in VFP the Bindevent() has a 5th Parameter in which you can determine how it should behave (from help):
    nFlags Specifies an additive bit flag you can set for the event binding operation.
    The nFlags parameter is ignored when a Windows message event binding is created.
    nFlags Bits Event Type Description
    0 000 FoxPro object Call delegate code before event code. (Default)
    1 001 FoxPro object Call event code before delegate code.
    2 010 FoxPro object Do not trigger event (call delegate code) by simple method call.
    3 011 FoxPro object Call event code before delegate code. Do not trigger event (call delegate code) when simple method calls occur.
    4 100 Windows Message Prevents recursion of similar events while user event code is executing.
    ..

    How can I set this by the += opperation?

    Please Log in or Create an account to join the conversation.

    BindEvent() And other 08 Jun 2020 20:16 #14909

    • robert
    • robert's Avatar


  • Posts: 3446
  • Jörg,
    I don't think this is possible in .Net.
    Every event runs "on its own".
    Can you explain how you are using this ?
    Robert
    XSharp Development Team
    The Netherlands

    Please Log in or Create an account to join the conversation.

    BindEvent() And other 12 Jun 2020 10:28 #14938

    • Jörg
    • Jörg's Avatar


  • Posts: 2
  • Hi Robert!

    In VFP you can determine if a Binding is "fired" before or after en Event.
    E.g. say you have a Save() Method. By Binding to the save() Method before, you can do some things before saving the Record (Change some Values).
    And after Saving you can refresh a special Element in the Form.
    In Our VFP Programm you can configure many, say nearly every Element of the gui by Database Entrys. So some Objects have to bind on base functions for working as expected.
    Jörg

    Please Log in or Create an account to join the conversation.

    BindEvent() And other 14 Jun 2020 04:47 #14962

    • xinjie
    • xinjie's Avatar
    • Topic Author


  • Posts: 9
  • robert wrote: xinjie,

    Maybe you can send me a private email to we can discuss this ?

    Robert


    I had send an email to you.

    Please Log in or Create an account to join the conversation.

    BindEvent() And other 14 Jun 2020 04:50 #14963

    • xinjie
    • xinjie's Avatar
    • Topic Author


  • Posts: 9
  • @FoxProMatt

    Thank's !

    Please Log in or Create an account to join the conversation.

    BindEvent() And other 01 Jul 2021 14:59 #18943

    • mainhatten
    • mainhatten's Avatar


  • Posts: 199
  • robert wrote: The BindEvent function is a runtime function that allows you to bind a function (method) to an event.
    In X# we do that at compile time, just like in C# and VB. For example for a Form object you can bind an event with the += syntax:

    oForm:Loaded += Form_Loaded
    The Form_Loaded method must have the right parameters (the compiler will check this)

    And to remove an event handler you write the same code with the "-=" syntax,
    In theory you can also do this in code (and we could therefore implement the BindEvents() function) but that is simply not the right solution.


    Hi Robert,

    I realize this is an old thread, but in vfp (due to the fact vfp always call the same method with different parameters filled or given) there is for me a huge benefit in BindEvent():
    I can retrofit existing code with a homegrown profiler with minimal effort/source changes, if I need to I can "wrap" method calls even externally after objects have been loaded by reading a table with specific object instance names, object classes or decendants of object classes.

    For this the vfp Bindevent NOT having to conform to the method signature of the wrapped method is ideal.
    Perhaps the same effect might be realized in x# code depending on reflection, but even then result will be marred (in part) by same named methods calling each other with different (perhaps default) parameters.

    So yes, I realize vfp BindEvent does not map to Dotnet delegates well - but the ability to wrap any named method either from object.init() or even very late by recursive dynamic calls walking the object tree with amembers() helping is a very powerful (and hackish) approach.

    regards
    thomas

    Please Log in or Create an account to join the conversation.

    BindEvent() And other 01 Jul 2021 17:24 #18948

    • robert
    • robert's Avatar


  • Posts: 3446
  • Thomas,

    We may be able to emulate this behavior, but to properly do so we need an example that shows what you describe.
    Are you saying that you want to have one method as "handler" for all events, with different parameters depending on the event that was called ?
    We can probably do that by creating a method "on the fly" that then does a Clipper Calling convention call to your code.
    Can you provide us with an example ?

    Robert
    XSharp Development Team
    The Netherlands

    Please Log in or Create an account to join the conversation.

    BindEvent() And other 03 Jul 2021 00:14 #18968

    • mainhatten
    • mainhatten's Avatar


  • Posts: 199
  • Hi Robert,

    robert wrote: We may be able to emulate this behavior, but to properly do so we need an example that shows what you describe.
    Are you saying that you want to have one method as "handler" for all events, with different parameters depending on the event that was called ?
    We can probably do that by creating a method "on the fly" that then does a Clipper Calling convention call to your code.
    Can you provide us with an example ?


    Whipped up a VERY basic sample of the approach to "retrofit" a timing log to specific object.method() calls, as this is more "against Dotnet thinking" compared to having a special method linking specific delegates in the init of interesting classes.
    This approach might be used on the cursoradapter class of the largest tables, as larger tables are more suspect of causing delays. The second approach - hooking in Init of base class (perhaps with property switch) would be used to log_time all cursoradapter.method calls suspect of causing delays for all tables, for instance across different machines or on different customer data sets.

    Compared to coverage profiler this will give more realistic times, but I have specific C-logger .Fll functionality to check in more detail / with even less overhead / Heisenbug changes introduced by measuring, as well as specific "tableaction-wrappers" allowing me to see problematic/slow code parts.

    Code tries to reduce to the max, but it DOES have cleanup (not needed in most situations), but the objects wrapped normally are have their own lists of what and where to clear - unwrap is more a hint than sober implementation and logging would be piped either into txt or dbf....
    Fire up vfp, run and grin
    ;-)
    * BindEvent Logger
    clea
    
    *--- tiny stuff injected in app code
    private poLog
    poLog = createobject("Logger_Base")
    
    ***************************************************************
    *-- this would usually be table based, to switch several dozen timers on/off with single SQL on table
    = Check_Instance("Worker_Fast", "Do_Job")
    = Check_Instance("Worker_Base", "Do_Wrk, Do_Val, Do_Sav")
    = Check_Instance("Worker_Fast", "Do_Wrk, Do_Job")
    = Check_Instance("Worker_Slow", "Do_Wrk, Do_Val, Do_Sav, Do_Job")
    = Check_Instance("Worker_Sloppy", "Do_Wrk, Do_Val, Do_Sav, Do_Job")
    
    function Check_Instance(tcObj, tcWatchList)
    	local loWork
    	loWork = createobject(m.tcObj)
    	= poLog.Wrap_List(m.loWork, m.tcWatchList)
    	loWork.Do_Job()
    
    ***************************************************************
    * logger classes have more capabilities only example of "static external code"
    define class EvWrapper as custom
    	function Wrap_List(toSource, tcMethodCSV, toHandler, tcDelegate))
    		local laMethods[1], lnRun
    		for lnRun = 1 to alines(laMethods, m.tcMethodCSV, 5, ",")
    			= this.Wrap_Both(m.toSource, laMethods[m.lnRun], m.toHandler, m.tcDelegate)
    		next
    
    	function Wrap_Both(toSource, tcEvent, toHandler, tcDelegate)
    		local loHandler, lcDelegate
    		*-- make last 2 parameters optional via defaults
    		loHandler = iif(vartype(m.toHandler)=="O", m.toHandler, this)
    		lcDelegate = iif(vartype(m.toHandler)=="C", m.tcDelegate, "Log")
    		= bindevent(m.toSource, m.tcEvent, m.loHandler, m.lcDelegate+"_Setup",0)
    		= bindevent(m.toSource, m.tcEvent, m.loHandler, m.lcDelegate+"_TearDown",1)
    		return
    
    	function UnWrap(toSource)
    		*-- ok, here it gets really ugly
    		*-- in demo code trying to hint at better cleanup
    		local laEv[1], lnRun
    		for lnRun = 1 to aevents(laEv, m.toSource)
    			= unbindevents(m.toSource, laEv[m.lnRun, 3], laEv[m.lnRun, 2], laEv[m.lnRun, 4])
    		next
    		return
    enddefine
    
    
    define class Logger_Base as EvWrapper
    	*--- timing log does not need special info, dummy parameter, 
    	*--- don't overdo, as vfp parameters are slooooow
    	function Log_Setup(dum1, dum2, dum3)
    		= this.Log_Do("Setup")
    	function Log_TearDown(dum1, dum2, dum3)
    		= this.Log_Do("TearDown")
    
    	function Log_Do(tcFrom)
    		local laEv[1]
    		= aevents(laEv, 0)
    		? str(seconds(), 12, 4) + " at " + m.tcFrom ;
    			+ ">>>" + laEv[1].Class + "::" + laEv[2] 
    		return
    
    enddefine
    
    
    *****************************************************
    * here is the huge customer app where I am tasked to identify the slow parts
    * I don't want to mess *inside* their code too much, as subclass methods will also have code 
    * and not will depend on properties to be slow
    
    define class Worker_Base as custom
    	nVal = 1
    	nSav = 1
    	nWrk = 1
    
    	function Simulate(tnVal)
    		wait window program(program(-1)-1) timeout m.tnVal
    		wait clea
    		return
    
    	function destroy()
    		*-- ahemmm... good habits done ugly...
    		= poLog.UnWrap(this)
    		return dodefault()
    
    	function Do_Job()
    		= this.Do_wrk()
    		= this.Do_Val(1)
    		= this.Do_Sav("", 0)
    
    	function Do_wrk()
    		= this.Simulate(this.nWrk)
    	function Do_Val(toObj)
    		= this.Simulate(this.nVal)
    	function Do_Sav(toObj, tcTable)
    		= this.Simulate(this.nSav)
    
    enddefine
    
    define class Worker_Fast as Worker_Base
    	nVal = 0.2
    	nSav = 0.1
    	nWrk = 0.4
    enddefine
    
    define class Worker_Slow as Worker_Base
    	nVal = 2
    	nSav = 2
    	nWrk = 3
    enddefine
    
    define class Worker_Sloppy as Worker_Slow
    	nVal = 0.2
    	nSav = 3
    	nWrk = 1
    enddefine
    

    Please Log in or Create an account to join the conversation.

    Last edit: by mainhatten. Reason: spelling and minimal source commenting
    • Page:
    • 1