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

📄 outlookcontactlist.cpp

📁 一个WinCE6。0下的IP phone的源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this sample source code is subject to the terms of the Microsoft
// license agreement under which you licensed this sample source code. If
// you did not accept the terms of the license agreement, you are not
// authorized to use this sample source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the LICENSE.RTF on your install media or the root of your tools installation.
// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES.
//
#include "OutlookContactList.hpp"
#include "Common.hpp"
#include "DisplayItem.hpp"
#include "InfoApp.hpp"
#include <winuserm.h>
#include "PhoneAPI.hpp"
#include "SettingsApi.hpp"
#include "VoIPNotify.hpp"

#define INITIAL_ITEM_THRESHOLD  40
#define ADD_REST_OF_ITEMS_DELAY 900 //wait most of 1 second...
#define USER_RESPONSE_DELAY     250 //wait 1/4th of a second for the user to finish typing

/*------------------------------------------------------------------------------
    FilterToLabelId
    
    Convert a filter to a string id
------------------------------------------------------------------------------*/
inline int FilterToLabelId(
    OutlookContactListDialog_t::Filter_e    filter
    )
{
    switch (filter)
    {
    case OutlookContactListDialog_t::FirstName:
        return IDS_LABEL_FIRSTNAME;
        
    case OutlookContactListDialog_t::LastName:
        return IDS_LABEL_LASTNAME;

    case OutlookContactListDialog_t::Predictive:
        return IDS_LABEL_PREDICTIVE;

    default:
        ASSERT(FALSE);
        return 0;
    }
}

/*------------------------------------------------------------------------------
    MatchesFirstName
    
    Does this contact match the first name filter?
------------------------------------------------------------------------------*/
bool MatchesFirstName(
    const WCHAR* pToMatch, 
    int          Len,
    IContact*    pContact
    )
{
    ASSERT(pToMatch && pContact);

    ce::auto_bstr ContactFirstName;
    pContact->get_FirstName(&ContactFirstName);

    if (! ContactFirstName)
    {
        return false;
    }

    return (wcsnicmp(pToMatch, ContactFirstName, Len) == 0);
}

/*------------------------------------------------------------------------------
    MatchesLastName
    
    Does this contact match the last name filter?
------------------------------------------------------------------------------*/
bool MatchesLastName(
    const WCHAR* pToMatch, 
    int          Len,
    IContact*    pContact
    )
{
    ASSERT(pToMatch && pContact);

    ce::auto_bstr ContactLastName;
    pContact->get_LastName(&ContactLastName);

    if (! ContactLastName)
    {
        return false;
    }

    return (wcsnicmp(pToMatch, ContactLastName, Len) == 0);
}

/*------------------------------------------------------------------------------
    PredictiveMatch
    
    Does the Check string match the predictive filter string?
------------------------------------------------------------------------------*/
bool PredictiveMatch(
    const WCHAR*  pFilterText,
    int           TextLen,
    const WCHAR*  pCheck
    )
{
    //10 digits...(0-9)
    static const WCHAR* s_MatchGroups[10] =
    {
        L"",    //nothing
        L"*",   //everything
        L"abc", // 2
        L"def", // 3
        L"ghi", // 4
        L"jkl", // 5
        L"mno", // 6
        L"pqrs",// 7
        L"tuv", // 8
        L"wxyz",// 9
    };

    if (wcslen(pCheck) < wcslen(pFilterText))
    {
        return false;
    }
    
    const WCHAR* pRead = pCheck;
    const WCHAR* pCurrentFilter = pFilterText;

    while (*pCurrentFilter)
    {
        int Value = (*pCurrentFilter - L'0');

        //verify this is a digit...
        if (Value < 0 || Value >= _countof(s_MatchGroups))
        {
            return false;
        }

        //get the possible characters
        const WCHAR* pGroup = s_MatchGroups[Value];
        if (! pGroup[0])
        {
            return false;
        }

        //does it match this group (or wildcard) ?
        if (pGroup[0] == L'*' || wcschr(pGroup,towlower(*pRead)))
        {
            pRead++;
            pCurrentFilter++;
            continue;
        }

        return false;
    }

    return true;
}

/*------------------------------------------------------------------------------
    GetHighlightIndex
    
    Parse the "FileAs" attribute of the contact for the appropriate
    highlight indices
------------------------------------------------------------------------------*/
void
GetHighlightIndex(
    const WCHAR* pMatch, 
    int          FilterLen,
    IContact*    pContact,
    bool         IsFirstName,
    int*         pHighlightStart,
    int*         pHighlightEnd
    )
{
    ASSERT(pMatch && pContact && pHighlightEnd && pHighlightStart);

    const WCHAR* pSecondWord = NULL;
    ce::auto_bstr bstrFileAs;
    
    if (! IsFirstName)
    {
        goto do_default;
    }

    pContact->get_FileAs(&bstrFileAs);
    if (! bstrFileAs)
    {
        goto do_default;
    }
    
    //skip over the first word...
    pSecondWord = bstrFileAs;
    while (*pSecondWord && *pSecondWord != L' ' && *pSecondWord != L',')
    {
        pSecondWord++;
    }

    if (! *pSecondWord)
    {
        goto do_default;
    }

    pSecondWord = wcsstr(pSecondWord, pMatch);
    if (! pSecondWord)
    {
        goto do_default;
    }

    *pHighlightStart = pSecondWord - (const WCHAR*)bstrFileAs;
    *pHighlightEnd   = (*pHighlightStart + FilterLen - 1);
    return;

do_default:    
    *pHighlightStart = 0;
    *pHighlightEnd   = FilterLen-1;
    return;
}

