Running Sub in DLL

#1
I seem to have forgotten how to run a subroutine from a toolbar button inside a dll.

I thought it was

^C^C^C(Command "-VBARUN" "Mydll.dll!MySubroutine.SomeSub")

Am I missing something, I do not do this everyday.

Thank you,

ssc

#2
ssc,

A .dll needs to be loaded and this can be autoloaded when you code the .dll

The .dll runs as a command i.e. just type the name of the .dll at the command line or ^C^C^CMyDll




------------------
Regards
John Finlay

#3
John,

Thank you for the reply.

Obviously I am doing something wrong. I have created add-in's before with vb.net and they work. However, I have Office XP Developer and was trying to use the COM Add-in functionality (a little easier then vb.net).

I can compile the dll fine with it set to startup and it shows up fine in IntelliCAD. However, I cannot run anything in the dll from command line. If I go into vba editor and add a reference I can access the dll functions via vba so it seams to work this way.

So, what am I doing wrong that I cannot access the dll functions from the command line or the toolbar button?

Please help once again.

Thank you,

ssc

#4
I get erratic results when trying different toolbar strings. Sometimes the pushing the button will bring up the add-in manager box and other times it will bring up help.

This usually only happens when Intellicad is first started then it may not do anything.

I forgot to mention I am using the latest version 4 PE+

ssc

#5
ssc,

You may have an extra "Enter" in the string. This will repeat the last command and do things like call "help" and other stuff.

I haven't tried out the Office XP Developer's ability to create a .dll

------------------
Regards
John Finlay

#6
John,

Thank you for the reply.

No extra enters in the string. I do not know why it will not work, it shows up in the add-in manager and I can access it with vba. What else could be happening?

ssc

#7
sorry to be a bother about this but here is the latest,

The onconnection, ondisconnect, etc. events work fine in the dll when Icad is started or shutdown. But, I still cannot access any public subs or functions in the class without resorting to vba where I can access them fine.

Any other ideas John?

Thank you,

ssc

#8
I'm having the exact same trouble with creating an AddIn (dll) in VB6 - OnConnect, OnDisconnect, OnStartupComplete events all work great, but I can't access any public Subs/Functions unless I use VBA. It doesn't matter whether I set the dll to autoload or if I use appload. I've also tried the following:

-vbarun MyDll.Connect.MySub
-vbarun MyDll.dll!Connect.MySub

(MySub is a Sub in the Connect module created by the VB 6 AddIn Designer)

Has anyone figured this out? Any help would be much appreciated!



[This message has been edited by benqsmith (edited 03-28-2006).]

#9
benqsmith,

Try the following (from MSDN, I found out that Office Developer will cannot do this):

DLLs make ideal code libraries because they are small and fast. The disadvantage to using a DLL is that you must make certain it is properly registered on the user's machine.

To create a DLL that acts as a code library

Create a new DLL project in Microsoft® Visual Basic®.
Create a new class module in the project.
Set the class module's Instancing property to GlobalMultiUse. This ensures that your procedures will be visible to any project that wants to use them and that they will behave as global procedures.
Set references to any object libraries required by your code.
Add the procedures you want in your code library to the class module as public Function and Sub procedures.
Change the project's name to the name you want for your code library by clicking Properties on the Project menu and entering a new value for the Project Name property.
Make the DLL.
To use the code library from a VBA project, set a reference to the DLL. To set a reference to a DLL, click References on the Tools menu, and use the Browse button to locate the DLL. After the reference has been added, the Object Browser will display information about the procedures in the code library.

If your code library is large, you might not want to load it with your project. Rather than setting a reference to the DLL, you can use the Declare statement to declare references to individual procedures in the DLL.


ssc


[This message has been edited by ssc (edited 03-30-2006).]

#10
John,

Thanks for the quick response. Your solution works just as described for accessing a code-library-type dll with VBA. I guess if I have to use that method to access my existing dlls, I will, but what I'd really like to do is:

