bio*_*ion 7 mfc appbar windows-7 windows-8.1 windows-10
我正在修改现有的MFC应用程序以使用Win32 应用程序桌面工具栏 API,并且我有一个解决方案似乎大部分都在那里(至少对于Windows 10).但是,有三种行为 - 在三个版本的Windows上 - 我看到并且无法解释:
我的实现代码分为两个主要部分.第一个是进入/退出/修改AppBarState窗口当前的函数,它是一个枚举(包含在一个带有一些辅助函数的类中),包含每个窗口边缘的值以及禁用状态:
static constexpr DWORD AppBarStyleModifications = WS_CAPTION | WS_SIZEBOX | WS_SYSMENU;
if (!AppBarState::IsActive(eState_) && AppBarState::IsActive(eDesiredState)) {
ModifyStyle(AppBarStyleModifications, 0, SWP_FRAMECHANGED | SWP_NOREDRAW);
UpdateRegistration_(true);
}
if (AppBarState::IsActive(eDesiredState))
PositionAppBar_(eDesiredState);
if (AppBarState::IsActive(eState_) && !AppBarState::IsActive(eDesiredState)) {
UpdateRegistration_(false);
ModifyStyle(0, AppBarStyleModifications);
}
Run Code Online (Sandbox Code Playgroud)
在此代码中,该UpdateRegistration_函数是一个简单的辅助函数,用于发送ABM_NEW或ABM_REMOVE消息,视情况而定.实现的主要"肉"是PositionAppBar_,它看起来像这样(有一些健全性检查和错误处理剥离空间):
APPBARDATA Data;
Data.cbSize = sizeof(APPBARDATA);
Data.hWnd = GetSafeHwnd();
Data.uCallbackMessage = APPBAR_CALLBACK;
Data.uEdge = AppBarState::ConvertToPositionCode(eDesiredState);
Data.rc = CRect(GetMonitorInfo(*this).rcMonitor).MulDiv(winx::GetDpiScalingPercent(), 100);
SHAppBarMessage(ABM_QUERYPOS, &Data);
CRect WindowRect;
DwmGetWindowAttribute(Data.hWnd, DWMWA_EXTENDED_FRAME_BOUNDS, &WindowRect, sizeof(RECT));
switch (eDesiredState) {
case AppBarState::PinnedLeft:
Data.rc.right = Data.rc.left + WindowRect.Width();
break;
case AppBarState::PinnedTop:
Data.rc.bottom = Data.rc.top + WindowRect.Height();
break;
case AppBarState::PinnedRight:
Data.rc.left = Data.rc.right - WindowRect.Width();
break;
case AppBarState::PinnedBottom:
Data.rc.top = Data.rc.bottom - WindowRect.Height();
break;
}
SHAppBarMessage(ABM_SETPOS, &Data);
const auto TargetRect = CRect(Data.rc).MulDiv(100, winx::GetDpiScalingPercent());
MoveWindow(TargetRect, FALSE);
Run Code Online (Sandbox Code Playgroud)
这里,winx::GetDpiScalingPercent()(顾名思义)是用于确定设备像素和应用坐标之间的DPI缩放比的辅助函数.
虽然欢迎任何关于这里可能存在的问题的意见或建议,但我会尝试用一些更具体的问题来限制范围:
ABM_QUERYPOS多次发送消息以获得正确的结果?关于另一个问题的这个答案似乎表明那是(或者至少是)这种情况,但是从我的测试来看,在第二次发送消息后,结果矩形似乎是相同的.ABM_SETPOS无法预留空间的有效方案,如果有,在这些方案中可以采取哪些步骤?我在上面的示例代码中省略了这一点,但我正在验证返回值,SHAppBarMessage并确保Data.rc在发送消息后矩形在x轴和y轴上都具有非零大小,所以我希望意味着预订已按预期进行.编辑:快速附录:PositionAppBar_也用作处理ABN_POSCHANGED消息类型的逻辑.
| 归档时间: |
|
| 查看次数: |
180 次 |
| 最近记录: |