//*************************************************************** // ステートの終了処理 //*************************************************************** void CScene::UninitAll(void) { //ポインタ宣言 CScene *pScene; for(int nCount = 0 ; nCount < MAX_LIST - 1 ; nCount++) { pScene = m_apTop[nCount]; //全てのリストを解放するまで繰り返す while(pScene) { //次のオブジェクトへのポインタを保存 CScene *pSceneNext = pScene->m_pNext; //更新 pScene->Release(); //次のオブジェクトを代入 pScene = pSceneNext; } } }
//*************************************************************** // 全てのオブジェクトを破棄する //*************************************************************** void CScene::ReleaseAll(void) { //ポインタ宣言 CScene *pScene; for(int nCount = 0 ; nCount < MAX_LIST ; nCount++) { pScene = m_apTop[nCount]; //全てのリストを解放するまで繰り返す while(pScene) { //次のオブジェクトへのポインタを保存 CScene *pSceneNext = pScene->m_pNext; //更新 pScene->Release(); //次のオブジェクトを代入 pScene = pSceneNext; } } for(int nCount = 0 ; nCount < MAX_LIST ; nCount++) { pScene = m_apTop[nCount]; while(pScene) { //次のオブジェクトへのポインタを保存 CScene *pSceneNext = pScene->m_pNext; //死亡フラグが成立している場合 if(pScene->m_bDelete) { //リストの先頭の場合 if(pScene == m_apTop[pScene->m_nPriority]) { //先頭にリリース対象の次のアドレスを入れる m_apTop[pScene->m_nPriority] = pScene->m_pNext; //リストの残りが複数の時 if(pScene->m_pNext != NULL) { pScene->m_pNext->m_pPrev = NULL; } } //リストの最後の場合 else if(pScene == m_apCur[pScene->m_nPriority]) { m_apCur[pScene->m_nPriority] = pScene->m_pPrev; pScene->m_pPrev->m_pNext = NULL; } //それ以外 else { pScene->m_pPrev->m_pNext = pScene->m_pNext; pScene->m_pNext->m_pPrev = pScene->m_pPrev; } //解放処理 pScene->Uninit(); delete pScene; } //次のオブジェクトを代入 pScene = pSceneNext; } } }
LRESULT CALLBACK winproc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { MENUITEMINFO mii; HMENU hMenu = GetMenu(hWnd); OPENFILENAME ofn; char path[MAX_PATH]; HCURSOR hcur; switch (uMsg) { case WM_COMMAND: switch (LOWORD(wParam)) { case ID_MENU_FILE_OPEN: // wczytywanie pliku memset(&ofn, 0, sizeof(ofn)); memset(path, 0, MAX_PATH); ofn.lStructSize = sizeof(ofn); ofn.hwndOwner = hWnd; ofn.lpstrFile = path; ofn.nMaxFile = MAX_PATH; ofn.lpstrFilter = "3D Studio R4 (*.3ds)\0*.3ds\0\0"; ofn.lpstrTitle = NULL; ofn.Flags = OFN_EXPLORER | OFN_HIDEREADONLY | OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST; ofn.lpstrInitialDir = ".\\"; if (::GetOpenFileName(&ofn)) { CLoader3DS load_3ds(g_Scene); hcur = ::SetCursor(LoadCursor(NULL, IDC_WAIT)); load_3ds.Load(path); if (!g_Scene.SetActiveCamera("Camera01")) g_Scene.SetFirstCamera(); ::SetCursor(hcur); /// ustaw odpowiednio menu systemowe: ::ZeroMemory(&mii, sizeof(mii)); mii.cbSize = sizeof(mii); mii.fMask = MIIM_STATE; mii.fState = MFS_ENABLED; ::SetMenuItemInfo(hMenu, ID_MENU_VIEW_ANIMATION, FALSE, &mii); ::SetMenuItemInfo(hMenu, ID_MENU_FILE_CLOSE, FALSE, &mii); /// dopisz do titlebar'u nazwê otwartego pliku: char *foo = new char [strlen(g_lpszNoFileProgName) + strlen(path + ofn.nFileOffset) + 4]; strcpy(foo, g_lpszNoFileProgName); strcat(foo, " - "); strcat(foo, path + ofn.nFileOffset); DELETE_ARRAY(g_lpszProgName); g_lpszProgName = foo; ::SetWindowText(hWnd, g_lpszProgName); /// tutaj poœrednio ustawienie odpowiednie nazwu dla okienka z animacj¹: DELETE_ARRAY(g_WindowParams.szTitle); g_WindowParams.szTitle = strdup(path + ofn.nFileOffset); } break; case ID_MENU_FILE_CLOSE: { g_Scene.Release(); /// wygaœ odpowiednie opcje w menu: ZeroMemory(&mii, sizeof(mii)); mii.cbSize = sizeof(mii); mii.fMask = MIIM_STATE; mii.fState = MFS_GRAYED; ::SetMenuItemInfo(hMenu, ID_MENU_VIEW_ANIMATION, FALSE, &mii); ::SetMenuItemInfo(hMenu, ID_MENU_FILE_CLOSE, FALSE, &mii); /// umieœæ w titlebarze sam¹ nazwê aplikacji: DELETE_ARRAY(g_lpszProgName); g_lpszProgName = strdup(g_lpszNoFileProgName); ::SetWindowText(hWnd, g_lpszProgName); } break; case ID_MENU_FILE_EXIT: g_Scene.Release(); ::SendMessage(hWnd, WM_CLOSE, 0, 0); break; case ID_MENU_VIEW_ANIMATION: { if (!DialogBox(g_hInstance, MAKEINTRESOURCE(IDD_DIALOG1), MainhWnd, (DLGPROC)SetupDlgProc)) return 0; if (g_WindowParams.szTitle == NULL) g_WindowParams.szTitle = strdup("test"); g_WindowParams.lpfnProc = MainWndProc; g_WindowParams.hInst = g_hInstance; try { if (!g_Scene.SetActiveCamera("Camera01")) g_Scene.SetFirstCamera(); ::EnableWindow(hWnd, FALSE); InitOpenGL(g_WindowParams, hWnd); g_Scene.SetScreenAspect((float)g_WindowParams.nWidth/g_WindowParams.nHeight); //g_Scene.PrintInfo(LOG); g_Scene.PrepareAnimation(); g_Scene.InitTextures(); g_Scene.InitDisplayLists(); PlayAnimation(); g_Scene.DeinitDisplayLists(); g_Scene.DeinitTextures(); DeInitOpenGL(g_WindowParams); ::EnableWindow(hWnd, TRUE); ::SetActiveWindow(hWnd); } catch (CException ex) { if (ex.type == CException::EXCEPTION_STRING) { static char *error_msg = strdup(ex.error_string); fatal_error(error_msg); } else { char buffer[10]; _itoa(ex.error, buffer, 10); fatal_error(buffer); } } catch (...) { fatal_error("Unknown error!"); } } break; case ID_MENU_HELP_ABOUT: ::DialogBox(g_hInstance, MAKEINTRESOURCE(IDD_ABOUTBOX), MainhWnd, (DLGPROC)AboutDlgProc); break; default: break; } break; case WM_DESTROY: ::PostQuitMessage(0); break; case WM_CREATE: ZeroMemory(&mii, sizeof(mii)); mii.cbSize = sizeof(mii); mii.fMask = MIIM_STATE; mii.fState = MFS_GRAYED; ::SetMenuItemInfo(hMenu, ID_MENU_VIEW_ANIMATION, FALSE, &mii); ::SetMenuItemInfo(hMenu, ID_MENU_FILE_CLOSE, FALSE, &mii); break; default: return ::DefWindowProc(hWnd, uMsg, wParam, lParam); break; } return 0; }