1. Create an Add-In using the VB 6 Add-In Designer
2. Reference my existing .dlls within public Subs & Functions in the Add-In so that:
3. I can invoke the public Subs/Functions from the IntelliCAD command line, or if I get really ambitious, through menu items/toolbar buttons.

What I've accomplished so far is this - I've created an Add-In that IntelliCAD recognizes (it appears in the VBALOAD and APPLOAD windows). The Add-In events (AddinInstance_OnConnection, AddinInstance_OnDisconnection, etc.) work fine. But here's my problem: if I create public Subs or Functions in the Add-In (by "in the Add-In", I mean within the Connect.dsr class that the VB 6 Add-In designer creates), I can't figure out how to access these Subs/Functions from the IntelliCAD command line. Let me show you what I mean in code. Here is a quick connect.dsr class from an Add-In that works as described above (i.e., the events work great, but I can't seem to invoke a public Sub from the command line):

Private Sub_
AddinInstance_OnAddInsUpdate(custom() As_
Variant)
MsgBox ("OnAddInsUpdate")
End Sub

Private Sub AddinInstance_OnConnection(ByVal_
Application As Object, ByVal ConnectMode As_
AddInDesignerObjects.ext_ConnectMode, ByVal_
AddInInst As Object, custom() As Variant)
MsgBox ("OnConnection")
End Sub

Private Sub_
AddinInstance_OnDisconnection(ByVal_
RemoveMode As_
AddInDesignerObjects.ext_DisconnectMode,_
custom() As Variant)
MsgBox ("OnDisconnection")
End Sub

Private Sub_
AddinInstance_OnStartupComplete(custom() As_
Variant)
MsgBox ("OnStartupComplete")
End Sub

Public Sub ShowMessageBox()
MsgBox ("It works.")
End Sub

Ok, a little long-winded, but here is the question I've been banging my head against: in the example above, is there a way to invoke the public Sub "ShowMessageBox" from the command line without having to resort to VBA? If so, what is the command line syntax? From looking at other posts to the forum, I thought it was as easy as doing the following:

1. load the Add-In (either automatically at start-up or using VBALOAD)
2. enter something like "MyAddIn.dll!ShowMessageBox" or "MyAddIn.dll!Connect.ShowMessageBox" at the command line.

However, these things aren't working for me. I don't even know if my problem lies with my command line syntax or within the Add-In code. I've also tried adding a separate Class to the Add-In with the Instancing property set to "GlobalMultiUse", but to no avail.

I'd really appreciate any insight you have into this.

Thanks for your help, and sorry for the length of this post!

Ben Smith

#11
After quite a bit of trial and error, I managed to answer my own question. Although I've seen questions about building addins in quite a few places on the web, I've never actually seen an explanation of the process. So, I put together a list of all of the steps needed to create an addin for IntelliCAD using Visual Basic 6 Professional, and to be able to run public Subs from the Intellicad command line. I'm not sure if its the BEST way, but it works. Here it is:

How to Make an Intellicad Addin and Access Public Subs from the Command Line:

In VB 6:

1. Select File -> New Project to show the New Project dialog. Highlight the
"Addin" icon and click the OK button.
2. Right-click "Connect (Connect.Dsr)" and select View Object.
The "Connect (Addin Designer)" window appears.
3. In the Application pulldown, select "Intellicad."
4. Edit "Addin Display Name" and "Addin Description" as necessary.
5. Select the desired load behavior under the "Inital Load Behavior Pulldown."
6. Close the "Connect (Addin Designer)" window.
7. Select Project -> References. The References window appears.
8. Click the check box next to "IntelliCAD 200X Object Library" and then
click the OK button (200X will actually be 2000, 2004, etc., depending on
which version of IntelliCAD you have).
9. Right-click "Connect(Connect.dsr)" again and select View Code.
The Connect.dsr code window appears.
10. Delete EVERYTHING in the code window.
11. Paste the following in the code window (between the dashed lines):

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Dim IcadApp As IntelliCAD.Application

Private Sub AddinInstance_OnAddInsUpdate(custom() As Variant)
'Do nothing
End Sub

Private Sub AddinInstance_OnConnection(ByVal Application As Object, ByVal ConnectMode As AddInDesignerObjects.ext_ConnectMode, ByVal AddInInst As Object, custom() As Variant)
Set IcadApp = Intellicad.Application
'Define references to Subs here:
'IcadApp.DefineFunction "C:FuncName", AddressOf SomeModule.SomePublicSub

End Sub

Private Sub AddinInstance_OnDisconnection(ByVal RemoveMode As AddInDesignerObjects.ext_DisconnectMode, custom() As Variant)
'Do nothing
End Sub

Private Sub AddinInstance_OnStartupComplete(custom() As Variant)
'Do nothing
End Sub
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

12. Insert a module into the VB6 project: Project -> Add Module, highlight the
"Module" icon and click the Open button. The code window for the new module
will appear.
13. Enter all Public Subs that you want to be able to invoke from the command
line into this module.
14. Right-click "Connect(Connect.dsr)" again and select View Code.
The Connect.dsr code window appears.
15. Now, define an IntellCAD function for each sub in the AddinInstance_OnConnection
event of the Connect.dsr class.

Example:

(In the module from steps 12 and 13):

Public Sub ShowMessageBox()
msgbox("Showing a message box.")
End Sub

(Inside the AddinInstance_OnConnection event of the Connect.dsr class):

IcadApp.DefineFunction "C:ShowIt", AddressOf Module1.ShowMessageBox

Do this for each Public Sub that you want to be able to invoke from the
IntelliCAD command line.

Things to remember:
a. Remember to add "C:" before the function name - otherwise, the IntelliCAD
function will NOT be created.
b. The function name after "C:" does NOT have to be the same as the name
of the Public Sub.


16. Build the Addin .dll: File -> Make MyAddin.dll (where MyAddin.dll is whatever
you named the .dll in VB 6. Note: VB 6 will automatically run regsvr32.exe on
the .dll file to register it for use with IntelliCAD.

17. Assuming that in step 5 "Unloaded" was chosen for "Inital Load Behavior":
a. Start IntelliCAD
b. Type "VBALOAD" at the command line.
c. Highlight the name of the Addin in the list of Addins. Note: the name shown
will be the name enetered in step 4 under "Addin Display Name". Then click
the check box next to Loaded/Unloaded if it isn't already checked. When you
click the OK button, the AddinInstance_OnConnection event will fire.
d. If, in step 5, "Inital Load Behavior" was set to "Startup", all of step 17
can be skipped because the Addin will have been automatically loaded.

18. Referring to the example in step 15, entering "ShowIt" at the command line will
run Public Sub ShowMessageBox().

Notes:

a. In step 11, 3 of the events have only a comment in them ('Do nothing)
According to MSDN, all four events MUST be included in the Addin. If
there is no code at all inside an event, the VB compiler will skip the
event completely, so by including at least a comment, the events are
preserved, even if they don't actually do anything. Of course, actual
code could be put in them to be triggered by the events if you want
to do that.
b. In some posts to various IntelliCAD forums, I've read that after
creating the .dll, it has to be copied into the same directory where
Icad.exe resides, and then registered with regsvr32.exe. With VB 6, I've
found that this isn't necessary, but to do it here are the steps:
i. Open a dos/command prompt window (in Windows XP: Start -> Programs
-> Accessories -> Command Prompt)
ii. Navigate to the directory where Icad.exe resides (by typing
something like: cd c:\program files\intellicad\intellicad 6.0 professional)
iii. Type "regsvr32 myaddin.dll"

John - thanks for your help with this. Without it, I'd still be lost.

Ben Smith

#12
Very informative.Works like a charm.
Does this only work in VB6 as I only
have VB5 at work?
If not does anyone have an insight on how to do it with VB5?

Thanks

#15
gsprink,

AddressOf is a VB operator. My understanding is that it retrieves the memory address of the referenced Sub and passes it along to IntelliCAD. If you don't put "AddressOf" before the name of the Sub you are defining as a function in IntelliCAD, the function won't work in IntelliCAD.