Как работает combo box
От: Аноним  
Дата: 01.02.11 11:52
Оценка:
Кто знает, как внутри работает combo box. Интересует его popup составляющая, а конкретнее
1) Какое окно активно во время попапа
2) Как list box получает клавиатуру и мышь
3) Как происходит вылавливание ситуаций, когда попак нужно закрыть (а работает оно безотказно, даже если есть мешанина в окнах и их потоках)

Благодарен буду за экономию моего времени.
Re: Как работает combo box
От: Carc Россия https://vk.com/gosha_mazov
Дата: 01.02.11 17:08
Оценка:
Здравствуйте, Chabster, Вы писали:

C>Кто знает, как внутри работает combo box. Интересует его popup составляющая, а конкретнее

C>1) Какое окно активно во время попапа
ListBox
C>2) Как list box получает клавиатуру и мышь
C>3) Как происходит вылавливание ситуаций, когда попак нужно закрыть (а работает оно безотказно, даже если есть мешанина в окнах и их потоках)
Фокус потерялся, и это по любому он потеряется, какая бы мешанина потоков и окон не была. Фокус может иметь только один объект. По уму так вроде бы должно быть...

C>Благодарен буду за экономию моего времени.
Aml Pages Home
Re[2]: Как работает combo box
От: Pavel Dvorkin Россия  
Дата: 01.02.11 17:16
Оценка:
Здравствуйте, Carc, Вы писали:

C>Здравствуйте, Chabster, Вы писали:


C>>Кто знает, как внутри работает combo box. Интересует его popup составляющая, а конкретнее

C>>1) Какое окно активно во время попапа
C>ListBox
C>>2) Как list box получает клавиатуру и мышь
C>>3) Как происходит вылавливание ситуаций, когда попак нужно закрыть (а работает оно безотказно, даже если есть мешанина в окнах и их потоках)
C>Фокус потерялся, и это по любому он потеряется, какая бы мешанина потоков и окон не была. Фокус может иметь только один объект.

Окно в фокусе есть (необязательно) у каждого GUI потока. Другое дело, что это "потенциальный" фокус, то есть просто отмечено в свойствах потока, что вот это окно в фокусе.

GetGUIThreadInfo Function
typedef struct tagGUITHREADINFO {
DWORD cbSize;
DWORD flags;
HWND hwndActive;
HWND hwndFocus;
HWND hwndCapture;
HWND hwndMenuOwner;
HWND hwndMoveSize;
HWND hwndCaret;
RECT rcCaret;
} GUITHREADINFO, *PGUITHREADINFO;

Потенциальный фокус станет "реальным", когда окно в фокусе (или его предок в любом поколении) выйдет на фореграунд. Тогда в это окно в фокусе и будет направлен клавиатурный ввод.
With best regards
Pavel Dvorkin
Re[3]: Как работает combo box
От: Carc Россия https://vk.com/gosha_mazov
Дата: 01.02.11 17:29
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Здравствуйте, Carc, Вы писали:


C>>Здравствуйте, Chabster, Вы писали:


C>>>Кто знает, как внутри работает combo box. Интересует его popup составляющая, а конкретнее

C>>>1) Какое окно активно во время попапа
C>>ListBox
C>>>2) Как list box получает клавиатуру и мышь
C>>>3) Как происходит вылавливание ситуаций, когда попак нужно закрыть (а работает оно безотказно, даже если есть мешанина в окнах и их потоках)
C>>Фокус потерялся, и это по любому он потеряется, какая бы мешанина потоков и окон не была. Фокус может иметь только один объект.

PD>Окно в фокусе есть (необязательно) у каждого GUI потока. Другое дело, что это "потенциальный" фокус, то есть просто отмечено в свойствах потока, что вот это окно в фокусе.

А разве нам не NULL вернет GetFocus() когда наш поток вообще "фореграунд"? (надеюсь понятно выразился, в общем когда никто из нашего потока не имеет "реального" фокуса ввода)
Aml Pages Home
Re[4]: Как работает combo box
От: Pavel Dvorkin Россия  
Дата: 01.02.11 18:09
Оценка:
Здравствуйте, Carc, Вы писали:


C>А разве нам не NULL вернет GetFocus() когда наш поток вообще "фореграунд"? (надеюсь понятно выразился, в общем когда никто из нашего потока не имеет "реального" фокуса ввода)


