' ########################################################################################
' Microsoft Windows
' File: AfxCtl.inc
' Contents: Common controls wrapper functions
' Remarks: The files windowsx.bi and commctrl.bi include many macros for the common controls.
' This file contains additional procedures not implemented as macros.
' Compiler: Free Basic 32 & 64 bit
' Copyright (c) 2016 José Roca. Freeware. Use at your own risk.
' THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
' EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
' MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
' ########################################################################################

#pragma once
#include once "windows.bi"
#include once "win/commctrl.bi"
#include once "win/richedit.bi"
#include once "win/uxtheme.bi"
#include once "Afx/windowsxx.bi"
#include once "Afx/AfxWin.inc"

' Button
DECLARE SUB Button_Click (BYVAL hButton AS HWND)
DECLARE FUNCTION Button_GetImage (BYVAL hButton AS HWND) AS HANDLE
#if _WIN32_WINNT = &h0602
DECLARE SUB Button_SetDontClick (BYVAL hButton AS HWND, BYVAL bState AS LONG)
#endif
DECLARE FUNCTION Button_SetBitmap (BYVAL hButton AS HWND, BYVAL hbmp AS HBITMAP) AS HBITMAP
DECLARE FUNCTION Button_SetIcon (BYVAL hButton AS HWND, BYVAL hIcon AS HICON) AS HICON
DECLARE FUNCTION Button_SetImage (BYVAL hButton AS HWND, BYVAL ImageType AS DWORD, BYVAL hImage AS HANDLE) AS HANDLE
DECLARE FUNCTION Button_SetImageListXY (BYVAL hButton AS HWND, BYVAL himl AS HIMAGELIST, BYVAL nLeft AS LONG, BYVAL nTop AS LONG, BYVAL nRight AS LONG, BYVAL nBottom AS LONG, BYVAL uALign AS DWORD = 0) AS BOOLEAN
DECLARE FUNCTION Button_DeleteBitmap (BYVAL hButton AS HWND) AS BOOLEAN
DECLARE FUNCTION Button_DeleteIcon (BYVAL hButton AS HWND) AS BOOLEAN
DECLARE FUNCTION Button_DeleteImage (BYVAL hButton AS HWND, BYVAL ImageType AS DWORD) AS BOOLEAN
' Combobox
DECLARE FUNCTION AfxGetComboBoxText (BYVAL hComboBox AS HWND, BYVAL nIndex AS LONG) AS CWSTR
DECLARE FUNCTION ComboBox_GetComboBoxInfo (BYVAL hComboBox AS HWND, BYVAL pcbi AS COMBOBOXINFO PTR) AS BOOLEAN
DECLARE FUNCTION Combobox_CalcHorizontalExtent (BYVAL hComboBox AS HWND) AS LONG
DECLARE FUNCTION ComboBox_GetEditBoxHandle (BYVAL hComboBox AS HWND) AS HWND
DECLARE FUNCTION ComboBox_GetListBoxHandle (BYVAL hComboBox AS HWND) AS HWND
DECLARE FUNCTION ComboBox_GetDroppedWidth (BYVAL hComboBox AS HWND) AS LONG
DECLARE FUNCTION ComboBox_GetHorizontalExtent (BYVAL hComboBox AS HWND) AS LONG
DECLARE FUNCTION ComboBox_GetLocale (BYVAL hComboBox AS HWND) AS LONG
DECLARE FUNCTION ComboBox_GetTopIndex (BYVAL hComboBox AS HWND) AS LONG
DECLARE FUNCTION ComboBox_InitStorage (BYVAL hComboBox AS HWND, BYVAL items AS LONG, BYVAL cb AS LONG) AS LONG
DECLARE SUB ComboBox_SetHorizontalExtent (BYVAL hComboBox AS HWND, BYVAL nWidth AS LONG)
DECLARE FUNCTION ComboBox_SetLocale (BYVAL hComboBox AS HWND, BYVAL lcid AS LONG) AS LONG
DECLARE FUNCTION ComboBox_SetTopIndex (BYVAL hComboBox AS HWND, BYVAL index AS DWORD) AS LONG
' ComboboxEx
DECLARE FUNCTION ComboBoxEx_DeleteItem (BYVAL hComboboxEx AS HWND, BYVAL nIndex AS DWORD) AS INT_
DECLARE FUNCTION ComboBoxEx_GetComboControl (BYVAL hComboboxEx AS HWND) AS HWND
DECLARE FUNCTION ComboBoxEx_GetEditControl (BYVAL hComboboxEx AS HWND) AS HWND
DECLARE FUNCTION ComboBoxEx_GetExtendedStyle (BYVAL hComboboxEx AS HWND) AS DWORD
DECLARE FUNCTION ComboBoxEx_GetImageList (BYVAL hComboboxEx AS HWND) AS HIMAGELIST
DECLARE FUNCTION ComboBoxEx_GetItem (BYVAL hComboboxEx AS HWND, BYVAL pCBItem AS COMBOBOXEXITEMW PTR) AS BOOLEAN
DECLARE FUNCTION ComboBoxEx_GetUnicodeFormat (BYVAL hComboboxEx AS HWND) AS DWORD
DECLARE FUNCTION ComboBoxEx_HasEditChanged (BYVAL hComboboxEx AS HWND) AS BOOLEAN
DECLARE FUNCTION ComboBoxEx_InsertItem (BYVAL hComboboxEx AS HWND, BYVAL lpCBItem AS COMBOBOXEXITEMW PTR) AS LONG
DECLARE FUNCTION ComboBoxEx_SetExtendedStyle (BYVAL hComboboxEx AS HWND, BYVAL dwMask AS DWORD, BYVAL dwExStyle AS DWORD) AS DWORD
DECLARE FUNCTION ComboBoxEx_SetImageList (BYVAL hComboboxEx AS HWND, BYVAL himl AS HIMAGELIST) AS HIMAGELIST
DECLARE FUNCTION ComboBoxEx_SetItem (BYVAL hComboboxEx AS HWND, BYVAL lpCBItem AS COMBOBOXEXITEMW PTR) AS BOOLEAN
DECLARE FUNCTION ComboBoxEx_SetUnicodeFormat (BYVAL hComboboxEx AS HWND, BYVAL fUnicode AS DWORD) AS DWORD
DECLARE SUB ComboBoxEx_SetWindowTheme (BYVAL hComboboxEx AS HWND, BYVAL pwszStyle AS WSTRING PTR)
' Edit
DECLARE FUNCTION Edit_CharFromPos (BYVAL hEdit AS HWND, BYVAL x AS SHORT, BYVAL y AS SHORT) AS LONG
DECLARE SUB Edit_Clear (BYVAL hEdit AS HWND)
DECLARE SUB Edit_Copy (BYVAL hEdit AS HWND)
DECLARE SUB Edit_Cut (BYVAL hEdit AS HWND)
DECLARE FUNCTION Edit_GetIMEStatus (BYVAL hEdit AS HWND, BYVAL nStatusType AS LONG) AS LONG
DECLARE FUNCTION Edit_GetLimitText (BYVAL hEdit AS HWND) AS LONG
DECLARE FUNCTION Edit_GetMargins (BYVAL hEdit AS HWND) AS DWORD
DECLARE FUNCTION Edit_GetLeftMargin (BYVAL hEdit AS HWND) AS WORD
DECLARE FUNCTION Edit_GetRightMargin (BYVAL hEdit AS HWND) AS WORD
DECLARE FUNCTION Edit_GetSelStart (BYVAL hEdit AS HWND) AS WORD
DECLARE FUNCTION Edit_GetSelEnd (BYVAL hEdit AS HWND) AS WORD
DECLARE FUNCTION Edit_GetThumb (BYVAL hEdit AS HWND) AS LONG
DECLARE FUNCTION Edit_LineScroll (BYVAL hEdit AS HWND, BYVAL x AS LONG, BYVAL y AS LONG) AS BOOLEAN
DECLARE SUB Edit_Paste (BYVAL hEdit AS HWND)
DECLARE FUNCTION Edit_PosFromChar (BYVAL hEdit AS HWND, BYVAL index AS DWORD) AS LONG
DECLARE FUNCTION Edit_SetCueBannerTextFocused (BYVAL hEdit AS HWND, BYVAL pwszText AS WSTRING PTR, BYVAL fDrawFocused AS LONG) AS BOOLEAN
DECLARE FUNCTION Edit_SetIMEStatus (BYVAL hEdit AS HWND, BYVAL nStatusType AS LONG, BYVAL flags AS DWORD) AS DWORD
DECLARE SUB Edit_SetMargins (BYVAL hEdit AS HWND, BYVAL nMargins AS LONG, BYVAL nWidth AS LONG)
DECLARE SUB Edit_SetLeftMargin (BYVAL hEdit AS HWND, BYVAL nWidth AS WORD)
DECLARE SUB Edit_SetRightMargin (BYVAL hEdit AS HWND, BYVAL nWidth AS WORD)
' Header
DECLARE FUNCTION Header_HitTest (BYVAL hwndHD AS HWND, BYVAL phdhti AS HDHITTESTINFO PTR) AS LONG
DECLARE FUNCTION Header_GetItemWidth (BYVAL hwndHD AS HWND, BYVAL nItem AS LONG) AS LONG
DECLARE FUNCTION Header_SetItemWidth (BYVAL hwndHD AS HWND, BYVAL iItem AS LONG, BYVAL nWidth AS LONG) AS BOOLEAN
DECLARE FUNCTION Header_GetItemOrder (BYVAL hwndHD AS HWND, BYVAL nItem AS LONG) AS LONG
DECLARE FUNCTION Header_SetItemOrder (BYVAL hwndHD AS HWND, BYVAL nItem AS LONG, BYVAL iOrder AS LONG) AS LONG
DECLARE FUNCTION Header_GetItemText (BYVAL hwndHD AS HWND, BYVAL nItem AS LONG, BYVAL pszText AS WSTRING PTR, BYVAL cchTextMax AS LONG) AS BOOLEAN
DECLARE FUNCTION Header_SetItemText (BYVAL hwndHD AS HWND, BYVAL nItem AS LONG, BYVAL pwszText AS WSTRING PTR) AS BOOLEAN
' Hot key
DECLARE FUNCTION HotKey_GetHotKey (BYVAL hHotKey AS HWND) AS DWORD
DECLARE SUB HotKey_SetHotKey (BYVAL hHotKey AS HWND, BYVAL vkCode AS SHORT, BYVAL fMods AS SHORT)
DECLARE SUB HotKey_SetRules (BYVAL hHotKey AS HWND, BYVAL fwCombInv AS WORD, BYVAL fwModInv AS WORD)
' Scroll bar
DECLARE FUNCTION ScrollBar_SetRangeRedraw (BYVAL hScrollBar AS HWND, BYVAL posMin AS LONG, BYVAL posMax AS LONG) AS LONG
' SysLink
DECLARE FUNCTION SysLink_GetIdealHeight (BYVAL hLM AS HWND) AS LONG
DECLARE FUNCTION Syslink_GetItem (BYVAL hLM AS HWND, BYVAL lpItem AS LITEM PTR) AS BOOLEAN
DECLARE FUNCTION SysLink_HitTest (BYVAL hLM AS HWND, BYVAL lphti AS LHITTESTINFO PTR) AS BOOLEAN
DECLARE FUNCTION SysLink_SetItem (BYVAL hLM AS HWND, BYVAL lpItem AS LITEM PTR) AS BOOLEAN
' Listbox
DECLARE FUNCTION AfxGetListBoxText (BYVAL hListBox AS HWND, BYVAL nIndex AS LONG) AS CWSTR
DECLARE FUNCTION ListBox_AddFile (BYVAL hListBox AS HWND, BYVAL pwszFileName AS WSTRING PTR) AS LONG
DECLARE FUNCTION ListBox_GetAnchorIndex (BYVAL hListBox AS HWND) AS LONG
DECLARE FUNCTION Listbox_GetListboxInfo (BYVAL hListBox AS HWND) AS LONG
DECLARE FUNCTION ListBox_GetLocale (BYVAL hListBox AS HWND) AS LONG
DECLARE FUNCTION Listbox_InitStorage (BYVAL hListBox AS HWND, BYVAL nItems AS DWORD, BYVAL nBytes AS DWORD) AS LONG
DECLARE FUNCTION Listbox_ItemFromPoint (BYVAL hListBox AS HWND, BYVAL x AS SHORT, BYVAL y AS SHORT) AS LONG
DECLARE FUNCTION Listbox_SelItemRangeEx (BYVAL hListBox AS HWND, BYVAL startIndex AS LONG, BYVAL endIndex AS LONG) AS LONG
DECLARE FUNCTION ListBox_SetAnchorIndex (BYVAL hListBox AS HWND, BYVAL index AS LONG) AS LONG
DECLARE FUNCTION ListBox_SetLocale (BYVAL hListBox AS HWND, BYVAL wLocaleID AS DWORD) AS LONG
DECLARE FUNCTION ListBox_ReplaceString (BYVAL hListBox AS HWND, BYVAL index AS LONG, BYVAL pwszNewText AS WSTRING PTR, BYVAL pNewData AS LONG_PTR = 0) AS LONG
' Listview
DECLARE FUNCTION ListView_FindString (BYVAL hwndLV AS HWND, BYVAL pwszText AS WSTRING PTR) AS LONG
DECLARE FUNCTION ListView_GetFocusedItem (BYVAL hwndLV AS HWND) AS LONG
DECLARE FUNCTION ListView_HitTestEx (BYVAL hwndLV AS HWND, BYVAL pinfo AS LVHITTESTINFO PTR) AS LONG
DECLARE FUNCTION ListView_GetISearchStringLen (BYVAL hwndLV AS HWND) AS LONG
DECLARE FUNCTION ListView_GetSelection (BYVAL hwndLV AS HWND) AS LONG
DECLARE SUB ListView_SelectItem (BYVAL hwndLV AS HWND, BYVAL nIndex AS LONG)
DECLARE SUB ListView_SelectAllItems (BYVAL hwndLV AS HWND)
DECLARE SUB ListView_UnselectItem (BYVAL hwndLV AS HWND, BYVAL nIndex AS LONG)
DECLARE SUB ListView_UnselectAllItems (BYVAL hwndLV AS HWND)
DECLARE SUB ListView_MakeHeaderFlat (BYVAL hwndLV AS HWND)
DECLARE FUNCTION ListView_FitContent (BYVAL hwndLV AS HWND, BYVAL nCol AS LONG) AS BOOLEAN
DECLARE FUNCTION ListView_AutoSizeColumns (BYVAL hwndLV AS HWND) AS BOOLEAN
DECLARE FUNCTION ListView_FitHeader (BYVAL hwndLV AS HWND, BYVAL nCol AS LONG) AS BOOLEAN
DECLARE FUNCTION ListView_AutoSizeHeader (BYVAL hwndLV AS HWND) AS BOOLEAN
DECLARE FUNCTION ListView_GetColumnCount (BYVAL hwndLV AS HWND) AS LONG
DECLARE FUNCTION ListView_GetColumnOrder (BYVAL hwndLV AS HWND, BYVAL nCol AS LONG) AS LONG
DECLARE FUNCTION ListView_GetOrderArray (BYVAL hwndLV AS HWND, BYVAL nSize AS DWORD, BYVAL lpiArray AS LONG PTR) AS LONG
DECLARE FUNCTION ListView_GetTooltipsFont (BYVAL hwndLV AS HWND) AS HFONT
DECLARE SUB ListView_SetTooltipsFont (BYVAL hwndLV AS HWND, BYVAL hFont AS HFONT = NULL, BYVAL fRedraw AS BOOLEAN = FALSE)
DECLARE FUNCTION ListView_GetColumnText (BYVAL hwndLV AS HWND, BYVAL nCol AS LONG, BYVAL pwszText AS WSTRING PTR, BYVAL cchTextMax AS LONG) AS BOOLEAN
DECLARE FUNCTION ListView_GetHeaderText (BYVAL hwndLV AS HWND, BYVAL nCol AS LONG, BYVAL pwszText AS WSTRING PTR, BYVAL cchTextMax AS LONG) AS LONG
DECLARE FUNCTION ListView_AddColumn (BYVAL hwndLV AS HWND, BYVAL nCol AS LONG, BYVAL pwszText AS WSTRING PTR, BYVAL nWidth AS LONG, BYVAL nFormat AS LONG = 0) AS LONG
DECLARE FUNCTION ListView_AddItem (BYVAL hwndLV AS HWND, BYVAL nItem AS LONG, BYVAL nImage AS LONG, BYVAL pwszText AS WSTRING PTR) AS LONG
DECLARE FUNCTION ListView_AppendItem (BYVAL hwndLV AS HWND, BYVAL nImage AS LONG, BYVAL pwszText AS WSTRING PTR) AS LONG
' Rebar
DECLARE SUB Rebar_BeginDrag (BYVAL hRebar AS HWND, BYVAL uBand AS DWORD, BYVAL dwPos AS DWORD)
DECLARE FUNCTION Rebar_DeleteBand (BYVAL hRebar AS HWND, BYVAL uBand AS DWORD) AS BOOLEAN
DECLARE SUB Rebar_DragMove (BYVAL hRebar AS HWND, BYVAL dwPos AS DWORD)
DECLARE SUB Rebar_EndDrag (BYVAL hRebar AS HWND)
DECLARE SUB Rebar_GetBandBorders (BYVAL hRebar AS HWND, BYVAL uBand AS DWORD, BYVAL lprc AS RECT PTR)
DECLARE FUNCTION Rebar_GetBandCount (BYVAL hRebar AS HWND) AS DWORD
DECLARE FUNCTION Rebar_GetBandInfo (BYVAL hRebar AS HWND, BYVAL uBand AS DWORD, BYVAL lprbbi AS REBARBANDINFOW PTR) AS BOOLEAN
DECLARE SUB Rebar_GetBandMargins (BYVAL hRebar AS HWND, BYVAL pMargins AS MARGINS PTR)
DECLARE FUNCTION Rebar_GetBarHeight (BYVAL hRebar AS HWND) AS DWORD
DECLARE FUNCTION Rebar_GetBarInfo (BYVAL hRebar AS HWND, BYVAL lprbi AS REBARINFO PTR) AS BOOLEAN
DECLARE FUNCTION Rebar_GetBkColor (BYVAL hRebar AS HWND) AS COLORREF
DECLARE FUNCTION Rebar_GetColorScheme (BYVAL hRebar AS HWND, BYVAL lpcs AS COLORSCHEME PTR) AS BOOLEAN
DECLARE FUNCTION Rebar_GetDropTarget (BYVAL hRebar AS HWND) AS IDropTarget PTR
DECLARE FUNCTION Rebar_GetExtendedStyle (BYVAL hRebar AS HWND) AS DWORD
DECLARE FUNCTION Rebar_GetPalette (BYVAL hRebar AS HWND) AS DWORD
DECLARE FUNCTION Rebar_GetRect (BYVAL hRebar AS HWND, BYVAL uBand AS DWORD, BYVAL lprc AS RECT PTR) AS BOOLEAN
DECLARE FUNCTION Rebar_GetRowCount (BYVAL hRebar AS HWND) AS DWORD
DECLARE FUNCTION Rebar_GetRowHeight (BYVAL hRebar AS HWND, BYVAL uRow AS DWORD) AS DWORD
DECLARE FUNCTION Rebar_GetTextColor (BYVAL hRebar AS HWND) AS COLORREF
DECLARE FUNCTION Rebar_GetTooltips (BYVAL hRebar AS HWND) AS HWND
DECLARE FUNCTION Rebar_GetUnicodeFormat (BYVAL hRebar AS HWND) AS LONG
DECLARE FUNCTION Rebar_HitTest (BYVAL hRebar AS HWND, BYVAL lprhbt AS RBHITTESTINFO PTR) AS LONG
DECLARE FUNCTION Rebar_IdToIndex (BYVAL hRebar AS HWND, BYVAL uBandID AS DWORD) AS LONG
DECLARE FUNCTION Rebar_InsertBand (BYVAL hRebar AS HWND, BYVAL nIndex AS LONG, BYVAL lprbbi AS REBARBANDINFOW PTR) AS BOOLEAN
DECLARE SUB Rebar_MaximizeBand (BYVAL hRebar AS HWND, BYVAL uBand AS DWORD, BYVAL fIdeal AS DWORD)
DECLARE SUB Rebar_MinimizeBand (BYVAL hRebar AS HWND, BYVAL uBand AS DWORD)
DECLARE FUNCTION Rebar_MoveBand (BYVAL hRebar AS HWND, BYVAL nFrom AS DWORD, BYVAL nTo AS DWORD) AS BOOLEAN
DECLARE SUB Rebar_PushChevron (BYVAL hRebar AS HWND, BYVAL uBand AS DWORD, BYVAL iAppValue AS DWORD)
DECLARE FUNCTION Rebar_SetBandInfo (BYVAL hRebar AS HWND, BYVAL uBand AS DWORD, BYVAL lprbbi AS REBARBANDINFOW PTR) AS BOOLEAN
#if _WIN32_WINNT = &h0602
DECLARE FUNCTION Rebar_SetBandWidth (BYVAL hRebar AS HWND, BYVAL uBand AS DWORD, BYVAL nWidth AS DWORD) AS BOOLEAN
#endif
DECLARE FUNCTION Rebar_SetBarInfo (BYVAL hRebar AS HWND, BYVAL lprbi AS REBARINFO PTR) AS BOOLEAN
DECLARE FUNCTION Rebar_SetBkColor (BYVAL hRebar AS HWND, BYVAL clrBk AS COLORREF) AS COLORREF
DECLARE SUB Rebar_SetColorScheme (BYVAL hRebar AS HWND, BYVAL lpcs AS COLORSCHEME PTR)
DECLARE FUNCTION Rebar_SetPalette (BYVAL hRebar AS HWND, BYVAL hpal AS HPALETTE) AS HPALETTE
DECLARE FUNCTION Rebar_SetParent (BYVAL hRebar AS HWND, BYVAL hwndParent AS hWND) AS HWND
DECLARE FUNCTION Rebar_SetTextColor (BYVAL hRebar AS HWND, BYVAL clrText AS COLORREF) AS COLORREF
DECLARE SUB Rebar_SetTooltips (BYVAL hRebar AS HWND, BYVAL hwndToolTip AS HWND)
DECLARE FUNCTION Rebar_SetUnicodeFormat (BYVAL hRebar AS HWND, BYVAL fUnicode AS DWORD) AS DWORD
DECLARE SUB Rebar_SetWindowTheme (BYVAL hRebar AS HWND, BYVAL pwszTheme AS WSTRING PTR)
DECLARE FUNCTION Rebar_ShowBand (BYVAL hRebar AS HWND, BYVAL uBand AS DWORD, BYVAL fShow AS DWORD) AS BOOLEAN
DECLARE FUNCTION Rebar_SizeToRect (BYVAL hRebar AS HWND, BYVAL prc AS RECT PTR) AS BOOLEAN
' Static
DECLARE FUNCTION Static_SetImage (BYVAL hStatic AS HWND, BYVAL nType AS LONG, BYVAL hImage AS HANDLE) AS HANDLE
DECLARE FUNCTION Static_DeleteImage (BYVAL hStatic AS HWND, BYVAL nType AS LONG) AS BOOLEAN
DECLARE FUNCTION Static_GetImage (BYVAL hStatic AS HWND, BYVAL nType AS LONG) AS HANDLE
DECLARE FUNCTION Static_SetBitmap (BYVAL hStatic AS HWND, BYVAL hBitmap AS HBITMAP) AS HBITMAP
DECLARE FUNCTION Static_DeleteIcon (BYVAL hStatic AS HWND) AS BOOLEAN
DECLARE FUNCTION Static_DeleteBitmap (BYVAL hStatic AS HWND) AS BOOLEAN
DECLARE FUNCTION Static_SetCursor (BYVAL hStatic AS HWND, BYVAL hCursor AS HCURSOR) AS HCURSOR
DECLARE FUNCTION Static_DeleteCursor (BYVAL hStatic AS HWND) AS BOOLEAN
DECLARE FUNCTION Static_SetEnhancedMetafile (BYVAL hStatic AS HWND, BYVAL hEnhMetafile AS HENHMETAFILE) AS HENHMETAFILE
DECLARE FUNCTION Static_DeleteEnhancedMetafile (BYVAL hStatic AS HWND) AS BOOLEAN
' Toolbar
DECLARE FUNCTION Toolbar_AddBitmap (BYVAL hToolBar AS HWND, BYVAL nButtons AS DWORD, BYVAL tabm AS TBADDBITMAP PTR) AS LONG
DECLARE FUNCTION Toolbar_AddButtons (BYVAL hToolBar AS HWND, BYVAL nButtons AS DWORD, BYVAL lpButtons AS TBBUTTON PTR) AS BOOLEAN
DECLARE FUNCTION Toolbar_AddButton (BYVAL hToolBar AS HWND, BYVAL idxBitmap AS LONG, BYVAL idCommand AS LONG, _
                 BYVAL fsState AS UBYTE = 0, BYVAL fsStyle AS UBYTE = 0, BYVAL dwData AS DWORD_PTR = 0, BYVAL pwszText AS WSTRING PTR = NULL) AS BOOLEAN
DECLARE FUNCTION Toolbar_AddSeparator (BYVAL hToolBar AS HWND, BYVAL nWidth AS LONG = 0) AS BOOLEAN
DECLARE FUNCTION Toolbar_InsertButton OVERLOAD (BYVAL hToolBar AS HWND, BYVAL idxButton AS LONG, BYVAL lpButton AS TBBUTTON PTR) AS BOOLEAN
DECLARE FUNCTION Toolbar_InsertButton OVERLOAD (BYVAL hToolBar AS HWND, BYVAL idxButton AS LONG, BYVAL idxBitmap AS LONG, BYVAL idCommand AS LONG, _
                 BYVAL fsState AS UBYTE = 0, BYVAL fsStyle AS UBYTE = 0, BYVAL dwData AS DWORD_PTR = 0, BYVAL pwszText AS WSTRING PTR = NULL) AS BOOLEAN
DECLARE FUNCTION Toolbar_InsertSeparator (BYVAL hToolBar AS HWND, BYVAL idxButton AS LONG, BYVAL nWidth AS LONG = 0) AS BOOLEAN
DECLARE FUNCTION Toolbar_AddString (BYVAL hToolBar AS HWND, BYVAL hInst AS HINSTANCE, BYVAL idString AS INT_PTR) AS LONG
DECLARE SUB Toolbar_AutoSize (BYVAL hToolBar AS HWND)
DECLARE FUNCTION Toolbar_ButtonCount (BYVAL hToolBar AS HWND) AS DWORD
DECLARE SUB Toolbar_ButtonStructSize (BYVAL hToolBar AS HWND, BYVAL cb AS LONG)
DECLARE FUNCTION Toolbar_CheckButton (BYVAL hToolBar AS HWND, BYVAL idButton AS LONG, BYVAL fCheck AS SHORT) AS BOOLEAN
DECLARE FUNCTION Toolbar_CommandToIndex (BYVAL hToolBar AS HWND, BYVAL idButton AS LONG) AS LONG
DECLARE SUB Toolbar_Customize (BYVAL hToolBar AS HWND)
DECLARE FUNCTION Toolbar_DeleteButton (BYVAL hToolBar AS HWND, BYVAL nButton AS LONG) AS BOOLEAN
DECLARE FUNCTION Toolbar_EnableButton (BYVAL hToolBar AS HWND, BYVAL idButton AS LONG) AS BOOLEAN
DECLARE FUNCTION Toolbar_DisableButton (BYVAL hToolBar AS HWND, BYVAL idButton AS LONG) AS BOOLEAN
DECLARE FUNCTION Toolbar_GetAnchorHighlight (BYVAL hToolBar AS HWND) AS BOOLEAN
DECLARE FUNCTION Toolbar_GetBitmap (BYVAL hToolBar AS HWND, BYVAL idButton AS LONG) AS LONG
DECLARE FUNCTION Toolbar_GetBitmapFlags (BYVAL hToolBar AS HWND) AS DWORD
DECLARE FUNCTION Toolbar_GetButton (BYVAL hToolBar AS HWND, BYVAL nButton AS LONG, BYVAL ptbb AS TBBUTTON PTR) AS BOOLEAN
DECLARE FUNCTION Toolbar_GetButtonHeight (BYVAL hToolBar AS HWND) AS DWORD
DECLARE FUNCTION Toolbar_GetButtonWidth (BYVAL hToolBar AS HWND) AS DWORD
DECLARE FUNCTION Toolbar_GetButtonSize (BYVAL hToolBar AS HWND) AS DWORD
DECLARE FUNCTION Toolbar_GetButtonInfo (BYVAL hToolBar AS HWND, BYVAL iID AS LONG, BYVAL lptbbi AS TBBUTTONINFOW PTR) AS LONG
DECLARE FUNCTION Toolbar_GetColorScheme (BYVAL hToolBar AS HWND, BYVAL lpcs AS COLORSCHEME PTR) AS BOOLEAN
DECLARE FUNCTION Toolbar_GetImageList (BYVAL hToolBar AS HWND) AS HIMAGELIST
DECLARE FUNCTION Toolbar_GetDisabledImageList (BYVAL hToolBar AS HWND) AS HIMAGELIST
DECLARE FUNCTION Toolbar_GetHotImageList (BYVAL hToolBar AS HWND) AS HIMAGELIST
DECLARE FUNCTION Toolbar_GetExtendedStyle (BYVAL hToolBar AS HWND) AS DWORD
DECLARE FUNCTION Toolbar_GetHotItem (BYVAL hToolBar AS HWND) AS DWORD
DECLARE FUNCTION Toolbar_GetInsertMark (BYVAL hToolBar AS HWND, BYVAL ptbim AS TBINSERTMARK PTR) AS LONG
DECLARE FUNCTION Toolbar_GetInsertMarkColor (BYVAL hToolBar AS HWND) AS COLORREF
DECLARE FUNCTION Toolbar_GetItemRect (BYVAL hToolBar AS HWND, BYVAL nButton AS LONG, BYVAL lprc AS RECT PTR) AS BOOLEAN
DECLARE FUNCTION Toolbar_GetMaxSize (BYVAL hToolBar AS HWND, BYVAL psize AS SIZE PTR) AS BOOLEAN
DECLARE SUB Toolbar_GetMetrics (BYVAL hToolBar AS HWND, BYVAL ptbMetrics AS TBMETRICS PTR)
DECLARE FUNCTION Toolbar_GetPadding (BYVAL hToolBar AS HWND) AS DWORD
DECLARE FUNCTION Toolbar_GetHorizontalPadding (BYVAL hToolBar AS HWND) AS DWORD
DECLARE FUNCTION Toolbar_GetVerticalPadding (BYVAL hToolBar AS HWND) AS DWORD
DECLARE FUNCTION Toolbar_GetRect (BYVAL hToolBar AS HWND, BYVAL iID AS LONG, BYVAL lprc AS RECT PTR) AS BOOLEAN
DECLARE FUNCTION Toolbar_GetRows (BYVAL hToolBar AS HWND) AS DWORD
DECLARE FUNCTION Toolbar_GetState (BYVAL hToolBar AS HWND, BYVAL idButton AS LONG) AS DWORD
DECLARE FUNCTION Toolbar_GetString (BYVAL hToolBar AS HWND, BYVAL iString AS SHORT, BYVAL pBuffer AS WSTRING PTR, BYVAL cchMax AS SHORT) AS LONG
DECLARE FUNCTION Toolbar_GetStyle (BYVAL hToolBar AS HWND) AS DWORD
DECLARE FUNCTION Toolbar_GetTextRows (BYVAL hToolBar AS HWND) AS DWORD
DECLARE FUNCTION Toolbar_GetTooltips (BYVAL hToolBar AS HWND) AS HWND
DECLARE FUNCTION Toolbar_GetUnicodeFormat (BYVAL hToolBar AS HWND) AS DWORD
DECLARE FUNCTION Toolbar_HideButton (BYVAL hToolBar AS HWND, BYVAL idButton AS LONG, BYVAL fShow AS SHORT) AS BOOLEAN
DECLARE FUNCTION Toolbar_HitTest (BYVAL hToolBar AS HWND, BYVAL pptHitTest AS POINT PTR) AS LONG
DECLARE FUNCTION Toolbar_Indeterminate (BYVAL hToolBar AS HWND, BYVAL idButton AS LONG, BYVAL fIndeterminate AS SHORT) AS BOOLEAN
DECLARE FUNCTION Toolbar_InsertMarkHitTest (BYVAL hToolBar AS HWND, BYVAL lppt AS POINT PTR, BYVAL lptbim AS TBINSERTMARK PTR) AS BOOLEAN
DECLARE FUNCTION Toolbar_IsButtonChecked (BYVAL hToolBar AS HWND, BYVAL idButton AS LONG) AS BOOLEAN
DECLARE FUNCTION Toolbar_IsButtonEnabled (BYVAL hToolBar AS HWND, BYVAL idButton AS LONG) AS BOOLEAN
DECLARE FUNCTION Toolbar_IsButtonHidden (BYVAL hToolBar AS HWND, BYVAL idButton AS LONG) AS BOOLEAN
DECLARE FUNCTION Toolbar_IsButtonHighlighted (BYVAL hToolBar AS HWND, BYVAL idButton AS LONG) AS BOOLEAN
DECLARE FUNCTION Toolbar_IsButtonIndeterminate (BYVAL hToolBar AS HWND, BYVAL idButton AS LONG) AS BOOLEAN
DECLARE FUNCTION Toolbar_IsButtonPressed (BYVAL hToolBar AS HWND, BYVAL idButton AS LONG) AS BOOLEAN
DECLARE FUNCTION Toolbar_LoadImages (BYVAL hToolBar AS HWND, BYVAL iBitmapID AS DWORD, BYVAL hinst AS HINSTANCE) AS LONG
DECLARE FUNCTION Toolbar_MapAccelerator (BYVAL hToolBar AS HWND, BYVAL chAccel AS DWORD, BYVAL pIDBtn AS DWORD PTR) AS BOOLEAN
DECLARE FUNCTION Toolbar_MarkButton (BYVAL hToolBar AS HWND, BYVAL idButton AS LONG, BYVAL fHighlight AS SHORT) AS BOOLEAN
DECLARE FUNCTION Toolbar_MoveButton (BYVAL hToolBar AS HWND, BYVAL uOldPos AS DWORD, BYVAL uNewPos AS DWORD) AS BOOLEAN
DECLARE FUNCTION Toolbar_PressButton (BYVAL hToolBar AS HWND, BYVAL idButton AS LONG, BYVAL fPress AS SHORT) AS BOOLEAN
DECLARE FUNCTION Toolbar_ReplaceBitmap (BYVAL hToolBar AS HWND, BYVAL ptbrb AS TBREPLACEBITMAP PTR) AS BOOLEAN
DECLARE SUB Toolbar_SaveRestore (BYVAL hToolBar AS HWND, BYVAL fSave AS LONG, BYVAL ptbsp AS TBSAVEPARAMSW PTR)
DECLARE FUNCTION Toolbar_SetAnchorHighlight (BYVAL hToolBar AS HWND, BYVAL fAnchor AS BOOLEAN) AS BOOLEAN
DECLARE FUNCTION Toolbar_SetBitmapSize (BYVAL hToolBar AS HWND, BYVAL dxBitmap AS SHORT, BYVAL dyBitmap AS SHORT) AS BOOLEAN
DECLARE FUNCTION Toolbar_SetButtonInfo (BYVAL hToolBar AS HWND, BYVAL iID AS LONG, BYVAL lptbbi AS TBBUTTONINFOW PTR) AS BOOLEAN
DECLARE FUNCTION Toolbar_SetButtonSize (BYVAL hToolBar AS HWND, BYVAL dxButton AS SHORT, BYVAL dyButton AS SHORT) AS BOOLEAN
DECLARE FUNCTION Toolbar_SetButtonWidth (BYVAL hToolBar AS HWND, BYVAL cxMin AS SHORT, BYVAL cxMax AS SHORT) AS BOOLEAN
DECLARE FUNCTION Toolbar_SetCmdId (BYVAL hToolBar AS HWND, BYVAL index AS SHORT, BYVAL cmdid AS SHORT) AS BOOLEAN
DECLARE SUB Toolbar_SetColorScheme (BYVAL hToolBar AS HWND, BYVAL lpcs AS COLORSCHEME PTR)
DECLARE FUNCTION Toolbar_SetImageList (BYVAL hToolBar AS HWND, BYVAL himlNew AS HIMAGELIST) AS HIMAGELIST
DECLARE FUNCTION Toolbar_SetHotImageList (BYVAL hToolBar AS HWND, BYVAL himlNewHot AS HIMAGELIST) AS HIMAGELIST
DECLARE FUNCTION Toolbar_SetDisabledImageList (BYVAL hToolBar AS HWND, BYVAL himlNewDisabled AS HIMAGELIST) AS HIMAGELIST
DECLARE FUNCTION Toolbar_SetDrawTextFlags (BYVAL hToolBar AS HWND, BYVAL dwMask AS DWORD, BYVAL dwDTFlags AS DWORD) AS DWORD
DECLARE FUNCTION Toolbar_SetExtendedStyle (BYVAL hToolBar AS HWND, BYVAL dwExStyle AS DWORD) AS DWORD
DECLARE FUNCTION Toolbar_SetHotItem (BYVAL hToolBar AS HWND, BYVAL iHot AS LONG) AS LONG
DECLARE FUNCTION Toolbar_SetIndent (BYVAL hToolBar AS HWND, BYVAL iIndent AS LONG) AS BOOLEAN
DECLARE SUB Toolbar_SetInsertMark (BYVAL hToolBar AS HWND, BYVAL lptbim AS TBINSERTMARK PTR)
DECLARE FUNCTION Toolbar_SetInsertMarkColor (BYVAL hToolBar AS HWND, BYVAL clrInsertMark AS COLORREF) AS COLORREF
DECLARE SUB Toolbar_SetListGap (BYVAL hToolBar AS HWND, BYVAL gap AS DWORD)
DECLARE FUNCTION Toolbar_SetMaxTextRows (BYVAL hToolBar AS HWND, BYVAL iMaxRows AS LONG) AS BOOLEAN
DECLARE SUB Toolbar_SetMetrics (BYVAL hToolBar AS HWND, BYVAL ptbMetrics AS TBMETRICS PTR)
DECLARE FUNCTION Toolbar_SetPadding (BYVAL hToolBar AS HWND, BYVAL cx AS SHORT, BYVAL cy AS SHORT) AS DWORD
DECLARE FUNCTION Toolbar_SetParent (BYVAL hToolBar AS HWND, BYVAL hwndParent AS HWND) AS HWND
DECLARE FUNCTION Toolbar_SetPressedImageList (BYVAL hToolBar AS HWND, BYVAL iImageID AS DWORD, BYVAL himlNew AS HIMAGELIST) AS HIMAGELIST
DECLARE SUB Toolbar_SetRows (BYVAL hToolBar AS HWND, BYVAL cRows AS WORD, BYVAL fLarger AS BOOLEAN, BYVAL lprc AS RECT PTR)
DECLARE FUNCTION Toolbar_SetState (BYVAL hToolBar AS HWND, BYVAL idButton AS LONG, BYVAL fState AS SHORT) AS BOOLEAN
DECLARE SUB Toolbar_SetStyle (BYVAL hToolBar AS HWND, BYVAL dwStyle AS DWORD)
DECLARE SUB Toolbar_SetToolTips (BYVAL hToolBar AS HWND, BYVAL hwndToolTip AS HWND)
DECLARE FUNCTION Toolbar_SetUnicodeFormat (BYVAL hToolBar AS HWND, BYVAL fUnicode AS DWORD) AS DWORD
DECLARE SUB Toolbar_SetWindowTheme (BYVAL hToolBar AS HWND, BYVAL pwszTheme AS WSTRING PTR)
DECLARE SUB Toolbar_MakeOpaque (BYVAL hToolBar AS HWND)
DECLARE FUNCTION Toolbar_GetObject (BYVAL hToolBar AS HWND) AS IDropTarget PTR
DECLARE FUNCTION Toolbar_GetButtonText (BYVAL hToolBar AS HWND, BYVAL idButton AS LONG, BYVAL pBuffer AS WSTRING PTR) AS LONG
DECLARE FUNCTION Toolbar_GetButtonTextLength (BYVAL hToolBar AS HWND, BYVAL idButton AS LONG) AS LONG
' Tooltips
DECLARE FUNCTION AfxAddTooltip (BYVAL hwndCtrl AS HWND, BYREF wszText AS CONST WSTRING = "", BYVAL bBalloon AS BOOLEAN = FALSE, BYVAL bCentered AS BOOLEAN = FALSE) AS HWND
DECLARE SUB AfxSetTooltipText (BYVAL hTooltip AS HWND, BYVAL hwndCtrl AS HWND, BYREF wszText AS CONST WSTRING)
DECLARE SUB AfxDeleteTooltip (BYVAL hTooltip AS HWND, BYVAL hwndCtrl AS HWND)
' Treeview
DECLARE FUNCTION TreeView_GetItemEx (BYVAL hwndTV AS HWND, BYVAL pitem AS TVITEMEXW PTR) AS BOOLEAN
DECLARE FUNCTION TreeView_AddItem (BYVAL hwndTV AS HWND, BYVAL hParent AS HTREEITEM, BYVAL hInsertAfter AS HTREEITEM, _
   BYVAL pwszText AS WSTRING PTR, BYVAL lParam AS LPARAM = 0, BYVAL iImage AS LONG = 0, BYVAL iSelectedImage AS LONG = 0) AS HTREEITEM
