I need to call TestDlg::DlgProc function from Dialog::StaticDlgProc. To do this, I pass this pointer for DialogBoxParam function. The problem is that return dlg->DlgProc(hwnd,message,wParam,lParam); //line 16, dialog.cpp calls dialog::DlgProc instead of TestDlg::DlgProc
Static member functions like DlgProc don't mix with polymorphism. They are always determined based on the static type (Dialog) and never on the dynamic type (TestDlg).
Rule 1: If you want to use the polymorphic behavior you always need to use virtual functions!
Rule 2: Static functions cannot be virtual.
Solution:
* add a virtual function called getDlgProc accepting no arguments and returning a pointer to your callback function (maybe use a typedef for the callback signature to increase readability).
* since the function is virtual, it depends on the dynamic type and returns a pointer to the correct callback function.
#include <windows.h>
#include "resource.h"
#include "dialog.h"
class TestDlg: public Dialog
{
public:
DLGPROC get_proc();
bool Run();
BOOL CALLBACK DlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
};
bool TestDlg::Run()
{
DialogBoxParam(GetModuleHandle(0), MAKEINTRESOURCE(IDD_UNLOCK), NULL, StaticDlgProc,(LPARAM)this);
}
DLGPROC TestDlg::get_proc() // get_proc function implemented in derived class
{
return (DLGPROC)&Dialog::DlgProc;
}
BOOL CALLBACK TestDlg::DlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_CLOSE:
EndDialog(hwnd, 0);
return TRUE;
case WM_COMMAND:
switch(LOWORD(wParam))
{
case IDCANCEL:
EndDialog(hwnd,0);
break;
}
}
return FALSE;
}
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
TestDlg t;
t.Run();
}
If I try to use DLGPROC_INTERNAL as a function pointer I get a bunch of errors...
Btw, one problem with your example is that Derived::DerivedCallback is static, so I had to modify it like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
class Base
{
public:
virtual ~Base();
typedefvoid (*MyCallbackType) ();
virtual MyCallbackType getProc();
staticvoid BaseCallback();
};
class Derived : public Base
{
public:
MyCallbackType getProc();
void DerivedCallback(); // no static keyword here
};
You can't mix pointer to static or free functions and member functions (without a static)!
They don't even have the same size. You can think of a pointer to a non-static member function as a pointer to a class plus a pointer to the member function.
They are invoked differently too.
So if you cast a pointer to a non-static member function to a static member function this is likely to crash!
In my version of VS2005 it doesn't even compile.
If you need the flexibility to invoke a non-static member function then better use a different approach.
I modified my version to use this pattern.
Together with the wiki site you should be able to figure out how it works and how to adapt to your needs!
Hint: You need to modify the signature of the execute member.