如果我有五个 Win32 静态控件,我如何将其中一个设置为特定的前景色? [英] If I have five Win32 static controls, how can I set one of them with a specific foreground color?

查看:23
本文介绍了如果我有五个 Win32 静态控件,我如何将其中一个设置为特定的前景色?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

据我所知,这不是一个重复的问题,因为它处理的是一组静态(标签)控件.我想将前景色设置为我在瘦 OOP 库中调用的特定颜色.

As far as I can tell, this is not a duplicate question because it's dealing with a collection of static (label) controls. I want to set a foreground color to a specific one that I call in my thin OOP library.

我将库中的静态控件称为标签".这是我设置颜色的方式:

I call a static control a "Label" in my library. This is how I set the color:

void Label::setForeColor(const BYTE red, const BYTE green, const BYTE blue)
{
    m_foreColor = RGB(red, green, blue);
}

这只是设置控件应该具有的 COLORRREF.我找不到解决方案来为该特定静态控件发送消息而不影响其他人.

This just sets a COLORRREF that the control should have. I'm having trouble finding a solution to send a message for that specific static control without affecting others.

很多人说要使用 WM_CTLCOLORSTATIC,但我已经是为了控件的透明度:

Many say to use WM_CTLCOLORSTATIC, but I already am for transparency of controls:

case WM_CTLCOLORBTN:
case WM_CTLCOLORSTATIC: 
{
    char  class_Name[100];
    WNDCLASS lpcls{};

    SetBkMode((HDC)wParam, TRANSPARENT);
    // SetTextColor((HDC)wParam, RGB(0, 0, 255));  This works and can set all statics as blue, but I need just one control blue.        
    GetClassName(hWnd, class_Name, 100); 
    GetClassInfo(frm.getInstance(), class_Name, &lpcls);

    return  (LRESULT)lpcls.hbrBackground;
}  

但问题是:我可能在一个窗口上有多个标签,所以这不仅仅是像大多数示例所示那样设置单个标签.可能有 5 个标签,有 5 种不同的颜色.

But here's the issue: I may have more than one label on a window, so this goes beyond than just setting a single label as most examples show. There may be 5 labels with 5 different colors.

这是顶层:

Label lblName("This is a label.", 330, 303);
lblName.setVisible(true);  
lblName.setForeColor(0, 0, 255);
lblName.setFont("Garamond", 24, false, false, false);
lblName.OnMouseOver(lblName_onMouseOver);   

理想情况下,我想通过发送消息在我的 setFont() 函数中设置颜色.

Ideally, I would like to set the color in my setFont() function by sending a message.

bool Label::setFont(const std::string &fontName, const int size, const bool bold,
    const bool italic, const bool underlined)
{
    DWORD dwItalic;
    DWORD dwBold;
    DWORD dwUnderlined;
    SIZE linkSize;
    HFONT old_font;

    dwItalic = (italic) ? TRUE : FALSE;
    dwBold = (bold) ? FW_BOLD : FW_DONTCARE;
    dwUnderlined = (underlined) ? TRUE : FALSE;

    m_font = CreateFont(size, 0, 0, 0, dwBold, dwItalic, dwUnderlined, FALSE,
        ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
        DEFAULT_PITCH | FF_SWISS, fontName.c_str());

    SendMessage(m_handle, WM_SETFONT, WPARAM(m_font), TRUE);

    // Calculate the correct width and height size  
    HDC hDC = GetDC(m_handle); 
    old_font = SelectFont(hDC, m_font);   
    GetTextExtentPoint32(hDC, m_text.c_str(), (int)m_text.length(), &linkSize);
    setSize(linkSize.cx, size);  
    DeleteFont(old_font); 
    ReleaseDC(m_handle, hDC); 

    return true;
}

最后,这就是我检索我感兴趣的标签的方式.我想知道是否需要类似地设置字体颜色.

Finally, this is how I retrieve my labels that I'm interested in. I wonder if I need to set the font color similarly.

    case WM_MOUSEMOVE:
    {
        X3D::Windows::Control *ctrl = (X3D::Windows::Control*) dwRefData;

        // Check if this is a X3D Label control.
        X3D::Windows::Label *lbl = dynamic_cast<X3D::Windows::Label*>(ctrl);
        if (lbl)
        {
            lbl->setHovering(true);
            lbl->invokeOnMouseHover();
        }
        else
        {
            lbl->setHovering(false);
        }
        break;
    }

