예제 #1
0
INT WINAPI WinMain(HINSTANCE Instance, HINSTANCE, LPSTR, INT) {
    gInstance = Instance;

    INITCOMMONCONTROLSEX icc;

    // Initialise common controls.
    icc.dwSize = sizeof(icc);
    icc.dwICC = ICC_WIN95_CLASSES;
    InitCommonControlsEx(&icc);

    // Initialize menu bar and set the check boxes' initial state
    gMainMenu = LoadMenu(Instance, "mainMenu");
    CheckMenuItem(gMainMenu, IDM_DISPLAYVIDEO, MF_BYCOMMAND | MF_CHECKED);

    const char* mainClassName = "KinectBoard";

    gKinectON = LoadIcon(Instance, "kinect1-ON");
    gKinectOFF = LoadIcon(Instance, "kinect2-OFF");

    HBRUSH mainBrush = CreateSolidBrush(RGB(0, 0, 0));

    // Define a class for our main window
    WNDCLASSEX WindowClass;
    ZeroMemory(&WindowClass, sizeof(WNDCLASSEX));
    WindowClass.cbSize        = sizeof(WNDCLASSEX);
    WindowClass.style         = 0;
    WindowClass.lpfnWndProc   = &MainProc;
    WindowClass.cbClsExtra    = 0;
    WindowClass.cbWndExtra    = 0;
    WindowClass.hInstance     = Instance;
    WindowClass.hIcon         = gKinectOFF;
    WindowClass.hCursor       = LoadCursor(nullptr, IDC_ARROW);
    WindowClass.hbrBackground = mainBrush;
    WindowClass.lpszMenuName  = "mainMenu";
    WindowClass.lpszClassName = mainClassName;
    WindowClass.hIconSm       = gKinectOFF;
    RegisterClassEx(&WindowClass);

    MSG Message;
    HACCEL hAccel;

    /* ===== Make two windows to display ===== */
    // Set the size, but not the position
    RECT winSize = {0, 0, static_cast<int>(ImageVars::width),
                    static_cast<int>(ImageVars::height)};
    AdjustWindowRect(
        &winSize,
        WS_SYSMENU | WS_CAPTION | WS_VISIBLE | WS_MINIMIZEBOX | WS_CLIPCHILDREN,
        TRUE); // window has menu

    // Create a new window to be used for the lifetime of the application
    gDisplayWindow = CreateWindowEx(0,
        mainClassName,
        "KinectBoard",
        WS_SYSMENU | WS_CAPTION | WS_VISIBLE | WS_MINIMIZEBOX | WS_CLIPCHILDREN,
        (GetSystemMetrics(SM_CXSCREEN) - (winSize.right - winSize.left)) / 2,
        (GetSystemMetrics(SM_CYSCREEN) - (winSize.bottom - winSize.top)) / 2,
        winSize.right - winSize.left, // returns image width (resized as window)
        winSize.bottom - winSize.top, // returns image height (resized as window)
        nullptr,
        gMainMenu,
        Instance,
        nullptr);
    /* ======================================= */

    // Load keyboard accelerators
    hAccel = LoadAccelerators(gInstance, "KeyAccel");

    gProjectorKnt.setScreenRect(gCurrentMonitor.dim);

    // Make window receive video stream events and image from Kinect instance
    gProjectorKnt.registerVideoWindow(gDisplayWindow);

    gProjectorKnt.startVideoStream();
    gProjectorKnt.startDepthStream();
    gProjectorKnt.enableColor(Processing::Red);
    gProjectorKnt.enableColor(Processing::Blue);

    while (GetMessage(&Message, nullptr, 0, 0) > 0) {
        if (!TranslateAccelerator(gDisplayWindow, // Handle to receiving window
                                  hAccel, // Handle to active accelerator table
                                  &Message)) // Message data
        {
            // If a message was waiting in the message queue, process it
            TranslateMessage(&Message);
            DispatchMessage(&Message);
        }
    }

    DestroyIcon(gKinectON);
    DestroyIcon(gKinectOFF);

    UnregisterClass(mainClassName, Instance);
    UnregisterClass("monitorButton", Instance);
    TestScreen::unregisterClass();

    return Message.wParam;
}
예제 #2
0
// Message handler for "Change Monitor" box
BOOL CALLBACK MonitorCbk(HWND hDlg, UINT message, WPARAM wParam,
                         LPARAM lParam) {
    switch (message) {
    case WM_INITDIALOG: {
        RECT windowSize;
        GetClientRect(hDlg, &windowSize);

        // Store button box's width and height
        unsigned int boxWidth = windowSize.right - windowSize.left - 18;
        unsigned int boxHeight = 89 - 9;

        // All buttons are scaled to fit within this window
        HWND buttonBox = CreateWindowEx(0,
                                        "STATIC",
                                        "",
                                        WS_VISIBLE | WS_CHILD,
                                        9,
                                        9,
                                        boxWidth,
                                        boxHeight,
                                        hDlg,
                                        reinterpret_cast<HMENU>(NULL),
                                        gInstance,
                                        nullptr);

        EnumDisplayMonitors(nullptr, // List all monitors
                            nullptr, // Don't clip area
                            MonitorEnumProc,
                            reinterpret_cast<LPARAM>(&gMonitors) // User data
        );

        /* Find coordinates of box that will fit all current desktop monitors
         * * Starts within 0 x 0 rectangle and expands it as necessary
         * * Then creates buttons within based upon that rectangle and matches
         *   them with their corresponding monitor
         */
        RECT desktopDims = {0, 0, 0, 0};

        for (auto& monitor : gMonitors) {
            if (monitor.dim.left < desktopDims.left) {
                desktopDims.left = monitor.dim.left;
            }

            if (monitor.dim.right > desktopDims.right) {
                desktopDims.right = monitor.dim.right;
            }

            if (monitor.dim.top < desktopDims.top) {
                desktopDims.top = monitor.dim.top;
            }

            if (monitor.dim.bottom > desktopDims.bottom) {
                desktopDims.bottom = monitor.dim.bottom;
            }
        }

        // Store desktop width and height
        unsigned int desktopWidth = desktopDims.right - desktopDims.left;
        unsigned int desktopHeight = desktopDims.bottom - desktopDims.top;

        char buttonText[2];
        bool isButtonClicked = false;
        // Create a button that will represent the monitor in this dialog
        for (auto& monitor : gMonitors) {
            isButtonClicked = gCurrentMonitor.dim.left == monitor.dim.left &&
                              gCurrentMonitor.dim.right == monitor.dim.right &&
                              gCurrentMonitor.dim.top == monitor.dim.top &&
                              gCurrentMonitor.dim.bottom == monitor.dim.bottom;

            if (isButtonClicked) {
                std::strcpy(buttonText, "*");
            }
            else {
                std::strcpy(buttonText, " ");
            }

            monitor.activeButton = CreateWindowEx(0,
                "BUTTON",
                (buttonText + to_string(monitor.dim.right - monitor.dim.left) +
                        " x " + to_string(monitor.dim.bottom - monitor.dim.top) +
                        " ").c_str(),
                WS_VISIBLE | WS_CHILD,
                boxWidth * (monitor.dim.left - desktopDims.left) / desktopWidth,
                boxHeight * (monitor.dim.top - desktopDims.top) / desktopHeight,
                boxWidth * (monitor.dim.right - monitor.dim.left) / desktopWidth,
                boxHeight * (monitor.dim.bottom - monitor.dim.top) / desktopHeight,
                buttonBox,
                reinterpret_cast<HMENU>(NULL),
                gInstance,
                nullptr);

            if (isButtonClicked) {
                gCurrentMonitor = monitor;
            }
        }

        return TRUE;
    }

    case WM_PARENTNOTIFY: {
        if (LOWORD(wParam) == WM_LBUTTONDOWN) {
            /* This message is only received when a button other than OK was
             * pressed in the dialog window
             */

            /* Convert cursor coordinates from dialog to desktop,
             * since the button's position is also in desktop coordinates
             */
            POINT cursorPos = {LOWORD(lParam), HIWORD(lParam)};
            MapWindowPoints(hDlg, nullptr, &cursorPos, 1);

            RECT buttonPos;

            // Change where test pattern will be drawn if button was clicked on
            for (auto& monitor : gMonitors) {
                GetWindowRect(monitor.activeButton, &buttonPos);

                // If cursor is within boundaries of button
                if (cursorPos.x > buttonPos.left &&
                    cursorPos.x < buttonPos.right &&
                    cursorPos.y > buttonPos.top &&
                    cursorPos.y < buttonPos.bottom) {
                    // Remove asterisk from previous button's text
                    SetWindowText(gCurrentMonitor.activeButton,
                            (" " + to_string(gCurrentMonitor.dim.right - gCurrentMonitor.dim.left) +
                             " x " + to_string(gCurrentMonitor.dim.bottom - gCurrentMonitor.dim.top) +
                             " ").c_str());

                    // Set new selected button
                    gCurrentMonitor = monitor;

                    // Add asterisk to new button's text
                    SetWindowText(gCurrentMonitor.activeButton,
                            ("*" + to_string(gCurrentMonitor.dim.right - gCurrentMonitor.dim.left) +
                             " x " + to_string(gCurrentMonitor.dim.bottom - gCurrentMonitor.dim.top) +
                             " ").c_str());
                }
            }
        }

        break;
    }

    case WM_COMMAND: {
        if (LOWORD(wParam) == IDOK) {
            for (auto& monitor : gMonitors) {
                DestroyWindow(monitor.activeButton);
            }
            gMonitors.clear();

            gCurrentMonitor.activeButton = nullptr;

            // Give Kinect correct monitor dimensions so mouse is moved to proper position
            gProjectorKnt.setScreenRect(gCurrentMonitor.dim);

            EndDialog(hDlg, LOWORD(wParam));
        }
        else if (LOWORD(wParam) == IDCANCEL) {
            EndDialog(hDlg , LOWORD(wParam));
        }

        break;
    }

    case WM_CLOSE: {
        EndDialog(hDlg, 0);

        break;
    }

    default: {
        return FALSE;
    }
    }

    return TRUE;
}