LRESULT CALLBACK MainProc(HWND handle, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_CREATE: { HWND recalibButton = CreateWindowEx(0, "BUTTON", "Recalibrate", WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON, 9, ImageVars::height - 9 - 28, 100, 28, handle, reinterpret_cast<HMENU>(IDC_RECALIBRATE_BUTTON), gInstance, nullptr); SendMessage(recalibButton, WM_SETFONT, reinterpret_cast<WPARAM>(GetStockObject(DEFAULT_GUI_FONT)), MAKELPARAM(FALSE, 0)); HWND toggleStreamButton = CreateWindowEx(0, "BUTTON", "Start", WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON, ImageVars::width - 9 - 100, ImageVars::height - 9 - 28, 100, 28, handle, reinterpret_cast<HMENU>(IDC_STREAMTOGGLE_BUTTON), gInstance, nullptr); SendMessage(toggleStreamButton, WM_SETFONT, reinterpret_cast<WPARAM>(GetStockObject(DEFAULT_GUI_FONT)), MAKELPARAM(FALSE, 0)); break; } case WM_COMMAND: { int wmId = LOWORD(wParam); switch (wmId) { case IDC_RECALIBRATE_BUTTON: { // If there is no Kinect connected, don't bother trying to retrieve images if (gProjectorKnt.isVideoStreamRunning()) { TestScreen testWin(gInstance, false); testWin.create(gCurrentMonitor.dim); testWin.setColor(Processing::Red); testWin.display(); // Give Kinect time to get image w/ test pattern in it std::this_thread::sleep_for(std::chrono::milliseconds(750)); gProjectorKnt.setCalibImage(Processing::Red); testWin.setColor(Processing::Blue); testWin.display(); // Give Kinect time to get image w/ test pattern in it std::this_thread::sleep_for(std::chrono::milliseconds(750)); gProjectorKnt.setCalibImage(Processing::Blue); gProjectorKnt.calibrate(); } break; } case IDC_STREAMTOGGLE_BUTTON: { // If button was pressed from video display window if (handle == gProjectorKnt.getRegisteredVideoWindow()) { if (gProjectorKnt.isVideoStreamRunning()) { gProjectorKnt.stopVideoStream(); } else { gProjectorKnt.startVideoStream(); } } // If button was pressed from depth image display window else if (handle == gProjectorKnt.getRegisteredDepthWindow()) { if (gProjectorKnt.isDepthStreamRunning()) { gProjectorKnt.stopDepthStream(); } else { gProjectorKnt.startDepthStream(); } } break; } case IDM_STARTTRACK: { gProjectorKnt.setMouseTracking(true); MessageBox(handle, "Mouse tracking has been enabled", "Mouse Tracking", MB_ICONINFORMATION | MB_OK); break; } case IDM_STOPTRACK: { gProjectorKnt.setMouseTracking(false); MessageBox(handle, "Mouse tracking has been disabled", "Mouse Tracking", MB_ICONINFORMATION | MB_OK); break; } case IDM_DISPLAYVIDEO: { // Check "Display Video" and uncheck "Display Depth" CheckMenuItem(gMainMenu, IDM_DISPLAYVIDEO, MF_BYCOMMAND | MF_CHECKED); CheckMenuItem(gMainMenu, IDM_DISPLAYDEPTH, MF_BYCOMMAND | MF_UNCHECKED); // Stop depth stream from displaying and switch to video stream gProjectorKnt.registerVideoWindow(gDisplayWindow); gProjectorKnt.unregisterDepthWindow(); /* Change button text to correctly represent status of stream * displayed */ char windowText[16]; if (gProjectorKnt.isVideoStreamRunning()) { // Change Start/Stop button text to "Stop" EnumChildWindows(handle, StartStreamChildCbk, reinterpret_cast<LPARAM>(windowText)); } else { // Change Start/Stop button text to "Start" EnumChildWindows(handle, StopStreamChildCbk, reinterpret_cast<LPARAM>(windowText)); } break; } case IDM_DISPLAYDEPTH: { // Uncheck "Display Video" and check "Display Depth" CheckMenuItem(gMainMenu, IDM_DISPLAYVIDEO, MF_BYCOMMAND | MF_UNCHECKED); CheckMenuItem(gMainMenu, IDM_DISPLAYDEPTH, MF_BYCOMMAND | MF_CHECKED); // Stop video stream from displaying and switch to depth stream gProjectorKnt.unregisterVideoWindow(); gProjectorKnt.registerDepthWindow(gDisplayWindow); /* Change button text to correctly represent status of stream * displayed */ char windowText[16]; if (gProjectorKnt.isDepthStreamRunning()) { // Change Start/Stop button text to "Stop" EnumChildWindows(handle, StartStreamChildCbk, reinterpret_cast<LPARAM>(windowText)); } else { // Change Start/Stop button text to "Start" EnumChildWindows(handle, StopStreamChildCbk, reinterpret_cast<LPARAM>(windowText)); } break; } case IDM_CHANGEMONITOR: { DialogBox(gInstance, MAKEINTRESOURCE(IDD_MONITORBOX), handle, MonitorCbk); break; } case IDM_HELP: { HINSTANCE status = ShellExecute(handle, "open", "help.html", nullptr, "help", SW_SHOWNORMAL); if (reinterpret_cast<int>(status) <= 32) { std::string errorMsg = "Could not open help file\nError: "; MessageBox(handle, (errorMsg + to_string(status)).c_str(), "Error", MB_ICONERROR | MB_OK); } // TODO: Finish writing HTML help page break; } case IDM_ABOUT: { DialogBox(gInstance, MAKEINTRESOURCE(IDD_ABOUTBOX), handle, AboutCbk); break; } } break; } case WM_PAINT: { PAINTSTRUCT ps; HDC hdc; hdc = BeginPaint(handle, &ps); // If we're painting the video display window if (handle == gProjectorKnt.getRegisteredVideoWindow()) { gProjectorKnt.displayVideo(gDisplayWindow, 0, 0, hdc); } // If we're painting the depth image display window else if (handle == gProjectorKnt.getRegisteredDepthWindow()) { gProjectorKnt.displayDepth(gDisplayWindow, 0, 0, hdc); } EndPaint(handle, &ps); break; } case WM_DESTROY: { // If the display window is being closed, exit the application if (handle == gDisplayWindow) { PostQuitMessage(0); } break; } case WM_KINECT_VIDEOSTART: { // Change video window icon to green because the stream started PostMessage(handle, WM_SETICON, ICON_SMALL, reinterpret_cast<LPARAM>(gKinectON)); PostMessage(handle, WM_SETICON, ICON_BIG, reinterpret_cast<LPARAM>(gKinectON)); // Change Start/Stop button text to "Stop" char windowText[16]; EnumChildWindows(handle, StartStreamChildCbk, reinterpret_cast<LPARAM>(windowText)); break; } case WM_KINECT_VIDEOSTOP: { // Change video window icon to red because the stream stopped PostMessage(handle, WM_SETICON, ICON_SMALL, reinterpret_cast<LPARAM>(gKinectOFF)); PostMessage(handle, WM_SETICON, ICON_BIG, reinterpret_cast<LPARAM>(gKinectOFF)); // Change Start/Stop button text to "Start" char windowText[16]; EnumChildWindows(handle, StopStreamChildCbk, reinterpret_cast<LPARAM>(windowText)); break; } case WM_KINECT_DEPTHSTART: { // Change depth window icon to green because the stream started PostMessage(handle, WM_SETICON, ICON_SMALL, reinterpret_cast<LPARAM>(gKinectON)); PostMessage(handle, WM_SETICON, ICON_BIG, reinterpret_cast<LPARAM>(gKinectON)); // Change Start/Stop button text to "Stop" char windowText[16]; EnumChildWindows(handle, StartStreamChildCbk, reinterpret_cast<LPARAM>(windowText)); break; } case WM_KINECT_DEPTHSTOP: { // Change depth window icon to red because the stream stopped PostMessage(handle, WM_SETICON, ICON_SMALL, reinterpret_cast<LPARAM>(gKinectOFF)); PostMessage(handle, WM_SETICON, ICON_BIG, reinterpret_cast<LPARAM>(gKinectOFF)); // Change Start/Stop button text to "Start" char windowText[16]; EnumChildWindows(handle, StopStreamChildCbk, reinterpret_cast<LPARAM>(windowText)); break; } default: { return DefWindowProc(handle, message, wParam, lParam); } } return 0; }