00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
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>
00020 #include "resource.rh"
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;
00031
00032 float g_fCubeRotationX, g_fCubeRotationY;
00033
00034 bool g_bMouseDrag = 0;
00035 int g_iMouseLastX;
00036 int g_iMouseLastY;
00037 int g_iMouseDeltaX;
00038 int g_iMouseDeltaY;
00039
00040 typedef struct CHILD
00041 {
00042 HDC hDC;
00043 HGLRC hRC;
00044 HWND hWnd;
00045 } CHILD;
00046
00047 int g_iMaxChild = 50;
00048 int g_iNumChild = 0;
00049 CHILD* g_child = new CHILD[g_iMaxChild];
00050
00051
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
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)
00104 {
00105 g_fCubeRotationX += (float)g_iMouseDeltaY * 0.5;
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
00117 glColor3f(1.0,0.0,0.0);
00118 glVertex3f(-1.0, -1.0, 1.0);
00119 glColor3f(0.0,1.0,0.0);
00120 glVertex3f( 1.0, -1.0, 1.0);
00121 glColor3f(0.0,0.0,1.0);
00122 glVertex3f( 1.0, 1.0, 1.0);
00123 glColor3f(1.0,1.0,0.0);
00124 glVertex3f(-1.0, 1.0, 1.0);
00125
00126 glColor3f(0.0,0.0,1.0);
00127 glVertex3f(-1.0, -1.0, -1.0);
00128 glColor3f(0.0,1.0,0.0);
00129 glVertex3f(-1.0, 1.0, -1.0);
00130 glColor3f(1.0,0.0,0.0);
00131 glVertex3f( 1.0, 1.0, -1.0);
00132 glColor3f(1.0,1.0,0.0);
00133 glVertex3f( 1.0, -1.0, -1.0);
00134
00135 glColor3f(0.0,1.0,0.0);
00136 glVertex3f(-1.0, 1.0, -1.0);
00137 glColor3f(1.0,1.0,0.0);
00138 glVertex3f(-1.0, 1.0, 1.0);
00139 glColor3f(0.0,0.0,1.0);
00140 glVertex3f( 1.0, 1.0, 1.0);
00141 glColor3f(1.0,0.0,0.0);
00142 glVertex3f( 1.0, 1.0, -1.0);
00143
00144 glColor3f(0.0,0.0,1.0);
00145 glVertex3f(-1.0, -1.0, -1.0);
00146 glColor3f(1.0,1.0,0.0);
00147 glVertex3f( 1.0, -1.0, -1.0);
00148 glColor3f(0.0,1.0,0.0);
00149 glVertex3f( 1.0, -1.0, 1.0);
00150 glColor3f(1.0,0.0,0.0);
00151 glVertex3f(-1.0, -1.0, 1.0);
00152
00153 glColor3f(1.0,1.0,0.0);
00154 glVertex3f( 1.0, -1.0, -1.0);
00155 glColor3f(1.0,0.0,0.0);
00156 glVertex3f( 1.0, 1.0, -1.0);
00157 glColor3f(0.0,0.0,1.0);
00158 glVertex3f( 1.0, 1.0, 1.0);
00159 glColor3f(0.0,1.0,0.0);
00160 glVertex3f( 1.0, -1.0, 1.0);
00161
00162 glColor3f(0.0,0.0,1.0);
00163 glVertex3f(-1.0, -1.0, -1.0);
00164 glColor3f(1.0,0.0,0.0);
00165 glVertex3f(-1.0, -1.0, 1.0);
00166 glColor3f(1.0,1.0,0.0);
00167 glVertex3f(-1.0, 1.0, 1.0);
00168 glColor3f(0.0,1.0,0.0);
00169 glVertex3f(-1.0, 1.0, -1.0);
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
00184 ccs.hWindowMenu = NULL;
00185
00186
00187 ccs.idFirstChild = ID_MDI_FIRSTCHILD;
00188
00189 g_hMDIClient = CreateWindowEx(WS_EX_CLIENTEDGE, "MDICLIENT", NULL,
00190 WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
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)
00210 g_iNumChild++;
00211 else
00212 break;
00213
00214 char szWindowTitle[20];
00215 sprintf(szWindowTitle, "%d", g_iNumChild - 1);
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
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;
00262 g_child[g_iNumChild - 1].hDC = GetDC(hChild);
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);
00275
00276 g_child[g_iNumChild - 1].hRC = wglCreateContext(g_child[g_iNumChild - 1].hDC);
00277 wglMakeCurrent(g_child[g_iNumChild - 1].hDC, g_child[g_iNumChild - 1].hRC);
00278 InitGL();
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)
00322 {
00323 for(iLoop = 0; iLoop < g_iNumChild; iLoop++)
00324 {
00325 SendMessage(g_child[iLoop].hWnd, WM_CLOSE, 0, 0);
00326 }
00327 }
00328 delete[] g_child;
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;
00349 g_iMouseLastX = LOWORD(lParam);
00350 g_iMouseLastY = HIWORD(lParam);
00351 SetCapture(hWnd);
00352 break;
00353
00354 case WM_MOUSEMOVE:
00355 if(g_bMouseDrag)
00356 {
00357 g_iMouseDeltaX = LOWORD(lParam) - g_iMouseLastX;
00358 g_iMouseDeltaY = HIWORD(lParam) - g_iMouseLastY;
00359 g_iMouseLastX = LOWORD(lParam);
00360 g_iMouseLastY = HIWORD(lParam);
00361 }
00362 break;
00363
00364 case WM_LBUTTONUP:
00365 g_bMouseDrag = 0;
00366 ReleaseCapture();
00367 break;
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407 case WM_CLOSE:
00408 g_iNumChild--;
00409 if(g_iNumChild == 0)
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);
00422 wglDeleteContext(g_child[iThisChild].hRC);
00423 if(iThisChild != g_iNumChild)
00424 {
00425 for (iLoop = iThisChild; iLoop < (g_iNumChild); iLoop++)
00426 {
00427 g_child[iLoop] = g_child[iLoop + 1];
00428 sprintf(szWindowTitle, "%d", iLoop);
00429 SetWindowText(g_child[iLoop].hWnd, szWindowTitle);
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)
00442 {
00443 uEnableFlag = MF_ENABLED;
00444 }
00445 else
00446 {
00447 uEnableFlag = MF_GRAYED;
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
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
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);
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
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)
00541 {
00542 for(iLoop = 0; iLoop < g_iNumChild; iLoop++)
00543 {
00544 if(!IsIconic(g_child[iLoop].hWnd))
00545 {
00546 wglMakeCurrent(g_child[iLoop].hDC, g_child[iLoop].hRC);
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);
00550 DrawGLScene();
00551 glFlush();
00552 SwapBuffers(g_child[iLoop].hDC);
00553 }
00554 }
00555 }
00556 }
00557 return Msg.wParam;
00558 }
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585