Click here to Skip to main content
15,896,153 members
Articles / Desktop Programming / WTL

Making of a Color Spy utility with WTL

Rate me:
Please Sign up or sign in to vote.
4.92/5 (28 votes)
30 Sep 2003MIT8 min read 92.3K   1.7K   51  
Making of color picker utility using WTL and recap of clipboard management APIs.
//////////////////////////////////////////////////////////////////////
// ColorSpy Copyright 2003 Tom Furuya [tom_furuya@yahoo.com]
//
// Readers of this article may copy the code for use in developing their own applications.
// If the code is used in a commercial application, however, an acknolegement must 
// be included in the following form: 
// "Segment of the code (c) 2003 Tom Furuya for CodeProject.com".
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_COLORSPYCBVIEWER_H__BAB47C31_C2AC_4725_B0E4_A45F62CF3E83__INCLUDED_)
#define AFX_COLORSPYCBVIEWER_H__BAB47C31_C2AC_4725_B0E4_A45F62CF3E83__INCLUDED_

#pragma once

//////////////////////////////////////////////////////////////////////
// CColorSpy's Clipboard Viewer 
// 
// CColorSpyCBViewer is a class that turns ColorSpy into a clipboard viewer window 
// for reading color codes from clipboard.
//
////////////////////////////////////////////////////////////////////////
template<typename T> 
class CColorSpyCBViewer
{
public:
    HWND m_hWndNextCBViewer;
    bool m_bRegistered;
    
    BEGIN_MSG_MAP(CColorSpyCBViewer< T >)
        ALT_MSG_MAP(1)
        MESSAGE_HANDLER(WM_CREATE, OnCreate)       // for CWindowImpl based windows
        MESSAGE_HANDLER(WM_INITDIALOG, OnCreate)   // for CDialogImpl based windows
        MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
        // Notification handlers
        MESSAGE_HANDLER(WM_DRAWCLIPBOARD, OnDrawClipboard)
        MESSAGE_HANDLER(WM_CHANGECBCHAIN, OnChangeCbChain) // necessary indeed
    END_MSG_MAP()
        
    CColorSpyCBViewer() : m_hWndNextCBViewer(0), m_bRegistered(false) {}

    LRESULT OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
    {
        bHandled = FALSE;
        T* pT = static_cast<T*>(this);

        // Join the members of clipboard viewer chain
        m_hWndNextCBViewer = pT->SetClipboardViewer(); //can be nothing
        m_bRegistered = true;
        return 0;
    }
    
    LRESULT OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
    {
        T* pT = static_cast<T*>(this);

        // Say good-bye to my friends
        if (IsWindow(m_hWndNextCBViewer))
            pT->ChangeClipboardChain(m_hWndNextCBViewer);
        return 0;
    }
    
    LRESULT OnDrawClipboard(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/)
    {
        // Viewer receives whenever the content of the clipboard is changed
        // wParam is a handle to the window that has put clipboard data
        
        T* pT = static_cast<T*>(this);
        
        // Registering this window as a CB wiewer window
        if (m_bRegistered == false) // calling ::SetClipboardViewer() in OnCrate handler
        {
            ATLTRACE("Registering... wParam: %#x\n", wParam);
            return 0; // do nothing but return gracefully
        }

        ATLTRACE("OnDrawClipboard(): Wnd %#x put CB data\n", wParam);

        if (IsClipboardFormatAvailable(CF_TEXT) && pT->OpenClipboard())
        {
            CString text;
            HANDLE hData = ::GetClipboardData( CF_TEXT );
            text = (char*)::GlobalLock( hData );
            ::GlobalUnlock( hData );
            CloseClipboard();

            pT->SetColor(text);
        }
        
        // Pass WM_DRAWCLIPBOARD to the next window in clipboard viewer chain
        RouteMessage(uMsg, wParam, lParam);
        return 0;
    }
    
    LRESULT OnChangeCbChain(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/)
    {
        T* pT = static_cast<T*>(this);

        // Clipboard wiewer window is supposed to respond to WM_CHANGECBCHAIN.

        HWND hWndRemove = reinterpret_cast<HWND>(wParam);
        HWND hWndAfter = reinterpret_cast<HWND>(lParam);
        
        if (m_hWndNextCBViewer == hWndRemove)
        {
            m_hWndNextCBViewer = hWndAfter;
        }
        
        // pass the WM_CHANGECBCHAIN (0x030D)
        RouteMessage(WM_CHANGECBCHAIN, wParam, lParam);
        return 0;
    }

    void RouteMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
    {
        // Toss WM_CHANGECBCHAIN message to the next Clipboard wiewer in the viewer chain
        // to notify of the update of chain.
        if (m_hWndNextCBViewer)
            ::SendMessage(m_hWndNextCBViewer, uMsg, wParam, lParam);
    }
};


#endif // !defined(AFX_COLORSPYCBVIEWER_H__BAB47C31_C2AC_4725_B0E4_A45F62CF3E83__INCLUDED_)

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 MIT License


Written By
Japan Japan
Live (1994 "Throwing Copper" till 1999 "The Distance To Here") is one of his favorite bands.

After 9 years life in U.S, he lives in his hometown Yokohama, working in Automotive After-sales business.
He sometimes found himself drunk once in a while in Munich.



He has put the period to his windows development after writing first and last article about a light-weight memory program, called colorspy (which is amusingly running on his latest windows except for dual display support.)
He has a message to the WTL author, "you rock. you proved that WTL kicks ass, M*F*C". F, in the middle, always reminds him of somewhat different wording.


Time lapse



His codepen is live.copper. His main focus has changed to various web technologies, to build fastest EPC services for automotive clients instead of pharmaceutical ones.
Ironically, he has not yet been released from the chaotic Windows software development installations even though he is no longer programming for Windows but for server side development.




Ein Prosit, Ein Prosit! He is still with a company in Munich as he loves to help people all over the world who need to fix their cars.

Comments and Discussions