要实现一个将 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) 编辑 收藏 引用