#include <windows.h>

HANDLE ghInstance;


long FAR PASCAL WndProc (HWND, WORD, WPARAM, LPARAM);
long FAR PASCAL ChildProc(HWND, WORD, WPARAM, LPARAM);

int PASCAL WinMain (HANDLE hInstance, HANDLE hPrevInstance,
		    LPSTR lpszCmdParam, int nCmdShow)
    {
    static char szAppName[] = "ClassLook" ;
    HWND        hwnd ;
    MSG		msg ;
    WNDCLASS    wndclass ;

    ghInstance = hInstance;
    if (!hPrevInstance)
	 {
	 wndclass.style		= CS_HREDRAW | CS_VREDRAW ;
	 wndclass.lpfnWndProc	= WndProc ;
	 wndclass.cbClsExtra	= 0 ;
	 wndclass.cbWndExtra	= 0 ;
	 wndclass.hInstance	= hInstance ;
	 wndclass.hIcon		= LoadIcon (NULL, IDI_APPLICATION) ;
	 wndclass.hCursor	= LoadCursor (NULL, IDC_ARROW) ;
	 wndclass.hbrBackground	= GetStockObject (WHITE_BRUSH) ;
	 wndclass.lpszMenuName	= NULL ;
	 wndclass.lpszClassName	= szAppName ;

	 RegisterClass (&wndclass) ;
	 }

    hwnd = CreateWindow (szAppName,	/* window class name */
		  "ClassLook",		/* window caption */
		  WS_OVERLAPPEDWINDOW,	/* window style */
		  CW_USEDEFAULT,	/* initial x position */
		  CW_USEDEFAULT,	/* initial y position */
		  600,	/* initial x size */
		  400,	/* initial y size */
		  NULL,			/* parent window handle */
		  NULL,			/* window menu handle */
		  hInstance,		/* program instance handle */
		  NULL) ;		/* creation parameters */

    ShowWindow (hwnd, nCmdShow) ;
    UpdateWindow (hwnd) ;

    while (GetMessage (&msg, NULL, 0, 0))
	 {
	 TranslateMessage (&msg) ;
	 DispatchMessage (&msg) ;
	 }
    return msg.wParam ;
    }

long FAR PASCAL WndProc (HWND hwnd, WORD message, WPARAM wParam, LPARAM lParam)
    {
    HDC		hdc ;
    PAINTSTRUCT	ps ;
    RECT	rect ;
    WNDCLASS    wndclass ;

    static HWND	hChild;

    switch (message)
	 {
	 case WM_CREATE :
	     wndclass.style		= CS_PARENTDC | CS_HREDRAW | CS_VREDRAW;
    	     wndclass.lpfnWndProc	= ChildProc ;
    	     wndclass.cbClsExtra	= 0 ;
    	     wndclass.cbWndExtra	= 0 ;
    	     wndclass.hInstance		= ghInstance ;
    	     wndclass.hIcon		= NULL ;
    	     wndclass.hCursor		= LoadCursor (NULL, IDC_CROSS) ;
    	     wndclass.hbrBackground	= GetStockObject (LTGRAY_BRUSH) ;
    	     wndclass.lpszMenuName	= NULL ;
    	     wndclass.lpszClassName	= "SecondClass" ;

	     RegisterClass (&wndclass);
              
             hChild = CreateWindow("SecondClass","Child Window",
                 WS_CHILD | WS_VISIBLE | WS_BORDER,
                 10, 10, 580, 380, hwnd, NULL, ghInstance, NULL);
             ShowWindow(hChild, SW_SHOW);
	 case WM_PAINT :
	      hdc = BeginPaint (hwnd, &ps) ;

	      GetClientRect (hwnd, &rect) ;

	      DrawText (hdc, "Hello, Windows!", -1, &rect,
			DT_SINGLELINE | DT_CENTER | DT_VCENTER) ;

	      EndPaint (hwnd, &ps);
	      return 0 ;

	 case WM_DESTROY :
	      PostQuitMessage (0) ;
	      return 0 ;
	 }
    return DefWindowProc (hwnd, message, wParam, lParam) ;
    }

long FAR PASCAL ChildProc(HWND hwnd, WORD message, WPARAM wParam, LPARAM lParam)
{
    HDC			hDC;
    PAINTSTRUCT		ps;
    WNDCLASS		wndClass;
    char*		classes[]={"EDIT","BUTTON","LISTBOX","STATIC","SCROLLBAR","COMBOBOX","COMBOLBOX", NULL};
    char**		curr;
    char		buf[256];
    RECT	rect ;
    int i;

    switch (message) {
        case WM_PAINT:
            curr = classes;
            i=0;
            hDC = BeginPaint(hwnd, &ps);
            SelectObject(hDC,GetStockObject(ANSI_FIXED_FONT));
            while (*curr) {
              wsprintf(buf,"%12s:",*curr);
              GetClassInfo(NULL, *curr, &wndClass);
              if(wndClass.style&CS_VREDRAW)  lstrcat(buf," | CS_VREDRAW");
              if(wndClass.style&CS_HREDRAW)  lstrcat(buf," | CS_HREDRAW" );
              if(wndClass.style&CS_KEYCVTWINDOW) lstrcat(buf," | CS_KEYCVTWINDOW" );
              if(wndClass.style&CS_DBLCLKS) lstrcat(buf," | CS_DBLCLKS" );
              if(wndClass.style&CS_OWNDC) lstrcat(buf," | CS_OWNDC" );
              if(wndClass.style&CS_CLASSDC) lstrcat(buf," | CS_CLASSDC" );
              if(wndClass.style&CS_PARENTDC) lstrcat(buf," | CS_PARENTDC" );
              if(wndClass.style&CS_NOKEYCVT) lstrcat(buf," | CS_NOKEYCVT" );
              if(wndClass.style&CS_NOCLOSE) lstrcat(buf," | CS_NOCLOSE" );
              if(wndClass.style&CS_SAVEBITS) lstrcat(buf," | CS_SAVEBITS" );
              if(wndClass.style&CS_GLOBALCLASS) lstrcat(buf," | CS_GLOBALCLASS");
	      GetClientRect (hwnd, &rect) ;
	      TextOut (hDC, 5,20+i,buf,lstrlen(buf)) ;
              i += 15;
              curr++;
            }
/*            EndPaint(hwnd, &ps);
            break;
            hDC = BeginPaint(hwnd, &ps);
*/
            MoveTo(hDC, 0, 0);
            LineTo(hDC, 500, 500);
            EndPaint(hwnd, &ps);
            break;
        default:
            return DefWindowProc (hwnd, message, wParam, lParam) ;
    }
    return (0L);
}

