Well, looks like it may be in how I am creating my framework. I've used this method in some simpler programs that have worked fine but now it seems like it is broken somewhere...
Basic functins are controlled by my CFramework class
Code:
class CFramework
{
public:
CFramework(CBaseApp* pApp);
~CFramework() { Release(); }
bool Initialize(char* title, HINSTANCE hInstance, CBaseApp *pApp);
void Release();
void AttachWndProc(HWND h, CBaseApp *pClass) { m_WndMap[h] = pClass; }
void RemoveWndProc(HWND h) { m_WndMap.erase(h); }
void AttachDlgProc(HWND h, CBaseDialog *pClass) { m_DlgMap[h] = pClass; }
void RemoveDlgProc(HWND h) { m_DlgMap.erase(h); }
int Run();
BOOL MakeButton(LPCTSTR title, int x, int y, int h, int w, HWND hParent, int id, HWND *hReturn);
BOOL MakeDialog(int type, HWND hParentWnd, CBaseDialog *pNewDialog, CBaseDialog *pOldDialog = NULL);
static LRESULT CALLBACK StaticWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
static BOOL CALLBACK StaticDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
static hWndMap m_WndMap;
static hDlgMap m_DlgMap;
private:
void OnCreateControl();
void OnDestroyControl();
HWND m_hWnd;
HINSTANCE m_hInstance;
CBaseApp *m_pApp;
CBaseDialog *m_pDialog;
};
and I have a CApp class that is derived from a virtual CBaseApp class
Code:
class CBaseApp
{
public:
virtual ~CBaseApp() { }
virtual void Release() = 0;
virtual void OnCreateControl(HWND) = 0;
virtual void OnDestroyControl() = 0;
virtual int Run() = 0;
};
class CApp : public CBaseApp
{
public:
CApp();
~CApp () { Release(); }
void Release();
void OnCreateControl(HWND hWnd);
void OnDestroyControl();
int Run();
bool Initialize();
void SetFramework(CFramework* pFramework) { m_pFramework = pFramework; }
LRESULT CALLBACK InstanceWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
private:
CFramework *m_pFramework;
CBaseDialog *m_pCurrentDlg;
CDlgTrace m_DlgTrace;
CDlgCustomerLookup m_DlgCustomerLookup;
CDlgCityDispatchPlan m_DlgCityDispatchPlan;
};
and a CDialog class which is derived similarly from a CBaseDialog class.
Code:
class CBaseDialog
{
public:
virtual ~CBaseDialog() { }
virtual void Release() = 0;
virtual HWND Create(int type, HWND hParentWnd) = 0;
virtual HWND GetHandle() = 0;
virtual BOOL CALLBACK InstanceDlgProc(HWND hwnd,
UINT msg,
WPARAM wParam,
LPARAM lParam) = 0;
};
class CDlgCustomerLookup : public CBaseDialog
{
public:
CDlgCustomerLookup() { m_hDialog = NULL; m_hParentWnd = NULL; }
~CDlgCustomerLookup() { Release(); }
void Release() { if (m_hDialog != NULL) {DestroyWindow(m_hDialog);m_hDialog = NULL; } }
HWND Create(int type, HWND hParentWnd);
HWND GetHandle() { return m_hDialog; }
BOOL CALLBACK InstanceDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
private:
HWND m_hDialog;
HWND m_hParentWnd;
};
and my WinMain
Code:
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine, int nCmdShow)
{
CApp *pApp = new CApp();
CFramework *pFramework = new CFramework( (CBaseApp*)pApp);
int msg;
pApp->SetFramework(pFramework);
if (pApp->Initialize() )
{
// Initialize the Framework
if (pFramework->Initialize("Test App", hInst, pApp) )
{
// Run the application
msg = pFramework->Run();
}
else
SHOWERROR("CFramework::Initialize() failed");
}
else
SHOWERROR("CApp::Initialize() failed");
// Clean up resources
delete pFramework;
delete pApp;
return msg;
}
and the message loop starts in CFramework where I simple transfer control to CApp so I can do application dependent processing such as IsDlgMessage()
Code:
int CFramework::Run()
{
if (m_pApp != NULL)
{
return m_pApp->Run();
}
return 0;
}
int CApp::Run()
{
MSG Msg;
while(GetMessage(&Msg, NULL, 0, 0) > 0)
{
BOOL handled = FALSE;
if (m_pCurrentDlg)
handled = IsDialogMessage(m_pCurrentDlg->GetHandle(), &Msg);
if (!handled)
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
}
return Msg.wParam;
}
m_pCurrentDlg is simply a pointer to a CBaseDialog object which is the current dialog box being displayed
I am using a std::map to link the window handle with the InstanceWndProc, and the same with the dialogs, as seen in CFramework::AttachWndProc and CFramework::AttachDlgProc
I am using a static WndProc and DlgProc to direct messages to the correct instance
Code:
LRESULT CALLBACK CFramework::StaticWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
hWndMap::iterator it = m_WndMap.find(hWnd);
if (it != m_WndMap.end() )
{
CApp *pClass = (CApp*)it->second;
return pClass->InstanceWndProc(hWnd, msg, wParam, lParam);
}
return DefWindowProc(hWnd, msg, wParam, lParam);
}
BOOL CALLBACK CFramework::StaticDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
hDlgMap::iterator it = m_DlgMap.find(hDlg);
if (it != m_DlgMap.end() )
{
CDialog *pClass = (CDialog*)it->second;
return pClass->InstanceDlgProc(hDlg, msg, wParam, lParam);
}
return FALSE;
}
This part is working, as I can create controls in the InstanceWndProc based off of menu selections on the menu bar. But it seems like the correct hWnd is not being sent as it is just the functions that require a HWND are not working right. For instance, in my InstanceWndProc I have
Code:
// Menu Bar Commands
case WM_COMMAND:
{
switch (LOWORD(wParam) )
{
case IDD_CUSTOMERLOOKUP:
{
if(!m_pFramework->MakeDialog(LOWORD(wParam), hWnd, &m_DlgCustomerLookup, m_pCurrentDlg) )
SHOWERROR("Dialog Creation Failed");
m_pCurrentDlg = &m_DlgCustomerLookup;
}
break;
}
}
break;
and this creates the correct dialog box. But if I replace this with a simple TextOut() command, nothing happens.
I know this is a bit to look through and I'm sure it is something simple but I am completely at a loss here. Thanks to anyone willing to help.