Here's the thing - we have a C++ MFC Project including a ribbon. We managed to hide the Main Button. Now we want to do the same with the QAT because it won't be used - we have our own QAT category. Is this possible and how?
Solved it! I derived CMFCRibbonBar. I added a method delQAT() in which i call m_QAToolbar.RemoveAll(). In CMyAppMainFrame::OnCreate() I call this new method.
class CRibbonBar : public CMFCRibbonBar
{
public:
void delQAT()
{
m_QAToolbar.RemoveAll(); //m_QAToolbar is a protected member of CMFCRibbon
}
}
class CMyAppMainFrame(...)
{
//...
protected:
CRibbon m_wndRibbonBar;
//...
public:
void OnCreate()
{
//...
m_wndRibbonBar.delQAT();
//...
}
}
Hope it'll help other people with the same problem :)
Related
Lately, I've been pondering about the following problem for a while. For the code bellow, what is the easiest way to modify Game::counter via Event::Perform() method which is called from Game class?
I considered Observer and Command design patterns, but it seems that there is a much simpler way to do this.
class Game
{
public:
Game();
private:
int counter;
vector<Event*> Events;
};
class Event
{
public:
virtual void Perform() = 0;
};
Thank you
Directly from Perform, none. counter is private, so it can only be accessed by Game, as part of one of the functions of the interface it provides.
Calling this function is then just a matter of having access to the right Game instance. You can pass that one as a parameter to Perform:
virtual void Perform(Game &) = 0;
... or inject it into derived Events:
struct MyEvent : Event {
MyEvent(Game &game) : _game{&game} { }
void Perform() const override {
// Do something with *game
}
private:
Game *_game;
};
Since I guess we are talking about the Events referenced by Game::Events, which Game itself will process, the parameter looks like the most cohesive approach.
I'm sorry, this is probably a stupid question. I am obviously misunderstanding something fundamental about object oriented programming. I am used to C and am now trying to use C++.
I have some buttons in a class called Button. Each button does something different. What I want to write is something like this:
Button button1;
Button button2;
...
void button1::onClick () {
...
}
void button2::onClick () {
...
}
But that does not work ("button 1 is not a class, namespace or enumeration" - yes I know!). I know I could just make a separate class for each button:
class button1_class : public Button {
public:
void onclick () {
...
}
} button1;
class button2_class : public Button {
...
}
But to me it 'feels' wrong to make a class when I know for sure it will only have one member.
I'm using Agui, a GUI library for Allegro 5.
EDIT
Thanks for the responses. While they are all helpful and (I think) all valid answers, nobody has actually said yet "no you cannot have an object with its own unique method because..."
So for example, if object1 is of type ObjectClass then object1 is not allowed to have a method (a member function) that is unique to object1, but rather possesses only the methods that are defined as part of ObjectClass. Is that right?
I'm sorry I did not include my actual use case. I was kind of more interested in just getting my head around OOP so that I can do it properly on my own.
EDIT2
Looking at the responses in more detail I suppose it is possible with lambda expressions, it's just not in the way I imagined it. Thanks again
The natural C++ way is to do as vsoftco explained, with virtuals and inheritance.
However, if your Button class has already everything needed, and the only thing that changes between the buttons is the unique (trhow-away) action to be performed, you may want to consider this alternative:
class Button {
function<void()> f;
public:
Button(function<void()> mf) : f(mf) {}
void onClick() { f(); }
};
This variant of your class uses a function object (think of it as a kind of function pointer but much more flexible to use).
You can then use it with lambda-functions as in this example:
int main(int ac, char**av)
{
Button button1([&]() { cout << "Hello 1!\n"; });
Button button2 ([]() { cout << "Hello 2!\n"; });
button1.onClick();
button2.onClick();
}
If the buttons have different functionalities, best thing to do is to create a BaseButton class in which you mark the onclick() as virtual (or make it pure virtual, which will make BaseButton an abstract class), then derive each other button from BaseButton, making sure to override onclick() in each derived class. You then need to use the buttons via a reference or pointer to a BaseButton, this way you achieve what is called "polymorphic behaviour".
For example:
class BaseButton
{
virtual void onclick() {/*implement here or declare pure virtual*/}
};
class RedButton: public BaseButton /* overrides only onclick */
{
void onclick() override { /*specific implementation for Red Buttons */}
};
class ShinyRedButton: public RedButton /* overrides only onclick */
{
void onclick() override { /*specific implementation for Shiny Red Buttons */}
};
then use it like (C++14 smart pointers)
std::unique_ptr<BaseButton> bb = new ShinyRedButton;
bb->onclick(); // will pick up the "right" ShinyRedButton::onclick()` function
You can do this in many ways.
Using a Button class where button objects have a pointer to methods that are invoked onClick. In C you would do this using a callback and you can also do it that way in C++:
class Button {
using funType = void(void);
public:
Button(funType* callback) : function(callback) { }
void onClick() { function(); }
private:
funType* function;
};
However do take note that function pointers are error prone, can't really be inlined by the compiler, and should generally be avoided. This method also works with capture-less lambdas.
Button red([] { std::cout << "Red button\n"; });
Button green(&green_button_function);
Creating different Button objects with different onClick methods on the fly. C++ has a mechanism to do this called templates:
template <class Fun>
class Button {
public:
Button(Fun f) : functor(f) { }
void onClick() { functor(); }
private:
Fun functor;
};
template <class Fun>
Button<Fun> make_button(Fun f) { return Button<Fun>(f); }
I am omitting details such as references on purpose here.
You could then use the Button class with callbacks as well as lambdas in the following way:
auto green = make_button([] { std::cout << "Green button pressed!\n"; });
auto red = make_button(&red_button_function);
You need to use auto with this method because otherwise you would have to specify the type of the functionality by hand, which is not possible e.g. for lambda objects.
Using polymorphism as shown by vsoftco, where you create separate classes for each Button functionality. Or you can make a ButtonAction abstract class to which Button has a reference. Then you implement different functionalities in different classes, but stay with one Button class. This is known as the strategy pattern:
class ButtonAction {
public:
virtual void onClick() = 0;
};
class Button {
public:
Button(std::unique_ptr<ButtonAction> action) :
action_(std::move(action)) {}
void onClick() { action_->onClick(); }
private:
std::unique_ptr<ButtonAction> action_;
};
class RedButtonAction : public ButtonAction {
void onClick() override { red(); }
};
class GreenButtonAction : public ButtonAction {
void onClick() override { green(); }
};
Using this method requires constructing Buttons from ButtonAction unique_ptrs
Button red(std::unique_ptr<ButtonAction>(new RedButtonAction));
Button green(std::unique_ptr<ButtonAction>(new GreenButtonAction));
You're right in that, if each button is fundamentally the same but needs different event handlers bound to it, implementing a new type for each one is not quite right.
Instead your Button type would have a member function that allows users to "attach" an event handler, and a member function to invoke it.
class Button
{
public:
Button()
: onClickHandler()
{}
void setOnClickHandler(std::function<void()> callback)
{
onClickHandler = callback;
}
friend class UI;
private:
void onClick()
{
onClickHandler();
}
std::function<void()> onClickHandler;
};
Then your user does:
void foo()
{
std::cout << "Some buttons do this!\n";
}
Button btn;
btn.setOnClickHandler(foo);
And your program's internals will set up things such that your window manager (above I've assumed that it's some class called UI) invokes btn.onClick() for you, which, since you "attached" foo, will end up invoking foo.
(In modern C++ you'd probably make use of lambda functions to tidy this up, but the above is a simple example to showcase the general design idea.)
In this way, you can attach different handlers to different Button instances, but the Button interface itself is stable.
This is similar to how, for example, you manipulate the DOM in JavaScript.
Using a std::function is the key here. You will have the virtual call overheard and potential memory allocation if your callable (lambda, function, member function) is large. This achieves your requirements of a single type executing different callbacks without defining an class inheritance. Also using uniform initialization makes it very convenient to construct Button class with a lambda without manually creating a constructor.
Live example:
http://coliru.stacked-crooked.com/a/f9007c3f103f3ffe
#include <functional>
#include <vector>
using namespace std;
struct Button
{
function<void()> OnClick;
};
int main()
{
vector<Button> buttons =
{
{[] { printf("Button0::OnClick()\n"); }},
{[] { printf("Button1::OnClick()\n"); }},
{[] { printf("Button2::OnClick()\n"); }},
};
for(auto&& button : buttons)
button.OnClick();
}
Your Agui library supports a signaling system, with the member function addActionListener.
This allows you to derive a class from agui::ActionListener to perform the specific task intended for one or more buttons:
class SimpleActionListener : public agui::ActionListener
{
public:
virtual void actionPerformed(const agui::ActionEvent &evt)
{
std::cout << "Button pushed" << std::endl;
}
};
The object above can be attached to a button's "press" action with:
SimpleActionListener simpleAL;
button1.addActionListener(&simpleAL);
The application defines 3 interfaces to be implemented in a plug-in. Widget is always the base.
// Application code...
class Widget {
virtual void animate() = 0;
};
class BigWidget : public Widget {
};
class SmallWidget : public Widget {
};
Every interface implementation is derived from NiceWidget which provides some plug-in internal common information.
// Plug-in code...
class NiceWidget {
// nice::Thing is only known in plug-in code.
nice::Thing thing();
};
class NiceBigWidget : public NiceWidget, public BigWidget {
void animate() override;
};
class NiceSmallWidget : public NiceWidget, public SmallWidget {
void animate() override;
};
func is called from application code. wid is known to be implemented by this plugin. Thus wid is also a NiceWidget. The goal of func is to call the thing method of it.
// Plugin-in code...
void func(Widget* wid) {
// wid is either NiceBigWidget or NiceSmallWidget.
auto castedBig = dynamic_cast<NiceBigWidget*>(wid);
if (castedBig) {
castedBig->thing().foo();
return;
}
auto castedSmall = dynamic_cast<NiceSmallWidget*>(wid);
if (castedSmall) {
castedSmall->thing().foo();
return;
}
assert(false);
}
But trying to cast wid to every Nice* can become very awful with increasing hierarchy size. Are there better solutions out there?
First: if you know that wid will always be a NiceWidget*, why not say so in func()? And you would not need a cast at all:
void func(NiceWidget* wid)
{
wid->thing().foo(); // Done
}
Even if you can't change the function signature for whatever reason, you would only need one cast:
void func(Widget* wid)
{
NiceWidget* casted = dynamic_cast<NiceWidget*>(wid);
if (casted)
casted->thing().foo();
else
throw std::exception(); // Well, throw the right exception
}
You can assert() instead of throwing an exception, of course, if you think it is better for your purposes.
In any case, you just need a pointer to the class that defines the functions you need to use (in this case, thing()), not to the most derived classes. If you will override the function in derived classes, make it virtual and you are done anyway.
If you know, that every NiceWidget is Widget, you should consider extending NiceWidget from Widget.
class Widget {
virtual void animate() = 0;
};
class BigWidget : public Widget {
};
class SmallWidget : public Widget {
};
class NiceWidget : Widget{
// nice::Thing is only known in plug-in code.
nice::Thing thing();
};
class NiceBigWidget : public NiceWidget, public BigWidget {
void animate() override;
};
class NiceSmallWidget : public NiceWidget, public SmallWidget {
void animate() override;
};
There will be another problem called The diamond problem, and it may be solved using virtual extending
After that it's should be OK to dynamic_cast from Widget to NiceWidget
I'm trying to access a dialog item from a function that is not in the same class as the dialog class. How can I do that?
Example:
class AnotherClass : CClas
{
AnotherClass();
public:
void MyFunction();
};
void AnotherClass::MyFunction() //Message overwriting, can't change parameters
{
CClass* temp = (CClass*)GetDlgItem(IDC_ID); //Reference to dialog item IDC_ID
temp->DoSomething(); //This gives me an assertion error
}
I know I can use "this" if it is the same dialog item than the message, but I want to access another dialog item.
Thanks for your attention.
Solution:
As suggested by Moo-Juice, you can simply pass the dialog when you instantiate the class. In my case, I couldn't do that. For some reason subclassing didn't work that way. If you face the same issue when doing an application in MFC , you can create a pointer to a CDialog and pass it your main dialog at OnInitDialog():
Example (Class):
class AnotherClass : CClass
{
AnotherClass();
public:
void MyFunction();
CDialog * mainDialog;
};
void AnotherClass::MyFunction() //Message overwriting, can't change parameters
{
CClass* temp = (CClass*)mainDialog->GetDlgItem(IDC_ID); //Reference to dialog item IDC_ID
temp->DoSomething(); //This gives me an assertion error
}
Example (OnInitDialog()):
MyMainDialog::OnInitDialog()
{
...
AnotherClass obj; //Instantiate class
obj->mainDialog = this;
return true;
}
In this example simply passing it as a parameter when creating the object makes more sense. It just didn't work with me for what I was doing.
Hope it helps anyone with a similar question.
When you instantiate AnotherClass, pass it the dialog class:
class AnotherClass
{
private:
CDialog& dialog_;
public:
AnotherClass(CDialog& dialog) : dialog_(dialog) { }
void MyFunction();
};
void AnotherClass::MyFunction()
{
CClass* temp = (CClass*)dialog_.GetDigItem(IDC_ID);
temp->doSOmething();
}
I don't think this is possible, but if it is, I'd find it very usseful.
I'm making a Gui API where the user does the paint event. Lets say I want to make a Numeric TextBox. Well it would only seem good practice for it to inherit from TextBox. The problem with this, is that the user is then stuck to reimplement the paint event for the textbox since
TextBox::paint();
Would just call my default way of drawing it.
It would be annoying if they had to maintain all their TextBox derivatives.
Is there a way to get around this problem?
Lets say my TextBox paints a square, then the numeric part adds a circle, but the user's textbox, which derives from my TextBox draws a triangle, and my Numeric one derives from my TextBox I want the result to be triangle, circle.
Thanks
As I say in my comment, I think the bridge pattern is actually what you want, but since you're trying to insert a user's class as a base class for your NumericField thing the way you'd do THAT is to:
template < typename Base = TextField >
struct NumericField : Base
{
...
void paint() { Base::paint(); draw_circle(); }
};
Now the user could use NumericField<> or they could insert their class:
struct UserField : TextField
{
...
void paint() { draw_triangle(); }
};
NumericField<UserField> my_field;
The bridge answer would look more like so:
struct TextField
{
TextField() : extender_(new null_extender) {}
...
void set_extender(extender*);
virtual void paint() { draw_square(); extender_->paint(); }
...
};
struct extender { virtual void paint() = 0; };
struct null_extender { void paint() {}};
struct numeric_extender { void paint() { draw_circle(); }};
struct UserField
{
void paint() { draw_triangle(); extender()->paint(); }
};
Lots of details missing from that, but that would sort of be the story.
Isn't the only difference between NumericTextBox and TextBox that the former only allows the input of certain characters? Do you want it to paint differently?
I'm not sure quite what you mean. Your question is not that clear.
The title seems to be asking how to call the base class initializer or constructor,
is that what you want?
If this is what you want then just like this.
class TextBox
{
public:
TextBox() { }
virtual ~TextBox() { }
virtual Paint() { }
};
class NumericTextBox : public TextBox
{
public:
NumericTextBox() : TextBox() { }
~NumericTextBox() { }
};
Make sure the base class for TextBox::Paint and any other methods are declared virtual as well as the destructor.