Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Последние темы форума

Показать новые сообщения »

Почтовая рассылка

Подписчиков: 11654
Последний выпуск: 19.06.2015

WinAPI Rebar Toolbar Bug

35K
18 сентября 2010 года
The Void
3 / / 25.02.2008
Доброго времени суток.

Столкнулся с проблемой при использовании тулбара.
При одновременном нажатии левой и правой кнопками мыши на любой из кнопок тулбара кнопка залипает, а также главное окно программы перестаёт отвечать (в WndProc никакие сообщения не приходят). Если убрать фокус с окна (кликнув, например, на рабочем столе), то окно снова начинает принимать сообщения и всё работает.

Данная проблема была также обнаружена в uTorrent, Radmin, Notepad++ (WinRAR, IE - частично, там всех спасает контекстное меню, которое появляется после клика правой кнопкой мыши, но кнопки остаются залипшими).

Вот кусок кода с инициализацией тулбара:

Код:
int InitElements(HWND hWnd)
{
  DWORD dwStyle;


/* ================ CREATING REBAR ================ */
  dwStyle = WS_VISIBLE | WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS |
            RBS_VARHEIGHT | RBS_BANDBORDERS | RBS_AUTOSIZE |
            CCS_NODIVIDER;

  hRebar = CreateWindowEx(0,
                          REBARCLASSNAME,
                          0,
                          dwStyle,
                          0, 0, 0, 0,
                          hWnd,
                          0,
                          hInst,
                          0);


/* ================ CREATING TOOLBAR ================ */
  dwStyle = WS_VISIBLE | WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS |
            TBSTYLE_FLAT |
            CCS_NODIVIDER;

  hToolbar = CreateWindowEx(TBSTYLE_EX_DOUBLEBUFFER,
                            TOOLBARCLASSNAME,
                            0,
                            dwStyle,
                            0, 0, 0, 0,
                            hRebar,
                            0,
                            hInst,
                            0);


/* ================ FILLING REBAR ================ */
  REBARBANDINFO rbbiBand;

  rbbiBand.cbSize = sizeof(REBARBANDINFO);
  rbbiBand.fMask = RBBIM_CHILD | RBBIM_CHILDSIZE | RBBIM_STYLE;
  rbbiBand.cxMinChild = 0;
  rbbiBand.cyMinChild = 58;
  rbbiBand.fStyle = RBBS_CHILDEDGE; /* GRIPPER - полоска у банда (на ребаре) отвечающая за изменение его размера и позиции (если банд не один) */
  rbbiBand.hwndChild = hToolbar;

  SendMessage (hRebar, RB_INSERTBAND, (WPARAM)-1, (LPARAM) (LPREBARBANDINFO)&rbbiBand);


/* ================ FILLING TOOLBAR ================ */
  SendMessage(hToolbar, TB_SETBITMAPSIZE, 0, MAKELPARAM(48, 48)); // Set image size to 48x48;

  TBADDBITMAP tbabImages[8];
  tbabImages[0].hInst = 0; // use bitmap handles (nID is handle). if not (hInst) - use res id.
  tbabImages[0].nID = (UINT_PTR)BitmapFromIconFromResource(MAKEINTRESOURCE(IDI_ICON_ADDSOURCE), 48, 48);
  tbabImages[1].hInst = 0; // use bitmap handles (nID is handle). if not (hInst) - use res id.
  tbabImages[1].nID = (UINT_PTR)BitmapFromIconFromResource(MAKEINTRESOURCE(IDI_ICON_START), 48, 48);
  /* ... */
  tbabImages[7].hInst = 0; // use bitmap handles (nID is handle). if not (hInst) - use res id.
  tbabImages[7].nID = (UINT_PTR)BitmapFromIconFromResource(MAKEINTRESOURCE(IDI_ICON_MODULES), 48, 48);


  TBBUTTON tbButtons[11];

  tbButtons[0].iBitmap = SendMessage(hToolbar, TB_ADDBITMAP, 1, (LPARAM)&tbabImages[0]); // add 1 icons, get index;
  tbButtons[0].idCommand = IDM_ADD_SOURCE1;
  tbButtons[0].fsState = TBSTATE_ENABLED;
  tbButtons[0].fsStyle = BTNS_AUTOSIZE;
  tbButtons[0].dwData = 0;
  tbButtons[0].iString = 0;

  tbButtons[1].iBitmap = 7; // width of separator
  tbButtons[1].idCommand = 0;
  tbButtons[1].fsState = TBSTATE_ENABLED;
  tbButtons[1].fsStyle = BTNS_SEP; // SEPARATOR
  tbButtons[1].dwData = 0;
  tbButtons[1].iString = 0;

  /* ... */

  tbButtons[10].iBitmap = SendMessage(hToolbar, TB_ADDBITMAP, 1, (LPARAM)&tbabImages[7]); // add 1 icons, get index;
  tbButtons[10].idCommand = IDM_MODULES1;
  tbButtons[10].fsState = TBSTATE_ENABLED;
  tbButtons[10].fsStyle = BTNS_AUTOSIZE;
  tbButtons[10].dwData = 0;
  tbButtons[10].iString = 0;

  SendMessage(hToolbar, TB_BUTTONSTRUCTSIZE, (WPARAM)sizeof(TBBUTTON), 0);

  SendMessage(hToolbar, TB_ADDBUTTONS, (WPARAM)11, (LPARAM)&tbButtons); // 11 buttons.

  SendMessage(hToolbar, TB_AUTOSIZE, 0, 0);

  // status bar //

  dwStyle = WS_VISIBLE | WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;

  hStatusbar = CreateWindowEx(0,
                              STATUSCLASSNAME,
                              0,
                              dwStyle,
                              0, 0, 0, 0,
                              hWnd,
                              0,
                              hInst,
                              0);





  return 0;
}


