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

📄 painthelper.cpp

📁 一个WinCE6。0下的IP phone的源代码
💻 CPP
字号:
//
// 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 "PaintHelper.hpp"
#include "Common.hpp"


#define INVALID_BKMODE  -1

//constants
const DWORD PaintHelper_t::CANVAS_CREATED = 0x00000001;


PaintHelper_t::PaintHelper_t(
    )
{
    ZeroMemory(&m_PaintStruct, sizeof(PAINTSTRUCT));
    m_OldBitmap = NULL;
    m_OldBkColor = CLR_INVALID;
    m_OldBkMode = INVALID_BKMODE;
    m_OldBrush = NULL;
    m_OldFont = NULL;
    m_OldPen = NULL;
    m_OldTextColor = CLR_INVALID;
    m_hwnd = NULL;

    m_Flags = 0;
}

PaintHelper_t::~PaintHelper_t(
    )
{
    End();
}

HRESULT
PaintHelper_t::Attach(
    HDC hdc
    )
{
    ASSERT(m_hdc == NULL);

    if (!hdc)
    {
        return E_INVALIDARG;
    }

    m_hdc = hdc;
    return S_OK;
}

HRESULT
PaintHelper_t::Begin(
    HWND hwnd
    )
{
    ASSERT(m_hdc == NULL);

    m_hwnd = hwnd;
    m_hdc = BeginPaint(hwnd, &m_PaintStruct);

    if (!m_hdc)
    {
        return CommonUtilities_t::GetErrorFromWin32();
    }

    m_OldTextColor = GetTextColor(m_PaintStruct.hdc);
    return S_OK;
}

void
PaintHelper_t::End(
    )
{
    if (!m_hdc)
    {
        return;
    }

    if (m_OldBitmap)
    {
        SelectObject(m_hdc, m_OldBitmap);
        m_OldBitmap = NULL;
    }

    if (m_OldBkColor != CLR_INVALID)
    {
        ::SetBkColor(m_hdc, m_OldBkColor);
        m_OldBkColor = CLR_INVALID;
    }

    if (m_OldBkMode != INVALID_BKMODE)
    {
        ::SetBkMode(m_hdc, m_OldBkMode);
        m_OldBkMode = INVALID_BKMODE;
    }

    if (m_OldBrush)
    {
        SelectObject(m_hdc, m_OldBrush);
        m_OldBrush = NULL;
    }

    if (m_OldFont)
    {
        SelectObject(m_hdc, m_OldFont);
        m_OldFont = NULL;
    }

    if (m_OldPen)
    {
        SelectObject(m_hdc, m_OldPen);
        m_OldPen = NULL;
    }

    if (m_OldTextColor != CLR_INVALID)
    {
        ::SetTextColor(m_PaintStruct.hdc, m_OldTextColor);
        m_OldTextColor = CLR_INVALID;
    }

    if (m_PaintStruct.hdc)
    {
        EndPaint(m_hwnd, &m_PaintStruct);
        ZeroMemory(&m_PaintStruct, sizeof(PAINTSTRUCT));
    }

    if (!(m_Flags & CANVAS_CREATED))
    {
        //release the device context since we do not own it
        m_hdc.release();
    }

    if (m_Bitmap.valid())
    {
        SetRectEmpty(&m_PaintStruct.rcPaint);
        m_Bitmap = NULL;
    }

    m_hdc = NULL;
    m_Flags = 0;
}

HRESULT
PaintHelper_t::CreateCanvas(
    HWND hwnd,
    int Width,
    int Height
    )
{
    ASSERT(m_hdc == NULL);

    ce::auto_hdc Screen = GetDC(hwnd);

    if (!Screen)
    {
        return CommonUtilities_t::GetErrorFromWin32(E_OUTOFMEMORY);
    }

    ce::auto_hdc OffScreen = CreateCompatibleDC(Screen);
    if (!OffScreen)
    {
        return CommonUtilities_t::GetErrorFromWin32(E_OUTOFMEMORY);
    }

    m_Flags |= CANVAS_CREATED;

    //create bitpmap only when requested
    if ((Width > 0) && (Height > 0))
    {
        m_Bitmap = CreateCompatibleBitmap(Screen, Width, Height);
        if (!m_Bitmap)
        {
            return CommonUtilities_t::GetErrorFromWin32(E_OUTOFMEMORY);
        }
        m_hdc = OffScreen.release();
        SetBitmap(m_Bitmap);

        SetRect(&m_PaintStruct.rcPaint, 0, 0, Width, Height);
    }
    else
    {
        m_hdc = OffScreen.release();
    }

    return S_OK;
}

