Tom Mueller 5 Posted Friday at 07:58 AM A common scenario in our applications involves using a centralized TActionList connected to a TVirtualImageList on a data module. The actions in the list are linked to controls on different forms (UI). However, when moving a form to a monitor with a different DPI, the action images do not scale properly. This occurs because the TVirtualImageList is not located on the moved form. Given that we have several centralized TActionLists in our applications, moving or duplicating them to different forms solely for image scaling doesn’t seem like an ideal solution. How should centralized TActionLists be handled in HighDPI-supported applications? Share this post Link to post
John R. 20 Posted Friday at 09:31 AM That might not answer your specific question but if you have access to DevExpress components, I highly recommend using only SVG icons in their image lists. You will no worries about icon quality, scale, dpi settings... anymore. Share this post Link to post
Tom Mueller 5 Posted Friday at 09:52 AM Thank you for your tip. I tested the DevExpress TcxImageList, and it works fine with DevExpress controls. However, it does not support certain Delphi controls, such as TMainMenu, TPopupMenu, TToolBar, TTreeView, TListView and maybe more, which are essential controls for me. Share this post Link to post
Uwe Raabe 2103 Posted Friday at 09:59 AM Usually you connect the actions of such a TActionList to some visual control of a form (TMainMenu, TPopupMenu, TToolBar, TTreeView, TListView ...). Most of these controls have their own property to connect a TVirtualImageList, which should reside on the form itself. The latter is mandatory to make DPI awareness work properly. It may sound wrong to have separate virtual image lists in each form, which often contain the same content - sometimes the same as the one connected to the ActionList. If you imagine that each each image list can only hold one size of images and each form can have run on a different DPI it becomes clear that this is unavoidable. While it can be tedious to have all these TVirtualImagelist instances at design time, there are ways to simplify it. If you are interested I suggest reading my blog posts about ImageLists and High DPI 1 Share this post Link to post
Tom Mueller 5 Posted Friday at 10:49 AM This essentially means that no ImageList can be used for a centralized TActionList. Instead, a TVirtualImageList must be created on each form and associated with the control. This is a significant limitation of the TImageCollection/TVirtualImageList concept. I wonder how DevExpress handles this, as the scaling works even when the cxImageList is placed on a DataModule. Thanks Uwe for pointing me to your blog. The article is very well-written and could help me with implementing centralized image management. Share this post Link to post
Uwe Raabe 2103 Posted Friday at 10:58 AM Just now, Tom Mueller said: I wonder how DevExpress handles this, as the scaling works even when the cxImageList is placed on a DataModule. I'm not familiar with the DevExpress approach, but I assume the DX controls can request an image of arbitrary size/DPI from an DX image list (probably acting like a VCL TImageCollection). Standard controls based on Windows require an HIMAGELIST at the end, which contains images all of the same size. Compatibility is the limiting factor here. Share this post Link to post
Tom Mueller 5 Posted Friday at 11:04 AM Just now, Uwe Raabe said: Compatibility is the limiting factor here. Yes, unfortunately. cxImageList would be the ideal solution if all controls (not just DevExpress) were supported. Share this post Link to post
John R. 20 Posted Friday at 01:43 PM I've just tested a TcxImageList with a SVG image and used by a TActionList, Speed button and standard menu, and it seems to work just fine. Share this post Link to post
Anders Melander 1924 Posted Friday at 02:06 PM 4 hours ago, John R. said: DevExpress [...] You will no worries about icon quality, scale, dpi settings... anymore. Well, I wouldn't say you don't have to worry; They work pretty well but they are not without their own bugs. Our code is littered with work-arounds for DevExpress bugs, many of them High-DPI related. 4 hours ago, Tom Mueller said: it does not support certain Delphi controls, such as TMainMenu, TPopupMenu, TToolBar, TTreeView, TListView and maybe more, which are essential controls for me. If you enable skinning then TMainMenu and TPopupMenu are drawn by DevExpress. They also have treeview and listview controls based on TTreeView and TListView so migration should be fairly easy. TToolbar will have to be replaced but that should be no great loss. Share this post Link to post
msohn 28 Posted Friday at 02:42 PM I spent a major part of the last 4 years making our application here HighDPI compliant. And I ended up using DevExpress TcxImageList exclusively with SVGs, partially custom made. SVGs not only solve the DPI problem, they also feature a skin-adaptable palette, so that if your app has e.g. a light and a dark skin, the SVGs actually adapt their color (which they have to, to be identifiable in dark mode). With this approach a centralised ImageList is absolutely no problem - in fact you can request a specific image from the list in any desirable size/scale e.g. for use in custom drawings etc. 26 minutes ago, Anders Melander said: Well, I wouldn't say you don't have to worry; They work pretty well but they are not without their own bugs. Our code is littered with work-arounds for DevExpress bugs, many of them High-DPI related. Would you be willing to share more info on what these are, e.g. links to DX support issues? Littering code with workarounds sounds awful. I remember that back in maybe 2020 there were still a few issues, especially with the adaptable SVG palette, but with the 2022 version and RX 11.2 I'm currently using I'm actually very satisfied. 26 minutes ago, Anders Melander said: If you enable skinning then TMainMenu and TPopupMenu are drawn by DevExpress. They also have treeview and listview controls based on TTreeView and TListView so migration should be fairly easy. TToolbar will have to be replaced but that should be no great loss. I had to stop using TcxTreeView and TcxListView altogether, they are just shells around the native controls and as such do not support proper skinning and scaling as well as the SVG palettes. DX also made it quite clear that they don't intend to put more work into these controls, but rather in the alternatives TcxTreeList and TdxListViewControl. And since TcxTreeList is also capable to replace TVirtualTreeView I went this route. Share this post Link to post
Tom Mueller 5 Posted Friday at 02:50 PM 44 minutes ago, John R. said: I've just tested a TcxImageList with a SVG image and used by a TActionList, Speed button and standard menu, and it seems to work just fine. My little tests with TcxImageList and SVG images shows the lack of scaling on a HighDPI monitor (here scaled to 225%). Even TcxListView does not scale correctly compared to Delphi TVirtualImageList. 35 minutes ago, Anders Melander said: If you enable skinning then TMainMenu and TPopupMenu are drawn by DevExpress. They also have treeview and listview controls based on TTreeView and TListView so migration should be fairly easy. TToolbar will have to be replaced but that should be no great loss. Thank you for the skinning tip. Until now we tried to avoid skinning or styling our applications - but I'll give it a try. Share this post Link to post
Tom Mueller 5 Posted Friday at 03:04 PM 11 minutes ago, msohn said: I spent a major part of the last 4 years making our application here HighDPI compliant. And I ended up using DevExpress TcxImageList exclusively with SVGs... Thank you for sharing your experience with us. How did you replace TMainMenu, TPopupMenu, and TToolBar controls? Especially the MainMenu and PopupMenus, as they are widely used in our applications. Share this post Link to post
msohn 28 Posted Friday at 03:14 PM Just now, Tom Mueller said: How did you replace TMainMenu, TPopupMenu, and TToolBar controls? Especially the MainMenu and PopupMenus, as they are widely used in our applications. We already used ExpressBars in most of the places. And just like TListView and TTreeView (regardless if original or cx version) don't support SVGs and skinning properly, so is the skinning and SVG support for TMainMenu et al very limited. With regard to TPopupMenu, if you need to use a control which cannot handle TcxPopupMenu, you can just handle popping up the menu manually via an OnContextPopup even handler (not sure if this is the right name). But I freely admit, this is only giving good results if you go all-in on the DX controls and it's a lot of work. But for us this was just a logical conclusion and it made us clean up very old parts of the GUI. The end result using TdxLayoutControl etc. is much more flexible than it ever was before. Share this post Link to post
Anders Melander 1924 Posted Friday at 03:20 PM 5 minutes ago, msohn said: Would you be willing to share more info on what these are, e.g. links to DX support issues? Littering code with workarounds sounds awful. Here's the latest (not HighDPI related though): https://supportcenter.devexpress.com/ticket/details/t1277096/drawing-of-screentip-description-does-not-take-skin-palette-into-account TLDR; It ended up as "won't do" since they deem it a corner case (ScreenTip with formatted text and skins) and too expensive to fix. Even though I don't think it's that much of a corner case I can't really blame them much; Resources are limited. I don't mind the workarounds that much. I do mind the cases where I have to patch their code because that is really a pain to maintain. A search, in the project I have open right now, for "work.?around.+devexpress" gives me 29 hits. Most have no reference to a DevExpress issue (and some have probably never been reported) but here's the first 5 that does have a reference (only one of them is HighDPI related): https://supportcenter.devexpress.com/ticket/details/t1135725 Requires patching https://supportcenter.devexpress.com/ticket/details/t1130612 Requires patching. I believe this one has just been resolved in the latest release. https://supportcenter.devexpress.com/ticket/details/t1073008 https://supportcenter.devexpress.com/ticket/details/t1263794 https://supportcenter.devexpress.com/ticket/details/t1267760 HighDPI problem. All the same issue. Will supposedly be fixed at some point... https://supportcenter.devexpress.com/ticket/details/t1270641 https://supportcenter.devexpress.com/ticket/details/t1195057 Share this post Link to post
Anders Melander 1924 Posted Friday at 03:33 PM 4 minutes ago, msohn said: The end result using TdxLayoutControl etc. is much more flexible than it ever was before. For me this is the single most useful of their controls in terms of UI design. It can be be hard to work with if you need an unusual layout but for the bread and butter dialog layout it is just perfect. With regard to skinning, I recommend chosing one of the vector based skins (this avoids most of the bloat). If the user must be able to customize the color scheme, then just give them 3 choices: Light, Dark, Custom (selects among the available color palettes). As an example, here's the UI to do this from BTM: As far as I remember that whole dialog is a layout control. Share this post Link to post
msohn 28 Posted Friday at 03:43 PM 12 minutes ago, Anders Melander said: A search, in the project I have open right now, for "work.?around.+devexpress" gives me 29 hits Thanks for sharing Anders. I regularly run into tickets by you on the DX support site and I'm often impressed how well written and researched these are. I bet the support guys at DX very much remember your name by now 😉 FWIW I "starred" a few tickets which I'd like to see fixed as well - one can only hope. 1 minute ago, Anders Melander said: For me this is the single most useful of their controls in terms of UI design. It can be be hard to work with if you need an unusual layout but for the bread and butter dialog layout it is just perfect. Yes that is exactly my experience as well. Sometimes one feels like your hands are being tied, but then you just need to remember how much more tedious it was without the LayoutControl. 3 minutes ago, Anders Melander said: With regard to skinning, I recommend chosing one of the vector based skins (this avoids most of the bloat). Yes that's also exactly what I did - specifically TheBezier skin with different palettes and an unskinned mode where main forms are lfOffice11 (yeah I know, looks a bit old) and all dialogs use NativeStyle - this was the original look and was kept for people not wanting to adapt the looks. Share this post Link to post
Dave Novo 56 Posted Friday at 05:04 PM (edited) What we have done is have a centralized imageList in a datamodule for the application. We then have separate actionList/imageList pairs on every form. In the form Create, we copy the image(s) we need for that form from the central image list to the image list on the form being shown. Its a bit of a pain, we have a list of constants on the central datamodule so we can request images in an easy to read manner. So, on any given form's Create, we do something like actExportToExcel.ImageIndex:=CentralImageDataModule.AddImage(self.ImageList,IMG_EXPORT_TO_EXCEL) Its a bit of a pain and we have some utility functions like CentralDAtaModule.AddImageIndices([act1,act2,ac3],[CONST1,CONST2,CONST3]) to make it a bit simpler. But that way we can update the images in the central data module and have them update everywhere. Edited Friday at 05:05 PM by Dave Novo Share this post Link to post