Если вообще нет фокуса, то да, NULL

Return Value

The return value is the handle to the window with the keyboard focus. If the calling thread's message queue does not have an associated window with the keyboard focus, the return value is NULL.
With best regards
Pavel Dvorkin
Re[5]: Как работает combo box
От: Carc Россия https://vk.com/gosha_mazov
Дата: 01.02.11 22:29
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Здравствуйте, Carc, Вы писали:



C>>А разве нам не NULL вернет GetFocus() когда наш поток вообще "фореграунд"? (надеюсь понятно выразился, в общем когда никто из нашего потока не имеет "реального" фокуса ввода)


PD>Если вообще нет фокуса, то да, NULL


PD>Return Value


PD>The return value is the handle to the window with the keyboard focus. If the calling thread's message queue does not have an associated window with the keyboard focus, the return value is NULL.


Ну дык в контексте стартовой темы: тогда ListBox (гордо названный попапом топикстартером) всегда будет получать WM_KILLFOCUS при потере им фокуса. Если фокус вообще уходит в чужой поток, то в параметре будет NULL, и ListBox по любому схлопнется. Если свой поток, то в параметрах будет HWND куда уходит фокус, и в этом случае ListBox может проверить куда именно уходит фокус и решить самостоятельно как себя вести... Я как бы к этому все вёл... Разве в чем-то не прав?
Aml Pages Home
Re: Как работает combo box
От: c-smile Канада http://terrainformatica.com
Дата: 03.02.11 05:54
Оценка:
Здравствуйте, Chabster, Вы писали:

C>Кто знает, как внутри работает combo box. Интересует его popup составляющая, а конкретнее

C>1) Какое окно активно во время попапа

Окно самого combo box. popup является inactive окном.
Как и меню.

C>3) Как происходит вылавливание ситуаций, когда попак нужно закрыть (а работает оно безотказно, даже если есть мешанина в окнах и их потоках)


Посмотри пример в Windows platform SDK
sdk/Samples/winui/shell/legacysamples/fakemenu/
Это "рыба" для popups. В реальности все сложнее, но ненамного.
Re[2]: Как работает combo box
От: Аноним  
Дата: 03.02.11 11:51
Оценка:
Здравствуйте, c-smile, Вы писали:

CS>Здравствуйте, Chabster, Вы писали:


C>>Кто знает, как внутри работает combo box. Интересует его popup составляющая, а конкретнее

C>>1) Какое окно активно во время попапа

CS>Окно самого combo box. popup является inactive окном.

CS>Как и меню.

C>>3) Как происходит вылавливание ситуаций, когда попак нужно закрыть (а работает оно безотказно, даже если есть мешанина в окнах и их потоках)


CS>Посмотри пример в Windows platform SDK

CS>sdk/Samples/winui/shell/legacysamples/fakemenu/
CS>Это "рыба" для popups. В реальности все сложнее, но ненамного.

Я видел это еще давно. Врядли новомодные выпадающие окна работают так же, как этот устаревший пример.
Поведение date time picker'а от версии 5 к 6 поменялось. Попап с выбором даты остается висеть на экране если он выпал в одном потоке, а щелчок мышью произошел в другом. В версии 6 все работает как часы, ему плевать на потоки и все остальное — окна выбора даты, выпадающие списки — все схлопывается четко.

Меня интересует правильный механизм для выбрасывания выпадающего окна. Варианта два
1) Эмуляция активности окна-родителя: окно теряет активацию, но выглядит как активное; выпадающее окно получает активацию и фокус);
2) Окно-родитель активацию не теряет: выпадающее окно не активируется никогда.

В обоих случаях нужно отлавливать щелчки мышью на посторонних окнах во всех потоках, а также магических образом фильтровать сообщения. Скажем, чтобы во время видимости выпадающего окна элементы управления перестали реагировать на mouse hover. Еще простой пример — клик мышью, приводящий к закрытию выпадающего окна, кушается. Если клацнуть по кнопке — попап схлопнется, но кнопка не нажмется.

Тонкостей куча. Хотелось бы знать четко как работает это в стандартных элементах управления.
Re[3]: Как работает combo box
От: kero Россия  
Дата: 03.02.11 12:55
Оценка:
Здравствуйте, Chabster, Вы писали:

C>Я видел это еще давно. Врядли новомодные выпадающие окна работают так же, как этот устаревший пример.

