MS Word has a very useful mechanism to wrap up its dialog boxes to use via COM or .Net. You can execute a "Display" method - which does the obvious - and also an "Execute" method which is equivalent to pressing "OK". I have a legacy MFC app which I am attempting to attach a COM object model to for scripting and regression testing, and I would like to do the same thing. It has a number of dialogs that I want to control programmatically from my test harness. It's been years since I really delved into MFC, and I can't find anything useful on t'internet so far.
My guess would be to wrap up the CDialog derived classes, perhaps within an ATL class (ATL is used extensively in the project), but I have a suspicion that there may be a better way.
Worst case scenario, I'll move the dialogs to C# and make them COMVisible (which is probably more strategic), but that's going to be more work.
Any thoughts and help appreciated - obviously this is rather antiquated technology!
All CDialog derived classes in MFC are a subclass of CCmdTarget.
CCmdTarget is the baseclass for MFC COM functionality.
There is a lot of work you have to do under the hood. You should define and IDL file for your interfaces, compile the IDL, and then have the compiled typelibrary be a resource in your program.
There are helper macros for your CCmdTarget derived classes like:
DECLARE_INTERFACE_MAP()
BEGIN_INTERFACE_PART()
END_INTERFACE_PART()
BEGIN_INTERFACE_MAP()
INTERFACE_PART()
END_INTERFACE_MAP()
I would say that if you want to see how MFC does it, use the App Wizard and generate an MFC application that has OLE Automation enabled and then look at the generated code. It will show you what you need to wire up your MFC app for OLE Automation.
I'm programming Windows COM in C++ and I see that a lot of functions get prefixed with :: so that the global namespace version got called. Why is that?
I understand that there may be conflicts with namespaces, but does it happen so often in COM that everyone has become so paranoid that every single function now has to be resolved explicitly?
Here are some examples that I see often:
wStrLen = ::SysAllocStringLen(NULL, wStr);
::SysFreeString(str);
::CoTaskMemFree(item);
And many others.
It just puzzles me why the programmers chose to resolve namespace explicitly and why they didn't just write:
wStrLen = SysAllocStringLen(NULL, wStr);
SysFreeString(str);
CoTaskMemFree(item);
Any ideas?
No, that's not common in COM programming, not in any I wrote or studied anyway. COM itself adds few names to the global namespace, there are not that many helper functions. A common way to implement a COM interface is to use a C++ class, you can stick it in any namespace you like since it doesn't get exposed at all outside of the module. I suspect that it is just something the team whose code you saw preferred. If you saw it in a book then that's a good way to increase the odds that the book code sample can drop into an existing program without too much trouble. There's otherwise nothing wrong with it.
I've got a VSTO3 Word addin that makes use of custom ribbons and taskbars, etc.
Now, Office 2010 comes along and there's this nifty new BACKSTAGE concept, which I'd like to hook into. However, from what I can tell, doing it with VSTO requires Vsto 4, which requires VS2010, which isn't an option.
Soooo. I started looking online and have found all sorts of examples of, essentially, piggybacking the backstage XML onto whatever Ribbon xml I define and returning that as the value of GetCustomUI. All good, except if you're using VSTO3, there doesn't appear to be any way to "hook" into the call chain for GetCustomUI. It's all "automagically" handled for you by the OfficeRibbon and RibbonManage classes.
I know I +COULD+ convert the addin to a shared addin and just implement the IDTExtensibility interfaces directly. I'd lose all the vsto goodness (yeah, that's debatable) but I'd gain access to the GetCustomUI call.
Anyone every tried to get access to GetCustomUI +WHILE+ using VSTO though? Is it even possible?
I thought I could create a wrapper class for RibbonManager, but lo, MS has gone and done what looks to be some supreme violation of encapsulation. The RibbonManager implements the nice and easy IRibbonExtensibility interface, and yet, where that interface is passed around, they actually check the passed object to be sure it's of the actual type RibbonManager! Ugh, so much for any kind of wrapper.
Turns out it's possible, just not easy. You have to override the CreateRibbonExtensibilityObject method on connect, as well as the CreateRibbonObjects, and the RequestService methods.
Then, you have to create an object that wraps the built in VSTO RibbonManager object, and implements iReflect to intercept reflection INVOKE calls and forward them on to the underlying RibbonManager.
Finally, on the interceptor object, you have to also implement IRibbonExtensibility, then code up the GetCustomUI method of that interface.
once you do all that, your GetCustomUI will be called and passed in the full XML of the ribbons you've defined via VSTO, which you can then alter directly (in my case I needed to add backstage support), and then return that xml from the function.
definitely not straightforward, but it works.
If you want to edit XML ribbon at runtime in a VSTO app, I have created a simple solution here: Outlook 2007 ribbon customization in .NET using VS2010; insertBeforeMso dynamic function
I am currently designing the migration of my existing .NET / C# / WinForms project to a platform neutral solution and the most attractive alternative I have seen seems to be wxWidgets especially taking in consideration my familiarity with C++ and with MFC that appears to have a lot in common with it.
After going though the documentation and the sample code I need to clarify the following issue:
Is it a valid assumption that the way to develop a User Control (by C# terminology) in a wx environment is to derive a class from wxPanel , customize it and place it in a wxFrame?
If this is the case what is the wxFrame method to be used to add the wxPanel object to it ?
The only relative method I was able to find was wxWindow::AddChild but the documentation states that is mostly internal to wxWidgets and shouldn't be called by the user code.
To avoid confusion please note that my question is about a User Control and not a Custom Control (which is clearly addressed in the documentation)
I think you have to set the parent window in the constructor of your wxPanel-derived class and pass it to the inherited constructor (cf. wxPanel constructor)
A better solution, though, is to use sizers (see wx Sizers) for layouting.
And yes, imo you're right about wxPanelbeing (roughly) the equivalent of a C# UserControl.
I searched hard, but was unable to grasp the whole idea. Can anyone tell me:
What COM actually is?
How do GUIDs work, and how are they used by COM?
How does COM resolve the issues of different DLL versions.
Or at least, point me to a good article somewhere that explains these concepts?
Thanks!
COM is "Component Object Model". It is one of the first technologies designed to allow "binary reuse" of components... Originally, it was the rewrite of what was, in Microsoft Office circa 1988-1992 time frame, referred to as Dynamic Data Exchange (DDE), a technology designed to allow the various Office applications to talk to one another. The first attempt to rewrite it was called OLE-Automation (Object Linking and Embedding). But when they got done they renamed it to COM.
How it works:
Essentially, before COM, when a client component wanted to use a component (written as a C++ library), it had to be compiled WITH the library, so it could know exactly how many bytes into the compiled binary file to find each method or function call.
With COM, there is a defined mechanism as to how these methods will be structured, and then the compiler produces a separate file (called a type library or an Interface Definition Language (IDL) file, that contains all this function offset data.
Then, as a user of the component, you have to "register" it, which writes all this information (Keyed off of GUIDs) into the OS Registry, where any client app can access it, and by reading the data from the registry, it can know where in the binary file to find each method or class entry point.
Your question is a little large for a full explanation here. A quick high-level introduction to COM can be found in the book Understanding ActiveX and OLE. A more detailed but still introductory introduction is Inside COM. The best book on the subject is Don Box's Essential COM.
A couple of quick answers:
COM is a binary interface standard for objects. It allows various programs to write to interfaces without all having to have been written in the same langauge with the same compiler. There are also related services available.
GUIDs are globally unique numbers that COM uses to identify interfaces.
COM doesn't resolve different DLL version problems. It only allows a single DLL to be registered for each GUID.
COM enables reusable software. Like building blocks, you can create COM objects (or now Assemblies in .NET) to provide functionality to a larger piece of software. I have used COM to provide DB integration for Excel and MS BizTalk. Software like MS BizTalk use COM/Assemblies to extend the processing capabilities of a standard process; you can insert a COM into the message workflow to do more processing than is implemented by Microsoft. COM also allows use of Component Services providing built in object pooling, security, and control interface.
Wikipedia has a good definition of GUID. Note that Microsoft has a formatting that is not necessarly used in the rest of development community.
COM by itself does not resolve DLL version issues. It enables you to extend software incrementally if you use the COM versioning capability. So if you have an application that uses a COM to convert XML to Text (for example) and you want to enhance, you can create a new version (2.0) which you can roll-out slowly as you update the source application to use the new COM. This way you could (if need be) have a switch statement that can still use the old COM if required by system limitations, or use the new one (they would be different DLLs).
COM is a lot of different things. I recommend Don Box's book, Essential COM as a good way to learn.
At a bare minimum, a COM object is an object that exposes a single interface, IUnknown. This interface has 3 methods, AddRef, Release, and QueryInterface. AddRef/Release enables the object to be reference counted, and automatically deleted when the last reference is released. QueryInterface allows you to interrogate the object for other interfaces it supports.
Most COM objects are discoverable. They are registered in the registry under HKEY_CLASSES_ROOT with an identifying GUID, called a CLSID (class ID). This enables you to call CoCreateInstance to create an instance of a registered object if you know a GUID. You can also query the registry via a COM API for the CLSID that backs a ProgId (program id), which is a string that identifies the object.
Many COM objects have typelibs that specify the interfaces and methods the object supports, as well as IDispatch which has a method, Invoke, that allows you to dynamically call methods on the object. This enables the object to be used from scripting languages that don't support strong typing.
Some objects support being run in a different process, on a different thread, or on a different machine. COM supports marshalling for these types of objects. If possible, a standard marshaller can use the object's typelib to marshal calls to the object, but custom marshallers can be provided as well.
And there's a whole lot more to COM objects, I'm barely scratching the surface.
10,000 foot view:
COM is the communication mechanism for software components. Example, you can interact with COM interfaces (COM interop in .NET) to use functionality not exposed through a common interface (.NET assembly).
GUIDs are explained fairly decent on Wikipedia http://en.wikipedia.org/wiki/Globally_Unique_Identifier
I always understood LIB files to be object files for the C++ linker. They contain the code for all objects in a cpp file. The compiler optimizes when it links disregarding portions of the object file that it doesn't need.
Someone please clarify as I am sure I butchered some of this.
COM is Microsoft's Component Object Model, a binary-compatible interface for programs written in various languages to interoperate with each other. It is the "evolutionary step" between the OLE and .NET technologies.
If you want to learn about COM from the C++ perspective, take a look at Don Box's Essential COM, or ATL Internals by Rector and Sells.
The group microsoft.public.vc.atl is probably the best place to ask questions you can't get answers for here. It's primarily an ATL newsgroup, but it seems to be the newsgroup with the most traffic for general COM questions as well. (just be prepared for the usual newsgroup curtness & impatience)
COM is a method to develop software components, small binary exe, that provides services for applications, OS and other components. Developing custom COM comnponent is like developing Object oriented API. GUID is a Global unique ID and used to identify a COM component uniquely.
You can refer a very good book by Dale Rogerson for more details. Inside COM