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

📄 listbox.cpp

📁 一个WinCE6。0下的IP phone的源代码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
    {
        //ignore focus, since all we care about is selection
       return TRUE;
    }

    IVoIPDisplayItem* pItem = reinterpret_cast<IVoIPDisplayItem*>(
        OnGetItemData(pDrawStruct->itemID)
        );
    if (!pItem)
    {
        ASSERT(0);
        return TRUE;
    }

    RECT ItemRect = pDrawStruct->rcItem;
#endif

    if (((HDC)m_ItemBackBuffer == NULL) ||
        (RECTHEIGHT(pDrawStruct->rcItem) > RECTHEIGHT(m_ItemBackBuffer.Rect())))
    {
        m_ItemBackBuffer.End();

        if (FAILED(
            m_ItemBackBuffer.CreateCanvas(
                NULL,
                RECTWIDTH(ItemRect),
                RECTHEIGHT(ItemRect)
                )
            ))
        {
            return TRUE;
        }
    }

    RECT DrawRectangle;
    SetRect(
        &DrawRectangle,
        0,
        0,
        RECTWIDTH(ItemRect),
        RECTHEIGHT(ItemRect)
        );

    //if the item is selected, have it set focus to the child controls first
    if ((pDrawStruct->itemState & ODS_SELECTED) &&
        CommonUtilities_t::HasParentalFocus(m_hwnd))
    {
        IVoIPDisplayControl* pControl;
        if (FAILED(
            pItem->QueryInterface(
                IID_IVoIPDisplayControl,
                reinterpret_cast<void**>(&pControl)
                )
            ) ||
            !pControl->SetFocus()
            )
        {
            SetFocus(m_hwnd);
        }
    }

    //Have the item draw into the back buffer
    if (FAILED(
        pItem->Draw(
            m_ItemBackBuffer,
            &DrawRectangle,
            (pDrawStruct->itemState & ODS_SELECTED),
            FALSE
            )
        ))
    {
        return TRUE;
    }

    BitBlt(
        pDrawStruct->hDC,
        ItemRect.left,
        ItemRect.top,
        RECTWIDTH(ItemRect),
        RECTHEIGHT(ItemRect),
        m_ItemBackBuffer,
        0,
        0,
        SRCCOPY
        );

    return TRUE;
}

/*------------------------------------------------------------------------------
    ListBoxImpl_t::OnMeasureItem

    Handles WM_MEASUREITEM

    If this is a variable height listbox then we will be prompted to measure the
    height of a specific item. We delegate that to the current item.

    NOTE: This message MUST be forwarded from the parent if the listbox
    is to handle the measuring of the items
------------------------------------------------------------------------------*/
LRESULT
ListBoxImpl_t::MeasureItem(
    MEASUREITEMSTRUCT* pMeasureStruct
    )
{
#ifdef VIRTUAL_LISTBOX
    //Get the item to measure
    IVoIPDisplayItem* pItem = reinterpret_cast<IVoIPDisplayItem*>(
        OnGetItemData(Index)
        );
    if (!pItem)
    {
        ASSERT(0);
        return FALSE;
    }

    RECT ClientRect = {0};
    GetClientRect(m_hwnd, &ClientRect);

    UINT ItemHeight;

    //ask the item to get its height
    if (!pItem->GetHeight(&ItemHeight))
    {
        //if the item doesn't know how to gets its height, set the default
        ItemHeight = Layout_t::ListBoxDefaultItemHeight;
    }

    m_VariableHeight[Index] = ItemHeight;
#else
    if (!pMeasureStruct)
    {
        return FALSE;
    }

    //Get the item to measure
    IVoIPDisplayItem* pItem = reinterpret_cast<IVoIPDisplayItem*>(
        OnGetItemData(pMeasureStruct->itemID)
        );
    if (!pItem)
    {
        ASSERT(0);
        return FALSE;
    }

    RECT ClientRect;
    GetClientRect(m_hwnd, &ClientRect);

    pMeasureStruct->itemWidth = RECTWIDTH(ClientRect);

    //ask the item to get its height
    if (!pItem || !pItem->GetHeight(&pMeasureStruct->itemHeight))
    {
        //if the item doesn't know how to gets its height, set the default
        pMeasureStruct->itemHeight = Layout_t::ListBoxDefaultItemHeight();
    }
#endif

    return TRUE;
}

LRESULT
ListBoxImpl_t::OnFindItem(
    IVoIPDisplayItem* pItem
    )
{
    return DefWindowProc(LB_FINDSTRING, 0, (LPARAM)pItem);
}

