Jump to content

GUICtrlCreateListViewItem and WM_NOTIFY Bug


Recommended Posts

Same as @Melba, I can only make the GUI freeze by adjusting the column width, so maybe my problem and your problem are not the same, and they seems not the same indeed, since my test did nothing in your case.

Haven't you tried to disable WM_NOTIFY message handler (by comment out the GUIRegisterMsg line)?

Beside that, I don't think mikell's way is a workaround. Its way to avoid anything 'weird' with the script.

99 little bugs in the code

99 little bugs!

Take one down, patch it around

117 little bugs in the code!

Link to comment
Share on other sites

@binhnx 

 

Haven't you tried to disable WM_NOTIFY message handler (by comment out the GUIRegisterMsg line)?

Yes i did and it works but i need my Notify Handler. By the way, while freezin, the notify handler still intercepts messages, but that was already discussed.

I have tried everything but i can't figure out the real problem.

Hypothetical, we say the Ownerdraw flag only works with the UDF, then there is no bug, but then all the exmaples out there with ownerdraw are technically wrong.

So: When i only use GUI Functions (GUICtrlCreateListView and GUICtrlCreateListViewItem) it doesn't work, GUICtrlCreateListView + UDF and only UDF works.

Edited by Trolleule
Link to comment
Share on other sites

  • 8 months later...

Hi all,

I think I isolated the problem. It's not the owndraw, nor the UDF/Build in functions but the WM_NOTIFY consuming too much time to perform the actions required. 

If you replace the customdraw options with a simple Sleep(10) the same error occurs (the best way to make the gui freeze is to press PAGE DOWN and PAGE UP multiple times). This happens to me with 3.3.12.0, 3.3.14.1 and 3.3.15.0. I think that the internal AutoIt Handler runs in a infinite loop. The cpu-load goes to 100% on a single core. But I don't understand why it does not make any changes if I return the RUNDEFMSG or nothing (Only Return without something behind)

Can anybody help or find a work around? I would be very thankful! 

Minimalized example Code:

#include <GUIConstantsEx.au3>
#include <GuiListView.au3>
#include <WindowsConstants.au3>



$hGUI_Main = GUICreate("test", 615, 437, 192, 124)
$hMAIN_ListView_List = _GUICtrlListView_Create($hGUI_Main,"No|Time|Protocol|Message", 8, 8, 586, 414)

For $i = 0 To 100
    _GUICtrlListView_AddItem($hMAIN_ListView_List, "Yarp" & $i)
Next

GUISetState(@SW_SHOW)
GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY");ListView

While GUIGetMsg() <> -3
WEnd


Func WM_NOTIFY($hWnd, $Msg, $wParam, $lParam)
    #forceref $hWnd, $Msg, $wParam

    Sleep(10); Do a lot of stuff!
    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_NOTIFY

 

Greetings,

Spider

Edited by GtaSpider

www.AutoIt.de - Moderator of the German AutoIt Forum

 

Link to comment
Share on other sites

You already have a workaround. If you want to use both WM_NOTIFY and WM_DRAWITEM functions make sure, that all cells in the list view are filled out. Fill out the empty cells with a blank.

As a programmer you know, that empty cells in the list view generates LVN_GETDISPINFO notifications, which will be handled by the WM_NOTIFY function.

The problem here is (I have been playing with the code in post 14), that when the empty cell has to be drawn by the code in WM_DRAWITEM, it generates a LVN_GETDISPINFO notification. This means that the WM_NOTIFY function is executed in the middle of the WM_DRAWITEM function. If you do this sufficiently many times e.g. by changing the width of the columns with the header control, you end up in a situation where you execute more code than there is time for. You are blocking the functions. This should not be done as stated in the help file.

If I replace the code in WM_NOTIFY and WM_DRAWITEM functions with this code,

Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam)
  ConsoleWrite( "WM_NOTIFY" & @CRLF )
  Return $GUI_RUNDEFMSG
EndFunc

