I have a legacy Win32 application (WndProcs, etc) that needs to consume a COM object. With the use of a little ATL headers and some smart pointers that was a snap, however what I'm currently struggling with is how best to sink the events coming off that COM object?
My current working plan has been to build a second COM object (as a dll) that handles all the sinking and uses windows messages to communicate with the legacy application. This is "ok" but there's a lot of cruft moving messages back and forth to make the legacy application do what I want.
Is there a readily accessible way to get the Win32 legacy application to sink COM events directly vs running through the second "sinker" com object?
Before I go to far down this process I wanted to see if anyone else ran across this before and had a working solution.
Thanks!
Stumbled across this excellent write up by the always brilliant Raymond Chen.
http://blogs.msdn.com/b/oldnewthing/archive/2013/06/12/10425215.aspx
As WhozCraig indicated above, all I needed was the Interface pointer and to setup the Advise, handle the Invoke.
Nice and clean.
Thanks!
Related
We have a MFC application setup where a client receives data from server whenever new data is available. Client is being rewritten in C# but communication with server part is in MFC. We have written a C++/CLI wrapper to classes associated with MFC and are able to receive data on application initialization. Communication engine is still in MFC and we have created wrapper classes only for data items. When we initialize the CLI wrapper we copy the data from MFC arrays to CLI arrays. But am not sure how to get the data which is received lets say after 5 seconds. How can it notify C++/CLI wrapper that new data has been received by MFC code running in the background. Please let me know if you need clarifications. Thanks.
or
Is there a way to invoke a C++/CLI method from C++ code ?
NOTE:
its a mixed mode compilation which has vc++ and C++/CLI code.
Edit ::
As mentioned by Hans below added request for callback solutions.
Resolved this issue by converting, CPP events to CLI delegates, which are recognized by .NET as .NET delegates.
this way we can control actions at C# end from CPP. If anybody has a better solution please share.
I am new to .Net and hitting the brick wall trying to resolve this....
Having done enough googling for the past few days I've come across nothing but some vague (at lease for me) C# related info
Basically, I am trying to set up a few global hooks to carry out certain automation process. Since the development environment is VS2008 C++ windows forms, I started by compiling a native Dll to be injected by the calling prog. The strategy being for the callback proc in native dll calling a function in .Net program (or maybe a wrapper managed dll), passing the filtered raw data (keyboard/mouse/WM_create/etc) messages for further processing.
Question: How do I pass on the handle of such function(s) to my injected dll?
Is the managed wrapper dll path an easier choice or simply have the managed & native functions residing side by side in the main application?
I'll have to do a lot of Marshalling which is yet another dark side of the matter. Is there a link to precise documentation/examples of marshalling functions?
I thank you for your help in advance.
Mark
Have a look at 'Marshal.GetFunctionPointerForDelegate'
I have a plugin for a c++ MFC app. I'm working with the developer of another plugin for the same app, that's trying to get notifications of events in my code. Both plugins are in the form of c++ dlls.
How can I pass messages from my plugin to his plugin? The solution needs to be robust to mismatched versions of our two plugins, as well as the host app. The notifications are during control point movement, so several times a second.
I could set up a callback mechanism, where upon load his plugin calls a function in my plugin with a function pointer. We're not guaranteed any loading order, but we could probably just check periodically.
I know Win32 has a messaging system, but I'm not sure how it works, really. We could add a hook, and I could send messages, but I'm a bit fuzzy on how we'd synchronize what the message id is, or any details other than what I said, really.
Any other ideas on how to do this?
I'm a bit fuzzy on how we'd synchronize what the message id
Use the RegisterWindowMessage API.
Take a look at this article here, it shows the available IPC mechanisms in windows. I might try COM, Mailslots, Pipes or Shared Memory (file mapping) in your case, in addition to windows messages which you already mentioned.
I have a VB6 application that I don't have source code. This application uses third-party ActiveX controls. I want to automate these ActiveX controls. Is it possible to get the IUnknowns or Object references? For some of these, I can get the underlying HWNDs, but from what I can tell there isn't a generic way to convert these HWNDs to the ActiveX control.
Some testing software allows you to script VB6 applications with ActiveX controls. How do they do it?
Are these ActiveX controls in a separate DLL? If so, you can use OLE View (an VS 6.0 tool) to open the dll and view all the interfaces, coclasse and etc.
You might be able to using DLL injection via Microsoft Research Detours library. Basically you'd want to hook the cocreate for those specific controls. You will need to be ultra careful especially if you do anything cross-thread/cross-process (COM threading rules are vitally important).
On whole Detours is easy to use... but I've never tried it with COM routines. You might want to look at a different solution.
Also note that Detours has some licensing restrictions on it that may affect your ability to distribute it.
Testing software may well just send the appropriate WM_XXX messages to the particular windows in question (eg. WM_MOUSEMOVE).
Sorry to say but the VB6 EXE don't contain the manifests needed to pull out the COM objects it uses. You best bet is trying some of rbobby's suggestions especially about sending WM_XXX messages.
I wrote a device controller (rs232) and it is being used successfully, however users want to view data and control the device (or perhaps communicate through my program) from Excel. I dismissed DDE as an option and found that RTD (IRtdServer) is probably a good start (though no way to send data back to the "server" from the real time data client).
I found these resources for the RTD part:
http://support.microsoft.com/?id=327215
and
http://support.microsoft.com/?id=327215
This is a multi-threaded app and I had already added the ability to have multiple listeners on the com port so that I could update multiple clients. I will add the COM interface to the EXE.
But what I need after that is some way of controlling my app/proxying commands to the device through my app from Excel.
What would be the best way to do that?
Perhaps another COM interface and calling it from VBA or something? I am not familiar with using scripting from Excel, so perhaps someone can provice sample code or links that show both the code for a COM object and the accompanying VB(A?) code?
Keep in mind that this is an unmanaged C++ application and it cannot be converted to managed or C# right now. Alternatives using C# are welcome as well, but that is a long-term rewrite.
Thanks
EDIT
I have an alternative to adding COM support into the existing EXE. I think it is more flexible to add a two-way communications (cross platform - maybe boost or corba or just straight IP based with my own message protocol)
A COM server (or two) can wrap that communications channel - whatever it is. This doesn;t really affect my question at all - I still would like to know the options for controlling an external EXE from Excel.
EDIT
Not having to roll out .NET to customers is also an big plus. many of these devices are on PCs that are pretty old and have perhaps NT or XP on them and I don't relish increasing my setup/install package from 700KB to the ridiculous .NET install size...
Option #1:
Create a small COM server - make sure its interfaces are suitable for scripting with the built Visual Basic engine in Excel. (e.g. use simple types and BSTRS).
Write Excel VB Macros to (1) add your own tool bar to excel and (2) call your COM server.
You can also add buttons and other UI elements to sheets and hook them them up to VB macros.
Option #2:
I realize that you do not want to use C# - but automating office, and talking to COM objects is really, really easy in C# with Visual Studio Tools for Office (VSTO). You shoul really look into this option - If done correctly, it shouldn't mean re-writing any of your existing code. Just use C# and VSTO as a bridge between Excel and your RTD server. As with VB, its straight froward to connect UI elements in Excel to C# and then to your RTD server.
Calling a COM object from VBA is straightforward. This SO Question and my answer give an example of how to create a COM object. Calling exposed methods is as you would expect:
object.ExposedMethod(optional params...);