Написал небольшую консольную программку чтобы выводить сообщения, которые приходят окну в данный момент. Вот результат её работы:


Код:
0x0210: WM_PARENTNOTIFY Code: 0x0204:WM_RBUTTONDOWN // Нажимаю правой кнопкой мыши на кнопку тулбара.
0x0021: WM_MOUSEACTIVATE
0x0020: WM_SETCURSOR
0x004E: WM_NOTIFY       From: 0x1105FC: TOOLBAR Code: 0xFFFFFD43: TBN_BEGINDRAG // Останавливается здесь
0x004E: WM_NOTIFY       From: 0x1D05C6: REBAR   Code: 0xFFFFFFF4: NM_CUSTOMDRAW // Нажимаю левой кнопкой
0x004E: WM_NOTIFY       From: 0x1105FC: TOOLBAR Code: 0xFFFFFFF4: NM_CUSTOMDRAW
0x004E: WM_NOTIFY       From: 0x1105FC: TOOLBAR Code: 0xFFFFFD43: TBN_BEGINDRAG
0x004E: WM_NOTIFY       From: 0x1105FC: TOOLBAR Code: 0xFFFFFFEC: NM_LDOWN
0x004E: WM_NOTIFY       From: 0x1105FC: TOOLBAR Code: 0xFFFFFD36: TBN_DRAGOUT
0x004E: WM_NOTIFY       From: 0x1105FC: TOOLBAR Code: 0xFFFFFD37: TBN_HOTITEMCHANGE
0x004E: WM_NOTIFY       From: 0x1D05C6: REBAR   Code: 0xFFFFFFF4: NM_CUSTOMDRAW
0x004E: WM_NOTIFY       From: 0x1105FC: TOOLBAR Code: 0xFFFFFFF4: NM_CUSTOMDRAW // Останавливается здесь
0x004E: WM_NOTIFY       From: 0x1105FC: TOOLBAR Code: 0xFFFFFFFE: NM_CLICK  // Отпускаю левую кнопку
0x004E: WM_NOTIFY       From: 0x1105FC: TOOLBAR Code: 0xFFFFFFFB: NM_RCLICK // Отпускаю правую кнопку
0x007B: WM_CONTEXTMENU
0x004E: WM_NOTIFY       From: 0x1105FC: TOOLBAR Code: 0xFFFFFD37: TBN_HOTITEMCHANGE // Двигаю курсором в клиентскую область главного окна
0x004E: WM_NOTIFY       From: 0x1D05C6: REBAR   Code: 0xFFFFFFF4: NM_CUSTOMDRAW
0x004E: WM_NOTIFY       From: 0x1105FC: TOOLBAR Code: 0xFFFFFFF4: NM_CUSTOMDRAW
0x004E: WM_NOTIFY       From: 0x1105FC: TOOLBAR Code: 0xFFFFFD37: TBN_HOTITEMCHANGE
0x004E: WM_NOTIFY       From: 0x1D05C6: REBAR   Code: 0xFFFFFFF4: NM_CUSTOMDRAW
0x004E: WM_NOTIFY       From: 0x1105FC: TOOLBAR Code: 0xFFFFFFF4: NM_CUSTOMDRAW // на этом всё. никакие сообщения в WndProc не приходят,

кроме:
0x004E: WM_NOTIFY       From: 0x1105FC: TOOLBAR Code: 0xFFFFFFEC: NM_LDOWN // кликаю левой в клиентской области главного окна
0x004E: WM_NOTIFY       From: 0x1105FC: TOOLBAR Code: 0xFFFFFFFE: NM_CLICK
0x004E: WM_NOTIFY       From: 0x1105FC: TOOLBAR Code: 0xFFFFFFFB: NM_RCLICK // клинаю правой
0x007B: WM_CONTEXTMENU
0x004E: WM_NOTIFY       From: 0x1105FC: TOOLBAR Code: 0xFFFFFFFB: NM_RCLICK
0x007B: WM_CONTEXTMENU
0x004E: WM_NOTIFY       From: 0x1105FC: TOOLBAR Code: 0xFFFFFFFB: NM_RCLICK
0x007B: WM_CONTEXTMENU


Буду очень благодарен если кто-то обьяснит что я делаю не так и что нужно сделать чтобы этого не происходило.
Заранее спасибо.
14
21 сентября 2010 года
Phodopus
3.3K / / 19.06.2008
Скорее всего баг кепчуринга в Common Controls. Напишите в Microsoft.

Знаете кого-то, кто может ответить? Поделитесь с ним ссылкой.

Ваш ответ

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог