更改编辑控件的背景颜色的困难 [英] Difficulties in changing the background color of edit control
问题描述
我在一个对话框中有编辑控件,检查输入是否有效。
我应该通过更改编辑控件的背景颜色来指示有效性,如果输入是无效,否则我什么都不做。
我正在检查 EN_CHANGE
处理程序中的输入,如果输入无效我将编辑控件的句柄存储在向量中。最后我调用 InvalidateRect((HWND)lParam,NULL,TRUE);
所以编辑控件可以用适当的颜色重新绘制。
要重新编辑编辑控件,我正在处理 WM_CTLCOLOREDIT
,如下所示:
case WM_CTLCOLOREDIT:
{
bool IsInvalid = 假跨度>; // 此编辑控件是否包含无效文字?
// vector InvalidInput包含编辑控件的句柄
// 输入无效,所以我们检查我们的窗口是否存储在那里
(向量< HWND> :: size_type i = 0 ;
!IsInvalid&&(i< InvalidInput.size()); i ++)
{
if (InvalidInput [i] ==(HWND)lParam)
IsInvalid = 真跨度>;
}
// 如果输入无效,请将背景颜色更改为浅灰色
if (IsInvalid)
{
// 需要用于文本背景透明度的SetBkMode
SetBkMode((HDC)wParam,TRANSPARENT);
// 返回浅灰色画笔
return (INT_PTR)((HBRUSH)GetStockObject(LTGRAY_BRUSH));
}
else
return FALSE; // 说我们没有处理它
// 所以对话程序可以为我们做到这一点
}
之后我启动程序编辑控件正确绘制。
输入有效的输入后,编辑控件被正确绘制。
我在之后立即输入无效字符后,背景颜色为浅灰色,一切似乎都正常。
如果删除无效字符然后背景保持灰色而不是返回默认系统颜色。
我做错了什么,我应该如何解决这个问题?
编辑:
如果我放 InvalidateRect()
在我的 WM_COMMAND
处理程序中 IDC_MYEDIT
然后问题似乎消失了:
<前la ng =c ++> case WM_COMMAND:
{
switch (LOWORD( wParam))
{
case IDC_MYEDIT:
{
if (HIWORD(wParam)== EN_CHANGE)
{
// 进行验证东西
}
InvalidateRect(...);
}
break ;
// 代码的其余部分......
END OF EDIT
谢谢。
祝你好运。
再看一下该函数应返回的内容
http:// msdn。 microsoft.com/en-us/library/windows/desktop/bb761691%28v=vs.85%29.aspx [ ^ ]
在任何阶段都没有要求你返回FALSE所以这是错误的。关于返回false的一点是针对一个对话框处理程序,它为你正在做的子窗口背景着色。
return FALSE; // 说我们没有处理它
// 所以对话程序可以为我们做到这一点
它说默认情况下,DefWindowProc函数选择编辑控件的默认系统颜色。
所以你应该做的只是传递信息如果你想要正常的背景颜色,请到默认窗口处理程序。
return(DefWindowProc(hwnd,uMsg,wParam,lParam));
也许读下一行
由SetWindowLong函数设置的DWL_MSGRESULT值被忽略。
想要猜测DWL_MSGRESULT中的什么现在将在您返回时被忽略false ????
是的默认处理程序被调用但是没有有效的画笔。
我不知道微软的意图是什么,但是你所处的简单解决方案就是在DWL_MSGRESULT仍然有效时自己手动调用默认处理程序。
它很长一段时间都是这样的,也许这是一个错误或疏忽我只知道它有效。
实际上对于商业产品我们大多数人都是标准编辑的子类条目类型的框,其中编辑框处理自己的验证,标签等。这意味着更多可重复使用的代码,更少使用对话框处理程序在许多情况下,您只需使用标准对话框处理程序。
I have edit control in a dialog box which input is checked for validity.
I should indicate validity by changing the background color of an edit control if input is invalid, otherwise I should do nothing.
I am checking the input in EN_CHANGE
handler and if input is invalid I store the handle of the edit control in a vector. In the end I call InvalidateRect( (HWND)lParam, NULL, TRUE );
so edit control can be repainted with proper color.
To repaint edit control I am handling WM_CTLCOLOREDIT
like this:
case WM_CTLCOLOREDIT:
{
bool IsInvalid = false; // does this edit control hold invalid text ?
// vector InvalidInput contains handles of edit controls
// with invalid input, so we check if our window is stored there
for( vector<HWND>::size_type i = 0;
!IsInvalid && ( i < InvalidInput.size() ); i++ )
{
if( InvalidInput[i] == (HWND)lParam )
IsInvalid = true;
}
// if input is invalid change background color to light gray
if( IsInvalid )
{
// Needed SetBkMode for text background transparency
SetBkMode( (HDC)wParam, TRANSPARENT );
// return light gray brush
return (INT_PTR)( (HBRUSH)GetStockObject( LTGRAY_BRUSH ) );
}
else
return FALSE; // say we didn't handle it
// so dialog procedure can do that for us
}
After I start the program edit control is painted properly.
After I type valid entry edit control is painted properly.
After I type invalid character immediately after, background is colored into light gray and everything seems to work fine.
If I delete the invalid character then the background stays gray instead of returning to default system color.
What am I doing wrong and how should I fix this ?
EDIT:
If I put InvalidateRect()
in my WM_COMMAND
handler for IDC_MYEDIT
then the problem seems to disappear:
case WM_COMMAND:
{
switch( LOWORD(wParam) )
{
case IDC_MYEDIT:
{
if( HIWORD(wParam) == EN_CHANGE )
{
//do your validation stuff
}
InvalidateRect(...);
}
break;
// the rest of the code...
END OF EDIT
Thank you.
Best regards.
Look again at the what the function is supposed to return
http://msdn.microsoft.com/en-us/library/windows/desktop/bb761691%28v=vs.85%29.aspx[^]
At no stage does it ask you to return FALSE so this is wrong. The bit about returning false is for a dialog box handler that is coloring it's child windows backgrounds which you are not doing.
return FALSE; // say we didn't handle it // so dialog procedure can do that for us
It says "By default, the DefWindowProc function selects the default system colors for the edit control."
So what you are supposed to do is simply pass the message to the default window handler if you want the normal background color.
return (DefWindowProc(hwnd, uMsg, wParam, lParam));
Perhaps read the next line
The DWL_MSGRESULT value set by the SetWindowLong function is ignored.
Want to guess whats in the DWL_MSGRESULT that is now going to be ignored when you return false????
Yes the default handler gets called but there is no valid brush.
I have no idea what microsoft's intention was with this but the simple solution from where you are is to simply call the default handler yourself manually while DWL_MSGRESULT is still valid.
It has been like that for a very very long time, perhaps it's a bug or oversight I just know it works.
Realistically for commercial products most of us subclass the standard edit box for types of entries with the edit boxes handling there own validation, tabbing etc. It means far more reusable code and much less playing around with dialog handlers in many cases you can just use the standard dialog handler.
这篇关于更改编辑控件的背景颜色的困难的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!