Как поймать WM_PAINT от combobox
От: Sandr7  
Дата: 21.09.05 13:48
Оценка:
Создаю comobobox так:
    hwndCombobox = CreateWindow (TEXT ("combobox"), TEXT (""),
        WS_VSCROLL | WS_VISIBLE | WS_CHILD | WS_BORDER | CBS_DROPDOWNLIST,
        5,5,80,100, hWnd, (HMENU) IDC_COMBOBOX, hInstance, NULL);

Затем отлавливаю сообщения отнего:
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    int wmId, wmEvent;
    int temp;

    switch (message) 
    {
        case WM_COMMAND:
            wmId    = LOWORD(wParam); 
            wmEvent = HIWORD(wParam); 
            // Parse the menu selections:
            switch (wmId)
            {    
                case IDC_COMBOBOX:
//возможно где-то тут надо обработать WM_PAINT от Combobox
                    break;
            }
            break;
,,,,,,,,,,,,,,,,,,,,,,,.


Подскажите плиз, как это сделать...
Re: Как поймать WM_PAINT от combobox
От: Кодт Россия  
Дата: 21.09.05 13:54
Оценка: +1
Здравствуйте, Sandr7, Вы писали:

<>

WndProc относится здесь к окну, на котором лежит комбобокс, а не к самому комбобоксу.
Он шлёт туда разные нотификации, включая WM_COMMAND.

S>Подскажите плиз, как это сделать...


3 варианта:
— или сделать его OwnerDrawn, тогда он будет посылать нотификацию хозяину
— или сабклассить конкретный комбобокс (перехватить его оконную функцию)
— или суперклассить (создать оконный класс на основе "combobox" и написать для него оконную функцию)
Перекуём баги на фичи!
Re: Как поймать WM_PAINT от combobox
От: Antech  
Дата: 21.09.05 13:59
Оценка:
Да очень просто. Вам нужно обработать WM_PAINT в оконной процедуре самого комбика. И возвратить ноль.

У меня почему-то не получилось правильно обработать WM_PAINT даже для диалога (класс "#32770") с использованием GetDC/ReleaseDC. Однако, BeginPaint/EndPaint работают нормально, советую использровать эти функции.

Что, надоел дурацкий Client Edge, или голимая кнопочка не по вкусу ? Я делал вообще свой комбик, когда мне понадобилась редактируемая таблица.
Re[2]: Как поймать WM_PAINT от combobox
От: Timeo  
Дата: 21.09.05 15:21
Оценка:
Здравствуйте, Кодт, Вы писали:

К><>

К>WndProc относится здесь к окну, на котором лежит комбобокс, а не к самому комбобоксу.
К>Он шлёт туда разные нотификации, включая WM_COMMAND.
S>>Подскажите плиз, как это сделать...
К>3 варианта:
К>- или сделать его OwnerDrawn, тогда он будет посылать нотификацию хозяину
К>- или сабклассить конкретный комбобокс (перехватить его оконную функцию)
К>- или суперклассить (создать оконный класс на основе "combobox" и написать для него оконную функцию)

И ещё хочу добавить:
комбобокс может быть, как известно SIMPLE, DROPDOWN и DROPDOWNLIST.
В первом случае внутри самого окошечка комбобокса лежат ещё и EDIT и LISTBOX. Если хочется перехватить их перерисовки — это надо делать отдельно, т.е. тут суперкласс не пойдёт, надо сабклассить. Нащупывать эти контрольчики проще всего через GetDlgItem, они имеют фиксированные id (сейчас точно не помню какие именно, но это несложно выяснить). Правда это насчёт id, afaik, нигде не документировано — если хочется по-честному, то это тоже не трудно, контролов там всего два
У DROPDOWN комбобокса тоже есть EDIT и LISTBOX. С EDIT`ом всё так же, как и в SIMPLE'e, а вот LISTBOX уже имеет своим parent'ом не самого combobox'a, а desktop — т.е. найти его значительно сложнее. Ещё у DROPDOWN'a есть кнопка — вот с ней никаких проблем, она нарисована прямо на combobox'e.
DROPDOWNLIST всё как DROPDOWN, но EDIT'a нету. Его эмуляция нарисована прямо поверх combobox'a, т.е. искать уже надо только LISTBOX.

Есть ещё ComboboxEx, но это совсем другая история
Re[3]: Как поймать WM_PAINT от combobox
От: Sandr7  
Дата: 21.09.05 15:59
Оценка:
Здравствуйте, Timeo, Вы писали:

T>И ещё хочу добавить:

T>комбобокс может быть, как известно SIMPLE, DROPDOWN и DROPDOWNLIST.
T>В первом случае внутри самого окошечка комбобокса лежат ещё и EDIT и LISTBOX. Если хочется перехватить их перерисовки — это надо делать отдельно, т.е. тут суперкласс не пойдёт, надо сабклассить. Нащупывать эти контрольчики проще всего через GetDlgItem, они имеют фиксированные id (сейчас точно не помню какие именно, но это несложно выяснить). Правда это насчёт id, afaik, нигде не документировано — если хочется по-честному, то это тоже не трудно, контролов там всего два
T>У DROPDOWN комбобокса тоже есть EDIT и LISTBOX. С EDIT`ом всё так же, как и в SIMPLE'e, а вот LISTBOX уже имеет своим parent'ом не самого combobox'a, а desktop — т.е. найти его значительно сложнее. Ещё у DROPDOWN'a есть кнопка — вот с ней никаких проблем, она нарисована прямо на combobox'e.
T>DROPDOWNLIST всё как DROPDOWN, но EDIT'a нету. Его эмуляция нарисована прямо поверх combobox'a, т.е. искать уже надо только LISTBOX.

T>Есть ещё ComboboxEx, но это совсем другая история


Вот мне как раз надо DROPDOWNLIST, хотклось перерисовать этот самый статический edit не по стандартному...
Попрбую создать свой класс.
А пояните плиз новичку чем отличается суперкласс от сабкласса? Тем что сабкласс наследуется от другого, а суперкласс нет?
Re[2]: Как поймать WM_PAINT от combobox
От: Sandr7  
Дата: 21.09.05 16:03
Оценка:
Здравствуйте, Antech, Вы писали:

A>Да очень просто. Вам нужно обработать WM_PAINT в оконной процедуре самого комбика. И возвратить ноль.


A>У меня почему-то не получилось правильно обработать WM_PAINT даже для диалога (класс "#32770") с использованием GetDC/ReleaseDC. Однако, BeginPaint/EndPaint работают нормально, советую использровать эти функции.


A>Что, надоел дурацкий Client Edge, или голимая кнопочка не по вкусу ? Я делал вообще свой комбик, когда мне понадобилась редактируемая таблица.


Надо сделатб что-то типа LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM); только для combobox'a? WndProc для родительского окна присваивается в MyRegisterClass... А где вызвать эту функцию?

