Что нового

Как получать события изменения в _GUICtrlComboBoxEx c вставленным ImageList?

inververs

AutoIT Гуру
Сообщения
2,135
Репутация
465
Не понимаю почему перестает работать
Код:
GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")

Если взять обычный пример из функции
Код:
_GUICtrlComboBoxEx_Create
то события WM_NOTIFY приходят и можно получить текущую выделенную строку в Combo.
Но если Combo содержит изображения, то события уже не приходят. Вот как здесь:
Код:
#include <GuiComboBoxEx.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
 #include <GuiImageList.au3>
Global $g_hCombo

Example()

Func Example()
	Local $hGUI

	; Create GUI
	$hGUI = GUICreate("ComboBoxEx Create", 400, 300)
	$g_hCombo = _GUICtrlComboBoxEx_Create($hGUI, "", 2, 2, 394, 100, BitOR($CBS_DROPDOWN,$CBS_DROPDOWNLIST))
	GUISetState(@SW_SHOW)

	GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")

    Local $hImage = _GUIImageList_Create(16, 16, 5, 3)
    _GUIImageList_Add($hImage, _GUICtrlComboBoxEx_CreateSolidBitMap($g_hCombo, 0xFF0000, 16, 16))
    _GUIImageList_Add($hImage, _GUICtrlComboBoxEx_CreateSolidBitMap($g_hCombo, 0x00FF00, 16, 16))
    _GUICtrlComboBoxEx_SetImageList($g_hCombo, $hImage)

    For $x = 0 To 1
        _GUICtrlComboBoxEx_AddString($g_hCombo, StringFormat("%03d : Random string", Random(1, 200, 1)), $x, $x)
    Next

	Do
	Until GUIGetMsg() = $GUI_EVENT_CLOSE
EndFunc   ;==>Example

Func WM_NOTIFY($hWnd, $iMsg, $wParam, $lParam)
	Local $hWndFrom, $iIDFrom, $iCode, $tNMHDR, $tInfo
	ConsoleWrite('WM_NOTIFY' & @CRLF)
EndFunc   ;==>WM_NOTIFY

Как тогда и какие события ловить, что бы знать что выбрали другую элемент в Combo?
 

veretragna

Как писал, так и работает.
Сообщения
140
Репутация
10
Можно как минимум записывать приходящие сообщения и проанализировать.
Нужные сообщения потом можно выцепить.

Код:
Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam)
	#forceref $hWnd, $iMsg, $iwParam
	Local $hWndFrom, $iIDFrom, $iCode, $tNMHDR, $hWndCombo
	$hWndCombo= $g_hCombo
	If Not IsHWnd($g_hCombo) Then $hWndCombo= GUICtrlGetHandle($g_hCombo)

	$tNMHDR = DllStructCreate($tagNMHDR, $ilParam)
	$hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom"))
	$iIDFrom = DllStructGetData($tNMHDR, "IDFrom")
	$iCode = DllStructGetData($tNMHDR, "Code")
	Switch $hWndFrom
		Case $hWndCombo
			FileWrite("log.txt", "0x" & Hex($iCode) & @CRLF)
	EndSwitch
	Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_NOTIFY


Сейчас проверим, как оно работает.

UPD:
Выдает 2 кода: 0xFFFFFCDF и 0xFFFFFFEF, осталось выяснить, что это за константы.
А с другой стороны, можно и не выяснять, просто захардкодить и всего делов (это если работу нужно сделать быстро).
А при наличии свободного времени посмотреть в константы сообщений в Include'ах и присвоить человеческое имя.
 
Автор
inververs

inververs

AutoIT Гуру
Сообщения
2,135
Репутация
465
У вас приходят сообщения когда выбираете элемент, или прокручиваете список колесиком?
 

veretragna

Как писал, так и работает.
Сообщения
140
Репутация
10
Приходят при любых поступающих сообщениях. Щелчок по контролю, прокрутка, выбор элемента - сообщения сыплются валом.
Но разнообразием они не отличаются - только эти 2.
 
Автор
inververs

inververs

