DrJohn Posted June 19, 2020 Share Posted June 19, 2020 This is a minor annoyance, but it's bugging me because I feel like there should be a way out of it, and I haven't found it. I've got a script with two ListView's. Early on, I decided to create them with the UDF function [_GUICtrlListView_Create()] instead of GUICtrlCreateListView(), because it seems to me that the UDF functions to populate and work with a ListView are just easier to use. Unfortunately, there isn't any UDF function to set the ListView font and font size. So I ended up using _WinAPI_CreateFont() and _WinAPI_SetFont() to do it. Which seems to work fine. Then I decided to make the ListView font and font size configurable. So I whipped up a font chooser GUI, which allows for selection of font style and size. In the GUI, when you choose a style and size, it displays a Label in that style/size so you can get a preview of what it will look like. So far so good. Then I set the ListView font with that style and size. And it doesn't match. The text in the ListView is much smaller than in the GUI preview Label. Because, apparently, when you set the font size for a GUI Label with GUICtrlSetFont(), you're specifying size in points. With _WinAPI_CreateFont(), the size is 'height of font' (in pixels, I assume). So then I thought ... I need to take a given font style and point size, and convert it to the appropriate height. Then the ListView text should match what the GUI preview Label showed. Here's what I came up with. First, use GDIPlus to create a font object of the given family and size: $hGraphic = _GDIPlus_GraphicsCreateFromHWND($g_GUI) $hFamily = _GDIPlus_FontFamilyCreate($family) $hFont = _GDIPlus_FontCreate($hFamily, $g_Size) Then, get its height: $height = _GDIPlus_FontGetHeight($hFont, $hGraphic) Then pass that height to _WinAPI_CreateFont(): $font_obj = _WinAPI_CreateFont( _ $height, 0, 0, 0, _ $FW_DONTCARE, False, False, False, _ $DEFAULT_CHARSET, $OUT_DEFAULT_PRECIS, $CLIP_DEFAULT_PRECIS, _ $PROOF_QUALITY, $DEFAULT_PITCH, _ $g_Style _ ) It almost works. But not quite. Attached is a test script that demonstrates. When you choose a font style and size, it displays two labels. The first is set to the chosen point size. The second is set with _WinAPI_CreateFont() using a height obtained by the method I describe. In the case of some fonts (on my system, at least), the two effectively look identical. In other cases, not so much. (The difference shows particularly well for Trebuchet MS, and any of the Montserrat font styles, which I think are present on most Windows systems? Especially at larger sizes). Ought this not to work? Or is there another way I can convert point size to appropriate height to pass to _WinAPI_CreateFont() so it matches? Thanks! /John font_enum.au3 Link to comment Share on other sites More sharing options...
careca Posted June 20, 2020 Share Posted June 20, 2020 Wouldn't it be more simple to just revert to GUICtrlCreateListView? Or @Melba23's listview UDF? If there isn't anything there that you can't find elsewhere, (_GUICtrlListView_Create VS GUICtrlCreateListView) i think a good approach is to step back and look for the better path. Spoiler Renamer - Rename files and folders, remove portions of text from the filename etc. GPO Tool - Export/Import Group policy settings. MirrorDir - Synchronize/Backup/Mirror Folders BeatsPlayer - Music player. Params Tool - Right click an exe to see it's parameters or execute them. String Trigger - Triggers pasting text or applications or internet links on specific strings. Inconspicuous - Hide files in plain sight, not fully encrypted. Regedit Control - Registry browsing history, quickly jump into any saved key. Time4Shutdown - Write the time for shutdown in minutes. Power Profiles Tool - Set a profile as active, delete, duplicate, export and import. Finished Task Shutdown - Shuts down pc when specified window/Wndl/process closes. NetworkSpeedShutdown - Shuts down pc if download speed goes under "X" Kb/s. IUIAutomation - Topic with framework and examples Au3Record.exe Link to comment Share on other sites More sharing options...
DrJohn Posted June 20, 2020 Author Share Posted June 20, 2020 (edited) > Wouldn't it be more simple to just revert to GUICtrlCreateListView? Yes. Emphatically. I actually looked into that, and decided it would be intractable. Because basically I didn't see the forest for the trees. Here's the explanation, for what it's worth. The way the code is now, I create and populate my ListView like this: _GUICtrlListView_Create() _GUICtrlListView_AddColumn() ... _GUICtrlListView_AddItem()/_GUICtrlListView_AddSubItem() Then when I want to operate on the selected ListView item: $index = _GUICtrlListView_GetSelectedIndices() _GUICtrlListView_GetItemText($listview, $index) My whole code base essentially operates by passing that $index around and using it to access the ListView item. I thought that if I created the ListView using GUICtrlCreateListView(), then I had to populate it with GUICtrlCreateListViewItem(), which seems to follow a different paradigm -- each ListView item gets its own ControlID, and you access by ControlID instead of by index. Not accessing by index was going to mess with a bunch of my code. But it seems I was wrong about that. Even if you use GUICtrlCreateListView() to create the ListView, you can still populate it with _GUICtrlListView_AddColumn() and _GUICtrlListView_AddItem()/SubItem(). And then you can access by index. So this is probably the way to go. I just needed to think outside the box a little. Thanks, @careca. /John Edited June 20, 2020 by DrJohn careca 1 Link to comment Share on other sites More sharing options...
DrJohn Posted June 20, 2020 Author Share Posted June 20, 2020 (edited) Update: So I did switch over to using GUICtrlCreateListView(). A couple of minor hitches, but nothing that was too big a deal, and it works fine. In the process, though, I discovered something that surprises me. In fact, it was one of the things I bumped up against when I first considered making the switch, that made me think it was going to be trouble. I use the following code to access the currently selected list item: $idx = _GUICtrlListView_GetSelectedIndices($lv) $s = _GUICtrlListView_GetItemText($lv, $idx) This fails, apparently because $idx is a string (which I realize I have asked for deliberately, by letting the second parameter to _GUICtrlListView_GetSelectedIndices() default). _GUICtrlListView_GetItemText() apparently wants an integer, because this works: $idx = Number(_GUICtrlListView_GetSelectedIndices($lv)) $s = _GUICtrlListView_GetItemText($lv, $idx) Two things about this surprise me. First, I thought AutoIt took care of conversion between strings and numbers fairly transparently, and one didn't have to worry about this sort of thing. I know I mostly haven't. The second thing that I think is weird is that I only see this problem when the ListView is created with GUICtrlCreateListView(). If it is created with _GUICtrlListView_Create(), both of the above code blocks work as expected. In my case, when I switched from _GUICtrlListView_Create() to GUICtrlCreateListView(), the code broke in many places, and I thought I was hosed. It turned out it was just this one minor thing. A script to demonstrate is attached. As is, the ListView is created with GUICtrlCreateListView(). Run it, select a row in the list, and hit the Test button. The _GUICtrlListView_GetItemText() call on line #43 fails, but the one on line #48 succeeds. Flip the commenting on lines #12 and #13 so that the ListView is created with _GUICtrlListView_Create(), and both lines #43 and #48 succeed. No current problem on my part. I just thought if anyone else was wrestling with this issue, the information might be helpful. /John test.au3 Edited June 20, 2020 by DrJohn (Forgot to attach the script ...) Link to comment Share on other sites More sharing options...
Moderators Melba23 Posted June 20, 2020 Moderators Share Posted June 20, 2020 DrJohn, I have looked inside the _GUICtrlListView_GetItemText function and the $iIndex parameter is passed directly to Windows in the following line: _SendMessage($hWnd, $LVM_GETITEMTEXTW, $iIndex, $tItem, 0, "wparam", "struct*") Although AutoIt is pretty good at automatically converting datatypes, Windows is not and does not like a string being passed as $wparam. Thus it works when you force the number datatype, but not when you do not. M23 Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind Open spoiler to see my UDFs: Spoiler ArrayMultiColSort ---- Sort arrays on multiple columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area Link to comment Share on other sites More sharing options...
DrJohn Posted June 20, 2020 Author Share Posted June 20, 2020 Thanks @Melba23. That makes sense. It's good to know -- I can be on the lookout for it in the future. /John Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now