HBITMAP
PaintHelper_t::SetBitmap(
    HBITMAP bitmap
    )
{
    HBITMAP OldBitmap = NULL;

    if (bitmap)
    {
        OldBitmap = (HBITMAP)SelectObject(m_hdc, bitmap);
        if (m_OldBitmap == NULL)
        {
            m_OldBitmap = OldBitmap;
        }
    }
    else if (m_OldBitmap)
    {
        //restore original bitmap
        OldBitmap = (HBITMAP)SelectObject(m_hdc, m_OldBitmap);
        m_OldBitmap = NULL;
    }
    return OldBitmap;
}

void
PaintHelper_t::SetBkColor(
    COLORREF color
    )
{
    COLORREF OldColor = ::SetBkColor(m_hdc, color);
    if (m_OldBkColor == CLR_INVALID)
    {
        m_OldBkColor = OldColor;
    }
    return;
}

void
PaintHelper_t::SetBkMode(
    int BkMode
    )
{
    int OldMode = ::SetBkMode(m_hdc, BkMode);

    if (m_OldBkMode == INVALID_BKMODE)
    {
        m_OldBkMode = OldMode;
    }
    return;
}

void
PaintHelper_t::SetBrush(
    HBRUSH brush
    )
{
    if (brush)
    {
        HBRUSH OldBrush = (HBRUSH)SelectObject(m_hdc, brush);
        if (m_OldBrush == NULL)
        {
            m_OldBrush = OldBrush;
        }
    }
    else if (m_OldBrush)
    {
        //restore original brush
        SelectObject(m_hdc, m_OldBrush);
        m_OldBrush = NULL;
    }
    return;
}

void
PaintHelper_t::SetFont(
    HFONT font
    )
{
    HFONT OldFont = (HFONT)SelectObject(m_hdc, font);
    if (m_OldFont == NULL)
    {
        m_OldFont = OldFont;
    }
    return;
}

void
PaintHelper_t::SetPen(
    HPEN Pen
    )
{
    if (Pen)
    {
        HPEN OldPen = (HPEN)SelectObject(m_hdc, Pen);
        if (m_OldPen == NULL)
        {
            m_OldPen = OldPen;
        }
    }
    else if (m_OldPen)
    {
        //restore original pen
        SelectObject(m_hdc, m_OldPen);
        m_OldPen = NULL;
    }
    return;
}

void
PaintHelper_t::SetTextColor(
    COLORREF color
    )
{
    COLORREF OldColor = ::SetTextColor(m_hdc, color);
    if (m_OldTextColor == CLR_INVALID)
    {
        m_OldTextColor = OldColor;
    }
    return;
}

PaintHelper_t&
PaintHelper_t::operator=(
    PaintHelper_t& Source
    )
{
    BitBlt(
        m_hdc,
        Source.Rect().left,
        Source.Rect().top,
        RECTWIDTH(Source.Rect()),
        RECTHEIGHT(Source.Rect()),
        Source,
        0,
        0,
        SRCCOPY
        );
    return *this;
}

PaintHelper_t::operator HDC(
    )
{
    return (HDC)m_hdc;
}

HRESULT
PaintHelper_t::DrawText(
    const WCHAR* pText,
    int TextLength,
    const RECT* pRect,
    DWORD StyleFlags
    )
{
    if (!::DrawText(
        m_hdc,
        pText,
        TextLength,
        (RECT*)pRect,
        StyleFlags
        ))
    {
        return CommonUtilities_t::GetErrorFromWin32();
    }

    return S_OK;
}

HRESULT
PaintHelper_t::CalculateTextDimensions(
    const WCHAR* pText,
    int TextLength,
    HFONT FontToBeUsed,
    RECT* pRectangle,
    UINT DrawTextFlags
    )
{
    if (!pText || !pRectangle)
    {
        return E_INVALIDARG;
    }

    HRESULT hr;
    PaintHelper_t fake;

    hr = fake.CreateCanvas(NULL);
    if (FAILED(hr))
    {
        ASSERT(FALSE);
        return hr;
    }

    fake.SetFont(FontToBeUsed);

    hr = fake.DrawText(
        pText,
        TextLength,
        pRectangle,
        DrawTextFlags | DT_CALCRECT
        );

    return hr;
}

