⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 listbox.cpp

📁 一个WinCE6。0下的IP phone的源代码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
        pRectangle->top = (Index - m_TopItem) * m_FixedItemHeight;
        pRectangle->bottom = pRectangle->top + m_FixedItemHeight;
    }

    return 0;
#else
    return DefWindowProc(LB_GETITEMRECT, Index, (LPARAM)pRectangle);
#endif
}

LRESULT
ListBoxImpl_t::OnGetCount(
    void
    )
{
#ifdef VIRTUAL_LISTBOX
    return m_Items.size();
#else
    return DefWindowProc(LB_GETCOUNT, 0, 0);
#endif
}

LRESULT
ListBoxImpl_t::OnGetCurSel(
    void
    )
{
#ifdef VIRTUAL_LISTBOX
    return m_SelectedItem;
#else
    return DefWindowProc(LB_GETCURSEL, 0, 0);
#endif
}

LRESULT
ListBoxImpl_t::OnGetTopIndex(
    void
    )
{
#ifdef VIRTUAL_LISTBOX
    return m_TopItem;
#else
    return DefWindowProc(LB_GETTOPINDEX, 0, 0);
#endif
}

LRESULT
ListBoxImpl_t::OnSetTopIndex(
    int Index
    )
{
#ifdef VIRTUAL_LISTBOX
    if (IsValidIndex(Index))
    {
        return LB_ERR;
    }

    // Move this item to top of listbox
    m_TopItem = Index;

    return 0;
#else
    return DefWindowProc(LB_SETTOPINDEX, Index, 0);
#endif
}

/*------------------------------------------------------------------------------
    ListBoxImpl_t::OnMouseButton

    Handles a mouse button being clicked in the listbox's client area

    WM_LBUTTONDOWN,
    WM_LBUTTONDBLCLK
    WM_RBUTTONDOWN
    WM_RBUTTONDBLCLK
------------------------------------------------------------------------------*/
LRESULT
ListBoxImpl_t::OnMouseButton(
    WPARAM wParam,
    LPARAM lParam
    )
{
    LRESULT Result = OnItemFromPoint(LOWORD(lParam), HIWORD(lParam));

    bool IsInsideClientArea = (HIWORD(Result) == 0);
    int Index = LOWORD(Result);

    IVoIPDisplayItem * pItem = NULL;

    if (!IsInsideClientArea || !IsValidIndex(Index))
    {
        return 0;
    }

    RECT ItemRect = {0};
    OnGetItemRect(Index, &ItemRect);

    //The width of an item spans the entire client width
    //if the click is inside the item, select it
    //otherwise bail out
    if (ItemRect.bottom < HIWORD(lParam))
    {
        return 0;
    }

    pItem = (IVoIPDisplayItem *)OnGetItemData(Index);
    if (!pItem)
    {
        return 0;
    }

    if (pItem->IsSelectable())
    {
        IVoIPDisplayControl* pControl;
        if (FAILED(
            pItem->QueryInterface(
                IID_IVoIPDisplayControl,
                reinterpret_cast<void**>(&pControl)
                )
            ) ||
            !pControl->SetFocus()
            )
        {
            SetFocus(m_hwnd);
        }

        // Only choose the item when it is selectable
        OnSetCurSel(Index);
        SimulateItemActivated();
    }

    return 0;
}

/*------------------------------------------------------------------------------
    ListBoxImpl_t::SimulateItemActivated

    Simulates an item being activated (e.g. clicked on - not just focused)
------------------------------------------------------------------------------*/
inline
void
ListBoxImpl_t::SimulateItemActivated(
    void
    )
{
    //Inform the parent of a fake double click
    ForwardMessageToParent(
        WM_COMMAND,
        MAKEWPARAM(GetWindowLong(m_hwnd, GWL_ID), LBN_DBLCLK),
        (LPARAM)m_hwnd
        );
}

