Code:
#include <windows.h>
#define numChild 2
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
//children window procedure
LRESULT CALLBACK ChildWndProc(HWND, UINT, WPARAM, LPARAM);
TCHAR szChildClass [] = TEXT("Children"); //Child class name
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) {
static TCHAR szAppName[] = TEXT("ChildWindowDemo");
WNDCLASS wc;
MSG msg;
HWND hwnd;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hInstance = hInstance;
wc.lpfnWndProc = WndProc;
wc.lpszClassName = szAppName;
wc.lpszMenuName = NULL;
wc.style = CS_HREDRAW | CS_VREDRAW;
if(!RegisterClass(&wc)) {
MessageBox(NULL, TEXT("Could not register class"), szAppName, MB_ICONERROR);
return 0;
}
//define and register child window class
wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
wc.lpfnWndProc = ChildWndProc;
wc.hIcon = NULL;
wc.lpszClassName = szChildClass;
RegisterClass(&wc);
//-------------------------------------
hwnd = CreateWindow(szAppName,
TEXT("Child Window Demo"),
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
hInstance,
NULL);
ShowWindow(hwnd, iCmdShow);
UpdateWindow(hwnd);
while(GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
static HWND hwndChild[numChild]; //create array to hold children
int cxBlock, cyBlock, x;
switch(message) {
case WM_CREATE:
//create our children
for(x = 0; x < numChild; x++) {
hwndChild[x] = CreateWindow(szChildClass,
NULL,
WS_CHILDWINDOW | WS_VISIBLE,
0,
0,
0,
0,
hwnd,
(HMENU)(1 << 8 | x), //child window ID
(HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE),
NULL);
}
return 0;
case WM_SIZE:
//each window will be 1/2 width of parent and = height
cxBlock = LOWORD(lParam) / numChild;
cyBlock = HIWORD(lParam);
for(x = 0; x < numChild; x++) {
MoveWindow(hwndChild[x],
x * cxBlock,
0,
cxBlock,
cyBlock,
TRUE);
}
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd, message, wParam, lParam);
}
LRESULT CALLBACK ChildWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
static int iColor;
int bkgColor[4] = {WHITE_BRUSH, LTGRAY_BRUSH, DKGRAY_BRUSH, BLACK_BRUSH};
switch(message) {
case WM_CREATE:
iColor = 0;
SetWindowLong(hwnd, 0, 0);
return 0;
case WM_LBUTTONUP:
SetClassLong(hwnd, GCL_HBRBACKGROUND, (LONG)GetStockObject(bkgColor[iColor]));
InvalidateRect(hwnd, NULL, TRUE);
if(!(iColor == 3)) {
iColor++;
}else {
iColor = 0;
}
return 0;
}
return DefWindowProc(hwnd, message, wParam, lParam);
}
As you can see the same child window procedure is used for both the child windows, its not like you have to worry about iterating through all your windows to do something to them, hence no inefficiency. To prove the point just change numChild to some other number, and you will see the program still acts the same. Windows is message based so it resolves who the messages are going to for you. Hope this helps to answer your question and welcome to the board.