C>Поведение date time picker'а от версии 5 к 6 поменялось. Попап с выбором даты остается висеть на экране если он выпал в одном потоке, а щелчок мышью произошел в другом. В версии 6 все работает как часы, ему плевать на потоки и все остальное — окна выбора даты, выпадающие списки — все схлопывается четко.
C>Меня интересует правильный механизм для выбрасывания выпадающего окна. Варианта два
C>1) Эмуляция активности окна-родителя: окно теряет активацию, но выглядит как активное; выпадающее окно получает активацию и фокус);
C>2) Окно-родитель активацию не теряет: выпадающее окно не активируется никогда.
C>В обоих случаях нужно отлавливать щелчки мышью на посторонних окнах во всех потоках, а также магических образом фильтровать сообщения. Скажем, чтобы во время видимости выпадающего окна элементы управления перестали реагировать на mouse hover. Еще простой пример — клик мышью, приводящий к закрытию выпадающего окна, кушается. Если клацнуть по кнопке — попап схлопнется, но кнопка не нажмется.
C>Тонкостей куча. Хотелось бы знать четко как работает это в стандартных элементах управления.

Для удовлетворения такого рода любопытства есть только 2 пути:
подружиться с разработчиком и получить исходники...
либо лично самому исследовать всю эту кучу тонкостей.
Ишь, -

Благодарен буду за экономию моего времени

По всему, пашиным хозяевам позарез нужна война в Европе
(уверены — к ним не залетит, в предыдущих двух не залетало жеж)
Автор: kero
Дата: 21.07.14
Re[4]: Как работает combo box
От: Аноним  
Дата: 03.02.11 13:54
Оценка:
Здравствуйте, kero, Вы писали:

K>Для удовлетворения такого рода любопытства есть только 2 пути:

K>подружиться с разработчиком и получить исходники...
K>либо лично самому исследовать всю эту кучу тонкостей.
K>Ишь, -

Благодарен буду за экономию моего времени



Вдруг у кого уже есть експертиза
Все исследования нужно документировать, чтобы с пользой для других.
Re[3]: Как работает combo box
От: c-smile Канада http://terrainformatica.com
Дата: 05.02.11 00:16
Оценка:
Здравствуйте, Chabster, Вы писали:

C>Здравствуйте, c-smile, Вы писали:


CS>>Здравствуйте, Chabster, Вы писали:


C>>>Кто знает, как внутри работает combo box. Интересует его popup составляющая, а конкретнее

C>>>1) Какое окно активно во время попапа

CS>>Окно самого combo box. popup является inactive окном.

CS>>Как и меню.

C>>>3) Как происходит вылавливание ситуаций, когда попак нужно закрыть (а работает оно безотказно, даже если есть мешанина в окнах и их потоках)


CS>>Посмотри пример в Windows platform SDK

CS>>sdk/Samples/winui/shell/legacysamples/fakemenu/
CS>>Это "рыба" для popups. В реальности все сложнее, но ненамного.

C>Я видел это еще давно. Врядли новомодные выпадающие окна работают так же, как этот устаревший пример.

C>Поведение date time picker'а от версии 5 к 6 поменялось. Попап с выбором даты остается висеть на экране если он выпал в одном потоке, а щелчок мышью произошел в другом. В версии 6 все работает как часы, ему плевать на потоки и все остальное — окна выбора даты, выпадающие списки — все схлопывается четко.

Это бага date time picker'а. Оно вообще на удивление баганутое.

Ну и потом код например DialogBox() в windows sources датирован еще 95 или близко к тому годом.
Сильно ничего не меняется. И это хорошо.

C>2) Окно-родитель активацию не теряет: выпадающее окно не активируется никогда.


Это правильный механизм. Любое другое решение — грязный хак.

C>Тонкостей куча. Хотелось бы знать четко как работает это в стандартных элементах управления.


Тот пример что я дал написан Raymond Chen'ом (http://blogs.msdn.com/b/oldnewthing/). Оченно авторитетный товарищ в Windows UI и Shell.
Re[4]: Как работает combo box
От: kero Россия  
Дата: 05.02.11 01:33
Оценка:
Здравствуйте, c-smile, Вы писали:

CS>Любое другое решение — грязный хак.


