I've created an MFC control class, which I derived from CWnd.
The control is written from scratch and does not use any child controls. This single class implements all the control logic, including state maintenance, painting, responding to events, etc.
In addition, I need a more "public" interface to be used by the code that uses the control. Ideally, it seems like this would be a simpler class with a much simpler interface. However, having two MFC classes associated with the same Window seems to cause all sorts of problems, or is not even possible.
I'm not really sure the best way to approach this. I'm interested in thoughts on how best to provide a simple interface class to a control like this.
Note that the control is not precompiled into a library or anything. It will be compiled as part of the application.
You might try splitting the class in two, with the more complicated implementation class being a child of the public class.
Ordinarily I'd suggest making a separate pure virtual interface class and using multiple inheritance to connect it to MFC, but I'm guessing you'll want to be able to use the standard CWnd methods on the interface.
The MFC interfaces are simple because they don't actually implement the class, they just wrap the public API (C & WM) to make your coding easier in C++.
For instance you could sendMessage hwnd WM_SetText to the edit field, or use CEdit(hwnd).setText() to do the same.
2 Classes is the go I think,
You could make the interface class the parent of the implementation, or perhaps go for a PIMPL model to join the interface with the implementation.
Related
I have the following question regards qml object loaded with qml Loader (setSource("qmlObject.qml")).
In qmlObject.qml I have imported objectClass(.h/.cpp) created with qmlRegisterType, thus when I launch loader.setSource("qmlObject.qml") command an instance of objectClass(.h/.cpp) is created.
I have other main class named coreClass(.h/.cpp) and I should exchange data between objectClass(.h/.cpp) and coreClass(.h/.cpp).
What's the best practice to implement this feature in my simple qt application?
There are two ways to do that:
on C++ level, since both your objects are C++ objects, you can skip using QML as an intermediator and communicate directly. Presumably your core class will be one for the whole application, so you can expose it as a static member pointer to the core in your object class. Therefore all object class instances will have access to it.
on QML level, by exposing the core class to QML as a context property, or preferably as a singleton, because the latter is the most efficient way. Then you can use its properties, signals and slots (but not pure public C++ stuff) in the form of a defined functional interface.
The first approach will be much faster performance wise, and will use less memory, the downside is you will have to recompile the C++ code on every change.
The second approach will limit the interaction to what is visible in QML, which is properties, signals, slots, and functions that have been marked as invokable. It will be slower and use more memory, but on the upside you won't have to recompile, so prototyping is much more rapid.
Often such interactions will be GUI based, so the overhead will not really matter, as the user doesn't interact with the GUI thousands of times per second. If efficiency is key, you can prototype using the second approach and get things running faster, and when you are done simply port the code to the first solution.
It is also important to mention that when you do C++ to QML integration, the correct way would be to have the C++ stuff exposed to QML and use it from QML. You should never ever have to reach from C++ to arbitrary stuff in QML, this is an indication of wrong design.
You can easily exchange data between c++ classes with SIGNAL and SLOT mechanism.
just pass pointer of coreClass to objectClass and connect signal and slots.
I need to extend an old C++ project which uses COM and MFC. I worked with C++/COM before but it was years ago. I see that all COM interfaces implementations in the project inherit CCmdTarget. Even the ones which are not used for UI tasks but just transfer data to methods. Surely CCmdTarget does implement all necessary stuff for COM but it looks like it contains a lot more which is not needed: like wait cursor support and message processing. This is not needed for simple interfaces. Isn't there a more lightweight way to implement them? Or is it a common practice to use CCmdTarget as a base object for all MFC COM implementations?
Sorry if this question seems obvious for everyone, but I am very new to COM. From the tutorial I see here http://www.codeguru.com/cpp/com-tech/activex/tutorials/article.php/c5567, it seems like every COM class created in C++ must implement its own QueryInterface, AddRef and Release. Since these methods should have basically the same implementation for any new class, I don't understand why there isn't some abstract class or whatever that implements it for the developer. I don't understand why I should re-implement the same thing that so many people have already implemented again and again (unless the tutorial is wrong and there IS something).
Thanks
FTA:
"I believe that every programmer who wishes to understand the basic principles behind COM, must write atleast one simple COM object using plain C++ , i.e. without the aid of templates and macros that comes along with MFC/ATL."
To answer your question: Yes, every COM component must implement IUnknown, it's the foundation COM is built on. However, as for the "standard pluming" for creating COM objects this is what the ATL Project Wizard is for.
If you don't want to use ATL or other helper libraries you can use the QISearch helper function that handles QueryInterface for you. AddRef and Release can be implemented in your own base class.
COM needs to work with plain C also so the windows sdk does not really go beyond the definition of the class and its methods.
Yes, every COM class must implement IUnknown, because every COM class inherits from IUnknown - that's one of the basic COM technology principles. This is usually done by using ATL - it has templates and macros for doing that rather easily and even if you don't want to use ATL you can write a template for most trivial cases (like implementing one interface) pretty easily and reuse that.
Tomorrow I have planed to do some IDispatch related work, and I will have to create a class that supports this interface.
I have been using ATL classes for a while to create COM objects and manage COM pointers, so I would like to use them for my class as well. But research so far, and discussions with colleagues have led me to believe that I need all the heavyweight IDL stuff even if I want to create a simple class with one property or method.
If that's the case I'll probably resort to writing everything from scratch, but I still hope I'm missing something. Is there a template I've missed?
ATL has an IDispatchImpl class.
I've seen with Microsoft COM and XPCOM, at least from what I've read and gathered so far, that the implementations of interfaces in a component have to essentially be in the single class that derives all the virtual interfaces. Is this correct? What am I missing?
Is there a way to have multiple objects (possibly in separate DLL's) each provide their functionality and still be able to freely transition between them using QueryIterface?
What I'm looking for is to have a component with some functionality, but still allow external client code to create new extensions of the component with (possibly) new interfaces. Ideally this should happen without divulging the current source of the component and its implementation.
This should be possible, although probably not supported by the standard high-level wrappers. Most of the wrappers (ATL, MFC, etc.) only support mapping a COM object to a single class. However, QueryInterface is allowed to return a different pointer and calls COM object code, so the first COM object could load a different DLL, instantiate a different object, and return a pointer to it's interface (vtable).
It's all possible as far as I know, you'll just likely be writing a lot of the low-level glue code yourself.
Yes, ATL supports tear-off interfaces
This allows to imlement the interface in another class that is instantiated only when the interface is requested. Since it passes only an interface, I guess it can be put into a separate DLL, too.
(can also be cached after being requested once)