I'm using the SetupDi... functions to enumerate HID devices.
If I'm looking at these devices in the windows settings, they have nice hi-res icons (photos). I'm looking for the API to receive those.
I've tried SetupDiLoadDeviceIcon, but the result is underwelming:
This is when I request a 100x100 icon. I've tried larger and smaller sizes as well.
Here's the code I'm using (somewhat simplified, iterating through index gives all HID devices):
GUID guid;
HidD_GetHidGuid(&guid);
device_info_set = SetupDiGetClassDevs(guid,
NULL, NULL,
DIGCF_PRESENT|DIGCF_DEVICEINTERFACE);
SP_DEVINFO_DATA dev_info;
SetupDiEnumDeviceInfo(device_info_set, index, &dev_info);
SetupDiLoadDeviceIcon(device_info_set,
dev_info,
100, 100,
0,
&hicon);
This is the small icon used in the device manager (missing the alpha mask). How can I get the pretty ones?
Just to be clear, these are kind of icons / images I'm looking for.
The logitech HID device, for example, is not a stock picture:
After calling SetupDiGetClassDevs+SetupDiEnumDeviceInfo and requesting a 256x256 icon from SetupDiLoadDeviceIcon I'm given a icon that is 256x256 pixels in size but it has clearly been resized because the quality is horrible.
GetIconInfoEx tells me the icon has been loaded from setupapi.dll and that library only contains 16x16, 32x32 and some 48x48 device icons. This does not apply to all devices, some are able to deliver a high quality icon.
If you want high quality generic device icons you can use SHGetStockIconInfo.
Related
Windows 10 has new pin icons in the Jump List. Black and white for different themes.
Old Windows 7 pin icons stayed inside imageres.dll, ID 5100, 5101.
Where are new icons stored? How get they with WinAPI?
Icons have traditionally been raster images. The benefit of raster images is, that they are blazingly fast to render. That speed comes with a downside, namely that raster images only look good at a narrow range of pixel densities. That was great for as long as most displays had a pixel density of 96 PPI (pixels per inch). With pixel densities increasing, raster images stopped being as useful as they used to be. On high-density displays, icons would either render too small, or had to be scaled up with all sorts of visual artifacts.
To address this, Windows 8 introduced font-based icons as the Windows UI Symbol font, that was superseded in Windows 10 by the Segoe MDL2 Assets font. Fonts are vector-based, and can be scaled across a wide range without (or very little) visual artifacts.
While I have not verified, whether the Windows Shell actually does use font icons, the icons you are looking for are available in the Segoe MDL2 Assets font with Unicode code points in the private use area:
U+E718 ("Pin")
U+E77A ("Unpin")
Since Windows 10 version 1903, icon resource files have been relocated to: C:\Windows\SystemResources\imageres.dll.mun
There is now a new extension for these files .mun instead of .mui (which still exist in system32 and syswow64 sub folders.
Also see the answer to the question Can I trust imageres.dll system icons indexes?:
The correct way to get the icons is to use SHGetStockIconInfo. It will tell you where the icon is in the current version of Windows.
If you want the system's current folder icons (which may not be the standard ones due to user customization), use SHGetFileInfo.
I don't have any Deep-Color capable hardware attached to my computer, so I haven't been able to experiment myself, and searching online for "win32 deep-color" or "win32 10-bit color" (or 30-bit, 48-bit or 64-bit) yields nothing relevant or recent. The top result is still this NVIDIA PDF from 2009: https://www.nvidia.com/docs/IO/40049/TB-04701-001_v02_new.pdf - it describes using OpenGL and an NVIDIA API for displaying images with more than 8-bits per channel.
I understand how using OpenGL allows 30-bit color images to be displayed: it effectively bypasses the operating system and the OpenGL surface is rendered in deep-color on the GPU and sent directly to the monitor in an appropriate format over DisplayPort or HDMI.
But what options are there outside of OpenGL?
In Win32, after you create a Window with CreateWindow, you render it by handling the WM_PAINT message, and then calling BeginPaint, which gives you a handle to a GDI device-context, which cannot be more than 32bpp (8-bits per channel).
While GDI ostensibly abstracts away implementation details of the rendering device, including color depth, it is impossible to specify a 10bpp RGB value, for example (the COLORREF struct is hardcoded to use 32-bit (8bpp) DWORD values), a leaky-abstraction.
Does this mean it is impossible to display 30bpp / Deep-color content in the Windows Desktop using a program handling WM_PAINT and that OpenGL is the only way?
And what would happen if you attempted to blit from an in-memory OpenGL rendering buffer back to the window surface? (i.e. what happens if you press PrintScreen while displaying a Deep-Color BluRay disc in a BD player, or displaying 30-bit content in Photoshop?)
When I make a new Universal App in Visual Studio 2013 I get a number of graphics files for the logos, splash screens, etc. in the Assets folder, for example Square71x71Logo.scale-240.png. The Package.appxmanifest then maps these files to the various required things. For example Square71x71Logo.scale-240.png is mapped in Package.appxmanifest to Square 71x71 Logo.
The actual file is 170 pixels wide, 170 pixels high, Photoshop reads it as having 72 pixels per inch, and it has an 8 bit colour depth.
What does the .scale-240 part of the file name signify?
I'm replacing the file and I am not sure how to scale-240-ify the new image.
The scale-240 part of the file name is a resource qualifier that indicates that the file is used for 240% DPI systems.
Resource qualifiers allow the app to provide different versions of the same resource for different scenarios and refer them all internally by the base name:
Scaling for different DPI systems: .scale-100, .scale-140, .scale-180, .scale-240
Language (if the image has text in it): .lang-de-DE, .lang-en-us
Contrast (to simplify for high contrast modes): .contrast-high, .contrast-standard
Layout direction (if the image should be different in LTR vs RTL language settings): .layoutdir-RTL, .layoutdir-LTR
DirectX feature level: .DXFL-DX9, .DXFL-DX11
The app can reference the image by its base name (e.g. logo.png) and the version which best matches the current scale, contrast level, language, etc. will be automatically used.
The default phone template provides scale-240 images since high-DPI phones are fairly common and it is generally better to scale down from a larger image than to scale up a small image. Best would be for you to provide multiple resolutions when you replace the stock ones with your own, especially if your images are complicated and don't scale well by default.
See How to name resources using qualifiers (XAML)
Universal apps need to be able to run on very different screens. You cannot predict up front what kind of device the user might have. Big difference if he has a cheap contract phone, an expensive slate or a desktop machine. WinRT helps by automatically scaling your app to match the screen resolution.
Supported scaling percentages for a desktop/slate app are 80, 100, 140 or 180%. For a phone it is 100, 140 or 240%.
Text can auto-scale easily but images do not. They get blurry when they get rescaled, a single pixel in the image no longer coincides with a single screen pixel. Pretty noticeable when the image contains fine line art or text. Scaling down necessarily loses pixels, details may disappear.
So the Visual Assets tab of the manifest editor allows you to select multiple images, each suitable for a specific scaling percentage. You found the -240 version in your phone project's Assets directory, the 240% scaling version that were auto-generated when you created the project. The desktop version has -100 assets by default, 100% scaling.
You may want to add your own. You don't have to.
.scale-xxx appears to refer to pre-scaled image resources.
If you are using a an image logo.png with size 100x100px then logo.scale-240.png should be an image of size 240x240px, i.e. scaled by a factor of 240 percent. The idea behind this concept is apparently to avoid potentially expensive and inaccurate rescaling by the displaying device, by supplying several prescaled images at defined scales.
In your case: 170px / 2.40 = ~71px
See also the corresponding MSDN article. (The linked article is in German, I will leave it to the interested reader to find the matching English one ;-)
What I'm trying to do:
I've added a splash screen to an application I'm creating for Windows Phone 7. I did this simply by replacing the pre-existing splash screen file with my own.
What goes wrong:
The splash screen is not displayed like it should be - it is being down sampled to an 8 bit image or something weird:
-
The image I'm using
-
The image that gets displayed
It's a bit hard to see depending on your monitor, but on a phone it's reasonably obvious. There are fuzzy greenish lines that appear - basically like the image is being down sampled or the quality worsened.
Any idea what I'm doing wrong, or what might be happening?
Thanks.
Try forcing the app to display images at 32 bits per pixel (instead of the default of 16)
Add an attribute of BitsPerPixel="32" to the app element in WMAppManifest.xml
See http://forums.create.msdn.com/forums/p/85960/520394.aspx#520394
The problem is that the gradient on your splash screen is causing banding, which you can solve by dithering. Robby Ingebretsen has an action for PhotoShop that you can use: http://nerdplusart.com/photoshop-action-for-windows-phone-7-dithering
I suspect the emulator. Run the emulator at full size or run the app on an actual device.
Windows Phone is currently only supporting a color depth of 16bit, causing especially some gradients displaying downsampled for 24bit images. Some first generation firmwares by HTC had a "bug" that also allowed 24bit. Theoretically it is just a registry key, but you cannot commonly change it. Microsoft has limited the color depth to 16bit for the benefit of performance, but as far as I knnow there are some second-generation models without this limitation now.
You may try to downsample the image in Photoshop to 16bit and optimize it for this color depth.
when I open the application icon of a MFC-project with Visual Studio 2008 there are 13 images (different sizes, different color palette). How would you change the icon of your MFC-application without changing each image?
Thanks!
I like to use the Icons file type extension with Paint.NET. When you open a .ICO file it will prompt you for which image to open - select only the largest / highest-bit image. Make your changes, and then save. You will be prompted for which sizes and bitness to save - select the same list that was present in the original icon.
Using this method, you will get automatically scaled and dithered icons at the smaller sizes. A designer would actually tweak the icons at each size to get the best look, but for most applications this technique produces something that is usable.
An icon resource typically contains many different versions of an icon. For an application icon you would expect 16x16, 32x32, 48x48 and 256x256. You'd also expect to see the 3 smaller ones at 32 bit colour, 8 bit colour 4 bit colour. Or some variant on that. Microsoft publishes guidelines.
Why so many different versions of the same icon?
Well, the icon will be drawn in different settings. On a window caption bar, the 16px version will typically be shown. On the Windows 7 taskbar the 48px version will be shown. When usint ALT+TAB in XP the 32px will be shown. In Vista/7 explorer with ultra large icon view, the 256px will be shown.
To obtain the best visual appearance you must have different versions of the image for different sizes because small raster images aren't easy to scale. What's more, you may present a slightly different version of the icon at different resolutions. For example you may use 3D effects only on larger resolution, partial transparency versions.
When using remote desktop, lower colour depths may be used if the connection is bandwidth challenged.
The MS guidelines go into these issues in detail.
The normal practice of for the graphic designer to design the icon and once you are happy with it the designer will produce rasterised versions for all the required sizes and colour depths, typically in a single .ico file.