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

📄 freebusydisplayitem.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 "FreeBusyDisplayItem.h"
#include "auto_xxx.hxx"
#include "Resource.h"
#include "InfoApp.hpp"
#include "Common.hpp"
#include "PaintHelper.hpp"
#include "SystemTimeUtils.h"
#include "Layout.hpp"

//Settings used by the exchange client

const UINT c_FreeBusyIntervalAmount = 15; //interval of time for each fb character
//settings for the drawn time (the window that we care about)
const UINT c_nTotalWindowHours      = 9;

//Helper constants (also need to be moved to registry)
///TODO: Move to registry
#define MINUTES_IN_HOUR     60
#define INTERVALS_PER_HOUR  (MINUTES_IN_HOUR / c_FreeBusyIntervalAmount)    //4      //60 / 15 = 4
#define DISPLAY_INTERVALS   (INTERVALS_PER_HOUR * c_nTotalWindowHours)      //9*4 = 36

enum FreeBusyStatus
{
    StatusFree      = L'0',
    StatusTentative = L'1',
    StatusBusy      = L'2',
    StatusOOF       = L'3',
    StatusUnknown
};

inline FreeBusyStatus CharToFBStatus(
    WCHAR Char
    )
{
    if (Char >= StatusFree && Char <= StatusOOF)
    {
        return static_cast<FreeBusyStatus>(Char);
    }

    return StatusUnknown;
}

/*------------------------------------------------------------------------------
    GetStatusString
    
    Helper function to get the resource string 
    for the specified status char (from outlook)

    0 - free
    1 - tentative
    2 - busy
    3 - oof
    4+ - unknown
------------------------------------------------------------------------------*/
const WCHAR* GetStatusString(
    FreeBusyStatus status
    )
{
    UINT idStatus = 0;
    switch (status)
    {
    case StatusFree:
        idStatus = IDS_STATUS_FREEBUSY_FREE;
        break;

    case StatusTentative:
        idStatus = IDS_STATUS_FREEBUSY_TENTATIVE;
        break;

    case StatusBusy:
        idStatus = IDS_STATUS_FREEBUSY_BUSY;
        break;

    case StatusOOF:
        idStatus = IDS_STATUS_FREEBUSY_OOF;
        break;

    case StatusUnknown:
    default:
        idStatus = IDS_STATUS_FREEBUSY_UNKNOWN;
        break;
    }

    return CommonUtilities_t::LoadString(GlobalData_t::s_ModuleInstance, idStatus);
}

/*------------------------------------------------------------------------------
    DrawTentative
    
    Drawing helper function. Draws the tentative bitmap into
    the rectangle. 

    Because we don't want to strecth the bitmap, we will
    repeatedly blt the bitmap to cover the rect
------------------------------------------------------------------------------*/
HRESULT DrawTentative(
    HDC hdc,
    RECT *prc
    )
{
    PREFAST_ASSERT(prc);
    
    HRESULT hr            = S_OK;
    RECT    rcDraw        = *prc;

    HBITMAP hbmpTentative = GlobalData_t::s_GDICacheObject.LoadCachedBitmap(IDB_TENTATIVE);

    ce::auto_hdc     hdcTentative; //the dc to blt from

    hr = CommonUtilities_t::ToHR(hbmpTentative != NULL);
    if (FAILED(hr))
    {
        ASSERT(FALSE);
        return hr;
    }
    
    //Load the cached bitmap into the bltfrom DC
    hdcTentative = CreateCompatibleDC(hdc);
    hr = CommonUtilities_t::ToHR(hdcTentative != NULL);
    if (FAILED(hr))
    {
        ASSERT(FALSE);
        return hr;
    }
    
    //Select the bitmap into the bltting dc
    HBITMAP hbmpOld = (HBITMAP)SelectObject(hdcTentative, hbmpTentative);
    
    rcDraw.right = min(rcDraw.left + Layout_t::TentativeBmpWidth(), prc->right);
    while (1)
    {
        //blt this portion of the bitmap
        hr = CommonUtilities_t::ToHR(BitBlt(
            hdc,
            rcDraw.left,
            rcDraw.top,
            rcDraw.right - rcDraw.left,
            rcDraw.bottom - rcDraw.top,
            hdcTentative,
            0,
            0,
            SRCCOPY
            ));
        ASSERT(SUCCEEDED(hr));

        if (rcDraw.right == prc->right)
        {
            break;
        }
        
        rcDraw.left  = rcDraw.right;
        rcDraw.right = min(rcDraw.left + Layout_t::TentativeBmpWidth(), prc->right);
    }

    //restore the bltting dc
    SelectObject(hdcTentative, hbmpOld);
    return hr;
}