Что такое грязный хак ?
По всему, пашиным хозяевам позарез нужна война в Европе
(уверены — к ним не залетит, в предыдущих двух не залетало жеж)
Автор: kero
Дата: 21.07.14
Re[5]: Как работает combo box
От: c-smile Канада http://terrainformatica.com
Дата: 05.02.11 02:58
Оценка:
Здравствуйте, kero, Вы писали:

K>Здравствуйте, c-smile, Вы писали:


CS>>Любое другое решение — грязный хак.


K>Что такое грязный хак ?


Это любое другое решение.
Re[6]: Как работает combo box
От: kero Россия  
Дата: 05.02.11 04:32
Оценка:
Здравствуйте, c-smile, Вы писали:

CS>>>Любое другое решение — грязный хак.


K>>Что такое грязный хак ?


CS>Это любое другое решение.


весьма благодарен за экономию моего времени, сам бы не допер.
По всему, пашиным хозяевам позарез нужна война в Европе
(уверены — к ним не залетит, в предыдущих двух не залетало жеж)
Автор: kero
Дата: 21.07.14
Re[7]: Как работает combo box
От: c-smile Канада http://terrainformatica.com
Дата: 05.02.11 04:43
Оценка:
Здравствуйте, kero, Вы писали:

K>Здравствуйте, c-smile, Вы писали:


CS>>>>Любое другое решение — грязный хак.


K>>>Что такое грязный хак ?


CS>>Это любое другое решение.


K>весьма благодарен за экономию моего времени, сам бы не допер.


Ты бы блин гораздо больше времени с'экономил корректно сформулировав свой вопрос.
Что тебя кокретно интересует? Это http://www.flickr.com/photos/randomskk/3226059874/ ?
Re[8]: Как работает combo box
От: kero Россия  
Дата: 05.02.11 09:45
Оценка:
Здравствуйте, c-smile, Вы писали:

CS>>>>>Любое другое решение — грязный хак.


K>>>>Что такое грязный хак ?


CS>>>Это любое другое решение.


K>>весьма благодарен за экономию моего времени, сам бы не допер.


CS>Ты бы блин гораздо больше времени с'экономил корректно сформулировав свой вопрос.

CS>Что тебя кокретно интересует? Это http://www.flickr.com/photos/randomskk/3226059874/ ?

Хоспиди, да пошутил я, пошутил. Был уверен, что и ты пошутил. А также, что для c-smile вспомогательные смайлики без надобности. А оно, выходит, вот оно как...
По всему, пашиным хозяевам позарез нужна война в Европе
(уверены — к ним не залетит, в предыдущих двух не залетало жеж)
Автор: kero
Дата: 21.07.14
Re[4]: Как работает combo box
От: Аноним  
Дата: 05.02.11 18:44
Оценка:
Здравствуйте, c-smile, Вы писали:

CS>Тот пример что я дал написан Raymond Chen'ом (http://blogs.msdn.com/b/oldnewthing/). Оченно авторитетный товарищ в Windows UI и Shell.


Андрей, там пример очень простой. Вывалить окно, запретить его активацию и сожрать мышь — ерундовое дело.

Я для .NET-а сделал класс, который показывает произвольную форму в качестве выпадающего окна. Грязным хаком создается видимость активности окна-владельца, выпадающее окно получает активацию, фокус работает как положено. Но, судя по combo-box'у, который схлопывается в любом случае, мое выпадающее окно не покрывает все сценарии схлопывания. Ровно как не выполняет необходимую фильтрацию сообщений хуком. Нужно ли съедать все мышиные сообщения, которые не относятся к выпадающему окну и его содержимому? Наверное. Нужно следить за щелчками на всем, кроме выпадающего окна и его содержимого. Наверное. И т.д.

Пример Чена простой в том плане, что выпадающее окно не содержит вложенных окон, не нужна нафигация клавиатурой, отображение фокуса, кнопок (как на окне выбора даты в новомодных Windows Vista/7). Combo-box же вываливает list-box, а это полноценное окно, со своими обработчиками клавиатуры, крысы и пр. И вот тут я не могу понять как это все реализовано. Учитывая, что сам combo-box не теряет фокус.
Re[5]: Как работает combo box
От: c-smile Канада http://terrainformatica.com
Дата: 05.02.11 20:24
Оценка:
Здравствуйте, Chabster, Вы писали:

C>Здравствуйте, c-smile, Вы писали:


CS>>Тот пример что я дал написан Raymond Chen'ом (http://blogs.msdn.com/b/oldnewthing/). Оченно авторитетный товарищ в Windows UI и Shell.


