【问题标题】:`SetWindowLong()` function doesn't change window style even after calling `SetWindowPos()``SetWindowLong()` 函数即使在调用 `SetWindowPos()` 后也不会改变窗口样式
【发布时间】:2013-07-27 08:55:07
【问题描述】:

我用下面的代码创建了静态控件:

hWnd = CreateWindowExW( 0,
                        L"STATIC",
                        Content.c_str(),
                        SS_LEFT | WS_VISIBLE | WS_CHILD /*| SS_SUNKEN*/,
                        200,
                        120,
                        120,
                        40,
                        hWndParent,
                        NULL,
                        hInstance,
                        NULL);

如果我在上面的创建代码中启用SS_SUNKEN样式,创建的静态控件就会出现下沉成功。

但是,我要做的是在创建后更改控件样式。
我试过这个:

void BaseWindowClass::AddStyle(DWORD NewStyle)
{
    // NewStyle     = 0x00001000 = SS_SUNKEN
    LONG oldstyle, changedstyle;
    oldstyle=SetWindowLongW(hWnd, GWL_STYLE, changedstyle=GetWindowLongW(hWnd, GWL_STYLE) | NewStyle);
    UpdateWindowStyles();
    // oldstyle     = 0x50000000
    // changedstyle = 0x50001000 (everything looks normal)
}
void BaseWindowClass::UpdateWindowStyles()
{
    BOOL success;
    success=SetWindowPos(hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);
    // success = 0x00000001 (non-zero: SetWindowPos sucseeded)
}

文档:
SetWindowLong()
SetWindowPos()

我在调用SetWindowLongW() 之后调用SetWindowPos(),因为在SetWindowLong 的文档中,它说:

某些窗口数据被缓存,因此您使用 SetWindowLong 所做的更改在调用 SetWindowPos 函数之前不会生效。具体来说,如果您更改任何框架样式,则必须调用带有 SWP_FRAMECHANGED 标志的 SetWindowPos 才能正确更新缓存。

而且,在 SetWindowPos 的文档中,它说:

如果您使用 SetWindowLong 更改了某些窗口数据,则必须调用 SetWindowPos 才能使更改生效。对 uFlags 使用以下组合: SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED。

即使更改了SetWindowLongW()SetWindowPos(),我的静态控件的样式也没有改变。

我做错了什么,或者我错过了什么?

【问题讨论】:

    标签: c++ winapi win32gui window-style


    【解决方案1】:

    SS_SUNKEN 有效地将扩展样式 (GWL_EXSTYLE) 窗口中的 WS_EX_STATICEDGE 设置为长,因此您可以适当地更新 GWL_EXSTYLE 并按照您当前的操作重新定位。

    【讨论】:

      【解决方案2】:

      尽管 SS_SUNKEN 确实会影响静态控件的框架,但它并不是 note 所指的“框架样式”之一。

      该注释是指影响所有窗口的通用框架样式,例如 WS_BORDERWS_EX_CLIENTEDGE - 更改时需要重新计算窗口非客户区的样式。

      许多系统控件在创建时会缓存其样式,即使您通过SetWindowLong 更改样式也不更新缓存。我猜这就是这里发生的事情 - 如果您不使用 SS_SUNKEN 创建静态控件,则以后无法添加它。您最好的选择是简单地销毁并使用新样式重新创建控件。

      【讨论】:

      • +1。 SS_SUNKEN 仅在创建时咨询。动态更改它没有效果。如果要动态更改效果,请不要使用SS_SUNKEN。相反,请使用WS_EX_STATICEDGE
      猜你喜欢
      • 1970-01-01
      • 2013-08-28
      • 2011-07-07
      • 2012-12-01
      • 2020-06-26
      • 1970-01-01
      • 1970-01-01
      • 2015-12-30
      • 2019-01-21
      相关资源
      最近更新 更多