Click here to Skip to main content
15,891,607 members
Articles / Desktop Programming / MFC

ImageStone - A Powerful C++ Class Library for Image Manipulation

Rate me:
Please Sign up or sign in to vote.
4.81/5 (250 votes)
6 Dec 2011Zlib3 min read 1.1M   51.5K   405  
An article on a library for image manipulation
/*
    Copyright (C) =USTC= Fu Li

    Author   :  Fu Li
    Create   :  2008-3-23
    Home     :  http://www.phoxo.com
    Mail     :  crazybitwps@hotmail.com

    This file is part of UIStone

    The code distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

    Redistribution and use the source code, with or without modification,
    must retain the above copyright.
*/
#pragma once
#include "track_mouse_hover.h"
#include "font.h"

//-------------------------------------------------------------------------------------
/**
    Custom draw button.
*/
class FCButtonBase : public CButton,
                     public FCTrackMouseHover
{
public:
    FCButtonBase()
    {
        m_tooltip_style = TTS_ALWAYSTIP ;
        m_check = BST_UNCHECKED ;
        m_nDelayTimeMS = 250 ;
        m_cursor = NULL ;
    }

    /// Create button, WS_VISIBLE is not set by default.
    BOOL Create (CRect rcWnd, CWnd* pParent, UINT nID, DWORD dwStyle=0)
    {
        return CButton::Create (_T(""), WS_CHILD|BS_OWNERDRAW|dwStyle, rcWnd, pParent, nID) ;
    }

    /// Is the button highlighted.
    BOOL IsButtonHighlight() const {return (GetState() & BST_PUSHED) ? TRUE : FALSE ;}

    /**
        @name Tooltip.
    */
    //@{
    /// Get tooltip text.
    CString GetTooltipText() const {return m_tip;}
    /// Set tooltip text.
    void SetTooltipText (LPCTSTR strTip) {m_tip = strTip;}
    /// Set tooltip's style, default style is TTS_ALWAYSTIP, you can set TTS_BALLOON | TTS_ALWAYSTIP
    void SetTooltipStyle (DWORD dwStyle=TTS_ALWAYSTIP) {m_tooltip_style = dwStyle;}
    /// Set button cursor, set NULL to use standard arrow cursor.
    void SetButtonCursor (HCURSOR hCursor) {m_cursor = hCursor;}
    /// Set delay milliseconds.
    void SetTooltipDelayTime (UINT nDelay) {m_nDelayTimeMS = nDelay;}
    //@}

protected:
    /// Override to draw button.
    virtual void OnDrawButton (CDC* pDC, CRect rcButton) {}

protected:
    /// If you override it, must call base function first (in order to register tool tip).
    virtual void OnMouse_EnterWnd()
    {
        ReRegisterToolTip() ;
    }

    virtual void OnMouse_LeaveWnd()
    {
        m_tip_ctrl.DestroyWindow() ;
    }

    virtual void PreSubclassWindow()
    {
        // can't create tooltip window in PreSubclassWindow
        __super::PreSubclassWindow() ;
        ModifyStyle (0, BS_OWNERDRAW) ;
    }

    virtual BOOL PreTranslateMessage(MSG* pMsg)
    {
        if (m_tip_ctrl.GetSafeHwnd())
            m_tip_ctrl.RelayEvent(pMsg) ;
        return __super::PreTranslateMessage(pMsg) ;
    }

protected:
    /// Draw background of button using system theme (it doesn't draw focus rect).
    void DrawSystemBack (CDC* pDC, CRect rcButton)
    {
        HTHEME   hTm = OpenThemeData (NULL, L"Button") ;
        if (hTm)
        {
            int   n = PBS_NORMAL ;
            if (IsButtonHighlight())
                n = PBS_PRESSED ;
            else if (IsMouseHovering())
                n = PBS_HOT ;

            DrawThemeBackground (hTm, *pDC, BP_PUSHBUTTON, n, rcButton, NULL) ;
            CloseThemeData(hTm) ;
        }
        else
        {
            UINT   t = 0 ;
            if (IsButtonHighlight() || GetCheck())
                t = DFCS_PUSHED ;
            pDC->DrawFrameControl (rcButton, DFC_BUTTON, DFCS_BUTTONPUSH | t) ;
        }
    }

    virtual void DrawItem (LPDRAWITEMSTRUCT lpDIS)
    {
        CRect   rcClient ;
        GetClientRect(rcClient) ;

        CBitmap   bmp ;
        bmp.Attach (CreateCompatibleBitmap(lpDIS->hDC, rcClient.Width(), rcClient.Height())) ;

        {
            FCImageDrawDC   memDC(bmp) ;

            DrawButtonToDC (memDC, rcClient) ;

            BitBlt (lpDIS->hDC, 0, 0, rcClient.Width(), rcClient.Height(), memDC, 0, 0, SRCCOPY) ;
        } // <-- select bmp out of dc
    }

    virtual LRESULT WindowProc (UINT msg, WPARAM wParam, LPARAM lParam)
    {
        FCTrackMouseHover::FilterMouseMessage (m_hWnd, msg) ;

        switch (msg)
        {
            case WM_ERASEBKGND :
                return 1 ;

            case BM_GETCHECK :
                return m_check ;

            case BM_SETCHECK :
                m_check = wParam ;
                Invalidate() ;
                return 0 ;

            case WM_SETCURSOR :
                if (m_cursor)
                {
                    ::SetCursor(m_cursor) ;
                    return TRUE ;
                }
                break;
        }
        return __super::WindowProc(msg, wParam, lParam) ;
    }

private:
    DWORD     m_tooltip_style ;
    LRESULT   m_check ;
    CString   m_tip ;
    UINT      m_nDelayTimeMS ;
    HCURSOR   m_cursor ;

    CToolTipCtrl   m_tip_ctrl ;

    enum
    {
        ID_UISTONE_BUTTON_TOOLIP = 100,
    };

    void DrawButtonToDC (HDC dc, CRect rcButton)
    {
        HGDIOBJ   hOldFont = SelectObject (dc, FCFontManager::GetDefaultFont()) ;

        CDC   * pDC = CDC::FromHandle(dc) ;
        if (pDC)
        {
            OnDrawButton (pDC, rcButton) ;
        }

        SelectObject (dc, hOldFont) ;
    }

    // internal.
    void ReRegisterToolTip()
    {
        if (!GetSafeHwnd())
            {ASSERT(FALSE); return;}

        if (m_tip_ctrl.GetSafeHwnd())
            m_tip_ctrl.DestroyWindow() ;

        if (!m_tip.GetLength())
            return ;

        m_tip_ctrl.Create (this, m_tooltip_style) ;
        m_tip_ctrl.SetMaxTipWidth(500) ; // max 500-pixel width
        m_tip_ctrl.SetDelayTime(m_nDelayTimeMS) ;
        m_tip_ctrl.SetDelayTime(TTDT_AUTOPOP, 15000) ;
        m_tip_ctrl.Activate(TRUE) ;

        CRect   rc ;
        GetClientRect(rc) ;
        m_tip_ctrl.AddTool (this, m_tip, rc, ID_UISTONE_BUTTON_TOOLIP) ;
    }
};

//-------------------------------------------------------------------------------------
class UIStone
{
public:
    static UINT MSG_UPDATE_LAYERED_WINDOW()
    {
        static UINT   n = ::RegisterWindowMessage (_T("MSG_UPDATE_LAYERED_WINDOW")) ;
        return n ;
    }

    static UINT MSG_DRAW_PARENT_PANEL()
    {
        static UINT   n = ::RegisterWindowMessage (_T("MSG_DRAW_PARENT_PANEL")) ;
        return n ;
    }

    static Gdiplus::Rect ToGdiplusRect (CRect rc)
    {
        return Gdiplus::Rect(rc.left, rc.top, rc.Width(), rc.Height()) ;
    }
};

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The zlib/libpng License


Written By
Team Leader PhoXo
China China
graduate from University of Science and Technology of China at 2002.

Now I work at www.phoxo.com.

Comments and Discussions