Hello,
I know that this issue was already asked before many times. I made some research through the web and I found what I was looking for.
I found some solutions to this problem and I chose one of them. I came here to look for an explanation about the approach I used in my code.
I'm trying to develop an error class to my Win32 application and I decided that the error messages will show up in a Win32 DialogBox.
So, I developed an Error class. This class has a method CreateDialogBox, where I will call the DialogBox in the resource file. I need to pass as a parameter to the Win32 API function "DialogBox", that will create my DialogBox, a function called DialogProc with the signature expected by the Win32 API function "DialogBox".
How did I solve this problem? I used the wrapper approach with a global pointer to the instance of the class declared into my Error.cpp file.
As you can see in the code below, the DialogProc is a method of my Error class. There is a static wrapper, with the same signature of the DialogProc, that will be passed to the WIN32 API function "DialogBox". Look the code below:
Error.h:
Code:
class Error
{
private:
char* errorMessage;
int sizeOfMessage;
bool stopExecution;
public:
Error();
~Error();
BOOL CALLBACK DialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
static BOOL CALLBACK Wrapper(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
void CreateDialogBox();
void CreateErrorMessage(int size);
void DestroyErrorMessage();
void SetErrorMessage(char* msg);
char* GetErrorMessage();
void SetStopExecution(bool flag);
bool GetStopExecution();
};
Error.cpp:
Code:
#include "../Global.h"
void* ptrError;
Error::Error()
{
this->errorMessage = 0;
this->sizeOfMessage = 0;
this->stopExecution = false;
}
Error::~Error()
{
DestroyErrorMessage();
}
BOOL CALLBACK Error::DialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch(uMsg)
{
case WM_INITDIALOG:
SetDlgItemText(hwndDlg, IDC_TXT, this->errorMessage);
return TRUE;
case WM_CLOSE:
EndDialog(hwndDlg, 0);
return TRUE;
case WM_COMMAND:
switch(LOWORD(wParam))
{
case IDC_BTN_OK:
EndDialog(hwndDlg, 0);
return TRUE;
}
}
return FALSE;
}
BOOL CALLBACK Error::Wrapper(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
Error* mySelf = (Error*) ptrError;
return mySelf->DialogProc(hwndDlg, uMsg, wParam, lParam);
}
void Error::CreateDialogBox()
{
SDL_SysWMinfo *info;
SDL_GetWMInfo(info);
HWND hWin = info->window;
HINSTANCE hInstance = (HINSTANCE) GetWindowLong(hWin, GWL_HINSTANCE);
ptrError = this;
DialogBox(hInstance, MAKEINTRESOURCE(DLG_MAIN), NULL, Error::Wrapper);
}
void Error::CreateErrorMessage(int size)
{
this->errorMessage = new char[size];
this->sizeOfMessage = size;
memset(this->errorMessage, '\0', size);
}
void Error::DestroyErrorMessage()
{
if(this->errorMessage != 0)
{
delete errorMessage;
}
}
void Error::SetErrorMessage(char* msg)
{
strcpy(this->errorMessage, msg);
}
char* Error::GetErrorMessage()
{
return this->errorMessage;
}
void Error::SetStopExecution(bool flag)
{
this->stopExecution = flag;
}
bool Error::GetStopExecution()
{
return this->stopExecution;
}
I don't like very much the idea of using a global pointer to the class Error so I can call the method inside the wrapper.
So, the first question is: Is there any better way to to this?
Second: What are the problems I will have with the approach I chose?
Thanks in advance fot the answers...
Bruno.