I believe I've narrowed the problem down a bit. There is only trouble when I try to create more than one control WHEN I am using a class-encapsulated application. Ken Fitlike, I think this is where I need your help the most.
I should probably describe the class:
Code:
class CppProtoWnd
{
private:
char chClassName[100];
char chCaption[256];
protected:
HWND hParent;
HINSTANCE hInst;
public:
CppProtoWnd();
virtual ~CppProtoWnd();
virtual HWND Create(HWND hParent=NULL);
char * GetCaption();
char * GetClassName();
virtual void SetInstance(HINSTANCE hInstance);
virtual void SetCaption(char *chCap);
virtual void SetClassName(char *chClass);
int left,top,width,height;
int nStyle,nExStyle;
int nID;
};
class CppAppWnd:public CppProtoWnd
{
private:
int nClassStyle;
protected:
public:
CppAppWnd();
~CppAppWnd();
virtual HWND Create(HWND hParent=NULL);
static LRESULT CALLBACK CppAppWndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam);
HWND hAppWnd;
};
All credit for that class goes to Ken Fitlike. I don't want to be accused of plaguarism.
Code:
CppProtoWnd::CppProtoWnd()
{
hInst=NULL;
nExStyle=0; //no extended wnd style
nID=0; //no identifier or menu
}
CppProtoWnd::~CppProtoWnd()
{
}
HWND CppProtoWnd::Create(HWND hParent)
{
HWND hwnd; //the wnd handle
hwnd=CreateWindowEx(nExStyle, //more or 'extended' styles
chClassName, //the 'class' of window to create
chCaption, //the window title
nStyle, //window style: how it looks
left, //window position: left
top, //window position: top
width, //window width
height, //window height
hParent, //parent window handle
(HMENU)nID, //handle to wnd menu or cntrl ID
hInst, //application instance
(VOID*)this); //store pointer to class
return hwnd;
}
char *CppProtoWnd::GetCaption()
{
return chCaption;
}
char *CppProtoWnd::GetClassName()
{
return chClassName;
}
void CppProtoWnd::SetInstance(HINSTANCE hInstance)
{
hInst=hInstance;
}
void CppProtoWnd::SetCaption(char *chCap)
{
if ((chCap)&&(lstrlen(chCap)<256))
lstrcpy(chCaption,chCap);
}
void CppProtoWnd::SetClassName(char *chClass)
{
if ((chClass)&&(lstrlen(chClass)<100))
lstrcpy(chClassName,chClass);
}
CppAppWnd::CppAppWnd()
{
SetCaption("Window Caption");
SetClassName("myWindowClass");
hAppWnd=NULL;
left=GetSystemMetrics(SM_CXSCREEN)/4;
top=GetSystemMetrics(SM_CYSCREEN)/4;
width=GetSystemMetrics(SM_CXSCREEN)/2;
height=GetSystemMetrics(SM_CYSCREEN)/2;
nStyle=WS_OVERLAPPEDWINDOW;
nClassStyle=CS_HREDRAW|CS_VREDRAW;
}
CppAppWnd::~CppAppWnd()
{
}
//************************************************************************************
//===============================App Window Procedure=================================
//************************************************************************************
LRESULT CALLBACK CppAppWnd::CppAppWndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
{
switch (msg)
{
case WM_COMMAND:
switch (LOWORD(wParam))
{
case 1:
return DefWindowProc(hwnd,msg,wParam,lParam);
default:
return DefWindowProc(hwnd,msg,wParam,lParam);
}
case WM_CLOSE:
DestroyWindow(hwnd);
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
default:
return DefWindowProc(hwnd,msg,wParam,lParam);
}
return DefWindowProc(hwnd,msg,wParam,lParam);
}
HWND CppAppWnd::Create(HWND hParent)
{
WNDCLASSEX wcx; //this structure is used for storing information about the wnd 'class'
wcx.cbSize = sizeof(WNDCLASSEX); //byte size of WNDCLASSEX struct
wcx.style = nClassStyle; //ensure wnd is always redrawn
wcx.lpfnWndProc = (WNDPROC)CppAppWndProc; //pointer to the Window Procedure
wcx.cbClsExtra = 0; //Extra bytes for 'class' wnds
wcx.cbWndExtra = 0; //Extra bytes for this wnd
wcx.hInstance = hInst; //Application instance
wcx.hIcon = LoadIcon(hInst,(LPCTSTR)IDI_APP); //Application icon
wcx.hCursor = LoadCursor(NULL,IDC_ARROW); //Cursor for wnd
wcx.hbrBackground = (HBRUSH)(COLOR_BTNFACE+1); //Background wnd colour
wcx.lpszMenuName = NULL; //Name of wnd menu
wcx.lpszClassName = GetClassName(); //Name of this wnd 'class'
wcx.hIconSm = NULL; //Icon in top-left corner of wnd
if (!RegisterClassEx(&wcx))
return NULL;
HWND hwnd;
hwnd=CppProtoWnd::Create();
if (!hwnd)
return NULL;
if (!hAppWnd)
hAppWnd=hwnd;
ShowWindow(hwnd,SW_SHOW);
UpdateWindow(hwnd);
cTree *ct=new cTree(hwnd);
ct->width=200;
ct->height=300;
ct->Create(hwnd,hInst);
cTree *ct2=new cTree(hwnd);
ct2->left=205;
ct2->width=200;
ct2->height=300;
ct2->Create(hwnd,hInst);
return hwnd;
}
The second cTree attempted bombs out during CreateWindowEx, causing an "Invalid Window Handle" error. I've tried placing other cTrees in different parts of the program, but wherever it is, if it's not the first cTree, it won't work.
Maybe the problem is something to do with instances of classes, static stuff, etc?