C>Андрей, там пример очень простой. Вывалить окно, запретить его активацию и сожрать мышь — ерундовое дело.


C>Я для .NET-а сделал класс, который показывает произвольную форму в качестве выпадающего окна. Грязным хаком создается видимость активности окна-владельца, выпадающее окно получает активацию, фокус работает как положено. Но, судя по combo-box'у, который схлопывается в любом случае, мое выпадающее окно не покрывает все сценарии схлопывания. Ровно как не выполняет необходимую фильтрацию сообщений хуком. Нужно ли съедать все мышиные сообщения, которые не относятся к выпадающему окну и его содержимому? Наверное. Нужно следить за щелчками на всем, кроме выпадающего окна и его содержимого. Наверное. И т.д.


"Грязным хаком создается видимость активности окна-владельца"

Это действительно хак. В свое время я получил по пальцам за это практически буквально.
Да, визуально ты можешь подавить эффект активности но IAccessible и все что вокруг него (например NotifyWinEvent())
продолжает считать не то окно активным. Там много еще других интерференций на самом деле.

C>Пример Чена простой в том плане, что выпадающее окно не содержит вложенных окон, не нужна нафигация клавиатурой, отображение фокуса, кнопок (как на окне выбора даты в новомодных Windows Vista/7). Combo-box же вываливает list-box, а это полноценное окно, со своими обработчиками клавиатуры, крысы и пр. И вот тут я не могу понять как это все реализовано. Учитывая, что сам combo-box не теряет фокус.


Тот пример и ценен тем что он простой. Объясняет базовый принцип.

"И вот тут я не могу понять как это все реализовано."

Да ничего там особо сложного нет (как я понимаю).
Функция окна combobox (active,in-focus) получает все сообщения, транслирует те что нужно и передает их в функцию окна listbox.
На самом деле там по идее должна быть не совсем стандартная функция listbox, есть отличия. Например mouse hover по разному обрабатывается.

Основная проблема состоит в том что popup не активное окно. Его функция окна (и DefWindowProc) не должны получать WM_LBUTTONDOWN, etc.
Иначе будет активация окна — нам она не нужна. Чен сделал забор WM_LBUTTONDOWN c помощью SetCapture но это не работает с дочерними окнами на popup.

Перенаправление WM_LBUTTONDOWN со товарищи в Функцию окна combobox я так понимаю делается внутри DispatchMessage().
В которую мы влезть не можем. Поэтому два варианта:

1) Или писать свой DispatchMessage() и просить чтобы все юзеры в message pump вставляли MyDispatchMessage() вместо стандартного либо
2) Ставить хук в GUI thread и делать все там.

Оба способа 100% валидно-документирваны. Какой из них использовать зависит от типа того что ты строишь.

Как-то так.
Re[6]: Как работает combo box
От: Аноним  
Дата: 05.02.11 21:00
Оценка:
Здравствуйте, c-smile, Вы писали:

CS>Оба способа 100% валидно-документирваны. Какой из них использовать зависит от типа того что ты строишь.


CS>Как-то так.


Ну, я предполагаю те же танцы с оконной процедурой, хуком сообщений и их специальной обработкой.

В общем получается, что выпадающее окно не должно забирать активации, соответственно оно должно быть цельным, не содержать вложенных окон. Как вариант — windowless реализация вложенных элементов управления.

Иначе даже самый простой пример с двумя кнопками, которые должны отображать фокус и выбираться табом, превращается в ад.
Re: Как работает combo box
От: ak_miass Россия  
Дата: 05.02.11 21:19
Оценка:
C>Кто знает, как внутри работает combo box.
Когда-то очень давно делал самописный контрол, похожий на ComboBox, но там выпадал движок для каких-то там децибелов для микрофона
Помню, что нюансов было очень много, вот те которые сразу вспомнились:
1. Выпадающее окно показывал и скрывал только с помощью SetWindowPos с флагами SWP_SHOWWINDOW, SWP_HIDEWINDOW и SWP_NOACTIVATE. Это чтобы выпадающее окно не забирало фокус.
2. Нужно было ловить WM_MOUSEACTIVATE, тоже чтобы не забирать фокус, когда тычут мышкой.
3. Вроде были ещё какие-то пляски вокруг SetCapture\ReleaseCapture, но уже не помню зачем
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.