今天自绘了一个EDIT控件,使它具有计算器的edit类似的属性,只能接受数字和最多一个小数点
主要思路是用自己写的一个类,然后定义个对象去处理,用个类成员窗口过程函数处理WM_CHAR消息来过滤,其他的消息返回原窗口过程处理
这样的话新窗口过程要定义成全局或者静态的,然后类成员句柄就要定义成静态的才能处理,但是如果有多个EDIT的话就无法处理了
解决方法是在用自定义的类和空间关联的时候用SetProp ,再在新的窗口过程中用GetProp来获取类对象的指针
Attach函数和控件关联
m_hWnd = hWnd;
SetProp(hWnd, DOUBLE_EDIT_PROP_NAME, this);
m_lOldProc = SetWindowLong(hWnd, GWL_WNDPROC, (long)NewEditProc);
//新的窗口过程来过滤,其中要使用到类的成员变量保存旧的窗口过程,用来处理其他消息,
//在新的静态窗口过程中要使用类成员旧的窗口过程来返回,就使用GetProp来获取类对象指针就OK了
LRESULT CALLBACK CDoubleEdit::NewEditProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
CDoubleEdit *pEdit = (CDoubleEdit*)GetProp(hWnd, DOUBLE_EDIT_PROP_NAME);
BOOL bCanceled = FALSE;
if (uMsg == WM_CHAR)
{
TCHAR szBuf[32] = { 0 };
pEdit->GetStringValue(szBuf, 32);
switch (wParam)
{
case '.' :
if (_tcschr(szBuf, '.'))
{
bCanceled = TRUE;
}
break;
default:
if (wParam > '9' || wParam < '0' && wParam != VK_BACK)
{
bCanceled = TRUE;
}
break;
}
if (bCanceled)
{
MessageBeep(-1);
return 0;
}
}
return CallWindowProc((WNDPROC)pEdit->m_lOldProc, hWnd, uMsg, wParam, lParam);
}