int CheckAndSave() { //Get the filename if we don't have one if (strlen(cSaveName)<=1) GetSaveFile(cWindow.GetHandle()); //Save the meal & make sure it saved bool okay = 0; while(!okay) { if (!SaveMeal()) { switch(MessageBox(cWindow.GetHandle(), "Failed to save the file, do you wish to try again?", "Error", MB_YESNOCANCEL | MB_ICONERROR)) { case IDYES: GetSaveFile(cWindow.GetHandle()); break; case IDNO: return(0); break; case IDCANCEL: return(-1); break; default: break; } } else { okay = 1; } } return(1); }
// Run() void Run() { HDC backDC = backBuf.GetDC(); // 塗りつぶし RECT rc; rc.left = rc.top = 0; rc.right = backBuf.GetWidth(); rc.bottom = backBuf.GetHeight(); FillRect(backDC, &rc, (HBRUSH)GetStockObject(BLACK_BRUSH)); // 図形描画 HPEN hPenOld, hPen; hPen = CreatePen(PS_SOLID, 0, RGB(0xff, 0, 0)); hPenOld = (HPEN)SelectObject(backDC, hPen); Vector2 r[4]; Vector2 trans(backBuf.GetWidth()>>1, backBuf.GetHeight()>>1); Matrix2 rot, sc; static int t = 0; t += 5; Matrix2Rotation(rot, t/180.0f*3.14); Matrix2Scaling(sc, 2, 2); for (int i = 0; i < 4; ++i) { r[i] = rect[i] * sc * rot; r[i] = r[i] + trans; } /*Vector3 r[4]; Vector3 trans(backBuf.GetWidth()>>1, backBuf.GetHeight()>>1, 0); Matrix3 rot, sc; static int t = 0; t += 5; Matrix3RotationHV(rot, t/180.0f*3.14); for (int i = 0; i < 4; ++i) { r[i].x = rect[i].x; r[i].y = rect[i].y; r[i] = r[i] * rot; r[i] = r[i] + trans; }*/ for (int i = 0; i < 4; ++i) { MoveToEx(backDC, r[i].x, r[i].y, NULL); LineTo(backDC, r[(i+1)&3].x, r[(i+1)&3].y); } SelectObject(backDC, hPenOld); DeleteObject(hPen); // フリップ HDC hDC = GetDC(wnd.GetHandle()); BitBlt(hDC, 0, 0, rc.right, rc.bottom, backDC, 0, 0, SRCCOPY); ReleaseDC(wnd.GetHandle(), hDC); Sleep(100); }
void EventImpl::SetMousePosition(int x, int y, const Window& relativeTo) { HWND handle = reinterpret_cast<HWND>(relativeTo.GetHandle()); if (handle) { POINT pos = {x, y}; ClientToScreen(handle, &pos); SetCursorPos(pos.x, pos.y); } else NazaraError("Invalid window handle"); }
bool OpenSaveFileDialog::Run(const std::wstring& window_title, const Window& winOwner, bool runSave) { // the filters std::vector<wchar_t> buff; std::vector<std::wstring>::iterator filters_iter = _filters.begin(); while (filters_iter != _filters.end()) { buff.insert(buff.end(), filters_iter->begin(), filters_iter->end()); buff.push_back(L'\0'); ++filters_iter; } buff.push_back(L'\0'); buff.push_back(L'\0'); _ofname.lpstrFilter = &buff.front(); _ofname.nFilterIndex = 1; // the default file name buffer, also receives the selected file name wchar_t file_name[MAX_PATH]; wcscpy_s(file_name, MAX_PATH, _default_file_name.c_str()); _ofname.lpstrFile = file_name; _ofname.nMaxFile = MAX_PATH - 1; _ofname.lpstrInitialDir = _default_path.c_str(); if (!window_title.empty()) _ofname.lpstrTitle = window_title.c_str(); else _ofname.lpstrTitle = NULL; _ofname.hInstance = GetModuleHandle(NULL); _ofname.hwndOwner = winOwner.GetHandle(); _ofname.Flags = runSave ? OFN_OVERWRITEPROMPT : 0; BOOL result; if (runSave) result = GetSaveFileName(&_ofname); else result = GetOpenFileName(&_ofname); if (result != 0) { _selected_full_file_name = file_name; _selected_file_name = file_name + _ofname.nFileOffset; } return result != 0; }
Engine* EngineFactory::Create(const Configuration& /*config*/) { ClockFactory* clockFactory = new ClockFactory(); Time* time = new Time(clockFactory); Window* window = new Window("Eden engine", 1900, 960); ActionKeyMap actionKeys; actionKeys["move_forward"] = 'W'; actionKeys["move_backward"] = 'S'; actionKeys["strafe_right"] = 'D'; actionKeys["strafe_left"] = 'A'; actionKeys["move_up"] = VK_SHIFT; actionKeys["move_down"] = VK_CONTROL; actionKeys["main_menu"] = VK_OEM_3; actionKeys["quit"] = VK_ESCAPE; InputProcessor* inputProcessor = new InputProcessor(actionKeys); DisplayParams displayParams; displayParams.width = 1900; displayParams.height = 960; displayParams.vSync = true; displayParams.fullScreen = false; LowLevelGraphics* lowLevelGraphics = new LowLevelGraphics(window->GetHandle(), displayParams); IGeometryFileReader* geometryFileReader = new AssimpFileReader(); EffectRepository* effectRepository = new EffectRepository(lowLevelGraphics, "..\\..\\assets", "effects"); TextureFactory* textureFactory = new TextureFactory(lowLevelGraphics); FontFactory* fontFactory = new FontFactory(lowLevelGraphics); ResourceManager* resourceManager = new ResourceManager(lowLevelGraphics, geometryFileReader, effectRepository, textureFactory, fontFactory); IEntityReader* entityReader = new PrefabEntityReader(); EntityImporter* entityImporter = new EntityImporter(entityReader, resourceManager); IEntityWriter* entityWriter = new PrefabEntityWriter(); EntityExporter* entityExporter = new EntityExporter(entityWriter); Scene* scene = new Scene(entityImporter, entityExporter); RenderingSettings renderingSettings; renderingSettings.width = displayParams.width; renderingSettings.height = displayParams.height; renderingSettings.vSync = displayParams.vSync; renderingSettings.fullScreen = displayParams.fullScreen; renderingSettings.debugRenderingEnabled = true; renderingSettings.debugLightEnabled = true; RenderManager* renderManager = new RenderManager(lowLevelGraphics, resourceManager, renderingSettings); Engine* engine = new Engine(time, window, inputProcessor, resourceManager, renderManager, scene); return engine; }
Error::E RenderSystem::CreateSwapChain(const Window &window) { assert(_device); _swapDesc = kDefaultSwapDesc; _swapDesc.SampleDesc.Count = 4; _swapDesc.SampleDesc.Quality = _msaaQualityLevel - 1; _swapDesc.OutputWindow = window.GetHandle(); _swapDesc.BufferDesc.Width = window.GetWidth(); _swapDesc.BufferDesc.Height = window.GetHeight(); IDXGIFactory *factory = FactoryFromDevice(_device); DEBUG_HR(factory->CreateSwapChain(_device, &_swapDesc, &_swapChain)); ReleaseCom(factory); return Error::OK; }
Vector2i EventImpl::GetMousePosition(const Window& relativeTo) { HWND handle = reinterpret_cast<HWND>(relativeTo.GetHandle()); if (handle) { POINT pos; GetCursorPos(&pos); ScreenToClient(handle, &pos); return Vector2i(pos.x, pos.y); } else { NazaraError("Invalid window handle"); // Attention que (-1, -1) est une position tout à fait valide et ne doit pas servir de test return Vector2i(-1, -1); } }
SaveFileDialog::SaveFileDialog(Window& parent, const tstring& filter) { OPENFILENAME ofn = {0}; TCHAR FileName[MAX_PATH] = WIDEN(""); TCHAR leFilter[MAX_PATH] = WIDEN(""); unsigned int i = 0; for(const auto& letter : filter) leFilter[i++] = letter; ofn.lStructSize = sizeof(ofn); ofn.hwndOwner = parent.GetHandle(); ofn.lpstrFilter = leFilter; ofn.lpstrFile = FileName; ofn.lpstrInitialDir = WIDEN("."); ofn.nMaxFile = MAX_PATH; ofn.Flags = OFN_EXPLORER | OFN_PATHMUSTEXIST | OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT; if(GetSaveFileName(&ofn)) this->retStr = tstring(FileName); }
OpenFileDialog::OpenFileDialog(Window& parent, const tstring& filter) { OPENFILENAME ofn = {0}; TCHAR FileName[MAX_PATH] = WIDEN(""); TCHAR leFilter[MAX_PATH] = WIDEN(""); unsigned int i = 0; for(const auto& letter : filter) leFilter[i++] = letter; ofn.lStructSize = sizeof(OPENFILENAME); ofn.hwndOwner = parent.GetHandle(); ofn.lpstrFilter = leFilter; ofn.lpstrFile = FileName; ofn.nMaxFile = MAX_PATH; ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST; ofn.nFileOffset = 0; ofn.nFileExtension = 0; ofn.nFilterIndex = 0; if(GetOpenFileName(&ofn)) this->retStr = tstring(FileName); }
int CALLBACK WinMain(HINSTANCE _hInstance, HINSTANCE _hPrevInstance, LPSTR _lpCmdLine, int _nCmdShow) { Window Window; Window.Initialize(_hInstance, _nCmdShow); Window.Create(Platform::Window::eWindow_Mode_Normal, L"FTL Engine", 0, 0, 1024, 768); RendererDLL rendererDLL; Renderer* pRenderer; rendererDLL.Create(&pRenderer); { Graphics::Renderer::Settings Settings; Settings.nWidth = 1024; Settings.nHeight = 768; Settings.nRefreshRate = 0; Settings.nMSAASamples = 1; Settings.nSampleQuality = 0; Settings.nBufferCount = 1; Settings.eDriverMode = Graphics::Renderer::eDriverMode_Hardware; Settings.hOutput = Window.GetHandle(); Settings.bDebugMode = true; pRenderer->Initialize(Settings); pRenderer->Startup(); { // Shaders Graphics::HShader VertexShader = pRenderer->CompileFromFile(L"Source/Shader.hlsl", "VShader", Graphics::Shader::eSHADER_TYPE_VERTEX); Graphics::HShader PixelShader = pRenderer->CompileFromFile(L"Source/Shader.hlsl", "PShader", Graphics::Shader::eSHADER_TYPE_PIXEL); // Vertex Format Graphics::VertexFormat::VertDataPair VertFormat[2] = { { Graphics::VertexFormat::eSEMANTICS_POSITION, Graphics::VertexFormat::eDATASIZES_FLOAT3}, { Graphics::VertexFormat::eSEMANTICS_COLOR, Graphics::VertexFormat::eDATASIZES_FLOAT4}, }; Graphics::HVertexFormat hVertexFormat = pRenderer->CreateVertexFormat(VertFormat, 2); // Vertex Buffer Vertex VertexBuffer[] = { { 0.00f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f}, { 0.45f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, {-0.45f, -0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f}, }; Graphics::HVertexBuffer hVertexBuffer = pRenderer->CreateVertexBuffer(3, &VertexBuffer, hVertexFormat); // Index Buffer uint32 IntexBuffer[] = { 0, 1, 2, }; Graphics::HIndexBuffer hIndexBuffer = pRenderer->CreateIndexBuffer(3, IntexBuffer); // Activate Settings VertexShader->SetShaderActive(); PixelShader->SetShaderActive(); hVertexBuffer->SetBufferActive(); hIndexBuffer->SetBufferActive(); pRenderer->SetPrimitiveTopology(Graphics::Primitive::eTOPOLOGY_TRIANGLELIST); //while(Window.Update()) Window.Update(); { float Color[4] = {0.33f, 0.33f, 0.33f, 1.00f}; pRenderer->ClearBackBuffer(Color); pRenderer->Draw(3, 0, 0); pRenderer->Present(); } Window.Update(); } pRenderer->Shutdown(); } rendererDLL.Release(); return NULL; }
/* Creates an OpenGL 3.2 CORE PROFILE rendering context. Sets itself as the current renderer of the passed 'parent' Window. Not the best way to do it - but it kept the Tutorial code down to a minimum! */ OGLRenderer::OGLRenderer(Window &window) { init = false; HWND windowHandle = window.GetHandle(); // Did We Get A Device Context? if (!(deviceContext=GetDC(windowHandle))) { std::cout << "OGLRenderer::OGLRenderer(): Failed to create window!" << std::endl; return; } //A pixel format descriptor is a struct that tells the Windows OS what type of front / back buffers we want to create etc PIXELFORMATDESCRIPTOR pfd; memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR)); pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR); pfd.nVersion = 1; pfd.dwFlags = PFD_DOUBLEBUFFER | PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW; //It must be double buffered, it must support OGL(!), and it must allow us to draw to it... pfd.iPixelType = PFD_TYPE_RGBA; //We want our front / back buffer to have 4 channels! pfd.cColorBits = 32; //4 channels of 8 bits each! pfd.cDepthBits = 24; //24 bit depth buffer pfd.cStencilBits = 8; //plus an 8 bit stencil buffer pfd.iLayerType = PFD_MAIN_PLANE; GLuint PixelFormat; if (!(PixelFormat=ChoosePixelFormat(deviceContext,&pfd))) { // Did Windows Find A Matching Pixel Format for our PFD? std::cout << "OGLRenderer::OGLRenderer(): Failed to choose a pixel format!" << std::endl; return; } if(!SetPixelFormat(deviceContext,PixelFormat,&pfd)) { // Are We Able To Set The Pixel Format? std::cout << "OGLRenderer::OGLRenderer(): Failed to set a pixel format!" << std::endl; return; } HGLRC tempContext; //We need a temporary OpenGL context to check for OpenGL 3.2 compatibility...stupid!!! if (!(tempContext=wglCreateContext(deviceContext))) { // Are We Able To get the temporary context? std::cout << "OGLRenderer::OGLRenderer(): Cannot create a temporary context!" << std::endl; wglDeleteContext(tempContext); return; } if(!wglMakeCurrent(deviceContext,tempContext)) { // Try To Activate The Rendering Context std::cout << "OGLRenderer::OGLRenderer(): Cannot set temporary context!" << std::endl; wglDeleteContext(tempContext); return; } //Now we have a temporary context, we can find out if we support OGL 3.x char* ver = (char*)glGetString(GL_VERSION); // ver must equal "3.2.0" (or greater!) int major = ver[0] - '0'; //casts the 'correct' major version integer from our version string int minor = ver[2] - '0'; //casts the 'correct' minor version integer from our version string if(major < 3) { //Graphics hardware does not support OGL 3! Erk... std::cout << "OGLRenderer::OGLRenderer(): Device does not support OpenGL 3.x!" << std::endl; wglDeleteContext(tempContext); return; } if(major == 3 && minor < 2) { //Graphics hardware does not support ENOUGH of OGL 3! Erk... std::cout << "OGLRenderer::OGLRenderer(): Device does not support OpenGL 3.2!" << std::endl; wglDeleteContext(tempContext); return; } //We do support OGL 3! Let's set it up... int attribs[] = { WGL_CONTEXT_MAJOR_VERSION_ARB, major, //TODO: Maybe lock this to 3? We might actually get an OpenGL 4.x context... WGL_CONTEXT_MINOR_VERSION_ARB, minor, WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB #ifdef OPENGL_DEBUGGING | WGL_CONTEXT_DEBUG_BIT_ARB #endif //No deprecated stuff!! DIE DIE DIE glBegin!!!! ,WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_CORE_PROFILE_BIT_ARB, //We want everything OpenGL 3.2 provides... 0 //That's enough attributes... }; //Everywhere else in the Renderers, we use function pointers provided by GLEW...but we can't initialise GLEW yet! So we have to use the 'Wiggle' API //to get a pointer to the function that will create our OpenGL 3.2 context... PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC) wglGetProcAddress("wglCreateContextAttribsARB"); renderContext = wglCreateContextAttribsARB(deviceContext,0, attribs); // Check for the context, and try to make it the current rendering context if(!renderContext || !wglMakeCurrent(deviceContext,renderContext)) { std::cout << "OGLRenderer::OGLRenderer(): Cannot set OpenGL 3 context!" << std::endl; //It's all gone wrong! wglDeleteContext(renderContext); wglDeleteContext(tempContext); return; } wglDeleteContext(tempContext); //We don't need the temporary context any more! glewExperimental = GL_TRUE; //This forces GLEW to give us function pointers for everything (gets around GLEW using 'old fashioned' methods //for determining whether a OGL context supports a particular function or not if (glewInit() != GLEW_OK) { //Try to initialise GLEW std::cout << "OGLRenderer::OGLRenderer(): Cannot initialise GLEW!" << std::endl; //It's all gone wrong! return; } //If we get this far, everything's going well! #ifdef OPENGL_DEBUGGING if (major >= 4 && minor >= 0) { glDebugMessageCallback((GLDEBUGPROC)&OGLRenderer::DebugCallback, NULL); glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB); } #endif glClearColor(0.2f,0.2f,0.2f,1.0f); //When we clear the screen, we want it to be dark grey window.RegisterResizeCallback(BasicResizeFunc);//Tell our window about the new renderer! (Which will in turn resize the renderer window to fit...) }
bool RenderContextOpenGLWin32::Initialize(Window& window, const RenderParameters_t& renderParameters) { Logger::GetInstance()->Debug("Initializing OpenGL context"); size_t colorBits, redBits, greenBits, blueBits, depthBits; size_t alphaBits = 0; size_t stencilBits = 0; switch (renderParameters.displayFormat) { case DISPLAY_FORMAT_A1R5G5B5: colorBits = 16; alphaBits = 1; redBits = blueBits = 5; greenBits = 6; break; case DISPLAY_FORMAT_A2R10G10B10: colorBits = 24; alphaBits = 2; redBits = greenBits = blueBits = 10; break; case DISPLAY_FORMAT_A8R8G8B8: colorBits = 24; alphaBits = 8; redBits = greenBits = blueBits = 8; break; case DISPLAY_FORMAT_R5G6B5: colorBits = 16; redBits = blueBits = 5; greenBits = 6; break; case DISPLAY_FORMAT_X1R5G5B5: colorBits = 16; redBits = greenBits = blueBits = 5; break; case DISPLAY_FORMAT_X8R8G8B8: colorBits = 24; redBits = greenBits = blueBits = 8; break; } switch (renderParameters.depthStencilBits) { case DEPTH_STENCIL_BITS_D15S1: depthBits = 15; stencilBits = 1; break; case DEPTH_STENCIL_BITS_D16: depthBits = 16; break; case DEPTH_STENCIL_BITS_D24S8: depthBits = 24; stencilBits = 8; break; case DEPTH_STENCIL_BITS_D24X4S4: depthBits = 24; stencilBits = 4; break; case DEPTH_STENCIL_BITS_D24X8: depthBits = 24; break; case DEPTH_STENCIL_BITS_D32: depthBits = 32; break; } if (!window.IsWindowed()) { // From http://www.falloutsoftware.com/tutorials/gl/gl2.htm DEVMODE dmode; memset(&dmode, 0, sizeof(DEVMODE)); dmode.dmSize=sizeof(DEVMODE); dmode.dmPelsWidth = renderParameters.width; dmode.dmPelsHeight = renderParameters.height; dmode.dmBitsPerPel = (colorBits == 24) ? 32 : colorBits; dmode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT; // Change resolution, if possible if (ChangeDisplaySettings(&dmode, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL) { Logger::GetInstance()->Warning("Couldn't set window to fullscreen mode"); } // Make the window flags compatible with fullscreen mode SetWindowLongW(window.GetHandle(), GWL_STYLE, WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS); SetWindowLongW(window.GetHandle(), GWL_EXSTYLE, WS_EX_APPWINDOW); SetWindowPos(window.GetHandle(), NULL, 0, 0, renderParameters.width, renderParameters.height, SWP_FRAMECHANGED); ShowWindow(window.GetHandle(), SW_SHOW); } deviceContext_ = GetDC(reinterpret_cast<HWND>(window.GetHandle())); if (!deviceContext_) { Logger::GetInstance()->Error("Couldn't retrieve device context"); return false; } PIXELFORMATDESCRIPTOR pixelFormat; ZeroMemory(&pixelFormat, sizeof(pixelFormat)); pixelFormat.nSize = sizeof(pixelFormat); pixelFormat.nVersion = 1; pixelFormat.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; pixelFormat.iPixelType = PFD_TYPE_RGBA; pixelFormat.cColorBits = colorBits; pixelFormat.cDepthBits = depthBits; pixelFormat.cAlphaBits = alphaBits; pixelFormat.cRedBits = redBits; pixelFormat.cGreenBits = greenBits; pixelFormat.cBlueBits = blueBits; pixelFormat.cStencilBits = stencilBits; pixelFormat.iLayerType = PFD_MAIN_PLANE; int format = ChoosePixelFormat(deviceContext_, &pixelFormat); if (format == 0) { Logger::GetInstance()->Error("Failed to create a suitable pixel format " "for device context"); return false; } if (!SetPixelFormat(deviceContext_, format, &pixelFormat)) { Logger::GetInstance()->Error("Couldn't set the pixel format"); return false; } // Create a dummy context, because we are going to create a context using // an extension function HGLRC dummyRenderContext = wglCreateContext(deviceContext_); wglMakeCurrent(deviceContext_, dummyRenderContext); int attributes[] = { WGL_CONTEXT_MAJOR_VERSION_ARB, 3, WGL_CONTEXT_MINOR_VERSION_ARB, 3, WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB, 0, 0 }; PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB = reinterpret_cast<PFNWGLCREATECONTEXTATTRIBSARBPROC>(wglGetProcAddress("wglCreateContextAttribsARB")); renderContext_ = wglCreateContextAttribsARB(deviceContext_, NULL, attributes); if (!renderContext_) { wglDeleteContext(dummyRenderContext); Logger::GetInstance()->Error("Couldn't create render context"); return false; } if (!wglDeleteContext(dummyRenderContext)) { Logger::GetInstance()->Error("Couldn't delete dummy context"); return false; } if (!wglMakeCurrent(deviceContext_, renderContext_)) { Logger::GetInstance()->Error("Couldn't set the new rendering context"); return false; } if (GLEW_OK != glewInit()) { Logger::GetInstance()->Error("Couldn't initialize GLEW library"); return false; } Logger::GetInstance()->Debug("Render context created"); return true; }
// This function is called by the Windows function DispatchMessage() LRESULT CALLBACK WindowProcedure (HWND hWnd, UINT mMsg, WPARAM wParam, LPARAM lParam) { switch (mMsg) { case WM_CREATE: break; case WM_SIZE: break; case WM_COMMAND: //If handle is the window, handle the menu if (hWnd == cWindow.GetHandle()) HandleMenu(hWnd, LOWORD(wParam)); if (LOWORD(wParam) == IDR_START_BUTTON) { //Check if we have a connection to the scale if (scale != NULL && scale->IsConnected()) { //Check if we just finished a meal as well, if we didn't, start one if (!bMealActive) { //If the meal is not active, start it or reset it if (vMealItems.size() == 0) { _beginthread(Meal, 0, (void*)hWnd); } else { vMealItems.clear(); HandleMenu(hWnd, ID_FILE_NEW); } } else { //Otherwise, stop it if (strlen(cSaveName)<=1) GetSaveFile(hWnd); bMealActive = 0; } } } break; case WM_CLOSE: if (strlen(cSaveName) > 1 && !SaveMeal()) { if (CheckAndSave() == -1) break; } else if (!bSaved && vMealItems.size() > 0) { switch(MessageBox(hWnd, "You haven't saved the current meal, would you like to?","Hold Up!", MB_YESNOCANCEL | MB_ICONINFORMATION)) { case IDYES: if (CheckAndSave() == -1) break; case IDNO: if (scale) delete scale; DestroyWindow(hWnd); hWnd = NULL; break; case IDCANCEL: break; default: break; } } else { if (hWnd != NULL) { if (scale) delete scale; DestroyWindow(hWnd); } } break; case WM_DESTROY: PostQuitMessage(0); break; case WM_UPDATE_READING: //Destroy any spare messages if scale is null if (scale == NULL) break; //Retreive the information and print it on the button char tBuf[32]; sprintf(tBuf, "Connected on %s - %.2f %s %s", scale->GetName(), scale->GetWeight(), scale->GetUnit(), (scale->IsStable()?"":"(unstable)")); cEditBox.SetText(tBuf); hScaleThread = (HANDLE)_beginthread(GetScaleReading, 0, (void*) hWnd); break; case WM_SCALE_CONNECTED: ToggleScaleMenu(1); break; case WM_SCALE_DISCONNECTED: ToggleScaleMenu(0); cEditBox.SetText("Disconnected"); break; default: return DefWindowProc (hWnd, mMsg, wParam, lParam); } return 0; }