Implement IConnectionPointContainer on an object extending from COleDocument (instead of COleControl) - com

Has anybody had any experience with COM / MFC trying to implement IConnectionPointContainer on an object extending from COleDocument (instead of COleControl) ? Can somebody please provide any tips, or a pointer to a guide on how to do this ? I need to implement notifications for objects that listen to changes to the document, which are made as part of implementations of another interface which is implemented by the Document.

MFC connection macros are not specific to COleControl but CCmdTarget. You can use DECLARE_CONNECTION_MAP/BEGIN_CONNECTION_MAP etc as long as your class is derived from CCmdTarget, and in this case, COleDocument is.
Suggested reading:
TN038: MFC/OLE IUnknown Implementation
Connpts.exe sample demonstrates how to implement connection points and connection point sinks in Visual C++

Related

Two simple COM IDL syntax questions: is there a way to specify the threading model, and do I need void to say "no arguments"?

Two simple COM IDL file questions I can't seem to find answers for, even with searching MSDN and the general internet:
Is there an interface attribute which lets me specify my interface is to be implemented by STA objects only, or is this a detail for my documentation alone? I already have [object, local] which I think is correct for non-remoting (in-process) COM objects.
Do I need void in the parentheses of my method declarations (like in C) to specify no arguments? MSDN is inconsistent about this; so are header files. My own personal implementations of this interface will be in C.
Thanks.
You are talking about the threading model you want to specify for your COM component. No, you cannot put that in the IDL, it is far too important. A client doesn't have to use your IDL, a scripting language like Javascript never will for example. It must go in the registry, in the CLSID key for your component. You want ThreadingModel = "Apartment" to request the client to provide an STA thread. If it is missing then COM assumes that by default.
Do keep in mind that this does not force the client programmer to provide one. If he favors MTA for some reason then COM will provide the STA thread to give your component as safe home. If your proxy makes it too slow to be usable then you do have a documentation requirement.
No HRESULT Method(void) in the IDL is not necessary, using HRESULT Method() is sufficient. Midl.exe doesn't care what language you use.

How to find COM interface definition for given interface GUID?

I have a COM interface GUID but I don't know that interface definition. I don't know what methods it has, what parameters they have and so on. How can I obtain such information? Is it possible in general?
Practical problem is obtaining interface definition for few COM interfaces defined in actxprxy.dll. For example IFileDialogPrivate ({AC92FFC5-F0E9-455A-906B-4A83E74A803B}). (Obviously the interface is not documented and the name does suggest there is a reason for that.) I tried to use OLE/COM Object Viewer (OleView.exe) for that but wasn't able to get the interface definition.
I am trying to implement IFileDialogPrivate while doing some experiments on forcing IExplorerBrowser control to filter Windows 7 library folders. IFileDialog (which seems to use IExplorerBrowser) does it somehow and IExplorerBrowser askes service provider for IFileDialog and IFileDialogPrivate if ICommDlgBrowser is provided so I tryied to explore that interface. (Also it asks for few other interestingly named interface - could be useful).

How to add and implement a new interface to an Inproc COM server

I've implemented a windows deskband (using the windows SDK sample) and need a way to communicate (one call to start IPC with another application, IPC is already working) with it.
My COM experience is very limited but extrapolating from what I've seen, I think it should be possible to create a new COM interface, implement it in the deskband object (which I have access to via IBandSite), call QueryInterface() for my own interface on it and then use it to call directly into the deskband.
I've tried this but ran into problems very quickly (main reason being: I've no idea what I'm actually doing most of the time ...)
So, my questions are: Is this a viable approach and can someone give me an outline on how to proceed if it is (or point to some resource that could be helpful - short of reading a COM book, which would be my last approach). If it is not, do alternatives come to mind ?
Thank you for your time and best wishes,
Rene.
Here's you path: you add a new interface into .idl file and also if you have a co-class in the .idl file that corresponds to you COM object you list that new interface in the co-class definition. Then you compile the .idl and this gets you a .h file and a .c file with identifiers - the C++ IID and C++ interface definition.
Then you inherit your COM object C++ class from the C++ interface and implement all methods of it. If for whatever reason you can't or don't want to implement a method you have to return E_NOTIMPL from that method implementation.
One very important final thing: you have to change QueryInterface() behavior in you COM object class. If you use ATL you have to add an entry into the COM map. If you don't use ATL change you QueryInterface() - see this question for how to implement QueryInterface() in case of implementing several COM interfaces.

How to push data from unmanaged to managed code?

I am using a C++/CLI Wrapper to access a purely C++ library (-> unmanaged) from a C# framework (-> managed). I want to build in a mechanism which enables the C++ library to push information about its status towards the framework. In my understanding this means that I will have to call at least a managed function from unmanaged code at some point. Is this possible and how can I achieve this?
Many thanks for your help!
Best regards,
Jakob
Use a delegate to let unmanaged code call a managed method. Marshal::GetFunctionPointerForDelegate() creates a stub that takes care of the transition, calling an instance method is supported. You can cast the returned pointer to a function pointer usable by the unmanaged code.
You'll find a full code sample in this answer.
I would recommend using a (managed) event for this. You could have your C++ wrapper call a method on your C++/CLI generated class which raises the event.
The event can easily be subscribed to from the C# side, and used like any other C# based event.

How do you extend a C# interface in C++/CLR?

I'm really frustrated with this one. I'm trying to extend a C# created interface in C++/CLR. The interface has one method and I've declared it in my class, but the compiler keeps telling me that I must still provide an implementation for the interface method. What more can I do? What am I missing!?
Does anyone have any examples of how to extend a C# interface in CLR?
I figured it out! I needed to make the implementation of elements virtual. I hope this helps other people with this same issue.