Если можно, хотелось бы увидеть кусок кода...
Re[3]: Как поймать WM_PAINT от combobox
От: Кодт Россия  
Дата: 21.09.05 16:14
Оценка:
Здравствуйте, Sandr7, Вы писали:

S>Надо сделатб что-то типа LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM); только для combobox'a? WndProc для родительского окна присваивается в MyRegisterClass... А где вызвать эту функцию?


S>Если можно, хотелось бы увидеть кусок кода...


Ключевое слово: сабклассинг. Или суперклассинг, но это более громоздко.
HWND hwndCombic = CreateWindow(.....);
SetProp(hwndCombic, "OldProc", // заначим старую процедуру в пользовательское свойство окна - чтобы обойтись без глобальных переменных
  SetWindowLong(hwndCombic, GWL_WNDPROC, MyCombicWndProc)
  );

......

LRESULT CALLBACK MyCombicWndProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp)
{
  WNDPROC oldproc = (WNDPROC)GetProp(hwnd, "OldProc");

  switch(msg)
  {
  case WM_PAINT: .......; return 0;
  }

  return CallWindowProc(oldproc, hwnd, msg, wp, lp);
}
Перекуём баги на фичи!
Re[4]: Как поймать WM_PAINT от combobox
От: Sandr7  
Дата: 21.09.05 18:31
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Ключевое слово: сабклассинг. Или суперклассинг, но это более громоздко.

