Zedna Posted August 30, 2007 Share Posted August 30, 2007 (edited) Maybe it's bug in GUICtrlSetImage() but I'm not sure so I post it here.Please can somebody look at it?I have workaround for that (restore header imagelist)but I prefer some explanation or correction. I simplified my huge LOG_View project to this smaller testing scriptbut it's still rather big so sorry for that. I didn't want to remove core functions related to problem.Some notes:- App consinst from ListView in report style with some ListView items - with ListView header is asociated dynamic created imagelist to show green arrow in header column representing sorting - with ListView items is used GUICtrlSetImage() to set item icon from resources (icons.res) Problem is when I use GUICtrlSetImage() to set items icons then green arrow in ListView header is destroyed and is shown icons from first and second ListView item (instead of green arrow from my imagelist)For simpler demonstation I created ListView without GUICtrlSetImage() first to show green arrow is shown correctly after clicking on column header. When you click button ""GUICtrlSetImage" then is applied GUICtrlSetImage() to ListView items and from now is not shown green arrow in column header after click on header column (instead is shown icon from first and second ListView item).When you check "Workaround checkbox" then is applied my workaround so after click on column header is shown green arrow correctly. My workaround uses SendMessage with HDM_SETIMAGELIST which restores imagelist.Here are screenshots and sources and all stuff (all_stuff.zip: ICONS.RC,ICONS.RES,log_view.au3)expandcollapse popup#AutoIt3Wrapper_useupx=n #AutoIt3Wrapper_run_after=ResHacker.exe -add %out%, %out%, icons.res ,,, #AutoIt3Wrapper_run_after=upx.exe --compress-icons=0 "%out%" #NoTrayIcon #include <GUIConstants.au3> #include <GuiListView.au3> Global Const $LVM_GETITEM = $LVM_FIRST + 5 Global Const $ILC_MASK = 0x0001 Global Const $ILC_COLOR32 = 0x0020 Global Const $HDM_SETIMAGELIST = 0x1208 Global Const $HDM_SETITEM = 0x1204 Global Const $HDI_FORMAT = 0x4 Global Const $HDI_IMAGE = 0x20 Global Const $HDF_STRING = 0x4000 Global Const $HDF_IMAGE = 0x800 Global Const $HDF_BITMAP_ON_RIGHT = 0x1000 Global $nCurCol = -1, $nSortDir = 1, $bSet = 0, $nCol = -1, $Done = 0 Global $Header, $HD_ITEM, $LViewImageList $Form1 = GUICreate("ListView header imagelist test", 300, 250) $ListView1 = GUICtrlCreateListView("Col1|Col2|Col3", 10, 10, 280, 180, BitOR($LVS_REPORT,$LVS_SINGLESEL,$LVS_SHOWSELALWAYS,$WS_HSCROLL,$WS_VSCROLL,$WS_BORDER), BitOR($WS_EX_CLIENTEDGE,$LVS_EX_FULLROWSELECT)) $btn1 = GUICtrlCreateButton("GUICtrlSetImage", 10, 200) $check1 = GUICtrlCreateCheckbox("Workaround", 150, 200) GUISetState(@SW_SHOW) ; init header imagelist $HD_ITEM = DllStructCreate("int;int;ptr;int;int;int;int;int;int") $LViewImageList = ImageList_Create(16, 16, BitOR($ILC_MASK, $ILC_COLOR32), 2, 0) $stIcon = DllStructCreate("int") ExtractIconEx(@ScriptFullPath, 3, 0, DllStructGetPtr($stIcon), 1) ; sort_asc.ico ImageList_AddIcon($LViewImageList, DllStructGetData($stIcon, 1)) ExtractIconEx(@ScriptFullPath, 4, 0, DllStructGetPtr($stIcon), 1) ; sort_desc.ico ImageList_AddIcon($LViewImageList, DllStructGetData($stIcon, 1)) DestroyIcon(DllStructGetData($stIcon, 1)) $stIcon = 0 $Header = GUICtrlSendMsg($ListView1, $LVM_GETHEADER, 0, 0) DllCall("user32.dll", "int", "SendMessage", "hwnd", $Header, "int", $HDM_SETIMAGELIST, "int", 0, "hwnd", $LViewImageList) ; add some data $item1 = GUICtrlCreateListViewItem('Data11|Data12|Data13', $ListView1) $item2 = GUICtrlCreateListViewItem('Data21|Data22|Data23', $ListView1) $item3 = GUICtrlCreateListViewItem('Data31|Data32|Data33', $ListView1) GUICtrlSendMsg($ListView1, $LVM_SETCOLUMNWIDTH, 0, 75) GUICtrlSendMsg($ListView1, $LVM_SETCOLUMNWIDTH, 1, 75) GUICtrlSendMsg($ListView1, $LVM_SETCOLUMNWIDTH, 2, 75) GUICtrlRegisterListViewSort($ListView1, "LVSort") While 1 $msg = GuiGetMsg() Switch $msg Case $GUI_EVENT_CLOSE Exit Case $btn1 ; this destroy listview header imagelist GUICtrlSetImage($item1, @ScriptFullPath, -6) GUICtrlSetImage($item2, @ScriptFullPath, -8) GUICtrlSetImage($item3, @ScriptFullPath, -10) Case $ListView1 $Done = 0 $bSet = 0 $nCurCol = $nCol EndSwitch WEnd ; sorting function, also sets sort icon in column header Func LVSort($hWnd, $nItem1, $nItem2, $nColumn) ; Switch the sorting direction If $nColumn = $nCurCol Then If Not $bSet Then $nSortDir = $nSortDir * -1 $bSet = 1 EndIf Else $nSortDir = 1 EndIf If $Done = 0 AND $nSortDir = 1 Then SetHeaderIcon($nColumn, 0) $Done = 1 ElseIf $Done = 0 AND $nSortDir = -1 Then SetHeaderIcon($nColumn, 1) $Done = 1 Endif $nCol = $nColumn $val1 = GetSubItemText($ListView1, $nItem1, $nColumn) $val2 = GetSubItemText($ListView1, $nItem2, $nColumn) $nResult = 0 ; No change of item1 and item2 positions If $val1 < $val2 Then $nResult = -1 ; Put item2 before item1 ElseIf $val1 > $val2 Then $nResult = 1 ; Put item2 behind item1 EndIf Return $nResult * $nSortDir EndFunc Func SetHeaderIcon($iCol, $iSortOrder) ; after GUICtrlSetImage header imagelist gets corrupted ; workaround: restore header imagelist If BitAnd(GUICtrlRead($check1),$GUI_CHECKED) = $GUI_CHECKED Then DllCall("user32.dll", "int", "SendMessage", "hwnd", $Header, "int", $HDM_SETIMAGELIST, "int", 0, "hwnd", $LViewImageList) EndIf DllStructSetData($HD_ITEM,1,BitOR($HDI_IMAGE,$HDI_FORMAT)) DllStructSetData($HD_ITEM,8,$iSortOrder) For $x = 0 To 2 If $x = $iCol Then DllStructSetData($HD_ITEM,6,BitOR($HDF_STRING,$HDF_IMAGE,$HDF_BITMAP_ON_RIGHT)) Else DllStructSetData($HD_ITEM,6,$HDF_STRING) EndIf DllCall("user32.dll", "int", "SendMessage", "hwnd", $Header, "int", $HDM_SETITEM, "int", $x, "ptr", DllStructGetPtr($HD_ITEM)) Next EndFunc ; ############### include files ################ Func GetSubItemText($nCtrlID, $nItemID, $nColumn) Local $stLvfi = DllStructCreate("uint;ptr;int;int[2];int") DllStructSetData($stLvfi, 1, $LVFI_PARAM) DllStructSetData($stLvfi, 3, $nItemID) Local $stBuffer = DllStructCreate("char[260]") $nIndex = GUICtrlSendMsg($nCtrlID, $LVM_FINDITEM, -1, DllStructGetPtr($stLvfi)) Local $stLvi = DllStructCreate("uint;int;int;uint;uint;ptr;int;int;int;int") DllStructSetData($stLvi, 1, $LVIF_TEXT) DllStructSetData($stLvi, 2, $nIndex) DllStructSetData($stLvi, 3, $nColumn) DllStructSetData($stLvi, 6, DllStructGetPtr($stBuffer)) DllStructSetData($stLvi, 7, 260) GUICtrlSendMsg($nCtrlID, $LVM_GETITEM, 0, DllStructGetPtr($stLvi)); $sItemText = DllStructGetData($stBuffer, 1) $stLvi = 0 $stLvfi = 0 $stBuffer = 0 Return $sItemText EndFunc Func ImageList_Create($nImageWidth, $nImageHeight, $nFlags, $nInitial, $nGrow) $hImageList = DllCall('comctl32.dll', 'hwnd', 'ImageList_Create', 'int', $nImageWidth, 'int', $nImageHeight, 'int', $nFlags, 'int', $nInitial, 'int', $nGrow) Return $hImageList[0] EndFunc Func ImageList_AddIcon($hIml, $hIcon) $nIndex = DllCall('comctl32.dll', 'int', 'ImageList_AddIcon', 'hwnd', $hIml, 'hwnd', $hIcon) Return $nIndex[0] EndFunc Func ImageList_Destroy($hIml) $bResult = DllCall('comctl32.dll', 'int', 'ImageList_Destroy', 'hwnd', $hIml) Return $bResult[0] EndFunc Func ExtractIconEx($sIconFile, $nIconID, $ptrIconLarge, $ptrIconSmall, $nIcons) $nCount = DllCall('shell32.dll', 'int', 'ExtractIconEx', 'str', $sIconFile, 'int', $nIconID, 'ptr', $ptrIconLarge, 'ptr', $ptrIconSmall, 'int', $nIcons) Return $nCount[0] EndFunc Func DestroyIcon($hIcon) $bResult = DllCall('user32.dll', 'int', 'DestroyIcon', 'hwnd', $hIcon) Return $bResult[0] EndFuncall_stuff.zip Edited August 30, 2007 by Zedna Resources UDF ResourcesEx UDF AutoIt Forum Search Link to comment Share on other sites More sharing options...
Zedna Posted September 20, 2007 Author Share Posted September 20, 2007 no one? Resources UDF ResourcesEx UDF AutoIt Forum Search Link to comment Share on other sites More sharing options...
martin Posted September 22, 2007 Share Posted September 22, 2007 no one?I don't get any icons displayed when I try your script Zedna. (I compiled it.) Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script. Link to comment Share on other sites More sharing options...
Zedna Posted September 22, 2007 Author Share Posted September 22, 2007 (edited) I don't get any icons displayed when I try your script Zedna. (I compiled it.)Sorryreshacker.exe and upx.exe must be in script directory (or in directory mentioned in global PATH - this is my case) at compile timebecause I used relative path in #AutoIt3Wrapper directive (for simplicity). Edited September 23, 2007 by Zedna Resources UDF ResourcesEx UDF AutoIt Forum Search Link to comment Share on other sites More sharing options...
Zedna Posted April 3, 2008 Author Share Posted April 3, 2008 bump. Resources UDF ResourcesEx UDF AutoIt Forum Search Link to comment Share on other sites More sharing options...
aec Posted April 22, 2008 Share Posted April 22, 2008 (edited) It certainly seems that the first call to GuiCtrlSetImage destroys the ListView-Header ImageList. So one solution is not to use GuiCtrlSetImage calls but only ImageList_xxx api calls. Perhaps this is complicated. However there are two more proposals [A] and that I could think of (that do not need the workaround of first post) [A] 1. Initialize autoit ImageList by a using GuiCtrlSetImage with an empty icon 2. Initialize header with ImageList_Create, ImageList_AddIcon, ..., $HDM_SETIMAGELIST msg ; init header imagelist $HD_ITEM = DllStructCreate("int;int;ptr;int;int;int;int;int;int") $LViewImageList = ImageList_Create(16, 16, BitOR($ILC_MASK, $ILC_COLOR32), 2, 0) GUICtrlSetImage($ListView1, @ScriptFullPath, -15) ; empty icon $stIcon = DllStructCreate("int") ExtractIconEx(@ScriptFullPath, 3, 0, DllStructGetPtr($stIcon), 1) ; sort_asc.ico ImageList_AddIcon($LViewImageList, DllStructGetData($stIcon, 1)) ExtractIconEx(@ScriptFullPath, 4, 0, DllStructGetPtr($stIcon), 1) ; sort_desc.ico ImageList_AddIcon($LViewImageList, DllStructGetData($stIcon, 1)) DestroyIcon(DllStructGetData($stIcon, 1)) $stIcon = 0 $Header = GUICtrlSendMsg($ListView1, $LVM_GETHEADER, 0, 0) DllCall("user32.dll", "int", "SendMessage", "hwnd", $Header, "int", $HDM_SETIMAGELIST, "int", 0, "hwnd", $LViewImageList) Edited April 22, 2008 by aec Link to comment Share on other sites More sharing options...
Zedna Posted April 22, 2008 Author Share Posted April 22, 2008 Thanks for response aec. It's not clear to me at first look but I will definitely play with it. Resources UDF ResourcesEx UDF AutoIt Forum Search 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