Func WM_DRAWITEM($hWnd, $Msg, $wParam, $lParam)
  ConsoleWrite( "WM_DRAWITEM" & @CRLF )
  Return $GUI_RUNDEFMSG
EndFunc

(the text in the list view cells is not drawn, but you still receive all events) I can easily generate 500 ConsoleWrites per second with intense use of the list view (arrow up/down, page up/down, home, end, scroll, header). This means that there is in average less than 2ms for the code in these two functions.

This code also shows that AutoIt is able to handle all the events. It's not true that the internal message handler ends up running in an infinite loop. There is no blocking or freezing. The problems arise if you add too much or lengthy code to the functions. It's your responsibility as a programmer not to do that.


If I replace Sleep(10) in the code in post 25 with a ConsoleWrite, I can easily generate more than 100 events per second with page up/down key presses. Mostly LVN_GETDISPINFO notifications because of the empty cells. With Sleep(10) enabled this will block the WM_NOTIFY function. The problem here is not AutoIt message handler running in an infinite loop. The problem is blocking the WM_NOTIFY function.


The return value from WM_NOTIFY or WM_DRAWITEM functions is used to decide whether the internal AutoIt code for that function if any is executed or not. If for example you have defined some resizing with GUICtrlSetResizing, the internal code will be executed if you return $GUI_RUNDEFMSG from WM_SIZE. If you don't return $GUI_RUNDEFMSG the internal resizing code will not be executed. But it has nothing to do with the Windows events, and it will not stop the Windows events from being generated. The return value can not prevent the blocking.

Link to comment
Share on other sites

How about disabling WM_NOTIFY while WM_DRAWITEM is running? Works fine for me. Had something similar with WM_COMMAND, where a function which I called in WM_COMMAND fired a new WM_COMMAND message, leading to an endless loop. Solved by disabling WM_COMMAND message at the beginning of the function and re-registering it directly before the function returns.

#include <GuiListView.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <ColorConstants.au3>


Global Const $ODT_LISTVIEW = 102
Global Const $ODA_DRAWENTIRE = 0x1
Global Const $ODA_SELECT = 0x2
Global Const $ODA_FOCUS = 0x4
Global Const $ODS_SELECTED = 0x0001

Global $GUI_main = GUICreate("", 300, 300, -1, -1)
Global $idLV = GUICtrlCreateListView("A|B|C", 15, 10, 250, 280, BitOR($LVS_REPORT, $LVS_SHOWSELALWAYS, $LVS_OWNERDRAWFIXED), 0) ; + $LVS_EX_CHECKBOXES + $LVS_SINGLESEL

For $i = 0 To 50
    ; if you comment out these lines, you can easily resize the columns and scroll without a freeze!
    If $i = 5 Then
        GUICtrlCreateListViewItem("|" & "sdfdsfs" & "|" & "", $idLV) ; if empty slot is present, gui gets freezed ; comment these lines out for check
        ContinueLoop
    EndIf
    GUICtrlCreateListViewItem("|" & "sdfdsfs" & "|" & $i, $idLV)
Next

GUIRegisterMsg($WM_DRAWITEM, "WM_DRAWITEM")
GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY") ; if you do not comment out line 20-23 you can comment out this line and it will work too!
GUISetState(@SW_SHOW)


; Loop until the user exits.
While 1
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            ExitLoop
    EndSwitch
WEnd


Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam)
    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_NOTIFY

