Advice on a VB6 app accessing a C\C++ DLL...
|
|
Thread rating:  |
Jason - 27 Apr 2006 17:49 GMT Hello,
I'm posting this in both a VB and a C\C++ Win32 group because this deals with both languages. If you feel I'm in the wrong spot, just direct me to where you think I should go. I don't claim to be an expert programmer, that's why I'm asking for advice. Thank you in advance.
Here's the situation. I have a VB6 app that accesses a C\C++ DLL. It has to be a C\C++ DLL because I link with some 3rd party object files. For the most part, this all works. I've exported functions and VB can access them just fine, I do some string and array passing between the 2, but I'm trying to take things a step further.
The 3rd party object files start a thread that currently doesn't interact with the VB app. The thread does some network access. When the network connection is lost, the thread calls a function that I specify. What I'd like to do is have the specified function create an event of some sort so the VB app knows something went wrong and can react.
Now, how do I do this?
I've read that the I can't simply use a VB callback function because it would be an outside thread calling the function and VB doesn't like that. I've also read in some places that this can be done with SubClassing in VB and a simple PostMessage call on the C\C++ DLL side. I've also read that this can be done if I create an ActiveX object on the C\C++ side and a call to FireEvent. There's probably a few other ways to do what I want, but these seem to be the most popular in my search. If there's something better\easier that'll do the trick, I'll gladly listen.
I've never attempted to do anything like this before, so I have no experience to draw from.
So, what is your advice? How would you go about doing this? ActiveX? SubClassing? Something else? Know any good books that deal with this subject?
Thank you,
Jason
Jim Mack - 27 Apr 2006 18:01 GMT > Hello, > [quoted text clipped - 17 lines] > that. I've also read in some places that this can be done with > SubClassing in VB and a simple PostMessage call on the C\C++ DLL side. It's true that VB6 does not support free threading, and you can crash it if a callback from a separate thread causes an access to the VBRT. You can get away with setting a global flag in VB code, which you poll for on the original thread, but that often isn't fully useful.
If all you're looking for is a notification, send WM_KEYDOWN to some control on the VB form, like a hidden textbox. Pass this hWnd to the C side when you call. This raises a _KeyDown event in the textbox, which you can react to as you would any event. Of course, your VB app must be processing messages, which won't happen if you're in a tight loop in the DLL.
 Signature Jim Mack MicroDexterity Inc www.microdexterity.com
