Results 1 to 21 of 21

Thread: Add-In - to call (run) host application's procedure

  1. #1

    Thread Starter
    Member
    Join Date
    Mar 2018
    Posts
    35

    Add-In - to call (run) host application's procedure

    Is it possible?

    I have in Add-In the universal code Export function (for backup purposes). It is suitable for most projects, which are used this Add-In. However some projects (this Add-In project it self, particularly) has their own more sofisticated backup functional.

    The goal is to detect existing in the specialy named module and the specialy named procedure in it. If it exist, so use it. If no - use common Export procedure, stored in Add-In.

    Thank you.
    .

  2. #2
    PowerPoster Zvoni's Avatar
    Join Date
    Sep 2012
    Location
    To the moon and then left
    Posts
    5,261

    Re: Add-In - to call (run) host application's procedure

    Not sure if i understood you correctly, but i think "CallByName" is what might get you running....
    Last edited by Zvoni; Tomorrow at 31:69 PM.
    ----------------------------------------------------------------------------------------

    One System to rule them all, One Code to find them,
    One IDE to bring them all, and to the Framework bind them,
    in the Land of Redmond, where the Windows lie
    ---------------------------------------------------------------------------------
    People call me crazy because i'm jumping out of perfectly fine airplanes.
    ---------------------------------------------------------------------------------
    Code is like a joke: If you have to explain it, it's bad

  3. #3

    Thread Starter
    Member
    Join Date
    Mar 2018
    Posts
    35

    Re: Add-In - to call (run) host application's procedure

    Zvoni, hello.

    Forgive for my English :(

    I try to rephrase...

    My add-in is developed to connect to both VB6 and VBA IDEs. So, in any project (host), being developed under VB6, or Access, or Excel, user can ask this add-in to simply backup this project to, say: "%CurDir%\_BackUp\TimeStamp\*.*", by pressing command button on add-in's control bar with the following calling of "sb_AddIn_BackUp", that is stored in compiled add-in. In case of VBA the modules are exported to tmp-place and then copied to backup-place. In case of VB6 the modules simply copied to backup-place.

    However, several of my projects has their own, individual backup procedures (with extended specific functionality). In this case I want of add-in do not call its mentioned backup procedure "sb_AddIn_BackUp", but tried first of all to search for the procedure "sb_App_BackUp" in the module "m_App_BackUp" of maintained host, and then tried call it, instead of its own "sb_AddIn_BackUp".

    Re: "CallByName"
    Thank you for advice, but I I already thought this way.

    Firstly, I never used it in my life and, accordingly, I do not know the nuances of its behavior.
    And, the second, to be honest, I look a little obliquely at it, as a very surrogate and palliative way.

    I very much hoped that there might be a more natural way to call. Maybe through the API ... maybe by raising some event in the host ... maybe through some form of callback ... maybe by AddressOf ... maybe somehow ... I don't know :(
    .

  4. #4

    Thread Starter
    Member
    Join Date
    Mar 2018
    Posts
    35

    Re: Add-In - to call (run) host application's procedure

    OK. I tried
    CallByName(object, procname, calltype,[args()])

    However, I can't give to it the right object it need as the first parameter,
    cause after the Add-In is loaded in host,
    all objects, that I have on the hands, are:

    1. Application (As VBIDE.VBE) - the reference on host application (IDE) and
    2. AddInInst (As VBIDE.AddIn) - the reference on Add-In instance in host.

    Both are passed by Add-In event:
    OnConnection(Application, ConnectMode, AddInInst, Custom)

    I unsuccessfully tried with various syntax of:
    GetObject([pathname] [, class])

    and I have no idea now
    - how to create the correct object, that will conform to the CallByName :(

    Code:
    ' this is an Add-In's procedure that try to call procedure in host
    ' mi__HostVBE - local instance of host Application, passed with OnConnection
    ' sp_CallByName_F - procedure in host
    
    Public Sub sp_CBN() ' CallByName
    Dim vpr As VBIDE.VBProject
    Dim vcm As VBIDE.VBComponent
    Dim obj As Object
    Dim sPcd$
        
        Set vpr = mi__HostVBE.ActiveVBProject
        
        For Each vcm In vpr.VBComponents
            With vcm
                Select Case .Name
                    Case "Form1"
                        Stop
                        sPcd = "sp_CallByName_F"
                        If fn_PcdExist(vcm, sPcd) Then ' If procedure exists in this module
                            Set obj = GetObject("???", "???")
                            Call CallByName(obj, sPcd, VbMethod)
                        End If
                    Case Else
                        Debug.Print .Name
                End Select
            End With
        Next
    End Sub
    Another alternative way, that I see, is to put call string in 'Imrnediate Window' in host and try to emulate keystroke 'Enter'.
    .

  5. #5
    PowerPoster
    Join Date
    Feb 2017
    Posts
    5,667

    Re: Add-In - to call (run) host application's procedure

    Quote Originally Posted by asbo View Post
    However, several of my projects has their own, individual backup procedures (with extended specific functionality). In this case I want of add-in do not call its mentioned backup procedure "sb_AddIn_BackUp", but tried first of all to search for the procedure "sb_App_BackUp" in the module "m_App_BackUp" of maintained host, and then tried call it, instead of its own "sb_AddIn_BackUp".
    But for the Add-In, the project is source code, it is text.
    How are you going to call it? The program is not running.

    It would have to run as vbScript, interpreted...

    (...If I am understanding correctly what you want to do.)

  6. #6

    Thread Starter
    Member
    Join Date
    Mar 2018
    Posts
    35

    Re: Add-In - to call (run) host application's procedure

    Quote Originally Posted by Eduardo- View Post
    But for the Add-In, the project is source code, it is text ...
    Yeah. I'm clearly understand it.
    And this is the reason why in the first sentence of the start post I not asked "How?", but asked "Is it possible?" ...


    Quote Originally Posted by Eduardo- View Post
    It would have to run as vbScript, interpreted...
    However... however it is an idea. It is the another way.

    Let Add-In can't run anything directly in host project, but the host can say to Add-In (by any comment line(s) in predefined place of project code): "Get saved vbscript on "Path-Name" and run it!"


    Quote Originally Posted by Eduardo- View Post
    (...If I am understanding correctly what you want to do.)
    I tried to explain everything as much detail as possible.
    Sorry for possible misunderstanding :(
    .

  7. #7
    PowerPoster
    Join Date
    Feb 2017
    Posts
    5,667

    Re: Add-In - to call (run) host application's procedure

    But I think (correct me if I'm not understanding correctly) that it is quite weird that the program itself has code to backup its own source code.

  8. #8

    Thread Starter
    Member
    Join Date
    Mar 2018
    Posts
    35

    Re: Add-In - to call (run) host application's procedure

    A little bit wrong :)

    Not "the program itself has code to backup its own source code", but the developer of this program has it. He use the Add-In for the same purposes - developing. And backup process is the part of developing.

    As for me it is very actual for several projects under Access. And now I continue to develope this Add-In under VB6. As I wrote above, it is universal Add-In for VB6 & VBA. However it need more complex backup & synch procedures between VB6 & VBA related code. I develope current version of this Add-In having connected in IDE the previous it's release. But the backup functionality for common cases, implemented in my own Add-In, not satisfy me in its developing :)

    Naturally, the need to have such a procedure inside the compiled release does not make sense. Only at the development stage it is needed ...
    .
    Last edited by asbo; Sep 5th, 2018 at 04:32 PM.

  9. #9
    PowerPoster
    Join Date
    Feb 2017
    Posts
    5,667

    Re: Add-In - to call (run) host application's procedure

    Then I think the Add-In should run the "custom backup" program from the developer compiled.

    If I understood, the developer should enter in some option of the Add-In the path to the backup program (exe), and the Add-in would run it when it is needed (with Shell, ShellExecute or similar method).

  10. #10

    Thread Starter
    Member
    Join Date
    Mar 2018
    Posts
    35

    Re: Add-In - to call (run) host application's procedure

    Then I think the Add-In should run the "custom backup" program from the developer compiled.
    No-no! Not compiled at all!

    When I say "to backup", it means here:
    to save current state of source code of not-compiled project that is being in developing(!) in current moment.


    ... the developer should enter in some option of the Add-In ...
    And "Yes", and "No" at the same time :)

    No - because the developer does not pass explicitly to Add-In any parameters at all.
    This is the main concept of my Add-In (up to now, at least) - no setup, no ini files or registry records. This add-on is self-contained and works from box. And I want to keep it that way if I can...

    Yes - because the Add-In receives, however, external directives, but in an implicit manner, through the presence of certain attributes in the code it investigated. That is to say - the specially named module(s) and the specially named procedure(s) in it (or any other uniquely interpretable and easy accessible for reading source code element).


    ---------------------
    Now I will try explain the goal once more time :)

    1. The common simple case
    The suffixes _xls, _mdb and _VB6 are not significant and not used to define type of project.
    They are here only for view clarity.

    Let, there are three of independent (in their functionality) projects:

    Code:
    Dvl\
        Dvl_xls.xls
        Dvl_mdb.mdb
    
        Dvl_VB6\
            Module1_VB6.bas
            Form1_VB6.frm
            Dvl_VB6.vbp
    Editing any of this projects the developer can create project's backup simply by pressing button on Add-In command bar in IDE, that will result to:

    For VBA-projects:
    Code:
    Dvl\
        Dvl_xls.xls
    
        _Bup\
            \Dvl_xls_mmdd_hhnn\
                Module1_VBA.bas
                Form1_VBA.frm
    For VB6-project:
    Code:
    Dvl\
        Dvl_VB6\
            Module1_VB6.bas
            Form1_VB6.frm
            Dvl_VB6.vbp
    Dvl\
        _Bup\
            \Dvl_VB6_mmdd_hhnn\
                Module1_VB6.bas
                Form1_VB6.frm
                Dvl_VB6.vbp
    In case of VB6-project the "_Bup" folder created at one level up ".." to project folder, cause it has own folder unlike vba-projects, that has no folder, but all of its members are in one-file-container.


    2. Rare special, individual case,
    when the universal application, intended for both of VB6 & VBA environments,
    is developing under VB6.

    Here and below "the project" means the union of both VB6- and VBA- branches.

    Code:
    Dvl\
        Dvl_VB6\
            Form1_VB6.frm
            Export_VB6.bas
            Module1_VB6.bas
            Module2_VB6.bas
            Module3_VB6.bas
            _Class_VB6.cls   ' *** ATTENTION !!!
            _Dvl_VB6.vbp
    
        Dvl_VBA\
            Form1_VBA.frm
            Export_VBA.bas
            Module1_VBA.bas
            Module2_VBA.bas
            Module3_VBA.bas
            _Class_VBA.cls   ' *** ATTENTION !!!
            _Dvl_VBA.vbp
    The peculiarity of this project is that both VB6 & VBA branches are identical,
    excluding members under ' *** ATTENTION !!! line, i.e. _Class_*.cls & _Dvl_*.vbp

    Reaching such identity I got the opportunity to develop any branch of the project - the one that is convenient for me at the moment.

    However, the simple backup procedure, implemented in Add-In, is not satisfied me already.
    So, I have the special backup procedure intended for this project only and placed in special module "Export.bas". This module will be removed from project when release code will be prepared (this functionality realised in its export procedures too).

    Say, I made changes in VB6-branch and called (manually) backup procedure.
    The result is:

    Code:
    Dvl\
        _Bup\
            mmdd_hhnn_VB6\      ' VB6 is master now
                VBA\            ' VBA is slave
                    _Class_VBA.cls   ' *** ATTENTION !!!
                    _Dvl_VBA.vbp
    
                Form1_VB6.frm
                Export_VB6.bas
                Module1_VB6.bas
                Module2_VB6.bas
                Module3_VB6.bas
                _Class_VB6.cls   ' *** ATTENTION !!!
                _Dvl_VB6.vbp
    And vice-versa:

    Code:
    Dvl\
        _Bup\
            mmdd_hhnn_VBA\      ' VBA is master now
                VB6\            ' VB6 is slave
                    _Class_VB6.cls   ' *** ATTENTION !!!
                    _Dvl_VB6.vbp
    
                Form1_VBA.frm
                Export_VBA.bas
                Module1_VBA.bas
                Module2_VBA.bas
                Module3_VBA.bas
                _Class_VBA.cls   ' *** ATTENTION !!!
                _Dvl_VBA.vbp
    Both of schemes above illustrated the case, when the slave folder was synchronized with master. If user didn't decide to synch them, then slave branch backuped in full, but not ATTENTION-members only.


    ---------------------
    And what I want of my Add-In?!

    Can it find module "Export_*"? Yes, it can.
    Can it find export procedure in module "Export_*"? Yes, it can.
    Can it run it instead of its own compiled backup routine? No answer :(

    Who knows...
    ???
    .

  11. #11
    PowerPoster
    Join Date
    Feb 2017
    Posts
    5,667

    Re: Add-In - to call (run) host application's procedure

    Hummm, every time I had a question regarding Add-ins I found very few people that knew something or had some experience with Add-Ins.
    You can find a couple here in the forum, perhaps.
    I have some experience with Add-Ins but I'm not an expert at all.
    But my understanding is that what you are trying to do is not possible, at least not in the way you wants to do it.

    What, I think it could be possible is:
    1) To read the source code from that backup routine (that you already have managed to find).
    2) To "copy" that source code and execute it line by line in the Add-In.
    3) How? With a VBScript interpreter.

    https://www.google.com/search?q=vb6+run+vbscript

  12. #12
    PowerPoster
    Join Date
    Feb 2017
    Posts
    5,667

    Re: Add-In - to call (run) host application's procedure

    Or... I would test if CallByName works.
    It was suggested by Zvoni on post #2

    The code should be a in form, and you call it like this:

    Code:
    CallByName Form, "ProcedureName", VbMethod
    The procedure "ProcedureName" must be Public.

    CallByName Function reference at MSDN.


    Another possibility of something to test would be to place the backup procedure in a bas module and use AddressOf and the API CallWindowProc with some window hwnd.

    I don't have much hopes that these thinks could work, but I would test them.
    If you don't know how to test these ideas, please provide sample projects of both: Add-In and host project, where you already managed to find the backup procedure.

  13. #13
    Frenzied Member
    Join Date
    Jun 2015
    Posts
    1,294

    Re: Add-In - to call (run) host application's procedure

    [...]
    Last edited by dz32; Apr 26th, 2019 at 11:14 AM.

  14. #14

    Thread Starter
    Member
    Join Date
    Mar 2018
    Posts
    35

    Re: Add-In - to call (run) host application's procedure

    Eduardo-, dz32,
    thank you very much for your support.

    I need a some of time now to create and present here the testing source code package of Add-In and several host applications.

    Moreover, I succsessfully tested the method from my post #4:
    "... put call string in 'Imrnediate Window' in host and try to emulate keystroke 'Enter'."
    I want to include this solution to testing bundle.

    Just a little time...
    I'll be back ASAP.
    .

  15. #15
    PowerPoster
    Join Date
    Feb 2017
    Posts
    5,667

    Re: Add-In - to call (run) host application's procedure

    Hello, I think I found a way to do it with an UserControl.

    Attached are the two test projects (Add-In and host project)

    PS: but if you are planning to backup projects in Office I think you don't have UserControls there...
    Attached Files Attached Files

  16. #16

    Thread Starter
    Member
    Join Date
    Mar 2018
    Posts
    35

    Re: Add-In - to call (run) host application's procedure

    So...
    Hello all.

    As I promised, I prepared the tested bundle at last:
    (half a year hasn't passed (c) VSV)

    Adi_Bnd.zip
    (why I can not get a beautiful picture of attachment like the others?)

    It based on MS VB6 Add-In template chassis of '98 conveyor,
    and includes:

    Code:
    \AddIn          - source code of
        \_MS_Src        - original MS chassis
        \VB6            - 'asbo_VB6_Dsn' add-in
        \VBA            - 'asbo_VBA_Dsn' add-in
    Both VB6 and VBA projects are identical, excluding:
    - d_asbo.dsr (difs are in header fields only, not in code!)
    - asbo_VB6_Dsn.vbp
    and both are needed to be compiled, of course :)
    (however, you can to try them under IDE too)

    Code:
    \Hosts          - host applications of
        \Host_VB6\*.*   - VB6 source
        Host_VBA.mdb    - VBA source Access 2003
        Host_VBA.xls    - VBA source Excel 2003
    They, naturally, no need to be compiled, but overwise -
    they intended to be in development mode, i.e. - in IDE.

    After the specific add-in being compiled, it will appeared in host VBE, under:
    '> Add-Ins > Add-In Manager ...'

    I hope, that it will be in non-auto-loading mode, so it need to be loaded
    (by dbl-click on it or set 'Loaded/Unloaded' flag).

    After it, the new option will be available at:
    '> Add-Ins > asbo_VB6_Dsn'

    There are four buttons on the form, that appears on this option click -
    two original MS buttons 'OK' and 'Cancel' with MS-programmed behavior and
    two my buttons:

    Fibo by AddIn
    add-in calcs Fibo with a low accuracy by its own code

    Fibo by Host (if exist)
    add-in will try to find in Host project:
    - the module, named 'm_Other' and
    - the procedure, named 'sx_Fibo', in it,
    to make more accurated Fibo calcs with its help.

    If the mentioned module or procedure not founded,
    add-in calcs Fibo by its own, low-accuracy procedure.

    Initially, 'm_Other.sx_Fibo' is presents in Host project,
    so, you need to rename (to comment or delete) this procedure or module at all
    and save the Host project after it to fully test the behavior above.

    As I wrote in post #4, I tricked with the Host's 'Immediate Window'.
    Before, I manually copy-pasted 'm_Other.sx_Fibo' and pressed 'Enter'.
    Now I do the same, but by more technological way:)

    However, I got the new flexibility and extensibility with this approach.
    It is possible now to pass some parameters for add-in in comment lines,
    to calc Fibo (in add-in) with greater accuracy, for example :)

    Of course, instead the example of Fibo calcs this scheme can be used for any other purposes.

    But, in general, I do not like this solution,
    as palliative and not elegant - to use string description of object instead of object itself.

    So, the question is open still...
    .
    Last edited by asbo; Sep 8th, 2018 at 02:40 PM.

  17. #17
    PowerPoster
    Join Date
    Feb 2017
    Posts
    5,667

    Re: Add-In - to call (run) host application's procedure

    Hello asbo,

    I'll check your project (may be later).

    But did you see what I posted on post #15?

  18. #18

    Thread Starter
    Member
    Join Date
    Mar 2018
    Posts
    35

    Re: Add-In - to call (run) host application's procedure

    Eduardo-, hello.

    Thanks a lot for yor efforts!

    I saw your meddage (#15) already, but I decided to not download attachment immediatelly,
    but to delay to the moment, when my bundle will be ready to publishing.

    Now I downloaded it already - thank you once more!

    The common idea is understanable for me.
    Several questions, that I have now, are not significant.
    But the one only - VBA. I will try to play on it.

    And, regardless of VBA, the serious obstacle is present - the necessarily to have an form and user-control.
    .

  19. #19
    PowerPoster
    Join Date
    Feb 2017
    Posts
    5,667

    Re: Add-In - to call (run) host application's procedure

    To make your code to work, I had to replace the line:

    Code:
    Set imw = HostVBE.Windows(IMW_NAME)
    with:

    Code:
    Dim w
    For Each w In HostVBE.Windows
        If w.Type = vbext_wt_Immediate Then
            Set imw = w
            Exit For
        End If
    Next
    Because "Immediate" (that is the value of IMW_NAME) is localized when VB6 is in other languages (in my case it is Spanish and it is "Inmediato").

  20. #20

    Thread Starter
    Member
    Join Date
    Mar 2018
    Posts
    35

    Re: Add-In - to call (run) host application's procedure

    Oh! This is a very valuable observation.
    Lucky you have another locale :)

    And, regardless of locale, your reference to an object by a predefined constant, but not by a name, is a more right approach.

    I accept this gratefully and will make corrections to the code.


    -----------
    Re: your "Add-In_backup_test"

    Unfortunately I can't find solution to implement User Control in VBA-based projects.
    Moreover, investigating your code I discovered, that VBA VBIDE has no
    Enum vbext_ControlType
    unlike VB6 VBIDE. It seems me, that it is unpossible to use User Controls in VBA :(

    Two question I have of your code:

    1. Does the following construction
    Code:
    If (iComp.Type = vbext_ct_VBForm) Or _
       (iComp.Type = vbext_ct_UserControl) Or _
       (iComp.Type = vbext_ct_VBMDIForm) Then
    means that you try to find the User Control in all mentioned objects?
    I never used User Controls before, so I don't know - may it be incapsulated not only in form, but in MDI Form or another User Control too?

    2. You try to identify control by its right (after dot) part of its .ProgId property:
    If Right(iCtl.ProgId, 19) = "ctlBackupSourceCode" Then

    that I transformed to:
    If Right$(iCtl.ProgId, Len(sCtlNam)) = sCtlNam Then

    However, the .ClassName property is present there and code may be simplified to:
    If .ClassName = sCtlNam Then

    But I'm afraid that your choice of .ProgId instead of .ClassName is a special and deliberate. Would you please, to clarify this point?
    .

  21. #21
    PowerPoster
    Join Date
    Feb 2017
    Posts
    5,667

    Re: Add-In - to call (run) host application's procedure

    Hello asbo,

    Quote Originally Posted by asbo View Post
    Re: your "Add-In_backup_test"

    Unfortunately I can't find solution to implement User Control in VBA-based projects.
    Moreover, investigating your code I discovered, that VBA VBIDE has no
    Enum vbext_ControlType
    unlike VB6 VBIDE. It seems me, that it is unpossible to use User Controls in VBA
    I just opened Excel and went to the VBA editor and (as suspected) I don't see any UserControl.
    So... there are no UserControls in VBA.

    Quote Originally Posted by asbo View Post
    Two question I have of your code:

    1. Does the following construction
    Code:
    If (iComp.Type = vbext_ct_VBForm) Or _
       (iComp.Type = vbext_ct_UserControl) Or _
       (iComp.Type = vbext_ct_VBMDIForm) Then
    means that you try to find the User Control in all mentioned objects?
    I never used User Controls before, so I don't know - may it be incapsulated not only in form, but in MDI Form or another User Control too?
    I used some code of an Add-In that I already had and modified it for making the test program.
    It means that the UserControl control instance for the backup could be placed not only in a Form but also in a MDIForm or in any (other) UserControl (of any other type).

    But I did that that way only because I had the code already written and I left it as I was.

    Quote Originally Posted by asbo View Post
    2. You try to identify control by its right (after dot) part of its .ProgId property:
    If Right(iCtl.ProgId, 19) = "ctlBackupSourceCode" Then

    that I transformed to:
    If Right$(iCtl.ProgId, Len(sCtlNam)) = sCtlNam Then

    However, the .ClassName property is present there and code may be simplified to:
    If .ClassName = sCtlNam Then

    But I'm afraid that your choice of .ProgId instead of .ClassName is a special and deliberate. Would you please, to clarify this point?
    .
    Again, the same: that was made very fast and I used iCtl.ProgId because I found the Control type name in that property used in the code that I already had (of the old Add-in program I was modifying), and because I didn't remember about .ClassName.
    I did that in a couple of minutes to test my idea of using an UserControl, and when I saw that it worked I posted it here.
    They were not "special and deliberate" but only because I don't remember much about Add-Ins programming and always start by modifying some other Add-In program already working.

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width