Func WM_DRAWITEM($hWnd, $Msg, $wParam, $lParam)
    GUIRegisterMsg($WM_NOTIFY,"")
    Local $tagDRAWITEMSTRUCT, $iBrushColor, $cID, $itmID, $itmAction, $itmState, $hItm, $hDC, $bSelected
    $tagDRAWITEMSTRUCT = DllStructCreate( _
            "uint cType;" & _
            "uint cID;" & _
            "uint itmID;" & _
            "uint itmAction;" & _
            "uint itmState;" & _
            "hwnd hItm;" & _
            "handle hDC;" & _
            "long itmRect[4];" & _
            "ulong_ptr itmData" _
            , $lParam)
    If DllStructGetData($tagDRAWITEMSTRUCT, "cType") <> $ODT_LISTVIEW Then
        GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")
        Return $GUI_RUNDEFMSG
    endif
    $cID = DllStructGetData($tagDRAWITEMSTRUCT, "cID")
    $itmID = DllStructGetData($tagDRAWITEMSTRUCT, "itmID")
    $itmAction = DllStructGetData($tagDRAWITEMSTRUCT, "itmAction")
    $itmState = DllStructGetData($tagDRAWITEMSTRUCT, "itmState")
    $hItm = DllStructGetData($tagDRAWITEMSTRUCT, "hItm")
    $hDC = DllStructGetData($tagDRAWITEMSTRUCT, "hDC")
    $bSelected = BitAND($itmState, $ODS_SELECTED)
    Switch $cID ; will look for ControlID, not window handle.
        Case $idLV
            Switch $itmAction
                Case $ODA_DRAWENTIRE
                    ; don't forget, this is BGR, not RGB
                    If $itmState = $bSelected Then ; item is not selected
                        $iBrushColor = 0xEEDDBB
                    Else ; item is selected
                        $iBrushColor = $COLOR_RED
                    EndIf
                    Local $aBrush = _WinAPI_CreateSolidBrush($iBrushColor)
                    Local $aBrushOld = _WinAPI_SelectObject($hDC, $aBrush)
                    Local $iLeft = DllStructGetData($tagDRAWITEMSTRUCT, "itmRect", 1)
                    DllStructSetData($tagDRAWITEMSTRUCT, "itmRect", $iLeft + 1, 1) ; rectangle coordinates for coloring
                    ; +1 is the left margin
                    _WinAPI_FillRect($hDC, DllStructGetPtr($tagDRAWITEMSTRUCT, "itmRect"), $aBrush)
                    _WinAPI_SelectObject($hDC, $aBrushOld)
                    _WinAPI_DeleteObject($aBrush)

                    ; for all columns of the row:
                    $local_alignment = $DT_LEFT
                    For $i = 0 To _GUICtrlListView_GetColumnCount($idLV) - 1
                        ; 1. get subitem text:
                        Local $iSubItmText = _GUICtrlListView_GetItemText($idLV, $itmID, $i)
                        ; If $iSubItmText = "" Then ContinueLoop ;ConsoleWrite("hier")
                        ; 2. get subitem coordinates for drawing its respective text
                        Local $aSubItmRect = _GUICtrlListView_GetSubItemRect($idLV, $itmID, $i)
                        ; the function above accepts not only subitems (one-based index), but also main item (index=0)
                        ; 3. pass the coordinates to a DLL struct
                        Local $iSubItmRect = DllStructCreate("long[4]")
                        DllStructSetData($iSubItmRect, 1, $aSubItmRect[0] + 6, 1) ; +6 is left margin (X)
                        DllStructSetData($iSubItmRect, 1, $aSubItmRect[1] + (-2), 2) ; + (-2) is upper margin (Y)
                        DllStructSetData($iSubItmRect, 1, $aSubItmRect[2], 3)
                        DllStructSetData($iSubItmRect, 1, $aSubItmRect[3], 4)
                        _WinAPI_SetTextColor($hDC, $COLOR_RED)

                        DllCall("user32.dll", "int", "DrawTextW", "hwnd", $hDC, "wstr", $iSubItmText, "int", StringLen($iSubItmText), _
                                "ptr", DllStructGetPtr($iSubItmRect), "int", $local_alignment)
                    Next
                    ;#ce
            EndSwitch
        EndSwitch
    GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")
    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_DRAWITEM

 

Link to comment
Share on other sites

Seems sufficient to disable WM_NOTIFY for _GUICtrlListView_GetItemText() call only.

#include <GuiListView.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <ColorConstants.au3>