/*------------------------------------------------------------------------------
    MatchesPredictiveFilter
    
    Does this contact match the predictive filter?
------------------------------------------------------------------------------*/
bool MatchesPredictiveFilter(
    const WCHAR*    pFilterText,
    int             TextLen,
    IContact*       pContact,
    int*            pHighlightStart, 
    int*            pHighlightEnd
    )
{
    ce::auto_bstr FirstName;
    pContact->get_FirstName(&FirstName);
    if (PredictiveMatch(pFilterText, TextLen, FirstName))
    {
        GetHighlightIndex(FirstName, TextLen, pContact, true, pHighlightStart, pHighlightEnd);
        return true;
    }
    
    ce::auto_bstr LastName;
    pContact->get_LastName(&LastName);
    if (PredictiveMatch(pFilterText, TextLen, LastName))
    {
        GetHighlightIndex(FirstName, TextLen, pContact, false, pHighlightStart, pHighlightEnd);
        return true;
    }

    return false;
}

/*------------------------------------------------------------------------------
    MatchesFilter
    
    Does this contact pass the filter?
------------------------------------------------------------------------------*/
inline bool MatchesFilter(
    OutlookContactListDialog_t::Filter_e    filter, 
    const WCHAR*                            pFilterText,
    int                                     TextLen,
    IContact*                               pContact,
    int*                                    pHighlightStart,
    int*                                    pHighlightEnd
    )
{
    if (!TextLen || ! pFilterText || ! pFilterText[0])
    {
        return true;
    }

    switch (filter)
    {
    case OutlookContactListDialog_t::FirstName:
        return MatchesFirstName(pFilterText, TextLen, pContact);
        
    case OutlookContactListDialog_t::LastName:
        return MatchesLastName(pFilterText, TextLen, pContact);

    case OutlookContactListDialog_t::Predictive:
        return MatchesPredictiveFilter(pFilterText, TextLen, pContact, pHighlightStart, pHighlightEnd);

    default:
        ASSERT(FALSE);
        return true;
    }
}

/*------------------------------------------------------------------------------
    OutlookContactListDialog_t::OutlookContactListDialog_t
    
    Ctor
------------------------------------------------------------------------------*/
OutlookContactListDialog_t::OutlookContactListDialog_t()
{
    m_CurrentMenuId     = 0;
    m_AddItemsTimer     = 0;
    m_UserResponseTimer = 0;
    m_Filter            = static_cast<Filter_e>(PHGetSetting(phsContactFilterType));
    
    if(m_Filter >= UnknownFilter)
    {
        ASSERT(FALSE);
        m_Filter = FirstName;
    }
}

/*------------------------------------------------------------------------------
    OutlookContactListDialog_t::~OutlookContactListDialog_t
    
    Dtor
------------------------------------------------------------------------------*/
OutlookContactListDialog_t::~OutlookContactListDialog_t()
{
    PHSetValue(phsContactFilterType, m_Filter);
    StopTimer(UserResponseTimer);
    StopTimer(AddItemsTimer);
}

/*------------------------------------------------------------------------------
    OutlookContactListDialog_t::CreateDialogScreen
    
    Create the dialog screen
------------------------------------------------------------------------------*/
HRESULT
OutlookContactListDialog_t::CreateDialogScreen(
    InfoApp_t* pApp
    )
{
    ASSERT(pApp);

    //make sure we can get the POOM instance before loading this page...
    HRESULT hr = pApp->GetOutlookApp(&m_cpOutlookApp);
    if (FAILED(hr))
    {
        return hr;
    }

    m_CurrentMenuId = IDMB_OUTLOOKCONTACTLIST;
    
    return DialogScreen_t::CreateDialogScreen(
        PHINFO_OUTLOOK_CONTACT_LIST_SCREEN_ID, 
        m_CurrentMenuId, 
        CommonUtilities_t::LoadString(GlobalData_t::s_ModuleInstance, IDS_TITLE_OUTLOOKCONTACTS), 
        L""
        );
}