DECLARE FUNCTION TreeView_AppendItem (BYVAL hwndTV AS HWND, BYVAL hParent AS HTREEITEM, _
   BYVAL pwszText AS WSTRING PTR, BYVAL lParam AS LPARAM = 0, BYVAL iImage AS LONG = 0, BYVAL iSelectedImage AS LONG = 0) AS HTREEITEM
DECLARE FUNCTION TreeView_InsertFirstItem (BYVAL hwndTV AS HWND, BYVAL hParent AS HTREEITEM, _
   BYVAL pwszText AS WSTRING PTR, BYVAL lParam AS LPARAM = 0, BYVAL iImage AS LONG = 0, BYVAL iSelectedImage AS LONG = 0) AS HTREEITEM
DECLARE FUNCTION TreeView_AddRootItem (BYVAL hwndTV AS HWND, BYVAL pwszText AS WSTRING PTR, _
   BYVAL lParam AS LPARAM = 0, BYVAL iImage AS LONG = 0, BYVAL iSelectedImage AS LONG = 0) AS HTREEITEM
DECLARE FUNCTION TreeView_InsertSortedItem (BYVAL hwndTV AS HWND, BYVAL hParent AS HTREEITEM, _
   BYVAL pwszText AS WSTRING PTR, BYVAL lParam AS LPARAM = 0, BYVAL iImage AS LONG = 0, BYVAL iSelectedImage AS LONG = 0) AS HTREEITEM
DECLARE FUNCTION TreeView_GetBold (BYVAL hwndTV AS HWND, BYVAL hItem AS HTREEITEM) AS BOOLEAN
DECLARE FUNCTION TreeView_IsItemChecked (BYVAL hwndTV AS HWND, BYVAL hItem AS HTREEITEM) AS BOOLEAN
DECLARE FUNCTION TreeView_GetISearchStringLen (BYVAL hwndTV AS HWND) AS LONG
DECLARE FUNCTION TreeView_GetlParam (BYVAL hwndTV AS HWND, BYVAL hItem AS HTREEITEM) AS LPARAM
DECLARE SUB TreeView_SetBold (BYVAL hwndTV AS HWND, BYVAL hItem AS HTREEITEM, BYVAL fBold AS BOOLEAN)
DECLARE FUNCTION TreeView_SetItemEx (BYVAL hwndTV AS HWND, BYVAL pitem AS TVITEMEXW PTR) AS BOOLEAN
DECLARE FUNCTION TreeView_SetItemText (BYVAL hwndTV AS HWND, BYVAL hItem AS HTREEITEM, BYVAL pwszText AS WSTRING PTR) AS BOOLEAN
DECLARE SUB TreeView_ExpandChildItems (BYVAL hwndTV AS HWND, BYVAL hNode AS HTREEITEM)
DECLARE SUB TreeView_ExpandSiblings (BYVAL hwndTV AS HWND, BYVAL hNode AS HTREEITEM)
DECLARE SUB TreeView_ExpandAllChildItems (BYVAL hwndTV AS HWND, BYVAL hNode AS HTREEITEM)
DECLARE SUB TreeView_ExpandAllItems (BYVAL hwndTV AS HWND)
DECLARE SUB TreeView_CollapseChildItems (BYVAL hwndTV AS HWND, BYVAL hNode AS HTREEITEM)
DECLARE SUB TreeView_CollapseSiblings (BYVAL hwndTV AS HWND, BYVAL hNode AS HTREEITEM)
DECLARE SUB TreeView_CollapseAllChildItems (BYVAL hwndTV AS HWND, BYVAL hNode AS HTREEITEM)
DECLARE SUB TreeView_CollapseAllItems (BYVAL hwndTV AS HWND)
DECLARE FUNCTION TreeView_GetItemText (BYVAL hwndTV AS HWND, BYVAL hItem AS HTREEITEM, BYVAL pwszText AS WSTRING PTR, BYVAL cchtextmax AS LONG) AS BOOLEAN
DECLARE FUNCTION TreeView_GetParentText (BYVAL hwndTV AS HWND, BYVAL hItem AS HTREEITEM, BYVAL pwszText AS WSTRING PTR, BYVAL cchTextMax AS LONG) AS BOOLEAN
DECLARE FUNCTION TreeView_ItemExists (BYVAL hTreeView AS HWND, BYVAL hNode AS HTREEITEM, BYVAL pwszText AS WSTRING PTR) AS BOOLEAN
DECLARE FUNCTION TreeView_ItemExistsIgnoreCase (BYVAL hTreeView AS HWND, BYVAL hNode AS HTREEITEM, BYVAL pwszText AS WSTRING PTR) AS BOOLEAN
' Task dialog
#if _WIN32_WINNT = &h0602
DECLARE SUB TaskDialog_ClickButton (BYVAL hTaskDlg AS HWND, BYVAL nButton AS DWORD)
DECLARE SUB TaskDialog_ClickRadioButton (BYVAL hTaskDlg AS HWND, BYVAL nRadioButton AS DWORD)
DECLARE SUB TaskDialog_ClickVerification (BYVAL hTaskDlg AS HWND, BYVAL fChecked AS LONG, BYVAL fFocused AS LONG)
DECLARE SUB TaskDialog_EnableButton (BYVAL hTaskDlg AS HWND, BYVAL nButton AS LONG, BYVAL fEnable AS LONG)
DECLARE SUB TaskDialog_EnableRadioButton (BYVAL hTaskDlg AS HWND, BYVAL nRadioButton AS LONG, BYVAL fEnable AS LONG)
DECLARE SUB TaskDialog_NavigatePage (BYVAL hTaskDlg AS HWND, BYVAL pTaskConfig AS TASKDIALOGCONFIG PTR)
DECLARE SUB TaskDialog_SetButtonElevationRequiredState (BYVAL hTaskDlg AS HWND, BYVAL nButton AS LONG, BYVAL fElevation AS LONG)
DECLARE SUB TaskDialog_SetElementText (BYVAL hTaskDlg AS HWND, BYVAL eElement AS LONG, BYVAL pszNewText AS WSTRING PTR)
DECLARE SUB TaskDialog_SetMarqueeProgressBar (BYVAL hTaskDlg AS HWND, BYVAL fMarquee AS BOOLEAN)
DECLARE SUB TaskDialog_SetProgressBarMarquee (BYVAL hTaskDlg AS HWND, BYVAL fMarquee AS LONG, BYVAL nSpeed AS LONG)
DECLARE FUNCTION TaskDialog_SetProgressBarPos (BYVAL hTaskDlg AS HWND, BYVAL nNewPos AS LONG) AS LONG
DECLARE FUNCTION TaskDialog_SetProgressBarRange (BYVAL hTaskDlg AS HWND, BYVAL nMinRange AS SHORT, BYVAL nMaxRange AS SHORT) AS DWORD
DECLARE FUNCTION TaskDialog_SetProgressBarState (BYVAL hTaskDlg AS HWND, BYVAL nNewState AS LONG) AS LONG
DECLARE SUB TaskDialog_UpdateElementText (BYVAL hTaskDlg AS HWND, BYVAL eElement AS LONG, BYVAL pszNewText AS WSTRING PTR)
DECLARE SUB TaskDialog_UpdateIcon (BYVAL hTaskDlg AS HWND, BYVAL nIconElement AS LONG, BYVAL idResource AS DWORD)
#endif
' IP address
DECLARE SUB IPAddress_ClearAddress (BYVAL hIPM AS HWND)
DECLARE FUNCTION IPAddress_GetAddress (BYVAL hIPM AS HWND, BYVAL pdwAddr AS DWORD PTR) AS LONG
DECLARE SUB IPAddress_IsBlank (BYVAL hIPM AS HWND)
DECLARE SUB IPAddress_SetAddress (BYVAL hIPM AS HWND, BYVAL dwAddr AS DWORD)
DECLARE SUB IPAddress_SetFocus (BYVAL hIPM AS HWND, BYVAL nField AS LONG)
DECLARE FUNCTION IPAddress_SetRange (BYVAL hIPM AS HWND, BYVAL nField AS LONG, BYVAL loRange AS BYTE, BYVAL hiRange AS BYTE) AS BOOLEAN
' Progress bar
DECLARE FUNCTION ProgressBar_DeltaPos (BYVAL hProgress AS HWND, BYVAL nIncrement AS LONG) AS LONG
DECLARE FUNCTION ProgressBar_GetHighLimit (BYVAL hProgress AS HWND) AS INT_
DECLARE FUNCTION ProgressBar_GetLowLimit (BYVAL hProgress AS HWND) AS LONG
DECLARE FUNCTION ProgressBar_GetMaxRange (BYVAL hProgress AS HWND) AS LONG
DECLARE FUNCTION ProgressBar_GetMinRange (BYVAL hProgress AS HWND) AS LONG
DECLARE FUNCTION ProgressBar_GetPos (BYVAL hProgress AS HWND) AS DWORD
DECLARE FUNCTION ProgressBar_GetRange (BYVAL hProgress AS HWND, BYVAL fWhichLimit AS DWORD, BYVAL ppBRange AS PBRANGE PTR) AS LONG
DECLARE FUNCTION ProgressBar_IncPos (BYVAL hProgress AS HWND, BYVAL nIncVal AS LONG) AS LONG
DECLARE FUNCTION ProgressBar_SetBarColor (BYVAL hProgress AS HWND, BYVAL clrBar AS COLORREF) AS COLORREF
DECLARE FUNCTION ProgressBar_SetBkColor (BYVAL hProgress AS HWND, BYVAL clrBk AS COLORREF) AS COLORREF
DECLARE FUNCTION ProgressBar_SetMarquee (BYVAL hProgress AS HWND, BYVAL fOn AS LONG, BYVAL dwAnimationSpeed AS DWORD) AS LONG
DECLARE FUNCTION ProgressBar_SetMarqueeOff (BYVAL hProgress AS HWND) AS LONG
DECLARE FUNCTION ProgressBar_SetMarqueeOn (BYVAL hProgress AS HWND, BYVAL dwAnimationSpeed AS DWORD) AS LONG
DECLARE FUNCTION ProgressBar_SetPos (BYVAL hProgress AS HWND, BYVAL nNewPos AS LONG) AS LONG
DECLARE FUNCTION ProgressBar_SetRange (BYVAL hProgress AS HWND, BYVAL nMinRange AS WORD, BYVAL nMaxRange AS WORD) AS DWORD
DECLARE FUNCTION ProgressBar_SetRange32 (BYVAL hProgress AS HWND, BYVAL nMinRange AS LONG, BYVAL nMaxRange AS LONG) AS DWORD
DECLARE FUNCTION ProgressBar_SetStep (BYVAL hProgress AS HWND, BYVAL nStepInc AS LONG) AS LONG
DECLARE FUNCTION ProgressBar_StepIt (BYVAL hProgress AS HWND) AS LONG
#if _WIN32_WINNT = &h0602
DECLARE FUNCTION ProgressBar_GetBarColor (BYVAL hProgress AS HWND) AS COLORREF
DECLARE FUNCTION ProgressBar_GetBkColor (BYVAL hProgress AS HWND) AS COLORREF
DECLARE FUNCTION ProgressBar_GetState (BYVAL hProgress AS HWND) AS LONG
DECLARE FUNCTION ProgressBar_SetState (BYVAL hProgress AS HWND, BYVAL iState AS LONG) AS LONG
#endif
' Status bar
DECLARE FUNCTION StatusBar_GetBorders (BYVAL hStatusBar AS HWND, BYVAL rgBorders AS LONG PTR) AS LONG
DECLARE FUNCTION StatusBar_GetIcon (BYVAL hStatusBar AS HWND, BYVAL nPart AS DWORD) AS HICON
DECLARE FUNCTION StatusBar_GetParts (BYVAL hStatusBar AS HWND, BYVAL nParts AS DWORD, BYVAL rgRightCoords AS LONG PTR) AS LONG
DECLARE FUNCTION StatusBar_GetPartsCount (BYVAL hStatusBar AS HWND) AS DWORD
DECLARE FUNCTION StatusBar_GetRect (BYVAL hStatusBar AS HWND, BYVAL nPart AS DWORD, BYVAL lprc AS RECT PTR) AS LONG
DECLARE FUNCTION StatusBar_GetTextDrawingMode (BYVAL hStatusBar AS HWND, BYVAL nPart AS DWORD) AS LONG
DECLARE FUNCTION StatusBar_GetTextLength (BYVAL hStatusBar AS HWND, BYVAL nPart AS DWORD) AS LONG
DECLARE SUB StatusBar_GetTipText (BYVAL hStatusBar AS HWND, BYVAL nPart AS WORD, BYVAL pwszText AS WSTRING PTR, BYVAL wMaxLen AS WORD)
DECLARE FUNCTION StatusBar_GetUnicodeFormat (BYVAL hStatusBar AS HWND) AS DWORD
DECLARE FUNCTION StatusBar_IsSimple (BYVAL hStatusBar AS HWND) AS BOOLEAN
DECLARE FUNCTION StatusBar_SetBkColor (BYVAL hStatusBar AS HWND, BYVAL clrBk AS COLORREF) AS COLORREF
DECLARE SUB StatusBar_SetFont (BYVAL hStatusBar AS HWND, BYVAL hFont AS HFONT, BYVAL fRedraw AS LONG = FALSE)
DECLARE FUNCTION StatusBar_SetIcon (BYVAL hStatusBar AS HWND, BYVAL nPart AS LONG, BYVAL hIcon AS HICON) AS BOOLEAN
DECLARE SUB StatusBar_SetMinHeight (BYVAL hStatusBar AS HWND, BYVAL minHeight AS DWORD)
DECLARE FUNCTION StatusBar_SetParts (BYVAL hStatusBar AS HWND, BYVAL dwParts AS DWORD, BYVAL rgWidths AS LONG PTR) AS BOOLEAN
DECLARE FUNCTION StatusBar_SetText (BYVAL hStatusBar AS HWND, BYVAL nPart AS LONG, BYVAL pwszText AS WSTRING PTR, BYVAL uType AS DWORD = 0) AS BOOLEAN
DECLARE SUB StatusBar_SetTipText (BYVAL hStatusBar AS HWND, BYVAL nPart AS LONG, BYVAL pwszTipText AS WSTRING PTR)
DECLARE FUNCTION StatusBar_SetUnicodeFormat (BYVAL hStatusBar AS HWND, BYVAL fUnicode AS DWORD) AS DWORD
DECLARE SUB StatusBar_Simple (BYVAL hStatusBar AS HWND, BYVAL fSimple AS BOOLEAN)
DECLARE FUNCTION StatusBar_GetHeight (BYVAL hStatusBar AS HWND) AS LONG
DECLARE FUNCTION StatusBar_GetText (BYVAL hStatusBar AS HWND, BYVAL nPart AS DWORD, BYVAL pwszText AS WSTRING PTR) AS DWORD
' Tab control
DECLARE FUNCTION TabCtrl_InsertTab (BYVAL hwndTab AS HWND, BYVAL nTabIndex AS DWORD, BYVAL iImage AS LONG, BYVAL pwszText AS WSTRING PTR, BYVAL lParam AS LPARAM = 0) AS LONG
DECLARE FUNCTION TabCtrl_AddTab (BYVAL hwndTab AS HWND, BYVAL iImage AS LONG, BYVAL pwszText AS WSTRING PTR, BYVAL lParam AS LPARAM = 0) AS LONG
DECLARE FUNCTION TabCtrl_GetText (BYVAL hwndTab AS HWND, BYVAL nTabIndex AS DWORD, BYVAL pwszText AS WSTRING PTR, BYVAL cchTextMax AS LONG) AS BOOLEAN
DECLARE FUNCTION TabCtrl_SetText (BYVAL hwndTab AS HWND, BYVAL nTabIndex AS DWORD, BYVAL pwszText AS WSTRING PTR) AS BOOLEAN
DECLARE FUNCTION TabCtrl_GetImageIndex (BYVAL hwndTab AS HWND, BYVAL iItem AS DWORD) AS LONG
DECLARE FUNCTION TabCtrl_SetImageIndex (BYVAL hwndTab AS HWND, BYVAL iItem AS DWORD, BYVAL iImage AS LONG) AS BOOLEAN
' Trackbar
DECLARE SUB Trackbar_ClearSel (BYVAL hTrackbar AS HWND, BYVAL fRedraw AS BOOLEAN = FALSE)
DECLARE SUB Trackbar_ClearTics (BYVAL hTrackbar AS HWND, BYVAL fRedraw AS BOOLEAN = FALSE)
DECLARE FUNCTION Trackbar_GetBuddy (BYVAL hTrackbar AS HWND, BYVAL fLocation AS LONG) AS HWND
DECLARE SUB Trackbar_GetChannelRect (BYVAL hTrackbar AS HWND, BYVAL lprc AS RECT PTR)
DECLARE FUNCTION Trackbar_GetLineSize (BYVAL hTrackbar AS HWND) AS LONG
DECLARE FUNCTION Trackbar_GetNumTics (BYVAL hTrackbar AS HWND) AS LONG
DECLARE FUNCTION Trackbar_GetPageSize (BYVAL hTrackbar AS HWND) AS LONG
DECLARE FUNCTION Trackbar_GetPos (BYVAL hTrackbar AS HWND) AS LONG
DECLARE FUNCTION Trackbar_GetPTics (BYVAL hTrackbar AS HWND) AS DWORD
DECLARE FUNCTION Trackbar_GetRangeMax (BYVAL hTrackbar AS HWND) AS LONG
DECLARE FUNCTION Trackbar_GetRangeMin (BYVAL hTrackbar AS HWND) AS LONG
DECLARE FUNCTION Trackbar_GetSelEnd (BYVAL hTrackbar AS HWND) AS LONG
DECLARE FUNCTION Trackbar_GetSelStart (BYVAL hTrackbar AS HWND) AS LONG
DECLARE FUNCTION Trackbar_GetThumbLength (BYVAL hTrackbar AS HWND) AS LONG
DECLARE SUB Trackbar_GetThumbRect (BYVAL hTrackbar AS HWND, BYVAL lprc AS RECT PTR)
DECLARE FUNCTION Trackbar_GetTic (BYVAL hTrackbar AS HWND, BYVAL iTic AS DWORD) AS LONG
DECLARE FUNCTION Trackbar_GetTicPos (BYVAL hTrackbar AS HWND, BYVAL iTic AS DWORD) AS LONG
DECLARE FUNCTION Trackbar_GetTooltips (BYVAL hTrackbar AS HWND) AS HWND
DECLARE FUNCTION Trackbar_GetUnicodeFormat (BYVAL hTrackbar AS HWND) AS DWORD
DECLARE FUNCTION Trackbar_SetBuddy (BYVAL hTrackbar AS HWND, BYVAL fLocation AS LONG, BYVAL hwndBuddy AS HWND) AS HWND
DECLARE FUNCTION Trackbar_SetLineSize (BYVAL hTrackbar AS HWND, BYVAL lLineSize AS LONG) AS LONG
DECLARE FUNCTION Trackbar_SetPageSize (BYVAL hTrackbar AS HWND, BYVAL lPageSize AS LONG) AS LONG
DECLARE SUB Trackbar_SetPos (BYVAL hTrackbar AS HWND, BYVAL fPosition AS LONG, BYVAL lPosition AS LONG)
DECLARE SUB Trackbar_SetRange (BYVAL hTrackbar AS HWND, BYVAL lMinimum AS LONG, BYVAL lMaximum AS LONG, BYVAL fRedraw AS BOOLEAN = FALSE)
DECLARE SUB Trackbar_SetRangeMax (BYVAL hTrackbar AS HWND, BYVAL lMaximum AS LONG, BYVAL fRedraw AS BOOLEAN = FALSE)
DECLARE SUB Trackbar_SetRangeMin (BYVAL hTrackbar AS HWND, BYVAL lMinimum AS LONG, BYVAL fRedraw AS BOOLEAN = FALSE)
DECLARE SUB Trackbar_SetSel (BYVAL hTrackbar AS HWND, BYVAL lMinimum AS LONG, BYVAL lMaximum AS LONG, BYVAL fRedraw AS BOOLEAN = FALSE)
DECLARE SUB Trackbar_SetSelEnd (BYVAL hTrackbar AS HWND, BYVAL lEnd AS LONG, BYVAL fRedraw AS BOOLEAN = FALSE)
DECLARE SUB Trackbar_SetSelStart (BYVAL hTrackbar AS HWND, BYVAL lStart AS LONG, BYVAL fRedraw AS BOOLEAN = FALSE)
DECLARE SUB Trackbar_SetThumbLength (BYVAL hTrackbar AS HWND, BYVAL iLength AS LONG)
DECLARE FUNCTION Trackbar_SetTic (BYVAL hTrackbar AS HWND, BYVAL lPosition AS LONG) AS BOOLEAN
DECLARE SUB Trackbar_SetTicFreq (BYVAL hTrackbar AS HWND, BYVAL wFreq AS WORD)
DECLARE FUNCTION Trackbar_SetTipSide (BYVAL hTrackbar AS HWND, BYVAL fLocation AS LONG) AS LONG
DECLARE SUB Trackbar_SetToolTips (BYVAL hTrackbar AS HWND, BYVAL hwndTT AS HWND)
DECLARE FUNCTION Trackbar_SetUnicodeFormat (BYVAL hTrackbar AS HWND, BYVAL fUnicode AS DWORD) AS DWORD
' UpDown
DECLARE FUNCTION UpDown_GetAccel (BYVAL hUDM AS HWND, BYVAL cAccels AS DWORD, BYVAL paAccels AS UDACCEL PTR) AS LONG
DECLARE FUNCTION UpDown_GetBase (BYVAL hUDM AS HWND) AS LONG
DECLARE FUNCTION UpDown_GetBuddy (BYVAL hUDM AS HWND) AS HWND
DECLARE FUNCTION UpDown_GetPos (BYVAL hUDM AS HWND) AS LONG
DECLARE FUNCTION UpDown_GetPos32 (BYVAL hUDM AS HWND, BYVAL pfError AS LONG PTR = NULL) AS LONG
DECLARE FUNCTION UpDown_GetRange (BYVAL hUDM AS HWND) AS LONG
DECLARE SUB UpDown_GetRange32 (BYVAL hUDM AS HWND, BYVAL pLow AS WORD PTR, BYVAL pHigh AS WORD PTR)
DECLARE FUNCTION UpDown_GetUnicodeFormat (BYVAL hUDM AS HWND) AS DWORD
DECLARE FUNCTION UpDown_SetAccel (BYVAL hUDM AS HWND, BYVAL cAccels AS DWORD, BYREF paAccels AS UDACCEL PTR) AS BOOLEAN
DECLARE FUNCTION UpDown_SetBase (BYVAL hUDM AS HWND, BYVAL nBase AS LONG) AS LONG
DECLARE FUNCTION UpDown_SetBuddy (BYVAL hUDM AS HWND, BYVAL hwndBuddy AS HWND) AS HWND
DECLARE FUNCTION UpDown_SetPos (BYVAL hUDM AS HWND, BYVAL nPos AS SHORT) AS LONG
DECLARE FUNCTION UpDown_SetPos32 (BYVAL hUDM AS HWND, BYVAL nPos AS LONG) AS LONG
DECLARE SUB UpDown_SetRange (BYVAL hUDM AS HWND, BYVAL nUpper AS SHORT, BYVAL nLower AS SHORT)
DECLARE SUB UpDown_SetRange32 (BYVAL hUDM AS HWND, BYVAL iLow AS LONG, BYVAL iHigh AS LONG)
DECLARE FUNCTION UpDown_SetUnicodeFormat (BYVAL hUDM AS HWND, BYVAL fUnicode AS DWORD) AS DWORD
' Tooltip
DECLARE SUB Tooltip_Activate (BYVAL hTooltip AS HWND, BYVAL fActivate AS BOOLEAN)
DECLARE FUNCTION Tooltip_AddTool (BYVAL hTooltip AS HWND, BYVAL lpti AS TOOLINFOW PTR) AS BOOLEAN
DECLARE FUNCTION Tooltip_AdjustRect (BYVAL hTooltip AS HWND, BYVAL fLarger AS BOOLEAN, BYVAL lprc AS RECT PTR) AS BOOLEAN
DECLARE SUB Tooltip_DelTool (BYVAL hTooltip AS HWND, BYVAL lpti AS TOOLINFOW PTR)
DECLARE FUNCTION Tooltip_EnumTools (BYVAL hTooltip AS HWND, BYVAL iTool AS DWORD, BYVAL lpti AS TOOLINFOW PTR) AS BOOLEAN
DECLARE FUNCTION Tooltip_GetBubbleSize (BYVAL hTooltip AS HWND, BYVAL lpTtm AS TOOLINFOW PTR) AS DWORD
DECLARE FUNCTION Tooltip_GetCurrentTool (BYVAL hTooltip AS HWND, BYVAL lpti AS TOOLINFOW PTR) AS BOOLEAN
DECLARE FUNCTION Tooltip_GetDelayTime (BYVAL hTooltip AS HWND, BYVAL dwDuration AS DWORD) AS LONG
DECLARE FUNCTION Tooltip_GetFont (BYVAL hTooltip AS HWND) AS HFONT
DECLARE SUB Tooltip_GetMargin (BYVAL hTooltip AS HWND, BYVAL lprc AS RECT PTR)
DECLARE FUNCTION Tooltip_GetMaxTipWidth (BYVAL hTooltip AS HWND) AS LONG
DECLARE SUB Tooltip_GetText (BYVAL hTooltip AS HWND, BYVAL numChars AS DWORD, BYVAL lpti AS TOOLINFOW PTR)
DECLARE FUNCTION Tooltip_GetTipBkColor (BYVAL hTooltip AS HWND) AS COLORREF
DECLARE FUNCTION Tooltip_GetTipTextColor (BYVAL hTooltip AS HWND) AS COLORREF
DECLARE SUB Tooltip_GetTitle (BYVAL hTooltip AS HWND, BYVAL pTTGetTitle AS TTGETTITLE PTR)
DECLARE FUNCTION Tooltip_GetToolCount (BYVAL hTooltip AS HWND) AS LONG
DECLARE FUNCTION Tooltip_GetToolInfo (BYVAL hTooltip AS HWND, BYVAL lpti AS TOOLINFOW PTR) AS BOOLEAN
DECLARE FUNCTION Tooltip_HitTest (BYVAL hTooltip AS HWND, BYVAL lphti AS TTHITTESTINFO PTR) AS BOOLEAN
DECLARE SUB Tooltip_NewToolRect (BYVAL hTooltip AS HWND, BYVAL lpti AS TOOLINFOW PTR)
DECLARE SUB Tooltip_Pop (BYVAL hTooltip AS HWND)
DECLARE SUB Tooltip_Popup (BYVAL hTooltip AS HWND)
DECLARE FUNCTION Tooltip_RelayEvent (BYVAL hTooltip AS HWND, BYVAL lpmsg AS tagMSG PTR) AS LONG
DECLARE SUB Tooltip_SetDelayTime (BYVAL hTooltip AS HWND, BYVAL dwDuration AS DWORD, BYVAL iTime AS SHORT)
DECLARE SUB Tooltip_SetFont (BYVAL hTooltip AS HWND, BYVAL hFont AS HFONT = NULL, BYVAL fRedraw AS BOOLEAN = FALSE)
DECLARE SUB Tooltip_SetMargin (BYVAL hTooltip AS HWND, BYVAL lprc AS RECT PTR)
DECLARE FUNCTION Tooltip_SetMaxTipWidth (BYVAL hTooltip AS HWND, BYVAL iWidth AS LONG) AS LONG
DECLARE SUB Tooltip_SetTipBkColor (BYVAL hTooltip AS HWND, BYVAL clr AS COLORREF)
DECLARE SUB Tooltip_SetTipTextColor (BYVAL hTooltip AS HWND, BYVAL clr AS COLORREF)
DECLARE FUNCTION Tooltip_SetTitle (BYVAL hTooltip AS HWND, BYVAL nIcon AS LONG, BYVAL pwszTitle AS WSTRING PTR) AS BOOLEAN
DECLARE SUB Tooltip_SetToolInfo (BYVAL hTooltip AS HWND, BYVAL lpti AS TOOLINFOW PTR)
DECLARE SUB Tooltip_SetWindowTheme (BYVAL hTooltip AS HWND, BYVAL pwszTheme AS WSTRING PTR)
DECLARE SUB Tooltip_TrackActivate (BYVAL hTooltip AS HWND, BYVAL bActivate AS BOOLEAN, BYVAL lpti AS TOOLINFOW PTR)
DECLARE SUB Tooltip_TrackPosition (BYVAL hTooltip AS HWND, BYVAL xPos AS LONG, BYVAL yPos AS LONG)
DECLARE SUB Tooltip_Update (BYVAL hTooltip AS HWND)
DECLARE SUB Tooltip_UpdateTipText (BYVAL hTooltip AS HWND, BYVAL lpti AS TOOLINFOW PTR)
DECLARE FUNCTION Tooltip_WindowFromPoint (BYVAL hTooltip AS HWND, BYVAL lppt AS POINT PTR) AS HWND


' ########################################################################################
'                                     *** BUTTON ***
' ########################################################################################

' ========================================================================================
' Simulates the user clicking a button. This message causes the button to receive the
' WM_LBUTTONDOWN and WM_LBUTTONUP messages, and the button's parent window to receive a
' BN_CLICKED notification code.
' ========================================================================================
PRIVATE SUB Button_Click (BYVAL hButton AS HWND)
   SendMessageW(hButton, BM_CLICK, 0, 0)
END SUB
' ========================================================================================

' ========================================================================================
' Retrieves a handle to the image (icon or bitmap) associated with the button.
' The return value is a handle to the image, if any; otherwise, it is NULL.
' ========================================================================================
PRIVATE FUNCTION Button_GetImage (BYVAL hButton AS HWND) AS HANDLE
   FUNCTION = cast(HANDLE, SendMessageW(hButton, BM_GETIMAGE, 0, 0))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Sets a flag on a radio button that controls the generation of BN_CLICKED messages when
' the button receives focus.
' - bState = A BOOL that specifies the state. CTRUE to set the flag, otherwise FALSE.
' ========================================================================================
#if _WIN32_WINNT = &h0602
PRIVATE SUB Button_SetDontClick (BYVAL hButton AS HWND, BYVAL bState AS BOOL)
   SendMessageW(hButton, BM_SETDONTCLICK, cast(WPARAM, bState), 0)
END SUB
#endif
' ========================================================================================

' ========================================================================================
' Associates a new bitmap with a button. The return value is a handle to the image previously
' associated with the button, if any; otherwise, it is NULL.
' ========================================================================================
PRIVATE FUNCTION Button_SetBitmap (BYVAL hButton AS HWND, BYVAL hbmp AS HBITMAP) AS HBITMAP
   FUNCTION = cast(HBITMAP, SendMessageW(hButton, BM_SETIMAGE, cast(WPARAM, IMAGE_BITMAP), cast(LPARAM, hbmp)))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Associates a new icon with the button. The return value is a handle to the image previously
' associated with the button, if any; otherwise, it is NULL.
' ========================================================================================
PRIVATE FUNCTION Button_SetIcon (BYVAL hButton AS HWND, BYVAL hIcon AS HICON) AS HICON
   FUNCTION = cast(HICON, SendMessageW(hButton, BM_SETIMAGE, cast(WPARAM, IMAGE_ICON), cast(LPARAM, hIcon)))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Associates a new image (icon or bitmap) with the button. The return value is a handle to
' the image previously associated with the button, if any; otherwise, it is NULL.
' ========================================================================================
PRIVATE FUNCTION Button_SetImage (BYVAL hButton AS HWND, BYVAL ImageType AS DWORD, BYVAL hImage AS HANDLE) AS HANDLE
   FUNCTION = cast(HANDLE, SendMessageW(hButton, BM_SETIMAGE, cast(WPARAM, ImageType), cast(LPARAM, hImage)))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Assigns an image list to a button control. Requires Windows XP or superior.
' Parameters:
' - hButon     = The handle of the button.
' - hImageList =
' - nLeft      = The x-coordinate of the upper-left corner of the rectangle for the image.
' - nTop       = The y-coordinate of the upper-left corner of the rectangle for the image.
' - nRight     = The x-coordinate of the lower-right corner of the rectangle for the image.
' - nBottom    = The y-coordinate of the lower-right corner of the rectangle for the image.
' - uAlign     = The alignment to use. This parameter can be one of the following values:
'                BUTTON_IMAGELIST_ALIGN_LEFT   Align the image with the left margin.
'                BUTTON_IMAGELIST_ALIGN_RIGHT  Align the image with the right margin
'                BUTTON_IMAGELIST_ALIGN_TOP    Align the image with the top margin
'                BUTTON_IMAGELIST_ALIGN_BOTTOM Align the image with the bottom margin
'                BUTTON_IMAGELIST_ALIGN_CENTER Center the image.
'                The default value is BUTTON_IMAGELIST_ALIGN_LEFT.
' Return value:  If the function succeeds, it returns TRUE. Otherwise it returns FALSE.
' Note:  To use this application programming interface (API), you must provide a manifest
' specifying Comclt32.dll version 6.0.
' ========================================================================================
PRIVATE FUNCTION Button_SetImageListXY (BYVAL hButton AS HWND, BYVAL himl AS HIMAGELIST, BYVAL nLeft AS LONG, BYVAL nTop AS LONG, BYVAL nRight AS LONG, BYVAL nBottom AS LONG, BYVAL uALign AS DWORD = 0) AS BOOLEAN
   DIM bi AS BUTTON_IMAGELIST = (himl, (nLeft, nTop, nRight, nBottom), uAlign)
   FUNCTION = SendMessageW(hButton, BCM_SETIMAGELIST, 0, cast(LPARAM, @bi))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Deletes a bitmap associated with a button.
' Returns TRUE or FALSE.
' ========================================================================================
PRIVATE FUNCTION Button_DeleteBitmap (BYVAL hButton AS HWND) AS BOOLEAN
   FUNCTION = DeleteObject(cast(HGDIOBJ, SendMessageW(hButton, BM_SETIMAGE, cast(WPARAM, IMAGE_BITMAP), cast(LPARAM, NULL))))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Deletes an icon associated with a button.
' Returns TRUE or FALSE.
' ========================================================================================
PRIVATE FUNCTION Button_DeleteIcon (BYVAL hButton AS HWND) AS BOOLEAN
   FUNCTION = DeleteObject(cast(HGDIOBJ, SendMessageW(hButton, BM_SETIMAGE, cast(WPARAM, IMAGE_ICON), cast(LPARAM, NULL))))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Deletes an image (icon or bitmap) associated a button.
' Returns TRUE or FALSE.
' ========================================================================================
PRIVATE FUNCTION Button_DeleteImage (BYVAL hButton AS HWND, BYVAL ImageType AS DWORD) AS BOOLEAN
   FUNCTION = DeleteObject(cast(HGDIOBJ, SendMessageW(hButton, BM_SETIMAGE, cast(WPARAM, ImageType), cast(LPARAM, NULL))))
END FUNCTION
' ========================================================================================


' ########################################################################################
'                                    *** COMBOBOX ***
' ########################################################################################

' ========================================================================================
' Gets a string from a list in a combo box.
' - hComboBox: A handle to the combobox.
' - nIndex: The zero-based index of the item.
' ========================================================================================
PRIVATE FUNCTION AfxGetComboBoxText (BYVAL hComboBox AS HWND, BYVAL nIndex AS LONG) AS CWSTR
   DIM nLen AS LONG = SendMessageW(hComboBox, CB_GETLBTEXTLEN, nIndex, 0)
   DIM cwsText AS CWSTR = SPACE(nLen + 1)
   SendMessageW(hComboBox, CB_GETLBTEXT, nIndex, cast(LPARAM, *cwsText))
   RETURN cwsText
END FUNCTION
' ========================================================================================

' ========================================================================================
' Retrieves information about the specified combo box. If the function succeeds, the return
' value is nonzero. If the function fails, the return value is zero. To get extended error
' information, call GetLastError.
' ========================================================================================
PRIVATE FUNCTION ComboBox_GetComboBoxInfo (BYVAL hComboBox AS HWND, BYVAL pcbi AS COMBOBOXINFO PTR) AS BOOLEAN
   FUNCTION = SendMessageW(hComboBox, CB_GETCOMBOBOXINFO, 0, cast(LPARAM, pcbi))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Calculates the size, in logical units, of the widest string item.
' ========================================================================================
PRIVATE FUNCTION Combobox_CalcHorizontalExtent (BYVAL hComboBox AS HWND) AS LONG
   IF IsWindow(hComboBox) = 0 THEN EXIT FUNCTION
   ' // Get an handle to the device context of the control
   DIM hDC AS HDC = GetDC(hComboBox)
   ' // Get the number of items
   DIM i AS LONG, cxScrollWidth AS LONG
   DIM cItems AS LRESULT = SendMessageW(hComboBox, CB_GETCOUNT, 0, 0)
   FOR i = 0 TO cItems - 1
      ' // Get the text of the item
      DIM cbLen AS LONG = SendMessageW(hComboBox, CB_GETLBTEXTLEN, i, 0)
      IF cbLen = 0 THEN CONTINUE FOR
      DIM pbuffer AS WSTRING PTR = CAllocate(cbLen * 2)
      SendMessageW(hComboBox, CB_GETLBTEXT, i, CAST(LPARAM, pbuffer))
      ' // Computes the width and height of the text
      DIM tsize AS SIZE
      GetTextExtentPoint32W hDC, pbuffer, cbLen, @tsize
      cxScrollWidth = MAX(cxScrollWidth, tsize.cx)
      Deallocate pbuffer
   NEXT
   ' // Release the device context
   ReleaseDC hComboBox, hDC
   ' // Return the width of the text
   FUNCTION = cxScrollWidth
END FUNCTION
' ========================================================================================

' ========================================================================================
' Retrieves the handle to the edit box of the combobox
' ========================================================================================
PRIVATE FUNCTION ComboBox_GetEditBoxHandle (BYVAL hComboBox AS HWND) AS HWND
   DIM tci AS COMBOBOXINFO
   tci.cbSize = sizeof(COMBOBOXINFO)
   IF SendMessageW(hComboBox, CB_GETCOMBOBOXINFO, 0, cast(LPARAM, cast(COMBOBOXINFO PTR, @tci))) = 0 THEN EXIT FUNCTION
   FUNCTION = tci.hwndItem
END FUNCTION
' ========================================================================================

' ========================================================================================
' Retrieves the handle to the drop down of the combobox
' ========================================================================================
PRIVATE FUNCTION ComboBox_GetListBoxHandle (BYVAL hComboBox AS HWND) AS HWND
   DIM tci AS COMBOBOXINFO
   tci.cbSize = sizeof(COMBOBOXINFO)
   IF SendMessageW(hComboBox, CB_GETCOMBOBOXINFO, 0, cast(LPARAM, cast(COMBOBOXINFO PTR, @tci))) = 0 THEN EXIT FUNCTION
   FUNCTION = tci.hwndList
END FUNCTION
' ========================================================================================

' ========================================================================================
' Retrieves the minimum allowable width, in pixels, of the list box of a combo box with
' the CBS_DROPDOWN or CBS_DROPDOWNLIST style. If the message succeeds, the return value
' is the width, in pixels. If the message fails, the return value is CB_ERR.
' ========================================================================================
PRIVATE FUNCTION ComboBox_GetDroppedWidth (BYVAL hComboBox AS HWND) AS LONG
   FUNCTION = SendMessageW(hComboBox, CB_GETDROPPEDWIDTH, 0, 0)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Retrieves from a combo box the width, in pixels, by which the list box can be scrolled
' horizontally (the scrollable width). This is applicable only if the list box has a
' horizontal scroll bar. The return value is the scrollable width, in pixels.
' ========================================================================================
PRIVATE FUNCTION ComboBox_GetHorizontalExtent (BYVAL hComboBox AS HWND) AS LONG
   FUNCTION = SendMessageW(hComboBox, CB_GETHORIZONTALEXTENT, 0, 0)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Retrieves the current locale of the combo box. The locale is used to determine the
' correct sorting order of displayed text for combo boxes with the CBS_SORT style and text
' added by using the CB_ADDSTRING message. The return value specifies the current locale
' of the combo box. The HIWORD contains the country/region code and the LOWORD contains
' the language identifier.
' ========================================================================================
PRIVATE FUNCTION ComboBox_GetLocale (BYVAL hComboBox AS HWND) AS LONG
   FUNCTION = SendMessageW(hComboBox, CB_GETLOCALE, 0, 0)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Retrieves the zero-based index of the first visible item in the list box portion of a
' combo box. Initially, the item with index 0 is at the top of the list box, but if the
' list box contents have been scrolled, another item may be at the top.
' If the message is successful, the return value is the index of the first visible item in
' the list box of the combo box. If the message fails, the return value is CB_ERR.
' ========================================================================================
PRIVATE FUNCTION ComboBox_GetTopIndex (BYVAL hComboBox AS HWND) AS LONG
   FUNCTION = SendMessageW(hComboBox, CB_GETTOPINDEX, 0, 0)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Allocates memory for storing list box items. An application sends the CB_INITSTORAGE
' message before adding a large number of items to the list box portion of a combo box.
' If the message is successful, the return value is the total number of items for which
' memory has been pre-allocated, that is, the total number of items added by all successful
' CB_INITSTORAGE messages. If the message fails, the return value is CB_ERRSPACE.
' ========================================================================================
PRIVATE FUNCTION ComboBox_InitStorage (BYVAL hComboBox AS HWND, BYVAL items AS LONG, BYVAL cb AS LONG) AS LONG
   FUNCTION = SendMessageW(hComboBox, CB_INITSTORAGE, CAST(WPARAM, items), CAST(LPARAM, cb))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Sets the maximum allowable width, in pixels, of the list box of a combo box with the
' CBS_DROPDOWN or CBS_DROPDOWNLIST style. If the message is successful, The return value
' is the new width of the list box. If the message fails, the return value is CB_ERR.
' ========================================================================================
PRIVATE FUNCTION ComboBox_SetDroppedWidth (BYVAL hComboBox AS HWND, BYVAL nWidth AS LONG) AS LONG
   FUNCTION = SendMessageW(hComboBox, CB_SETDROPPEDWIDTH, cast(WPARAM, nWidth), 0)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Sets the width, in pixels, by which a list box can be scrolled horizontally (the
' scrollable width). If the width of the list box is smaller than this value, the
' horizontal scroll bar horizontally scrolls items in the list box. If the width of the
' list box is equal to or greater than this value, the horizontal scroll bar is hidden or,
' if the combo box has the CBS_DISABLENOSCROLL style, disabled.
' ========================================================================================
PRIVATE SUB ComboBox_SetHorizontalExtent (BYVAL hComboBox AS HWND, BYVAL nWidth AS LONG)
   SendMessageW(hComboBox, CB_SETHORIZONTALEXTENT, cast(WPARAM, nWidth), 0)
END SUB
' ========================================================================================

' ========================================================================================
' Sets the current locale of the combo box. If the combo box has the CBS_SORT style and
' strings are added using CB_ADDSTRING, the locale of a combo box affects how list items
' are sorted.  The return value is the previous locale identifier. If lcid specifies a
' locale not installed on the system, the return value is CB_ERR and the current combo box
' locale is not changed.
' ========================================================================================
PRIVATE FUNCTION ComboBox_SetLocale (BYVAL hComboBox AS HWND, BYVAL lcid AS LONG) AS LONG
   FUNCTION = SendMessageW(hComboBox, CB_SETLOCALE, cast(WPARAM, lcid), 0)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Ensures that a particular item is visible in the list box of a combo box. The system
' scrolls the list box contents so that either the specified it. If the message is successful,
' the return value is zero. If the message fails, the return value is CB_ERR.
' ========================================================================================
PRIVATE FUNCTION ComboBox_SetTopIndex (BYVAL hComboBox AS HWND, BYVAL index AS DWORD) AS LONG
   FUNCTION = SendMessageW(hComboBox, CB_SETTOPINDEX, cast(WPARAM, index), 0)
END FUNCTION
' ========================================================================================

' ########################################################################################
'                                   *** COMBOBOXEX ***
' ########################################################################################

' ========================================================================================
' Removes an item from a ComboBoxEx control. Returns an INT value that represents the number
' of items remaining in the control. If iIndex is invalid, the message returns CB_ERR.
' ========================================================================================
PRIVATE FUNCTION ComboBoxEx_DeleteItem (BYVAL hComboboxEx AS HWND, BYVAL nIndex AS DWORD) AS INT_
   FUNCTION = SendMessageW(hComboboxEx, CBEM_DELETEITEM, cast(WPARAM, nIndex), 0)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Returns the handle to the combo box control within the ComboBoxEx control.
' ========================================================================================
PRIVATE FUNCTION ComboBoxEx_GetComboControl (BYVAL hComboboxEx AS HWND) AS HWND
   FUNCTION = cast(HWND, SendMessageW(hComboBoxEx, CBEM_GETCOMBOCONTROL, 0, 0))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Returns the handle to the edit control within the ComboBoxEx control if it uses the
' CBS_DROPDOWN style. Otherwise, the message returns NULL.
' ========================================================================================
PRIVATE FUNCTION ComboBoxEx_GetEditControl (BYVAL hComboboxEx AS HWND) AS HWND
   FUNCTION = cast(HWND, SendMessageW(hComboBoxEx, CBEM_GETEDITCONTROL, 0, 0))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Returns a DWORD value that contains the ComboBoxEx control extended styles in use for the control.
' ========================================================================================
PRIVATE FUNCTION ComboBoxEx_GetExtendedStyle (BYVAL hComboboxEx AS HWND) AS DWORD
   FUNCTION = SendMessageW(hComboBoxEx, CBEM_GETEXTENDEDSTYLE, 0, 0)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Retrieves the handle to an image list assigned to a ComboBoxEx control.
' ========================================================================================
PRIVATE FUNCTION ComboBoxEx_GetImageList (BYVAL hComboboxEx AS HWND) AS HIMAGELIST
   FUNCTION = cast(HIMAGELIST, SendMessageW(hComboBoxEx, CBEM_GETIMAGELIST, 0, 0))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Retrieves item information for a given ComboBoxEx item. Returns TRUE or FALSE.
' ========================================================================================
PRIVATE FUNCTION ComboBoxEx_GetItem (BYVAL hComboboxEx AS HWND, BYVAL pCBItem AS COMBOBOXEXITEMW PTR) AS BOOLEAN
   FUNCTION = SendMessageW(hComboBoxEx, CBEM_GETITEMW, 0, cast(LPARAM, pCBItem))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Returns the Unicode format flag for the control. If this value is nonzero, the control
' is using Unicode characters. If this value is zero, the control is using ANSI characters.
' ========================================================================================
PRIVATE FUNCTION ComboBoxEx_GetUnicodeFormat (BYVAL hComboboxEx AS HWND) AS DWORD
   FUNCTION = SendMessageW(hComboBoxEx, CBEM_GETUNICODEFORMAT, 0, 0)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Determines whether or not the user has changed the text of a ComboBoxEx edit control.
' Returns TRUE or FALSE.
' ========================================================================================
PRIVATE FUNCTION ComboBoxEx_HasEditChanged (BYVAL hComboboxEx AS HWND) AS BOOLEAN
   FUNCTION = SendMessageW(hComboBoxEx, CBEM_HASEDITCHANGED, 0, 0)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Returns the index at which the new item was inserted if successful, or -1 otherwise.
' ========================================================================================
PRIVATE FUNCTION ComboBoxEx_InsertItem (BYVAL hComboboxEx AS HWND, BYVAL lpCBItem AS COMBOBOXEXITEMW PTR) AS LONG
   FUNCTION = SendMessageW(hComboBoxEx, CBEM_INSERTITEMW, 0, cast(LPARAM, lpCBItem))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Returns a DWORD value that contains the extended styles previously used for the control.
' ========================================================================================
PRIVATE FUNCTION ComboBoxEx_SetExtendedStyle (BYVAL hComboboxEx AS HWND, BYVAL dwExMask AS DWORD, BYVAL dwExStyle AS DWORD) AS DWORD
   FUNCTION = SendMessageW(hComboBoxEx, CBEM_SETEXTENDEDSTYLE, cast(WPARAM, dwExMask), cast(LPARAM, dwExStyle))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Returns the handle to the image list previously associated with the control, or returns
' NULL if no image list was previously set.
' ========================================================================================
PRIVATE FUNCTION ComboBoxEx_SetImageList (BYVAL hComboboxEx AS HWND, BYVAL himl AS HIMAGELIST) AS HIMAGELIST
   FUNCTION = cast(HIMAGELIST, SendMessageW(hComboBoxEx, CBEM_SETIMAGELIST, 0, cast(LPARAM, himl)))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Sets the attributes for an item in a ComboBoxEx control.
' Returns nonzero if successful, or zero otherwise.
' ========================================================================================
PRIVATE FUNCTION ComboBoxEx_SetItem (BYVAL hComboboxEx AS HWND, BYVAL lpCBItem AS COMBOBOXEXITEMW PTR) AS BOOLEAN
   FUNCTION = SendMessageW(hComboBoxEx, CBEM_SETITEMW, 0, cast(LPARAM, lpCBItem))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Sets the UNICODE character format flag for the control. This message enables you to
' change the character set used by the control at run time rather than having to re-create
' the control. Returns the previous Unicode format flag for the control.
' ========================================================================================
PRIVATE FUNCTION ComboBoxEx_SetUnicodeFormat (BYVAL hComboboxEx AS HWND, BYVAL fUnicode AS DWORD) AS DWORD
   FUNCTION = SendMessageW(hComboBoxEx, CBEM_SETUNICODEFORMAT, cast(WPARAM, fUnicode), 0)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Sets the visual style of a ComboboxEx control.
' ========================================================================================
PRIVATE SUB ComboBoxEx_SetWindowTheme (BYVAL hComboboxEx AS HWND, BYVAL pwszStyle AS WSTRING PTR)
   SendMessageW(hComboBoxEx, CBEM_SETWINDOWTHEME, 0, cast(LPARAM, pwszStyle))
END SUB
' ========================================================================================

' ########################################################################################
'                                      *** EDIT ***
' ########################################################################################

' ========================================================================================
' Gets information about the character closest to a specified point in the client area of
' an edit control. You can send this message to either an edit control or a rich edit control.
' Return value: The LOWORD specifies the zero-based index of the character nearest the
' specified point. This index is relative to the beginning of the control, not the beginning
' of the line. If the specified point is beyond the last character in the edit control, the
' return value indicates the last character in the control. The HIWORD specifies the
' zero-based index of the line that contains the character. For single-line edit controls,
' this value is zero. The index indicates the line delimiter if the specified point is
' beyond the last visible character in a line.
' ========================================================================================
PRIVATE FUNCTION Edit_CharFromPos (BYVAL hEdit AS HWND, BYVAL x AS SHORT, BYVAL y AS SHORT) AS LONG
   FUNCTION = SendMessageW(hEdit, EM_CHARFROMPOS, 0, cast(LPARAM, MAKELONG(x, y)))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Deletes (clears) the current selection, if any, from the edit control.
' ========================================================================================
PRIVATE SUB Edit_Clear (BYVAL hEdit AS HWND)
   SendMessageW(hEdit, WM_CLEAR, 0, 0)
END SUB
' ========================================================================================

' ========================================================================================
' Copies the current selection to the clipboard in CF_TEXT format.
' ========================================================================================
PRIVATE SUB Edit_Copy (BYVAL hEdit AS HWND)
   SendMessageW(hEdit, WM_COPY, 0, 0)
END SUB
' ========================================================================================

' ========================================================================================
' Deletes (cuts) the current selection, if any, in the edit control and copy the deleted
' text to the clipboard in CF_TEXT format.
' ========================================================================================
PRIVATE SUB Edit_Cut (BYVAL hEdit AS HWND)
   SendMessageW(hEdit, WM_CUT, 0, 0)
END SUB
' ========================================================================================

' ========================================================================================
' Retrieves a set of status flags that indicate how the edit control interacts with the
' Input Method Editor (IME).
' ========================================================================================
PRIVATE FUNCTION Edit_GetIMEStatus (BYVAL hEdit AS HWND, BYVAL nStatusType AS LONG) AS LONG
   FUNCTION = SendMessageW(hEdit, EM_GETIMESTATUS, cast(WPARAM, nStatusType), 0)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Gets the current text limit for an edit control. The return value is the text limit.
' ========================================================================================
PRIVATE FUNCTION Edit_GetLimitText (BYVAL hEdit AS HWND) AS LONG
   FUNCTION = SendMessageW(hEdit, EM_GETLIMITTEXT, 0, 0)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Returns the width of the left margin in the LOWORD, and the width of the right margin in the HIWORD.
' ========================================================================================
PRIVATE FUNCTION Edit_GetMargins (BYVAL hEdit AS HWND) AS DWORD
   FUNCTION = SendMessageW(hEdit, EM_GETMARGINS, 0, 0)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Returns the width of the left margin for an edit control.
' ========================================================================================
PRIVATE FUNCTION Edit_GetLeftMargin (BYVAL hEdit AS HWND) AS WORD
   FUNCTION = LOWORD(SendMessageW(hEdit, EM_GETMARGINS, 0, 0))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Gets the width of the right margin for an edit control.
' ========================================================================================
PRIVATE FUNCTION Edit_GetRightMargin (BYVAL hEdit AS HWND) AS WORD
   FUNCTION = HIWORD(SendMessageW(hEdit, EM_GETMARGINS, 0, 0))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Gets the starting character position of the current selection in an edit control.
' ========================================================================================
PRIVATE FUNCTION Edit_GetSelStart (BYVAL hEdit AS HWND) AS WORD
   FUNCTION = LOWORD(SendMessageW(hEdit, EM_GETSEL, 0, 0))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Gets the ending character position of the current selection in an edit control.
' ========================================================================================
PRIVATE FUNCTION Edit_GetSelEnd (BYVAL hEdit AS HWND) AS WORD
   FUNCTION = HIWORD(SendMessageW(hEdit, EM_GETSEL, 0, 0))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Gets the position of the scroll box (thumb) in the vertical scroll bar of a multiline
' edit control.
' ========================================================================================
PRIVATE FUNCTION Edit_GetThumb (BYVAL hEdit AS HWND) AS LONG
   FUNCTION = SendMessageW(hEdit, EM_GETTHUMB, 0, 0)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Scrolls the text in a multiline edit control.
' If the message is sent to a multiline edit control, the return value is TRUE.
' If the message is sent to a single-line edit control, the return value is FALSE.
' ========================================================================================
PRIVATE FUNCTION Edit_LineScroll (BYVAL hEdit AS HWND, BYVAL x AS LONG, BYVAL y AS LONG) AS BOOLEAN
   FUNCTION = SendMessageW(hEdit, EM_LINESCROLL, cast(WPARAM, x), cast(LPARAM, y))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Copies the current content of the clipboard to the edit control at the current caret
' position. Data is inserted only if the clipboard contains data in CF_TEXT format.
' ========================================================================================
PRIVATE SUB Edit_Paste (BYVAL hEdit AS HWND)
   SendMessageW(hEdit, WM_PASTE, 0, 0)
END SUB
' ========================================================================================

' ========================================================================================
' Retrieves the client area coordinates of a specified character in an edit control.
' The return value contains the client area coordinates of the character. The LOWORD
' contains the horizontal coordinate and the HIWORD contains the vertical coordinate.
' ========================================================================================
PRIVATE FUNCTION Edit_PosFromChar (BYVAL hEdit AS HWND, BYVAL index AS DWORD) AS LONG
   FUNCTION = SendMessageW(hEdit, EM_POSFROMCHAR, cast(WPARAM, index), 0)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Sets the text that is displayed as the textual cue, or tip, for an edit control.
' - pwszText: A pointer to a Unicode string that contains the text to display as the textual cue.
' - fDrawFocused: TRUE if the cue banner should show even when the edit control has focus;
'   otherwise, FALSE. FALSE is the default behavior—the cue banner disappears when the user
'   clicks in the control.
' If the message succeeds, it returns TRUE. Otherwise it returns FALSE.
' ========================================================================================
PRIVATE FUNCTION Edit_SetCueBannerTextFocused (BYVAL hEdit AS HWND, BYVAL pwszText AS WSTRING PTR, BYVAL fDrawFocused AS LONG) AS BOOLEAN
   FUNCTION = SendMessageW(hEdit, EM_SETCUEBANNER, cast(WPARAM, fDrawFocused), cast(WPARAM, pwszText))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Sets the status flags that determine how an edit control interacts with the Input Method
' Editor (IME).
' - nStatusType: The type of status to set. This parameter can be EMSIS_COMPOSITIONSTRING.
' - flags: Data specific to the status type. If wParam is EMSIS_COMPOSITIONSTRING, this
'   parameter can be one or more of the following values: EIMES_GETCOMPSTRATONCE,
'   EIMES_CANCELCOMPSTRINFOCUS, EIMES_COMPLETECOMPSTRKILLFOCUS.
' Returns the previous value of the flags parameter.
' ========================================================================================
PRIVATE FUNCTION Edit_SetIMEStatus (BYVAL hEdit AS HWND, BYVAL nStatusType AS LONG, BYVAL flags AS DWORD) AS DWORD
   FUNCTION = SendMessageW(hEdit, EM_SETIMESTATUS, cast(WPARAM, nStatusType), cast(LPARAM, flags))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Sets the widths of the left and right margins for an edit control. The message redraws
' the control to reflect the new margins.
' - nMargins: One or more of the following values:
'   EC_LEFTMARGIN: Sets the left margin.
'   EC_RIGHTMARGIN: Sets the right margin.
' - nWidth: The low-order word specifies the new width of the left margin, in pixels.
'   The high-order word specifies the new width of the right margin, in pixels.
' ========================================================================================
PRIVATE SUB Edit_SetMargins (BYVAL hEdit AS HWND, BYVAL nMargins AS LONG, BYVAL nWidth AS LONG)
   SendMessageW(hEdit, EM_SETMARGINS, cast(WPARAM, nMargins), cast(LPARAM, nWidth))
END SUB
' ========================================================================================

' ========================================================================================
' Sets the width of the left margin for an edit control. The message redraws the control
' to reflect the new margin.
' ========================================================================================
PRIVATE SUB Edit_SetLeftMargin (BYVAL hEdit AS HWND, BYVAL nWidth AS WORD)
   SendMessageW(hEdit, EM_SETMARGINS, cast(WPARAM, EC_LEFTMARGIN), cast(LPARAM, MAKELONG(nWidth, 0)))
END SUB
' ========================================================================================

' ========================================================================================
' Sets the width of the right margin for an edit control. The message redraws the control
' to reflect the new margin.
' ========================================================================================
PRIVATE SUB Edit_SetRightMargin (BYVAL hEdit AS HWND, BYVAL nWidth AS WORD)
   SendMessageW(hEdit, EM_SETMARGINS, cast(WPARAM, EC_RIGHTMARGIN), cast(LPARAM, MAKELONG(0, nWidth)))
END SUB
' ========================================================================================


' ########################################################################################
'                                      *** HEADER ***
' ########################################################################################

' ========================================================================================
' Tests a point to determine which header item, if any, is at the specified point.
' ========================================================================================
PRIVATE FUNCTION Header_HitTest (BYVAL hwndHD AS HWND, BYVAL phdhti AS HDHITTESTINFO PTR) AS LONG
   FUNCTION = SendMessageW(hwndHD, HDM_HITTEST, 0, cast(LPARAM, phdhti))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Gets the width of the specified item of a header control.
' Returns the index of the item at the specified position, if any, or – 1 otherwise.
' ========================================================================================
PRIVATE FUNCTION Header_GetItemWidth (BYVAL hwndHD AS HWND, BYVAL nItem AS LONG) AS LONG
   DIM hdi AS HDITEMW
   hdi.mask = HDI_WIDTH
   IF SendMessageW(hwndHD, HDM_GETITEMW, cast(WPARAM, nItem), cast(LPARAM, cast(HDITEMW PTR, @hdi))) THEN FUNCTION = hdi.cxy
END FUNCTION
' ========================================================================================

' ========================================================================================
' Sets the width of the specified item of a header control.
' Returns nonzero upon success, or zero otherwise.
' ========================================================================================
PRIVATE FUNCTION Header_SetItemWidth (BYVAL hwndHD AS HWND, BYVAL nItem AS LONG, BYVAL nWidth AS LONG) AS BOOLEAN
   DIM hdi AS HDITEMW
   hdi.mask = HDI_WIDTH
   hdi.cxy = nWidth
   FUNCTION = SendMessageW(hwndHD, HDM_SETITEMW, cast(WPARAM, nItem), cast(LPARAM, cast(HDITEMW PTR, @hdi)))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Gets the order of the specified item of a header control.
' ========================================================================================
PRIVATE FUNCTION Header_GetItemOrder (BYVAL hwndHD AS HWND, BYVAL nItem AS LONG) AS LONG
   DIM hdi AS HDITEMW
   hdi.mask = HDI_ORDER
   IF SendMessageW(hwndHD, HDM_GETITEMW, cast(WPARAM, nItem), cast(LPARAM, cast(HDITEMW PTR, @hdi))) THEN FUNCTION = hdi.iOrder
END FUNCTION
' ========================================================================================

' ========================================================================================
' Sets the order of the specified item of a header control.
' ========================================================================================
PRIVATE FUNCTION Header_SetItemOrder (BYVAL hwndHD AS HWND, BYVAL nItem AS LONG, BYVAL iOrder AS LONG) AS LONG
   DIM hdi AS HDITEMW
   hdi.mask = HDI_ORDER
   hdi.iOrder = iOrder
   FUNCTION = SendMessageW(hwndHD, HDM_SETITEMW, cast(WPARAM, nItem), cast(LPARAM, cast(HDITEMW PTR, @hdi)))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Gets the text of the specified column.
' - hwndHD: Handle to the header control.
' - nItem: The index of the item for which information is to be retrieved.
' - pwszText: A pointer to an item string. If the text is being retrieved from the control,
'   this member must be initialized to point to a character buffer. If this member is set
'   to LPSTR_TEXTCALLBACK, the control will request text information for this item by sending
'   an HDN_GETDISPINFO notification code. Note that although the header control allows a
'   string of any length to be stored as item text, only the first 260 characters are displayed.
' - cchTextMax : Maximum number of characters to return. Both this value and the size of the
'   buffer pointed by pwszText must be one character bigger that the wanted length of the text
'   to return to make room for the null character terminator.
' Return value: Returns TRUE or FALSE.
' Usage example:
' DIM wszText AS WSTRING * 260
' Header_GetItemText(hTreeView, hItem, @wszText, 260)
' AfxMsg(wszText)
' ========================================================================================
PRIVATE FUNCTION Header_GetItemText (BYVAL hwndHD AS HWND, BYVAL nItem AS LONG, BYVAL pwszText AS WSTRING PTR, BYVAL cchTextMax AS LONG) AS BOOLEAN
   IF pwszText = NULL THEN EXIT FUNCTION
   DIM hdi AS HDITEMW
   hdi.mask = HDI_TEXT
   hdi.psztext = pwszText
   hdi.cchtextmax = cchtextmax
   FUNCTION = SendMessageW(hwndHD, HDM_GETITEMW, 0, cast(LPARAM, cast(HDITEMW PTR, @hdi)))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Sets the text of the specified item. Returns TRUE or FALSE.
' ========================================================================================
PRIVATE FUNCTION Header_SetItemText (BYVAL hwndHD AS HWND, BYVAL nItem AS LONG, BYVAL pwszText AS WSTRING PTR) AS BOOLEAN
   IF pwszText = NULL THEN EXIT FUNCTION
   DIM hdi AS HDITEMW
   hdi.mask = HDI_TEXT
   hdi.cchTextMax = LEN(*pwszText)
   hdi.pszText = pwszText
   FUNCTION = SendMessageW(hwndHD, HDM_SETITEMW, cast(WPARAM, nItem), cast(LPARAM, cast(HDITEMW PTR, @hdi)))
END FUNCTION
' ========================================================================================


' ########################################################################################
'                                    *** HOTKEY ***
' ########################################################################################

' ========================================================================================
' Gets the virtual key code and modifier flags of a hot key from a hot key control.
' Returns the virtual key code and modifier flags. The LOBYTE of the LOWORD is the virtual
' key code of the hot key. The HIBYTE of the LOWORD is the key modifier that specifies the
' keys that define a hot key combination. The modifier flags can be a combination of the
' following values:
'   HOTKEYF_ALT      ALT key
'   HOTKEYF_CONTROL  CONTROL key
'   HOTKEYF_EXT      Extended key
'   HOTKEYF_SHIFT    SHIFT key
' ========================================================================================
PRIVATE FUNCTION HotKey_GetHotKey (BYVAL hHotKey AS HWND) AS DWORD
   FUNCTION = SendMessageW(hHotKey, HKM_GETHOTKEY, 0, 0)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Sets the hot key combination for a hot key control.
' - vkCode: The virtual key code of the hot key.
' - fMods: The key modifier that indicates the keys that define a hot key combination.
' For a list of modifier flag values, see the description of the HotKey_GetHotKey function.
' ========================================================================================
PRIVATE SUB HotKey_SetHotKey (BYVAL hHotKey AS HWND, BYVAL vkCode AS SHORT, BYVAL fMods AS SHORT)
   SendMessageW(hHotKey, HKM_SETHOTKEY, MAKELONG(vkCode, fMods), 0)
END SUB
' ========================================================================================

' ========================================================================================
' Defines the invalid combinations and the default modifier combination for a hot key control.
' - fwCombInv: An array of flags that specify invalid key combinations. This parameter can be a combination
'   of the following values:
' Value Meaning
'   HKCOMB_A ALT
'   HKCOMB_C CTRL
'   HKCOMB_CA CTRL+ALT
'   HKCOMB_NONE Unmodified keys
'   HKCOMB_S SHIFT
'   HKCOMB_SA SHIFT+ALT
'   HKCOMB_SC SHIFT+CTRL
'   HKCOMB_SCA SHIFT+CTRL+ALT
' - fwModInv: An array of flags that specify the key combination to use when the user enters
'   an invalid combination. For a list of modifier flag values, see the description of the
'   HotKey_GetHotKey message.
' ========================================================================================
PRIVATE SUB HotKey_SetRules (BYVAL hHotKey AS HWND, BYVAL fwCombInv AS WORD, BYVAL fwModInv AS WORD)
   SendMessageW(hHotKey, HKM_SETRULES, cast(WPARAM, fwCombInv), cast(LPARAM, MAKELONG(fwModInv, 0)))
END SUB
' ========================================================================================


' ########################################################################################
'                                    *** SCROLLBAR ***
' ########################################################################################

' ========================================================================================
' Sets the minimum and maximum position values and redraws the control.
' Return value:
' ComCtl32.dll version 5.0: If the position of the scroll box changed, the return value is
' the previous position of the scroll box; otherwise, it is zero.
' ComCtl32.dll version 6.0: The current position of the scroll box, regardless of whether
' it has changed.
' ========================================================================================
PRIVATE FUNCTION ScrollBar_SetRangeRedraw (BYVAL hScrollBar AS HWND, BYVAL posMin AS LONG, BYVAL posMax AS LONG) AS LONG
   FUNCTION = SendMessageW(hScrollBar, SBM_SETRANGEREDRAW, cast(WPARAM, posMin), cast(LPARAM, posMax))
END FUNCTION
' ========================================================================================


' ########################################################################################
'                                    *** SYSLINK ***
' ########################################################################################

' ========================================================================================
' Retrieves the preferred height of a link for the control's current width.
' ========================================================================================
PRIVATE FUNCTION SysLink_GetIdealHeight (BYVAL hLM AS HWND) AS LONG
   FUNCTION = SendMessageW(hLM, LM_GETIDEALHEIGHT, 0, 0)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Retrieves the states and attributes of an item.
' Returns TRUE if the message succeeds in getting the values and attributes specified.
' ========================================================================================
PRIVATE FUNCTION Syslink_GetItem (BYVAL hLM AS HWND, BYVAL lpItem AS LITEM PTR) AS BOOLEAN
   FUNCTION = SendMessageW(hLM, LM_GETITEM, 0, cast(LPARAM, lpItem))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Determines if the user clicked the specified link.
' Returns TRUE if user clicked on a link, otherwise returns FALSE.
' ========================================================================================
PRIVATE FUNCTION SysLink_HitTest (BYVAL hLM AS HWND, BYVAL lphti AS LHITTESTINFO PTR) AS BOOLEAN
   FUNCTION = SendMessageW(hLM, LM_HITTEST, 0, cast(LPARAM, lphti))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Sets the states and attributes of an item.
' Returns TRUE if the message succeeds in setting the values and attributes specified.
' ========================================================================================
PRIVATE FUNCTION SysLink_SetItem (BYVAL hLM AS HWND, BYVAL lpItem AS LITEM PTR) AS BOOLEAN
   FUNCTION = SendMessageW(hLM, LM_SETITEM, 0, cast(LPARAM, lpItem))
END FUNCTION
' ========================================================================================


' ########################################################################################
'                                    *** LISTBOX ***
' ########################################################################################

' ========================================================================================
' Gets a string from a list box.
' - hComboBox: A handle to the list box.
' - nIndex: The zero-based index of the item.
' ========================================================================================
PRIVATE FUNCTION AfxGetListBoxText (BYVAL hListBox AS HWND, BYVAL nIndex AS LONG) AS CWSTR
   DIM nLen AS LONG = SendMessageW(hListBox, LB_GETTEXTLEN, nIndex, 0)
   DIM cwsText AS CWSTR = SPACE(nLen + 1)
   SendMessageW(hListBox, LB_GETTEXT, nIndex, cast(LPARAM, *cwsText))
   RETURN cwsText
END FUNCTION
' ========================================================================================

' ========================================================================================
' Adds the specified filename to a list box that contains a directory listing.
' The return value is the zero-based index of the file that was added, or LB_ERR if an error occurs.
' ========================================================================================
PRIVATE FUNCTION ListBox_AddFile (BYVAL hListBox AS HWND, BYVAL pwszFileName AS WSTRING PTR) AS LONG
   FUNCTION = SendMessageW(hListBox, LB_ADDFILE, 0, cast(LPARAM, pwszFileName))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Gets the index of the anchor item--that is, the item from which a multiple selection
' starts. A multiple selection spans all items from the anchor item to the caret item.
' The return value is the index of the anchor item.
' ========================================================================================
PRIVATE FUNCTION ListBox_GetAnchorIndex (BYVAL hListBox AS HWND) AS LONG
   FUNCTION = SendMessageW(hListBox, LB_GETANCHORINDEX, 0, 0)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Gets the number of items per column in a specified list box.
' ========================================================================================
PRIVATE FUNCTION Listbox_GetListboxInfo (BYVAL hListBox AS HWND) AS LONG
   FUNCTION = SendMessageW(hListBox, LB_GETLISTBOXINFO, 0, 0)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Gets the current locale of the list box. You can use the locale to determine the correct
' sorting order of displayed text (for list boxes with the LBS_SORT style) and of text
' added by the LB_ADDSTRING message.
' ========================================================================================
PRIVATE FUNCTION ListBox_GetLocale (BYVAL hListBox AS HWND) AS LONG
   FUNCTION = SendMessageW(hListBox, LB_GETLOCALE, 0, 0)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Allocates memory for storing list box items. This message is used before an application
' adds a large number of items to a list box. If the message is successful, the return
' value is the total number of items for which memory has been pre-allocated, that is, the
' total number of items added by all successful LB_INITSTORAGE messages. If the message
' fails, the return value is LB_ERRSPACE.
' ========================================================================================
PRIVATE FUNCTION Listbox_InitStorage (BYVAL hListBox AS HWND, BYVAL nItems AS DWORD, BYVAL nBytes AS DWORD) AS LONG
   FUNCTION = SendMessageW(hListBox, LB_INITSTORAGE, cast(WPARAM, nItems), cast(LPARAM, nBytes))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Gets the zero-based index of the item nearest the specified point in a list box.
' The return value contains the index of the nearest item in the LOWORD. The HIWORD is zero
' if the specified point is in the client area of the list box, or one if it is outside
' the client area.
' ========================================================================================
PRIVATE FUNCTION Listbox_ItemFromPoint (BYVAL hListBox AS HWND, BYVAL x AS SHORT, BYVAL y AS SHORT) AS LONG
   FUNCTION = SendMessageW(hListBox, LB_ITEMFROMPOINT, 0, cast(LPARAM, MAKELONG(x, y)))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Selects one or more consecutive items in a multiple-selection list box.
' If an error occurs, the return value is LB_ERR.
' ========================================================================================
PRIVATE FUNCTION Listbox_SelItemRangeEx (BYVAL hListBox AS HWND, BYVAL startIndex AS LONG, BYVAL endIndex AS LONG) AS LONG
   FUNCTION = SendMessageW(hListBox, LB_SELITEMRANGEEX, cast(WPARAM, startIndex), cast(LPARAM, endIndex))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Sets the anchor item--that is, the item from which a multiple selection starts.
' A multiple selection spans all items from the anchor item to the caret item.
' If the message succeeds, the return value is zero.
' If the message fails, the return value is LB_ERR.
' ========================================================================================
PRIVATE FUNCTION ListBox_SetAnchorIndex (BYVAL hListBox AS HWND, BYVAL index AS LONG) AS LONG
   FUNCTION = SendMessageW(hListBox, LB_SETANCHORINDEX, cast(WPARAM, index), 0)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Sets the count of items in a list box created with the LBS_NODATA style and not created
' with the LBS_HASSTRINGS style.
' ========================================================================================
PRIVATE FUNCTION Listbox_SetCount (BYVAL hListBox AS HWND, BYVAL nCount AS DWORD) AS LONG
   FUNCTION = SendMessageW(hListBox, LB_SETCOUNT, cast(WPARAM, nCount), 0)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Sets the current locale of the list box. You can use the locale to determine the correct
' sorting order of displayed text (for list boxes with the LBS_SORT style) and of text
' added by the LB_ADDSTRING message. If an error occurs, the return value is LB_ERR.
' If there is insufficient memory to store the items, the return value is LB_ERRSPACE.
' ========================================================================================
PRIVATE FUNCTION ListBox_SetLocale (BYVAL hListBox AS HWND, BYVAL wLocaleID AS DWORD) AS LONG
   FUNCTION = SendMessageW(hListBox, LB_SETLOCALE, cast(WPARAM, wLocaleID), 0)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Replaces a string, and his associated data, into a list box.
' The return value is the index of the position at which the string was inserted.
' If an error occurs, the return value is LB_ERR. If there is insufficient space to store
' the new string, the return value is LB_ERRSPACE.
' ========================================================================================
PRIVATE FUNCTION ListBox_ReplaceString (BYVAL hListBox AS HWND, BYVAL index AS LONG, BYVAL pwszNewText AS WSTRING PTR, BYVAL pNewData AS LONG_PTR = 0) AS LONG
   ' // Delete the string
   DIM lRes AS LRESULT = SendMessageW(hListBox, LB_DELETESTRING, index, 0)
   IF lRes = LB_ERR THEN RETURN lRes
   ' // Insert the new string
   index = SendMessageW(hListBox, LB_INSERTSTRING, index, CAST(LPARAM, pwszNewText))
   IF index = LB_ERR OR index = LB_ERRSPACE THEN Return index
   lRes = SendMessageW(hListBox, LB_SETITEMDATA, index, CAST(LPARAM, pNewData))
   IF lRes = LB_ERR THEN Return lRes
   FUNCTION = SendMessageW(hListBox, IIF((GetWindowLongPtrW(hListBox, GWL_STYLE) AND LBS_MULTIPLESEL), LB_SETSEL, LB_SETCURSEL), index, 0)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Calculates the size, in logical units, of the widest string item.
' ========================================================================================
PRIVATE FUNCTION Listbox_CalcHorizontalExtent (BYVAL hListBox AS HWND) AS LONG
   IF IsWindow(hListbox) = 0 THEN EXIT FUNCTION
   ' // Get an handle to the device context of the control
   DIM hDC AS HDC = GetDC(hListBox)
   ' // Get the number of items
   DIM i AS LONG, cxScrollWidth AS LONG
   DIM cItems AS LRESULT = SendMessageW(hListBox, LB_GETCOUNT, 0, 0)
   FOR i = 0 TO cItems - 1
      ' // Get the text of the item
      DIM cbLen AS LONG = SendMessageW(hListBox, LB_GETTEXTLEN, i, 0)
      IF cbLen = 0 THEN CONTINUE FOR
      DIM pbuffer AS WSTRING PTR = CAllocate(cbLen * 2)
      SendMessageW(hListBox, LB_GETTEXT, i, CAST(LPARAM, pbuffer))
      ' // Computes the width and height of the text
      DIM tsize AS SIZE
      GetTextExtentPoint32W hDC, pbuffer, cbLen, @tsize
      cxScrollWidth = MAX(cxScrollWidth, tsize.cx)
      Deallocate pbuffer
   NEXT
   ' // Release the device context
   ReleaseDC hListBox, hDC
   ' // Return the width of the text
   FUNCTION = cxScrollWidth
END FUNCTION
' ========================================================================================

' ########################################################################################
'                                    *** LISTVIEW ***
' ########################################################################################

' ========================================================================================
' Searches the listview for the specified string.
' Returns the index of the item if successful, or -1 otherwise.
' ========================================================================================
PRIVATE FUNCTION ListView_FindString (BYVAL hwndLV AS HWND, BYVAL pwszText AS WSTRING PTR) AS LONG
   DIM lvf AS LVFINDINFOW
   lvf.flags = LVFI_STRING
   lvf.psz = pwszText
   FUNCTION = SendMessageW(hwndLV, LVM_FINDITEMW, -1, cast(LPARAM, cast(LVFINDINFOW PTR, @lvf)))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Gets the item that has the focus, which may or may not be selected.
' Returns the index of the next item if successful, or -1 otherwise.
' ========================================================================================
PRIVATE FUNCTION ListView_GetFocusedItem (BYVAL hwndLV AS HWND) AS LONG
   FUNCTION = SendMessageW(hwndLV, LVM_GETNEXTITEM, -1, LVNI_ALL OR LVNI_FOCUSED)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Returns the number of characters in the incremental search string, not including the
' terminating NULL character, or zero if the list-view control is not in incremental search mode.
' ========================================================================================
PRIVATE FUNCTION ListView_GetISearchStringLen (BYVAL hwndLV AS HWND) AS LONG
   FUNCTION = SendMessageW(hwndLV, LVM_GETISEARCHSTRINGW, 0, NULL)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Determines which list-view item, if any, is at a specified position.
' ========================================================================================
PRIVATE FUNCTION ListView_HitTestEx (BYVAL hwndLV AS HWND, BYVAL pinfo AS LVHITTESTINFO PTR) AS LONG
   FUNCTION = SendMessageW(hwndLV, LVM_HITTEST, cast(WPARAM, -1), cast(LPARAM, pinfo))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Returns the zero-based index of the currently selected item.
' See the following Microsoft article: How To Select a Listview Item Programmatically
' http://support.microsoft.com/kb/131284
' ========================================================================================
PRIVATE FUNCTION ListView_GetSelection (BYVAL hwndLV AS HWND) AS LONG
   FUNCTION = SendMessageW(hwndLV, LVM_GETNEXTITEM, -1, LVNI_SELECTED)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Selects a ListView item.
' Windows does not provide a separate message or function to set the current selection in
' a listview. Instead, it defines item states or LVIS_* values that determine the listview
' item's appearance and functionality. LVIS_FOCUSED and LVIS_SELECTED in particular are
' the states that determine a listview item's selection state.
' Note that the last parameter passed to this macro is a mask specifying which bits are
' about to change. LVIS_FOCUSED and LVIS_SELECTED are defined in commctrl.inc as &H0001
' and &H0002 respectively, so you need to set the last four bits of the mask.
' See the following Microsoft article: How To Select a Listview Item Programmatically
' http://support.microsoft.com/kb/131284
' ========================================================================================
PRIVATE SUB ListView_SelectItem (BYVAL hwndLV AS HWND, BYVAL nIndex AS LONG)
   ListView_SetItemState(hwndLV, nIndex, LVIS_FOCUSED OR LVIS_SELECTED, &H000F)
END SUB
' ========================================================================================

' ========================================================================================
' Selects all the items.
' ========================================================================================
PRIVATE SUB ListView_SelectAllItems (BYVAL hwndLV AS HWND)
   DIM lvi AS LVITEMW
   lvi.mask = LVIF_STATE
   lvi.state = -1
   lvi.stateMask = LVIS_SELECTED
   SendMessageW(hwndLV, LVM_SETITEMSTATE, cast(WPARAM, -1), cast(LPARAM, cast(LVITEMW PTR, @lvi)))
END SUB
' ========================================================================================

' ========================================================================================
' Unselects an item in a ListView.
' ========================================================================================
PRIVATE SUB ListView_UnselectItem (BYVAL hwndLV AS HWND, BYVAL nIndex AS LONG)
   ListView_SetItemState(hwndLV, nIndex, 0, LVIS_SELECTED)
END SUB
' ========================================================================================

' ========================================================================================
' Unselects all items.
' ========================================================================================
PRIVATE SUB ListView_UnselectAllItems (BYVAL hwndLV AS HWND)
   ListView_SetItemState(hwndLV, -1, 0, LVIS_SELECTED OR LVIS_FOCUSED)
END SUB
' ========================================================================================

' ========================================================================================
' Removes the HDS_BUTTONS style from the header control to give it a flat appearance.
' ========================================================================================
PRIVATE SUB ListView_MakeHeaderFlat (BYVAL hwndLV AS HWND)
   DIM hLvHeader AS HWND = cast(HWND, SendMessageW(hwndLV, LVM_GETHEADER, 0, 0))
   IF hLvHeader = NULL THEN EXIT SUB
   SetWindowLongPtrW hLvHeader, GWL_STYLE, GetWindowLongPtrW(hLvHeader, GWL_STYLE) XOR HDS_BUTTONS
   SetWindowPos GetParent(hwndLV), NULL, 0, 0, 0, 0, SWP_NOZORDER OR SWP_NOMOVE OR SWP_NOSIZE OR SWP_DRAWFRAME
END SUB
' ========================================================================================

' ========================================================================================
' Automatically sizes the specified column. Returns TRUE or FALSE.
' ========================================================================================
PRIVATE FUNCTION ListView_FitContent (BYVAL hwndLV AS HWND, BYVAL nCol AS LONG) AS BOOLEAN
   FUNCTION = SendMessageW(hwndLV, LVM_SETCOLUMNWIDTH, cast(WPARAM, nCol), cast(LPARAM, LVSCW_AUTOSIZE))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Automatically sizes all the columns of a listview. Returns TRUE or FALSE.
' ========================================================================================
PRIVATE FUNCTION ListView_AutoSizeColumns (BYVAL hwndLV AS HWND) AS BOOLEAN
   DIM i AS LONG, nCount AS LONG, hLvHeader AS HWND
   hLvHeader = cast(HWND, SendMessageW(hwndLV, LVM_GETHEADER, 0, 0))
   IF hLvHeader = NULL THEN EXIT FUNCTION
   nCount = SendMessageW(hLvHeader, HDM_GETITEMCOUNT, 0, 0)
   FOR i = 0 TO nCount - 1
      FUNCTION = SendMessageW(hwndLV, LVM_SETCOLUMNWIDTH, cast(WPARAM, i), cast(LPARAM, LVSCW_AUTOSIZE))
   NEXT
END FUNCTION
' ========================================================================================

' ========================================================================================
' Automatically sizes the column to fit the header text. If you use this value with the
' last column, its width is set to fill the remaining width of the list-view control.
' Returns TRUE or FALSE.
' ========================================================================================
PRIVATE FUNCTION ListView_FitHeader (BYVAL hwndLV AS HWND, BYVAL nCol AS LONG) AS BOOLEAN
   FUNCTION = SendMessageW(hwndLV, LVM_SETCOLUMNWIDTH, cast(WPARAM, nCol), cast(LPARAM, LVSCW_AUTOSIZE_USEHEADER))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Automatically sizes all the columns of the header of a listview
' ========================================================================================
PRIVATE FUNCTION ListView_AutoSizeHeader (BYVAL hwndLV AS HWND) AS BOOLEAN
   DIM i AS LONG, nCount AS LONG, hLvHeader AS HWND
   hLvHeader = cast(HWND, SendMessageW(hwndLV, LVM_GETHEADER, 0, 0))
   IF hLvHeader = NULL THEN EXIT FUNCTION
   nCount = SendMessageW(hLvHeader, HDM_GETITEMCOUNT, 0, 0)
   FOR i = 0 TO nCount - 1
      FUNCTION = SendMessageW(hwndLV, LVM_SETCOLUMNWIDTH, cast(WPARAM, i), cast(LPARAM, LVSCW_AUTOSIZE_USEHEADER))
   NEXT
END FUNCTION
' ========================================================================================

' ========================================================================================
' Gets the number of columns of a listview.
' ========================================================================================
PRIVATE FUNCTION ListView_GetColumnCount (BYVAL hwndLV AS HWND) AS LONG
   DIM hLvHeader AS HWND = cast(HWND, SendMessageW(hwndLV, LVM_GETHEADER, 0, 0))
   IF hLvHeader = NULL THEN EXIT FUNCTION
   FUNCTION = SendMessageW(hLvHeader, HDM_GETITEMCOUNT, 0, 0)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Gets the order of the specified column of the listview's header control.
' ========================================================================================
PRIVATE FUNCTION ListView_GetColumnOrder (BYVAL hwndLV AS HWND, BYVAL nCol AS LONG) AS LONG
   DIM hLvHeader AS HWND = cast(HWND, SendMessageW(hwndLV, LVM_GETHEADER, 0, 0))
   IF hLvHeader = NULL THEN EXIT FUNCTION
   DIM hdi AS HDITEMW
   hdi.mask = HDI_ORDER
   IF SendMessageW(hLvHeader, HDM_GETITEM, cast(WPARAM, nCol), cast(LPARAM, cast(HDITEMW PTR, @hdi))) THEN FUNCTION = hdi.iOrder
END FUNCTION
' ========================================================================================

' ========================================================================================
' Gets the current left-to-right order of items in the header of a listview control.
' ========================================================================================
PRIVATE FUNCTION ListView_GetOrderArray (BYVAL hwndLV AS HWND, BYVAL nSize AS DWORD, BYVAL lpiArray AS LONG PTR) AS LONG
   DIM hLvHeader AS HWND = cast(HWND, SendMessageW(hwndLV, LVM_GETHEADER, 0, 0))
   IF hLvHeader = NULL THEN EXIT FUNCTION
   FUNCTION = SendMessageW(hLvHeader, HDM_GETORDERARRAY, cast(WPARAM, nSize), cast(LPARAM, lpiArray))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Retrieves the font used by the ToolTip control that the list-view control uses to display ToolTips.
' The return value is a handle to the font used by the control, or NULL if the control is
' using the system font.
' ========================================================================================
PRIVATE FUNCTION ListView_GetTooltipsFont (BYVAL hwndLV AS HWND) AS HFONT
   DIM hwndTooltips AS HWND = cast(HWND, SendMessageW(hwndLV, LVM_GETTOOLTIPS, 0, 0))
   FUNCTION = cast(HFONT, SendMessageW(hwndTooltips, WM_GETFONT, 0, 0))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Sets the font used by the ToolTip control that the list-view control uses to display ToolTips.
' Parameters:
' - hwndLV  = Handle to the ListView control.
' - hFont   = Handle to the font. If this parameter is NULL, the control uses the default system font to draw text.
' - fRedraw = Specifies whether the control should be redrawn immediately upon setting the font.
'             If this parameter is TRUE, the control redraws itself.
' ========================================================================================
PRIVATE SUB ListView_SetTooltipsFont (BYVAL hwndLV AS HWND, BYVAL hFont AS HFONT = NULL, BYVAL fRedraw AS BOOLEAN = FALSE)
   DIM hwndTooltips AS HWND = cast(HWND, SendMessageW(hwndLV, LVM_GETTOOLTIPS, 0, 0))
   IF hwndTooltips = NULL THEN EXIT SUB
   SendMessageW(hwndTooltips, WM_SETFONT, cast(WPARAM, hFont), cast(LPARAM, fRedraw))
END SUB
' ========================================================================================

' ========================================================================================
' Retrieves the text of the specified column. Returns TRUE or FALSE.
' - hwndLV: Handle to the listview control.
' - nCol: Zero-based index of the column
' - pwszText: A pointer to a buffer to receive the retrieved text.
' - cchTextMax : Maximum number of characters to return. Both this value and the size of the
'   buffer pointed by pwszText must be one character bigger that the wanted length of the text
'   to return to make room for the null character terminator.
' Return value: TRUE or FALSE.
' ========================================================================================
PRIVATE FUNCTION ListView_GetColumnText (BYVAL hwndLV AS HWND, BYVAL nCol AS LONG, BYVAL pwszText AS WSTRING PTR, BYVAL cchTextMax AS LONG) AS BOOLEAN
   IF pwszText = NULL THEN EXIT FUNCTION
   DIM lvc AS LVCOLUMNW
   lvc.mask = LVCF_TEXT
   lvc.cchTextMax = cchTextMax
   lvc.pszText = pwszText
   FUNCTION = SendMessageW(hwndLV, LVM_GETCOLUMNW, cast(WPARAM, nCol), cast(LPARAM, cast(LVCOLUMNW PTR, @lvc)))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Retrieves the text of a list-view item or subitem.
' - hwndLV: Handle to the ListView control.
' - nCol: Zero-based index of the column
' - pwszText: A pointer to a buffer that receives the item or subitem text.
' - cchTextMax : Maximum number of characters to return. Both this value and the size of the
'   buffer pointed by pwszText must be one character bigger that the wanted length of the text
'   to return to make room for the null character terminator.
' Returns the number of characters in the pszText member of the LVITEM structure.
' ========================================================================================
PRIVATE FUNCTION ListView_GetHeaderText (BYVAL hwndLV AS HWND, BYVAL nCol AS LONG, BYVAL pwszText AS WSTRING PTR, BYVAL cchTextMax AS LONG) AS LONG
   DIM hLvHeader AS HWND = cast(HWND, SendMessageW(hwndLV, LVM_GETHEADER, 0, 0))
   IF hLvHeader = NULL THEN EXIT FUNCTION
   DIM hdi AS HDITEMW
   hdi.mask = HDI_TEXT
   hdi.cchTextMax = cchTextMax
   hdi.pszText = pwszText
   FUNCTION = SendMessageW(hLvHeader, HDM_GETITEMW, cast(WPARAM, nCol), cast(LPARAM, cast(HDITEMW PTR, @hdi)))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Inserts a new column in a list-view control.
' - hwndLV: Handle to the ListView control.
' - nCol: Index of the new column.
' - pwszText: The column header text.
' - nWidth: The width of the column, in pixels.
' - nFormat: Alignment of the column header and the subitem text in the column.
'   The alignment of the leftmost column is always left-justified; it cannot be changed.
'   This member can be one of the following values:
'   see https://msdn.microsoft.com/en-us/library/windows/desktop/bb774743%28v=vs.85%29.aspx
' Returns the index of the new column if successful, or -1 otherwise.
' ========================================================================================
PRIVATE FUNCTION ListView_AddColumn (BYVAL hwndLV AS HWND, BYVAL nCol AS LONG, BYVAL pwszText AS WSTRING PTR, BYVAL nWidth AS LONG, BYVAL nFormat AS LONG = 0) AS LONG
   DIM lvc AS LVCOLUMNW
   lvc.mask = LVCF_FMT OR LVCF_WIDTH OR LVCF_TEXT OR LVCF_SUBITEM
   lvc.fmt = nFormat
   lvc.pszText = pwszText
   lvc.cx = nWidth
   lvc.iSubItem = nCol
   FUNCTION = SendMessageW(hwndLV, LVM_INSERTCOLUMNW, cast(WPARAM, nCol), cast(LPARAM, cast(LVCOLUMNW PTR, @lvc)))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Inserts a new item in a list-view control.
' - hwndLV: Handle to the ListView control.
' - nItem: Zero-based index at which the new item should be inserted. If this value is
'   greater than the number of items currently contained by the listview control, the new
'   item will be appended to the end of the list and assigned the correct index. Examine the
'   return value to determine the actual index assigned to the item.
' - nImage: Zero-based index of the item's icon in the control's image list.
' - pwszText: The item text.
' Returns the index of the new item if successful, or -1 otherwise.
' ========================================================================================
PRIVATE FUNCTION ListView_AddItem (BYVAL hwndLV AS HWND, BYVAL nItem AS LONG, BYVAL nImage AS LONG, BYVAL pwszText AS WSTRING PTR) AS LONG
   DIM lvi AS LVITEMW
   lvi.mask = LVIF_TEXT
   lvi.pszText = pwszText
   lvi.iItem = nItem
   lvi.iImage = nImage
   FUNCTION = SendMessageW(hwndLV, LVM_INSERTITEMW, cast(WPARAM, nItem), cast(LPARAM, cast(LVITEMW PTR, @lvi)))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Appends a new item in a list-view control.
' - hwndLV: Handle to the ListView control.
' - nImage: Zero-based index of the item's icon in the control's image list.
' - pwszText: The item text.
' Returns the index of the new item if successful, or -1 otherwise.
' ========================================================================================
PRIVATE FUNCTION ListView_AppendItem (BYVAL hwndLV AS HWND, BYVAL nImage AS LONG, BYVAL pwszText AS WSTRING PTR) AS LONG
   DIM lvi AS LVITEMW
   DIM nItem AS LONG = SendMessageW(hwndLV, LVM_GETITEMCOUNT, 0, 0)
   lvi.mask = LVIF_TEXT
   lvi.pszText = pwszText
   lvi.iItem = nItem
   lvi.iImage = nImage
   FUNCTION = SendMessageW(hwndLV, LVM_INSERTITEMW, cast(WPARAM, nItem), cast(LPARAM, cast(LVITEMW PTR, @lvi)))
END FUNCTION
' ========================================================================================


' ########################################################################################
'                                      *** REBAR ***
' ########################################################################################

' ========================================================================================
' Puts the rebar control in drag-and-drop mode.
' ========================================================================================
PRIVATE SUB Rebar_BeginDrag (BYVAL hRebar AS HWND, BYVAL uBand AS DWORD, BYVAL dwPos AS DWORD)
   SendMessageW(hRebar, RB_BEGINDRAG, cast(WPARAM, uBand), cast(LPARAM, dwPos))
END SUB
' ========================================================================================

' ========================================================================================
' Deletes a band from a rebar control. Returns TRUE or FALSE.
' ========================================================================================
PRIVATE FUNCTION Rebar_DeleteBand (BYVAL hRebar AS HWND, BYVAL uBand AS DWORD) AS BOOLEAN
   FUNCTION = SendMessageW(hRebar, RB_DELETEBAND, cast(WPARAM, uBand), 0)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Updates the drag position in the rebar control after a previous RB_BEGINDRAG message.
' ========================================================================================
PRIVATE SUB Rebar_DragMove (BYVAL hRebar AS HWND, BYVAL dwPos AS DWORD)
   SendMessageW(hRebar, RB_DRAGMOVE, 0, cast(LPARAM, dwPos))
END SUB
' ========================================================================================

' ========================================================================================
' Terminates the rebar control's drag-and-drop operation. This message does not cause an
' RBN_ENDDRAG notification to be sent.
' ========================================================================================
PRIVATE SUB Rebar_EndDrag (BYVAL hRebar AS HWND)
   SendMessageW(hRebar, RB_ENDDRAG, 0, 0)
END SUB
' ========================================================================================

' ========================================================================================
' Retrieves the borders of a band. The result of this message can be used to calculate the
' usable area in a band.
' ========================================================================================
PRIVATE SUB Rebar_GetBandBorders (BYVAL hRebar AS HWND, BYVAL uBand AS DWORD, BYVAL lprc AS RECT PTR)
   SendMessageW(hRebar, RB_GETBANDBORDERS, cast(WPARAM, uBand), cast(LPARAM, lprc))
END SUB
' ========================================================================================

' ========================================================================================
' Retrieves the bounding rectangle of a part in a status window.
' Parameters:
' - hRebarBar = Handle of the rebar control. It can belong to another application.
' - nBand = Zero-based index of the band for which the borders will be retrieved.
' Return value: A RECT structure with the band border.
'   If the rebar control has the RBS_BANDBORDERS style, each member of this structure will
'   receive the number of pixels, on the corresponding side of the band, that constitute
'   the border. If the rebar control does not have the RBS_BANDBORDERS style, only the left
'   member of this structure receives valid information.
' Remarks: The purpose of this function is to demonstrate how to retrieve information from
' a rebar control belonging to another application.
' ========================================================================================
PRIVATE FUNCTION AfxGetRebarBandRect (BYVAL hRebar AS HWND, BYVAL nBand AS LONG) AS RECT
   DIM idProc AS DWORD, hProcess AS HANDLE, pRbRect AS ANY PTR, rc AS RECT, cbBytesRead AS SIZE_T
   GetWindowThreadProcessId(hRebar, @idProc)
   IF idProc = 0 THEN EXIT FUNCTION
   hProcess = OpenProcess(PROCESS_VM_OPERATION OR PROCESS_VM_READ OR PROCESS_VM_WRITE OR _
              PROCESS_QUERY_INFORMATION, FALSE, idProc)
   IF hProcess = NULL THEN EXIT FUNCTION
   pRbRect = VirtualAllocEx(hProcess, NULL, SIZEOF(RECT), MEM_COMMIT, PAGE_READWRITE)
   IF pRbRect THEN
      SendMessageW(hRebar, RB_GETBANDBORDERS, nBand, cast(LPARAM, pRbRect))
      ReadProcessMemory(hProcess, pRbRect, @rc, SIZEOF(rc), @cbBytesRead)
      VirtualFreeEx(hProcess, pRbRect, 0, MEM_RELEASE)
   END IF
   CloseHandle(hProcess)
   FUNCTION = rc
END FUNCTION
' ========================================================================================

' ========================================================================================
' Retrieves the count of bands currently in the rebar control.
' ========================================================================================
PRIVATE FUNCTION Rebar_GetBandCount (BYVAL hRebar AS HWND) AS DWORD
   FUNCTION = SendMessageW(hRebar, RB_GETBANDCOUNT, 0, 0)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Retrieves information about a specified band in a rebar control.
' Returns TRUE or FALSE.
' ========================================================================================
PRIVATE FUNCTION Rebar_GetBandInfo (BYVAL hRebar AS HWND, BYVAL uBand AS DWORD, BYVAL lprbbi AS REBARBANDINFOW PTR) AS BOOLEAN
   FUNCTION = SendMessageW(hRebar, RB_GETBANDINFO, cast(WPARAM, uBand), cast(LPARAM, lprbbi))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Retrieves information about the specified band of the Rebar control
' Parameters:
' - hRebar : Handle to the rebar control. Can belong to another application.
' - nBand : Zero-based index of the band for which the information will be retrieved.
' Return value:
'   A REBARBANDINFOW structure with the band information.
' Remarks: The purpose of this function is to demonstrate howto retrieve information from
' a rebar control belonging to another application.
' ========================================================================================
PRIVATE FUNCTION AfxGetRebarBandInfo (BYVAL hRebar AS HWND, BYVAL nBand AS LONG) AS REBARBANDINFOW
   DIM idProc AS DWORD, hProcess AS HANDLE, pInfo AS ANY PTR, cbBytesRead AS SIZE_T
   DIM rbbi AS REBARBANDINFOW
   IF AfxWindowsVersion >= 600 AND AfxComCtlVersion >= 600 THEN
      rbbi.cbSize  = REBARBANDINFO_V6_SIZE
   ELSE
      rbbi.cbSize  = REBARBANDINFO_V3_SIZE
   END IF
   rbbi.fMask = RBBIM_BACKGROUND OR RBBIM_CHILD OR RBBIM_CHILDSIZE OR RBBIM_COLORS OR RBBIM_ID OR _
                RBBIM_HEADERSIZE OR RBBIM_IDEALSIZE OR RBBIM_IMAGE OR RBBIM_SIZE OR RBBIM_STYLE OR RBBIM_TEXT
   GetWindowThreadProcessId(hRebar, @idProc)
   IF idProc = 0 THEN EXIT FUNCTION
   hProcess = OpenProcess(PROCESS_VM_OPERATION OR PROCESS_VM_READ OR PROCESS_VM_WRITE OR _
              PROCESS_QUERY_INFORMATION, FALSE, idProc)
   IF hProcess = NULL THEN EXIT FUNCTION
   pInfo = VirtualAllocEx(hProcess, NULL, SIZEOF(REBARBANDINFOW), MEM_COMMIT, PAGE_READWRITE)
   IF pInfo THEN
      WriteProcessMemory(hProcess, pInfo, @rbbi, SIZEOF(REBARBANDINFOW), NULL)
      IF SendMessageW(hRebar, RB_GETBANDINFOW, CAST(WPARAM, nBand), CAST(LPARAM, pInfo)) THEN
         ReadProcessMemory(hProcess, pInfo, @rbbi, SIZEOF(rbbi), @cbBytesRead)
      END IF
      VirtualFreeEx(hProcess, pInfo, 0, MEM_RELEASE)
   END IF
   CloseHandle(hProcess)
   FUNCTION = rbbi
END FUNCTION
' ========================================================================================

' ========================================================================================
' Retrieves the margins of a band.
' ========================================================================================
PRIVATE SUB Rebar_GetBandMargins (BYVAL hRebar AS HWND, BYVAL pMargins AS MARGINS PTR)
   SendMessageW(hRebar, RB_GETBANDMARGINS, 0, cast(LPARAM, pMargins))
END SUB
' ========================================================================================

' ========================================================================================
' Retrieves the height of the rebar control.
' ========================================================================================
PRIVATE FUNCTION Rebar_GetBarHeight (BYVAL hRebar AS HWND) AS DWORD
   FUNCTION = SendMessageW(hRebar, RB_GETBARHEIGHT, 0, 0)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Retrieves information about the rebar control and the image list it uses.
' Return value: Returns TRUE or FALSE.
' ========================================================================================
PRIVATE FUNCTION Rebar_GetBarInfo (BYVAL hRebar AS HWND, BYVAL lprbi AS REBARINFO PTR) AS BOOLEAN
   FUNCTION = SendMessageW(hRebar, RB_GETBARINFO, 0, cast(LPARAM, lprbi))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Retrieves a rebar control's default background color.
' ========================================================================================
PRIVATE FUNCTION Rebar_GetBkColor (BYVAL hRebar AS HWND) AS COLORREF
   FUNCTION = SendMessageW(hRebar, RB_GETBKCOLOR, 0, 0)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Retrieves the color scheme information from the rebar control.
' Return value: Returns TRUE or FALSE.
' ========================================================================================
PRIVATE FUNCTION Rebar_GetColorScheme (BYVAL hRebar AS HWND, BYVAL lpcs AS COLORSCHEME PTR) AS BOOLEAN
   FUNCTION = SendMessageW(hRebar, RB_GETCOLORSCHEME, 0, cast(LPARAM, lpcs))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Retrieves a rebar control's IDropTarget interface pointer.
' ========================================================================================
PRIVATE FUNCTION Rebar_GetDropTarget (BYVAL hRebar AS HWND) AS IDropTarget PTR
   DIM ppIDropTarget AS IDropTarget PTR
   SendMessageW(hRebar, RB_GETDROPTARGET, 0, CAST(LPARAM, @ppIDropTarget))
   FUNCTION = ppIDropTarget
END FUNCTION
' ========================================================================================

' ========================================================================================
' Gets the extended style.
' ========================================================================================
PRIVATE FUNCTION Rebar_GetExtendedStyle (BYVAL hRebar AS HWND) AS DWORD
   FUNCTION = SendMessageW(hRebar, RB_GETEXTENDEDSTYLE, 0, 0)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Retrieves the rebar control's current palette.
' ========================================================================================
PRIVATE FUNCTION Rebar_GetPalette (BYVAL hRebar AS HWND) AS DWORD
   FUNCTION = SendMessageW(hRebar, RB_GETPALETTE, 0, 0)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Retrieves the bounding rectangle for a given band in a rebar control.
' Return value: Returns TRUE or FALSE.
' ========================================================================================
PRIVATE FUNCTION Rebar_GetRect (BYVAL hRebar AS HWND, BYVAL uBand AS DWORD, BYVAL lprc AS RECT PTR) AS BOOLEAN
   FUNCTION = SendMessageW(hRebar, RB_GETRECT, cast(WPARAM, uBand), cast(LPARAM, lprc))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Retrieves the number of rows of bands in a rebar control.
' ========================================================================================
PRIVATE FUNCTION Rebar_GetRowCount (BYVAL hRebar AS HWND) AS DWORD
   FUNCTION = SendMessageW(hRebar, RB_GETROWCOUNT, 0, 0)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Retrieves the height of a specified row in a rebar control.
' ========================================================================================
PRIVATE FUNCTION Rebar_GetRowHeight (BYVAL hRebar AS HWND, BYVAL uRow AS DWORD) AS DWORD
   FUNCTION = SendMessageW(hRebar, RB_GETROWHEIGHT, cast(WPARAM, uRow), 0)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Retrieves a rebar control's default text color.
' ========================================================================================
PRIVATE FUNCTION Rebar_GetTextColor (BYVAL hRebar AS HWND) AS COLORREF
   FUNCTION = SendMessageW(hRebar, RB_GETTEXTCOLOR, 0, 0)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Retrieves the handle to any ToolTip control associated with the rebar control.
' ========================================================================================
PRIVATE FUNCTION Rebar_GetTooltips (BYVAL hRebar AS HWND) AS HWND
   FUNCTION = cast(HWND, SendMessageW(hRebar, RB_GETTOOLTIPS, 0, 0))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Retrieves the Unicode character format flag for the control.
' ========================================================================================
PRIVATE FUNCTION Rebar_GetUnicodeFormat (BYVAL hRebar AS HWND) AS LONG
   FUNCTION = SendMessageW(hRebar, RB_GETUNICODEFORMAT, 0, 0)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Determines which portion of a rebar band is at a given point on the screen, if a rebar
' band exists at that point.
' - hRebar: Pointer to the rebar control.
' - lprhbt: Pointer to an RBHITTESTINFO structure. Before sending the message, the pt member
'   of this structure must be initialized to the point that will be hit tested, in client coordinates.
' Returns the zero-based index of the band at the given point, or -1 if no rebar band was at the point.
' ========================================================================================
PRIVATE FUNCTION Rebar_HitTest (BYVAL hRebar AS HWND, BYVAL lprhbt AS RBHITTESTINFO PTR) AS LONG
   FUNCTION = SendMessageW(hRebar, RB_HITTEST, 0, cast(LPARAM, lprhbt))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Converts a band identifier to a band index in a rebar control.
' Returns the zero-based band index if successful, or -1 otherwise. If duplicate band
' identifiers exist, the first one is returned.
' ========================================================================================
PRIVATE FUNCTION Rebar_IdToIndex (BYVAL hRebar AS HWND, BYVAL uBandID AS DWORD) AS LONG
   FUNCTION = SendMessageW(hRebar, RB_IDTOINDEX, cast(WPARAM, uBandID), 0)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Inserts a new band in a rebar control.
' ========================================================================================
PRIVATE FUNCTION Rebar_InsertBand (BYVAL hRebar AS HWND, BYVAL nIndex AS LONG, BYVAL lprbbi AS REBARBANDINFOW PTR) AS BOOLEAN
   FUNCTION = SendMessageW(hRebar, RB_INSERTBAND, cast(WPARAM, nIndex), cast(LPARAM, lprbbi))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Resizes a band in a rebar control to either its ideal or largest size.
' ========================================================================================
PRIVATE SUB Rebar_MaximizeBand (BYVAL hRebar AS HWND, BYVAL uBand AS DWORD, BYVAL fIdeal AS DWORD)
   SendMessageW(hRebar, RB_MAXIMIZEBAND, cast(WPARAM, uBand), cast(LPARAM, fIdeal))
END SUB
' ========================================================================================

' ========================================================================================
' Resizes a band in a rebar control to its smallest size.
' ========================================================================================
PRIVATE SUB Rebar_MinimizeBand (BYVAL hRebar AS HWND, BYVAL uBand AS DWORD)
  SendMessageW(hRebar, RB_MINIMIZEBAND, cast(WPARAM, uBand), 0)
END SUB
' ========================================================================================

' ========================================================================================
' Moves a band from one index to another. Returns TRUE or FALSE.
' ========================================================================================
PRIVATE FUNCTION Rebar_MoveBand (BYVAL hRebar AS HWND, BYVAL nFrom AS DWORD, BYVAL nTo AS DWORD) AS BOOLEAN
   FUNCTION = SendMessageW(hRebar, RB_MOVEBAND, cast(WPARAM, nFrom), cast(LPARAM, nTo))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Sent to a rebar control to programmatically push a chevron.
' ========================================================================================
PRIVATE SUB Rebar_PushChevron (BYVAL hRebar AS HWND, BYVAL uBand AS DWORD, BYVAL iAppValue AS DWORD)
   SendMessageW(hRebar, RB_PUSHCHEVRON, cast(WPARAM, uBand), cast(LPARAM, iAppValue))
END SUB
' ========================================================================================

' ========================================================================================
' Sets characteristics of an existing band in a rebar control. Returns TRUE or FALSE.
' ========================================================================================
PRIVATE FUNCTION Rebar_SetBandInfo (BYVAL hRebar AS HWND, BYVAL uBand AS DWORD, BYVAL lprbbi AS REBARBANDINFOW PTR) AS BOOLEAN
   FUNCTION = SendMessageW(hRebar, RB_SETBANDINFO, cast(WPARAM, uBand), cast(LPARAM, lprbbi))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Sets the characteristics of a rebar control. Returns TRUE or FALSE.
' ========================================================================================
#if _WIN32_WINNT = &h0602
PRIVATE FUNCTION Rebar_SetBandWidth (BYVAL hRebar AS HWND, BYVAL uBand AS DWORD, BYVAL nWidth AS DWORD) AS BOOLEAN
   FUNCTION = SendMessageW(hRebar, RB_SETBANDWIDTH, cast(WPARAM, uBand), cast(LPARAM, nWidth))
END FUNCTION
#endif
' ========================================================================================

' ========================================================================================
' Sets the characteristics of a rebar control. Returns TRUE or FALSE.
' ========================================================================================
PRIVATE FUNCTION Rebar_SetBarInfo (BYVAL hRebar AS HWND, BYVAL lprbi AS REBARINFO PTR) AS BOOLEAN
   FUNCTION = SendMessageW(hRebar, RB_SETBARINFO, 0, cast(LPARAM, lprbi))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Sets a rebar control's default background color.
' Returns a COLORREF value that represents the previous default background color.
' ========================================================================================
PRIVATE FUNCTION Rebar_SetBkColor (BYVAL hRebar AS HWND, BYVAL clrBk AS DWORD) AS DWORD
   FUNCTION = SendMessageW(hRebar, RB_SETBKCOLOR, 0, cast(LPARAM, clrBk))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Sets the color scheme information for the rebar control.
' ========================================================================================
PRIVATE SUB Rebar_SetColorScheme (BYVAL hRebar AS HWND, BYVAL lpcs AS COLORSCHEME PTR)
   SendMessageW(hRebar, RB_SETCOLORSCHEME, 0, cast(LPARAM, lpcs))
END SUB
' ========================================================================================

' ========================================================================================
' Sets the rebar control's current palette.
' Returns an HPALETTE that specifies the rebar control's previous palette.
' ========================================================================================
PRIVATE FUNCTION Rebar_SetPalette (BYVAL hRebar AS HWND, BYVAL hpal AS HPALETTE) AS HPALETTE
   FUNCTION = cast(HPALETTE, SendMessageW(hRebar, RB_SETPALETTE, 0, cast(LPARAM, hpal)))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Sets a rebar control's parent window.
' Returns the handle to the previous parent window, or NULL if there is no previous parent.
' ========================================================================================
PRIVATE FUNCTION Rebar_SetParent (BYVAL hRebar AS HWND, BYVAL hwndParent AS hWND) AS HWND
   FUNCTION = cast(HWND, SendMessageW(hRebar, RB_SETPARENT, cast(WPARAM, hwndParent), 0))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Sets a rebar control's default text color.
' Returns a COLORREF value that represents the previous default text color.
' ========================================================================================
PRIVATE FUNCTION Rebar_SetTextColor (BYVAL hRebar AS HWND, BYVAL clrText AS COLORREF) AS COLORREF
   FUNCTION = SendMessageW(hRebar, RB_SETTEXTCOLOR, 0, cast(LPARAM, clrText))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Associates a tooltip control with the rebar control.
' ========================================================================================
PRIVATE SUB Rebar_SetTooltips (BYVAL hRebar AS HWND, BYVAL hwndToolTip AS HWND)
   SendMessageW(hRebar, RB_SETTOOLTIPS, cast(WPARAM, hwndToolTip), 0)
END SUB
' ========================================================================================

' ========================================================================================
' Sets the Unicode character format flag for the control. This message allows you to
' change the character set used by the control at run time rather than having to re-create
' the control. Returns the previous Unicode format flag for the control.
' ========================================================================================
PRIVATE FUNCTION Rebar_SetUnicodeFormat (BYVAL hRebar AS HWND, BYVAL fUnicode AS DWORD) AS DWORD
   FUNCTION = SendMessageW(hRebar, RB_SETUNICODEFORMAT, cast(WPARAM, fUnicode), 0)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Sets the visual style of a rebar control.
' ========================================================================================
PRIVATE SUB Rebar_SetWindowTheme (BYVAL hRebar AS HWND, BYVAL pwszTheme AS WSTRING PTR)
   SendMessageW(hRebar, RB_SETWINDOWTHEME, 0, cast(LPARAM, pwszTheme))
END SUB
' ========================================================================================

' ========================================================================================
' Shows or hides a given band in a rebar control. Returns TRUE or FALSE.
' ========================================================================================
PRIVATE FUNCTION Rebar_ShowBand (BYVAL hRebar AS HWND, BYVAL uBand AS DWORD, BYVAL fShow AS DWORD) AS BOOLEAN
   FUNCTION = SendMessageW(hRebar, RB_SHOWBAND, cast(WPARAM, uBand), cast(LPARAM, fShow))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Attempts to find the best layout of the bands for the given rectangle. Returns TRUE or FALSE.
' ========================================================================================
PRIVATE FUNCTION Rebar_SizeToRect (BYVAL hRebar AS HWND, BYVAL prc AS RECT PTR) AS BOOLEAN
   FUNCTION = SendMessageW(hRebar, RB_SIZETORECT, 0, cast(LPARAM, prc))
END FUNCTION
' ========================================================================================


' ########################################################################################
'                                     *** STATIC ***
' ########################################################################################

' ========================================================================================
' Associates a new image with a static control.
' The return value is a handle to the image previously associated with the static control,
' if any; otherwise, it is NULL.
' To associate an image with a static control, the control must have the proper style. The
' following table shows the style needed for each image type.
' Image type          Static control style
'   IMAGE_BITMAP      SS_BITMAP
'   IMAGE_CURSOR      SS_ICON
'   IMAGE_ENHMETAFILE SS_ENHMETAFILE
'   IMAGE_ICON        SS_ICON
' ========================================================================================
PRIVATE FUNCTION Static_SetImage (BYVAL hStatic AS HWND, BYVAL nType AS LONG, BYVAL hImage AS HANDLE) AS HANDLE
   FUNCTION = cast(HANDLE, SendMessageW(hStatic, STM_SETIMAGE, cast(WPARAM, nType), cast(LPARAM, hImage)))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Deletes an image associated with an static control. Returns TRUE or FALSE.
' ========================================================================================
PRIVATE FUNCTION Static_DeleteImage (BYVAL hStatic AS HWND, BYVAL nType AS LONG) AS BOOLEAN
   FUNCTION = DeleteObject(cast(HGDIOBJ, SendMessageW(hStatic, STM_SETIMAGE, cast(WPARAM, nType), 0)))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Retrieves a handle to the image (icon or bitmap) associated with a static control.
' The return value is a handle to the image, if any; otherwise, it is NULL.
' ========================================================================================
PRIVATE FUNCTION Static_GetImage (BYVAL hStatic AS HWND, BYVAL nType AS LONG) AS HANDLE
   FUNCTION = cast(HANDLE, SendMessageW(hStatic, STM_GETIMAGE, nType, 0))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Associates a bitmap with an static control.
' The return value is a handle to the image previously associated with the static control,
' if any; otherwise, it is NULL.
' ========================================================================================
PRIVATE FUNCTION Static_SetBitmap (BYVAL hStatic AS HWND, BYVAL hBitmap AS HBITMAP) AS HBITMAP
   FUNCTION = cast(HBITMAP, SendMessageW(hStatic, STM_SETIMAGE, cast(WPARAM, IMAGE_BITMAP), cast(LPARAM, hBitmap)))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Deletes an icon associated with an static control. Returns TRUE o FALSE.
' ========================================================================================
PRIVATE FUNCTION Static_DeleteIcon (BYVAL hStatic AS HWND) AS BOOLEAN
   FUNCTION = DeleteObject(cast(HGDIOBJ, SendMessageW(hStatic, STM_SETICON, 0, 0)))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Deletes a bitmap associated with an static control. Returns TRUE o FALSE.
' ========================================================================================
PRIVATE FUNCTION Static_DeleteBitmap (BYVAL hStatic AS HWND) AS BOOLEAN
   FUNCTION = DeleteObject(cast(HGDIOBJ, SendMessageW(hStatic, STM_SETIMAGE, cast(WPARAM, IMAGE_BITMAP), 0)))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Associates a cursor with an static control.
' The return value is a handle to the cursor previously associated with the static control,
' ========================================================================================
PRIVATE FUNCTION Static_SetCursor (BYVAL hStatic AS HWND, BYVAL hCursor AS HCURSOR) AS HCURSOR
   FUNCTION = cast(HCURSOR, SendMessageW(hStatic, STM_SETIMAGE, cast(WPARAM, IMAGE_CURSOR), cast(LPARAM, hCursor)))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Deletes a cursor associated with an static control. Returns TRUE or FALSE.
' ========================================================================================
PRIVATE FUNCTION Static_DeleteCursor (BYVAL hStatic AS HWND) AS BOOLEAN
   FUNCTION = DeleteObject(cast(HGDIOBJ, SendMessageW(hStatic, STM_SETIMAGE, cast(WPARAM, IMAGE_CURSOR), 0)))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Associates an enhanced metafile with an static control.
' The return value is a handle to the image previously associated with the static control,
' if any; otherwise, it is NULL.
' ========================================================================================
PRIVATE FUNCTION Static_SetEnhancedMetafile (BYVAL hStatic AS HWND, BYVAL hEnhMetafile AS HENHMETAFILE) AS HENHMETAFILE
   FUNCTION = cast(HENHMETAFILE, SendMessageW(hStatic, STM_SETIMAGE, cast(WPARAM, IMAGE_ENHMETAFILE), cast(LPARAM, hEnhMetafile)))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Deletes a cursor associated with an static control. Returns TRUE or FALSE.
' ========================================================================================
PRIVATE FUNCTION Static_DeleteEnhancedMetafile (BYVAL hStatic AS HWND) AS BOOLEAN
   FUNCTION = DeleteObject(cast(HGDIOBJ, SendMessageW(hStatic, STM_SETIMAGE, cast(WPARAM, IMAGE_ENHMETAFILE), 0)))
END FUNCTION
' ========================================================================================


' ########################################################################################
'                                    *** TOOLBAR ***
' ########################################################################################

' ========================================================================================
' Adds one or more images to the list of button images available for a toolbar.
' Returns the index of the first new image if successful, or -1 otherwise.
' ========================================================================================
PRIVATE FUNCTION Toolbar_AddBitmap (BYVAL hToolBar AS HWND, BYVAL nButtons AS DWORD, BYVAL tabm AS TBADDBITMAP PTR) AS LONG
   FUNCTION = SendMessageW(hToolBar, TB_ADDBITMAP, cast(WPARAM, nButtons), CAST(LPARAM, tabm))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Adds one or more buttons to a toolbar.
' Returns TRUE if successful, or FALSE otherwise.
' ========================================================================================
PRIVATE FUNCTION Toolbar_AddButtons (BYVAL hToolBar AS HWND, BYVAL nButtons AS DWORD, BYVAL lpButtons AS TBBUTTON PTR) AS BOOLEAN
   FUNCTION = SendMessageW(hToolBar, TB_ADDBUTTONSW, cast(WPARAM, nButtons), CAST(LPARAM, lpButtons))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Adds a button to a toolbar.
' Returns TRUE if successful, or FALSE otherwise.
' ========================================================================================
PRIVATE FUNCTION Toolbar_AddButton (BYVAL hToolBar AS HWND, BYVAL idxBitmap AS LONG, BYVAL idCommand AS LONG, _
BYVAL fsState AS UBYTE = 0, BYVAL fsStyle AS UBYTE = 0, BYVAL dwData AS DWORD_PTR = 0, BYVAL pwszText AS WSTRING PTR = NULL) AS BOOLEAN
   IF fsState = 0 THEN fsState = TBSTATE_ENABLED
   DIM idxString AS INT_PTR
   IF pwszText <> NULL THEN idxString = IIF(LEN(*pwszText) = 0, -1, CAST(INT_PTR, pwszText))
#ifdef __FB_64BIT__
   DIM tbb AS TBBUTTON = (idxBitmap, idCommand, fsState, fsStyle, {0, 0, 0, 0, 0, 0}, dwData, idxString)
#else
   DIM tbb AS TBBUTTON = (idxBitmap, idCommand, fsState, fsStyle, {0, 0}, dwData, idxString)
#endif
   FUNCTION = SendMessageW(hToolBar, TB_ADDBUTTONSW, 1, CAST(LPARAM, @tbb))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Adds a separator to a toolbar.
' Returns TRUE if successful, or FALSE otherwise.
' ========================================================================================
PRIVATE FUNCTION Toolbar_AddSeparator (BYVAL hToolBar AS HWND, BYVAL nWidth AS LONG = 0) AS BOOLEAN
#ifdef __FB_64BIT__
   DIM tbb AS TBBUTTON = (nWidth, 0, TBSTATE_ENABLED, TBSTYLE_SEP, {0, 0, 0, 0, 0, 0}, 0, -1)
#else
   DIM tbb AS TBBUTTON = (nWidth, 0, TBSTATE_ENABLED, TBSTYLE_SEP, {0, 0}, 0, -1)
#endif
   FUNCTION = SendMessageW(hToolBar, TB_ADDBUTTONSW, 1, CAST(LPARAM, @tbb))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Inserts a button in a toolbar.
' Returns TRUE if successful, or FALSE otherwise.
' ========================================================================================
PRIVATE FUNCTION Toolbar_InsertButton OVERLOAD (BYVAL hToolBar AS HWND, BYVAL idxButton AS LONG, BYVAL lpButton AS TBBUTTON PTR) AS BOOLEAN
   FUNCTION = SendMessageW(hToolBar, TB_INSERTBUTTONW, cast(WPARAM, idxButton), CAST(LPARAM, lpButton))
END FUNCTION
' ========================================================================================
' ========================================================================================
PRIVATE FUNCTION Toolbar_InsertButton OVERLOAD (BYVAL hToolBar AS HWND, BYVAL idxButton AS LONG, BYVAL idxBitmap AS LONG, BYVAL idCommand AS LONG, _
BYVAL fsState AS UBYTE = 0, BYVAL fsStyle AS UBYTE = 0, BYVAL dwData AS DWORD_PTR = 0, BYVAL pwszText AS WSTRING PTR = NULL) AS BOOLEAN
   IF fsState = 0 THEN fsState = TBSTATE_ENABLED
   DIM idxString AS INT_PTR
   IF pwszText <> NULL THEN idxString = IIF(LEN(*pwszText) = 0, -1, CAST(INT_PTR, pwszText))
#ifdef __FB_64BIT__
   DIM tbb AS TBBUTTON = (idxBitmap, idCommand, fsState, fsStyle, {0, 0, 0, 0, 0, 0}, dwData, idxString)
#else
   DIM tbb AS TBBUTTON = (idxBitmap, idCommand, fsState, fsStyle, {0, 0}, dwData, idxString)
#endif
   FUNCTION = SendMessageW(hToolBar, TB_INSERTBUTTONW, idxButton, CAST(LPARAM, @tbb))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Inserts a separator in a toolbar.
' Returns TRUE if successful, or FALSE otherwise.
' ========================================================================================
PRIVATE FUNCTION Toolbar_InsertSeparator (BYVAL hToolBar AS HWND, BYVAL idxButton AS LONG, BYVAL nWidth AS LONG = 0) AS BOOLEAN
#ifdef __FB_64BIT__
   DIM tbb AS TBBUTTON = (nWidth, 0, TBSTATE_ENABLED, TBSTYLE_SEP, {0, 0, 0, 0, 0, 0}, 0, -1)
#else
   DIM tbb AS TBBUTTON = (nWidth, 0, TBSTATE_ENABLED, TBSTYLE_SEP, {0, 0}, 0, -1)
#endif
   FUNCTION = SendMessageW(hToolBar, TB_INSERTBUTTONW, idxButton, CAST(LPARAM, @tbb))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Adds a new string to the toolbar's string pool.
' Returns the index of the first new string if successful, or -1 otherwise.
' ========================================================================================
PRIVATE FUNCTION Toolbar_AddString (BYVAL hToolBar AS HWND, BYVAL hInst AS HINSTANCE, BYVAL idString AS INT_PTR) AS LONG
   FUNCTION = SendMessageW(hToolBar, TB_ADDSTRINGW, CAST(WPARAM, hInst), IIF(hInst = NULL, idString, MAKELONG(idString, 0)))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Causes a toolbar to be resized.
' ========================================================================================
PRIVATE SUB Toolbar_AutoSize (BYVAL hToolBar AS HWND)
   SendMessageW(hToolBar, TB_AUTOSIZE, 0, 0)
END SUB
' ========================================================================================

' ========================================================================================
' Retrieves a count of the buttons currently in the toolbar.
' ========================================================================================
PRIVATE FUNCTION Toolbar_ButtonCount (BYVAL hToolBar AS HWND) AS DWORD
   FUNCTION = SendMessageW(hToolBar, TB_BUTTONCOUNT, 0, 0)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Specifies the size of the TBBUTTON structure.
' ========================================================================================
PRIVATE SUB Toolbar_ButtonStructSize (BYVAL hToolBar AS HWND, BYVAL cb AS LONG)
   SendMessageW(hToolBar, TB_BUTTONSTRUCTSIZE, cb, 0)
END SUB
' ========================================================================================

' ========================================================================================
' Changes the bitmap for a button in a toolbar.
' Returns TRUE if successful, or FALSE otherwise.
' ========================================================================================
PRIVATE FUNCTION Toolbar_ChangeBitmap (BYVAL hToolBar AS HWND, BYVAL idButton AS LONG, BYVAL iBitmap AS WORD) AS BOOLEAN
   FUNCTION = SendMessageW(hToolBar, TB_CHANGEBITMAP, cast(WPARAM, idButton), cast(LPARAM, MAKELONG(iBitmap, 0)))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Checks or unchecks a given button in a toolbar.
' Returns TRUE if successful, or FALSE otherwise.
' ========================================================================================
PRIVATE FUNCTION Toolbar_CheckButton (BYVAL hToolBar AS HWND, BYVAL idButton AS LONG, BYVAL fCheck AS SHORT) AS BOOLEAN
   FUNCTION = SendMessageW(hToolBar, TB_CHECKBUTTON, cast(WPARAM, idButton), cast(LPARAM, MAKELONG(fCheck, 0)))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Retrieves the zero-based index for the button associated with the specified command
' identifier. Returns the zero-based index for the button or -1 if the specified command
' identifier is invalid.
' ========================================================================================
PRIVATE FUNCTION Toolbar_CommandToIndex (BYVAL hToolBar AS HWND, BYVAL idButton AS LONG) AS LONG
   FUNCTION = SendMessageW(hToolBar, TB_COMMANDTOINDEX, cast(WPARAM, idButton), 0)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Displays the Customize Toolbar dialog box.
' ========================================================================================
PRIVATE SUB Toolbar_Customize (BYVAL hToolBar AS HWND)
   SendMessageW(hToolBar, TB_CUSTOMIZE, 0, 0)
END SUB
' ========================================================================================

' ========================================================================================
' Deletes a button from the toolbar.
' Returns TRUE if successful, or FALSE otherwise.
' ========================================================================================
PRIVATE FUNCTION Toolbar_DeleteButton (BYVAL hToolBar AS HWND, BYVAL nButton AS LONG) AS BOOLEAN
   FUNCTION = SendMessageW(hToolBar, TB_DELETEBUTTON, cast(WPARAM, nButton), 0)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Enables the specified button in a toolbar.
' Returns TRUE if successful, or FALSE otherwise.
' ========================================================================================
PRIVATE FUNCTION Toolbar_EnableButton (BYVAL hToolBar AS HWND, BYVAL idButton AS LONG) AS BOOLEAN
   FUNCTION = SendMessageW(hToolBar, TB_ENABLEBUTTON, cast(WPARAM, idButton), cast(LPARAM, MAKELONG(CTRUE, 0)))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Disables the specified button in a toolbar.
' Returns TRUE if successful, or FALSE otherwise.
' ========================================================================================
PRIVATE FUNCTION Toolbar_DisableButton (BYVAL hToolBar AS HWND, BYVAL idButton AS LONG) AS BOOLEAN
   FUNCTION = SendMessageW(hToolBar, TB_ENABLEBUTTON, cast(WPARAM, idButton), cast(LPARAM, MAKELONG(FALSE, 0)))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Retrieves the anchor highlight setting for a toolbar.
' Returns a Boolean value that indicates if anchor highlighting is set. If this value is
' nonzero, anchor highlighting is enabled. If this value is zero, it is disabled.
' ========================================================================================
PRIVATE FUNCTION Toolbar_GetAnchorHighlight (BYVAL hToolBar AS HWND) AS BOOLEAN
   FUNCTION = SendMessageW(hToolBar, TB_GETANCHORHIGHLIGHT, 0, 0)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Retrieves the index of the bitmap associated with a button in a toolbar.
' Returns the index of the bitmap if successful, or zero otherwise.
' ========================================================================================
PRIVATE FUNCTION Toolbar_GetBitmap (BYVAL hToolBar AS HWND, BYVAL idButton AS LONG) AS LONG
   FUNCTION = SendMessageW(hToolBar, TB_GETBITMAP, cast(WPARAM, idButton), 0)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Retrieves the flags that describe the type of bitmap to be used.
' Returns a DWORD value that describes the type of bitmap that should be used. If this
' return value has the TBBF_LARGE flag set, applications should use large bitmaps (24 x 24);
' otherwise, applications should use small bitmaps (16 x 16). All other bits are reserved.
' ========================================================================================
PRIVATE FUNCTION Toolbar_GetBitmapFlags (BYVAL hToolBar AS HWND) AS DWORD
   FUNCTION = SendMessageW(hToolBar, TB_GETBITMAPFLAGS, 0, 0)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Retrieves information about the specified button in a toolbar.
' Returns TRUE if successful, or FALSE otherwise.
' ========================================================================================
PRIVATE FUNCTION Toolbar_GetButton (BYVAL hToolBar AS HWND, BYVAL nButton AS LONG, BYVAL ptbb AS TBBUTTON PTR) AS BOOLEAN
   FUNCTION = SendMessageW(hToolBar, TB_GETBUTTON, CAST(WPARAM, nButton), CAST(LPARAM, ptbb))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Retrieves the current width and height of toolbar buttons, in pixels.
' Returns a DWORD value that contains the width and height values in the low word and high
' word, respectively.
' ========================================================================================
PRIVATE FUNCTION Toolbar_GetButtonSize (BYVAL hToolBar AS HWND) AS DWORD
   FUNCTION = SendMessageW(hToolBar, TB_GETBUTTONSIZE, 0, 0)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Retrieves the current height of toolbar buttons, in pixels.
' ========================================================================================
PRIVATE FUNCTION Toolbar_GetButtonHeight (BYVAL hToolBar AS HWND) AS DWORD
   FUNCTION = HIWORD(SendMessageW(hToolBar, TB_GETBUTTONSIZE, 0, 0))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Retrieves the current width of toolbar buttons, in pixels.
' ========================================================================================
PRIVATE FUNCTION Toolbar_GetButtonWidth (BYVAL hToolBar AS HWND) AS DWORD
   FUNCTION = LOWORD(SendMessageW(hToolBar, TB_GETBUTTONSIZE, 0, 0))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Retrieves extended information for a button in a toolbar.
' Returns the zero-based index of the button, or -1 if an error occurs.
' ========================================================================================
PRIVATE FUNCTION Toolbar_GetButtonInfo (BYVAL hToolBar AS HWND, BYVAL iID AS LONG, BYVAL lptbbi AS TBBUTTONINFOW PTR) AS LONG
   FUNCTION = SendMessageW(hToolBar, TB_GETBUTTONINFOW, cast(WPARAM, iID), cast(LPARAM, lptbbi))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Retrieves the color scheme information from the toolbar control.
' - lpcs: Pointer to a COLORSCHEME structure that will receive the color scheme information.
'   You must set the cbSize member of this structure to sizeof(COLORSCHEME) before sending
'   this message.
' Returns nonzero if successful, or zero otherwise.
' ========================================================================================
PRIVATE FUNCTION Toolbar_GetColorScheme (BYVAL hToolBar AS HWND, BYVAL lpcs AS COLORSCHEME PTR) AS BOOLEAN
   FUNCTION = SendMessageW(hToolBar, TB_GETCOLORSCHEME, 0, CAST(LPARAM, lpcs))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Retrieves the image list that a toolbar control uses to display buttons in their default
' state. A toolbar control uses this image list to display buttons when they are not hot
' or disabled.
' ========================================================================================
PRIVATE FUNCTION Toolbar_GetImageList (BYVAL hToolBar AS HWND) AS HIMAGELIST
   FUNCTION = CAST(HIMAGELIST, SendMessageW(hToolBar, TB_GETIMAGELIST, 0, 0))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Retrieves the image list that a toolbar control uses to display inactive buttons.
' A toolbar control uses this image list to display buttons when they are disabled.
' ========================================================================================
PRIVATE FUNCTION Toolbar_GetDisabledImageList (BYVAL hToolBar AS HWND) AS HIMAGELIST
   FUNCTION = CAST(HIMAGELIST, SendMessageW(hToolBar, TB_GETDISABLEDIMAGELIST, 0, 0))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Retrieves the image list that a toolbar control uses to display hot buttons.
' ========================================================================================
PRIVATE FUNCTION Toolbar_GetHotImageList (BYVAL hToolBar AS HWND) AS HIMAGELIST
   FUNCTION = CAST(HIMAGELIST, SendMessageW(hToolBar, TB_GETHOTIMAGELIST, 0, 0))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Retrieves the extended styles for a toolbar control.
' Returns a DWORD that represents the styles currently in use for the toolbar control.
' This value can be a combination of extended styles.
' ========================================================================================
PRIVATE FUNCTION Toolbar_GetExtendedStyle (BYVAL hToolBar AS HWND) AS DWORD
   FUNCTION = SendMessageW(hToolBar, TB_GETEXTENDEDSTYLE, 0, 0)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Retrieves the horizontal padding for a toolbar control.
' Minimum operating systems Windows 2000, Windows NT 4.0 with Internet Explorer 4.0,
' Windows 98, Windows 95 with Internet Explorer 4.0
' ========================================================================================
PRIVATE FUNCTION Toolbar_GetHorizontalPadding (BYVAL hToolBar AS HWND) AS DWORD
   FUNCTION = LOWORD(SendMessageW(hToolBar, TB_GETPADDING, 0, 0))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Retrieves the vertical padding for a toolbar control.
' ========================================================================================
PRIVATE FUNCTION Toolbar_GetVerticalPadding (BYVAL hToolBar AS HWND) AS DWORD
   FUNCTION = HIWORD(SendMessageW(hToolBar, TB_GETPADDING, 0, 0))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Retrieves the index of the hot item in a toolbar.
' ========================================================================================
PRIVATE FUNCTION Toolbar_GetHotItem (BYVAL hToolBar AS HWND) AS DWORD
   FUNCTION = SendMessageW(hToolBar, TB_GETHOTITEM, 0, 0)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Retrieves the current insertion mark for the toolbar.
' Always returns TRUE.
' ========================================================================================
PRIVATE FUNCTION Toolbar_GetInsertMark (BYVAL hToolBar AS HWND, BYVAL ptbim AS TBINSERTMARK PTR) AS LONG
   FUNCTION = SendMessageW(hToolBar, TB_GETINSERTMARK, 0, CAST(LPARAM, ptbim))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Retrieves the color used to draw the insertion mark for the toolbar.
' Returns a COLORREF value that contains the current insertion mark color.
' ========================================================================================
PRIVATE FUNCTION Toolbar_GetInsertMarkColor (BYVAL hToolBar AS HWND) AS COLORREF
   FUNCTION = SendMessageW(hToolBar, TB_GETINSERTMARKCOLOR, 0, 0)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Retrieves the bounding rectangle of a button in a toolbar.
' Returns TRUE if successful, or FALSE otherwise.
' ========================================================================================
PRIVATE FUNCTION Toolbar_GetItemRect (BYVAL hToolBar AS HWND, BYVAL nButton AS LONG, BYVAL lprc AS RECT PTR) AS BOOLEAN
   FUNCTION = SendMessageW(hToolBar, TB_GETITEMRECT, cast(WPARAM, nButton), CAST(LPARAM, lprc))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Retrieves the total size of all of the visible buttons and separators in the toolbar.
' Returns TRUE if successful, or FALSE otherwise.
' ========================================================================================
PRIVATE FUNCTION Toolbar_GetMaxSize (BYVAL hToolBar AS HWND, BYVAL psize AS SIZE PTR) AS BOOLEAN
   FUNCTION = SendMessageW(hToolBar, TB_GETMAXSIZE, 0, CAST(LPARAM, psize))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Retrieves the metrics of a toolbar control.
' Note: To use this API, you must provide a manifest specifying Comclt32.dll version 6.0.
' ========================================================================================
PRIVATE SUB Toolbar_GetMetrics (BYVAL hToolBar AS HWND, BYVAL ptbMetrics AS TBMETRICS PTR)
   SendMessageW(hToolBar, TB_GETMETRICS, 0, CAST(LPARAM, ptbMetrics))
END SUB
' ========================================================================================

' ========================================================================================
' Retrieves the padding for a toolbar control.
' Returns a DWORD value that contains the horizontal padding in the low word and the
' vertical padding in the high word, in pixels.
' ========================================================================================
PRIVATE FUNCTION Toolbar_GetPadding (BYVAL hToolBar AS HWND) AS DWORD
   FUNCTION = SendMessageW(hToolBar, TB_GETPADDING, 0, 0)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Retrieves the bounding rectangle for a specified toolbar button.
' Returns TRUE if successful, or FALSE otherwise.
' ========================================================================================
PRIVATE FUNCTION Toolbar_GetRect (BYVAL hToolBar AS HWND, BYVAL iID AS LONG, BYVAL lprc AS RECT PTR) AS BOOLEAN
   FUNCTION = SendMessageW(hToolBar, TB_GETRECT, cast(WPARAM, iID), CAST(LPARAM, lprc))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Retrieves the number of rows of buttons in a toolbar with the TBSTYLE_WRAPABLE style.
' ========================================================================================
PRIVATE FUNCTION Toolbar_GetRows (BYVAL hToolBar AS HWND) AS DWORD
   FUNCTION = SendMessageW(hToolBar, TB_GETROWS, 0, 0)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Retrieves information about the state of the specified button in a toolbar, such as
' whether it is enabled, pressed, or checked.
' ========================================================================================
PRIVATE FUNCTION Toolbar_GetState (BYVAL hToolBar AS HWND, BYVAL idButton AS LONG) AS DWORD
   FUNCTION = SendMessageW(hToolBar, TB_GETSTATE, cast(WPARAM, idButton), 0)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Retrieves a string from a toolbar's string pool.
' - iString: Index of the string
' - pBuffer: Pointer to a buffer used to return the string.
' - cchMax: Length of the buffer in bytes.
' Returns the string length if successful, or -1 otherwise.
' ========================================================================================
PRIVATE FUNCTION Toolbar_GetString (BYVAL hToolBar AS HWND, BYVAL iString AS SHORT, BYVAL pBuffer AS WSTRING PTR, BYVAL cchMax AS SHORT) AS LONG
   FUNCTION = SendMessageW(hToolBar, TB_GETSTRINGW, MAKELONG(cchMax, iString), CAST(LPARAM, pbuffer))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Retrieves the styles currently in use for a toolbar control.
' Returns a DWORD value that is a combination of toolbar control styles.
' ========================================================================================
PRIVATE FUNCTION Toolbar_GetStyle (BYVAL hToolBar AS HWND) AS DWORD
   FUNCTION = SendMessageW(hToolBar, TB_GETSTYLE, 0, 0)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Retrieves the number of rows of buttons in a toolbar with the TBSTYLE_WRAPABLE style.
' ========================================================================================
PRIVATE FUNCTION Toolbar_GetTextRows (BYVAL hToolBar AS HWND) AS DWORD
   FUNCTION = SendMessageW(hToolBar, TB_GETTEXTROWS, 0, 0)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Retrieves the handle to the ToolTip control, if any, associated with the toolbar.
' ========================================================================================
PRIVATE FUNCTION Toolbar_GetTooltips (BYVAL hToolBar AS HWND) AS HWND
   FUNCTION = cast(HWND, SendMessageW(hToolBar, TB_GETTOOLTIPS, 0, 0))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Retrieves the Unicode character format flag for the control.
' ========================================================================================
PRIVATE FUNCTION Toolbar_GetUnicodeFormat (BYVAL hToolBar AS HWND) AS DWORD
   FUNCTION = SendMessageW(hToolBar, TB_GETUNICODEFORMAT, 0, 0)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Hides or shows the specified button in a toolbar.
' Returns TRUE if successful, or FALSE otherwise.
' ========================================================================================
PRIVATE FUNCTION Toolbar_HideButton (BYVAL hToolBar AS HWND, BYVAL idButton AS LONG, BYVAL fShow AS SHORT) AS BOOLEAN
   FUNCTION = SendMessageW(hToolBar, TB_HIDEBUTTON, idButton, MAKELONG(fShow, 0))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Determines where a point lies in a toolbar control.
' Returns an integer value. If the return value is zero or a positive value, it is the
' zero-based index of the nonseparator item in which the point lies. If the return value
' is negative, the point does not lie within a button. The absolute value of the return
' value is the index of a separator item or the nearest nonseparator item.
' ========================================================================================
PRIVATE FUNCTION Toolbar_HitTest (BYVAL hToolBar AS HWND, BYVAL pptHitTest AS POINT PTR) AS LONG
   FUNCTION = SendMessageW(hToolBar, TB_HITTEST, 0, CAST(LPARAM, pptHitTest))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Sets or clears the indeterminate state of the specified button in a toolbar.
' Returns TRUE if successful, or FALSE otherwise.
' ========================================================================================
PRIVATE FUNCTION Toolbar_Indeterminate (BYVAL hToolBar AS HWND, BYVAL idButton AS LONG, BYVAL fIndeterminate AS SHORT) AS BOOLEAN
   FUNCTION = SendMessageW(hToolBar, TB_INDETERMINATE, cast(WPARAM, idButton), MAKELONG(fIndeterminate, 0))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Retrieves the insertion mark information for a point in a toolbar.
' Minimum operating systems Windows 2000, Windows NT 4.0 with Internet Explorer 4.0,
' Windows 98, Windows 95 with Internet Explorer 4.0
' ========================================================================================
PRIVATE FUNCTION Toolbar_InsertMarkHitTest (BYVAL hToolBar AS HWND, BYVAL lppt AS POINT PTR, BYVAL lptbim AS TBINSERTMARK PTR) AS BOOLEAN
   FUNCTION = SendMessageW(hToolBar, TB_INSERTMARKHITTEST, CAST(WPARAM, lppt), CAST(LPARAM, lptbim))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Determines whether the specified button in a toolbar is checked.
' Returns TRUE if the point is an insertion mark, or FALSE otherwise.
' ========================================================================================
PRIVATE FUNCTION Toolbar_IsButtonChecked (BYVAL hToolBar AS HWND, BYVAL idButton AS LONG) AS BOOLEAN
   FUNCTION = SendMessageW(hToolBar, TB_ISBUTTONCHECKED, cast(WPARAM, idButton), 0)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Determines whether the specified button in a toolbar is enabled.
' Returns TRUE if the button is enabled, or FALSE otherwise.
' ========================================================================================
PRIVATE FUNCTION Toolbar_IsButtonEnabled (BYVAL hToolBar AS HWND, BYVAL idButton AS LONG) AS BOOLEAN
   FUNCTION = SendMessageW(hToolBar, TB_ISBUTTONENABLED, cast(WPARAM, idButton), 0)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Determines whether the specified button in a toolbar is hidden.
' Returns TRUE if the button is hidden, or FALSE otherwise.
' ========================================================================================
PRIVATE FUNCTION Toolbar_IsButtonHidden (BYVAL hToolBar AS HWND, BYVAL idButton AS LONG) AS BOOLEAN
   FUNCTION = SendMessageW(hToolBar, TB_ISBUTTONHIDDEN, cast(WPARAM, idButton), 0)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Checks the highlight state of a toolbar button.
' Returns TRUE if the button is highlighted, or FALSE otherwise.
' ========================================================================================
PRIVATE FUNCTION Toolbar_IsButtonHighlighted (BYVAL hToolBar AS HWND, BYVAL idButton AS LONG) AS BOOLEAN
   FUNCTION = SendMessageW(hToolBar, TB_ISBUTTONHIGHLIGHTED, cast(WPARAM, idButton), 0)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Determines whether the specified button in a toolbar is indeterminate.
' Returns TRUE if the button is in a indetermides state, or FALSE otherwise.
' ========================================================================================
PRIVATE FUNCTION Toolbar_IsButtonIndeterminate (BYVAL hToolBar AS HWND, BYVAL idButton AS LONG) AS BOOLEAN
   FUNCTION = SendMessageW(hToolBar, TB_ISBUTTONINDETERMINATE, cast(WPARAM, idButton), 0)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Determines whether the specified button in a toolbar is pressed.
' Returns TRUE if the button is pressed, or FALSE otherwise.
' ========================================================================================
PRIVATE FUNCTION Toolbar_IsButtonPressed (BYVAL hToolBar AS HWND, BYVAL idButton AS LONG) AS BOOLEAN
   FUNCTION = SendMessageW(hToolBar, TB_ISBUTTONPRESSED, cast(WPARAM, idButton), 0)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Loads system-defined button images into a toolbar control's image list.
' The count of images in the image list. Returns zero if the toolbar has no image list or
' if the existing image list is empty.
' ========================================================================================
PRIVATE FUNCTION Toolbar_LoadImages (BYVAL hToolBar AS HWND, BYVAL iBitmapID AS DWORD, BYVAL hinst AS HINSTANCE) AS LONG
   FUNCTION = SendMessageW(hToolBar, TB_LOADIMAGES, cast(WPARAM, iBitmapID), CAST(LPARAM, hinst))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Determines the ID of the button that corresponds to the specified accelerator character.
' Returns TRUE if one of the buttons has wParam as its accelerator character, or FALSE otherwise.
' ========================================================================================
PRIVATE FUNCTION Toolbar_MapAccelerator (BYVAL hToolBar AS HWND, BYVAL chAccel AS DWORD, BYVAL pIDBtn AS DWORD PTR) AS BOOLEAN
   FUNCTION = SendMessageW(hToolBar, TB_MAPACCELERATOR, cast(WPARAM, chAccel), CAST(LPARAM, pIDBtn))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Sets the highlight state of a given button in a toolbar control.
' Returns TRUE if successful, or FALSE otherwise.
' ========================================================================================
PRIVATE FUNCTION Toolbar_MarkButton (BYVAL hToolBar AS HWND, BYVAL idButton AS LONG, BYVAL fHighlight AS SHORT) AS BOOLEAN
   FUNCTION = SendMessageW(hToolBar, TB_MARKBUTTON, cast(WPARAM, idButton), cast(LPARAM, MAKELONG(fHighlight, 0)))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Moves a button from one index to another.
' Returns TRUE if successful, or FALSE otherwise.
' ========================================================================================
PRIVATE FUNCTION Toolbar_MoveButton (BYVAL hToolBar AS HWND, BYVAL uOldPos AS DWORD, BYVAL uNewPos AS DWORD) AS BOOLEAN
   FUNCTION = SendMessageW(hToolBar, TB_MOVEBUTTON, cast(WPARAM, uOldPos), cast(LPARAM, uNewPos))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Presses or releases the specified button in a toolbar.
' Returns TRUE if successful, or FALSE otherwise.
' ========================================================================================
PRIVATE FUNCTION Toolbar_PressButton (BYVAL hToolBar AS HWND, BYVAL idButton AS LONG, BYVAL fPress AS SHORT) AS BOOLEAN
   FUNCTION = SendMessageW(hToolBar, TB_PRESSBUTTON, cast(WPARAM, idButton), cast(LPARAM, MAKELONG(fPress, 0)))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Replaces an existing bitmap with a new bitmap.
' Returns TRUE if successful, or FALSE otherwise.
' ========================================================================================
PRIVATE FUNCTION Toolbar_ReplaceBitmap (BYVAL hToolBar AS HWND, BYVAL ptbrb AS TBREPLACEBITMAP PTR) AS BOOLEAN
   FUNCTION = SendMessageW(hToolBar, TB_REPLACEBITMAP, 0, CAST(LPARAM, ptbrb))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Send this message to initiate saving or restoring a toolbar state.
' Minimum operating systems Windows NT 3.51, Windows 95
' ========================================================================================
PRIVATE SUB Toolbar_SaveRestore (BYVAL hToolBar AS HWND, BYVAL fSave AS LONG, BYVAL ptbsp AS TBSAVEPARAMSW PTR)
   SendMessageW(hToolBar, TB_SAVERESTOREW, cast(WPARAM, fSave), CAST(LPARAM, ptbsp))
END SUB
' ========================================================================================

' ========================================================================================
' Sets the anchor highlight setting for a toolbar.
' Returns the previous anchor highlight setting. If this value is nonzero, anchor highlighting
' was enabled. If this value is zero, anchor highlighting was disabled.
' ========================================================================================
PRIVATE FUNCTION Toolbar_SetAnchorHighlight (BYVAL hToolBar AS HWND, BYVAL fAnchor AS BOOLEAN) AS BOOLEAN
   FUNCTION = SendMessageW(hToolBar, TB_SETANCHORHIGHLIGHT, fAnchor, 0)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Sets the size of the bitmapped images to be added to a toolbar.
' Returns TRUE if successful, or FALSE otherwise.
' ========================================================================================
PRIVATE FUNCTION Toolbar_SetBitmapSize (BYVAL hToolBar AS HWND, BYVAL dxBitmap AS SHORT, BYVAL dyBitmap AS SHORT) AS BOOLEAN
   FUNCTION = SendMessageW(hToolBar, TB_SETBITMAPSIZE, 0, MAKELONG(dxBitmap, dyBitmap))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Sets the information for an existing button in a toolbar.
' Returns TRUE if successful, or FALSE otherwise.
' ========================================================================================
PRIVATE FUNCTION Toolbar_SetButtonInfo (BYVAL hToolBar AS HWND, BYVAL iID AS LONG, BYVAL lptbbi AS TBBUTTONINFOW PTR) AS BOOLEAN
   FUNCTION = SendMessageW(hToolBar, TB_SETBUTTONINFOW, cast(WPARAM, iID), CAST(LPARAM, lptbbi))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Sets the size of the buttons to be added to a toolbar.
' Returns TRUE if successful, or FALSE otherwise.
' ========================================================================================
PRIVATE FUNCTION Toolbar_SetButtonSize (BYVAL hToolBar AS HWND, BYVAL dxButton AS SHORT, BYVAL dyButton AS SHORT) AS BOOLEAN
   FUNCTION = SendMessageW(hToolBar, TB_SETBUTTONSIZE, 0, cast(LPARAM, MAKELONG(dxButton, dyButton)))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Sets the minimum and maximum button widths in the toolbar control.
' Returns TRUE if successful, or FALSE otherwise.
' ========================================================================================
PRIVATE FUNCTION Toolbar_SetButtonWidth (BYVAL hToolBar AS HWND, BYVAL cxMin AS SHORT, BYVAL cxMax AS SHORT) AS BOOLEAN
   FUNCTION = SendMessageW(hToolBar, TB_SETBUTTONWIDTH, 0, cast(LPARAM, MAKELONG(cxMin, cxMax)))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Sets the command identifier of a toolbar button.
' Returns TRUE if successful, or FALSE otherwise.
' ========================================================================================
PRIVATE FUNCTION Toolbar_SetCmdId (BYVAL hToolBar AS HWND, BYVAL index AS SHORT, BYVAL cmdid AS SHORT) AS BOOLEAN
   FUNCTION = SendMessageW(hToolBar, TB_SETCMDID, cast(WPARAM, index), cast(LPARAM, cmdid))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Sets the color scheme information for the toolbar control.
' ========================================================================================
PRIVATE SUB Toolbar_SetColorScheme (BYVAL hToolBar AS HWND, BYVAL lpcs AS COLORSCHEME PTR)
   SendMessageW(hToolBar, TB_SETCOLORSCHEME, 0, CAST(LPARAM, lpcs))
END SUB
' ========================================================================================

' ========================================================================================
' Sets the image list that the toolbar will use to display buttons that are in their
' default state. Returns the handle to the image list previously used to display buttons
' in their default state, or NULL if no image list was previously set.
' ========================================================================================
PRIVATE FUNCTION Toolbar_SetImageList (BYVAL hToolBar AS HWND, BYVAL himlNew AS HIMAGELIST) AS HIMAGELIST
   FUNCTION = CAST(HIMAGELIST, SendMessageW(hToolBar, TB_SETIMAGELIST, 0, CAST(LPARAM, himlNew)))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Sets the image list that the toolbar control will use to display hot buttons.
' Returns the handle to the image list previously used to display hot buttons, or NULL if
' no image list was previously set.
' ========================================================================================
PRIVATE FUNCTION Toolbar_SetHotImageList (BYVAL hToolBar AS HWND, BYVAL himlNewHot AS HIMAGELIST) AS HIMAGELIST
   FUNCTION = CAST(HIMAGELIST, SendMessageW(hToolBar, TB_SETHOTIMAGELIST, 0, CAST(LPARAM, himlNewHot)))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Sets the image list that the toolbar control will use to display disabled buttons.
' Returns the handle to the image list previously used to display disabled buttons, or NULL
' if no image list was previously set.
' ========================================================================================
PRIVATE FUNCTION Toolbar_SetDisabledImageList (BYVAL hToolBar AS HWND, BYVAL himlNewDisabled AS HIMAGELIST) AS HIMAGELIST
   FUNCTION = CAST(HIMAGELIST, SendMessageW(hToolBar, TB_SETDISABLEDIMAGELIST, 0, CAST(LPARAM, himlNewDisabled)))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Sets the image list that the toolbar uses to display buttons that are in a pressed state.
' Returns the handle to the image list previously used to display buttons in their pressed
' state, or NULL if no such image list was previously set.
' ========================================================================================
PRIVATE FUNCTION Toolbar_SetPressedImageList (BYVAL hToolBar AS HWND, BYVAL iImageID AS DWORD, BYVAL himlNew AS HIMAGELIST) AS HIMAGELIST
   FUNCTION = CAST(HIMAGELIST, SendMessagew(hToolBar, TB_SETPRESSEDIMAGELIST, cast(WPARAM, iImageID), CAST(LPARAM, himlNew)))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Sets the text drawing flags for the toolbar.
' Returns the previous text drawing flags.
' ========================================================================================
PRIVATE FUNCTION Toolbar_SetDrawTextFlags (BYVAL hToolBar AS HWND, BYVAL dwMask AS DWORD, BYVAL dwDTFlags AS DWORD) AS DWORD
   FUNCTION = SendMessageW(hToolBar, TB_SETDRAWTEXTFLAGS, cast(WPARAM, dwMask), cast(LPARAM, dwDTFlags))
END FUNCTION
' ========================================================================================
' ========================================================================================
' Sets the extended styles for a toolbar control.
' Returns a DWORD that represents the previous extended styles. This value can be a
' combination of extended styles.
' ========================================================================================
PRIVATE FUNCTION Toolbar_SetExtendedStyle (BYVAL hToolBar AS HWND, BYVAL dwExStyle AS DWORD) AS DWORD
   FUNCTION = SendMessageW(hToolBar, TB_SETEXTENDEDSTYLE, 0, cast(LPARAM, dwExStyle))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Sets the hot item in a toolbar.
' iHot: Index of the item that will be made hot. If this value is -1, none of the items will be hot.
' Returns the index of the previous hot item, or -1 if there was no hot item.
' ========================================================================================
PRIVATE FUNCTION Toolbar_SetHotItem (BYVAL hToolBar AS HWND, BYVAL iHot AS LONG) AS LONG
   FUNCTION = SendMessageW(hToolBar, TB_SETHOTITEM, cast(WPARAM, iHot), 0)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Sets the indentation for the first button in a toolbar control.
' Returns TRUE if successful, or FALSE otherwise.
' ========================================================================================
PRIVATE FUNCTION Toolbar_SetIndent (BYVAL hToolBar AS HWND, BYVAL iIndent AS LONG) AS BOOLEAN
   FUNCTION = SendMessageW(hToolBar, TB_SETINDENT, cast(WPARAM, iIndent), 0)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Sets the current insertion mark for the toolbar.
' ========================================================================================
PRIVATE SUB Toolbar_SetInsertMark (BYVAL hToolBar AS HWND, BYVAL lptbim AS TBINSERTMARK PTR)
   SendMessageW(hToolBar, TB_SETINSERTMARK, 0, CAST(LPARAM, lptbim))
END SUB
' ========================================================================================

' ========================================================================================
' Sets the color used to draw the insertion mark for the toolbar.
' clrInsertMark: COLORREF value that contains the new insertion mark color.
' Returns a COLORREF value that contains the previous insertion mark color.
' ========================================================================================
PRIVATE FUNCTION Toolbar_SetInsertMarkColor (BYVAL hToolBar AS HWND, BYVAL clrInsertMark AS COLORREF) AS COLORREF
   FUNCTION = SendMessageW(hToolBar, TB_SETINSERTMARKCOLOR, cast(WPARAM, clrInsertMark), 0)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Sets the distance between the toolbar buttons on a specific toolbar.
' ========================================================================================
PRIVATE SUB Toolbar_SetListGap (BYVAL hToolBar AS HWND, BYVAL gap AS DWORD)
   SendMessageW(hToolBar, TB_SETLISTGAP, gap, 0)
END SUB
' ========================================================================================

' ========================================================================================
' Sets the maximum number of text rows displayed on a toolbar button.
' Returns TRUE if successful, or FALSE otherwise.
' ========================================================================================
PRIVATE FUNCTION Toolbar_SetMaxTextRows (BYVAL hToolBar AS HWND, BYVAL iMaxRows AS LONG) AS BOOLEAN
   FUNCTION = SendMessageW(hToolBar, TB_SETMAXTEXTROWS, cast(WPARAM, iMaxRows), 0)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Sets the metrics of a toolbar control.
' ptbMetrics: TBMETRICS structure that contains the toolbar metrics to set.
' ========================================================================================
PRIVATE SUB Toolbar_SetMetrics (BYVAL hToolBar AS HWND, BYVAL ptbMetrics AS TBMETRICS PTR)
   SendMessageW(hToolBar, TB_SETMETRICS, 0, CAST(LPARAM, ptbmetrics))
END SUB
' ========================================================================================

' ========================================================================================
' Sets the padding for a toolbar control.
' Returns a DWORD value that contains the previous horizontal padding in the LOWORD and
' the previous vertical padding in the HIWORD, in pixels.
' ========================================================================================
PRIVATE FUNCTION Toolbar_SetPadding (BYVAL hToolBar AS HWND, BYVAL cx AS SHORT, BYVAL cy AS SHORT) AS DWORD
   FUNCTION = SendMessageW(hToolBar, TB_SETPADDING, 0, MAKELONG(cx, cy))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Sets the window to which the toolbar control sends notification messages.
' The return value is a handle to the previous notification window, or NULL if there is no
' previous notification window.
' ========================================================================================
PRIVATE FUNCTION Toolbar_SetParent (BYVAL hToolBar AS HWND, BYVAL hwndParent AS HWND) AS HWND
   FUNCTION = CAST(HWND, SendMessageW(hToolBar, TB_SETPARENT, CAST(WPARAM, hwndParent), 0))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Sets the number of rows of buttons in a toolbar.
' ========================================================================================
PRIVATE SUB Toolbar_SetRows (BYVAL hToolBar AS HWND, BYVAL cRows AS WORD, BYVAL fLarger AS BOOLEAN, BYVAL lprc AS RECT PTR)
   SendMessageW(hToolBar, TB_SETROWS, MAKELONG(cRows, fLarger), CAST(LPARAM, lprc))
END SUB
' ========================================================================================

' ========================================================================================
' Sets the state for the specified button in a toolbar.
' Returns TRUE if successful, or FALSE otherwise.
' ========================================================================================
PRIVATE FUNCTION Toolbar_SetState (BYVAL hToolBar AS HWND, BYVAL idButton AS LONG, BYVAL fState AS SHORT) AS BOOLEAN
   FUNCTION = SendMessageW(hToolBar, TB_SETSTATE, cast(WPARAM, idButton), MAKELONG(fState, 0))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Sets the style for a toolbar control.
' ========================================================================================
PRIVATE SUB Toolbar_SetStyle (BYVAL hToolBar AS HWND, BYVAL dwStyle AS DWORD)
   SendMessageW(hToolBar, TB_SETSTYLE, 0, dwStyle)
END SUB
' ========================================================================================

' ========================================================================================
' Associates a ToolTip control with a toolbar.
' ========================================================================================
PRIVATE SUB Toolbar_SetToolTips (BYVAL hToolBar AS HWND, BYVAL hwndToolTip AS HWND)
   SendMessageW(hToolBar, TB_SETTOOLTIPS, CAST(WPARAM, hwndToolTip), 0)
END SUB
' ========================================================================================

' ========================================================================================
' Sets the Unicode character format flag for the control. This message allows you to
' change the character set used by the control at run time rather than having to re-create
' the control. Returns the previous Unicode format flag for the control.
' ========================================================================================
PRIVATE FUNCTION Toolbar_SetUnicodeFormat (BYVAL hToolBar AS HWND, BYVAL fUnicode AS DWORD) AS DWORD
   FUNCTION = SendMessageW(hToolBar, TB_SETUNICODEFORMAT, cast(WPARAM, fUnicode), 0)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Sets the visual style of a toolbar control.
' Note: To use this API, you must provide a manifest specifying Comclt32.dll version 6.0.
' Minimum Operating System: Windows XP.
' ========================================================================================
PRIVATE SUB Toolbar_SetWindowTheme (BYVAL hToolBar AS HWND, BYVAL pwszTheme AS WSTRING PTR)
   SendMessageW(hToolBar, TB_SETWINDOWTHEME, CAST(WPARAM, pwszTheme), 0)
END SUB
' ========================================================================================

' ========================================================================================
' Makes the toolbar opaque by removing the TBSTYLE_TRANSPARENT style.
' ========================================================================================
PRIVATE SUB Toolbar_MakeOpaque (BYVAL hToolBar AS HWND)
   SetWindowLongPtrW(hToolBar, GWL_STYLE, GetWindowLongPtrW(hToolBar, GWL_STYLE) AND NOT TBSTYLE_TRANSPARENT)
END SUB
' ========================================================================================

' ========================================================================================
' Retrieves the IDropTarget for a toolbar control.
' Minimum operating systems Windows 2000, Windows NT 4.0 with Internet Explorer 4.0,
' Windows 98, Windows 95 with Internet Explorer 4.0
' ========================================================================================
PRIVATE FUNCTION Toolbar_GetObject (BYVAL hToolBar AS HWND) AS IDropTarget PTR
   DIM ppvObject AS IDropTarget PTR
   DIM IID_IDropTarget AS GUID = (&h00000122, &h0000, &h0000, {&hC0, &h00, &h00, &h00, &h00, &h00, &h00, &h46})
   DIM hr AS HRESULT = SendMessageW(hToolBar, TB_GETOBJECT, CAST(WPARAM, @IID_IDropTarget), CAST(LPARAM, ppvObject))
   IF hr <> S_OK THEN FUNCTION = ppvObject
END FUNCTION
' ========================================================================================

' ========================================================================================
' Retrieves the display text of a button on a toolbar.
' Returns the length, in characters, of the string pointed to by lParam. The length does
' not include the terminating null character. If unsuccessful, the return value is -1.
' idButton = Command identifier of the button whose text is to be retrieved.
' pBuffer = Pointer to a buffer that receives the button text.
' Minimum operating systems Windows NT 3.51, Windows 95
' Security Warning: Using this message incorrectly might compromise the security of your
' program. This message does not provide a way for you to know the size of the buffer.
' If you use this message, first call the message passing NULL in the lParam, this returns
' the number of characters, excluding NULL that are required. Then call the message a
' second time to retrieve the string.
' The returned string corresponds to the text that is currently displayed by the button.
' ========================================================================================
PRIVATE FUNCTION Toolbar_GetButtonText (BYVAL hToolBar AS HWND, BYVAL idButton AS LONG, BYVAL pBuffer AS WSTRING PTR) AS LONG
   FUNCTION = SendMessageW(hToolBar, TB_GETBUTTONTEXTW, cast(WPARAM, idButton), CAST(LPARAM, pbuffer))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Retrieves the length of the display text of a button on a toolbar.
' Returns the length, in characters, of the string pointed to by lParam. The length does
' not include the terminating null character. If unsuccessful, the return value is -1.
' ========================================================================================
PRIVATE FUNCTION Toolbar_ButtonGetTextLength (BYVAL hToolBar AS HWND, BYVAL idButton AS LONG) AS LONG
   FUNCTION = SendMessageW(hToolBar, TB_GETBUTTONTEXTW, cast(WPARAM, idButton), 0)
END FUNCTION
' ========================================================================================


' ########################################################################################
'                                   *** TREEVIEW ***
' ########################################################################################

' ========================================================================================
' Retrieves some or all of a tree-view item's attributes.
' Returns TRUE if successful, or FALSE otherwise.
' Usage example:
' DIM item AS TVITEMEXW
' item.mask = TVIF_TEXT
' item.hitem = hitem
' DIM wszText AS WSTRING * MAX_PATH
' item.pszText = @wszText
' item.cchTextMax = MAX_PATH
' TreeView_GetItemEx(hTreeView, @item)
' ========================================================================================
PRIVATE FUNCTION TreeView_GetItemEx (BYVAL hwndTV AS HWND, BYVAL pitem AS TVITEMEXW PTR) AS BOOLEAN
   FUNCTION = SendMessageW(hwndTV, TVM_GETITEMW, 0, cast(LPARAM, pitem))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Inserts a new item in a tree-view control.
' Note: It should have been named TreeView_InsertItem, but this name is already been used by a macro.
' ========================================================================================
PRIVATE FUNCTION TreeView_AddItem (BYVAL hwndTV AS HWND, BYVAL hParent AS HTREEITEM, BYVAL hInsertAfter AS HTREEITEM, _
BYVAL pwszText AS WSTRING PTR, BYVAL lParam AS LPARAM = 0, BYVAL iImage AS LONG = 0, BYVAL iSelectedImage AS LONG = 0) AS HTREEITEM
   DIM tvinsert AS TVINSERTSTRUCTW
   tvinsert.hParent             = hParent
   tvinsert.hInsertAfter        = hInsertAfter
   tvinsert.Item.iImage         = iImage
   tvinsert.Item.iSelectedImage = iSelectedImage
   tvinsert.Item.lParam         = lParam
   tvinsert.Item.mask           = TVIF_TEXT OR TVIF_IMAGE OR TVIF_SELECTEDIMAGE OR TVIF_PARAM
   tvinsert.Item.pszText        = pwszText
   tvinsert.Item.cchTextMax     = LEN(*pwszText)
   FUNCTION = cast(HTREEITEM, SendMessageW(hwndTV, TVM_INSERTITEMW, 0, cast(LPARAM, cast(TVINSERTSTRUCTW PTR, @tvinsert))))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Inserts the item at the end of the list in a tree-view control.
' ========================================================================================
PRIVATE FUNCTION TreeView_AppendItem (BYVAL hwndTV AS HWND, BYVAL hParent AS HTREEITEM, _
BYVAL pwszText AS WSTRING PTR, BYVAL lParam AS LPARAM = 0, BYVAL iImage AS LONG = 0, BYVAL iSelectedImage AS LONG = 0) AS HTREEITEM
   FUNCTION = TreeView_AddItem(hwndTV, hParent, TVI_LAST, pwszText, lParam, iImage, iSelectedImage)
END FUNCTION
' ========================================================================================
' ========================================================================================
' Inserts the item at the beginning of the list in a tree-view control.
' ========================================================================================
PRIVATE FUNCTION TreeView_InsertFirstItem (BYVAL hwndTV AS HWND, BYVAL hParent AS HTREEITEM, _
BYVAL pwszText AS WSTRING PTR, BYVAL lParam AS LPARAM = 0, BYVAL iImage AS LONG = 0, BYVAL iSelectedImage AS LONG = 0) AS HTREEITEM
   FUNCTION = TreeView_AddItem(hwndTV, hParent, TVI_FIRST, pwszText, lParam, iImage, iSelectedImage)
END FUNCTION
' ========================================================================================
' ========================================================================================
' Add the item as the root item in a tree-view control.
' ========================================================================================
PRIVATE FUNCTION TreeView_AddRootItem (BYVAL hwndTV AS HWND, BYVAL pwszText AS WSTRING PTR, _
BYVAL lParam AS LPARAM = 0, BYVAL iImage AS LONG = 0, BYVAL iSelectedImage AS LONG = 0) AS HTREEITEM
   FUNCTION = TreeView_AddItem(hwndTV, NULL, TVI_ROOT, pwszText, lParam, iImage, iSelectedImage)
END FUNCTION
' ========================================================================================
' ========================================================================================
' Inserts the item into the list in alphabetical order.
' ========================================================================================
PRIVATE FUNCTION TreeView_InsertSortedItem (BYVAL hwndTV AS HWND, BYVAL hParent AS HTREEITEM, _
BYVAL pwszText AS WSTRING PTR, BYVAL lParam AS LPARAM = 0, BYVAL iImage AS LONG = 0, BYVAL iSelectedImage AS LONG = 0) AS HTREEITEM
   FUNCTION = TreeView_AddItem(hwndTV, hParent, TVI_SORT, pwszText, lParam, iImage, iSelectedImage)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Returns TRUE if the bold attribute is set, or FALSE otherwise.
' ========================================================================================
PRIVATE FUNCTION TreeView_GetBold (BYVAL hwndTV AS HWND, BYVAL hItem AS HTREEITEM) AS BOOLEAN
   FUNCTION = ((TreeView_GetItemState(hwndTV, hItem, TVIS_BOLD) AND TVIS_BOLD) = TVIS_BOLD)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Returns TRUE if the item is checked, or FALSE otherwise.
' ========================================================================================
PRIVATE FUNCTION TreeView_IsItemChecked (BYVAL hwndTV AS HWND, BYVAL hItem AS HTREEITEM) AS BOOLEAN
   FUNCTION = (TreeView_GetCheckState(hwndTV, hItem) = 1)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Returns the number of characters in the incremental search string.
' If the tree-view control is not in incremental search mode, the return value is zero.
' ========================================================================================
PRIVATE FUNCTION TreeView_GetISearchStringLen (BYVAL hwndTV AS HWND) AS LONG
   FUNCTION = SendMessage(hwndTV, TVM_GETISEARCHSTRING, 0, CAST(LPARAM, NULL))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Retrieve the lParam value from a Treeview
' ========================================================================================
PRIVATE FUNCTION TreeView_GetlParam (BYVAL hwndTV AS HWND, BYVAL hItem AS HTREEITEM) AS LPARAM
   DIM tvi AS TVITEMW
   tvi.hItem = hItem
   tvi.mask  = TVIF_HANDLE OR TVIF_PARAM
   TreeView_GetItem(hwndTV, @tvi)
   FUNCTION = tvi.lParam
END FUNCTION
' ========================================================================================

' ========================================================================================
' Sets/unsets the bold attribute of the specified item.
' ========================================================================================
PRIVATE SUB TreeView_SetBold (BYVAL hwndTV AS HWND, BYVAL hItem AS HTREEITEM, BYVAL fBold AS BOOLEAN)
   TreeView_SetItemState(hwndTV, hItem, IIF(fBold = 0, 0, TVIS_BOLD), TVIS_BOLD)
END SUB
' ========================================================================================

' ========================================================================================
' Sets some or all of a tree-view item's attributes.
' Returns TRUE if successful, or FALSE otherwise.
' ========================================================================================
PRIVATE FUNCTION TreeView_SetItemEx (BYVAL hwndTV AS HWND, BYVAL pitem AS TVITEMEXW PTR) AS BOOLEAN
   FUNCTION = SendMessageW(hwndTV, TVM_SETITEMW, 0, cast(WPARAM, pitem))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Sets the text of the specified item.
' ========================================================================================
PRIVATE FUNCTION TreeView_SetItemText (BYVAL hwndTV AS HWND, BYVAL hItem AS HTREEITEM, BYVAL pwszText AS WSTRING PTR) AS BOOLEAN
   DIM tvi AS TVITEMW
   tvi.hitem = hItem
   tvi.mask = TVIF_TEXT
   tvi.psztext = pwszText
   tvi.cchtextmax = LEN(*pwszText)
   FUNCTION = SendMessageW(hwndTV, TVM_SETITEMW, 0, cast(LPARAM, @tvi))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Expands the list of child items, if any, associated with the specified parent node.
' ========================================================================================
PRIVATE SUB TreeView_ExpandChildItems (BYVAL hwndTV AS HWND, BYVAL hNode AS HTREEITEM)
   DIM hChildNode AS HTREEITEM
   DO WHILE hNode
      ' // Expand the node
      TreeView_Expand(hwndTV, hNode, TVM_EXPAND)
      ' // Get the first child node
      hChildNode = TreeView_GetChild(hwndTV, hNode)
      IF hChildNode THEN TreeView_ExpandChildItems(hwndTV, hChildNode)
      hNode = NULL
   LOOP
END SUB
' ========================================================================================

' ========================================================================================
' Expands the list of sibling items, if any, associated with the specified parent node.
' ========================================================================================
PRIVATE SUB TreeView_ExpandSiblings (BYVAL hwndTV AS HWND, BYVAL hNode AS HTREEITEM)
   DIM hChildNode AS HTREEITEM
   DO WHILE hNode
      ' // Expand the node
      TreeView_Expand(hwndTV, hNode, TVM_EXPAND)
      ' // Get the next sibling item
      hNode = TreeView_GetNextSibling(hwndTV, hNode)
   LOOP
END SUB
' ========================================================================================

' ========================================================================================
' Expands the list of child items, if any, associated with the specified parent node and
' the sibling nodes below it.
' ========================================================================================
PRIVATE SUB TreeView_ExpandAllChildItems (BYVAL hwndTV AS HWND, BYVAL hNode AS HTREEITEM)
   DIM hChildNode AS HTREEITEM
   DO WHILE hNode
      ' // Expand the node
      TreeView_Expand(hwndTV, hNode, TVM_EXPAND)
      ' // Get the first child node
      hChildNode = TreeView_GetChild(hwndTV, hNode)
      IF hChildNode THEN TreeView_ExpandAllChildItems(hwndTV, hChildNode)
      ' // Get the next sibling item
      hNode = TreeView_GetNextSibling(hwndTV, hNode)
   LOOP
END SUB
' ========================================================================================

' ========================================================================================
' Expands all the list of items.
' Note: This is a very slow process if the control has many items because of the continuous
' redrawing; therefore, disable redrawing before calling it with
'   SendMessageW(hwndTV, WM_SETREDRAW, FALSE, 0)
' and reenable drawing once it has ended with
'   SendMessageW(hwndTV, WM_SETREDRAW, TRUE, 0)
' followed by a redrawing of the control
'   InvalidateRect hwndTV, NULL, CTRUE
'   UpdateWindow hwndTV
' ========================================================================================
PRIVATE SUB TreeView_ExpandAllItems (BYVAL hwndTV AS HWND)
   DIM hNode AS HTREEITEM = TreeView_GetRoot(hwndTV)
   IF hNode THEN TreeView_ExpandAllChildItems(hwndTV, hNode)
END SUB
' ========================================================================================

' ========================================================================================
' Collapses the list of child items, if any, associated with the specified parent node.
' ========================================================================================
PRIVATE SUB TreeView_CollapseChildItems (BYVAL hwndTV AS HWND, BYVAL hNode AS HTREEITEM)
   DIM hChildNode AS HTREEITEM
   DO WHILE hNode
      ' // Collapse the node
      TreeView_Expand(hwndTV, hNode, TVE_COLLAPSE)
      ' // Get the first child node
      hChildNode = TreeView_GetChild(hwndTV, hNode)
      IF hChildNode THEN TreeView_CollapseChildItems(hwndTV, hChildNode)
      hNode = NULL
   LOOP
END SUB
' ========================================================================================

' ========================================================================================
' Collapses the list of sibling items, if any, associated with the specified parent node.
' ========================================================================================
PRIVATE SUB TreeView_CollapseSiblings (BYVAL hwndTV AS HWND, BYVAL hNode AS HTREEITEM)
   DIM hChildNode AS HTREEITEM
   DO WHILE hNode
      ' // Collapse the node
      TreeView_Expand(hwndTV, hNode, TVE_COLLAPSE)
      ' // Get the next sibling item
      hNode = TreeView_GetNextSibling(hwndTV, hNode)
   LOOP
END SUB
' ========================================================================================

' ========================================================================================
' Collapses the list of child items, if any, associated with the specified parent node and
' the sibling nodes below it.
' ========================================================================================
PRIVATE SUB TreeView_CollapseAllChildItems (BYVAL hwndTV AS HWND, BYVAL hNode AS HTREEITEM)
   DIM hChildNode AS HTREEITEM
   DO WHILE hNode
      ' // Collapse the node
      TreeView_Expand(hwndTV, hNode, TVE_COLLAPSE)
      ' // Get the first child node
      hChildNode = TreeView_GetChild(hwndTV, hNode)
      IF hChildNode THEN TreeView_CollapseAllChildItems(hwndTV, hChildNode)
      ' // Get the next sibling item
      hNode = TreeView_GetNextSibling(hwndTV, hNode)
   LOOP
END SUB
' ========================================================================================

' ========================================================================================
' Collapses all the list of items.
' ========================================================================================
PRIVATE SUB TreeView_CollapseAllItems (BYVAL hwndTV AS HWND)
   DIM hNode AS HTREEITEM = TreeView_GetRoot(hwndTV)
   IF hNode THEN TreeView_CollapseAllChildItems(hwndTV, hNode)
END SUB
' ========================================================================================

' ========================================================================================
' Retrieves the text of the specified item.
' Returns TRUE if successful, or FALSE otherwise.
' Usage example:
' DIM wszText AS WSTRING * 260
' TreeView_GetItemText(hTreeView, hItem, @wszText, 260)
' AfxMsg(wszText)
' ========================================================================================
PRIVATE FUNCTION TreeView_GetItemText (BYVAL hwndTV AS HWND, BYVAL hItem AS HTREEITEM, BYVAL pwszText AS WSTRING PTR, BYVAL cchtextmax AS LONG) AS BOOLEAN
   IF pwszText = NULL THEN EXIT FUNCTION
   DIM tvi AS TVITEMW
   tvi.hitem = hItem
   tvi.mask = TVIF_TEXT
   tvi.psztext = pwszText
   tvi.cchtextmax = cchtextmax
   FUNCTION = SendMessageW(hwndTV, TVM_GETITEMW, 0, cast(LPARAM, cast(TVITEMW PTR, @tvi)))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Retrieves the text of the parent item of the specified tree-view item.
' Usage example:
' DIM wszText AS WSTRING * 260
' TreeView_GetParentText(hTreeView, hItem, @wszText, 260)
' AfxMsg(wszText)
' Returns TRUE if successful, or FALSE otherwise.
' ========================================================================================
PRIVATE FUNCTION TreeView_GetParentText (BYVAL hwndTV AS HWND, BYVAL hItem AS HTREEITEM, BYVAL pwszText AS WSTRING PTR, BYVAL cchTextMax AS LONG) AS BOOLEAN
   IF pwszText = NULL THEN EXIT FUNCTION
   DIM hNode AS HTREEITEM = TreeView_GetNextItem(hwndTV, hItem, TVGN_PARENT)
   IF hNode THEN FUNCTION = TreeView_GetItemText(hwndTV, hNode, pwszText, cchTextMax)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Searches for an exact string in a tree view node. Search is case sensitive.
' Returns TRUE or FALSE.
' ========================================================================================
PRIVATE FUNCTION TreeView_ItemExists (BYVAL hTreeView AS HWND, BYVAL hNode AS HTREEITEM, BYVAL pwszText AS WSTRING PTR) AS BOOLEAN
   IF pwszText = NULL THEN EXIT FUNCTION
   DIM cbLen AS LONG = LEN(*pwszText)
   IF cbLen = 0 THEN EXIT FUNCTION
   DIM cwsItemText AS CWSTR = SPACE((cbLen + 1) * 2)
   DIM hItem AS HTREEITEM = TreeView_GetChild(hTreeView, hNode)
   DO
      IF hItem = NULL THEN EXIT FUNCTION
      IF TreeView_GetItemText(hTreeView, hItem, *cwsItemText, LEN(cwsItemText)) = FALSE THEN EXIT DO
      IF cwsItemText = *pwszText THEN
         FUNCTION = TRUE
         EXIT DO
      END IF
      hItem = TreeView_GetNextSibling(hTreeView, hItem)
   LOOP
END FUNCTION
' ========================================================================================

' ========================================================================================
' Searches for an exact string in a tree view node. Search is case insensitive.
' Returns TRUE or FALSE.
' ========================================================================================
PRIVATE FUNCTION TreeView_ItemExistsIgnoreCase (BYVAL hTreeView AS HWND, BYVAL hNode AS HTREEITEM, BYVAL pwszText AS WSTRING PTR) AS BOOLEAN
   IF pwszText = NULL THEN EXIT FUNCTION
   DIM cbLen AS LONG = LEN(*pwszText)
   IF cbLen = 0 THEN EXIT FUNCTION
   DIM cwsItemText AS CWSTR = SPACE((cbLen + 1) * 2)
   DIM hItem AS HTREEITEM = TreeView_GetChild(hTreeView, hNode)
   DO
      IF hItem = NULL THEN EXIT FUNCTION
      IF TreeView_GetItemText(hTreeView, hItem, *cwsItemText, LEN(cwsItemText)) = FALSE THEN EXIT DO
      IF UCASE(cwsItemText) = UCASE(*pwszText) THEN
         FUNCTION = TRUE
         EXIT DO
      END IF
      hItem = TreeView_GetNextSibling(hTreeView, hItem)
   LOOP
END FUNCTION
' ========================================================================================


' ########################################################################################
'                                   *** TASK DIALOG ***
' ########################################################################################
#if _WIN32_WINNT = &h0602
' ========================================================================================
' Simulates the action of a button click in the Task Dialog.
' ========================================================================================
PRIVATE SUB TaskDialog_ClickButton (BYVAL hTaskDlg AS HWND, BYVAL nButton AS DWORD)
   SendMessageW(hTaskDlg, TDM_CLICK_BUTTON, cast(WPARAM, nButton), 0)
END SUB
' ========================================================================================

' ========================================================================================
' Simulates the action of a radio button click in the TaskDialog.
' ========================================================================================
PRIVATE SUB TaskDialog_ClickRadioButton (BYVAL hTaskDlg AS HWND, BYVAL nRadioButton AS DWORD)
   SendMessageW(hTaskDlg, TDM_CLICK_RADIO_BUTTON, cast(WPARAM, nRadioButton), 0)
END SUB
' ========================================================================================

' ========================================================================================
' Simulates a click on the verification checkbox of the Task Dialog, if it exists.
' ========================================================================================
PRIVATE SUB TaskDialog_ClickVerification (BYVAL hTaskDlg AS HWND, BYVAL fChecked AS LONG, BYVAL fFocused AS LONG)
   SendMessageW(hTaskDlg, TDM_CLICK_VERIFICATION, cast(WPARAM, fChecked), cast(LPARAM, fFocused))
END SUB
' ========================================================================================

' ========================================================================================
' Enables or disables a push button in the TaskDialog.
' ========================================================================================
PRIVATE SUB TaskDialog_EnableButton (BYVAL hTaskDlg AS HWND, BYVAL nButton AS LONG, BYVAL fEnable AS LONG)
   SendMessageW(hTaskDlg, TDM_ENABLE_BUTTON, cast(WPARAM, nButton), cast(LPARAM, fEnable))
END SUB
' ========================================================================================

' ========================================================================================
' Enables or disables a radio button in the TaskDialog.
' ========================================================================================
PRIVATE SUB TaskDialog_EnableRadioButton (BYVAL hTaskDlg AS HWND, BYVAL nRadioButton AS LONG, BYVAL fEnable AS LONG)
   SendMessageW(hTaskDlg, TDM_ENABLE_RADIO_BUTTON, cast(WPARAM, nRadioButton), cast(LPARAM, fEnable))
END SUB
' ========================================================================================

' ========================================================================================
' Refreshes the contents of the Task Dialog.
' ========================================================================================
PRIVATE SUB TaskDialog_NavigatePage (BYVAL hTaskDlg AS HWND, BYVAL pTaskConfig AS TASKDIALOGCONFIG PTR)
   SendMessageW(hTaskDlg, TDM_NAVIGATE_PAGE, 0, CAST(LPARAM, pTaskConfig))
END SUB
' ========================================================================================

' ========================================================================================
' Used by clients to designate whether a given Task Dialog button or command link should
' have a User Account Control (UAC) shield icon (in other words, whether the action
' invoked by the button requires elevation).
' ========================================================================================
PRIVATE SUB TaskDialog_SetButtonElevationRequiredState (BYVAL hTaskDlg AS HWND, BYVAL nButton AS LONG, BYVAL fElevation AS LONG)
   SendMessageW(hTaskDlg, TDM_SET_BUTTON_ELEVATION_REQUIRED_STATE, cast(WPARAM, nButton), cast(LPARAM, fElevation))
END SUB
' ========================================================================================

' ========================================================================================
' Used by clients to update a text element on the Task Dialog.
' ========================================================================================
PRIVATE SUB TaskDialog_SetElementText (BYVAL hTaskDlg AS HWND, BYVAL eElement AS LONG, BYVAL pszNewText AS WSTRING PTR)
   SendMessageW(hTaskDlg, TDM_SET_ELEMENT_TEXT, cast(WPARAM, eElement), cast(LPARAM, pszNewText))
END SUB
' ========================================================================================

' ========================================================================================
' Indicates whether the hosted progress bar should be displayed in marquee mode.
' ========================================================================================
PRIVATE SUB TaskDialog_SetMarqueeProgressBar (BYVAL hTaskDlg AS HWND, BYVAL fMarquee AS BOOLEAN)
   SendMessageW(hTaskDlg, TDM_SET_MARQUEE_PROGRESS_BAR, cast(WPARAM, fMarquee), 0)
END SUB
' ========================================================================================

' ========================================================================================
' Starts and stops the marquee display of the progress bar, and sets the speed of the marquee.
' ========================================================================================
PRIVATE SUB TaskDialog_SetProgressBarMarquee (BYVAL hTaskDlg AS HWND, BYVAL fMarquee AS LONG, BYVAL nSpeed AS LONG)
   SendMessageW(hTaskDlg, TDM_SET_PROGRESS_BAR_MARQUEE, cast(WPARAM, fMarquee), cast(LPARAM, nSpeed))
END SUB
' ========================================================================================

' ========================================================================================
' The TDM_SET_PROGRESS_BAR_POS message is used set the current position for a progress bar.
' Returns the previous position.
' ========================================================================================
PRIVATE FUNCTION TaskDialog_SetProgressBarPos (BYVAL hTaskDlg AS HWND, BYVAL nNewPos AS LONG) AS LONG
   FUNCTION = SendMessageW(hTaskDlg, TDM_SET_PROGRESS_BAR_POS, cast(WPARAM, nNewPos), 0)
END FUNCTION
' ========================================================================================

' ========================================================================================
' The TDM_SET_PROGRESS_BAR_RANGE message is used set the minimum and maximum values for
' the hosted progress bar. Returns the previous minimum and maximum values, if successful,
' or zero otherwise. The LOWORD contains the minimum value, and the HIWORD contains the
' maximum value.
' ========================================================================================
PRIVATE FUNCTION TaskDialog_SetProgressBarRange (BYVAL hTaskDlg AS HWND, BYVAL nMinRange AS SHORT, BYVAL nMaxRange AS SHORT) AS DWORD
   FUNCTION = SendMessageW(hTaskDlg, TDM_SET_PROGRESS_BAR_RANGE, 0, MAKELONG(nMinRange, nMaxRange))
END FUNCTION
' ========================================================================================

' ========================================================================================
' The TDM_SET_PROGRESS_BAR_POS message is used set the current position for a progress bar.
' If the function succeeds, the return value is non zero. If the function fails, the return
' value is zero. To get extended error information call GetLastError.
' ========================================================================================
PRIVATE FUNCTION TaskDialog_SetProgressBarState (BYVAL hTaskDlg AS HWND, BYVAL nNewState AS LONG) AS LONG
   FUNCTION = SendMessageW(hTaskDlg, TDM_SET_PROGRESS_BAR_STATE, cast(WPARAM, nNewState), 0)
END FUNCTION
' ========================================================================================

' ========================================================================================
' The TDM_UPDATE_ELEMENT_TEXT message is available for use by clients to update a text
' element on the Task Dialog.
' ========================================================================================
PRIVATE SUB TaskDialog_UpdateElementText (BYVAL hTaskDlg AS HWND, BYVAL eElement AS LONG, BYVAL pszNewText AS WSTRING PTR)
   SendMessageW(hTaskDlg, TDM_UPDATE_ELEMENT_TEXT, cast(WPARAM, eElement), CAST(LPARAM, pszNewText))
END SUB
' ========================================================================================

' ========================================================================================
' Refreshes the icon of a task dialog. A window receives this message through its
' WindowProc function.
' ========================================================================================
PRIVATE SUB TaskDialog_UpdateIcon (BYVAL hTaskDlg AS HWND, BYVAL nIconElement AS LONG, BYVAL idResource AS DWORD)
   SendMessageW(hTaskDlg, TDM_UPDATE_ICON, cast(WPARAM, nIconElement), CAST(LPARAM, idResource))
END SUB
' ========================================================================================
#endif

' ########################################################################################
'                                   *** IP ADDRESS ***
' ########################################################################################

' ========================================================================================
' Clears the contents of the IP address control.
' ========================================================================================
PRIVATE SUB IPAddress_ClearAddress (BYVAL hIPM AS HWND)
   SendMessageW(hIPM, IPM_CLEARADDRESS, 0, 0)
END SUB
' ========================================================================================

' ========================================================================================
' Gets the address values for all four fields in the IP address control.
' Returns the number of nonblank fields.
' ========================================================================================
PRIVATE FUNCTION IPAddress_GetAddress (BYVAL hIPM AS HWND, BYVAL pdwAddr AS DWORD PTR) AS LONG
   FUNCTION = SendMessageW(hIPM, IPM_GETADDRESS, 0, CAST(LPARAM, pdwAddr))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Determines if all fields in the IP address control are blank.
' ========================================================================================
PRIVATE SUB IPAddress_IsBlank (BYVAL hIPM AS HWND)
   SendMessageW(hIPM, IPM_ISBLANK, 0, 0)
END SUB
' ========================================================================================

' ========================================================================================
' Sets the address values for all four fields in the IP address control.
' ========================================================================================
PRIVATE SUB IPAddress_SetAddress (BYVAL hIPM AS HWND, BYVAL dwAddr AS DWORD)
   SendMessageW(hIPM, IPM_SETADDRESS, 0, cast(LPARAM, dwAddr))
END SUB
' ========================================================================================

' ========================================================================================
' Sets the keyboard focus to the specified field in the IP address control.
' All of the text in that field will be selected.
' ========================================================================================
PRIVATE SUB IPAddress_SetFocus (BYVAL hIPM AS HWND, BYVAL nField AS LONG)
   SendMessageW(hIPM, IPM_SETFOCUS, cast(WPARAM, nField), 0)
END SUB
' ========================================================================================

' ========================================================================================
' Sets the valid range for the specified field in the IP address control.
' Returns TRUE if successful, or FALSE otherwise.
' ========================================================================================
PRIVATE FUNCTION IPAddress_SetRange (BYVAL hIPM AS HWND, BYVAL nField AS LONG, BYVAL loRange AS BYTE, BYVAL hiRange AS BYTE) AS BOOLEAN
   FUNCTION = SendMessageW(hIPM, IPM_SETRANGE, cast(WPARAM, nField), cast(LPARAM, MAKEIPRANGE(loRange, hiRange)))
END FUNCTION
' ========================================================================================

' ########################################################################################
'                                  *** PROGRESS BAR ***
' ########################################################################################

' ========================================================================================
' Advances the current position of a progress bar by a specified increment and redraws the
' bar to reflect the new position. Returns the previous position.
' ========================================================================================
PRIVATE FUNCTION ProgressBar_DeltaPos (BYVAL hProgress AS HWND, BYVAL nIncrement AS LONG) AS LONG
   FUNCTION = SendMessageW(hProgress, PBM_DELTAPOS, cast(WPARAM, nIncrement), 0)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Retrieves the current high limit of a given progress bar control.
' ========================================================================================
PRIVATE FUNCTION ProgressBar_GetHighLimit (BYVAL hProgress AS HWND) AS LONG
   FUNCTION = SendMessageW(hProgress, PBM_GETRANGE, FALSE, 0)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Retrieves the current low limit of a given progress bar control.
' ========================================================================================
PRIVATE FUNCTION ProgressBar_GetLowLimit (BYVAL hProgress AS HWND) AS LONG
   FUNCTION = SendMessageW(hProgress, PBM_GETRANGE, TRUE, 0)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Retrieves the current maximum range of a given progress bar control.
' ========================================================================================
PRIVATE FUNCTION ProgressBar_GetMaxRange (BYVAL hProgress AS HWND) AS LONG
   FUNCTION = SendMessageW(hProgress, PBM_GETRANGE, FALSE, 0)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Retrieves the current minimum range of a given progress bar control.
' ========================================================================================
PRIVATE FUNCTION ProgressBar_GetMinRange (BYVAL hProgress AS HWND) AS LONG
   FUNCTION = SendMessageW(hProgress, PBM_GETRANGE, TRUE, 0)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Retrieves the current position of the progress bar.
' ========================================================================================
PRIVATE FUNCTION ProgressBar_GetPos (BYVAL hProgress AS HWND) AS DWORD
   FUNCTION = SendMessageW(hProgress, PBM_GETPOS, 0, 0)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Retrieves information about the current high and low limits of a given progress bar control.
' - fWhichLimit: Flag value specifying which limit value is to be used as the message's return
'   value. This parameter can be one of the following values: TRUE (return the low limit),
'   FALSE (return the high limit).
' - ppBRange: Pointer to a PBRANGE structure that is to be filled with both limit values.
' Returns an INT that represents the limit value specified by fWhichLimit
' ========================================================================================
PRIVATE FUNCTION ProgressBar_GetRange (BYVAL hProgress AS HWND, BYVAL fWhichLimit AS DWORD, BYVAL ppBRange AS PBRANGE PTR) AS LONG
   FUNCTION = SendMessageW(hProgress, PBM_GETRANGE, cast(WPARAM, fWhichLimit), cast(LPARAM, ppBRange))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Advances the current position for a progress bar by the specified increment and redraws
' the bar to reflect the new position. nIncVaL: Signed integer that becomes the new position.
' If nIncVal is outside the range of the control, the position is set to the closest boundary.
' Do not send this message to a control that has the PBS_MARQUEE style.
' ========================================================================================
PRIVATE FUNCTION ProgressBar_IncPos (BYVAL hProgress AS HWND, BYVAL nIncVal AS LONG) AS LONG
   DIM nPos AS LONG = SendMessageW(hProgress, PBM_GETPOS, 0, 0)
   FUNCTION = SendMessageW(hProgress, PBM_SETPOS, cast(WPARAM, nPos + nIncVal), 0)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Sets the color of the progress indicator bar in the progress bar control.
' - clrBar: The COLORREF value that specifies the new progress indicator bar color.
'   Specifying the CLR_DEFAULT value causes the progress bar to use its default progress
'   indicator bar color.
' Returns the previous progress indicator bar color, or CLR_DEFAULT if the progress
' indicator bar color is the default color.
' ========================================================================================
PRIVATE FUNCTION ProgressBar_SetBarColor (BYVAL hProgress AS HWND, BYVAL clrBar AS COLORREF) AS COLORREF
   FUNCTION = SendMessageW(hProgress, PBM_SETBARCOLOR, 0, cast(LPARAM, clrBar))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Sets the background color in the progress bar.
' - clrBk: COLORREF value that specifies the new background color. Specify the CLR_DEFAULT
'   value to cause the progress bar to use its default background color.
' Returns the previous background color, or CLR_DEFAULT if the background color is the default color.
' ========================================================================================
PRIVATE FUNCTION ProgressBar_SetBkColor (BYVAL hProgress AS HWND, BYVAL clrBk AS COLORREF) AS COLORREF
   FUNCTION = SendMessageW(hProgress, PBM_SETBKCOLOR, 0, cast(LPARAM, clrBk))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Sets the progress bar to marquee mode. This causes the progress bar to move like a marquee.
' - fOn: Indicates whether to turn the marquee mode on or off.
' - dwAnimationSpeed: Time, in milliseconds, between marquee animation updates. If this
'   parameter is zero, the marquee animation is updated every 30 milliseconds.
' Return value: Always returns TRUE.
' ========================================================================================
PRIVATE FUNCTION ProgressBar_SetMarquee (BYVAL hProgress AS HWND, BYVAL fOn AS LONG, BYVAL dwAnimationSpeed AS DWORD) AS LONG
   FUNCTION = SendMessageW(hProgress, PBM_SETMARQUEE, cast(WPARAM, fOn), cast(LPARAM, dwAnimationSpeed))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Sets the progress bar marquee mode to off.
' Return value: Always returns TRUE.
' ========================================================================================
PRIVATE FUNCTION ProgressBar_SetMarqueeOff (BYVAL hProgress AS HWND) AS LONG
   FUNCTION = SendMessageW(hProgress, PBM_SETMARQUEE, cast(WPARAM, FALSE), 0)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Sets the progress bar to marquee mode. This causes the progress bar to move like a marquee.
' Return value: Always returns TRUE.
' ========================================================================================
PRIVATE FUNCTION ProgressBar_SetMarqueeOn (BYVAL hProgress AS HWND, BYVAL dwAnimationSpeed AS DWORD) AS LONG
   FUNCTION = SendMessageW(hProgress, PBM_SETMARQUEE, cast(WPARAM, CTRUE), cast(LPARAM, dwAnimationSpeed))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Sets the current position for a progress bar and redraws the bar to reflect the new position.
' - nNewPos: Signed integer that becomes the new position.
' Returns the previous position.
' ========================================================================================
PRIVATE FUNCTION ProgressBar_SetPos (BYVAL hProgress AS HWND, BYVAL nNewPos AS LONG) AS LONG
   FUNCTION = SendMessageW(hProgress, PBM_SETPOS, cast(WPARAM, nNewPos), 0)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Sets the current position for a progress bar and redraws the bar to reflect the new position.
' The minimum range value must not be negative. By default, the minimum value is zero.
' The maximum range value must be greater than the minimum range value. By default, the
' maximum range value is 100.
' Returns the previous range values if successful, or zero otherwise. The LOWORD specifies
' the previous minimum value, and the HIWORD specifies the previous maximum value.
' ========================================================================================
PRIVATE FUNCTION ProgressBar_SetRange (BYVAL hProgress AS HWND, BYVAL nMinRange AS WORD, BYVAL nMaxRange AS WORD) AS DWORD
   FUNCTION = SendMessageW(hProgress, PBM_SETRANGE, 0, cast(LPARAM, MAKELONG(nMinRange, nMaxRange)))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Sets the minimum and maximum values for a progress bar to 32-bit values, and redraws the
' bar to reflect the new range. Returns a DWORD value that holds the previous 16-bit low
' limit in its LOWORD and the previous 16-bit high limit in its HIWORD. If the previous
' ranges were 32-bit values, the return value consists of the LOWORDs of both 32-bit limits.
' To retrieve the entire high and low 32-bit values, use the PBM_GETRANGE message.
' ========================================================================================
PRIVATE FUNCTION ProgressBar_SetRange32 (BYVAL hProgress AS HWND, BYVAL nMinRange AS LONG, BYVAL nMaxRange AS LONG) AS DWORD
   FUNCTION = SendMessageW(hProgress, PBM_SETRANGE32, cast(WPARAM, nMinRange), cast(LPARAM, nMaxRange))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Specifies the step increment for a progress bar. The step increment is the amount by
' which the progress bar increases its current position whenever it receives a PBM_STEPIT
' message. By default, the step increment is set to 10.
' Return value: Returns the previous step increment.
' ========================================================================================
PRIVATE FUNCTION ProgressBar_SetStep (BYVAL hProgress AS HWND, BYVAL nStepInc AS LONG) AS LONG
   FUNCTION = SendMessageW(hProgress, PBM_SETSTEP, cast(WPARAM, nStepInc), 0)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Advances the current position for a progress bar by the step increment and redraws the
' bar to reflect the new position. An application sets the step increment by sending the
' PBM_SETSTEP message. Return value: Returns the previous position.
' Remarks: When the position exceeds the maximum range value, this message resets the
' current position so that the progress indicator starts over again from the beginning.
' ========================================================================================
PRIVATE FUNCTION ProgressBar_StepIt (BYVAL hProgress AS HWND) AS LONG
   FUNCTION = SendMessageW(hProgress, PBM_STEPIT, 0, 0)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Returns the color of the progress bar.
' ========================================================================================
#if _WIN32_WINNT = &h0602
PRIVATE FUNCTION ProgressBar_GetBarColor (BYVAL hProgress AS HWND) AS COLORREF
   FUNCTION = SendMessageW(hProgress, PBM_GETBARCOLOR, 0, 0)
END FUNCTION
' ========================================================================================
' ========================================================================================
' Returns the color of the progress bar.
' ========================================================================================
PRIVATE FUNCTION ProgressBar_GetBkColor (BYVAL hProgress AS HWND) AS COLORREF
   FUNCTION = SendMessageW(hProgress, PBM_GETBKCOLOR, 0, 0)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Returns the current state of the progress bar. One of the following values.
' - PBST_NORMAL: In progress
' - PBST_ERROR: Error
' - PBST_PAUSED: Paused
' ========================================================================================
PRIVATE FUNCTION ProgressBar_GetState (BYVAL hProgress AS HWND) AS LONG
   FUNCTION = SendMessageW(hProgress, PBM_GETSTATE, 0, 0)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Sets the state of the progress bar. Can be one of the following values:
' PBST_NORMAL (in progress), PBST_ERROR (error), PBST_PAUSED (paused).
' Return value: Returns the previous state.
' ========================================================================================
PRIVATE FUNCTION ProgressBar_SetState (BYVAL hProgress AS HWND, BYVAL iState AS LONG) AS LONG
   FUNCTION = SendMessageW(hProgress, PBM_SETSTATE, cast(LPARAM, iState), 0)
END FUNCTION
' ========================================================================================
#endif


' ########################################################################################
'                                  *** STATUS BAR ***
' ########################################################################################

' ========================================================================================
' Retrieves the current widths of the horizontal, and vertical borders of a status window,
' and the width of the border between rectangles. Returns TRUE if successful, or FALSE otherwise.
' ========================================================================================
PRIVATE FUNCTION StatusBar_GetBorders (BYVAL hStatusBar AS HWND, BYVAL rgBorders AS LONG PTR) AS LONG
   FUNCTION = SendMessageW(hStatusBar, SB_GETBORDERS, 0, cast(LPARAM, rgBorders))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Returns the height of the status bar.
' ========================================================================================
PRIVATE FUNCTION StatusBar_GetHeight (BYVAL hStatusBar AS HWND) AS LONG
   DIM rc AS RECT
   GetWindowRect(hStatusbar, @rc)
   FUNCTION = rc.Bottom - rc.Top
END FUNCTION
' ========================================================================================

' ========================================================================================
' Retrieves the icon for a part in a status bar.
' Returns the handle to the icon if successful, or NULL otherwise.
' ========================================================================================
PRIVATE FUNCTION StatusBar_GetIcon (BYVAL hStatusBar AS HWND, BYVAL nPart AS DWORD) AS HICON
  FUNCTION = cast(HICON, SendMessageW(hStatusBar, SB_GETICON, nPart, 0))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Retrieves a count of the parts in a status window. The message also retrieves the
' coordinate of the right edge of the specified number of parts.
' - nParts: Number of parts for which to retrieve coordinates. If this parameter is greater
'   than the number of parts in the window, the message retrieves coordinates for existing
'   parts only.
' - rgRightCoords: Pointer to an integer array that has the same number of elements as parts
'   specified by nParts. Each element in the array receives the client coordinate of the
'   right edge of the corresponding part. If an element is set to -1, the position of the
'   right edge for that part extends to the right edge of the window. To retrieve the current
'   number of parts, set this parameter to zero.
' This message always returns the number of parts in the status bar.
' ========================================================================================
PRIVATE FUNCTION StatusBar_GetParts (BYVAL hStatusBar AS HWND, BYVAL nParts AS DWORD, BYVAL rgRightCoords AS LONG PTR) AS LONG
   FUNCTION = SendMessageW(hStatusBar, SB_GETPARTS, nParts, cast(LPARAM, rgRightCoords))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Retrieves a count of the parts in a status window.
' ========================================================================================
PRIVATE FUNCTION StatusBar_GetPartsCount (BYVAL hStatusBar AS HWND) AS DWORD
   FUNCTION = SendMessageW(hStatusBar, SB_GETPARTS, 0, 0)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Retrieves the bounding rectangle of a part in a status window.
' - nPart: Zero-based index of the part whose bounding rectangle is to be retrieved.
' - lprc: Pointer to a RECT structure that receives the bounding rectangle.
' Returns TRUE if successful, or FALSE otherwise.
' ========================================================================================
PRIVATE FUNCTION StatusBar_GetRect (BYVAL hStatusBar AS HWND, BYVAL nPart AS DWORD, BYVAL lprc AS RECT PTR) AS LONG
   FUNCTION = SendMessageW(hStatusBar, SB_GETRECT, cast(WPARAM, nPart), cast(LPARAM, lprc))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Retrieves the type of operation used to draw the text.
' ========================================================================================
PRIVATE FUNCTION StatusBar_GetTextDrawingMode (BYVAL hStatusBar AS HWND, BYVAL nPart AS DWORD) AS LONG
   DIM dwResult AS DWORD = SendMessageW(hStatusBar, SB_GETTEXTLENGTH, cast(WPARAM, nPart), 0)
   FUNCTION = HIWORD(dwResult)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Retrieves the length, in characters, of the text from the specified part of a status window.
' ========================================================================================
PRIVATE FUNCTION StatusBar_GetTextLength (BYVAL hStatusBar AS HWND, BYVAL nPart AS DWORD) AS LONG
   DIM dwResult AS DWORD = SendMessageW(hStatusBar, SB_GETTEXTLENGTH, cast(WPARAM, nPart), 0)
   FUNCTION = LOWORD(dwResult)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Retrieves the tooltip text for a part in a status bar. The status bar must have been
' created with the SBT_TOOLTIPS style to enable tooltips.
' Using this message incorrectly can cause problems for your application. For example, if
' the text is too large for the pwszText buffer, it could cause a buffer overflow.
' ========================================================================================
PRIVATE SUB StatusBar_GetTipText (BYVAL hStatusBar AS HWND, BYVAL nPart AS WORD, BYVAL pwszText AS WSTRING PTR, BYVAL wMaxLen AS WORD)
   IF pwszText = NULL THEN EXIT SUB
   SendMessageW(hStatusBar, SB_GETTIPTEXTW, cast(WPARAM, MAKELONG(nPart, wMaxLen)), cast(LPARAM, pwszText))
END SUB
' ========================================================================================

' ========================================================================================
' Returns the Unicode format flag for the control. If this value is nonzero, the control
' is using Unicode characters. If this value is zero, the control is using ANSI characters.
' ========================================================================================
PRIVATE FUNCTION StatusBar_GetUnicodeFormat (BYVAL hStatusBar AS HWND) AS DWORD
   FUNCTION = SendMessageW(hStatusBar, SB_GETUNICODEFORMAT, 0, 0)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Checks a status bar control to determine if it is in simple mode.
' Returns TRUE if the status bar control is in simple mode, or FALSE otherwise.
' ========================================================================================
PRIVATE FUNCTION StatusBar_IsSimple (BYVAL hStatusBar AS HWND) AS BOOLEAN
   FUNCTION = SendMessageW(hStatusBar, SB_ISSIMPLE, 0, 0)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Sets the background color in a status bar.
' - clrBk: COLORREF value that specifies the new background color. Specify the CLR_DEFAULT
'   value to cause the status bar to use its default background color.
' Returns the previous background color, or CLR_DEFAULT if the background color is the default color.
' ========================================================================================
PRIVATE FUNCTION StatusBar_SetBkColor (BYVAL hStatusBar AS HWND, BYVAL clrBk AS COLORREF) AS COLORREF
   FUNCTION = SendMessageW(hStatusBar, SB_SETBKCOLOR, 0, cast(LPARAM, clrBk))
END FUNCTION
' ========================================================================================

' ========================================================================================
'  Sets the font that the status bar is to use when drawing text.
' ========================================================================================
PRIVATE SUB StatusBar_SetFont (BYVAL hStatusBar AS HWND, BYVAL hFont AS HFONT, BYVAL fRedraw AS LONG = FALSE)
   SendMessageW(hStatusBar, WM_SETFONT, cast(WPARAM, hFont), cast(LPARAM, fRedraw))
END SUB
' ========================================================================================

' ========================================================================================
' Sets the icon for a part in a status bar.
' - nPart: Zero-based index of the part that will receive the icon. If this parameter is -1,
'   the status bar is assumed to be a simple status bar.
' - hIcon: Handle to the icon to be set. If this value is NULL, the icon is removed from the part.
' Returns TRUE if successful, or FALSE otherwise.
' ========================================================================================
PRIVATE FUNCTION StatusBar_SetIcon (BYVAL hStatusBar AS HWND, BYVAL nPart AS LONG, BYVAL hIcon AS HICON) AS BOOLEAN
   FUNCTION = SendMessageW(hStatusBar, SB_SETICON, cast(WPARAM, nPart), cast(LPARAM, hIcon))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Sets the minimum length, in pixels, of a status window's drawing area.
' The minimum height is the sum of minHeight and twice the width, in pixels, of the vertical
' border of the status window. An application must send the WM_SIZE message to the status
' window to redraw the window.
' ========================================================================================
PRIVATE SUB StatusBar_SetMinHeight (BYVAL hStatusBar AS HWND, BYVAL minHeight AS DWORD)
   SendMessageW(hStatusBar, SB_SETMINHEIGHT, cast(WPARAM, minHeight), 0)
END SUB
' ========================================================================================

' ========================================================================================
' Sets the number of parts in a status window and the coordinate of the right edge of each part.
' - dwParts: Number of parts to set (cannot be greater than 256).
' - rgWidths: Pointer to an integer array. The number of elements is specified in dwParts.
'   Each element specifies the position, in client coordinates, of the right edge of the
'   corresponding part. If an element is -1, the right edge of the corresponding part extends
'   to the border of the window.
' Returns TRUE if successful, or FALSE otherwise.
' ========================================================================================
PRIVATE FUNCTION StatusBar_SetParts (BYVAL hStatusBar AS HWND, BYVAL dwParts AS DWORD, BYVAL rgWidths AS LONG PTR) AS BOOLEAN
   FUNCTION = SendMessageW(hStatusBar, SB_SETPARTS, cast(WPARAM, dwParts), cast(LPARAM, rgWidths))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Sets the text in the specified part of a status window.
' - nPart: The zero-based index of the part to set. If it is set to SB_SIMPLEID, the status
'   window is assumed to be a simple mode status bar; that is, a status bar with only one part.
' - pwszText: Pointer to a null-terminated string that specifies the text to set. If nPart is
'   SBT_OWNERDRAW, this parameter represents 32 bits of data. The parent window must interpret
'   the data and draw the text when it receives the WM_DRAWITEM message.
' - uType:
'   0	: The text is drawn with a border to appear lower than the plane of the window.
'   SBT_NOBORDERS    : The text is drawn without borders.
'   SBT_OWNERDRAW    : The text is drawn by the parent window.
'                      Note  A simple mode status bar does not support owner drawing.
'   SBT_POPOUT       : The text is drawn with a border to appear higher than the plane of the window.
'   SBT_RTLREADING   : The text will be displayed in the opposite direction to the text in the parent window.
'   SBT_NOTABPARSING : Tab characters are ignored.
' Returns TRUE if successful, or FALSE otherwise.
' ========================================================================================
PRIVATE FUNCTION StatusBar_SetText (BYVAL hStatusBar AS HWND, BYVAL nPart AS LONG, BYVAL pwszText AS WSTRING PTR, BYVAL uType AS DWORD = 0) AS BOOLEAN
   FUNCTION = SendMessageW(hStatusBar, SB_SETTEXTW, cast(WPARAM, nPart OR uType), cast(LPARAM, pwszText))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Sets the tooltip text for a part in a status bar. The status bar must have been created
' with the SBT_TOOLTIPS style to enable tooltips.
' - nPart: Zero-based index of the part that will receive the tooltip text.
' - pwszText: Pointer to a character buffer that contains the new tooltip text.
' ========================================================================================
PRIVATE SUB StatusBar_SetTipText (BYVAL hStatusBar AS HWND, BYVAL nPart AS LONG, BYVAL pwszTipText AS WSTRING PTR)
   SendMessageW(hStatusBar, SB_SETTIPTEXTW, cast(WPARAM, nPart), cast(LPARAM, pwszTipText))
END SUB
' ========================================================================================

' ========================================================================================
' Sets the Unicode character format flag for the control. This message allows you to
' change the character set used by the control at run time rather than having to re-create
' the control. Returns the previous Unicode format flag for the control.
' ========================================================================================
PRIVATE FUNCTION StatusBar_SetUnicodeFormat (BYVAL hStatusBar AS HWND, BYVAL fUnicode AS DWORD) AS DWORD
   FUNCTION = SendMessageW(hStatusBar, SB_SETUNICODEFORMAT, cast(WPARAM, fUnicode), 0)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Specifies whether a status window displays simple text or displays all window parts set
' by a previous SB_SETPARTS message.
' - fSimple: Display type flag. If this parameter is TRUE, the window displays simple text.
'   If it is FALSE, it displays multiple parts.
' ========================================================================================
PRIVATE SUB StatusBar_Simple (BYVAL hStatusBar AS HWND, BYVAL fSimple AS BOOLEAN)
   SendMessageW(hStatusBar, SB_SIMPLE, fSimple, 0)
END SUB
' ========================================================================================

' ========================================================================================
' Retrieves the text from the specified part of a status window.
' - nPart: Zero-based index of the part from which to retrieve text.
' - pwszText: Pointer to the buffer that receives the text as a null-terminated string.
'   Use the SB_GETTEXTLENGTH message to determine the required size of the buffer.
' Returns a 32-bit value that consists of two 16-bit values. The low word specifies the
' length, in characters, of the text. The high word specifies the type of operation used
' to draw the text.
' ========================================================================================
PRIVATE FUNCTION StatusBar_GetText (BYVAL hStatusBar AS HWND, BYVAL nPart AS DWORD, BYVAL pwszText AS WSTRING PTR) AS DWORD
   IF pwszText = NULL THEN EXIT FUNCTION
   FUNCTION = SendMessageW(hStatusBar, SB_GETTEXTW, cast(WPARAM, nPart), cast(LPARAM, pwszText))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Retrieves the bounding rectangle of a part in a status window.
' Parameters:
' - hStatusBar = Handle of the status bar control. It can belong to another application.
' - nPart = Zero-based index of the part whose bounding rectangle is to be retrieved.
' Return value: A RECT structure with the bounding rectangle.
' Remarks: The purpose of this function is to demonstrate how to retrieve information from
' a status bar control belonging to another application.
' ========================================================================================
PRIVATE FUNCTION AfxGetStatusBarRect (BYVAL hStatusBar AS HWND, BYVAL nPart AS LONG) AS RECT
   DIM idProc AS DWORD, hProcess AS HANDLE, pSbRect AS ANY PTR, rc AS RECT, cbBytesRead AS SIZE_T
   GetWindowThreadProcessId(hStatusBar, @idProc)
   IF idProc = 0 THEN EXIT FUNCTION
   hProcess = OpenProcess(PROCESS_VM_OPERATION OR PROCESS_VM_READ OR PROCESS_VM_WRITE OR _
              PROCESS_QUERY_INFORMATION, FALSE, idProc)
   IF hProcess = NULL THEN EXIT FUNCTION
   pSbRect = VirtualAllocEx(hProcess, NULL, SIZEOF(RECT), MEM_COMMIT, PAGE_READWRITE)
   IF pSbRect THEN
      SendMessageW(hStatusBar, SB_GETRECT, nPart, cast(LPARAM, pSbRect))
      ReadProcessMemory(hProcess, pSbRect, @rc, SIZEOF(rc), @cbBytesRead)
      VirtualFreeEx(hProcess, pSbRect, 0, MEM_RELEASE)
   END IF
   CloseHandle(hProcess)
   FUNCTION = rc
END FUNCTION
' ========================================================================================

' ########################################################################################
'                                      *** TAB ***
' ########################################################################################

' ========================================================================================
' Inserts a new tab in a tab control.
' - hTab: Handle to the tab control.
' - nTabInxex = Zero-based index of the tab
' - iImage = Zero-based index of the image in the image list or -1 for no image.
' - pwszText = Pointer to a null-terminated string that contains the tab text when item
'     information is being set.
' - lParam: Application-defined data associated with the tab control item.
' Returns the index of the new tab if successful, or -1 otherwise.
' ========================================================================================
PRIVATE FUNCTION TabCtrl_InsertTab (BYVAL hwndTab AS HWND, BYVAL nTabIndex AS DWORD, BYVAL iImage AS LONG, BYVAL pwszText AS WSTRING PTR, BYVAL lParam AS LPARAM = 0) AS LONG
   IF IsWindow(hwndTab) = FALSE THEN RETURN -1
   IF pwszText = NULL THEN RETURN -1
   DIM ttc_item AS TCITEMW
   ttc_item.mask = TCIF_TEXT OR TCIF_IMAGE OR TCIF_RTLREADING OR TCIF_PARAM OR TCIF_STATE OR TCIS_BUTTONPRESSED OR TCIS_HIGHLIGHTED
   ttc_item.pszText = pwszText
   ttc_item.cchTextMax = LEN(*pwszText)
   ttc_item.iImage = iImage
   ttc_item.lParam = lParam
   FUNCTION = SendMessageW(hwndTab, TCM_INSERTITEMW, cast(WPARAM, nTabIndex), cast(LPARAM, @ttc_item))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Retrieves the number of tabs and calls TabCtrl_InsertTab to add a new tab.
' ========================================================================================
PRIVATE FUNCTION TabCtrl_AddTab (BYVAL hwndTab AS HWND, BYVAL iImage AS LONG, BYVAL pwszText AS WSTRING PTR, BYVAL lParam AS LPARAM = 0) AS LONG
   IF IsWindow(hwndTab) = FALSE THEN RETURN -1
   IF pwszText = NULL THEN RETURN -1
   DIM nTabIndex AS LONG = SendMessageW(hwndTab, TCM_GETITEMCOUNT, 0, 0)
   FUNCTION = TabCtrl_InsertTab(hwndTab, nTabIndex, iImage, pwszText, lParam)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Gets the name of a tab in a Tab control.
' Returns TRUE if successful, or FALSE otherwise.
' ========================================================================================
PRIVATE FUNCTION TabCtrl_GetText (BYVAL hwndTab AS HWND, BYVAL nTabIndex AS DWORD, BYVAL pwszText AS WSTRING PTR, BYVAL cchTextMax AS LONG) AS BOOLEAN
   DIM ttc_item AS TCITEMW
   ttc_item.mask = TCIF_TEXT
   ttc_item.pszText = pwszText
   ttc_item.cchTextMax = cchTextMax
   FUNCTION = SendMessageW(hwndTab, TCM_GETITEMW, cast(WPARAM, nTabIndex), cast(LPARAM, @ttc_item))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Sets the name of a tab in a Tab control.
' Returns TRUE if successful, or FALSE otherwise.
' ========================================================================================
PRIVATE FUNCTION TabCtrl_SetText (BYVAL hwndTab AS HWND, BYVAL nTabIndex AS DWORD, BYVAL pwszText AS WSTRING PTR) AS BOOLEAN
   DIM ttc_item AS TCITEMW
   ttc_item.mask = TCIF_TEXT
   ttc_item.pszText = pwszText
   ttc_item.cchTextMax = LEN(*pwszText)
   FUNCTION = SendMessageW(hwndTab, TCM_SETITEMW, cast(WPARAM, nTabIndex), cast(LPARAM, @ttc_item))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Gets the 0-based index in the tab control's image list.
' Returns the index of the image or -1 if not found.
' ========================================================================================
PRIVATE FUNCTION TabCtrl_GetImageIndex (BYVAL hwndTab AS HWND, BYVAL iItem AS DWORD) AS LONG
   DIM ttc_item AS TCITEMW
   ttc_item.mask = TCIF_IMAGE
   FUNCTION = -1
   IF SendMessageW(hwndTab, TCM_GETITEMW, cast(WPARAM, iItem), cast(LPARAM, @ttc_item)) THEN
      FUNCTION = ttc_item.iImage
   END IF
END FUNCTION
' ========================================================================================

' ========================================================================================
' Sets the zero-based index in the tab control's image list.
' Returns TRUE if successful, or FALSE otherwise.
' ========================================================================================
PRIVATE FUNCTION TabCtrl_SetImageIndex (BYVAL hwndTab AS HWND, BYVAL iItem AS DWORD, BYVAL iImage AS LONG) AS BOOLEAN
   DIM ttc_item AS TCITEMW
   ttc_item.mask = TCIF_IMAGE
   ttc_item.iImage = iImage
   FUNCTION = SendMessageW(hwndTab, TCM_SETITEMW, cast(WPARAM, iItem), cast(LPARAM, @ttc_item))
END FUNCTION
' ========================================================================================


' ########################################################################################
'                                     *** TRACKBAR ***
' ########################################################################################

' ========================================================================================
' Clears the current selection range in a trackbar.
' ========================================================================================
PRIVATE SUB Trackbar_ClearSel (BYVAL hTrackbar AS HWND, BYVAL fRedraw AS BOOLEAN = FALSE)
   SendMessageW(hTrackbar, TBM_CLEARSEL, cast(WPARAM, fRedraw), 0)
END SUB
' ========================================================================================

' ========================================================================================
' Removes the current tick marks from a trackbar. This message does not remove the first
' and last tick marks, which are created automatically by the trackbar.
' ========================================================================================
PRIVATE SUB Trackbar_ClearTics (BYVAL hTrackbar AS HWND, BYVAL fRedraw AS BOOLEAN = FALSE)
   SendMessageW(hTrackbar, TBM_CLEARTICS, cast(WPARAM, fRedraw), 0)
END SUB
' ========================================================================================

' ========================================================================================
' Retrieves the handle to a trackbar control buddy window at a given location.
' Value indicating which buddy window handle will be retrieved, by relative location.
' This value can be one of the following:
' - TRUE : Retrieves the handle to the buddy to the left of the trackbar. If the trackbar
'   control uses the TBS_VERT style, the message will retrieve the buddy above the trackbar.
' - FALSE : Retrieves the handle to the buddy to the right of the trackbar. If the trackbar
'   control uses the TBS_VERT style, the message will retrieve the buddy below the trackbar.
' Returns the handle to the buddy window at the location specified by wParam, or NULL if no buddy window exists at that location.
' ========================================================================================
PRIVATE FUNCTION Trackbar_GetBuddy (BYVAL hTrackbar AS HWND, BYVAL fLocation AS LONG) AS HWND
   FUNCTION = cast(HWND, SendMessage(hTrackbar, TBM_GETBUDDY, cast(WPARAM, fLocation), 0))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Retrieves the size and position of the bounding rectangle for a trackbar's channel.
' (The channel is the area over which the slider moves. It contains the highlight when a
' range is selected.)
' ========================================================================================
PRIVATE SUB Trackbar_GetChannelRect (BYVAL hTrackbar AS HWND, BYVAL lprc AS RECT PTR)
   SendMessageW(hTrackbar, TBM_GETCHANNELRECT, 0, cast(LPARAM, lprc))
END SUB
' ========================================================================================

' ========================================================================================
' Retrieves the number of logical positions the trackbar's slider moves in response to
' keyboard input from the arrow keys, such as the or keys. The logical positions are the
' integer increments in the trackbar's range of minimum to maximum slider positions.
' ========================================================================================
PRIVATE FUNCTION Trackbar_GetLineSize (BYVAL hTrackbar AS HWND) AS LONG
   FUNCTION = SendMessageW(hTrackbar, TBM_GETLINESIZE, 0, 0)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Retrieves the number of tick marks in a trackbar.
' ========================================================================================
PRIVATE FUNCTION Trackbar_GetNumTics (BYVAL hTrackbar AS HWND) AS LONG
   FUNCTION = SendMessageW(hTrackbar, TBM_GETNUMTICS, 0, 0)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Retrieves the number of logical positions the trackbar's slider moves in response to
' keyboard input, such as the or keys, or mouse input, such as clicks in the trackbar's
' channel. The logical positions are the integer increments in the trackbar's range of
' minimum to maximum slider positions.
' ========================================================================================
PRIVATE FUNCTION Trackbar_GetPageSize (BYVAL hTrackbar AS HWND) AS LONG
   FUNCTION = SendMessageW(hTrackbar, TBM_GETPAGESIZE, 0, 0)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Retrieves the current logical position of the slider in a trackbar. The logical positions
' are the integer values in the trackbar's range of minimum to maximum slider positions.
' ========================================================================================
PRIVATE FUNCTION Trackbar_GetPos (BYVAL hTrackbar AS HWND) AS LONG
   FUNCTION = SendMessageW(hTrackbar, TBM_GETPOS, 0, 0)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Retrieves the address of an array that contains the positions of the tick marks for a trackbar.
' ========================================================================================
PRIVATE FUNCTION Trackbar_GetPTics (BYVAL hTrackbar AS HWND) AS DWORD
   FUNCTION = SendMessageW(hTrackbar, TBM_GETPTICS, 0, 0)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Retrieves the maximum position for the slider in a trackbar.
' ========================================================================================
PRIVATE FUNCTION Trackbar_GetRangeMax (BYVAL hTrackbar AS HWND) AS LONG
   FUNCTION = SendMessageW(hTrackbar, TBM_GETRANGEMAX, 0, 0)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Retrieves the maximum position for the slider in a trackbar.
' ========================================================================================
PRIVATE FUNCTION Trackbar_GetRangeMin (BYVAL hTrackbar AS HWND) AS LONG
   FUNCTION = SendMessageW(hTrackbar, TBM_GETRANGEMIN, 0, 0)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Retrieves the ending position of the current selection range in a trackbar.
' ========================================================================================
PRIVATE FUNCTION Trackbar_GetSelEnd (BYVAL hTrackbar AS HWND) AS LONG
   FUNCTION = SendMessageW(hTrackbar, TBM_GETSELEND, 0, 0)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Retrieves the starting position of the current selection range in a trackbar.
' ========================================================================================
PRIVATE FUNCTION Trackbar_GetSelStart (BYVAL hTrackbar AS HWND) AS LONG
   FUNCTION = SendMessageW(hTrackbar, TBM_GETSELSTART, 0, 0)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Retrieves the length of the slider in a trackbar.
' ========================================================================================
PRIVATE FUNCTION Trackbar_GetThumbLength (BYVAL hTrackbar AS HWND) AS LONG
   FUNCTION = SendMessageW(hTrackbar, TBM_GETTHUMBLENGTH, 0, 0)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Retrieves the length of the slider in a trackbar.
' ========================================================================================
PRIVATE SUB Trackbar_GetThumbRect (BYVAL hTrackbar AS HWND, BYVAL lprc AS RECT PTR)
   SendMessageW(hTrackbar, TBM_GETTHUMBRECT, 0, cast(LPARAM, lprc))
END SUB
' ========================================================================================

' ========================================================================================
' Retrieves the length of the slider in a trackbar.
' ========================================================================================
PRIVATE FUNCTION Trackbar_GetTic (BYVAL hTrackbar AS HWND, BYVAL iTic AS DWORD) AS LONG
   FUNCTION = SendMessageW(hTrackbar, TBM_GETTIC, cast(WPARAM, iTic), 0)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Retrieves the length of the slider in a trackbar.
' ========================================================================================
PRIVATE FUNCTION Trackbar_GetTicPos (BYVAL hTrackbar AS HWND, BYVAL iTic AS DWORD) AS LONG
   FUNCTION = SendMessageW(hTrackbar, TBM_GETTICPOS, cast(WPARAM, iTic), 0)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Retrieves the handle to the ToolTip control assigned to the trackbar, if any.
' ========================================================================================
PRIVATE FUNCTION Trackbar_GetTooltips (BYVAL hTrackbar AS HWND) AS HWND
   FUNCTION = cast(HWND, SendMessageW(hTrackbar, TBM_GETTOOLTIPS, 0, 0))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Retrieves the Unicode character format flag for the control.
' ========================================================================================
PRIVATE FUNCTION Trackbar_GetUnicodeFormat (BYVAL hTrackbar AS HWND) AS DWORD
   FUNCTION = SendMessageW(hTrackbar, TBM_GETUNICODEFORMAT, 0, 0)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Assigns a window as the buddy window for a trackbar control. Trackbar buddy windows are
' automatically displayed in a location relative to the control's orientation (horizontal
' or vertical).
' Returns the handle to the window that was previously assigned to the control at that location.
' ========================================================================================
PRIVATE FUNCTION Trackbar_SetBuddy (BYVAL hTrackbar AS HWND, BYVAL fLocation AS LONG, BYVAL hwndBuddy AS HWND) AS HWND
   FUNCTION = cast(HWND, SendMessageW(hTrackbar, TBM_SETBUDDY, cast(WPARAM, fLocation), cast(LPARAM, hwndBuddy)))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Sets the number of logical positions the trackbar's slider moves in response to keyboard
' input from the arrow keys, such as the or keys. The logical positions are the integer
' increments in the trackbar's range of minimum to maximum slider positions.
' Returns a 32-bit value that specifies the previous line size.
' Remarks: The default setting for the line size is 1.
' ========================================================================================
PRIVATE FUNCTION Trackbar_SetLineSize (BYVAL hTrackbar AS HWND, BYVAL lLineSize AS LONG) AS LONG
   FUNCTION = SendMessageW(hTrackbar, TBM_SETLINESIZE, 0, lLineSize)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Sets the number of logical positions the trackbar's slider moves in response to keyboard
' input, such as the or keys, or mouse input, such as clicks in the trackbar's channel.
' The logical positions are the integer increments in the trackbar's range of minimum to
' maximum slider positions.
' Returns a 32-bit value that specifies the previous page size.
' ========================================================================================
PRIVATE FUNCTION Trackbar_SetPageSize (BYVAL hTrackbar AS HWND, BYVAL lPageSize AS LONG) AS LONG
   FUNCTION = SendMessage(hTrackbar, TBM_SETPAGESIZE, 0, lPageSize)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Sets the current logical position of the slider in a trackbar.
' ========================================================================================
PRIVATE SUB Trackbar_SetPos (BYVAL hTrackbar AS HWND, BYVAL fPosition AS LONG, BYVAL lPosition AS LONG)
   SendMessageW(hTrackbar, TBM_SETPOS, cast(WPARAM, fPosition), cast(LPARAM, lPosition))
END SUB
' ========================================================================================

' ========================================================================================
' Sets the range of minimum and maximum logical positions for the slider in a trackbar.
' ========================================================================================
PRIVATE SUB Trackbar_SetRange (BYVAL hTrackbar AS HWND, BYVAL lMinimum AS LONG, BYVAL lMaximum AS LONG, BYVAL fRedraw AS BOOLEAN = FALSE)
   SendMessageW(hTrackbar, TBM_SETRANGE, cast(WPARAM, fRedraw), cast(LPARAM, MAKELONG(lMinimum, lMaximum)))
END SUB
' ========================================================================================

' ========================================================================================
' Sets the maximum logical position for the slider in a trackbar.
' ========================================================================================
PRIVATE SUB Trackbar_SetRangeMax (BYVAL hTrackbar AS HWND, BYVAL lMaximum AS LONG, BYVAL fRedraw AS BOOLEAN = FALSE)
   SendMessageW(hTrackbar, TBM_SETRANGEMAX, cast(WPARAM, fRedraw), cast(LPARAM, lMaximum))
END SUB
' ========================================================================================

' ========================================================================================
' Sets the minimum logical position for the slider in a trackbar.
' ========================================================================================
PRIVATE SUB Trackbar_SetRangeMin (BYVAL hTrackbar AS HWND, BYVAL lMinimum AS LONG, BYVAL fRedraw AS BOOLEAN = FALSE)
   SendMessageW(hTrackbar, TBM_SETRANGEMIN, cast(WPARAM, fRedraw), cast(LPARAM, lMinimum))
END SUB
' ========================================================================================

' ========================================================================================
' Sets the starting and ending positions for the available selection range in a trackbar.
' ========================================================================================
PRIVATE SUB Trackbar_SetSel (BYVAL hTrackbar AS HWND, BYVAL lMinimum AS LONG, BYVAL lMaximum AS LONG, BYVAL fRedraw AS BOOLEAN = FALSE)
   SendMessageW(hTrackbar, TBM_SETSEL, cast(WPARAM, fRedraw), cast(LPARAM, MAKELONG(lMinimum, lMaximum)))
END SUB
' ========================================================================================

' ========================================================================================
' Sets the ending logical position of the current selection range in a trackbar. This
' message is ignored if the trackbar does not have the TBS_ENABLESELRANGE style.
' ========================================================================================
PRIVATE SUB Trackbar_SetSelEnd (BYVAL hTrackbar AS HWND, BYVAL lEnd AS LONG, BYVAL fRedraw AS BOOLEAN = FALSE)
   SendMessageW(hTrackbar, TBM_SETSELEND, cast(WPARAM, fRedraw), cast(LPARAM, lEnd))
END SUB
' ========================================================================================

' ========================================================================================
' Sets the starting logical position of the current selection range in a trackbar. This
' message is ignored if the trackbar does not have the BS_ENABLESELRANGE style.
' ========================================================================================
PRIVATE SUB Trackbar_SetSelStart (BYVAL hTrackbar AS HWND, BYVAL lStart AS LONG, BYVAL fRedraw AS BOOLEAN = FALSE)
   SendMessageW(hTrackbar, TBM_SETSELSTART, cast(WPARAM, fRedraw), cast(LPARAM, lStart))
END SUB
' ========================================================================================

' ========================================================================================
' Sets the length of the slider in a trackbar. This message is ignored if the trackbar
' does not have the TBS_FIXEDLENGTH style.
' ========================================================================================
PRIVATE SUB Trackbar_SetThumbLength (BYVAL hTrackbar AS HWND, BYVAL iLength AS LONG)
   SendMessageW(hTrackbar, TBM_SETTHUMBLENGTH, cast(WPARAM, iLength), 0)
END SUB
' ========================================================================================

' ========================================================================================
' Sets a tick mark in a trackbar at the specified logical position.
' ========================================================================================
PRIVATE FUNCTION Trackbar_SetTic (BYVAL hTrackbar AS HWND, BYVAL lPosition AS LONG) AS BOOLEAN
   FUNCTION = SendMessageW(hTrackbar, TBM_SETTIC, 0, cast(WPARAM, lPosition))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Sets the interval frequency for tick marks in a trackbar.
' ========================================================================================
PRIVATE SUB Trackbar_SetTicFreq (BYVAL hTrackbar AS HWND, BYVAL wFreq AS WORD)
   SendMessageW(hTrackbar, TBM_SETTICFREQ, cast(WPARAM, wFreq), 0)
END SUB
' ========================================================================================

' ========================================================================================
' Positions a ToolTip control used by a trackbar control. Trackbar controls that use the
' TBS_TOOLTIPS style display ToolTips.
' ========================================================================================
PRIVATE FUNCTION Trackbar_SetTipSide (BYVAL hTrackbar AS HWND, BYVAL fLocation AS LONG) AS LONG
   FUNCTION = SendMessageW(hTrackbar, TBM_SETTIPSIDE, cast(WPARAM, fLocation), 0)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Assigns a ToolTip control to a trackbar control.
' ========================================================================================
PRIVATE SUB Trackbar_SetToolTips (BYVAL hTrackbar AS HWND, BYVAL hwndTT AS HWND)
   SendMessageW(hTrackbar, TBM_SETTOOLTIPS, cast(WPARAM, hwndTT), 0)
END SUB
' ========================================================================================

' ========================================================================================
' Sets the Unicode character format flag for the control. This message allows you to
' change the character set used by the control at run time rather than having to re-create
' the control. Returns the previous Unicode format flag for the control.
' ========================================================================================
PRIVATE FUNCTION Trackbar_SetUnicodeFormat (BYVAL hTrackbar AS HWND, BYVAL fUnicode AS DWORD) AS DWORD
   FUNCTION = SendMessageW(hTrackbar, TBM_SETUNICODEFORMAT, fUnicode, 0)
END FUNCTION
' ========================================================================================


' ########################################################################################
'                                     *** UPDOWN ***
' ########################################################################################

' ========================================================================================
' Retrieves acceleration information for an up-down control.
' The return value is the number of accelerators currently set for the control.
' ========================================================================================
PRIVATE FUNCTION UpDown_GetAccel (BYVAL hUDM AS HWND, BYVAL cAccels AS DWORD, BYVAL paAccels AS UDACCEL PTR) AS LONG
   FUNCTION = SendMessageW(hUDM, UDM_GETACCEL, cAccels, CAST(LPARAM, paAccels))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Retrieves the current radix base (that is, either base 10 or 16) for an up-down control.
' ========================================================================================
PRIVATE FUNCTION UpDown_GetBase (BYVAL hUDM AS HWND) AS LONG
   FUNCTION = SendMessageW(hUDM, UDM_GETBASE, 0, 0)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Retrieves the handle to the current buddy window.
' ========================================================================================
PRIVATE FUNCTION UpDown_GetBuddy (BYVAL hUDM AS HWND) AS HWND
   FUNCTION = cast(HWND, SendMessageW(hUDM, UDM_GETBUDDY, 0, 0))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Retrieves the current position of an up-down control with 16-bit precision.
' ========================================================================================
PRIVATE FUNCTION UpDown_GetPos (BYVAL hUDM AS HWND) AS LONG
   FUNCTION = SendMessageW(hUDM, UDM_GETPOS, 0, 0)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Returns the 32-bit position of an up-down control.
' ========================================================================================
PRIVATE FUNCTION UpDown_GetPos32 (BYVAL hUDM AS HWND, BYVAL pfError AS LONG PTR = NULL) AS LONG
   FUNCTION = SendMessageW(hUDM, UDM_GETPOS32, 0, cast(LPARAM, pfError))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Returns the 32-bit position of an up-down control.
' ========================================================================================
PRIVATE FUNCTION UpDown_GetRange (BYVAL hUDM AS HWND) AS LONG
   FUNCTION = SendMessageW(hUDM, UDM_GETRANGE, 0, 0)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Returns the 32-bit position of an up-down control.
' ========================================================================================
PRIVATE SUB UpDown_GetRange32 (BYVAL hUDM AS HWND, BYVAL pLow AS WORD PTR, BYVAL pHigh AS WORD PTR)
   SendMessageW(hUDM, UDM_GETRANGE32, cast(WPARAM, pLow), cast(LPARAM, pHigh))
END SUB
' ========================================================================================

' ========================================================================================
' Retrieves the Unicode character format flag for the control.
' ========================================================================================
PRIVATE FUNCTION UpDown_GetUnicodeFormat (BYVAL hUDM AS HWND) AS DWORD
   FUNCTION = SendMessageW(hUDM, UDM_GETUNICODEFORMAT, 0, 0)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Sets the acceleration for an up-down control.
' Returns TRUE if successful, or FALSE otherwise.
' ========================================================================================
PRIVATE FUNCTION UpDown_SetAccel (BYVAL hUDM AS HWND, BYVAL cAccels AS DWORD, BYREF paAccels AS UDACCEL PTR) AS BOOLEAN
   FUNCTION = SendMessageW(hUDM, UDM_SETACCEL, cast(WPARAM, cAccels), cast(LPARAM, paAccels))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Sets the acceleration for an up-down control.
' The return value is the previous base value. If an invalid base is given, the return value is zero.
' ========================================================================================
PRIVATE FUNCTION UpDown_SetBase (BYVAL hUDM AS HWND, BYVAL nBase AS LONG) AS LONG
   FUNCTION = SendMessageW(hUDM, UDM_SETBASE, cast(WPARAM, nBase), 0)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Sets the buddy window for an up-down control.
' The return value is the handle to the previous buddy window.
' ========================================================================================
PRIVATE FUNCTION UpDown_SetBuddy (BYVAL hUDM AS HWND, BYVAL hwndBuddy AS HWND) AS HWND
   FUNCTION = cast(HWND, SendMessageW(hUDM, UDM_SETBUDDY, cast(WPARAM, hwndBuddy), 0))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Sets the current position for an up-down control with 16-bit precision.
' The return value is the previous position.
' ========================================================================================
PRIVATE FUNCTION UpDown_SetPos (BYVAL hUDM AS HWND, BYVAL nPos AS SHORT) AS LONG
   FUNCTION = SendMessageW(hUDM, UDM_SETPOS, 0, cast(LPARAM, MAKELONG(nPos, 0)))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Sets the current position for an up-down control with 32-bit precision.
' The return value is the previous position.
' ========================================================================================
PRIVATE FUNCTION UpDown_SetPos32 (BYVAL hUDM AS HWND, BYVAL nPos AS LONG) AS LONG
   FUNCTION = SendMessageW(hUDM, UDM_SETPOS32, 0, cast(LPARAM, nPos))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Sets the minimum and maximum positions (range) for an up-down control.
' ========================================================================================
PRIVATE SUB UpDown_SetRange (BYVAL hUDM AS HWND, BYVAL nUpper AS SHORT, BYVAL nLower AS SHORT)
   SendMessageW(hUDM, UDM_SETRANGE, 0, MAKELONG(nUpper, nLower))
END SUB
' ========================================================================================

' ========================================================================================
' Sets the minimum and maximum positions (range) for an up-down control.
' ========================================================================================
PRIVATE SUB UpDown_SetRange32 (BYVAL hUDM AS HWND, BYVAL iLow AS LONG, BYVAL iHigh AS LONG)
   SendMessageW(hUDM, UDM_SETRANGE32, cast(WPARAM, iLow), cast(LPARAM, iHigh))
END SUB
' ========================================================================================

' ========================================================================================
' Sets the Unicode character format flag for the control.
' Returns the previous Unicode format flag for the control.
' ========================================================================================
PRIVATE FUNCTION UpDown_SetUnicodeFormat (BYVAL hUDM AS HWND, BYVAL fUnicode AS DWORD) AS DWORD
   FUNCTION = SendMessageW(hUDM, UDM_SETUNICODEFORMAT, cast(WPARAM, fUnicode), 0)
END FUNCTION
' ========================================================================================

' ########################################################################################
'                                   *** TOOLTIPS ***
' ########################################################################################

' ========================================================================================
' Activates or deactivates a ToolTip control.
' ========================================================================================
PRIVATE SUB Tooltip_Activate (BYVAL hTooltip AS HWND, BYVAL fActivate AS BOOLEAN)
   SendMessageW(hTooltip, TTM_ACTIVATE, fActivate, 0)
END SUB
' ========================================================================================

' ========================================================================================
' Registers a tool with a ToolTip control.
' ========================================================================================
PRIVATE FUNCTION Tooltip_AddTool (BYVAL hTooltip AS HWND, BYVAL lpti AS TOOLINFOW PTR) AS BOOLEAN
   FUNCTION = SendMessageW(hTooltip, TTM_ADDTOOLW, 0, CAST(LPARAM, lpti))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Calculates a ToolTip control's text display rectangle from its window rectangle, or the
' ToolTip window rectangle needed to display a specified text display rectangle.
' ========================================================================================
PRIVATE FUNCTION Tooltip_AdjustRect (BYVAL hTooltip AS HWND, BYVAL fLarger AS BOOLEAN, BYVAL lprc AS RECT PTR) AS BOOLEAN
   FUNCTION = SendMessageW(hTooltip, TTM_ADJUSTRECT, cast(WPARAM, fLarger), cast(LPARAM, lprc))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Removes a tool from a ToolTip control.
' ========================================================================================
PRIVATE SUB Tooltip_DelTool (BYVAL hTooltip AS HWND, BYVAL lpti AS TOOLINFOW PTR)
   SendMessageW(hTooltip, TTM_DELTOOLW, 0, cast(LPARAM, lpti))
END SUB
' ========================================================================================

' ========================================================================================
' Retrieves the information that a ToolTip control maintains about the current tool--that
' is, the tool for which the ToolTip is currently displaying text.
' ========================================================================================
PRIVATE FUNCTION Tooltip_EnumTools (BYVAL hTooltip AS HWND, BYVAL iTool AS DWORD, BYVAL lpti AS TOOLINFOW PTR) AS BOOLEAN
   FUNCTION = SendMessageW(hTooltip, TTM_ENUMTOOLSW, cast(WPARAM, iTool), cast(LPARAM, lpti))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Returns the width and height of a ToolTip control.
' ========================================================================================
PRIVATE FUNCTION Tooltip_GetBubbleSize (BYVAL hTooltip AS HWND, BYVAL lpTtm AS TOOLINFOW PTR) AS DWORD
   FUNCTION = SendMessageW(hTooltip, TTM_GETBUBBLESIZE, 0, cast(LPARAM, lpTtm))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Retrieves the information for the current tool in a ToolTip control.
' ========================================================================================
PRIVATE FUNCTION Tooltip_GetCurrentTool (BYVAL hTooltip AS HWND, BYVAL lpti AS TOOLINFOW PTR) AS BOOLEAN
   FUNCTION = SendMessageW(hTooltip, TTM_GETCURRENTTOOLW, 0, cast(LPARAM, lpti))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Retrieves the information for the current tool in a ToolTip control.
' ========================================================================================
PRIVATE FUNCTION Tooltip_GetDelayTime (BYVAL hTooltip AS HWND, BYVAL dwDuration AS DWORD) AS LONG
   FUNCTION = SendMessageW(hTooltip, TTM_GETDELAYTIME, cast(WPARAM, dwDuration), 0)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Retrieves the handle of the font used by the ToolTip control.
' ========================================================================================
PRIVATE FUNCTION Tooltip_GetFont (BYVAL hTooltip AS HWND) AS HFONT
   FUNCTION = cast(HFONT, SendMessageW(hTooltip, WM_GETFONT, 0, 0))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Retrieves the top, left, bottom, and right margins set for a ToolTip window. A margin is
' the distance, in pixels, between the ToolTip window border and the text contained within
' the ToolTip window.
' ========================================================================================
PRIVATE SUB Tooltip_GetMargin (BYVAL hTooltip AS HWND, BYVAL lprc AS RECT PTR)
   SendMessageW(hTooltip, TTM_GETMARGIN, 0, cast(LPARAM, lprc))
END SUB
' ========================================================================================

' ========================================================================================
' Retrieves the maximum width for a ToolTip window.
' ========================================================================================
PRIVATE FUNCTION Tooltip_GetMaxTipWidth (BYVAL hTooltip AS HWND) AS LONG
   FUNCTION = SendMessageW(hTooltip, TTM_GETMAXTIPWIDTH, 0, 0)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Retrieves the information a ToolTip control maintains about a tool.
' ========================================================================================
PRIVATE SUB Tooltip_GetText (BYVAL hTooltip AS HWND, BYVAL numChars AS DWORD, BYVAL lpti AS TOOLINFOW PTR)
   SendMessageW(hTooltip, TTM_GETTEXTW, numChars, cast(LPARAM, lpti))
END SUB
' ========================================================================================

' ========================================================================================
' Retrieves the background color in a ToolTip window.
' ========================================================================================
PRIVATE FUNCTION Tooltip_GetTipBkColor (BYVAL hTooltip AS HWND) AS COLORREF
   FUNCTION = SendMessageW(hTooltip, TTM_GETTIPBKCOLOR, 0, 0)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Retrieves the text color in a ToolTip window.
' ========================================================================================
PRIVATE FUNCTION Tooltip_GetTipTextColor (BYVAL hTooltip AS HWND) AS COLORREF
   FUNCTION = SendMessageW(hTooltip, TTM_GETTIPTEXTCOLOR, 0, 0)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Retrieves information concerning the title of a tooltip control.
' ========================================================================================
PRIVATE SUB Tooltip_GetTitle (BYVAL hTooltip AS HWND, BYVAL pTTGetTitle AS TTGETTITLE PTR)
   SendMessageW(hTooltip, TTM_GETTITLE, 0, cast(LPARAM, pTTGetTitle))
END SUB
' ========================================================================================

' ========================================================================================
' Retrieves a count of the tools maintained by a ToolTip control.
' ========================================================================================
PRIVATE FUNCTION Tooltip_GetToolCount (BYVAL hTooltip AS HWND) AS LONG
   FUNCTION = SendMessageW(hTooltip, TTM_GETTOOLCOUNT, 0, 0)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Retrieves the information that a ToolTip control maintains about a tool.
' ========================================================================================
PRIVATE FUNCTION Tooltip_GetToolInfo (BYVAL hTooltip AS HWND, BYVAL lpti AS TOOLINFOW PTR) AS BOOLEAN
   FUNCTION = SendMessageW(hTooltip, TTM_GETTOOLINFOW, 0, cast(LPARAM, lpti))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Tests a point to determine whether it is within the bounding rectangle of the specified
' tool and, if it is, retrieves information about the tool.
' ========================================================================================
PRIVATE FUNCTION Tooltip_HitTest (BYVAL hTooltip AS HWND, BYVAL lphti AS TTHITTESTINFO PTR) AS BOOLEAN
   FUNCTION = SendMessageW(hTooltip, TTM_HITTEST, 0, cast(LPARAM, lphti))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Sets a new bounding rectangle for a tool.
' ========================================================================================
PRIVATE SUB Tooltip_NewToolRect (BYVAL hTooltip AS HWND, BYVAL lpti AS TOOLINFOW PTR)
   SendMessageW(hTooltip, TTM_NEWTOOLRECTW, 0, cast(LPARAM, lpti))
END SUB
' ========================================================================================

' ========================================================================================
' Removes a displayed ToolTip window from view.
' ========================================================================================
PRIVATE SUB Tooltip_Pop (BYVAL hTooltip AS HWND)
   SendMessageW hTooltip, TTM_POP, 0, 0
END SUB
' ========================================================================================

' ========================================================================================
' Causes the ToolTip to display at the coordinates of the last mouse message.
' ========================================================================================
PRIVATE SUB Tooltip_Popup (BYVAL hTooltip AS HWND)
   SendMessageW hTooltip, TTM_POPUP, 0, 0
END SUB
' ========================================================================================

' ========================================================================================
' Passes a mouse message to a ToolTip control for processing.
' ========================================================================================
PRIVATE FUNCTION Tooltip_RelayEvent (BYVAL hTooltip AS HWND, BYVAL lpmsg AS tagMSG PTR) AS LONG
   FUNCTION = SendMessageW(hTooltip, TTM_RELAYEVENT, 0, cast(LPARAM, lpmsg))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Sets the initial, pop-up, and reshow durations for a ToolTip control.
' ========================================================================================
PRIVATE SUB Tooltip_SetDelayTime (BYVAL hTooltip AS HWND, BYVAL dwDuration AS DWORD, BYVAL iTime AS SHORT)
   SendMessageW(hTooltip, TTM_SETDELAYTIME, dwDuration, MAKELONG(iTime, 0))
END SUB
' ========================================================================================

' ========================================================================================
' Sets the font used by the ToolTip control.
' Parameters:
' - hTooltip  = Handle to the ToolTip control.
' - hFont     = Handle to the font. If this parameter is NULL, the control uses the default
'               system font to draw text.
' - fRedraw   = Specifies whether the control should be redrawn immediately upon setting the font.
'               If this parameter is TRUE, the control redraws itself.
' ========================================================================================
PRIVATE SUB Tooltip_SetFont (BYVAL hTooltip AS HWND, BYVAL hFont AS HFONT = NULL, BYVAL fRedraw AS BOOLEAN = FALSE)
   SendMessageW(hTooltip, WM_SETFONT, cast(WPARAM, hFont), cast(LPARAM, fRedraw))
END SUB
' ========================================================================================

' ========================================================================================
' Sets the top, left, bottom, and right margins for a ToolTip window. A margin is the
' distance, in pixels, between the ToolTip window border and the text contained within the
' ToolTip window.
' ========================================================================================
PRIVATE SUB Tooltip_SetMargin (BYVAL hTooltip AS HWND, BYVAL lprc AS RECT PTR)
   SendMessageW(hTooltip, TTM_SETMARGIN, 0, cast(LPARAM, lprc))
END SUB
' ========================================================================================

' ========================================================================================
' Sets the maximum width for a ToolTip window.
' ========================================================================================
PRIVATE FUNCTION Tooltip_SetMaxTipWidth (BYVAL hTooltip AS HWND, BYVAL iWidth AS LONG) AS LONG
   FUNCTION = SendMessageW(hTooltip, TTM_SETMAXTIPWIDTH, 0, cast(LPARAM, iWidth))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Sets the background color in a ToolTip window.
' ========================================================================================
PRIVATE SUB Tooltip_SetTipBkColor (BYVAL hTooltip AS HWND, BYVAL clr AS COLORREF)
   SendMessageW(hTooltip, TTM_SETTIPBKCOLOR, cast(WPARAM, clr), 0)
END SUB
' ========================================================================================

' ========================================================================================
' Sets the text color in a ToolTip window.
' ========================================================================================
PRIVATE SUB Tooltip_SetTipTextColor (BYVAL hTooltip AS HWND, BYVAL clr AS COLORREF)
   SendMessageW(hTooltip, TTM_SETTIPTEXTCOLOR, cast(WPARAM, clr), 0)
END SUB
' ========================================================================================

' ========================================================================================
' Adds a standard icon and title string to a ToolTip.
' ========================================================================================
PRIVATE FUNCTION Tooltip_SetTitle (BYVAL hTooltip AS HWND, BYVAL nIcon AS LONG, BYVAL pwszTitle AS WSTRING PTR) AS BOOLEAN
   FUNCTION = SendMessageW(hTooltip, TTM_SETTITLEW, nIcon, cast(LPARAM, pwszTitle))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Sets the information that a ToolTip control maintains for a tool.
' ========================================================================================
PRIVATE SUB Tooltip_SetToolInfo (BYVAL hTooltip AS HWND, BYVAL lpti AS TOOLINFOW PTR)
   SendMessageW(hTooltip, TTM_SETTOOLINFOW, 0, cast(LPARAM, lpti))
END SUB
' ========================================================================================

' ========================================================================================
' Sets the visual style of a ToolTip control.
' ========================================================================================
PRIVATE SUB Tooltip_SetWindowTheme (BYVAL hTooltip AS HWND, BYVAL pwszTheme AS WSTRING PTR)
   SendMessageW(hTooltip, TTM_SETWINDOWTHEME, 0, cast(LPARAM, pwszTheme))
END SUB
' ========================================================================================

' ========================================================================================
' Activates or deactivates a tracking ToolTip.
' ========================================================================================
PRIVATE SUB Tooltip_TrackActivate (BYVAL hTooltip AS HWND, BYVAL bActivate AS BOOLEAN, BYVAL lpti AS TOOLINFOW PTR)
   SendMessageW(hTooltip, TTM_TRACKACTIVATE, cast(WPARAM, bActivate), cast(LPARAM, lpti))
END SUB
' ========================================================================================

' ========================================================================================
' Activates or deactivates a tracking ToolTip.
' ========================================================================================
PRIVATE SUB Tooltip_TrackPosition (BYVAL hTooltip AS HWND, BYVAL xPos AS LONG, BYVAL yPos AS LONG)
   SendMessageW(hTooltip, TTM_TRACKPOSITION, 0, cast(LPARAM, MAKELONG(xPos, yPos)))
END SUB
' ========================================================================================

' ========================================================================================
' Activates or deactivates a tracking ToolTip.
' ========================================================================================
PRIVATE SUB Tooltip_Update (BYVAL hTooltip AS HWND)
   SendMessageW(hTooltip, TTM_UPDATE, 0, 0)
END SUB
' ========================================================================================

' ========================================================================================
' Sets the ToolTip text for a tool.
' ========================================================================================
PRIVATE SUB Tooltip_UpdateTipText (BYVAL hTooltip AS HWND, BYVAL lpti AS TOOLINFOW PTR)
   SendMessageW(hTooltip, TTM_UPDATETIPTEXTW, 0, cast(LPARAM, lpti))
END SUB
' ========================================================================================

' ========================================================================================
' Allows a subclass procedure to cause a ToolTip to display text for a window other than
' the one beneath the mouse cursor.
' ========================================================================================
PRIVATE FUNCTION Tooltip_WindowFromPoint (BYVAL hTooltip AS HWND, BYVAL lppt AS POINT PTR) AS HWND
   FUNCTION = cast(HWND, SendMessageW(hTooltip, TTM_WINDOWFROMPOINT, 0, cast(LPARAM, lppt)))
END FUNCTION
' ========================================================================================

' ========================================================================================
' Creates a tooltip for a control.
' Parameters:
' - hwnd      = Handle of the window or control
' - wszText   = Tooltip text
' - bBalloon  = Ballon tip (TRUE or FALSE)
' - bCentered = Centered (TRUE or FALSE)
' Return Value:
'   The handle of the tooltip control
' ========================================================================================
PRIVATE FUNCTION AfxAddTooltip (BYVAL hwnd AS HWND, BYREF wszText AS CONST WSTRING = "", BYVAL bBalloon AS BOOLEAN = FALSE, BYVAL bCentered AS BOOLEAN = FALSE) AS HWND
   IF IsWindow(hwnd) = 0 THEN EXIT FUNCTION
   ' // Creates the tooltip control
   DIM dwStyle AS DWORD = WS_POPUP OR TTS_ALWAYSTIP
   IF bBalloon THEN dwStyle = dwStyle OR TTS_BALLOON
   DIM hTooltip AS HWND
   hTooltip = CreateWindowExW(0, "tooltips_class32", "", dwStyle, 0, 0, 0, 0, NULL, NULL, NULL, NULL)
   IF hTooltip = NULL THEN EXIT FUNCTION
   ' // You must explicitly define a tooltip control as topmost. Otherwise, it might be covered by the parent window.
   SetWindowPos(hTooltip, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE OR SWP_NOSIZE OR SWP_NOACTIVATE)
   ' // Registers the window with the tooltip control
   ' // 32-bit: The size of the TOOLINFOW structure is 48 bytes in
   '    version 6 of comctl32.dll, and 44 bytes in lower versions.
   ' // 64-bit: The size of the TOOLINFOW structure is 72 bytes in
   '    version 6 of comctl32.dll, and 64 bytes in lower versions.
   DIM tti AS TOOLINFOW
#ifdef __FB_64BIT__
   IF AfxComCtlVersion < 600 THEN tti.cbSize = 64 ELSE tti.cbSize = 72
#else
   IF AfxComCtlVersion < 600 THEN tti.cbSize = 44 ELSE tti.cbSize = 48
#endif
   IF (GetWindowLongPtrW(hwnd, GWL_STYLE) AND WS_CHILD) = WS_CHILD THEN
      tti.uFlags = TTF_IDISHWND OR TTF_SUBCLASS
      tti.hwnd = GetParent(hwnd)
      tti.uId = CAST(UINT_PTR, hwnd)
   ELSE
      tti.uFlags = TTF_SUBCLASS
      tti.hwnd = hwnd
      tti.uId = 0
      GetClientRect(hwnd, @tti.rect)
   END IF
   IF bCentered THEN tti.uFlags = tti.uFlags OR TTF_CENTERTIP
   tti.hinst = GetModuleHandleW(NULL)
   tti.lpszText = CAST(LPWSTR, @wszText)
   SendMessageW(hTooltip, TTM_ADDTOOLW, 0, CAST(LPARAM, @tti))
   FUNCTION = hTooltip
END FUNCTION
' ========================================================================================

' ========================================================================================
' Sets/replaces the text of a tooltip control
' Parameters:
' - hTooltip = Handle of the tooltip control
' - hwnd     = Handle of the window or control
' - wszText  = Tooltip text
' ========================================================================================
PRIVATE SUB AfxSetTooltipText (BYVAL hTooltip AS HWND, BYVAL hwnd AS HWND, BYREF wszText AS CONST WSTRING)
   IF hTooltip = NULL OR hwnd = NULL THEN EXIT SUB
   ' // 32-bit: The size of the TOOLINFOW structure is 48 bytes in
   '    version 6 of comctl32.dll, and 44 bytes in lower versions.
   ' // 64-bit: The size of the TOOLINFOW structure is 72 bytes in
   '    version 6 of comctl32.dll, and 64 bytes in lower versions.
   DIM tti AS TOOLINFOW
#ifdef __FB_64BIT__
   IF AfxComCtlVersion < 600 THEN tti.cbSize = 64 ELSE tti.cbSize = 72
#else
   IF AfxComCtlVersion < 600 THEN tti.cbSize = 44 ELSE tti.cbSize = 48
#endif
   IF (GetWindowLongPtrW(hwnd, GWL_STYLE) AND WS_CHILD) = WS_CHILD THEN
      tti.hwnd = GetParent(hwnd)
      tti.uId = CAST(UINT_PTR, hwnd)
   ELSE
      tti.hwnd = hwnd
      tti.uId = 0
   END IF
   ' // Retrieve the tooltip information
   SendMessageW(hTooltip, TTM_GETTOOLINFOW, 0, CAST(LPARAM, @tti))
   IF SendMessageW(hTooltip, TTM_GETTOOLINFOW, 0, CAST(LPARAM, @tti)) THEN
      tti.lpszText = CAST(LPWSTR, @wszText)
      SendMessageW(hTooltip, TTM_SETTOOLINFOW, 0, CAST(LPARAM, @tti))
   END IF
   ' // Note: Windows provides the TTM_UPDATETIPTEXT message, but needs Vista or superior.
END SUB
' ========================================================================================

' ========================================================================================
' Removes a tool from a tooltip control.
' Parameters:
' - hTooltip = Handle of the tooltip control
' - hwnd     = Handle of the window or control
' ========================================================================================
PRIVATE SUB AfxDeleteTooltip (BYVAL hTooltip AS HWND, BYVAL hwnd AS HWND)
   IF hTooltip = NULL OR hwnd = NULL THEN EXIT SUB
   ' // 32-bit: The size of the TOOLINFOW structure is 48 bytes in
   '    version 6 of comctl32.dll, and 44 bytes in lower versions.
   ' // 64-bit: The size of the TOOLINFOW structure is 72 bytes in
   '    version 6 of comctl32.dll, and 64 bytes in lower versions.
   DIM tti AS TOOLINFOW
#ifdef __FB_64BIT__
   IF AfxComCtlVersion < 600 THEN tti.cbSize = 64 ELSE tti.cbSize = 72
#else
   IF AfxComCtlVersion < 600 THEN tti.cbSize = 44 ELSE tti.cbSize = 48
#endif
   IF (GetWindowLongPtrW(hwnd, GWL_STYLE) AND WS_CHILD) = WS_CHILD THEN
      tti.hwnd = GetParent(hwnd)
      tti.uId = CAST(UINT_PTR, hwnd)
   ELSE
      tti.hwnd = hwnd
      tti.uId = 0
   END IF
   ' // Remove the tooltip
   SendMessageW(hTooltip, TTM_DELTOOL, 0, CAST(LPARAM, @tti))
END SUB
' ========================================================================================


' ########################################################################################
'                                   *** PROPSHEET ***
' ########################################################################################

#if _WIN32_WINNT = &h0602

'PSM_SETNEXTTEXTW         = (WM_USER + 137)
'PSM_SETNEXTTEXT          = PSM_SETNEXTTEXTW

PRIVATE SUB PropSheet_SetNextText (BYVAL hDlg AS HWND, BYVAL pwszText AS WSTRING PTR)
   SendMessage(hDlg, WM_USER + 137, 0, cast(LPARAM, pwszText))
END SUB

'PSWIZB_SHOW                    = 0
'PSWIZB_RESTORE                 = 1

'PSM_SHOWWIZBUTTONS             = (WM_USER + 138)

PRIVATE SUB PropSheet_ShowWizButtons (BYVAL hDlg AS HWND, BYVAL dwFlag AS DWORD, BYVAL dwButton AS DWORD)
   SendMessage(hDlg, WM_USER + 138, cast(WPARAM, dwFlag), cast(LPARAM, dwButton))
END SUB

'PSM_ENABLEWIZBUTTONS           = (WM_USER + 139)

PRIVATE SUB PropSheet_EnableWizButtons (BYVAL hDlg AS HWND, BYVAL dwState AS DWORD, BYVAL dwMask AS DWORD)
   SendMessage(hDlg, WM_USER + 139, cast(WPARAM, dwState), cast(LPARAM, dwMask))
END SUB

'PSM_SETBUTTONTEXTW         = (WM_USER + 140)
'PSM_SETBUTTONTEXT          = PSM_SETBUTTONTEXTW

PRIVATE SUB PropSheet_SetButtonText (BYVAL hDlg AS HWND, BYVAL dwButton AS DWORD, BYVAL pwszText AS WSTRING PTR)
   SendMessage(hDlg, WM_USER + 140, cast(WPARAM, dwButton), cast(LPARAM, pwszText))
END SUB

#endif

