1

As you can see by my code, I'm trying to create a onClick event for a button that invoke a function from another class (I'm trying to make my custom button class instead of using win32 default ones for testing).

But even if this does not throw any error, it just doesn't invoke the given method.

This is the function signature inside Button.hpp

void onClick(POINT pt, void (ButtonsHandler::*clicked)(void));

This is the implementation inside Button.cpp (Using clicked() throws C++ expression preceding parentheses of apparent call must have pointer-to function type)

void Button::onClick(POINT pt, void (ButtonsHandler::*clicked)(void)) 
{
    if (PtInRect(&textRect, pt) != 0) 
    {
        clicked;
    }
}

And this is where I actually call it

mainMenu.getPlay().onClick(pt, &ButtonsHandler::onPlay);

EDIT: solved thank you guys I was just not creating a ButtonsHandler object to execute the non-static function Here's the correct code I was missing.

void Button::onClick(POINT pt, void (ButtonsHandler::*clicked)(void)) {
    if (PtInRect(&textRect, pt) != 0) {
        ButtonsHandler bh;
        (bh.*clicked)();
    }
}
JeJo
  • 30,635
  • 6
  • 49
  • 88
  • 3
    `clicked;` is a valid expression but it doesn't call anything (assuming you intended this). How about `clicked();`? – Scheff's Cat Oct 25 '21 at 10:23
  • how about *this* pointer ? if you call class method you must pass pointer to class. where you try do this ? – RbMm Oct 25 '21 at 10:23
  • 1
    @JeJo Yes. And the missing instance pointer to the `ButtonsHandler` (or its unknown relation to `Button`) is yet another issue which is unclear from the exposed info. But, anyway: No brackets - no call. ;-) (and I was assuming that adding the brackets might cause a new error which leads into the right direction) – Scheff's Cat Oct 25 '21 at 10:37

1 Answers1

-1

It just doesn't invoke the given method!

The passed pointer to member function has to be called to get in effect.

I assume that the Button is inherited from the ButtonsHandler. Then, for instance, you can call with the pointer to member function with this pointer as follows:

void Button::onClick(POINT pt, void (ButtonsHandler::*clicked)(void)) 
{
    if (PtInRect(&textRect, pt) != 0) {
        (this->*clicked)();
        //^^^^^^^^^^^^^^^^^^
        // or
        // std::invoke(clicked, this) // need to include <functional> header(Since C++17)
    }
}

If both classes are unrelated, you required an instance of ButtonsHandler to call the member function. For example:

ButtonsHandler obj;
(obj.*clicked)();
// or
// std::invoke(clicked, obj) // need to include <functional> header
JeJo
  • 30,635
  • 6
  • 49
  • 88