Global Const $ODT_LISTVIEW = 102
Global Const $ODA_DRAWENTIRE = 0x1
Global Const $ODA_SELECT = 0x2
Global Const $ODA_FOCUS = 0x4
Global Const $ODS_SELECTED = 0x0001

Global $GUI_main = GUICreate("", 300, 300, -1, -1)
Global $idLV = GUICtrlCreateListView("A|B|C", 15, 10, 250, 280, BitOR($LVS_REPORT, $LVS_SHOWSELALWAYS, $LVS_OWNERDRAWFIXED), 0) ; + $LVS_EX_CHECKBOXES + $LVS_SINGLESEL

For $i = 0 To 50
    ; if you comment out these lines, you can easily resize the columns and scroll without a freeze!
    If $i = 5 Then
        GUICtrlCreateListViewItem("|" & "sdfdsfs" & "|" & "", $idLV) ; if empty slot is present, gui gets freezed ; comment these lines out for check
        ContinueLoop
    EndIf
    GUICtrlCreateListViewItem("|" & "sdfdsfs" & "|" & $i, $idLV)
Next

GUIRegisterMsg($WM_DRAWITEM, "WM_DRAWITEM")
GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY") ; if you do not comment out line 20-23 you can comment out this line and it will work too!
GUISetState(@SW_SHOW)


; Loop until the user exits.
While 1
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            ExitLoop
    EndSwitch
WEnd


Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam)
    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_NOTIFY

Func WM_DRAWITEM($hWnd, $Msg, $wParam, $lParam)
    Local $tagDRAWITEMSTRUCT, $iBrushColor, $cID, $itmID, $itmAction, $itmState, $hItm, $hDC, $bSelected
    $tagDRAWITEMSTRUCT = DllStructCreate( _
            "uint cType;" & _
            "uint cID;" & _
            "uint itmID;" & _
            "uint itmAction;" & _
            "uint itmState;" & _
            "hwnd hItm;" & _
            "handle hDC;" & _
            "long itmRect[4];" & _
            "ulong_ptr itmData" _
            , $lParam)
    If DllStructGetData($tagDRAWITEMSTRUCT, "cType") <> $ODT_LISTVIEW Then Return $GUI_RUNDEFMSG
    $cID = DllStructGetData($tagDRAWITEMSTRUCT, "cID")
    $itmID = DllStructGetData($tagDRAWITEMSTRUCT, "itmID")
    $itmAction = DllStructGetData($tagDRAWITEMSTRUCT, "itmAction")
    $itmState = DllStructGetData($tagDRAWITEMSTRUCT, "itmState")
    $hItm = DllStructGetData($tagDRAWITEMSTRUCT, "hItm")
    $hDC = DllStructGetData($tagDRAWITEMSTRUCT, "hDC")
    $bSelected = BitAND($itmState, $ODS_SELECTED)
    Switch $cID ; will look for ControlID, not window handle.
        Case $idLV
            Switch $itmAction
                Case $ODA_DRAWENTIRE
                    ; don't forget, this is BGR, not RGB
                    If $itmState = $bSelected Then ; item is not selected
                        $iBrushColor = 0xEEDDBB
                    Else ; item is selected
                        $iBrushColor = $COLOR_RED
                    EndIf
                    Local $aBrush = _WinAPI_CreateSolidBrush($iBrushColor)
                    Local $aBrushOld = _WinAPI_SelectObject($hDC, $aBrush)
                    Local $iLeft = DllStructGetData($tagDRAWITEMSTRUCT, "itmRect", 1)
                    DllStructSetData($tagDRAWITEMSTRUCT, "itmRect", $iLeft + 1, 1) ; rectangle coordinates for coloring
                    ; +1 is the left margin
                    _WinAPI_FillRect($hDC, DllStructGetPtr($tagDRAWITEMSTRUCT, "itmRect"), $aBrush)
                    _WinAPI_SelectObject($hDC, $aBrushOld)
                    _WinAPI_DeleteObject($aBrush)

                    ; for all columns of the row:
                    $local_alignment = $DT_LEFT
                    For $i = 0 To _GUICtrlListView_GetColumnCount($idLV) - 1
                        ; 1. get subitem text:

                        GUIRegisterMsg($WM_NOTIFY, "")
                        Local $iSubItmText = _GUICtrlListView_GetItemText($idLV, $itmID, $i)
                        GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")

                        ; If $iSubItmText = "" Then ContinueLoop ;ConsoleWrite("hier")
                        ; 2. get subitem coordinates for drawing its respective text

                        Local $aSubItmRect = _GUICtrlListView_GetSubItemRect($idLV, $itmID, $i)
                        ; the function above accepts not only subitems (one-based index), but also main item (index=0)
                        ; 3. pass the coordinates to a DLL struct
                        Local $iSubItmRect = DllStructCreate("long[4]")
                        DllStructSetData($iSubItmRect, 1, $aSubItmRect[0] + 6, 1) ; +6 is left margin (X)
                        DllStructSetData($iSubItmRect, 1, $aSubItmRect[1] + (-2), 2) ; + (-2) is upper margin (Y)
                        DllStructSetData($iSubItmRect, 1, $aSubItmRect[2], 3)
                        DllStructSetData($iSubItmRect, 1, $aSubItmRect[3], 4)

                        _WinAPI_SetTextColor($hDC, $COLOR_RED)

                        DllCall("user32.dll", "int", "DrawTextW", "hwnd", $hDC, "wstr", $iSubItmText, "int", StringLen($iSubItmText), "ptr", DllStructGetPtr($iSubItmRect), "int", $local_alignment)

                    Next
                    ;#ce

            EndSwitch
    EndSwitch

    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_DRAWITEM

 

