Search code examples
windowsstylesredrawsetwindowlong

How can I simplify code that modifies Window Styles using SetWindowLong & GetWindowLong?


I'm writing some wrapper functions and classes for the Windows API. A common occurrence I'm starting to come across is modifying Windows Styles.

The following is some example code that my adjusts a TextBox's Text Alignment based on the parameter ALIGNMENT enum. After much testing it seems I must remove the 2 alternative Alignment styles or it will conflict. Then SetWindowPos(..SWP_FRAMECHANGED) doesn't work either, so I replaced it with InvalidateRect() and UpdateWindow() to force the TextBox to be repainted after the style is updated.

I'd like some feedback if there is a simpler way of doing this. I feel like I'm overlooking something. Thanks! :)

enum ALIGNMENT
{
    Left,
    Right,
    Center
};

void TextBox::Alignment(ALIGNMENT Alignment)
{
    switch (Alignment)
    {
        case ALIGNMENT::Left:
            SetWindowLongPtr(m_hWnd, GWL_STYLE, (GetWindowLongPtr(m_hWnd, GWL_STYLE) & ~ES_CENTER & ~ES_RIGHT) | ES_LEFT);
        break;
        case ALIGNMENT::Center:
            SetWindowLongPtr(m_hWnd, GWL_STYLE, (GetWindowLongPtr(m_hWnd, GWL_STYLE) & ~ES_LEFT & ~ES_RIGHT) | ES_CENTER);
        break;
        case ALIGNMENT::Right:
            SetWindowLongPtr(m_hWnd, GWL_STYLE, (GetWindowLongPtr(m_hWnd, GWL_STYLE) & ~ES_LEFT & ~ES_CENTER) | ES_RIGHT);
        break;
    }

    InvalidateRect(m_hWnd, NULL, true);
    UpdateWindow(m_hWnd);
};

Solution

  • In WinUser.h:

    #define ES_LEFT             0x0000L
    #define ES_CENTER           0x0001L
    #define ES_RIGHT            0x0002L
    

    so you can do

    void TextBox::Alignment(ALIGNMENT Alignment)
    {
        int style = ES_LEFT; // default to left alignment
        switch (Alignment)
        {
            case ALIGNMENT::Center:
                style = ES_CENTER;
                break;
            case ALIGNMENT::Right:
                style = ES_RIGHT;
                break;
        }
    
        SetWindowLongPtr(m_hWnd, GWL_STYLE, GetWindowLongPtr(m_hWnd, GWL_STYLE) & ~(ES_CENTER|ES_RIGHT) | style);
        InvalidateRect(m_hWnd, NULL, TRUE);
        UpdateWindow(m_hWnd);
    };