Author | Topic: Return variable by reference in Event method | |
---|---|---|
R.M. Meijer | Return variable by reference in Event method on Fri, 13 Jan 2017 11:19:07 +0100 Hi, I am not able to return a variable by reference within a event callback method of an ActiveX component (TextControl). Sample Visual Basic code: [Visual Basic] Private Sub TXTextControl1_SpellCheckText(ByVal Text As String, MisspelledWordPositions As Variant) TXSpell1.Check (Text) MisspelledWordPositions = TXSpell1.MisspelledWordPositions End Sub My implementation looks like this: METHOD OwnActiveX:SpellCheckText(cText, aMisspelledWordPositions) ::oSpell:Check(cText) aMisspelledWordPositions := ::oSpell:MisspelledWordPositions RETURN aMisspelledWordPositions Unfortunately this approach does not work. ::oSpell:MisspelledWordPositions does contain an Array of misspelled word positions, but assigning this value to parameter aMisspelledWordPositions has no effect at all. The problem seems to be that there is no way to return a value (by reference) for this second parameter in Xbase++? Does anyone know a solution or workaround for this problem? With kind regards, Rens Zwanenburg rens[at]rmdata[dot]com | |
Jonathan Leeming | Re: Return variable by reference in Event method on Fri, 13 Jan 2017 08:15:20 -0700 Hi, I belive if you make the following changes to your code it will resolve your issue... METHOD OwnActiveX:SpellCheckText(cText, aMisspelledWordPositions) ::oSpell:Check(cText) ASIZE(aMisspelledWordPositions,LEN(::oSpell:MisspelledWordPositions)) ACOPY(::oSpell:MisspelledWordPositions,aMisspelledWordPositions) * aMisspelledWordPositions := ::oSpell:MisspelledWordPositions RETURN aMisspelledWordPositions When your method is called it is passing the memory address of the array aMissspelledWordPositions but when the line "aMisspelledWordPositions := ::oSpell:MisspelledWordPositions" is executed it changes the memory address of aMisspelledWordPositions as referenced in the METHOD but the function from which it was called is still referrencing the old memory address. Using the ASIZE / ACOPY lines will preserve the memory address and populate the array with the values from ::oSpell:MisspelledWordPositions. Assuming I'm understanding your issue correctly this should resolve your issue. Regards... Jonathan On Fri, 13 Jan 2017 11:19:07 +0100, R.M. Meijer wrote: >Hi, > >I am not able to return a variable by reference within a event callback >method of an ActiveX component (TextControl). > >Sample Visual Basic code: > >[Visual Basic] >Private Sub TXTextControl1_SpellCheckText(ByVal Text As String, >MisspelledWordPositions As Variant) > TXSpell1.Check (Text) > MisspelledWordPositions = TXSpell1.MisspelledWordPositions >End Sub > >My implementation looks like this: > >METHOD OwnActiveX:SpellCheckText(cText, aMisspelledWordPositions) > ::oSpell:Check(cText) > aMisspelledWordPositions := ::oSpell:MisspelledWordPositions >RETURN aMisspelledWordPositions > >Unfortunately this approach does not work. > >::oSpell:MisspelledWordPositions does contain an Array of misspelled >word positions, but assigning this value to parameter >aMisspelledWordPositions has no effect at all. > >The problem seems to be that there is no way to return a value (by >reference) for this second parameter in Xbase++? > >Does anyone know a solution or workaround for this problem? | |
R.M. Meijer | Re: Return variable by reference in Event method on Mon, 16 Jan 2017 14:49:11 +0100 Hi Jonathan, Thanks for your reply. Unfortunately it does not work. The argument "aMisspelledWordPositions" is not an Array, it is NIL. So I cannot use ASize() to change it. I tried cloning the array like this: aMisspelledWordPositions := AClone(::oSpell:MisspelledWordPositions) No errors, but also no result. Maybe XBase++ (1.9.355) does not allow ActiveX object to pass arguments by reference? Or it is a problem with the type of the argument, the documentation talks about an array of 'long' values. And according to Microsoft, a long value in Visual Basic is a 64 bit signed integer. As far as I know XBase integers are 32 bit, so maybe this is a problem for the component? Met vriendelijke groet, With kind regards, Rens Zwanenburg Op 13-1-2017 om 16:15 schreef Jonathan Leeming: > Hi, > > I belive if you make the following changes to your code it will > resolve your issue... > > METHOD OwnActiveX:SpellCheckText(cText, aMisspelledWordPositions) > ::oSpell:Check(cText) > > ASIZE(aMisspelledWordPositions,LEN(::oSpell:MisspelledWordPositions)) > ACOPY(::oSpell:MisspelledWordPositions,aMisspelledWordPositions) > > * aMisspelledWordPositions := ::oSpell:MisspelledWordPositions > > RETURN aMisspelledWordPositions > > When your method is called it is passing the memory address of the > array aMissspelledWordPositions but when the line > "aMisspelledWordPositions := ::oSpell:MisspelledWordPositions" is > executed it changes the memory address of aMisspelledWordPositions as > referenced in the METHOD but the function from which it was called is > still referrencing the old memory address. Using the ASIZE / ACOPY > lines will preserve the memory address and populate the array with the > values from ::oSpell:MisspelledWordPositions. > > Assuming I'm understanding your issue correctly this should resolve > your issue. > > Regards... Jonathan > > > On Fri, 13 Jan 2017 11:19:07 +0100, R.M. Meijer wrote: > >> Hi, >> >> I am not able to return a variable by reference within a event callback >> method of an ActiveX component (TextControl). >> >> Sample Visual Basic code: >> >> [Visual Basic] >> Private Sub TXTextControl1_SpellCheckText(ByVal Text As String, >> MisspelledWordPositions As Variant) >> TXSpell1.Check (Text) >> MisspelledWordPositions = TXSpell1.MisspelledWordPositions >> End Sub >> >> My implementation looks like this: >> >> METHOD OwnActiveX:SpellCheckText(cText, aMisspelledWordPositions) >> ::oSpell:Check(cText) >> aMisspelledWordPositions := ::oSpell:MisspelledWordPositions >> RETURN aMisspelledWordPositions >> >> Unfortunately this approach does not work. >> >> ::oSpell:MisspelledWordPositions does contain an Array of misspelled >> word positions, but assigning this value to parameter >> aMisspelledWordPositions has no effect at all. >> >> The problem seems to be that there is no way to return a value (by >> reference) for this second parameter in Xbase++? >> >> Does anyone know a solution or workaround for this problem? | |
Jonathan Leeming | Re: Return variable by reference in Event method on Mon, 16 Jan 2017 16:36:25 -0700 Hi Rens, I must be missing something... When you are calling your OwnActiveX:SpellCheckText(cText, aMisspelledWordPositions) can you not declare aMisspelledWordPositions := {} within the procedure/function before calling the method? On another note I created a spell check for my MLEs based upon a sample that Alaska provided... My Documents\Xbase++\source\samples\activex\spellchecker\spellchk.prg (for Xbase++ 2.0) C:\Program Files (x86)\ALASKA\XPPW32\source\samples\activex\spellchecker\spellchk.prg (for Xbase++ 1.9) It uses the spell checker engine from MS Word... I don't know if that will help... obviously MS Word needs to be installed on the workstation. Regards... Jonathan On Mon, 16 Jan 2017 14:49:11 +0100, R.M. Meijer wrote: >Hi Jonathan, > >Thanks for your reply. > >Unfortunately it does not work. > >The argument "aMisspelledWordPositions" is not an Array, it is NIL. So I >cannot use ASize() to change it. > >I tried cloning the array like this: > > aMisspelledWordPositions := AClone(::oSpell:MisspelledWordPositions) > >No errors, but also no result. > >Maybe XBase++ (1.9.355) does not allow ActiveX object to pass arguments >by reference? > >Or it is a problem with the type of the argument, the documentation >talks about an array of 'long' values. And according to Microsoft, a >long value in Visual Basic is a 64 bit signed integer. > >As far as I know XBase integers are 32 bit, so maybe this is a problem >for the component? | |
R.M. Meijer | Re: Return variable by reference in Event method on Thu, 19 Jan 2017 13:17:54 +0100 Hi Jonathan, The method "spellCheckText" is called automatically by the control (event), every time something in the document changes. But I am starting to think it is possibly some kind of data type miss match. Alaska is also looking into this, hopefully they will find the solution. Met vriendelijke groet, With kind regards, Rens Zwanenburg Op 17-1-2017 om 0:36 schreef Jonathan Leeming: > Hi Rens, > > I must be missing something... > > When you are calling your OwnActiveX:SpellCheckText(cText, > aMisspelledWordPositions) can you not declare aMisspelledWordPositions > := {} within the procedure/function before calling the method? > > On another note I created a spell check for my MLEs based upon a > sample that Alaska provided... > > My Documents\Xbase++\source\samples\activex\spellchecker\spellchk.prg > (for Xbase++ 2.0) > > C:\Program Files > (x86)\ALASKA\XPPW32\source\samples\activex\spellchecker\spellchk.prg > (for Xbase++ 1.9) > > It uses the spell checker engine from MS Word... I don't know if that > will help... obviously MS Word needs to be installed on the > workstation. > > Regards... Jonathan > > > > On Mon, 16 Jan 2017 14:49:11 +0100, R.M. Meijer wrote: > >> Hi Jonathan, >> >> Thanks for your reply. >> >> Unfortunately it does not work. >> >> The argument "aMisspelledWordPositions" is not an Array, it is NIL. So I >> cannot use ASize() to change it. >> >> I tried cloning the array like this: >> >> aMisspelledWordPositions := AClone(::oSpell:MisspelledWordPositions) >> >> No errors, but also no result. >> >> Maybe XBase++ (1.9.355) does not allow ActiveX object to pass arguments >> by reference? >> >> Or it is a problem with the type of the argument, the documentation >> talks about an array of 'long' values. And according to Microsoft, a >> long value in Visual Basic is a 64 bit signed integer. >> >> As far as I know XBase integers are 32 bit, so maybe this is a problem >> for the component? | |
Jim Lee | Re: Return variable by reference in Event method on Wed, 18 Jan 2017 05:16:49 +0100 hi, i did not use TX-Control so i have no Solution but perhaps a Tip as i see Type is "Variant" ... try to use o:callMethod() and different VT_* Constante. Note : \XPPW32\INCLUDE\activex.ch have more Constante than Help File search in Alaska Newsgroup for "VTType" or just "VT_" e.g. using with OpenOffice xParam := VTType():new( xValue, VT_ARRAY + VT_VARIANT ) xParam := VTType():new( xValue, VT_ARRAY + VT_UI1 ) if nothing help ask Pablo at www.xbwin.com if he know a solution. | |
R.M. Meijer | Re: Return variable by reference in Event method on Thu, 19 Jan 2017 14:05:44 +0100 Hi Jim, Thanks for the suggestion! As the spellCheckText event is automatically called by the component itself (whenever something changes in the document), I am not able to change the way it is being called. But you might be right about the data type miss match. Have been experimenting with different VT_ settings, but no result yet... Will post a question on the xbwin forum! Met vriendelijke groet, With kind regards, Rens Zwanenburg Op 18-1-2017 om 5:16 schreef Jim Lee: > hi, > > i did not use TX-Control so i have no Solution but perhaps a Tip > > as i see Type is "Variant" ... > try to use o:callMethod() and different VT_* Constante. > > Note : \XPPW32\INCLUDE\activex.ch have more Constante than Help File > > search in Alaska Newsgroup for "VTType" or just "VT_" e.g. using with > OpenOffice > > xParam := VTType():new( xValue, VT_ARRAY + VT_VARIANT ) > xParam := VTType():new( xValue, VT_ARRAY + VT_UI1 ) > > if nothing help ask Pablo at www.xbwin.com if he know a solution. > > | |
Jim Lee | Re: Return variable by reference in Event method on Fri, 20 Jan 2017 07:36:06 +0100 ok ... back to Start how does your "Create" look like oTxControl := XbpActiveXControl():new( ) oTxControl:CLSID := cTxTextControll oTxControl:license := 'TP-XXXXXXXXXXX' oTxControl:Userevents := .F. oTxControl:ReCreateHandle := .T. | |
R.M. Meijer | Re: Return variable by reference in Event method on Fri, 20 Jan 2017 16:47:15 +0100 This is my little test procedure: oSpell := createObject("AxTXSpell.AxTXSpellChecker") oTx := xbpActiveXControl():new() oTx:CLSID := cCLSID oTx:license := cLicense oTx:create(oParent, NIL, {100,100}, {500, 500}) oTx:show() oTx:enableSpellChecking := .T. oTx:SpellCheckText := {|cText, aMisspelledWordPositions| oSpell:Check(cText), aMisspelledWordPositions := oSpell:MisspelledWordPositions} Met vriendelijke groet, With kind regards, Rens Zwanenburg Op 20-1-2017 om 7:36 schreef Jim Lee: > ok ... back to Start > how does your "Create" look like > > oTxControl := XbpActiveXControl():new( ) > oTxControl:CLSID := cTxTextControll > oTxControl:license := 'TP-XXXXXXXXXXX' > oTxControl:Userevents := .F. > oTxControl:ReCreateHandle := .T. > > | |
Jim Lee | Re: Return variable by reference in Event method on Sat, 21 Jan 2017 04:37:09 +0100 hi, i was told, by a Man how use TXControl, that the Documentation about Spellchecker is not what you think. he use a external Spellchecker within TXControl after try internal Spellchecker Version. neverless back to the Problem : > This is my little test procedure: as it is send as Event you need to o:subscribeEvent() and use a Codeblock to pass Parameter to that VB Function. cEventName := "Name_of_Event_Constant" xVar := oActiveX:isEventPublished( cEventName ) IF xVar <> Nil lSuccess := oActiveX:SubscribeEvent( xVar, { |a,b,c ... ,z| MyFunc(a,b,c ... ,z) } ) ENDIF Parameter a,b,c,d are "send" from ActiveX which you pass to your Codeblock. you need as much Parameter in "| |" as Event send but it can be more than need. this Work have to be done to each Event you want to recive in your Xbase++ App ... and do not forget to o:unsubscribeEvent() all and oActiveX:Destroy() all Connection you have made. | |
R.M. Meijer | Re: Return variable by reference in Event method on Mon, 23 Jan 2017 09:08:55 +0100 Hi Jim, Actually, the spell checker component (txSpell.NET) works perfectly fine, after calling "oSpell:check(cText)" the variable oSpell:aMisspelledWordPositions contains an Array with the correct word positions. It is the SpellCheckText event method of txTextControl that just seems to ignore any value I put into the argument "aMisspelledWordPositions" (no red zigzag lines appear inside the textControl). Even if I manually set the Array (like aMisspelledWordPositions := {1, 3, 10, 14}), nothing happens. I tried your suggestion of subscribing to the event, but there is no difference. As far as I know (and the XBase++ manual says), you do not need to manually subscribe to these events, this is done automatically by XBase++. Thanks for you help! Met vriendelijke groet, With kind regards, Rens Zwanenburg Op 21-1-2017 om 4:37 schreef Jim Lee: > hi, > > i was told, by a Man how use TXControl, that the Documentation about > Spellchecker is not what you think. > he use a external Spellchecker within TXControl after try internal > Spellchecker Version. > > neverless back to the Problem : > >> This is my little test procedure: > as it is send as Event you need to o:subscribeEvent() and use a Codeblock to > pass Parameter to that VB Function. > > cEventName := "Name_of_Event_Constant" > xVar := oActiveX:isEventPublished( cEventName ) > IF xVar <> Nil > lSuccess := oActiveX:SubscribeEvent( xVar, { |a,b,c ... ,z| > MyFunc(a,b,c ... ,z) } ) > ENDIF > > Parameter a,b,c,d are "send" from ActiveX which you pass to your Codeblock. > you need as much Parameter in "| |" as Event send but it can be more than > need. > > this Work have to be done to each Event you want to recive in your Xbase++ > App > > ... and do not forget to o:unsubscribeEvent() all and oActiveX:Destroy() all > Connection you have made. > > | |
Jim Lee | Re: Return variable by reference in Event method on Mon, 23 Jan 2017 22:40:08 +0100 > I tried your suggestion of subscribing to the event, but there is no > difference. As far as I know (and the XBase++ manual says), you do not > need to manually subscribe to these events, this is done automatically by > XBase++. so what is o:subscribeEvent() for if you think you do not need it ? remember Windows Apps are send Event via Windows Queue but Xbase++ do not pass "all" to User. Question : how do you o:subscribeEvent() ? ( Syntax ) > Even if I manually set the Array that will not work while Event, after something "happend", is not send. normal Windows App will "fill" a Windows Structure and send a Event with a Pointer to that Structure. no Event -> no Structure -> no Result have you try undokumented o:Userevents / o :UseGuiThread / o:ReCreateHandle ? | |
R.M. Meijer | Re: Return variable by reference in Event method on Tue, 24 Jan 2017 12:08:30 +0100 > so what is o:subscribeEvent() for if you think you do not need it ? > remember Windows Apps are send Event via Windows Queue but Xbase++ do not > pass "all" to User. Well, that is because the callback slot is correctly being called when I set it like this: oTx:SpellCheckText := {|cText, aMisspelledWordPositions| SpellCheckText(cText, aMisspelledWordPositions) } > Question : how do you o:subscribeEvent() ? ( Syntax ) This is the source I used when manually subscribing to the event: ... nId := oTx:isEventPublished("SpellCheckText") If nId <> NIL oTx:subscribeEvent(nId, {|cText, aMisspelledWordPositions| SpellCheckText(cText, aMisspelledWordPositions) } ) Endif ... After this, the function 'SpellCheckText' is called correctly. >> Even if I manually set the Array > that will not work while Event, after something "happend", is not send. > normal Windows App will "fill" a Windows Structure and send a Event with a > Pointer to that Structure. > no Event -> no Structure -> no Result I meant: setting the argument 'aMisspelledWordPositions' inside the event callback "spellCheckText" with a mock-up value, see sample program below. > have you try undokumented o:Userevents / o :UseGuiThread / o:ReCreateHandle > ? Yes, it makes no difference. Here is a simple test program (without spell checking component, as that is not required to provoke this problem). In this program the method 'spellCheckText' is being called automatically by the control (event) whenever the text in side the control is changed. I simply tell the control the first word is always wrong, but again, no red zig-zag line. Alaska is also investigating this issue. PROCEDURE Main() Local nEvent, mp1, mp2, oXbp Local oDlg, oTx Create dialog window hidden oDlg := XbpDialog():new( ,,{100,100}, {600,400},, .F. ) oDlg:taskList := .T. oDlg:create() oDlg:drawingArea:resize := {|mp1, mp2, obj| obj:childList()[1]:setSize({mp2[1]-20, mp2[2]-20}) } create txTextControl oTx := MyTxControl():new(oDlg:drawingArea, NIL, {10,10}, {oDlg:drawingArea:currentSize()[1]-20, oDlg:drawingArea:currentSize()[2]-20}) oTx:CLSID := "TIS.TX.TextControl.24" oTx:license := "" no license = demo oTx:Create() enable spell checking oTx:EnableSpellChecking := .T. causes the 'spellCheckText' event to be fired when the text in the control changes show dialog and txControl oTx:show() oDlg:show() SetAppFocus(oTx) Do While nEvent <> xbeP_Close nEvent := AppEvent( @mp1, @mp2, @oXbp ) oXbp:handleEvent( nEvent, mp1, mp2 ) Do Case Case nEvent == xbeP_Keyboard .And. mp1 == xbeK_ESC nEvent := xbeP_Close EndCase Enddo oTx:destroy() oDlg:destroy() RETURN CLASS MyTxControl FROM xbpActiveXControl EXPORTED: METHOD Init METHOD SpellCheckText ENDCLASS METHOD MyTxControl:Init(oParent, oOwner, aPos, aSize, aPP, lShow) RETURN ::XbpActiveXControl:Init(oParent, oOwner, aPos, aSize, aPP, lShow) /* [Visual Basic] Private Sub TXTextControl1_SpellCheckText(ByVal Text As String, MisspelledWordPositions As Variant) TXSpell1.Check (Text) MisspelledWordPositions = TXSpell1.MisspelledWordPositions End Sub */ METHOD MyTxControl:SpellCheckText(cText, aMisspelledWordPositions) Local nWordLen If !Empty(cText) TODO: call spell checking engine to determine wrong word positions For now, just force the first word to be wrong... nWordLen := At(" ", cText) find first space characterto determine length of first word in 'cText' If nWordLen == 0 no space > use full length of 'cText' nWordLen := Len(cText) Endif aMisspelledWordPositions := {1, nWordLen} Endif RETURN Self Met vriendelijke groet, With kind regards, Rens Zwanenburg Op 23-1-2017 om 22:40 schreef Jim Lee: >> I tried your suggestion of subscribing to the event, but there is no >> difference. As far as I know (and the XBase++ manual says), you do not >> need to manually subscribe to these events, this is done automatically by >> XBase++. > so what is o:subscribeEvent() for if you think you do not need it ? > remember Windows Apps are send Event via Windows Queue but Xbase++ do not > pass "all" to User. > > Question : how do you o:subscribeEvent() ? ( Syntax ) > >> Even if I manually set the Array > that will not work while Event, after something "happend", is not send. > normal Windows App will "fill" a Windows Structure and send a Event with a > Pointer to that Structure. > no Event -> no Structure -> no Result > > have you try undokumented o:Userevents / o :UseGuiThread / o:ReCreateHandle > ? > > | |
Jim Lee | Re: Return variable by reference in Event method on Wed, 25 Jan 2017 07:59:14 +0100 >I simply tell the control the first word is always wrong, but again, no red >zig-zag line. i did not see that you are calling TXSpell1.Check (Text) in your Method MyTxControl:SpellCheckText() | |
R.M. Meijer | Re: Return variable by reference in Event method on Mon, 30 Jan 2017 10:33:47 +0100 That's because the Spell checking component (txSpell) is not required to provoke this problem. You can use whatever spell cheking component you like, as long as you return an Array of misspelled word positions within the spellCheckText event. I simply tried to get a red zig-zag line somewhere inside the control... Alaska support looked into it and now created PDR 6853 for this problem. The dev team will now look into this. I also submitted the issue at TextControl support. Meanwhile, I will try a different approach as suggested by Mark Sergent, using wSpell without the spellCheckText event. Met vriendelijke groet, With kind regards, Rens Zwanenburg Op 25-1-2017 om 7:59 schreef Jim Lee: >> I simply tell the control the first word is always wrong, but again, no red >> zig-zag line. > i did not see that you are calling > > TXSpell1.Check (Text) > > in your Method MyTxControl:SpellCheckText() > > > > | |
R.M. Meijer | Re: Return variable by reference in Event method on Wed, 12 Sep 2018 09:26:39 +0200 So, I would like to let you know that this problem is finally solved! 2 months ago Alaska fixed the issue in XBase 2.0, to make this event work. At first only for Windows 10, but then also for Windows 7. So now we can finally use this spell checking component in our solution! Met vriendelijke groet, With kind regards, Rens Zwanenburg Op 30-1-2017 om 10:33 schreef R.M. Meijer: > That's because the Spell checking component (txSpell) is not required > to provoke this problem. You can use whatever spell cheking component > you like, as long as you return an Array of misspelled word positions > within the spellCheckText event. > > I simply tried to get a red zig-zag line somewhere inside the control... > > Alaska support looked into it and now created PDR 6853 for this > problem. The dev team will now look into this. > > I also submitted the issue at TextControl support. > > Meanwhile, I will try a different approach as suggested by Mark > Sergent, using wSpell without the spellCheckText event. > > --- Dit e-mailbericht is gecontroleerd op virussen met Avast antivirussoftware. https://www.avast.com/antivirus | |
Jim Lee | Re: Return variable by reference in Event method on Wed, 12 Sep 2018 18:40:02 +0200 > 2 months ago Alaska fixed the issue in XBase 2.0, to make this event work. > At first only for Windows 10, but then also for Windows 7. so the Problem was Xbase++ v2.x ? | |
R.M. Meijer | Re: Return variable by reference in Event method on Mon, 08 Oct 2018 09:31:43 +0200 Yep. Met vriendelijke groet, With kind regards, Rens Zwanenburg Op 12-9-2018 om 18:40 schreef Jim Lee: >> 2 months ago Alaska fixed the issue in XBase 2.0, to make this event work. >> At first only for Windows 10, but then also for Windows 7. > so the Problem was Xbase++ v2.x ? > > --- Dit e-mailbericht is gecontroleerd op virussen met Avast antivirussoftware. https://www.avast.com/antivirus | |
Jim Lee | Re: Return variable by reference in Event method on Fri, 27 Jan 2017 23:29:07 +0100 have download TxControl Trail Version and try to make Demo. Question : did you have any *.VTD on your PC ? these are the Dictionary Files which you need to check |