/*------------------------------------------------------------------------------
    ListBoxImpl_t::OnSetCtrlBkgd

    Sent when a child control needs a background brush. The rule is, if the
    item is selected it gets a white brush, if the item is NOT selected
    it gets the standard LBBackground for this control
------------------------------------------------------------------------------*/
LRESULT
ListBoxImpl_t::OnSetControlBackground(
    UINT Message,
    HDC hdc,
    HWND Control
    )
{
    //Read only controls are handled by the def window proc
    SetBkMode(hdc, TRANSPARENT);

    if (GlobalData_t::s_ListBoxBrush == NULL)
    {
        GlobalData_t::s_ListBoxBrush = CreateSolidBrush(Colors_t::ListBoxBackgroundColor());
        ASSERT(GlobalData_t::s_ListBoxBrush);
    }

    if ((Message == WM_CTLCOLORSTATIC) &&
        (GetWindowLong(Control, GWL_STYLE) & ES_READONLY))
    {
        return reinterpret_cast<LRESULT>(GlobalData_t::s_ListBoxBrush);
    }

    //otherwise we want drawing done transparently wrt the background
    if (Control == GetFocus())
    {
        return reinterpret_cast<LRESULT>(GetStockObject(WHITE_BRUSH));
    }
    else
    {
        return reinterpret_cast<LRESULT>(GlobalData_t::s_ListBoxBrush);
    }
}

/*------------------------------------------------------------------------------
    ListBoxImpl_t::OnTimer

    Shows a tool tip (if it needs to be shown)
------------------------------------------------------------------------------*/
LRESULT
ListBoxImpl_t::OnTimer(
    )
{
    if (
        !m_CheckToolTip   ||
        (OnGetCount() <= 0)  ||
        ((GetTickCount() - m_dwToolTipTimer) < c_cmsToolTipLag)
        )
    {
        return 0;
    }

    int IndexToSelect;
    RECT ItemRect;
    RECT ToolTipRect;
    RECT ClientRect;
    UINT yTop = 0;
    SIZE size = {0};

    IndexToSelect = OnGetCurSel();
    if (IndexToSelect == LB_ERR)
    {
        return 0;
    }

    GetClientRect(m_hwnd, &ClientRect);
    OnGetItemRect(IndexToSelect, &ItemRect);

    m_ToolTip.GetWindowMetrics(RECTWIDTH(ItemRect), &size);

    yTop = ItemRect.bottom - (RECTHEIGHT(ItemRect)/2);
    if ((yTop + size.cy) > ClientRect.bottom)
    {
        yTop = ItemRect.bottom - size.cy - (RECTHEIGHT(ItemRect)/2);
    }

    ToolTipRect.left = ItemRect.right - size.cx;
    ToolTipRect.top = yTop;
    ToolTipRect.right = ItemRect.right;
    ToolTipRect.bottom = yTop + size.cy;

    MoveWindow(
        (HWND)m_ToolTip,
        ToolTipRect.left,
        ToolTipRect.top,
        RECTWIDTH(ToolTipRect),
        RECTHEIGHT(ToolTipRect),
        FALSE
        );

    ShowWindow((HWND)m_ToolTip, SW_SHOW);

    m_CheckToolTip = false;

    return 0;
}

#ifdef AUTOMATION
//Automation helper functions
#define MAX_LB_TEXT         MAX_PATH
#define MAX_LB_SUBTEXT_CT   8


LRESULT
ListBoxImpl_t::OnGetTextLen(
    int Index
    )
{
    return MAX_LB_TEXT;
}

LRESULT
ListBoxImpl_t::OnGetText(
    int Index,
    __out_ecount(MAX_LB_TEXT) WCHAR* pBuffer
    )
{
    __try
    {
        WCHAR* pwchCopy  = pBuffer;
        WCHAR* pwchStart = pwchCopy;

        IVoIPDisplayItem* pItem = NULL;

        pItem = reinterpret_cast<IVoIPDisplayItem*>(OnGetItemData(Index));
        if (!pItem)
        {
            return LB_ERR;
        }

        for (
            int i = 0;
            i < MAX_LB_SUBTEXT_CT && (pwchCopy - pwchStart) < MAX_LB_TEXT;
            i++
            )
        {
            if (pItem->GetSubItemText(
                i,
                pwchCopy,
                MAX_LB_TEXT - (pwchCopy - pwchStart)
                ) != S_OK)
            {
                *pwchCopy = 0;
                break;
            }
            else
            {
                pwchCopy += wcslen(pwchCopy);
                if ((pwchCopy - pwchStart) < MAX_LB_TEXT)
                {
                    *pwchCopy = STRING_DELIMITER;
                    pwchCopy++;
                }
            }
        }

        pwchStart[MAX_LB_TEXT - 1] = L'\0';
        return (LRESULT)(INT)(pwchCopy - pwchStart);
    }
    __except(EXCEPTION_EXECUTE_HANDLER)
    {
        RETAILMSG(1, (L"Buffer not at least MAX_LB_TEXT chars in length! Call LB_GETTEXTLEN first!"));
        return LB_ERR;
    }
}
#endif


/*------------------------------------------------------------------------------
    ListBoxImpl_t::OnSettingChange

    Handels WM_SETTINGCHANGE passed from UIManager

    if it is caused by the Sip panel changes, reposition the items accordingly
------------------------------------------------------------------------------*/
LRESULT
ListBoxImpl_t::OnSettingChange(
    UINT Flag
    )
{
    switch (Flag)
    {
    case SPI_SETSIPINFO:
    case SPI_SIPMOVE:
        //Caused by Sip panel changes
        RepositionDisplayItems();
        return 0;

    default:
        return 0;
    }

    return 1;
}