Link to comment
Share on other sites

I've been playing with this optimized code. Note that WM_NOTIFY is disabled while the header is dragged to change the width of the columns in the list view. 

#include <GuiListView.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>

Opt( "MustDeclareVars", 1 )

Global Const $ODT_LISTVIEW = 102
Global Const $ODA_DRAWENTIRE = 0x1
Global Const $ODA_SELECT = 0x2
Global Const $ODA_FOCUS = 0x4
Global Const $ODS_SELECTED = 0x0001

Global $hGui = GUICreate( "ListView", 300, 300 ), $aData[100][3]
Global $idLV = GUICtrlCreateListView("A|B|C", 10, 10, 280, 280, BitOR($LVS_REPORT, $LVS_SHOWSELALWAYS, $LVS_OWNERDRAWFIXED)) ; + $LVS_EX_CHECKBOXES + $LVS_SINGLESEL
Global $hHeader = _GUICtrlListView_GetHeader( $idLV )
Global $fEnableWM_NOTIFY = False

For $i = 0 To 99
  If Mod( $i, 2 ) Then
    GUICtrlCreateListViewItem("|" & "sdfdsfs" & "|" & "", $idLV)
    $aData[$i][1] = "sdfdsfs"
  Else
    GUICtrlCreateListViewItem("|" & "sdfdsfs" & "|" & $i, $idLV)
    $aData[$i][1] = "sdfdsfs"
    $aData[$i][2] = $i
  EndIf
Next

GUIRegisterMsg($WM_DRAWITEM, "WM_DRAWITEM")
GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")
GUISetState(@SW_SHOW)

While 1
  Switch GUIGetMsg()
    Case $GUI_EVENT_PRIMARYUP
      If $fEnableWM_NOTIFY Then
        GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")
        $fEnableWM_NOTIFY = False
      EndIf
    Case $GUI_EVENT_CLOSE
      ExitLoop
  EndSwitch
WEnd

Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam)
  Local $tNMHDR = DllStructCreate($tagNMHDR, $ilParam)
  Switch HWnd(DllStructGetData($tNMHDR, "hWndFrom"))
    Case $hHeader
      Switch DllStructGetData($tNMHDR, "Code")
        Case $HDN_BEGINTRACKW
          GUIRegisterMsg($WM_NOTIFY, "")
          $fEnableWM_NOTIFY = True
      EndSwitch
  EndSwitch
  Return $GUI_RUNDEFMSG
