更改编辑控件的背景颜色的困难 [英] Difficulties in changing the background color of edit control

查看:82
本文介绍了更改编辑控件的背景颜色的困难的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在一个对话框中有编辑控件,检查输入是否有效。



我应该通过更改编辑控件的背景颜色来指示有效性,如果输入是无效,否则我什么都不做。



我正在检查 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