Пример #1
0
static VOID
MonSelUpdateMonitorsInfo(IN OUT PMONITORSELWND infoPtr,
                         IN BOOL bRepaint)
{
    RECT rcExtSurface, rcExtDisplay;
    DWORD Index;

    /* Recalculate rcExtent */
    MonSelUpdateExtent(infoPtr);

    infoPtr-> CanDisplay = infoPtr->MonitorsCount != 0 &&
                           (infoPtr->ClientSize.cx > (2 * (infoPtr->Margin.cx + infoPtr->SelectionFrame.cx))) &&
                           (infoPtr->ClientSize.cy > (2 * (infoPtr->Margin.cy + infoPtr->SelectionFrame.cy)));

    if (infoPtr->CanDisplay)
    {
        /* Calculate the rectangle on the control in which may be painted */
        rcExtSurface.left = infoPtr->Margin.cx;
        rcExtSurface.top = infoPtr->Margin.cy;
        rcExtSurface.right = rcExtSurface.left + infoPtr->ClientSize.cx - (2 * infoPtr->Margin.cx);
        rcExtSurface.bottom = rcExtSurface.top + infoPtr->ClientSize.cy - (2 * infoPtr->Margin.cy);

        /* Calculate the rectangle on the control that is actually painted on */
        rcExtDisplay.left = rcExtDisplay.top = 0;
        rcExtDisplay.right = infoPtr->rcExtent.right - infoPtr->rcExtent.left;
        rcExtDisplay.bottom = infoPtr->rcExtent.bottom - infoPtr->rcExtent.top;

        ScaleRectSizeFit(&rcExtSurface,
                         &rcExtDisplay);

        infoPtr->rcOldMonitors = infoPtr->rcMonitors;
        infoPtr->rcMonitors = rcExtDisplay;

        /* Now that we know in which area all monitors are located,
           calculate the monitors selection rectangles on the screen */

        for (Index = 0; Index < infoPtr->MonitorsCount; Index++)
        {
            MonSelMonInfoToRect(&infoPtr->MonitorInfo[Index],
                                &rcExtDisplay);

            MonSelScaleRectRelative(&infoPtr->rcExtent,
                                    &rcExtDisplay,
                                    &infoPtr->rcMonitors,
                                    &infoPtr->Monitors[Index].rc);
        }

        MonSelResetMonitors(infoPtr);

        if (bRepaint)
            MonSelRepaint(infoPtr);
    }
    else if (bRepaint)
    {
        InvalidateRect(infoPtr->hSelf,
                       NULL,
                       TRUE);
    }
}
Пример #2
0
static LRESULT CALLBACK
MonitorSelWndProc(IN HWND hwnd,
                  IN UINT uMsg,
                  IN WPARAM wParam,
                  IN LPARAM lParam)
{
    PMONITORSELWND infoPtr;
    LRESULT Ret = 0;

    infoPtr = (PMONITORSELWND)GetWindowLongPtrW(hwnd,
              0);

    if (infoPtr == NULL && uMsg != WM_CREATE)
    {
        goto HandleDefaultMessage;
    }

    switch (uMsg)
    {
    case WM_PAINT:
    case WM_PRINTCLIENT:
    {
        PAINTSTRUCT ps;
        HDC hDC;

        if (wParam != 0)
        {
            if (!GetUpdateRect(hwnd,
                               &ps.rcPaint,
                               TRUE))
            {
                break;
            }
            hDC = (HDC)wParam;
        }
        else
        {
            hDC = BeginPaint(hwnd,
                             &ps);
            if (hDC == NULL)
            {
                break;
            }
        }

        if (infoPtr->CanDisplay)
        {
            MonSelPaint(infoPtr,
                        hDC,
                        &ps.rcPaint);
        }

        if (wParam == 0)
        {
            EndPaint(hwnd,
                     &ps);
        }
        break;
    }

    case WM_MOUSEMOVE:
    {
        POINT pt;

        if (!(wParam & MK_LBUTTON))
        {
            MonSelCancelDragging(infoPtr);
            break;
        }

        if (infoPtr->LeftBtnDown)
        {
            pt.x = (LONG)LOWORD(lParam);
            pt.y = (LONG)HIWORD(lParam);

            MonSelDrag(infoPtr,
                       &pt);
        }

        break;
    }

    case WM_RBUTTONDOWN:
    {
        if (!(infoPtr->ControlExStyle & MSLM_EX_SELECTONRIGHTCLICK))
            break;

        /* Fall through */
    }

    case WM_LBUTTONDBLCLK:
    case WM_LBUTTONDOWN:
    {
        INT Index;
        POINT pt;

        if (!infoPtr->HasFocus)
            SetFocus(infoPtr->hSelf);

        pt.x = (LONG)LOWORD(lParam);
        pt.y = (LONG)HIWORD(lParam);

        Index = MonSelHitTest(infoPtr,
                              &pt);
        if (Index >= 0 || (infoPtr->ControlExStyle & MSLM_EX_ALLOWSELECTNONE))
        {
            MonSelSetCurSelMonitor(infoPtr,
                                   Index,
                                   TRUE);
        }

        if (Index >= 0 && (uMsg == WM_LBUTTONDOWN || uMsg == WM_LBUTTONDBLCLK))
        {
            infoPtr->LeftBtnDown = TRUE;
            MonSelInitDragging(infoPtr,
                               (DWORD)Index,
                               &pt);
        }

        /* Fall through */
    }

    case WM_MBUTTONDOWN:
    {
        if (!infoPtr->HasFocus)
            SetFocus(hwnd);
        break;
    }

    case WM_RBUTTONUP:
    {
        MonSelContextMenu(infoPtr,
                          (SHORT)LOWORD(lParam),
                          (SHORT)HIWORD(lParam));
        break;
    }

    case WM_LBUTTONUP:
    {
        MonSelCancelDragging(infoPtr);
        infoPtr->LeftBtnDown = FALSE;
        break;
    }

    case WM_GETDLGCODE:
    {
        INT virtKey;

        virtKey = (lParam != 0 ? (INT)((LPMSG)lParam)->wParam : 0);
        switch (virtKey)
        {
        case VK_TAB:
        {
            /* Change the UI status */
            SendMessage(GetAncestor(hwnd,
                                    GA_PARENT),
                        WM_CHANGEUISTATE,
                        MAKEWPARAM(UIS_INITIALIZE,
                                   0),
                        0);
            break;
        }
        }

        Ret |= DLGC_WANTARROWS;

        if (infoPtr->ControlExStyle & MSLM_EX_SELECTBYNUMKEY)
            Ret |= DLGC_WANTCHARS;
        break;
    }

    case WM_SETFOCUS:
    {
        infoPtr->HasFocus = TRUE;
        MonSelRepaintSelected(infoPtr);
        break;
    }

    case WM_KILLFOCUS:
    {
        infoPtr->HasFocus = FALSE;
        MonSelCancelDragging(infoPtr);
        MonSelRepaintSelected(infoPtr);
        break;
    }

    case WM_UPDATEUISTATE:
    {
        DWORD OldUIState;

        Ret = DefWindowProcW(hwnd,
                             uMsg,
                             wParam,
                             lParam);

        OldUIState = infoPtr->UIState;
        switch (LOWORD(wParam))
        {
        case UIS_SET:
            infoPtr->UIState |= HIWORD(wParam);
            break;

        case UIS_CLEAR:
            infoPtr->UIState &= ~HIWORD(wParam);
            break;
        }

        if (infoPtr->UIState != OldUIState)
            MonSelRepaintSelected(infoPtr);
        break;
    }

    case WM_SETFONT:
    {
        Ret = (LRESULT)MonSelChangeFont(infoPtr,
                                        (HFONT)wParam,
                                        (BOOL)LOWORD(lParam));
        break;
    }

    case WM_SIZE:
    {
        infoPtr->ClientSize.cx = LOWORD(lParam);
        infoPtr->ClientSize.cy = HIWORD(lParam);

        /* Don't let MonSelUpdateMonitorsInfo repaint the control
           because this won't work properly in case the control
           was sized down! */
        MonSelUpdateMonitorsInfo(infoPtr,
                                 FALSE);
        InvalidateRect(infoPtr->hSelf,
                       NULL,
                       TRUE);
        break;
    }

    case WM_GETFONT:
    {
        Ret = (LRESULT)infoPtr->hFont;
        break;
    }

    case WM_ENABLE:
    {
        infoPtr->Enabled = ((BOOL)wParam != FALSE);
        MonSelRepaint(infoPtr);
        break;
    }

    case WM_STYLECHANGED:
    {
        if (wParam == GWL_STYLE)
        {
            unsigned int OldEnabled = infoPtr->Enabled;
            infoPtr->Enabled = !(((LPSTYLESTRUCT)lParam)->styleNew & WS_DISABLED);

            if (OldEnabled != infoPtr->Enabled)
                MonSelRepaint(infoPtr);
        }
        break;
    }

    case WM_KEYDOWN:
    {
        INT Index;

        if (infoPtr->ControlExStyle & MSLM_EX_SELECTBYARROWKEY)
        {
            switch (wParam)
            {
            case VK_UP:
            case VK_LEFT:
            {
                Index = infoPtr->SelectedMonitor;

                if (infoPtr->MonitorsCount != 0)
                {
                    if (Index < 0)
                        Index = 0;
                    else if (Index > 0)
                        Index--;
                }

                if (Index >= 0)
                {
                    MonSelSetCurSelMonitor(infoPtr,
                                           Index,
                                           TRUE);
                }
                break;
            }

            case VK_DOWN:
            case VK_RIGHT:
            {
                Index = infoPtr->SelectedMonitor;

                if (infoPtr->MonitorsCount != 0)
                {
                    if (Index < 0)
                        Index = (INT)infoPtr->MonitorsCount - 1;
                    else if (Index < (INT)infoPtr->MonitorsCount - 1)
                        Index++;
                }

                if (infoPtr->SelectedMonitor < (INT)infoPtr->MonitorsCount)
                {
                    MonSelSetCurSelMonitor(infoPtr,
                                           Index,
                                           TRUE);
                }
                break;
            }
            }
        }
        break;
    }

    case WM_CHAR:
    {
        if ((infoPtr->ControlExStyle & MSLM_EX_SELECTBYNUMKEY) &&
                wParam >= '1' && wParam <= '9')
        {
            INT Index = (INT)(wParam - '1');
            if (Index < (INT)infoPtr->MonitorsCount)
            {
                MonSelSetCurSelMonitor(infoPtr,
                                       Index,
                                       TRUE);
            }
        }
        break;
    }

    case MSLM_SETMONITORSINFO:
    {
        Ret = MonSelSetMonitorsInfo(infoPtr,
                                    (DWORD)wParam,
                                    (const MONSL_MONINFO *)lParam);
        break;
    }

    case MSLM_GETMONITORSINFO:
    {
        Ret = MonSelGetMonitorsInfo(infoPtr,
                                    (DWORD)wParam,
                                    (PMONSL_MONINFO)lParam);
        break;
    }

    case MSLM_GETMONITORINFOCOUNT:
    {
        Ret = infoPtr->MonitorsCount;
        break;
    }

    case MSLM_HITTEST:
    {
        Ret = MonSelHitTest(infoPtr,
                            (const POINT *)wParam);
        break;
    }

    case MSLM_SETCURSEL:
    {
        Ret = MonSelSetCurSelMonitor(infoPtr,
                                     (INT)wParam,
                                     FALSE);
        break;
    }

    case MSLM_GETCURSEL:
    {
        Ret = infoPtr->SelectedMonitor;
        break;
    }

    case MSLM_SETMONITORINFO:
    {
        Ret = MonSelSetMonitorInfo(infoPtr,
                                   (INT)wParam,
                                   (const MONSL_MONINFO *)lParam);
        break;
    }

    case MSLM_GETMONITORINFO:
    {
        Ret = MonSelGetMonitorInfo(infoPtr,
                                   (INT)wParam,
                                   (PMONSL_MONINFO)lParam);
        break;
    }

    case MSLM_SETEXSTYLE:
    {
        Ret = MonSelSetExtendedStyle(infoPtr,
                                     (DWORD)lParam);
        break;
    }

    case MSLM_GETEXSTYLE:
    {
        Ret = MonSelGetExtendedStyle(infoPtr);
        break;
    }

    case MSLM_GETMONITORRECT:
    {
        Ret = (LRESULT)MonSelGetMonitorRect(infoPtr,
                                            (INT)wParam,
                                            (PRECT)lParam);
        break;
    }

    case WM_CREATE:
    {
        infoPtr = (PMONITORSELWND) HeapAlloc(GetProcessHeap(),
                                             0,
                                             sizeof(MONITORSELWND));
        if (infoPtr == NULL)
        {
            Ret = (LRESULT)-1;
            break;
        }

        ZeroMemory(infoPtr,
                   sizeof(MONITORSELWND));
        infoPtr->hSelf = hwnd;
        infoPtr->hNotify = ((LPCREATESTRUCTW)lParam)->hwndParent;
        infoPtr->Enabled = !(((LPCREATESTRUCTW)lParam)->style & WS_DISABLED);
        infoPtr->UIState = SendMessage(hwnd,
                                       WM_QUERYUISTATE,
                                       0,
                                       0);

        SetWindowLongPtrW(hwnd,
                          0,
                          (LONG_PTR)infoPtr);

        MonSelCreate(infoPtr);
        break;
    }

    case WM_DESTROY:
    {
        MonSelDestroy(infoPtr);

        HeapFree(GetProcessHeap(),
                 0,
                 infoPtr);
        SetWindowLongPtrW(hwnd,
                          0,
                          (DWORD_PTR)NULL);
        break;
    }

    default:
    {
HandleDefaultMessage:
        Ret = DefWindowProcW(hwnd,
                             uMsg,
                             wParam,
                             lParam);
        break;
    }
    }

    return Ret;
}