К>
К>HWND hwndCombic = CreateWindow(.....);
К>SetProp(hwndCombic, "OldProc", // заначим старую процедуру в пользовательское свойство окна - чтобы обойтись без глобальных переменных
К>  SetWindowLong(hwndCombic, GWL_WNDPROC, MyCombicWndProc)
К>  );

К>......

К>LRESULT CALLBACK MyCombicWndProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp)
К>{
К>  WNDPROC oldproc = (WNDPROC)GetProp(hwnd, "OldProc");

К>  switch(msg)
К>  {
К>  case WM_PAINT: .......; return 0;
К>  }

К>  return CallWindowProc(oldproc, hwnd, msg, wp, lp);
К>}
К>


Спасибо, все работает
Re[4]: Как поймать WM_PAINT от combobox
От: Timeo  
Дата: 22.09.05 09:53
Оценка:
Здравствуйте, Sandr7, Вы писали:

S>Вот мне как раз надо DROPDOWNLIST, хотклось перерисовать этот самый статический edit не по стандартному...

S>Попрбую создать свой класс.
S>А пояните плиз новичку чем отличается суперкласс от сабкласса? Тем что сабкласс наследуется от другого, а суперкласс нет?

Сабклассинг:
я создаю готовое окошко исходного класса (т.е. обычный комбобокс), а потом подставляю для этого окошка свою кастомную оконную процедуру, как у Кодта в примере.
Суперклассинг:
я создаю свой кастомный класс окна с моей собственной оконной процедурой — а уже в этой процедуре смотря по сообщению или делаю что мне хочется или вызываю стандартную комбобоксовскую процедуру.

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

Кстати, если тебе хочется только содержимое псевдоэдита по-своему перерисовывать, а вид рамочки и кнопочки тебя не смущают — то можно просто использовать OWNERDRAW комбобокс, это, имхо, будет проще чем с оконными процедурами возиться.
Re[3]: Как поймать WM_PAINT от combobox
От: vdimas Россия  
Дата: 27.09.05 08:41
Оценка:
Здравствуйте, Timeo, Вы писали:

T>У DROPDOWN комбобокса тоже есть EDIT и LISTBOX. С EDIT`ом всё так же, как и в SIMPLE'e, а вот LISTBOX уже имеет своим parent'ом не самого combobox'a, а desktop — т.е. найти его значительно сложнее. Ещё у DROPDOWN'a есть кнопка — вот с ней никаких проблем, она нарисована прямо на combobox'e.


Не надо вводить народ в заблуждение. В режиме DROPDOWN используется не LISTBOX, а ComboLBox. В MSDN находится легко поиском.

Искать этот list-control на десктопе тоже не надо, надо перехватить первое сообщение WM_CTLCOLORLISTBOX, вот здесь подробнее:

ms-help://MS.VSCC.2003/MS.MSDNQTR.2003FEB.1033/enu_kbwin32sdk/en-us/win32sdk/Q131845.htm

(исправьте строку "ms-help://MS.VSCC.2003/MS.MSDNQTR.2003FEB.1033" на свой заголовок в MSDN)


Фиксированный ID edit-control 1001.
Re[4]: Как поймать WM_PAINT от combobox
От: Timeo  
Дата: 28.09.05 13:58
Оценка:
Здравствуйте, vdimas, Вы писали:

T>>У DROPDOWN комбобокса тоже есть EDIT и LISTBOX. С EDIT`ом всё так же, как и в SIMPLE'e, а вот LISTBOX уже имеет своим parent'ом не самого combobox'a, а desktop — т.е. найти его значительно сложнее. Ещё у DROPDOWN'a есть кнопка — вот с ней никаких проблем, она нарисована прямо на combobox'e.

V>Не надо вводить народ в заблуждение. В режиме DROPDOWN используется не LISTBOX, а ComboLBox. В MSDN находится легко поиском.

Легко проверить, что COMBOLBOX — суперкласс LISTBOX'a.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.