总体问题:如果我有五个 Win32 静态控件,我如何为其中一个设置特定的前景色?

Overall question: If I have five Win32 static controls, how can I set one of them with a specific foreground color?

更新:

这是我当前的代码.Assert() 对我咆哮:Expression: map/set iterator not dereferencable

This is my current code. Assert() is barking at me: Expression: map/set iterator not dereferencable

case WM_CTLCOLORBTN:
case WM_CTLCOLORSTATIC: 
{
    char  class_Name[100];
    WNDCLASS lpcls{};

    SetBkMode((HDC)wParam, TRANSPARENT);

    GetClassName(hWnd, class_Name, 100); 
    GetClassInfo(frm.getInstance(), class_Name, &lpcls);

    for (int i = 0; i < frm.getControlCount(); i++)
    {
        if (frm.getControls().find(i)->second->getHandle() == (HWND)lParam)
        {

            // Obtain the control associated with the id.
            X3D::Windows::Control *ctrl = frm.getControls().find(i)->second;
            if (ctrl == NULL)
                return 0;

            // Check if this is a X3D Label control. 
            Label *lbl = dynamic_cast<X3D::Windows::Label*>(ctrl);

            if (lbl != NULL)
            {
                SetTextColor((HDC)wParam, lbl->getForeColor());
                break;
            }  
        }
    } 

    return  (LRESULT)lpcls.hbrBackground;
}  

更新:应用程序运行,但字体颜色没有更新.这有什么问题吗?

Update: App runs, but the font color isn't updating. Something wrong in this?

    int id = GetDlgCtrlID((HWND)lParam);

        // Obtain the control associated with the id.
    X3D::Windows::Control *ctrl = frm.getControls().at(id);
        if (ctrl == NULL)
            return 0;

        // Check if this is a X3D Label control. 
        Label *lbl = dynamic_cast<X3D::Windows::Label*>(ctrl);

        if (lbl != NULL)
        {
            SetTextColor((HDC)wParam, lbl->getForeColor());
            break;
        }   

也试过这个:

    int id = GetDlgCtrlID((HWND)lParam);

        // Obtain the control associated with the id.
    X3D::Windows::Control *ctrl = frm.getControls().find(id)->second;
        if (ctrl == NULL)
            return 0;

如果所有这些看起来都正确,我明天只需要调试它.

If all of that looks correct, I'll just have to debug it tomorrow.

推荐答案

WM_CTLCOLORSTATIC 被多次发送,您可以根据生成它的子窗口选择采取不同的行动.

WM_CTLCOLORSTATIC is sent multiple times, you can choose to take different actions depending on which child window is generating it.

MSDN 所示,<随消息一起到达的 code>lParam 是控件的 HWND.直接比较它,或者 GetDlgCtrlID() 如果您想使用对话框项 ID.

As shown on MSDN, the lParam that arrives with the message is the HWND for the control. Compare it directly, or GetDlgCtrlID() if you want to work with dialog item IDs.

子类 wndproc 不需要做任何特殊处理,因为 WM_CTLCOLORSTATIC 被发送到父窗口.

No need to do anything special in the subclass wndproc, because WM_CTLCOLORSTATIC is sent to the parent window.

但是没有消息要发送来更改颜色或字体,因为 STATIC 窗口类不使用每个标签的永久设备上下文(这是一件好事,因为许多程序都具有很多标签).因此,每次从池中借用 DC 时,需要将颜色和字体等文本配置重新应用于 DC.WM_CTLCOLORSTATIC 在执行此操作的理想时间发送到父窗口.

But there is no message to send to change the color or font, because the STATIC window class doesn't use a permanent device context per label (which is a good thing, because many programs have a lot of labels). So the text configuration like color and font need to be reapplied to the DC each time it is borrowed from the pool. WM_CTLCOLORSTATIC is sent to the parent window at the ideal time to do this.

如果您的颜色设置器被调用,请务必使用 InvalidateRect() 触发重绘.重新绘制将再次发送 WM_CTLCOLORSTATIC,让您有机会对更新后的颜色采取行动.

If your setter for the color is called, be sure to use InvalidateRect() to trigger a repaint. That repaint will send WM_CTLCOLORSTATIC again, giving you the opportunity to act on your updated color.

这篇关于如果我有五个 Win32 静态控件,我如何将其中一个设置为特定的前景色?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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