/*------------------------------------------------------------------------------
    ListBoxImpl_t::RepositionDisplayItems

    Reposition each display items when there is some change caused by Sip panel

    Returns (HRESULT): indicating success or failure
------------------------------------------------------------------------------*/
HRESULT
ListBoxImpl_t::RepositionDisplayItems(
    void
    )
{
    int SelectedItem = OnGetCurSel();
    int NewTop = OnGetTopIndex();

    if ((SelectedItem == LB_ERR) || (NewTop == LB_ERR))
    {
        return S_FALSE;
    }

    RECT ItemRect;
    RECT WindowRect;

    bool NeedToReposition = false;

    if (OnGetItemRect(SelectedItem, &ItemRect) == LB_ERR)
    {
        ASSERT(FALSE);
        return E_FAIL;
    }

    //If the Sip panel is being on
    if (Input_IsInputPanelVisible())
    {
        //Get the corresponding listbox new height by substracting listbox top from the
        //Sip panel's top
        GetWindowRect(m_hwnd, &WindowRect);

        int ListBoxHeightWithInputPanel = Input_GetInputPanelTop() - WindowRect.top;
        if (ListBoxHeightWithInputPanel < 0)
        {
            goto resize_back_to_original_size;
        }

        //if current item's bottom is greater than new height, then it is obscured by
        //the sip panel, so we need to reposition those items
        if (ItemRect.bottom > ListBoxHeightWithInputPanel)
        {
            NeedToReposition = true;
            OnSetRedraw(FALSE);

            NewTop = GetNewTopIndex(m_hwnd, SelectedItem, ListBoxHeightWithInputPanel);

            //set the new top index
            OnSetTopIndex(NewTop);

            //Check if the top index is different than it is being just set
            //it means we are at very last page
            if ((NewTop != OnGetTopIndex())&&(!m_ListBoxHeightChanged))
            {
                //Shrink the list box window to a new height
                if (!SetWindowPos(
                        m_hwnd,
                        NULL,
                        0,
                        0,
                        RECTWIDTH(WindowRect),
                        ListBoxHeightWithInputPanel,
                        SWP_NOMOVE | SWP_NOZORDER | SWP_SHOWWINDOW
                        ))
                {
                    ASSERT(FALSE);
                    return CommonUtilities_t::GetErrorFromWin32();
                }
                //Set the flag variable to be TRUE
                m_ListBoxHeightChanged = true;
            }

        }

    }
    else
    {
    resize_back_to_original_size:
        //If the sip panel is being OFF and the window has been shrinked
        if (m_ListBoxHeightChanged)
        {
            NeedToReposition = true;
            OnSetRedraw(FALSE);

            GetWindowRect(m_hwnd, &WindowRect);

            //restore the original window height
            if (!SetWindowPos(
                    m_hwnd,
                    NULL,
                    0,
                    0,
                    RECTWIDTH(WindowRect),
                    m_OriginalHeight, //restore the original height (initialized on WM_CREATE)
                    SWP_NOMOVE | SWP_NOZORDER | SWP_SHOWWINDOW
                    ))
            {
                ASSERT(FALSE);
                return CommonUtilities_t::GetErrorFromWin32();
            }
            //reset the flag variable back to FALSE
            m_ListBoxHeightChanged = false;
        }
    }

    //If we need to reposition, set the new top index, and redraw
    if (NeedToReposition)
    {
        OnSetTopIndex(NewTop);
        OnSetRedraw(TRUE);
    }

    return S_OK;
}

/*------------------------------------------------------------------------------
    ListBoxImpl_t::GetNextSelectableIndex

    Helper function to get the index of the next selectable item

    Parameters:
        IndexToSelect : the index is currently selected
        IsKeyUp: indicates if the Up key is pressed or not

    Returns (int): the index of next selectable item, if there is something wrong
                    return LB_ERR
------------------------------------------------------------------------------*/
int
ListBoxImpl_t::GetNextSelectableIndex(
    UINT IndexToSelect,
    bool IsKeyUp
    )
{
    IVoIPDisplayItem* pItem = NULL;
    int ItemCount = OnGetCount();
    int IndexLoop = ItemCount;

    pItem = (IVoIPDisplayItem *)OnGetItemData(IndexToSelect);
    if (!pItem)
    {
        return LB_ERR;
    }

    while (!pItem->IsSelectable())
    {
        if ((IndexToSelect == 0) && IsKeyUp)
        {
            IndexToSelect =  - 1;
        }
        else
        {
            IndexToSelect = IsKeyUp ? IndexToSelect - 1 : (IndexToSelect + 1) % ItemCount;
        }

        pItem = (IVoIPDisplayItem *)OnGetItemData(IndexToSelect);
        if (!pItem)
        {
            return LB_ERR;
        }

        if (-- IndexLoop <= 0)
        {
            return LB_ERR;
        }
    }

    return IndexToSelect;

}

⌨️ 快捷键说明

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