Search code examples
c++windowswinapigdidpi

What size of ImageList icons do I need to make & load for my app (considering higher DPI)?


I have a CListCtrl control (or a ListView in Win32) that is created with LVS_REPORT style.

I am intending to display icons in its items as such:

enter image description here

But the question is what size of icons do I need to make and load?

Let me explain. From the old Win32 samples, I can see that everyone creates image lists with 15x15 pixel icons. But the issue with those is that it looks horribly pixelated on any modern PC with higher DPI settings. Thus I was looking for a dynamic way to determine the appropriate size of image lists for the CListCtrl.

And also the first part of the question, what icon size should I make originally?

EDIT PS: Since DPI scaling came up, how do you find it out? I'm currently using the following approach:

//No error handling for brevity
HDC hDC = ::GetDC(hAppsMainWindowHandle);
int nCx = ::GetDeviceCaps(hDC, LOGPIXELSX);
int nCy = ::GetDeviceCaps(hDC, LOGPIXELSY);
::ReleaseDC(hAppsMainWindowHandle, hDC);

//I technically get horizontal & vertical scaling --
//can those be different?
double scalingCx = (double)nCx / 96.0;  //1.0 = 100%
double scalingCy = (double)nCy / 96.0;

Is font scaling something different?


Solution

  • A list view uses a "small" or "large" image list depending on its mode. In report mode, it uses the "small" image list. You can use GetSystemMetrics() to get the dimensions of "small" images using the SM_CXSMICON and SM_CYSMICON metrics (use SM_CXICON and SM_CYICON for "large" images).

    Note that the returned values will be virtual/scaled if your app is not DPI-aware, so to get accurate values, make sure it is DPI-aware via SetProcessDPIAware(), SetProcessDpiAwareness(), or a DPI manifest.

    Update: I just ran across this function, might be useful for you when writing a DPI-aware app:

    LoadIconWithScaleDown()

    Make larger images and let the API scale them down to smaller sizes.