AutoIT Гуру
Сообщения
2,135
Репутация
465
Не понимаю, у меня приходят при кликах, при движениях мыши еще какие то, но при выборе элементов или скроле тишина..
 

veretragna

Как писал, так и работает.
Сообщения
140
Репутация
10
Точно, тишина. 0xFFFFFFEF приходит тогда, когда мышью наводим на сам комбо-бокс, а 0xFFFFFCDF - при создании нового элемента в комбе. При щелчках на элементах реально тишина.
Есть вариант проверять еще и "окна" элементов. Возможно, они теперь считаются не родственными с родителем?


Добавлено:
Сообщение автоматически объединено:

Теперь еще интереснее. Если совсем убрать Switch, который фильтрует сообщения по контролям, то приходят те же 2 сообщения. Признаков жизни отдельных контролей не наблюдается - они не посылают WM_NOTIFY при щелчках или выделении. Такое ощущение, что элементы просто выпали из системы. Будем думать


Добавлено:
Сообщение автоматически объединено:

Легким гуглением нашлась вот эта статейка с примерами. Насколько я понял из текста, на элементы с картинками нужно навешивать коллбэк, и только по коллбэку приходит сообщение.


Добавлено:
Сообщение автоматически объединено:

Дополнено-2.

Из статьи:
A ComboBoxEx control notifies its parent window of events by sending WM_NOTIFY messages. Because the control uses a child combo box, it forwards all WM_COMMAND notification messages it receives to the parent window to be processed. Therefore, your application must be prepared to process WM_NOTIFY messages from the ComboBoxEx and WM_COMMAND messages forwarded from the ComboBoxEx's child combo box control.

То есть, сам комбо-бокс отправляет в родительское окно сообщение WM_NOTIFY, а дочерний список с картинками - WM_COMMAND.

Сообщения WM_COMMAND легко ловятся установкой соответствующего GUIRegisterMsg().
Я попробовал перехватывать это сообщение, и приходят вот эти сообщения, с которыми уже можно работать.
Код:
Global Const $CBN_CLOSEUP = 8
Global Const $CBN_DBLCLK = 2
Global Const $CBN_DROPDOWN = 7
Global Const $CBN_EDITCHANGE = 5
Global Const $CBN_EDITUPDATE = 6
Global Const $CBN_ERRSPACE = (-1)
Global Const $CBN_KILLFOCUS = 4
Global Const $CBN_SELCHANGE = 1
Global Const $CBN_SELENDCANCEL = 10
Global Const $CBN_SELENDOK = 9
Global Const $CBN_SETFOCUS = 3


Только что попробовал - заработало.
 
Автор
inververs

inververs

AutoIT Гуру
Сообщения
2,135
Репутация
465
veretragna отличное исследование и решение проблемы. Я у себя перехватывал сообщения WM_COMMAND для контрола но не выделял из них конкретный код, т.к не знал что за 1 и 9 он мне присылал, а вашим дополнением поправлю у себя. Спасибо. Значит тема решена.
 

veretragna

Как писал, так и работает.
Сообщения
140
Репутация
10
Для включения этих констант нужно подключить:
Код:
#include <ComboConstants.au3>

Но это уже мелочи. Рад, что помог.
 
Автор
inververs

inververs

AutoIT Гуру
Сообщения
2,135
Репутация
465
Добавлю решение:
Код:
Func WM_COMMAND($hWnd, $iMsg, $wParam, $lParam)
	;Local Const $CBN_SELCHANGE = 1
    Local $hWndFrom, $iIDFrom, $iCode
    $hWndFrom = $lParam
    $iIDFrom = BitAND($wParam, 0xFFFF) ; Low Word
    $iCode = BitShift($wParam, 16) ; Hi Word

    Switch $hWndFrom
		Case $GUI_CMB_LIST
			Switch $iCode
				Case $CBN_SELCHANGE
					;запись изменилась, можно считать через _GUICtrlComboBoxEx_GetCurSel и _GUICtrlComboBoxEx_GetItemText
			EndSwitch
    EndSwitch
	Return $GUI_RUNDEFMSG
EndFunc
 
Верх