0

I build a MDI (FormStyle = fsMDIForm) VCL application in Delphi 10 Seattle Update 1. I disable High-DPI and running the following code:

var F: TForm;
    B: TTaskBar;
begin
  F := TForm.Create(Application);
  F.FormStyle := fsMDIChild;

  B := TTaskBar.Create(F);
  B.TabProperties := [TThumbTabProperty.CustomizedPreview];
end;

I run the application on Windows 8.1 with multi monitor support with these settings:

  1. Primary Display 0: 1920 x 1080 resolution
  2. Display 1: 1366 x 768 resolution
  3. In Control Panel | Display, uncheck Let me choose one scaling level for all my displays and
  4. Change the size of all items to scale other than smaller(96 dpi) (e.g.: Middle - 120 dpi or Larger 144 dpi)

The application will raise Failed to set bitmap as preview exception when I move mouse pointer over to button on windows task bar.

If I enable the High DPI aware in Project | Option, it works fine.

Is TTaskBar not suitable for non High-DPI aware application?

Chau Chee Yang
  • 18,422
  • 16
  • 68
  • 132
  • Have you considered debugging this? – David Heffernan Dec 23 '15 at 07:10
  • @DavidHeffernan: I have tried debug, but no clue at all. It fail at `LResult := DwmSetIconicThumbnail(GetFormHandle, FTmpPreviewBitmap.Handle, 0);` – Chau Chee Yang Dec 23 '15 at 07:13
  • What is the HRESULT error code? Read MSDN docs. Try to understand the API. – David Heffernan Dec 23 '15 at 07:17
  • @DavidHeffernan: `HRESULT is -2147024809` MSDN only mentioned this: `If this function succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.` Couldn't find meaning for the error code. – Chau Chee Yang Dec 23 '15 at 07:31
  • 1
    Convert it to hex and then decode it. Do a websearch to understand how to decode. Take this opportunity to gain some skills. FWIW I guess that the framework is making a preview of the wrong size. – David Heffernan Dec 23 '15 at 07:35
  • FWIW, that `HResult` value is [`E_INVALIDARG`](https://msdn.microsoft.com/en-us/library/windows/desktop/aa378137%28v=vs.85%29.aspx). – Ondrej Kelle Dec 23 '15 at 08:42
  • As Remy said, this component is poor. Far better to use the raw API which is easy enough to use. – David Heffernan Dec 23 '15 at 08:58
  • @TOndrej: I use `CheckOSError` and it prompt `One or more arguments are not valid` – Chau Chee Yang Dec 23 '15 at 09:07
  • @ChauCheeYang Yes, that message corresponds to the `HResult` value, also shown on the page I linked to. – Ondrej Kelle Dec 23 '15 at 09:19
  • Try some debugging. Work out why this function is being called. What contract must it adhere to. Why is it failing? What changes with and without dpi awareness? This is all documented. Sure we could do that for you but I feel that you are capable of this. – David Heffernan Dec 23 '15 at 15:45
  • @DavidHeffernan: I have rephrase my question. The error happens on specific environment setting: MDI application and DPI = `120` or more – Chau Chee Yang Dec 24 '15 at 00:50
  • Why are you creating a (long deprecated) MDI application in the 21st century? That's 1980s. This is nearly 2016. No one has used MDI for twenty years, and it's only around now in Windows for backwards-compatibility reasons. It's no wonder it doesn't work properly now in current Windows versions. – Ken White Dec 24 '15 at 01:18
  • @KenWhite: The taskbar issue isn't fully related to MDI application. The method `TCustomTaskbar.DoThumbPreviewRequest` get form image from MDI child form explicitly. Even if I handle the event `TTaskBar.OnThumbPreviewRequest`, I will render the thumbnail image similarly regardless of it's formstyle and I will face the same issue too. – Chau Chee Yang Dec 24 '15 at 01:24
  • Why won't you debug this? – David Heffernan Dec 24 '15 at 07:32
  • @DavidHeffernan: I have tried to debug it. I found out two parameters: `APreviewHeight` and `APreviewWidth` in method `procedure TCustomTaskbar.DoThumbPreviewRequest` is the one that cause the error. If I reduce both parameters to `APreviewHeight := MulDiv(APreviewHeight, 96, 120)`, than it works. I think it was the size that cause the error to method `DwmSetIconicThumbnail`. The value of `96` and `120` is the default PPI and monitor's PPI respectively. – Chau Chee Yang Dec 24 '15 at 21:58
  • That tallies with what I said yesterday, "I guess that the framework is making a preview of the wrong size." – David Heffernan Dec 24 '15 at 22:13
  • @DavidHeffernan. Thanks David. At least I found the cause the problem. Now, next problem arise, The problem happens on non High-DPI aware application. How can I detect the current DPI setting for my display. `Screen.monitors[n].PIxelPerInch` all shows `96` in my case. The only way I found so far is access registry: `HKEY_CURRENT_USER\Control Panel\Desktop\WindowMetrics\AppliedDPI` to get the value. Is there a windows API to return actual screen DPI from non High-DPI runtime? – Chau Chee Yang Dec 24 '15 at 22:19
  • That question has been asked many times here. A search will find it. – David Heffernan Dec 24 '15 at 22:24
  • The best answer I found so far is using registry from `HKEY_CURRENT_USER\Control Panel\Desktop\WindowMetrics\AppliedDPI` but not API in https://stackoverflow.com/questions/6983837/getting-custom-dpi-percentage-in-delphi – Chau Chee Yang Dec 25 '15 at 12:22

0 Answers0