稍后更改组合框“项”的高度(用于 DPI 感知)

Change a combo box' items' height lateron (for DPI awareness)

提问人:Nick 提问时间:10/2/2019 最后编辑:Andrew TruckleNick 更新时间:10/7/2019 访问量:378

问:

背景:

我有一个具有每个显示器 DPI 感知模式的 MFC 应用程序。当我将窗口移动到另一台具有另一个屏幕缩放的显示器时,我接收并处理该消息。WM_DPICHANGED_AFTERPARENT

我的所有者绘制的组合框(带样式)已经填充了我需要根据新的缩放因子更新高度的项目。为此,我计算了新的高度并调用:CBS_OWNERDRAWFIXED

SetItemHeight(-1, height); // resizes the closed box
SetItemHeight(0, height); // do this on every item's index from 0 to n

问题:组合框在以前的缩放中尚未打开,但在更改项目高度后打开,似乎是错误的。列表打开时显示所有条目的后半部分,下半部分为空。关闭并重新打开它可以解决问题。

我尝试了从其他更新问题中知道的解决方法,例如显示和隐藏组合框,但它没有帮助。 完全重新填充所有条目有效,但这很慢并导致闪烁(我在该窗口中有 12 个这样的框)。Invalidate()

有什么想法吗?谢谢!

编辑:显然,只有在增加项目的高度时才会出现问题(因此,当我的窗口从100%移动到200%显示器时)。

Windows MFC DPI 感知

评论

1赞 Vlad Feinstein 10/4/2019
这可能与您的问题无关,但您没有正确使用该参数。根据 msdn.microsoft.com/en-us/ie/aa278721(v=vs.100),.indexnIndex must be 0 and the height of all list items will be set
0赞 Vlad Feinstein 10/4/2019
过去,我在需要更新控件的某些内部状态时使用函数 (learn.microsoft.com/en-us/windows/win32/api/winuser/...) 有很好的经验。SetWindowPos()SWP_FRAMECHANGED
0赞 Nick 10/7/2019
@VladFeinstein:谢谢!实际上,您的第一个提示与此问题无关,但无论如何,它有助于简化我的代码。您的第二个提示很有趣,但不幸的是没有帮助:-(( 但我找到了另一种解决方法,请参阅下面的答案。

答:

0赞 Nick 10/7/2019 #1

在尝试了多次尝试之后,我发现了一种解决方法,它似乎有助于通过添加虚拟条目并再次删除它来导致问题的所有情况:

// Workaround to avoid combo box bug after resizing (esp. enlarging) the entries' height:
int idx = AddString(L"");
DeleteString(idx);