/*------------------------------------------------------------------------------
    ListBoxImpl_t::OnKeydown

    Handles WM_KEYDOWN messages.

    Possibly, scrolls the listbox or activates an item
------------------------------------------------------------------------------*/
LRESULT
ListBoxImpl_t::OnKeydown(
    int VirtualKey,
    UINT KeyData
    )
{
    int IndexToSelect = 0;
    int SelectedItem = 0;
    int BottomIndex = 0;
    int ItemCount = OnGetCount();

    //LOWORD of KeyData is the repeat count
    bool IsRepeated  = (LOWORD(KeyData) > 1);

    if (ItemCount <= 0)
    {
        return 0;
    }

    switch (VirtualKey)
    {
    case VK_UP:
    case VK_DOWN:
        SelectedItem = OnGetCurSel();

        //choose the next item by default
        IndexToSelect = SelectedItem + ((VirtualKey == VK_UP) ? -1 : 1);

        //if this is a new press (e.g. not repeated) we can wrap the selection around
        if (!IsRepeated)
        {
            switch (VirtualKey)
            {
            case VK_UP:
                if (SelectedItem == 0)
                {
                    IndexToSelect = ItemCount-1;
                }
                break;

            case VK_DOWN:
                if (SelectedItem == ItemCount-1)
                {
                    IndexToSelect = 0;
                }
                break;
            }
        }

        IndexToSelect = GetNextSelectableIndex(IndexToSelect, (VirtualKey == VK_UP));
        IndexToSelect = min(max(IndexToSelect, 0), ItemCount-1 );

        if (IndexToSelect != SelectedItem)
        {
            OnSetCurSel(IndexToSelect);
        }
        break;

    case VK_PRIOR:
        //PAGE UP
        OnSetRedraw(FALSE);
        OnSetCurSel(OnGetTopIndex() - 1);
        OnSetCurSel(OnGetTopIndex());
        OnSetRedraw(TRUE);
        break;

    case VK_NEXT:
        //PAGE DOWN
        BottomIndex = GetBottomIndex();
        IndexToSelect = min(BottomIndex + 1, ItemCount-1);
        OnSetCurSel(IndexToSelect);
        break;

    default:
        return DefWindowProc(WM_KEYDOWN, VirtualKey, KeyData);
    }

    return 0;
}

/*------------------------------------------------------------------------------
    ListBoxImpl_t::OnSetCurSel

    Handles LB_SETCURSEL. We always want the LBN_SELCHANGE notification and
    since this message doesn't cause the LBN_SELCHANGE notification to go to
    the parent (see ListBox documentation), we simulate it.
------------------------------------------------------------------------------*/
LRESULT
ListBoxImpl_t::OnSetCurSel(
    int IndexToSelect
    )
{
    int TopItem = 0;
    int NewTopItem = -1;
    int SelectedItem = 0;
    int ItemCount = OnGetCount();

    RECT ItemRect = {0};
    RECT ClientRect = {0};

    bool NeedToSimulatePageUp = false;
    bool NeedToSimulatePageDown = false;

    LRESULT Result = 0;

    WCHAR ToolTipText[MAX_PATH] = L"";
    IVoIPDisplayItem *pItem = NULL;

    //If the user wants to clear the selection, let the def wnd proc handle it
    if (IndexToSelect == -1)
    {
        return DefWindowProc(LB_SETCURSEL, IndexToSelect, 0);
    }

    //hide the previous tooltip window
    ShowWindow(m_ToolTip, SW_HIDE);

    //Short circuit a same selection
    SelectedItem = OnGetCurSel();
    if (SelectedItem == IndexToSelect)
    {
        return 0;
    }

    if ((IndexToSelect > ItemCount) || (ItemCount == 0))
    {
        return 0;
    }

    //Check to see if the item we are going to select needs tooltip or not
    //if so, assign the full text to the tooltip control
    pItem = (IVoIPDisplayItem *)OnGetItemData(IndexToSelect);
    OnGetItemRect(IndexToSelect, &ItemRect);

    if (pItem)
    {
        m_CheckToolTip = pItem->NeedsToolTip(&ItemRect) ? true : false;
        if (m_CheckToolTip)
        {
            pItem->GetText(
                ToolTipText,
                _countof(ToolTipText)
                );
            SetWindowText(
                m_ToolTip,
                ToolTipText
                );
            m_dwToolTipTimer = GetTickCount();
        }
    }

    //Figure out if we need to scroll up or down
    TopItem = OnGetTopIndex();
    GetClientRect(m_hwnd, &ClientRect);

    NeedToSimulatePageUp   = (TopItem > IndexToSelect);
    NeedToSimulatePageDown = (TopItem < IndexToSelect) && (ItemRect.bottom > ClientRect.bottom);

    //figure out the new top index
    if (NeedToSimulatePageUp)
    {
        //if we are paging up, we need to determine the new top index such
        //that IndexToSelect is the bottom index!
        NewTopItem = GetNewTopIndex(m_hwnd, IndexToSelect, ClientRect.bottom - ClientRect.top);

        //Force to hide the Sip Panel when we page up
        //Because if we don't hide the sip panel, the last item at previous page will
        //not get redrawed since it will be all covered by the sip panel
        Input_HideInputPanel();
    }
    else if (NeedToSimulatePageDown)
    {
        //Make the IndexToSelect the new top index
        NewTopItem = IndexToSelect;
    }

    if (NewTopItem != -1)
    {
        //Reduce drawing flicker on page scroll
        OnSetRedraw(FALSE);

        OnSetTopIndex(NewTopItem);
        Result = DefWindowProc(LB_SETCURSEL, IndexToSelect, 0);
        OnSetRedraw(TRUE);

    }
    else
    {
        Result = DefWindowProc(LB_SETCURSEL, IndexToSelect, 0);
    }

    //Notify the parent
    SendMessage(
        GetParent(m_hwnd),
        WM_COMMAND,
        MAKEWPARAM(GetWindowLong(m_hwnd, GWL_ID), LBN_SELCHANGE),
        (LPARAM)m_hwnd
        );

    return Result;
}

