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

Posted

技术标签:

【中文标题】稍后更改组合框的项目高度(用于 DPI 感知)【英文标题】:Change a combo box' items' height lateron (for DPI awareness) 【发布时间】:2019-10-02 15:58:35 【问题描述】:

背景:

我有一个具有每个显示器 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

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

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

有什么想法吗?谢谢!

编辑:问题显然只发生在增加项目的高度时(所以当我的窗口从 100% 移动到 200% 监视器时)。

【问题讨论】:

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

在绝望地尝试了许多尝试之后,我找到了一种解决方法,它似乎对通过添加一个虚拟条目并再次删除它导致问题的所有情况都有帮助:

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

【讨论】:

以上是关于稍后更改组合框的项目高度(用于 DPI 感知)的主要内容,如果未能解决你的问题,请参考以下文章

qt 将最大高度设置为下拉组合框(样式 cleanlooks)

WPF:在不知道项目的情况下更改组合框的字体大小

如何根据从其他框中选择的文本更改动态创建的组合框的显示项

Winforms:更改分辨率时,ComboBox高度不会调整大小

访问表单组合框 listindex 更改

如何清除剑道组合框的值