/*------------------------------------------------------------------------------
    DrawRun
    
    Helper function to draw a run of free busy data. 
------------------------------------------------------------------------------*/
HRESULT DrawRun(
    HDC hdc,
    RECT *prc,
    const WCHAR wcStatus
    )
{
    FreeBusyStatus  Status = CharToFBStatus(wcStatus);
    
    //tentative is special
    if (Status == StatusTentative)
    {
        return DrawTentative(hdc, prc);
    }

    //all other draws use a solid color brush
    HRESULT          hr           = S_OK;
    COLORREF         crSolidBrush = 0;
    ce::auto_hbrush  hbrDraw;
    
    switch (wcStatus)
    {
    case L'0':
        crSolidBrush = Colors_t::FreeBusy_Free();
        break;

    case L'2':
        crSolidBrush = Colors_t::FreeBusy_Busy();
        break;

    case L'3':
        crSolidBrush = Colors_t::FreeBusy_OOF();
        break;

    default:
        crSolidBrush = Colors_t::FreeBusy_Unknown();
        break;
    }

    hbrDraw = CreateSolidBrush(crSolidBrush);
    hr = CommonUtilities_t::ToHR(hbrDraw != NULL);
    if (FAILED(hr))
    {
        ASSERT(FALSE);
        return hr;
    }

    return CommonUtilities_t::ToHR(FillRect(
        hdc,
        prc,
        hbrDraw
        ) != 0);
}

inline BOOL CanDrawOnOneLine(
    PH_FONT Font,
    __in const WCHAR* pText, 
    UINT cchText,
    UINT LineWidth
    )
{
    RECT CalculateRect = {0};
    PaintHelper_t::CalculateTextDimensions(
        pText,
        -1,
        PHGetFont(Font),
        &CalculateRect,
        DT_TOP | DT_LEFT | DT_NOPREFIX
        );

    return (LineWidth >= RECTWIDTH(CalculateRect));
}

/*------------------------------------------------------------------------------
    CFreeBusyDisplayItem::CFreeBusyDisplayItem
    
    Ctor
------------------------------------------------------------------------------*/
CFreeBusyDisplayItem::CFreeBusyDisplayItem()
{
    ZeroMemory(&m_stStart, sizeof(SYSTEMTIME));
}

CFreeBusyDisplayItem::~CFreeBusyDisplayItem()
{
}

/*------------------------------------------------------------------------------
    CFreeBusyDisplayItem::GetHeight
    
    Gets the height of the item
    
    Parameters:
        pfHeight: OUT - The height to fill in
    
    Returns (BOOL): TRUE if we set the height
------------------------------------------------------------------------------*/
BOOL CFreeBusyDisplayItem::GetHeight(
    UINT *pfHeight
    )
{
    PREFAST_ASSERT(pfHeight);
    *pfHeight = Layout_t::FreeBusyItemHeight();
    return TRUE;
}

/*------------------------------------------------------------------------------
    CFreeBusyDisplayItem::SetDisplayName
    
    Sets the name to display
------------------------------------------------------------------------------*/
HRESULT CFreeBusyDisplayItem::SetDisplayName(
    const WCHAR * c_wszDisplayName
    )
{
    if (c_wszDisplayName == NULL)
    {
        ASSERT(FALSE);
        return E_POINTER;
    }

    if (! m_wstrDisplayName.assign(c_wszDisplayName))
    {
        return E_OUTOFMEMORY;
    }
    
    return S_OK;
}

/*------------------------------------------------------------------------------
    CFreeBusyDisplayItem::SetFreeBusyStatus
    
    Sets the free busy status string 
------------------------------------------------------------------------------*/
HRESULT CFreeBusyDisplayItem::SetFreeBusyStatus(
    const WCHAR * c_wszFreeBusyStatus,
    SYSTEMTIME  * pstStart
    )
{
    PREFAST_ASSERT(pstStart && c_wszFreeBusyStatus);

#ifdef DEBUG
    //verify this is a good systemtime
    FILETIME ft = {0};
    ASSERT(SystemTimeToFileTime(pstStart, &ft));
#endif

    memcpy(&m_stStart, pstStart, sizeof(SYSTEMTIME));

    if (! m_wstrFreeBusy.assign(c_wszFreeBusyStatus))
    {
        return E_OUTOFMEMORY;
    }
    
    return S_OK;
}