EndFunc

Func WM_DRAWITEM($hWnd, $Msg, $wParam, $lParam)
  Local Static $tRect = DllStructCreate($tagRECT)
  Local $tDRAWITEM = DllStructCreate( "uint cType;uint cID;uint itmID;uint itmAction;uint itmState;hwnd hItm;handle hDC;long itmRect[4];ulong_ptr itmData", $lParam )
  If DllStructGetData($tDRAWITEM, "cType") <> $ODT_LISTVIEW Then Return $GUI_RUNDEFMSG

  Switch DllStructGetData($tDRAWITEM, "cID") ; Will look for ControlID, not window handle
    Case $idLV
      Switch DllStructGetData($tDRAWITEM, "itmAction")
        Case $ODA_DRAWENTIRE
          Local $itmID = DllStructGetData($tDRAWITEM, "itmID"), $itmState = DllStructGetData($tDRAWITEM, "itmState"), $hItm = DllStructGetData($tDRAWITEM, "hItm"), $hDC = DllStructGetData($tDRAWITEM, "hDC"), $iBrushColor
          If BitAND($itmState, $ODS_SELECTED) Then ; Don't forget, this is BGR, not RGB
            $iBrushColor = 0xFF0000                ; Blue in BGR
          Else
            $iBrushColor = 0xEEDDBB
          EndIf
          Local $aBrush = _WinAPI_CreateSolidBrush($iBrushColor), $aBrushOld = _WinAPI_SelectObject($hDC, $aBrush)
          ;DllStructSetData($tDRAWITEM, "itmRect", DllStructGetData($tDRAWITEM, "itmRect", 1) + 1, 1) ; Rectangle coordinates for coloring, add +1 is to left margin
          _WinAPI_FillRect($hDC, DllStructGetPtr($tDRAWITEM, "itmRect"), $aBrush)
          _WinAPI_SelectObject($hDC, $aBrushOld)
          _WinAPI_DeleteObject($aBrush)

          ; for all columns of the row:
          ;For $i = 0 To _GUICtrlListView_GetColumnCount($idLV) - 1
          Local $iSubItmText
          For $i = 0 To 2
            ; 1. get subitem text:
            ;$iSubItmText = _GUICtrlListView_GetItemText($idLV, $itmID, $i)
            $iSubItmText = $aData[$itmID][$i] ; 1000 times faster, no LVN_GETDISPINFO notifications

            ; 2. get subitem coordinates for drawing its respective text
            ;Local $aSubItmRect = _GUICtrlListView_GetSubItemRect($idLV, $itmID, $i)
            DllStructSetData($tRect, "Top", $i)
            DllStructSetData($tRect, "Left", $LVIR_BOUNDS)
            GUICtrlSendMsg($idLV, $LVM_GETSUBITEMRECT, $itmID, DllStructGetPtr($tRect))
            ; 3. pass the coordinates to a DLL struct
            DllStructSetData($tRect, 1, DllStructGetData($tRect, 1) + 6) ; +6 is left margin (X)
            DllStructSetData($tRect, 2, DllStructGetData($tRect, 2) -2) ; -2 is upper margin (Y)
            _WinAPI_SetTextColor($hDC, 0xFF0000) ; Blue in BGR

            DllCall("user32.dll", "int", "DrawTextW", "hwnd", $hDC, "wstr", $iSubItmText, "int", StringLen($iSubItmText), "ptr", DllStructGetPtr($tRect), "int", 0)
          Next
      EndSwitch
  EndSwitch
  Return $GUI_RUNDEFMSG
EndFunc

 

Link to comment
Share on other sites

  • Moderators

LarsJ & KaFu,

Nice piece of detective work - and some nice code to work around the problem.

M23

Edited by Melba23
Typo

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png 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 columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...