HRESULT
PaintHelper_t::TileBlt(
    __in Bitmap_t* pBitmap3x3Tiles,
    __in const RECT* pDestinationRect,
    __in_opt const RECT* pSourceRect,
    int cxLeft,
    int cyTop,
    int cxRight,
    int cyBottom,
    COLORREF TransparentColor
    )
{
    RECT SourceRect;

    if (!pBitmap3x3Tiles || !pDestinationRect)
    {
        return E_INVALIDARG;
    }

    if (!pSourceRect)
    {
        SetRect(
            &SourceRect,
            0,
            0,
            pBitmap3x3Tiles->Width(),
            pBitmap3x3Tiles->Height()
            );
        pSourceRect = &SourceRect;
    }

    struct Tile_t
    {
        bool m_ShouldBePainted;
        RECT m_DestinationRect;
        RECT m_SourceRect;
    };

    const Tile_t c_TilesToPaint[] =
    {
        {// Upper left corner
            (cxLeft > 0 && cyTop > 0),
            {pDestinationRect->left, pDestinationRect->top, cxLeft, cyTop},
            {pSourceRect->left, pSourceRect->top, cxLeft, cyTop}
        },
        {// Upper right corner
            (cxRight > 0 && cyTop > 0),
            {pDestinationRect->right - cxRight, pDestinationRect->top, cxRight, cyTop},
            {pSourceRect->right  - cxRight, pSourceRect->top, cxRight, cyTop}
        },
        {// Lower left corner
            (cxLeft > 0 && cyBottom > 0),
            {pDestinationRect->left, pDestinationRect->bottom - cyBottom, cxLeft, cyBottom},
            {pSourceRect->left, pSourceRect->bottom - cyBottom, cxLeft, cyBottom}
        },
        {// Lower right corner
            (cxRight > 0 && cyBottom > 0),
            {pDestinationRect->right - cxRight, pDestinationRect->bottom - cyBottom, cxRight, cyBottom},
            {pSourceRect->right  - cxRight, pSourceRect->bottom  - cyBottom, cxRight, cyBottom}
        },
        // Blit the top and bottom using stretched blits in X
        {// Top
            (cyTop > 0),
            {pDestinationRect->left + cxLeft, pDestinationRect->top, RECTWIDTH(*pDestinationRect) - (cxRight + cxLeft), cyTop},
            {pSourceRect->left + cxLeft, pSourceRect->top, RECTWIDTH(*pSourceRect) - (cxRight + cxLeft), cyTop}
        },
        {// Bottom
            (cyBottom > 0),
            {pDestinationRect->left + cxLeft, pDestinationRect->bottom - cyBottom, RECTWIDTH(*pDestinationRect) - (cxRight + cxLeft), cyBottom},
            {pSourceRect->left + cxLeft, pSourceRect->bottom - cyBottom, RECTWIDTH(*pSourceRect) - (cxRight + cxLeft), cyBottom}
        },
        // Blit the left and right using stretched blits in Y
        {// Left
            (cxLeft > 0),
            {pDestinationRect->left, pDestinationRect->top + cyTop, cxLeft, RECTHEIGHT(*pDestinationRect) - (cyBottom + cyTop)},
            {pSourceRect->left, pSourceRect->top + cyTop, cxLeft, RECTHEIGHT(*pSourceRect) - (cyBottom + cyTop)}
        },
        {// Right
            (cxRight > 0),
            {pDestinationRect->right - cxRight, pDestinationRect->top + cyTop, cxRight, RECTHEIGHT(*pDestinationRect) - (cyBottom + cyTop)},
            {pSourceRect->right - cxRight, pSourceRect->top + cyTop, cxRight, RECTHEIGHT(*pSourceRect) - (cyBottom + cyTop)}
        },
        // Finally, blit the center, stretching in X and Y
        {// Center
            true,
            {pDestinationRect->left + cxLeft,
                pDestinationRect->top + cyTop,
                RECTWIDTH(*pDestinationRect) - (cxRight + cxLeft),
                RECTHEIGHT(*pDestinationRect) - (cyBottom + cyTop)
                },
            {pSourceRect->left + cxLeft,
                pSourceRect->top + cyTop,
                RECTWIDTH(*pSourceRect) - (cxRight + cxLeft),
                RECTHEIGHT(*pSourceRect) - (cyBottom + cyTop)
                }
        },
    };

    for (int i = 0; i < _countof(c_TilesToPaint); i++)
    {
        if (c_TilesToPaint[i].m_ShouldBePainted)
        {
            if (CLR_INVALID != TransparentColor)
            {
                if (
                    !TransparentImage(
                        m_hdc,
                        c_TilesToPaint[i].m_DestinationRect.left,
                        c_TilesToPaint[i].m_DestinationRect.top,
                        c_TilesToPaint[i].m_DestinationRect.right,
                        c_TilesToPaint[i].m_DestinationRect.bottom,
                        *pBitmap3x3Tiles,
                        c_TilesToPaint[i].m_SourceRect.left,
                        c_TilesToPaint[i].m_SourceRect.top,
                        c_TilesToPaint[i].m_SourceRect.right,
                        c_TilesToPaint[i].m_SourceRect.bottom,
                        TransparentColor
                        )
                    )
                {
                    return CommonUtilities_t::GetErrorFromWin32();
                }
            }
            else
            {
                PaintHelper_t Source;
                HRESULT hr = Source.CreateCanvas(NULL);
                if (FAILED(hr))
                {
                    return hr;
                }

                Source.SetBitmap(*pBitmap3x3Tiles);

                if (
                    !StretchBlt(
                        m_hdc,
                        c_TilesToPaint[i].m_DestinationRect.left,
                        c_TilesToPaint[i].m_DestinationRect.top,
                        c_TilesToPaint[i].m_DestinationRect.right,
                        c_TilesToPaint[i].m_DestinationRect.bottom,
                        Source,
                        c_TilesToPaint[i].m_SourceRect.left,
                        c_TilesToPaint[i].m_SourceRect.top,
                        c_TilesToPaint[i].m_SourceRect.right,
                        c_TilesToPaint[i].m_SourceRect.bottom,
                        SRCCOPY
                        )
                    )
                {
                    return CommonUtilities_t::GetErrorFromWin32();
                }
            }
        }
    }

    return S_OK;
}

