Al's Programming Resource Homepage  Main Page   Compound List   File List   Compound Members   File Members  

Oglmdi.cpp

Go to the documentation of this file.
00001 /*
00002                                    OpenGL MDI Example
00003 
00004                                  Program by Alan Baylis 
00005                                   Copyright 24/01/2001
00006 
00007 
00008 This program demonstrates a Win32 MDI application with OpenGL compatible child windows.
00009 
00010 This code may be freely modified and redistributed but I make no warrantees about it; use at your own risk. If you use this code then give me credit and a link back to this site.
00011 An email or a post to my message board of where we could find your program would be nice too.
00012 
00013 */
00014 
00015 #include <windows.h>
00016 #include <gl\gl.h>
00017 #include <gl\glu.h>
00018 #include <stdio.h>
00019 #include <stdlib.h>                            // Header for Visual Component Library required for USERC(...);
00020 #include "resource.rh"                            // Header for resource file
00021 
00022 #define ID_MDI_CLIENT      4999             // ID for client menu
00023 #define ID_MDI_FIRSTCHILD  50000            // Start ID for child windows
00024 
00025 char g_szMainClassName[] = "MainWindow";
00026 char g_szChildClassName[] = "OpenGL";
00027 HINSTANCE g_hInst;
00028 HWND g_hMDIClient;
00029 HWND g_hMainWindow;
00030 RECT g_rectChild;                         // RECT structure required to get the child window dimensions
00031 
00032 float    g_fCubeRotationX, g_fCubeRotationY;      
00033 
00034 bool g_bMouseDrag = 0;                         // Mouse capture flag
00035 int g_iMouseLastX;                             // Holds previous X position of mouse
00036 int g_iMouseLastY;                             // Holds previous Y position of mouse
00037 int g_iMouseDeltaX;                            // Holds the mouse increment in X since LastX
00038 int g_iMouseDeltaY;                            // Holds the mouse increment in Y since LastY
00039 
00040 typedef struct CHILD                        // Child structure for each child window
00041 {
00042     HDC hDC;                                // Individual device context
00043     HGLRC hRC;                              // Individual rendering context
00044     HWND hWnd;                              // Handle to child window
00045 } CHILD;
00046 
00047 int g_iMaxChild = 50;                          // Maximum number of child windows wanted
00048 int g_iNumChild = 0;                           // Number of child windows created
00049 CHILD* g_child = new CHILD[g_iMaxChild];         // Create the CHILD structures
00050 
00051 /* Set the rendering options for OpenGL */
00052 void InitGL()
00053 {
00054     glCullFace(GL_BACK);
00055     glClearColor(0.0, 0.0, 0.0, 0.0);
00056     glClearDepth(1.0);
00057     glDepthFunc(GL_LESS);
00058     glEnable(GL_DEPTH_TEST);
00059     glShadeModel(GL_SMOOTH);
00060     glEnable(GL_NORMALIZE);
00061 
00062     float MatAmbient[] = {0.8, 0.8, 0.8, 1.0};
00063     float MatDiffuse[] = {0.8, 0.8, 0.8, 1.0};
00064     float MatSpecular[] = {0.9, 0.9, 0.9, 1.0};
00065     float MatEmmision[] = {0.0, 0.0, 0.0, 1.0};
00066     float MatShininess[] = {100.0};
00067 
00068     glMaterialfv(GL_FRONT, GL_AMBIENT, MatAmbient);
00069     glMaterialfv(GL_FRONT, GL_DIFFUSE, MatDiffuse);
00070     glMaterialfv(GL_FRONT, GL_SPECULAR, MatSpecular);
00071     glMaterialfv(GL_FRONT, GL_EMISSION, MatEmmision);
00072     glMaterialfv(GL_FRONT, GL_SHININESS, MatShininess);
00073 
00074     float LightAmbient[] = {0.2, 0.2, 0.2, 1.0};
00075     glLightfv(GL_LIGHT0, GL_AMBIENT, LightAmbient);
00076     float LightPosition[] = {-3.0, 2.0, 1.0, 1.0};
00077     glLightfv(GL_LIGHT0, GL_POSITION, LightPosition);
00078 
00079     glEnable(GL_LIGHTING);
00080     glEnable(GL_LIGHT0);
00081     glEnable(GL_CULL_FACE);
00082 }
00083 
00084 /* Sets the Projection matrix. The Modelview matrix is set in the DrawGLScene routine */
00085 void SetProjection(int iWidth, int iHeight)
00086 {
00087     if(iHeight == 0)
00088     {
00089         iHeight = 1;
00090     }
00091     glViewport(0, 0, iWidth, iHeight);
00092     glMatrixMode(GL_PROJECTION);
00093     glLoadIdentity();
00094     gluPerspective(45.0,(float)iWidth/(float)iHeight,0.1,200.0);
00095 }
00096 
00097 void DrawGLScene(void)
00098 {
00099     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
00100     glMatrixMode(GL_MODELVIEW);
00101     glLoadIdentity();
00102 
00103     if(g_bMouseDrag)        // If left mouse button is down
00104     {
00105         g_fCubeRotationX += (float)g_iMouseDeltaY * 0.5;   // Apply mouse deltas to cube rotation values
00106         g_fCubeRotationY += (float)g_iMouseDeltaX * 0.5;
00107     }
00108 
00109     glDisable(GL_TEXTURE_2D);
00110     glDisable(GL_LIGHTING);
00111     glPushMatrix();
00112     glTranslatef(0.0,0.0,-5.0);
00113     glRotatef(g_fCubeRotationX,1.0,0.0,0.0);
00114     glRotatef(g_fCubeRotationY,0.0,1.0,0.0);
00115     glBegin(GL_QUADS);
00116         // Front Face
00117         glColor3f(1.0,0.0,0.0);
00118         glVertex3f(-1.0, -1.0,  1.0);    // Bottom Left
00119         glColor3f(0.0,1.0,0.0);
00120         glVertex3f( 1.0, -1.0,  1.0);    // Bottom Right
00121         glColor3f(0.0,0.0,1.0);
00122         glVertex3f( 1.0,  1.0,  1.0);    // Top Right
00123         glColor3f(1.0,1.0,0.0);
00124         glVertex3f(-1.0,  1.0,  1.0);    // Top Left
00125         // Back Face
00126         glColor3f(0.0,0.0,1.0);
00127         glVertex3f(-1.0, -1.0, -1.0);    // Bottom Right
00128         glColor3f(0.0,1.0,0.0);
00129         glVertex3f(-1.0,  1.0, -1.0);    // Top Right
00130         glColor3f(1.0,0.0,0.0);
00131         glVertex3f( 1.0,  1.0, -1.0);    // Top Left
00132         glColor3f(1.0,1.0,0.0);
00133         glVertex3f( 1.0, -1.0, -1.0);    // Bottom Left
00134         // Top Face
00135         glColor3f(0.0,1.0,0.0);
00136         glVertex3f(-1.0,  1.0, -1.0);    // Top Left
00137         glColor3f(1.0,1.0,0.0);
00138         glVertex3f(-1.0,  1.0,  1.0);    // Bottom Left
00139         glColor3f(0.0,0.0,1.0);
00140         glVertex3f( 1.0,  1.0,  1.0);    // Bottom Right
00141         glColor3f(1.0,0.0,0.0);
00142         glVertex3f( 1.0,  1.0, -1.0);    // Top Right
00143         // Bottom Face
00144         glColor3f(0.0,0.0,1.0);
00145         glVertex3f(-1.0, -1.0, -1.0);    // Top Right
00146         glColor3f(1.0,1.0,0.0);
00147         glVertex3f( 1.0, -1.0, -1.0);    // Top Left
00148         glColor3f(0.0,1.0,0.0);
00149         glVertex3f( 1.0, -1.0,  1.0);    // Bottom Left
00150         glColor3f(1.0,0.0,0.0);
00151         glVertex3f(-1.0, -1.0,  1.0);    // Bottom Right
00152         // Right face
00153         glColor3f(1.0,1.0,0.0);
00154         glVertex3f( 1.0, -1.0, -1.0);    // Bottom Right
00155         glColor3f(1.0,0.0,0.0);
00156         glVertex3f( 1.0,  1.0, -1.0);    // Top Right
00157         glColor3f(0.0,0.0,1.0);
00158         glVertex3f( 1.0,  1.0,  1.0);    // Top Left
00159         glColor3f(0.0,1.0,0.0);
00160         glVertex3f( 1.0, -1.0,  1.0);    // Bottom Left
00161         // Left Face
00162         glColor3f(0.0,0.0,1.0);
00163         glVertex3f(-1.0, -1.0, -1.0);    // Bottom Left
00164         glColor3f(1.0,0.0,0.0);
00165         glVertex3f(-1.0, -1.0,  1.0);    // Bottom Right
00166         glColor3f(1.0,1.0,0.0);
00167         glVertex3f(-1.0,  1.0,  1.0);    // Top Right
00168         glColor3f(0.0,1.0,0.0);
00169         glVertex3f(-1.0,  1.0, -1.0);    // Top Left
00170     glEnd();
00171     glPopMatrix();
00172     glEnable(GL_LIGHTING);
00173     glEnable(GL_TEXTURE_2D);
00174 }
00175 
00176 LRESULT CALLBACK WndProc(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
00177 {
00178     switch(uMessage)
00179     {
00180         case WM_CREATE:
00181         {
00182             CLIENTCREATESTRUCT ccs;
00183             // Find window menu where children will be listed
00184             ccs.hWindowMenu = NULL;
00185 // If the menus document list for more than 9 children didn't upset the child ID then I would use the line below
00186             //ccs.hWindowMenu = (HMENU)GetSubMenu(GetMenu(hWnd), 2); // if you use less than 10 windows then use this line
00187             ccs.idFirstChild = ID_MDI_FIRSTCHILD;
00188 
00189             g_hMDIClient = CreateWindowEx(WS_EX_CLIENTEDGE, "MDICLIENT", NULL,
00190             WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,                    //WS_VSCROLL and WS_HSCROLL do not work properly yet
00191             CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
00192             hWnd, (HMENU)ID_MDI_CLIENT, g_hInst, (LPVOID)&ccs);
00193 
00194             ShowWindow(g_hMDIClient, SW_SHOW);
00195             return 0;
00196         }
00197         case WM_COMMAND:
00198         {
00199             switch(LOWORD(wParam))
00200             {
00201                 case CM_FILE_EXIT:
00202                     PostMessage(hWnd, WM_CLOSE, 0, 0);
00203                 break;
00204 
00205                 case CM_FILE_NEW:
00206                 {
00207                     HWND hChild;
00208 
00209                     if(g_iNumChild < g_iMaxChild)      // If the number of children hasn't reached the maximum
00210                         g_iNumChild++;              // Increment the number of children
00211                     else
00212                         break;                   // Otherwise break out of the routine
00213 
00214                     char szWindowTitle[20];
00215                     sprintf(szWindowTitle, "%d", g_iNumChild - 1);
00216 
00217 /* One way to create a child window is to send a WM_MDICREATE message to the client
00218 window and pass it a pointer to a MDICREATESTRUCT. */
00219 
00220 /*
00221                     MDICREATESTRUCT mcs;
00222                     mcs.szTitle = szWindowTitle;
00223                     mcs.szClass = g_szChildClassName;
00224                     mcs.hOwner  = g_hInst;
00225                     mcs.x = mcs.cx = CW_USEDEFAULT;
00226                     mcs.y = mcs.cy = CW_USEDEFAULT;
00227                     mcs.style = MDIS_ALLCHILDSTYLES;
00228 
00229                     hChild = (HWND)SenduMessage(g_hMDIClient, WM_MDICREATE, 0, (LONG)&mcs);
00230 //*/
00231 
00232 /* Another way to create a child window is to use CreateWindowEx and set the extended
00233 windows style  to WS_EX_MDICHILD. I prefer this method as it will allow each child to be created in
00234 seperate threads in the future. */
00235 
00236 //*
00237                     CREATESTRUCT cs;
00238                     ZeroMemory(&cs, sizeof(CREATESTRUCT));
00239 
00240                     hChild = CreateWindowEx(
00241                     WS_EX_MDICHILD,
00242                     g_szChildClassName,
00243                     szWindowTitle,
00244                     WS_CHILD | WS_VISIBLE | WS_OVERLAPPEDWINDOW,
00245                     CW_USEDEFAULT,
00246                     CW_USEDEFAULT,
00247                     CW_USEDEFAULT,
00248                     CW_USEDEFAULT,
00249                     g_hMDIClient,
00250                     NULL,
00251                     g_hInst,
00252                     &cs
00253                     );
00254 //*/
00255                     if(!hChild)
00256                     {
00257                         MessageBox(NULL, "Child creation failed.", "Error",
00258                         MB_ICONEXCLAMATION | MB_OK);
00259                     }
00260 
00261                     g_child[g_iNumChild - 1].hWnd = hChild;         // Set child windows handle
00262                     g_child[g_iNumChild - 1].hDC = GetDC(hChild);   // Set child windows device context
00263 
00264                     PIXELFORMATDESCRIPTOR pfd;
00265                     ZeroMemory(&pfd, sizeof(pfd));
00266                     pfd.nSize = sizeof(pfd);
00267                     pfd.nVersion = 1;
00268                     pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
00269                     pfd.iPixelType = PFD_TYPE_RGBA;
00270                     pfd.cColorBits = 24;
00271                     pfd.cDepthBits = 16;
00272                     pfd.iLayerType = PFD_MAIN_PLANE;
00273                     int iFormat = ChoosePixelFormat(g_child[g_iNumChild - 1].hDC, &pfd);
00274                     SetPixelFormat(g_child[g_iNumChild - 1].hDC, iFormat, &pfd);               // Set pixel format for this child
00275 
00276                     g_child[g_iNumChild - 1].hRC = wglCreateContext(g_child[g_iNumChild - 1].hDC);  // Set childs rendering context
00277                     wglMakeCurrent(g_child[g_iNumChild - 1].hDC, g_child[g_iNumChild - 1].hRC);     // Make this child the current DC and RC
00278                     InitGL();                                                             // Initialize the rendering defaults for this child
00279                 }
00280                 break;
00281 
00282                 case CM_WINDOW_TILEHORZ:
00283                     PostMessage(g_hMDIClient, WM_MDITILE, MDITILE_HORIZONTAL, 0);
00284                 break;
00285 
00286                 case CM_WINDOW_TILEVERT:
00287                     PostMessage(g_hMDIClient, WM_MDITILE, MDITILE_VERTICAL, 0);
00288                 break;
00289 
00290                 case CM_WINDOW_CASCADE:
00291                     PostMessage(g_hMDIClient, WM_MDICASCADE, 0, 0);
00292                 break;
00293 
00294                 case CM_WINDOW_ARRANGE:
00295                     PostMessage(g_hMDIClient, WM_MDIICONARRANGE, 0, 0);
00296                 break;
00297 
00298                 default:
00299                 {
00300                     if(LOWORD(wParam) >= ID_MDI_FIRSTCHILD)
00301                     {
00302                         DefFrameProc(hWnd, g_hMDIClient, uMessage, wParam, lParam);
00303                     }
00304                     else
00305                     {
00306                         HWND hChild;
00307                         hChild = (HWND)SendMessage(g_hMDIClient, WM_MDIGETACTIVE, 0, 0);
00308                         if(hChild)
00309                         {
00310                             SendMessage(hChild, WM_COMMAND, wParam, lParam);
00311                         }
00312                     }
00313                 }
00314             }
00315         }
00316         break;
00317 
00318         case WM_CLOSE:
00319         {
00320             int iLoop;
00321             if(g_iNumChild)             // If there are any children
00322             {
00323                 for(iLoop = 0; iLoop < g_iNumChild; iLoop++)     // Send all children the WM_CLOSE to free up their DC and RC
00324                 {
00325                     SendMessage(g_child[iLoop].hWnd, WM_CLOSE, 0, 0);
00326                 }
00327             }
00328             delete[] g_child;             // Delete the array of children
00329             DestroyWindow(hWnd);
00330         }
00331         break;
00332 
00333         case WM_DESTROY:
00334             PostQuitMessage(0);
00335         break;
00336 
00337         default:
00338             return DefFrameProc(hWnd, g_hMDIClient, uMessage, wParam, lParam);
00339     }
00340     return 0;
00341 }
00342 
00343 LRESULT CALLBACK MDIChildWndProc(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
00344 {
00345     switch(uMessage)
00346     {
00347         case WM_LBUTTONDOWN:
00348             g_bMouseDrag = 1;                // Set mouse flag
00349             g_iMouseLastX = LOWORD(lParam);  // Get mouse position
00350             g_iMouseLastY = HIWORD(lParam);
00351             SetCapture(hWnd);             // Capture the mouse
00352         break;
00353 
00354         case WM_MOUSEMOVE:
00355             if(g_bMouseDrag)                  // If mouse flag set
00356             {
00357                 g_iMouseDeltaX = LOWORD(lParam) - g_iMouseLastX;   // Get mouse deltas
00358                 g_iMouseDeltaY = HIWORD(lParam) - g_iMouseLastY;
00359                 g_iMouseLastX = LOWORD(lParam);                 // Get new mouse position
00360                 g_iMouseLastY = HIWORD(lParam);
00361             }
00362         break;
00363 
00364         case WM_LBUTTONUP:         // If left button is released
00365             g_bMouseDrag = 0;         // Clear mouse flag
00366             ReleaseCapture();      // Release the mouse capture
00367         break;
00368 
00369 /*
00370         //This msg isn't posted if the mouse is captured
00371         case WM_NCMOUSEMOVE:
00372         {
00373             POINTS pts;
00374             if(g_bMouseDrag)
00375             {
00376                 pts = MAKEPOINTS(lParam);
00377                 g_iMouseDeltaX = pts.x - g_iMouseLastX;
00378                 g_iMouseDeltaY = pts.y - g_iMouseLastY;
00379                 g_iMouseLastX = pts.x;
00380                 g_iMouseLastY = pts.y;
00381             }
00382         }
00383         break;
00384 //*/
00385 
00386 /* The following code paints the child window when necessary but isn't needed as we
00387 repaint all of them each frame. */
00388 
00389 /*
00390         case WM_PAINT:
00391         {
00392             int iThisChild;
00393             PAINTSTRUCT ps;
00394             BeginPaint(hWnd, &ps);
00395             iThisChild = GetDlgCtrlID(hWnd) - ID_MDI_FIRSTCHILD;
00396             wglMakeCurrent(g_child[iThisChild].hDC, g_child[iThisChild].hRC);
00397             GetClientRect(hWnd, &g_rectChild);
00398             if(g_rectChild.right > 0 && g_rectChild.bottom > 0)
00399                 SetProjection(g_rectChild.right, g_rectChild.bottom);
00400             DrawGLScene();
00401             glFlush();
00402             SwapBuffers(hDC);
00403             EndPaint(hWnd, &ps);
00404         }
00405         break;
00406 //*/
00407         case WM_CLOSE:
00408             g_iNumChild--;                       // Decrement the number of child windows
00409             if(g_iNumChild == 0)                 // If this is the last child window then just free the DC and RC
00410             {
00411                 wglMakeCurrent( NULL, NULL );
00412                 ReleaseDC(g_child[0].hWnd, g_child[0].hDC);
00413                 wglDeleteContext(g_child[0].hRC);
00414             }
00415             else
00416             {
00417                 int iLoop;
00418                 int iThisChild;
00419                 char szWindowTitle[20];
00420                 iThisChild = GetDlgCtrlID(hWnd) - ID_MDI_FIRSTCHILD;
00421                 ReleaseDC(g_child[iThisChild].hWnd, g_child[iThisChild].hDC);    // Free this childs DC and RC
00422                 wglDeleteContext(g_child[iThisChild].hRC);
00423                 if(iThisChild != g_iNumChild)                  // If this child isn't the last in the array of children
00424                 {
00425                     for (iLoop = iThisChild; iLoop < (g_iNumChild); iLoop++)   // Loop from this child to the end of the array
00426                     {
00427                         g_child[iLoop] = g_child[iLoop + 1];       // Shift the children forward in the array
00428                         sprintf(szWindowTitle, "%d", iLoop);
00429                         SetWindowText(g_child[iLoop].hWnd, szWindowTitle);  // Renumber the children
00430                     }
00431                 }
00432             }
00433         break;
00434 
00435         case WM_MDIACTIVATE:
00436         {
00437             HMENU hMenu, hFileMenu;
00438             UINT uEnableFlag;
00439 
00440             hMenu = GetMenu(g_hMainWindow);
00441             if(hWnd == (HWND)lParam)       //being activated
00442             {
00443                 uEnableFlag = MF_ENABLED;
00444             }
00445             else
00446             {
00447                 uEnableFlag = MF_GRAYED;    //being de-activated
00448             }
00449             EnableMenuItem(hMenu, 1, MF_BYPOSITION | uEnableFlag);
00450             EnableMenuItem(hMenu, 2, MF_BYPOSITION | uEnableFlag);
00451 
00452             hFileMenu = GetSubMenu(hMenu, 0);
00453             EnableMenuItem(hFileMenu, CM_FILE_SAVE, MF_BYCOMMAND | uEnableFlag);
00454             EnableMenuItem(hFileMenu, CM_FILE_SAVEAS, MF_BYCOMMAND | uEnableFlag);
00455 
00456             DrawMenuBar(g_hMainWindow);
00457         }
00458         break;
00459 
00460         case WM_COMMAND:
00461             switch(LOWORD(wParam))
00462             {
00463 //              case CM_FILE_SAVE: etc
00464             }
00465         return 0;
00466     }
00467     return DefMDIChildProc(hWnd, uMessage, wParam, lParam);
00468 }
00469 
00470 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int nCmdShow)
00471 {
00472     MSG Msg;
00473     WNDCLASSEX wc;
00474     g_hInst = hInstance;
00475 
00476     // Create an OpenGL compatible window class
00477     wc.cbSize = sizeof(WNDCLASSEX);
00478     wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC | CS_DBLCLKS;
00479     wc.lpfnWndProc = (WNDPROC)MDIChildWndProc;
00480     wc.cbClsExtra = 0;
00481     wc.cbWndExtra = 0;
00482     wc.hInstance = hInstance;
00483     wc.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_CHILDICON));
00484     wc.hCursor = LoadCursor(NULL, IDC_ARROW);
00485     wc.hbrBackground = (HBRUSH)(COLOR_3DSHADOW+1);    // Background color (Only seen if OGL fails)
00486     wc.lpszMenuName = NULL;
00487     wc.lpszClassName = g_szChildClassName;
00488     wc.hIconSm = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_CHILDICON));
00489 
00490     if(!RegisterClassEx(&wc))
00491     {
00492         MessageBox(NULL,"Failed to register the child window.","Error",MB_OK|MB_ICONEXCLAMATION);
00493         return FALSE;
00494     }
00495 
00496     // Create the frame window
00497     wc.cbSize = sizeof(WNDCLASSEX);
00498     wc.style = CS_HREDRAW | CS_VREDRAW;
00499     wc.lpfnWndProc = (WNDPROC)WndProc;
00500     wc.cbClsExtra = 0;
00501     wc.cbWndExtra = 0;
00502     wc.hInstance = hInstance;
00503     wc.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_MYICON));
00504     wc.hCursor = LoadCursor(NULL, IDC_ARROW);
00505     wc.hbrBackground = (HBRUSH)(COLOR_3DSHADOW+1);
00506     wc.lpszMenuName = "MAIN";
00507     wc.lpszClassName = g_szMainClassName;
00508     wc.hIconSm = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_MYICON));
00509 
00510     if(!RegisterClassEx(&wc))
00511     {
00512         MessageBox(0, "Failed to register the main window.", "Error",
00513         MB_ICONEXCLAMATION | MB_OK);
00514         return -1;
00515     }
00516 
00517     g_hMainWindow = CreateWindowEx(WS_EX_LEFT, g_szMainClassName, "Al's OpenGL MDI Example",
00518     WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
00519     CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
00520     NULL, NULL, hInstance, NULL);
00521 
00522     if(g_hMainWindow == NULL)
00523     {
00524         MessageBox(0, "Failed to create window.", "ERROR", MB_ICONEXCLAMATION | MB_OK);
00525         return -1;
00526     }
00527 
00528     ShowWindow(g_hMainWindow, nCmdShow);
00529     UpdateWindow(g_hMainWindow);
00530 
00531     int iLoop;
00532     while(GetMessage(&Msg, NULL, 0, 0))
00533     {
00534         if(!TranslateMDISysAccel(g_hMDIClient, &Msg))
00535         {
00536             TranslateMessage(&Msg);
00537             DispatchMessage(&Msg);
00538         }
00539 
00540         if(g_iNumChild)                             // If we have some children
00541         {
00542             for(iLoop = 0; iLoop < g_iNumChild; iLoop++)   // Loop through all children
00543             {
00544                 if(!IsIconic(g_child[iLoop].hWnd))   // If child isn't iconic (minimized)
00545                 {
00546                     wglMakeCurrent(g_child[iLoop].hDC, g_child[iLoop].hRC);  // Make them the current DC and RC
00547                     GetClientRect(g_child[iLoop].hWnd, &g_rectChild);
00548                     if(g_rectChild.right > 0 && g_rectChild.bottom > 0)
00549                         SetProjection(g_rectChild.right, g_rectChild.bottom);        // Set the childs projection matrix
00550                     DrawGLScene();
00551                     glFlush();
00552                     SwapBuffers(g_child[iLoop].hDC);
00553                 }
00554             }
00555         }
00556     }
00557     return Msg.wParam;
00558 }
00559 
00560 /*
00561 
00562 In this example I use the same draw routine for each child window. By adding a integer type
00563 index to the child structure a different draw routine could be used based on the index. This
00564 could then also be used to choose the type of child class to create and which child window
00565 process to use.
00566 
00567 btw
00568 The strange comment style you see in the code is a handy way to temporarily comment out blocks of
00569 code. By removing the first forward slash the code is disabled and to enable just add the first
00570 slash again. This saves having to run up and down the code adding and removing the first and last
00571 comment delimiters.
00572 
00573 ex.
00574 
00575 //*
00576 working code
00577 //*/
00578 
00579 /*
00580 disabled code
00581 //*/
00582 
00583                                          
00584 
00585 

Generated on Fri Dec 23 05:19:18 2005 for OpenGL MDI by doxygen1.2.15