How to use pointer member method -> error: reference to non-static member function must be called

I have these two functions:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
void BrowserMonitor::WinEventProc(HWINEVENTHOOK hWinEventHook, DWORD event, HWND hwnd, LONG idObject, LONG idChild, DWORD dwEventThread, DWORD dwmsEventTime)
{
    static string found_url;
    static vector<string> viewedUrls;

    IAccessible* pAcc = NULL;
    VARIANT varChild;
    if ((AccessibleObjectFromEvent(hwnd, idObject, idChild, &pAcc, &varChild) == S_OK) &&
            (pAcc != NULL))
    {
        char className[50];

        if (GetClassName(hwnd, (LPWSTR)className, 50) && strcmp(className, "Chrome_WidgetWin_1") == 0)
        {
            BSTR bstrName = nullptr;
            if (pAcc->get_accName(varChild, &bstrName) == S_OK)
            {
                if (wcscmp(bstrName, L"Address and search bar") == 0)
                {
                    BSTR bstrValue = nullptr;

                    if (pAcc->get_accValue(varChild, &bstrValue) == S_OK)
                    {
                        wstring wstringValue(bstrValue);



                        std::string strValue;

                        if(found_url != strValue && find(viewedUrls.begin(), viewedUrls.end(),
                                                         strValue) == viewedUrls.end())
                        {

                            found_url = strValue;
                        }

                        viewedUrls.push_back(strValue);
                        SysFreeString(bstrValue);
                    }
                }
                SysFreeString(bstrName);
            }
            pAcc->Release();
        }
    }
}

void BrowserMonitor::hook()
{
    qDebug() << chromeEdgeBraveAddressBarIdentifier;
    if (LHook != 0) return;
    CoInitialize(NULL);
    LHook = SetWinEventHook(EVENT_OBJECT_FOCUS, EVENT_OBJECT_VALUECHANGE, 0, WinEventProc, 0, 0, WINEVENT_SKIPOWNPROCESS); // error: reference to non-static member function must be called
}


If I remove the WinEventProc from the class and just leave it in the .cpp file it compiles fine.
But the thing is I have some member variables that I need to use in the WinEventProc function.
I think I have to use a pointer member method but I can't seem to figure it out.

If someone know how to do that please help.
Thank you.
what line?
the error message sounds like this:

class foo
{
void bar(){;}
};

main()
foo::bar(); //error: called non-static member function.
foo x;
x.bar(); //OK, called it from an instance.

what line?

Line 53
I think I have to use a pointer member method but I can't seem to figure it out.

All non-static member functions have an additional hidden parameter called the implicit object parameter. A corresponding implicit object argument must be supplied when the function is called.

For example, you need a BrowserMonitor to call the non-static member function BrowserMonitor::WinEventProc. This specific BrowserMonitor must be passed as the implicit object argument. Normally it goes on the left of the dot or arrow:
my_browser_monitor.WinEventProc(/* etc... */)
The problem is, the Windows API doesn't know about BrowserMonitor and therefore can't pass one as required.

The easiest way to get around this is to put the this pointer into a global or static variable.
This limits you to one BrowserMonitor at a time. For example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class BrowserMonitor 
{
  static BrowserMonitor* my_browser_monitor; 

  friend void WinEventProcThunk(HWINEVENTHOOK hWinEventHook, DWORD event, HWND hwnd, LONG idObject, LONG idChild, DWORD dwEventThread, DWORD dwmsEventTime)
  {
    return BrowserMonitor::my_browser_monitor->WinEventProc(hWinEventHook, event, hwnd, idObject, idChild, dwEventThread, dwmsEventTime);
  }

  void WinEventProc(/* ... */); // defined as in the original post
public:
  void BrowserMonitor::hook()
  {
    qDebug() << chromeEdgeBraveAddressBarIdentifier;
    BrowserMonitor::my_browser_monitor = this;
    if (LHook != 0) return;
    CoInitialize(NULL);
    LHook = SetWinEventHook(EVENT_OBJECT_FOCUS, EVENT_OBJECT_VALUECHANGE, 0, WinEventProcThunk, 0, 0, WINEVENT_SKIPOWNPROCESS); 
  }
};


Often APIs like this have some kind of pass-through "user-data" void* which you could use to pass your BrowserMonitor in, but unfortunately not here.
Last edited on
@mbozzi Thanks for the reply.

However I am error in where it is line 18 of the code you posted.

browsermonitor.h:39:82: error: use of undeclared identifier 'WinEventProcThunk'.

As a note, I came with a way to solve the and be able to use member variables in the function WinEventProc.

I made my singleton and then made the WinEventProc function a friend function of my class.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
class BrowserMonitor
{
    BrowserMonitor();
public:
    static BrowserMonitor& singleton();

    friend void WinEventProc(HWINEVENTHOOK hWinEventHook, DWORD event, HWND hwnd, LONG idObject, LONG idChild, DWORD dwEventThread, DWORD dwmsEventTime);

};

#define BROWSER_MONITOR BrowserMonitor::singleton()

// cpp file

BrowserMonitor& BrowserMonitor::singleton()
{
    static BrowserMonitor* instance = new BrowserMonitor;
    return *instance;
}

void BrowserMonitor::WinEventProc(HWINEVENTHOOK hWinEventHook, DWORD event, HWND hwnd, LONG idObject, 
                                 LONG idChild, DWORD dwEventThread, DWORD dwmsEventTime)
{
// Here I can just use any variable just by using BROWSER_MONITOR.variable_name

}


But I still want to use the code you posted and get it to work as having a singleton class might not be the best solution for me in this case as it might limit my code in the future.
Topic archived. No new replies allowed.