在Windows音量混合器中,当您的应用程序播放声音时,它会添加您应用程序的图标和定制的音量滑块,以调整特定应用程序的音量...很棒!但是,当您为应用程序使用大尺寸图标时(特别是在高DPI下,当Windows为任务栏等缩放您的图标时),音量混合器中的图标无法正确缩放。具体来说,以下代码是我用来设置应用程序图标的:
// set icons the normal way
cWnd.SetIcon( theApp.LoadIcon( res_id ), FALSE );
cWnd.SetIcon( theApp.LoadIcon( res_id ), TRUE );
// set hi-res if available
OSVERSIONINFO osv;
osv.dwOSVersionInfoSize = sizeof( osv );
if ( GetVersionEx( &osv ) ) {
// if we're Vista or more recent, use hi-def icons
if ( osv.dwMajorVersion >= 6 ) {
HICON hIcon = (HICON)::LoadImage( theApp.m_hInstance, MAKEINTRESOURCE( res_id ), IMAGE_ICON, 256, 256, LR_SHARED );
if ( hIcon ) {
cWnd.SetIcon( hIcon, TRUE );
}
}
}
问题在于“如果可用,使用高分辨率”部分。如果包括它,任务栏图标看起来很好,但音量混合器没有缩放并且看起来很糟糕。如果不包括它,任务栏图标看起来不好(缩放很糟糕),但是至少音量混合器的大小是正确的:
有人找到了使得两个图标都好看的解决方案吗?
编辑:在我的图标文件中,我有以下分辨率:256x256、48x48、32x32、24x24和16x16,全部是32位。256x256的被压缩成PNG格式,其他的是RAW格式。所有尺寸在它们在文件中所在的分辨率下看起来都很棒(我试图将ICO放在这里或imgur中,但显然两者都不允许图标)。此外,我尝试过包含一些8位图像,但那似乎没有改变任何东西。
编辑:我正在使用 GetDeviceCaps( hdc, LOGPIXELSX )
(和Y)来确定桌面缩放。通常桌面缩放为100%,我获得正常的96结果。但越来越多的电脑默认为125%。这可以通过右键单击桌面,个性化,其他:显示… 在那里有一个滑块(需要注销/登录才能更改)。
编辑:我还想指出,在高DPI模式下(即使用 Shell_NotifyIcon
时),托盘图标也会遇到类似的缩放问题。在这种情况下,我可以使用 GetDeviceCaps( hdc, LOGPIXELSX )
来确定Windows想要什么...如果我有大小,直接提供它,否则提供256x256的那个,而Windows会正确地缩放它。
编辑:悲伤降临。这个问题可能是一个Windows问题。在捕获用于演示目的的图像时,我注意到音量混合器图标本身看起来很差。作为比较:
最终编辑:如下所述,解决此问题的方法是缩放图标。因此,最终的可行代码是加载指向 Comctl32.dll
中的 LoadIconWithScaleDown
函数的指针(未显示),并在可用时使用它,或退回到“常规/旧”方式:
HICON hIcon = 0;
if ( FAILED( comctl32Loader.LoadIconWithScaleDown( theApp.m_hInstance, MAKEINTRESOURCE( res_id ), GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), &hIcon ) ) ) {
hIcon = theApp.LoadIcon( res_id );
}
cWnd.SetIcon( hIcon, FALSE );
if ( FAILED( comctl32Loader.LoadIconWithScaleDown( theApp.m_hInstance, MAKEINTRESOURCE( res_id ), GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON), &hIcon ) ) ) {
hIcon = theApp.LoadIcon( res_id );
}
cWnd.SetIcon( hIcon, TRUE );
LoadImage
或通过GetSystemMetrics(SM_CXSMICON)
),那么它会选择一个低分辨率的图标并进行缩放(而且效果很差)。 - markLoadIconWithScaleDown
函数是个好东西。我的应用程序被编译成XP兼容的,但由于我正在检测Vista,所以我刚刚组合了一个类来查询从Comctl32.dll
中获取的函数指针……非常好用!值得一提的是,我验证过它可以在100%、125%、150%和138%(只是为了尝试某些自定义)的缩放比例下正常工作。 - mark