RECT&
PaintHelper_t::Rect(
    )
{
    return m_PaintStruct.rcPaint;
}


Bitmap_t::Bitmap_t(
    )
{
    m_IsAttached = false;
}

Bitmap_t::~Bitmap_t(
    )
{
    if (m_IsAttached)
    {
        //release the bitmap since we do not own it
        m_Bitmap.release();
    }
}

bool
Bitmap_t::operator!(
    )
{
    return !m_Bitmap;
}

Bitmap_t::operator HBITMAP(
    )
{
    return (HBITMAP)m_Bitmap;
}

HRESULT
Bitmap_t::Attach(
    HBITMAP Bitmap
    )
{
    ASSERT(!m_Bitmap);

    BITMAP bmpObject;

    // Get the bitmap for its width and height
    if (0 == GetObject(Bitmap, sizeof(bmpObject), &bmpObject))
    {
        return CommonUtilities_t::GetErrorFromWin32();
    }

    m_Width = bmpObject.bmWidth;
    m_Height = bmpObject.bmHeight;

    m_Bitmap = Bitmap;
    m_IsAttached = true;

    return S_OK;
}

HRESULT
Bitmap_t::LoadBitmap(
    HINSTANCE Instance,
    UINT ResourceId
    )
{
    ASSERT(!m_Bitmap);

    m_Bitmap = ::LoadBitmap(
        Instance,
        MAKEINTRESOURCE(ResourceId)
        );
    if (!m_Bitmap)
    {
        return CommonUtilities_t::GetErrorFromWin32();
    }

    BITMAP bmpObject;

    // Get the bitmap for its width and height
    if (0 == GetObject((HBITMAP)m_Bitmap, sizeof(bmpObject), &bmpObject))
    {
        return CommonUtilities_t::GetErrorFromWin32();
    }

    m_Width = bmpObject.bmWidth;
    m_Height = bmpObject.bmHeight;

    return S_OK;
}

int
Bitmap_t::Height(
)
{
    return m_Height;
}

int
Bitmap_t::Width(
    )
{
    return m_Width;
}

⌨️ 快捷键说明

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