/*------------------------------------------------------------------------------
    OutlookContactListDialog_t::HookProc
    
    Dialog proc callback (handles windows messages)
------------------------------------------------------------------------------*/
BOOL
OutlookContactListDialog_t::HookProc(
    HWND hwnd, 
    UINT Message, 
    WPARAM wParam, 
    LPARAM lParam
    )
{
    HRESULT hr = S_OK;
    
    switch (Message)
    {
    case WM_INITDIALOG:
        if (FAILED(OnInitDialog()))
        {
            DestroyWindow(hwnd);
        }
        return FALSE;

    case WM_TIMER:
        hr = OnTimer(wParam);
        break;

    case WM_VKEYTOITEM:
        hr = SetFocusToFirstItem();
        break;

    case WM_COMMAND:
        switch (HIWORD(wParam))
        {
        case EN_UPDATE:
            UpdateQueryString();
            hr = StartTimer(UserResponseTimer);
            break;

        case LBN_SELCHANGE:
            OnSelectionChange();
            break;

        case 0:        
            switch (LOWORD(wParam))
            {
            case IDOK:
                hr = DialogScreen_t::Exit();
                break;

            case IDC_DIAL:
                hr = OnDial();
                break;

            case IDC_DETAILS:
                hr = OnDetails();
                break;
                
            case IDC_BACKSPACE:
                hr = DialogScreen_t::OnBackspace();
                break;

            case IDC_FILTER_FIRSTNAME:
                hr = UpdateFilter(FirstName);
                break;

            case IDC_FILTER_LASTNAME:
                hr = UpdateFilter(LastName);
                break;

            case IDC_FILTER_PREDICTIVE:
                hr = UpdateFilter(Predictive);
                break;
                
            default:
                return FALSE;
            }
            break;
        }
        break;

    default:
        return FALSE;
    }

    return SUCCEEDED(hr);
}

/*------------------------------------------------------------------------------
    OutlookContactListDialog_t::OnInitDialog
    
    Initialize the dialog
------------------------------------------------------------------------------*/
HRESULT
OutlookContactListDialog_t::OnInitDialog()
{
    //add the labeled item
    IVoIPDisplayItem* pItem;
    HRESULT hr = PHCreateLabeledEditDisplayItem(
        CommonUtilities_t::LoadString(GlobalData_t::s_ModuleInstance, FilterToLabelId(m_Filter)), 
        WS_BORDER | ((m_Filter == Predictive) ? ES_NUMBER : 0), 
        -1, 
        &pItem, 
        -1, 
        (m_Filter == Predictive) ? EIM_NUMBERS : EIM_SPELL
        );
    if (FAILED(hr))
    {
        ASSERT(FALSE);
        return hr;
    }

    hr = m_Listbox.AddItem(0, pItem);
    if (FAILED(hr))
    {
        delete pItem;
        return hr;
    }

    //hide the backspace button
    UpdateQueryString();
    
    return Refresh(AddBeginningOfItems);
}

HRESULT 
OutlookContactListDialog_t::Refresh(
    RefreshType_e   type
    )
{
    //disable redrawing...
    SendMessage(m_Listbox, WM_SETREDRAW, FALSE, 0);

    int ExistingItemCount = m_Listbox.GetCount();

    //keep the old items if we are adding the delayed items
    if (type != AddRestOfItems)
    {
        //clear the listbox (except for the first item)
        while (ExistingItemCount > 1)
        {
            SendMessage(m_Listbox, LB_DELETESTRING, 1, 0);
            ExistingItemCount--;
        }
    }
    else
    {
        //make sure there hasn't been a filter change since last time we
        //updated...
        if (ExistingItemCount != (INITIAL_ITEM_THRESHOLD + 1))
        {
            return S_FALSE;
        }
    }

    //add each item...
    CComPtr<IFolder>                    cpFolder;
    CComPtr<IPOutlookItemCollection>    cpItems;

    ce::auto_bstr SortOrder;
    int           TotalItems;
    
    int           CurrentItem;
    int           LastItem;

    HRESULT hr;

    STATUS_HEADER_PARAMETERS_EX StatusParams;
    WCHAR StatusText[MAX_PATH] = L"";
    
    IVoIPDisplayItem* pEditItem = m_Listbox.GetItem(0);
    if (! pEditItem)
    {
        ASSERT(FALSE);
        hr = E_UNEXPECTED;
        goto exit;
    }
    
    //get our contacts from POOM
    hr = m_cpOutlookApp->GetDefaultFolder(
        olFolderContacts, 
        &cpFolder
        );
    if (FAILED(hr))
    {
        ASSERT(FALSE);
        goto exit;
    }

    hr = cpFolder->get_Items(&cpItems);
    if (FAILED(hr))
    {
        ASSERT(FALSE);
        goto exit;
    }

    //sort the collection by the necessary sort order
    SortOrder = SysAllocString(L"[FileAs]");
    if (! SortOrder)
    {
        hr = E_OUTOFMEMORY;
        goto exit;
    }

    hr = cpItems->Sort(SortOrder, VARIANT_FALSE);
    if (FAILED(hr))
    {
        ASSERT(FALSE);
        goto exit;

⌨️ 快捷键说明

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