随笔-60  评论-262  文章-1  trackbacks-0

要实现一个将 IP 地址控件的 disabled 状态, 但是 Windows 的实现就没有将控件的颜色灰掉,
M$ 真是的, 最后一步懒得弄了, 我只好自己弄咯. 下面是我的WTL,实现代码.  BTW, 这个控件在
动态改变大小时, 里面的四个 EDIT 的大小没跟着改变, 我也懒得弄了 ;-)
 
 
#ifndef __ATL_GRAY_IP_ADDR_CTRL_H__
#define __ATL_GRAY_IP_ADDR_CTRL_H__
#pragma once
#include <vector>
 
#ifndef ARRAYSIZE
#define ARRAYSIZE( x ) (sizeof(x)/sizeof((x)[0]))
#endif // !defined(ARRAYSIZE)

namespace WTL {
    class CGrayIPAddrCtrlImpl : public CWindowImpl<CGrayIPAddrCtrlImpl, CIPAddressCtrl>
    {
        typedef CWindowImpl<CGrayIPAddrCtrlImpl, CIPAddressCtrl> baseClass;
    public:
        BEGIN_MSG_MAP_EX(CGrayIPAddrCtrlImpl)
            MESSAGE_HANDLER(WM_CREATE, OnCreate)
            MESSAGE_HANDLER(WM_PAINT, OnPaint)
            MESSAGE_HANDLER(WM_SIZE, OnSize)
        END_MSG_MAP();
        CGrayIPAddrCtrlImpl() : m_uFourTimes(0)
        { }
        LRESULT OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
        {
            uMsg, wParam, lParam, bHandled;
            m_vecEdit.clear();
            ::EnumChildWindows(m_hWnd, EnumChildProc, (LPARAM)this);
            bHandled = FALSE;
            return S_OK;
        }
        static BOOL CALLBACK EnumChildProc(HWND hwnd, LPARAM lParam)
        {
            CGrayIPAddrCtrlImpl *pThis = reinterpret_cast<CGrayIPAddrCtrlImpl *>(lParam);
            CEdit wndEdit(hwnd);
            if (pThis->m_uFourTimes < 4)
            {
                wndEdit.SetReadOnly();
                pThis->m_uFourTimes ++;
            }
            RECT rc = { 0 };
            wndEdit.GetClientRect(&rc);
            wndEdit.ClientToScreen(&rc);
            pThis->m_vecEdit.push_back(rc);
            ATLTRACE("======================EnumChildProc==%d==%d==%d===================\n",
                pThis->m_vecEdit.size(), rc.left, rc.right);
            return TRUE;
        }
        BOOL SubclassWindow(HWND hWnd)
        {
            BOOL bReturn = baseClass::SubclassWindow(hWnd);
            if (bReturn) {
                m_vecEdit.clear();
                ::EnumChildWindows(m_hWnd, EnumChildProc, (LPARAM)this);
            }
            return bReturn;
        }
        LRESULT OnPaint(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
        {
            uMsg, wParam, lParam, bHandled;
            TCHAR szText[MAX_PATH];
            GetWindowText(szText, ARRAYSIZE(szText));
            CRect       rc;
            CPaintDC    dcMem(m_hWnd); 
            GetClientRect(rc); 
            COLORREF crBack = GetSysColor(COLOR_BTNFACE);
            ::SetBkColor(dcMem, crBack);
            ::ExtTextOut(dcMem, 0, 0, ETO_OPAQUE, &rc, NULL, 0, NULL);
            {
                DWORD   dwFlags = DT_CENTER;
                DWORD   dwStyle = GetExStyle();
                COLORREF    crOldBk     = 0xFFFFFFFF;
                UINT        nOldMode    = (UINT)-1;
                if (dwStyle & WS_EX_TRANSPARENT) {
                    nOldMode = dcMem.SetBkMode(TRANSPARENT);
                } else {
                    crOldBk = dcMem.SetBkColor(crBack);
                }
                TCHAR szDot[] = _T(".");
                RECT rcTemp;
                std::vector<RECT>::reverse_iterator it;
                for(it=m_vecEdit.rbegin(); it!=m_vecEdit.rend(); it++)
                {
                    std::vector<RECT>::reverse_iterator itNext = it+1;
                    if (itNext != m_vecEdit.rend())
                    {
                        rcTemp.top = it->top;
                        rcTemp.bottom = it->bottom;
                        rcTemp.left = it->right;
                        rcTemp.right = itNext->left;
                        ScreenToClient(&rcTemp);
                        dcMem.DrawText(szDot, _tcslen(szDot), &rcTemp, dwFlags);  
                    }
                }
                if (dwStyle & WS_EX_TRANSPARENT) {
                    dcMem.SetBkMode(nOldMode);
                } else {
                    dcMem.SetBkColor(crOldBk);
                }
            }
            return S_OK;
        }
        LRESULT OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
        {
            uMsg, wParam, lParam, bHandled;
            m_vecEdit.clear();
            ::EnumChildWindows(m_hWnd, EnumChildProc, (LPARAM)this);
            bHandled = FALSE;
            return S_OK;
        }
        UINT m_uFourTimes;
        std::vector< RECT > m_vecEdit;
    };

};  // namespace WTL

#endif  // __ATL_GRAY_IP_ADDR_CTRL_H__

posted on 2008-03-08 14:51 free2000fly 阅读(445) 评论(0)  编辑 收藏 引用

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理