/*------------------------------------------------------------------------------
    ListBoxImpl_t::OnSetFocus

    When we gain focus, we need to ensure that we have reset the redraw flag
------------------------------------------------------------------------------*/
LRESULT
ListBoxImpl_t::OnSetFocus(
    HWND OldFocus
    )
{
    LRESULT Result = DefWindowProc(WM_SETFOCUS, (WPARAM)OldFocus, 0);

    int SelectedItem = OnGetCurSel();

    IVoIPDisplayItem *pItem = reinterpret_cast<IVoIPDisplayItem*>(
        OnGetItemData(SelectedItem)
        );
    if (pItem)
    {
        IVoIPDisplayControl* pControl;
        if (SUCCEEDED(pItem->QueryInterface(
            IID_IVoIPDisplayControl,
            reinterpret_cast<void**>(&pControl)
            )))
        {
            pControl->SetFocus();
        }
    }

    if (!m_RedrawingEnabled)
    {
        OnSetRedraw(TRUE);
    }

    return Result;
}

/*------------------------------------------------------------------------------
    ListBoxImpl_t::OnSetRedraw

    Optimizes a caller setting/unsetting redraw
------------------------------------------------------------------------------*/
LRESULT
ListBoxImpl_t::OnSetRedraw(
    BOOL Enable
    )
{
#ifdef VIRTUAL_LISTBOX
    LRESULT Result = 1;

    if (!Enable)
    {
        //remember that drawing is now disabled
        m_RedrawingEnabled = false;
    }
    else if (!m_RedrawingEnabled)
    {
        //SetCaret(TRUE);

        // want the whole window to redraw including
        // non-client area since scrollbars may have
        // gone away or come back.
        InvalidateRect(m_hwnd, NULL, TRUE);
        SetWindowPos(
            m_hwnd,
            0,
            0,
            0,
            0,
            0,
            SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER |
            SWP_NOACTIVATE | SWP_FRAMECHANGED
            );

        m_RedrawingEnabled = true;
        Result = 0;
    }

    return Result;
#else
    bool NeedToCallDefWndProc = true;

    LRESULT Result = 1;

    if (! Enable)
    {
        //remember that drawing is now disabled
        m_RedrawingEnabled = false;
    }
    else
    {
        //if redrawing is already enabled, we don't have to call the defwndproc
        if (m_RedrawingEnabled)
        {
            NeedToCallDefWndProc = false;
        }
        else
        {
            m_RedrawingEnabled = true;
        }
    }

    if (NeedToCallDefWndProc)
    {
        Result = DefWindowProc(WM_SETREDRAW, Enable, 0);
    }

    return Result;
#endif
}

/*------------------------------------------------------------------------------
    ListBoxImpl_t::OnPaint

    Handles WM_PAINT - paints the listview background and delegates the drawing
    of the items to the actual items

    Returns (LRESULT): indicating success or failure
------------------------------------------------------------------------------*/
LRESULT
ListBoxImpl_t::OnPaint(
    HDC hdc
    )
{
    RECT UpdateRect = {0};
    RECT ItemsArea = {0};
    RECT NonItemsArea = {0};
    RECT ClientRect = {0};

    int ItemCount = OnGetCount();

    HRESULT hr = S_OK;

    PaintHelper_t paint;

    //if paint is called between a SetRedraw(FALSE) and a SetRedraw(TRUE) block
    //we shouldn't reposition our children controls because WM_DRAWITEM will NOT
    //be generated
    if (m_RedrawingEnabled)
    {
        RepositionSubcontrols();
    }
    else
    {
        COMMON_DEBUGMSG(0, (L"we are repainting, but not repositioning the subcontrols because we don't have parental-focus"));
    }

    NotifyParentOfOffscreenItems();

    // Since we are not erasing the background we are responsible for drawing
    // the entire control.

    // Display items will draw themselves completely.  We will get a notification
    // from the parent before and after an item is going to be drawn
    // The only part of the control that we need to concern ourselves with is
    // the non-item portion, which will be filled in with the background color

    // Get the entire client region of the window.
    GetClientRect(m_hwnd, &ClientRect);

    // Get the bottom y-coordinate of the last item in the control.
    if (ItemCount > 0)
    {
         OnGetItemRect(ItemCount - 1, &ItemsArea);
    }

    // Can skip the rest of this if the control is completely covered by bands
    if (ItemsArea.bottom >= ClientRect.bottom)
    {
        goto paint_items;
    }

    ItemsArea.top = ClientRect.top;
    ItemsArea.left = ClientRect.left;

    // Get the update rectangle.
    GetUpdateRect(m_hwnd, &UpdateRect, FALSE);

    //start the painting operation
    if (FAILED(paint.Begin(m_hwnd)))
    {
        return 0;
    }

    if ((HDC)m_BackBuffer == NULL)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -