Owner Draw Combo Box with default $CBS_DROPDOWN. Not so obvious as it seems.
#include <WinAPIConv.au3>
#include <WinAPIGdi.au3>
#include <GUIConstants.au3>
#include <Constants.au3>
#include <GuiComboBox.au3>
Opt("MustDeclareVars", True)
Global Const $tagDRAWITEMSTRUCT = "uint CtlType;uint CtlID;uint itemID;uint itemAction;uint itemState;hwnd hwndItem;handle hDC;dword rcItem[4];ptr itemData"
Global Const $ODA_DRAWENTIRE = 1
Global Const $ODS_SELECTED = 1
Global $idCombo
Example()
Func Example()
GUICreate("Owner Draw", 300, 200)
$idCombo = GUICtrlCreateCombo("", 10, 10, 185, 20, BitOR($CBS_HASSTRINGS, $CBS_OWNERDRAWFIXED, $GUI_SS_DEFAULT_COMBO))
Local $idClose = GUICtrlCreateButton("Close", 210, 170, 85, 25)
GUICtrlSetData($idCombo, "1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17")
GUISetState()
Local $aAccelKeys[1][2] = [["{ENTER}", $idCombo]]
GUISetAccelerators($aAccelKeys)
GUIRegisterMsg($WM_COMMAND, WM_COMMAND)
GUIRegisterMsg($WM_DRAWITEM, WM_DRAWITEM)
While True
Switch GUIGetMsg()
Case $GUI_EVENT_CLOSE, $idClose
ExitLoop
EndSwitch
WEnd
EndFunc ;==>Example
Func WM_COMMAND($hWnd, $iMsg, $wParam, $lParam)
Local $idCtrl = _WinAPI_LoWord($wParam), $iCode = _WinAPI_HiWord($wParam)
If $idCtrl = $idCombo And ($iCode = $CBN_KILLFOCUS Or $iCode = $CBN_SELCHANGE) Then Validate($idCtrl)
Return $GUI_RUNDEFMSG
EndFunc ;==>WM_COMMAND
Func Validate($idComboBox)
Local Static $sSelection
Local $sComboRead = GUICtrlRead($idComboBox)
If $sSelection = $sComboRead Then Return
Local $iList = _GUICtrlComboBox_FindStringExact($idComboBox, $sComboRead)
If $iList = -1 Then
GUICtrlSendMsg($idComboBox, $CB_SETCURSEL, -1, 0)
$sSelection = ""
ConsoleWrite("Invalid data" & @CRLF)
Else
$sSelection = $sComboRead
ConsoleWrite("Currently displaying: " & $sComboRead & @CRLF)
If _GUICtrlComboBox_GetCurSel($idComboBox) = -1 Then _GUICtrlComboBox_SetCurSel($idComboBox, $iList)
EndIf
EndFunc ;==>Validate
Func WM_DRAWITEM($hWnd, $iMsg, $wParam, $lParam)
If $wParam <> $idCombo Then Return $GUI_RUNDEFMSG
Local $tDraw = DllStructCreate($tagDRAWITEMSTRUCT, $lParam), $sText
If $tDraw.itemAction = $ODA_DRAWENTIRE Then
Local $tRECT = DllStructCreate($tagRECT, DllStructGetPtr($tDraw, "rcItem"))
Local $hBrush = _WinAPI_CreateSolidBrush(BitAND($tDraw.itemState, $ODS_SELECTED) ? 0xFFCDAD : Mod($tDraw.itemID, 2) ? 0xFFFFFF : 0xE0E0E0)
_WinAPI_FillRect($tDraw.hDC, $tRECT, $hBrush)
$tRECT.Left += 5
$tRECT.Top += 2
_GUICtrlComboBox_GetLBText($tDraw.hwndItem, $tDraw.itemID, $sText)
_WinAPI_DrawText($tDraw.hDC, $sText, $tRECT, $DT_LEFT)
_WinAPI_DeleteObject($hBrush)
EndIf
Return $GUI_RUNDEFMSG
EndFunc ;==>WM_DRAWITEM
Note : you can tab, enter, up arrow, down arrow to validate the combo input field.