/*------------------------------------------------------------------------------
    CFreeBusyDisplayItem::Draw
    
    Draws the free busy item
    
    Parameters:
        hdc: The DC to draw into 
        prc: The rectangle to draw into
        fSelected: TRUE iff we are the selected item in the ListBox
    
    Returns (HRESULT): indicating success or failure
------------------------------------------------------------------------------*/
HRESULT CFreeBusyDisplayItem::Draw(
    HDC hdc, 
    const RECT * prc, 
    BOOL fSelected, 
    BOOL fTopItem
    )
{
    PREFAST_ASSERT(prc);

    PaintHelper_t   paint;
    HBRUSH          hbrBackground;
    HRESULT         hr;
    
    //Set up the DC for drawing text
    hr = paint.Attach(hdc);
    if (FAILED(hr))
    {
        ASSERT(FALSE);
        return hr;
    }
    
    paint.SetTextColor(Colors_t::FreeBusy_TextColor());
    paint.SetBkMode(TRANSPARENT);
    
    //The item always has the same background
    hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
    ASSERT(hbrBackground != NULL);

    if (fSelected)
    {
        hr = DrawBand(
            hdc, 
            prc, 
            fSelected, 
            fTopItem
            );
    }
    else
    {
        hr = CommonUtilities_t::ToHR(FillRect(
            hdc,
            prc,
            hbrBackground
            ));
    }
    ASSERT(SUCCEEDED(hr));
    
    //Draw the different components of the item
    hr = DrawName(hdc, prc);
    ASSERT(SUCCEEDED(hr));

    hr = DrawMain(hdc, prc);
    ASSERT(SUCCEEDED(hr));

    //restore the dc
    paint.End();

    return S_OK;
}

HRESULT CFreeBusyDisplayItem::DrawMain(
    HDC hdc, 
    const RECT *prc
    )
{
    HRESULT hr = DrawFreeBusyTitle(hdc, prc);
    ASSERT(SUCCEEDED(hr));
    
    hr = DrawFreeBusyGraphics(hdc, prc);
    ASSERT(SUCCEEDED(hr));

    return S_OK;
}

/*------------------------------------------------------------------------------
    CFreeBusyDisplayItem::DrawName
    
    Draw the name into the display items rect
------------------------------------------------------------------------------*/
HRESULT CFreeBusyDisplayItem::DrawName(
    HDC hdc,
    const RECT *prc
    )
{
    PREFAST_ASSERT(prc);

    HRESULT  hr       = S_OK;
    RECT     rcDraw   = *prc,
             rcCalc   = {0};

    if (! m_wstrDisplayName[0])
    {
        return S_FALSE;
    }

    PaintHelper_t   paint;
    hr = paint.Attach(hdc);
    if (FAILED(hr))
    {
        ASSERT(FALSE);
        return hr;
    }
        
    
    //Move/resize the rectangle for drawing
    rcDraw.top  +=  Layout_t::FreeBusyMarginHeight();
    rcDraw.left +=  Layout_t::FreeBusyMarginWidth();

    //Create the font to use
    paint.SetFont(PHGetFont(phfLargeText));

    //Make sure that the name fits in the rectangle
    //if the width is greater than what we have, choose a smaller font

    if (! CanDrawOnOneLine(
        phfLargeText, 
        m_wstrDisplayName, 
        m_wstrDisplayName.length(),
        rcDraw.right - rcDraw.left
        ))
    {
        paint.SetFont(PHGetFont(phfStandardTextBold));
    }
    
    //Draw the name (with ellipsis if necessary)
    hr = paint.DrawText(
        m_wstrDisplayName, 
        -1, 
        &rcDraw,
        DT_TOP | DT_LEFT | DT_SINGLELINE | DT_NOPREFIX | DT_END_ELLIPSIS
        );
    ASSERT(SUCCEEDED(hr));
    
    //restore the dc
    paint.End();
    
    return hr;
}

/*------------------------------------------------------------------------------
    CFreeBusyDisplayItem::GetFreeBusyTitle
    
    Helper function that gets the freebusy title based on current time
    (e.g. "Busy until 5:00")
------------------------------------------------------------------------------*/
HRESULT CFreeBusyDisplayItem::GetFreeBusyTitle(

⌨️ 快捷键说明

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