Click to See Complete Forum and Search --> : ActiveX exe variable passing
cscrum
Jan 7th, 2001, 08:52 PM
I'm creating a simple ActiveX exe so I can run an out of thread process. It is basically just a subroutine that I don't want holding up the main exe. I put the subroutine in the class section of the AX EXE, but I need to pass variables to it. I have referenced the AX object in my main code, but I don't know how to pass the variables to the subroutine in the AX EXE class. Can anyone help?
If you are using the ActiveX exe by calling a shell function, you can pass parameters as part of the command string. That is probably the easiest way to pass one or two variables. Another way is to expose a function in a class module in your ActiveX exe. The function can have the variables you need and it can launch other functions inside your activex exe with those parameters. Set a reference to the activex exe from your first project and you should see the functions in the class module.
cscrum
Jan 8th, 2001, 09:54 AM
Thanks for the info. I'm pretty new at this activeX exe and dll stuff. Let's say I needed to pass 2 variables x and y. What would the function look like in the aX exe? Also, if I decide to go the shell route, will it run as a seperate thread or will my main program still be locked while the process runs?
'This is in a class module (YourClass)
Option Explicit
Public Sub YourFunction(x as Integer, y as Integer)
'Add Code here to set your variables and call a function in activex
YourotherFunction (x,y)
End sub
In your main app,
Dim TheActiveXfunction as ActiveXexename.YourClass
'This should show up in the intellipopup if you have references right
Set TheActiveXfunction=CreateObject ("ActiveXexename.YourClass")
TheActivexfunction.YourFunction 10, 20
'This should pass 10 and 20 to the active X function
If you shell out it will be in a different thread by default. You can change to wait if you want.
You should take a look at the coffee2 project on the MSDN library CD. Good example (basic) but it will help.
cscrum
Jan 8th, 2001, 02:11 PM
Thanks. I'm sure this will help a ton. I looked at the coffee project in the VB books online, but it had nothing about variable passing, hence the original post. I assume the coffee2 is different. I'll pull out the CD's and see if I can find it.
Cameron
cscrum
Jan 9th, 2001, 10:31 AM
I modified your sample code to fit my application and the variables passed. However, the AX program still locks up my application. Do I need to include a timer to check to see if it is done so I can continue to use my main app? I thought the whole idea of starting a seperate process was to avoid doing this?
Cameron
Maybe I misunderstood what you are trying to do. Could you post the code here?
I use AX to send events to clients apps. I pass a number of variables to the clients. At one point I ran 16 clients on 3 different machines (48 total). I had some clients sleeping and some updating listviews and others just sitting there. I then generated 10 events from the AX server. all 48 clients received all 10 events (some when they woke up, but the thread got the message). The AX server did not care what the clients were doing. I do this through RaiseEvent in my public class at the AX server class module. At the clients, I process the message in the event sub (VB creates this for you just like command1_click if you have references right). It works great and is extremely fast. Another example that will help is DCOMserver Demo from MS.
Start here:
http://support.microsoft.com/support/kb/articles/Q161/8/37.ASP
cscrum
Jan 9th, 2001, 11:18 AM
Ron,
I'm not trying to do anything this elaborate. I just have one machine. The sub application searches through a very large database and the manipulates the results. It searches through a database of thousands of coordinate defined line segments to pull out and sort the ones that match together to form complete polygons based on specific criteria. It takes a while to do all this (a couple of hours...it's a big database). Since this is only one aspect of the program, I didn't want a user to have to sit and wait before running other parts of the program. I was trying to offload this processing to a seperate thread that would run in the background, so while the sub is running I can continue to perform other tasks in the main program. When I "call" the AX exe, my main program waits until the AX exe is fininshed processing before I can use the main app again. I am aware of the Event and RaiseEvent statements and am using them sucessfully to report the progress of the sub, but this is not the issue. I just want to keep using the main app while the sub processes. I thought the idea of a seperate thread was so that control of the main program wouldn't be locked up. Would compiling the AX as a sperate main exe and using a shell be better for someting like this?
I do this in other applications I have, but it seems kind of "hoaky" to me to do this.
Cameron
Cameron,
I would compile the first (main) app as a standard exe. the second app I would compile as a ActiveX exe. This tells VB to run it as an out-of-process thread. A ActiveX dll runs in-process on the same thread. In the ActiveX exe I would define a sub StartDatabaseFunction and an event Database(Percent as integer). Declare a Public Boolean DatabaseFunctionIsNotbusy. In the sub Main of AX , set DatabaseFunctionIsNotbusy = TRUE.
then add
While DatabaseFunctionIsNotbusy
'do your database routine here
Wend
In the class module StartDatabaseFunction
Set DatabaseFunctionIsNotBusy = False
in your database function
RaiseEvent at the end like RaiseEvent Database(100)
At the client, I would use the CreateObject function like
Dim WithEvents YourObject as YourAXexeName.Yourclass
Set YourObject=CreateObject("YourAXexeName.Yourclass")
YourObject.StartDatabaseFunction
Place the code to handle the events in the yourobject.database
Your client should receive the event and know when it is done. You could also pass percentages like 25, 50 ,75.
After the database function is done, the ActiveX exe should unload. Make sure you have the Start Mode under Component set to Active component.
Hope this points you in the right direction.
cscrum
Jan 9th, 2001, 10:40 PM
Ron,
This didn't do anything any different. The AX exe still locks up my main app. If I try to click anywhere in the main app while the AX exe is running, I get one of those switch to/retry windows. Any ideas?
Cameron
Cameron,
Maybe you could add a timer to the dll with it disabled by default. In your public function, enable the timer. In your timer event, disable the timer and do your database stuff. The remote client calls the public function and starts the timer and returns. When database function is done it raise the event. So your remote app is done when it enables the timer and the thread control should back at your remote app immediately.
Ron
JohnInBoulder
Jan 12th, 2001, 09:10 PM
Here is the deal. The multithreading is bass ackwords. Yes, the Activex Exe is running in another thread, but the only way that VB can marshal events, properties, methods etc between your main app and the other thread is by using THE MESSAGE QUEUE. Yep....Vb uses SendMessage to send a message that encapsulates the property, method, event etc to your ActiveX Exe. So you wait till the activex exe finishes.
AHHHHHHHHHHHHHHHHHHH. Can't wait for VB.NET can we.
Anyway, the HACK you need to do isnt all that bad.
1) In your activex exe, make a stub function that fires a timer off. The timer will then execute the function that takes a long time to call. This allows the SendMessage to return to your program instantly!
I used szInput and nVal to show you you can pass any parameters you want to setup the function...just save them in module level variables...dont do any calculations. You need to exit this function fast so it doesnt hang up the caller.
g_obj this is so you can refer to your object in the timer stub.
Public hTimer&
Public Function DoSomethingThatTakesALongTime(byval szInput as string, byval nVal as integer)
set g_obj = me
hTimer = SetTimer(0, 0, 10, AddressOf HackTimer)
End function
2) Create a .bas module in your project...only funcs in .bas modules work with AddressOf
Public g_obj As YOURCLASS
Public Sub HackTimer(ByVal hWnd&, ByVal dwMsg&, idEvent&, ByVal dwTime&)
Call KillTimer(0, g_obj.hTimer)
' this is the function you really wanted to call!
' And it runs in its own thread.!!!
g_obj.TheFunction
End Sub
Of course, this aint perfect, you got to put a little more effort into this to prevent recursion and stuff like that, but this will work.
Have Fun.
- John
tumblingdown
Jan 13th, 2001, 05:12 AM
Cameron, did you not get the reply to your mail. I sent to the return addy angela@waveconceptsintl.com
td.
cscrum
Jan 13th, 2001, 09:20 AM
TD,
I did not get that reply. That account has been terminated for a while. My wife must not have changed her identity yet on her machine. Please send it to c-crum@waveconceptsintl.com or post it here.
Thanks,
Cameron
vbforums.com
Copyright Internet.com Inc., All Rights Reserved.