fbpx
Welcome, Guest
Username: Password: Remember me
  • Page:
  • 1

TOPIC: How to solve class related code issues possible in VO but not in .Net?

How to solve class related code issues possible in VO but not in .Net? 04 May 2020 23:46 #14359

  • ic2's Avatar

  • ic2

  • Topic Author


  • Posts: 702
  • Earlier I wrote that I prefer to prepare my VO code as much as possible for an X# conversion so the actual conversion itself would take less time. I found out that having methods of a class in different libraries is not possible in .Net (while I thought an external class would allow that). See www.xsharp.info/forum/public-vo-vn/1853-...ses-used-per-library

    I figured out all the Error XS9016xxx _external_class errors pointed me to such "orphan" methods and I tried to find a solution for all of them. Some could easily be moved to where the class resided, others where just obsolete, some required a bit of work (passing functionality only present in the current lib as a parameter so it could work from the lib where the class resides). That leaves me with some remaining issues, which surprisingly had to do mostly with the (known and even understandable) impossibility to extend standard classes with methods.

    I do have a few categories and I wonder if I can solve this either in VO, in X# or in none. Not sure yet (because I am completely unfamiliar with it) if one or more of the issues below could be solved with the invoke Chris recommended in the above link’s post.

    1 In some subclassed datawindows I use a method to set a caption on the tab, which I think is not possibly by default, e.g.

    SELF:oDCTabControl:SetTabCaption(0, “Something")

    For that I use a method:

    METHOD SetTabCaption(nIndex, cCaption) CLASS TabControl

    which means I extend the standard TabControl class. I think I can not solve this by subclassing aTabControl (so I can change the class in the above method). The window editor allows me to insert tabcontrols, not subclassed tabcontrols.

    Or do I overlook something?

    2 Some methods have been added to repair bugs in VO, like methods for the DateTimePicker (which suddenly stopped reading values from VO SP4) or METHOD GetItemAtPosition(oPoint) CLASS MONTHCALENDAR which solved an issue with drag & drop to the month calendar.

    In VO I prefer to leave the methods where they are. But what to do in X#? Could the issues be solved in X# , assuming I want to start with all VO compatible windows? Or is there another solution to implement these?

    3 Some e.g. class windows methods are used in every window inheriting from it so it does make sense to have it once, as a class windows method. Does this mean I have to copy the code for every inheriting window? A nice example is:

    METHOD NoMethod() CLASS window which is called when a non existing method is called (e.g. using owner or send, so the compiler doesn’t see it)

    4 I also have a METHOD dispatch(oE) CLASS __FormDialogWindow
    which allows me to allow users to press ESCape to end certain windows. Not sure how to do this differently?

    All together it’s not to bad, in one relatively large library, so your comments how to solve this best (as much as possible in VO, unless impossible or unpractical) are appreciated.

    Dick

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

    How to solve class related code issues possible in VO but not in .Net? 05 May 2020 01:29 #14362

  • Chris's Avatar

  • Chris


  • Posts: 1957
  • Hi Dick,

    1-2. Yes, you can use subclassed controls in the VO Window Editor, same way as you can do it in VO. Just set in the "Inherit from" property the name of the subclass. But maybe you do not even need to do this, if the code in the external method does not use private members of the parent classes, then you can simply define an extension method which does the same work and you will practically need to change nothing in your code. Can you please show us the full body of the methods SetTabCaption() and GetItemAtPosition() ?

    3. I think the best way is to define a "CLASS MyBaseWindow INHERIT DataWindow", define this or any other common methods in it and then have all your data windows inherit from that class. Same for DataDialogs and DilogWindows, if you need that for them as well.

    4. Maybe we could add this functionality directly in the SDK classes. Can you please show us the contents of this method as well?
    XSharp Development Team
    chris(at)xsharp.eu

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

    How to solve class related code issues possible in VO but not in .Net? 05 May 2020 14:14 #14370

  • ic2's Avatar

  • ic2

  • Topic Author


  • Posts: 702
  • Hello Chris,

    Thanks for your reply. Option 3 I already thought so. Not a big deal, I do have subclassed windows. Again of course it shows how wonderful efficient VO is compared to .Net. Adding (and maintaining) just one method to an existing class instead of one for every sibling class.

    Now you write about the subclassed tabcontrol that I can do it just as I would do it in VO. But that is exactly my point, I don't know how to do it in VO. I have the toolbox window from which I can insert a default tabcontrol, not an inherited tab control (for how it can be done in X# I make a note but that is going to be of (much) later concern.

    I think it's better to mail you all the methods we use and look up why we used these. For now here are 2: this is to set a caption to a tab. I think there is no other way to do so, without the method?

    METHOD SetTabCaption(nIndex, cCaption) CLASS TabControl
    //#s Set caption of tab in tabwindow
    //#p nIndex = index of desired tab 0=1e 1 cCaption=Caption of Tab

    LOCAL strucTabItem IS _winTC_ITEM
    LOCAL pszCaption AS PSZ
    LOCAL lResult AS LOGIC

    IF (nIndex != -1)
    strucTabItem.Mask := TCIF_TEXT
    PSZCaption := StringAlloc(cCaption)
    strucTabItem.PSZText := StringAlloc(Psz2String(pszCaption))
    lResult := TabCtrl_SetItem(SELF:Handle(), nIndex, @strucTabItem)
    // Handle to tab control, Index of item, pointer to TC_ITEM STRUCTURE
    IF pszCaption != NULL_PSZ
    MemFree(PTR(_CAST, pszCaption))
    ENDIF
    ENDIF

    RETURN lResult

    This code, from Paul Piko but modified, will close a window when ESC is pressed, unless a class variable lPreventEsc is set to true in that window. It also deals with the correct return value for HoverButtons and for displaying help in a window.

    METHOD dispatch(oE) CLASS __FormDialogWindow
    //#s Dispatch for datawindows to arrange Escape for leaving it 12-3-2001
    //#s P.Piko
    //#x
    //#l 2-5-2002: JT: dispatch for context sensitive help
    //#l This is one of the windows that makes up a DataWindow
    //#l Paul Piko: Escape to leave datawindow
    //#l
    //#p
    //#p
    //#r
    //#e
    //#e


    LOCAL aNoCloseWindows:={} AS ARRAY
    LOCAL lGaDoor AS LOGIC


    lGaDoor:=TRUE // Init: ESC closes datawindow
    IF IVarGetInfo(SELF:owner:owner,#lPreventEsc)<>0 // Owner:owner=datawindow calling, we have added lPreventesc (set to true) for EVERY of the windows we don't want to close (it does not work in ic2dw!)
    lGaDoor:=!SELF:owner:owner:lPreventEsc // Use value as defined (lPreventEsc = true means lGadoor = false!)
    ENDIF

    IF oE:message == WM_COMMAND .AND. oE:wParam == IDCANCEL
    IF lGaDoor // 24-7-2003: do not react on escape if false
    PostMessage(SELF:owner:owner:handle(),WM_CHAR,VK_ESCAPE,0)
    SELF:oParent:owner:EndWindow() // GS
    RETURN 1L
    ELSE
    RETURN SUPER:dispatch(oE)
    ENDIF
    ELSEIF oE:OwnerDraw() == 1L // 27-10-2003 for HoverButton
    RETURN 1L
    ELSE
    IF (oE:message = WM_HELP)
    IF ! Empty(SELF:owner:owner:Helpfile)
    oprgHelp:DisplayTopic(SELF:owner:owner:Helpfile)
    RETURN 0L
    ENDIF
    ENDIF
    ENDIF
    RETURN SUPER:dispatch(oE)




    Dick

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

    How to solve class related code issues possible in VO but not in .Net? 05 May 2020 15:18 #14371

  • FFF's Avatar

  • FFF


  • Posts: 956
  • Dick,

    I don't know how to do it in VO. I have the toolbox window from which I can insert a default tabcontrol, not an inherited tab control

    You add a module, containing myTab inherit Tabcontrol
    In the form editor you add the tc, properties, second tab "general" first entry is "inherit from class" - contains "Auto" - overwrite with myTab.
    Look into source:
    CLASS MainDialog INHERIT DIALOGWINDOW 
    
    	PROTECT oCCOKButton AS PUSHBUTTON
    	PROTECT oCCCancelButton AS PUSHBUTTON
    	PROTECT oDCFixedText1 AS FIXEDTEXT
    	PROTECT oDCTabControl1 AS MYTAB
    
      //{{%UC%}} USER CODE STARTS HERE (do NOT remove this line)
    Regards
    Karl (X# 2.5a; Xide 1.25; W8.1/64 German)

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

    How to solve class related code issues possible in VO but not in .Net? 05 May 2020 16:36 #14372

  • Chris's Avatar

  • Chris


  • Posts: 1957
  • Hi Dick,

    As Karl said, for the inherited TabControl (which probably isn't needed anyway, as we discussed) you need to specify it in the Properties window of the Window Editor.

    For the SetTabCaption() method, this indeed does not use any non-public members of the class, it also does not participate in inheritance, so it is very easy to workaround it, as it is stated in the help file topics I pointed you to sometime ago. All you need to do is define an extension class/method:

    CLASS MyExtensions
    STATIC METHOD SetTabCaption(SELF oTabControl AS Vulcan.VO.TabControl, nIndex AS INT, cCaption AS STRING) AS LOGIC
    //#s Set caption of tab in tabwindow
    //#p nIndex = index of desired tab 0=1e 1 cCaption=Caption of Tab
    	
    	LOCAL strucTabItem IS _winTC_ITEM
    	LOCAL pszCaption AS PSZ
    	LOCAL lResult AS LOGIC
    	
    	IF (nIndex != -1)
    		strucTabItem.Mask := TCIF_TEXT
    		PSZCaption := StringAlloc(cCaption)
    		strucTabItem.PSZText := StringAlloc(Psz2String(pszCaption))
    		lResult := TabCtrl_SetItem(oTabControl:Handle(), nIndex, @strucTabItem)
    // Handle to tab control, Index of item, pointer to TC_ITEM STRUCTURE
    		IF pszCaption != NULL_PSZ
    			MemFree(PTR(_CAST, pszCaption))
    		ENDIF
    	ENDIF
    	
    RETURN lResult
    END CLASS

    Just add this anywhere in your code, and there is absolutely none other change you will need to make!

    Also thanks for posting your __FormDialogWindow:Dispatch(), we will review it and will possibly simply include this code in the SDK directly, so again you will need to chnage nothing and maybe other people can make use of this as well if they want. No promises yet though, we'll have a look and will get back to you.
    XSharp Development Team
    chris(at)xsharp.eu

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

    Last edit: by Chris.

    How to solve class related code issues possible in VO but not in .Net? 05 May 2020 17:17 #14373

  • ic2's Avatar

  • ic2

  • Topic Author


  • Posts: 702
  • Hello Karl,

    Ah, of course. I think I subclassed controls so long ago doing exactly what you wrote that I forgot that this is all it takes to move this SetTabCaption method to my subclass. Thanks.

    Dick

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

    How to solve class related code issues possible in VO but not in .Net? 05 May 2020 18:35 #14374

  • FFF's Avatar

  • FFF


  • Posts: 956
  • Glad to help.
    And yes, there are a lot of things, which one did soooo many moons ago, it is often difficult to remember - been there, done that :P
    Regards
    Karl (X# 2.5a; Xide 1.25; W8.1/64 German)

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

    How to solve class related code issues possible in VO but not in .Net? 06 May 2020 17:51 #14404

  • ic2's Avatar

  • ic2

  • Topic Author


  • Posts: 702
  • Hmmm, I got one more thing. What do I overlook?

    1 The AutoSize method was of class ListViewColumn so I created a subclass IC2ListViewColumn and made the autosize of that class:

    METHOD AutoSize() CLASS ic2ListViewColumn
    // This method will adjust the width of
    // the column so that the widest item is
    // completely visible(P. Piko)

    LOCAL dwIndex AS DWORD
    LOCAL n AS DWORD
    IF oOwner != NULL_OBJECT
    dwIndex := oOwner:__GetColumnIndexFromSymbol(SELF:NameSym) - 1
    ListView_SetColumnWidth(oOwner:Handle(), INT(dwIndex), SHORTINT(_CAST,LVSCW_AUTOSIZE))
    n := DWORD(ListView_GetColumnWidth(oOwner:Handle(), INT(dwIndex)))
    ListView_SetColumnWidth(oOwner:Handle(), INT(dwIndex), SHORTINT(_CAST,LVSCW_AUTOSIZE_USEHEADER))
    n := Max(n,ListView_GetColumnWidth(oOwner:Handle(), INT(dwIndex)))
    ListView_SetColumnWidth(oOwner:Handle(), INT(dwIndex), SHORTINT(n))
    ENDIF
    RETURN NIL

    2 For the autosize method of the (already subclassed) listview I changed the LOCAL o from ListViewColumn to ic2ListViewColumn, see below.
    But I can see that o := SELF:getcolumn(i) returns o of ListViewColumn , not of my subclass. Also creating
    METHOD getcolumn(xColumnID) CLASS IC2ListView
    RETURN SUPER:getcolumn(xColumnID)

    does not change that.

    It looks like I can not get this method to work except within the default classs?

    When I run it I get a No exported method error when it hits the line o:Autosize. In the debugger I can see that despite having set o to ic2ListViewColumn o is still from class ListViewColumn (from which I removed the AutoSize method)

    METHOD autosize CLASS IC2ListView
    LOCAL i AS DWORD
    LOCAL o AS ic2ListViewColumn
    FOR i := 1 TO SELF:columncount
    o := SELF:getcolumn(i)
    o:AutoSize()
    NEXT
    RETURN NIL

    Dick

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

    Last edit: by ic2.

    How to solve class related code issues possible in VO but not in .Net? 06 May 2020 18:10 #14407

  • Chris's Avatar

  • Chris


  • Posts: 1957
  • Hi Dick,

    The problem most probably is that the ListView control still creates columns of the standard type ListViewColumn, instead of your own. So when you construct the columns, you will need to use your subclass, instead of the default one.
    XSharp Development Team
    chris(at)xsharp.eu

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

    How to solve class related code issues possible in VO but not in .Net? 06 May 2020 19:30 #14412

  • ic2's Avatar

  • ic2

  • Topic Author


  • Posts: 702
  • Hello Chris,

    [quote="Chris" post=14407The problem most probably is that the ListView control still creates columns of the standard type ListViewColumn, instead of your own. So when you construct the columns, you will need to use your subclass, instead of the default one.[/quote]

    I can see that this happens but why? The method at the bottom of my post (see here again) uses the subclass for o, and getcolumn is the subclassed method too. Everything in red is (from) the subclass. What else should I do?

    Dick

    LOCAL o AS ic2ListViewColumn
    FOR i := 1 TO SELF:columncount
    o := SELF:getcolumn(i)
    o:AutoSize()

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

    How to solve class related code issues possible in VO but not in .Net? 06 May 2020 19:49 #14413

  • wriedmann's Avatar

  • wriedmann


  • Posts: 2281
  • Hi Dick,
    why don't use a extension method for this?
    This is code from my own class library:
    static class XsharpCompatibility
    
    static method AutoSize( self oListViewColumn as ListViewColumn ) as void
    	local nIndex		as int
    	local nWidth		as int
    	local oOwner 		as ListView
    
    	oOwner			:= oListViewColumn:Owner
    	if oOwner != NULL_OBJECT
    		nIndex				:= int( oOwner:__GetColumnIndexFromSymbol( oListViewColumn:NameSym ) ) - 1
    		ListView_SetColumnWidth( oOwner:handle(), int(nIndex), shortint( _cast, LVSCW_AUTOSIZE ) )
    		nWidth				:= ListView_GetColumnWidth( oOwner:Handle(), nIndex )
    		ListView_SetColumnWidth( oOwner:handle(), int(nIndex), shortint( _cast, LVSCW_AUTOSIZE_USEHEADER ) )
    		if nWidth > ListView_GetColumnWidth( oOwner:Handle(), nIndex )
    			ListView_SetColumnWidth( oOwner:handle(), nIndex, shortint( _cast, LVSCW_AUTOSIZE ) )
    		endif
    	endif
    
    	return
    
    static method GetPixelWidth( self oListViewColumn as ListViewColumn ) as int
    	local dwIndex as dword
    	local nPixelWidth as int
    	local oOwner as ListView
    
    	oOwner			:= oListViewColumn:Owner
    	if oOwner != NULL_OBJECT
    		dwIndex 		:= oOwner:__GetColumnIndexFromSymbol(oListViewColumn:NameSym) - 1
    		nPixelWidth 	:= ListView_GetColumnWidth(oOwner:Handle(), int(_cast, dwIndex))
    	else
    		nPixelWidth		:= 0
    	endif
    
    	return nPixelWidth
    
    static method SetPixelWidth( self oListViewColumn as ListViewColumn, nNewWidth as int ) as void
    	local dwIndex as dword
    	local oOwner as ListView
    
    	oOwner			:= oListViewColumn:Owner
    	if (oOwner != NULL_OBJECT) .and. (oOwner:CurrentView == #ReportView)
    		if (nNewWidth > 0)
    			dwIndex 		:= oOwner:__GetColumnIndexFromSymbol(oListViewColumn:NameSym) - 1
    			ListView_SetColumnWidth(oOwner:Handle(), int(_cast, dwIndex), nNewWidth)
    		endif
    	endif
    
    	return
    
    end class
    Wolfgang
    Wolfgang Riedmann
    Meran, South Tyrol, Italy

    www.riedmann.it - docs.xsharp.it

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

    How to solve class related code issues possible in VO but not in .Net? 06 May 2020 20:06 #14415

  • Chris's Avatar

  • Chris


  • Posts: 1957
  • Hi Dick,

    You may be asking the method to return you an object in the form of the type IC2ListViewColumn, but the actual object (column) created is of type ListViewColumn, so this cannot work like that. It's the equivalent of trying to do

    CLASS Dog INHERIT Animal
    PROPERTY HasSharpTeeth AS LOGIC
    ...
    LOCAL oBeing AS OBJECT
    oBeing := Animal()
    LOCAL oDog AS Dog
    oDog := oBeing

    this cannot work, the being has been created as a generic "Animal", you cannot convert this to a "Dog" which has more specific properties. You need to create it as a "Dog" in the first place instead. Of course the opposite would work, creating a "Dog" and then converting it to an "Animal", which is a broader (parent) class.
    XSharp Development Team
    chris(at)xsharp.eu

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

    How to solve class related code issues possible in VO but not in .Net? 06 May 2020 20:57 #14417

  • FFF's Avatar

  • FFF


  • Posts: 956
  • ic2 wrote:

    Show us the code. You should really know better than feed only some lines here and there....
    Better, make a new sample...
    Regards
    Karl (X# 2.5a; Xide 1.25; W8.1/64 German)

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

    Last edit: by FFF.

    How to solve class related code issues possible in VO but not in .Net? 06 May 2020 21:01 #14419

  • ic2's Avatar

  • ic2

  • Topic Author


  • Posts: 702
  • Hello Wolfgang, Chris,

    Thanks for your suggestions. But I am not talking about X# code. I am only preparing my VO code in case I would migrate my projects to X# and if I do that (which still won't be anytime soon I expect, sorry) I want the least possible amount of work in X#.

    I have reverted the changes here to go back to the windows class which works fine of course in VO.

    On the bright site, I've got now only 11 methods which won't work without additional work in X# (like creating extensions methods) , in my 2nd largest library. So that should enable a migration without too much time to spend on changes.

    Dick

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

    How to solve class related code issues possible in VO but not in .Net? 06 May 2020 22:51 #14422

  • ic2's Avatar

  • ic2

  • Topic Author


  • Posts: 702
  • Hello Karl,

    FFF wrote:

    ic2 wrote:

    Show us the code. You should really know better than feed only some lines here and there....
    Better, make a new sample...


    I did show the full code in message #14404 (which is 2 autosize methods). But I rather leave it like it is as it's not a big deal. It works very well in VO but would not in X# and I thought I overlooked something simple like I did with the Tabcontrol. But as it seems not, there's absolutely no reason why I would spend more time on changing this in VO except spending a bit less time on a future X# migration.

    Anyhow, thanks again for the suggestions!

    Dick

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

    • Page:
    • 1