Jason - 27 Apr 2006 19:21 GMT I think this is exactly what I'm looking for. It seems so easy now that you say it. THANK YOU!!!
Jason - 28 Apr 2006 01:15 GMT Just for people that may be googling this same thing. This did solve my problem. I had the VB app pass the parent window's handle (hwnd) and the button's handle (I used a hidden button, not a text box) to the DLL. Whenever I wanted the button pressed, I just sent a message like so from the thread the DLL created:
SendMessage(parentHwnd, WM_COMMAND, MAKELONG(GetDlgCtrlID(buttonHwnd), BN_CLICKED), (LPARAM)buttonHwnd);
Works like a charm. Things I haven't worked out yet and I'm not sure of because of inexperience with Windows messaging is what happens if there's another dialog box is the current focus. You may have to playing around. A easy solution if the signal is ignored\blocked\whatever would be to just continiously loop the button being pressed (with a timer delay).
J French - 28 Apr 2006 09:15 GMT >Just for people that may be googling this same thing. This did solve my >problem. I had the VB app pass the parent window's handle (hwnd) and [quoted text clipped - 4 lines] >SendMessage(parentHwnd, WM_COMMAND, MAKELONG(GetDlgCtrlID(buttonHwnd), >BN_CLICKED), (LPARAM)buttonHwnd);
>Works like a charm. Things I haven't worked out yet and I'm not sure of >because of inexperience with Windows messaging is what happens if >there's another dialog box is the current focus. You may have to >playing around. A easy solution if the signal is >ignored\blocked\whatever would be to just continiously loop the button >being pressed (with a timer delay). A MsgBox blocks the thread in the IDE, but not when compiled
You could try using PostMessage instead of SendMessage - SendMessage does not return to the Caller until the Message has been processed.
PostMessage shoves the Message on the Window Queue and returns immediately - the destination App responds when it is able to process messages.
Personally I'm a bit nervous about you having another tread running wild in the VB App - I would break that out into another EXE - say an AX EXE - and use the same notification method that Jim suggested
Incidentally it does not need to be an AX EXE - two normal EXEs can communicate just fine using SendMessage/PostMessage the parent kicks of the EXE on startup with a known hWnd in the Command Line - from there one can bootstrap up so that there is two way communication.
Personally I would use a Textbox and WM_SETTEXT for sending/receiving text data
Steve Gerrard - 28 Apr 2006 14:46 GMT > Personally I'm a bit nervous about you having another tread running > wild in the VB App - I would break that out into another EXE - say an > AX EXE - and use the same notification method that Jim suggested I don't think he has one (a wild thread, that is). If the DLL is sending or posting a message, it will be picked up by the VB app when its main thread processes messages, won't it? It seems to me like the right way to do the job.
J French - 29 Apr 2006 08:57 GMT >> Personally I'm a bit nervous about you having another tread running >> wild in the VB App - I would break that out into another EXE - say an >> AX EXE - and use the same notification method that Jim suggested
>I don't think he has one (a wild thread, that is). If the DLL is sending or >posting a message, it will be picked up by the VB app when its main thread >processes messages, won't it? It seems to me like the right way to do the job. The communication between the two threads will be fine, using SendMessage
- what worries me is that the DLL's thread will be allocating and de-allocating memory at the same time as the main thread.
I simply do not know how Windows allocates time slices between threads, it just strikes me as very risky.
Steve Gerrard - 29 Apr 2006 19:24 GMT > The communication between the two threads will be fine, using > SendMessage [quoted text clipped - 4 lines] > I simply do not know how Windows allocates time slices between > threads, it just strikes me as very risky. I think you are right that if the DLL and VB attempt to use the same data in anyway, there will be trouble. There is no synchroniziing between the two, and no blocking (i.e. mutexes) to prevent the DLL from modifying or deallocating memory that the VB part is still expecting to use. Asl long as it is just a signal, I think it's okay, but if its anything more, separate processes would be better.
Scott McPhillips [MVP] - 30 Apr 2006 01:30 GMT > I think you are right that if the DLL and VB attempt to use the same data in > anyway, there will be trouble. There is no synchroniziing between the two, and > no blocking (i.e. mutexes) to prevent the DLL from modifying or deallocating > memory that the VB part is still expecting to use. Asl long as it is just a > signal, I think it's okay, but if its anything more, separate processes would be > better. SendMessage provides interthread synchronization. It can pass the address of some data, then it blocks until the receiving HWND processes the message in its own thread and returns. After the receiving thread returns then SendMessage returns. This provides thread-safe access to the data while the receiver is processing the message.
 Signature Scott McPhillips [VC++ MVP]
J French - 30 Apr 2006 10:28 GMT <snip>
>> I simply do not know how Windows allocates time slices between >> threads, it just strikes me as very risky.
>I think you are right that if the DLL and VB attempt to use the same data in >anyway, there will be trouble. There is no synchroniziing between the two, and >no blocking (i.e. mutexes) to prevent the DLL from modifying or deallocating >memory that the VB part is still expecting to use. Asl long as it is just a >signal, I think it's okay, but if its anything more, separate processes would be >better. Yes it should be Ok for data that is Static and is updated in a single operation, Boolean, Integer, Long
There was a recent discussion on this in a Delphi NG
However complex things like Arrays and Strings take a lot more than one op to create/update - it is those things (and the stack) that make me very nervous
|
|
|