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;
}
WinAPI Rebar Toolbar Bug
Столкнулся с проблемой при использовании тулбара.
При одновременном нажатии левой и правой кнопками мыши на любой из кнопок тулбара кнопка залипает, а также главное окно программы перестаёт отвечать (в WndProc никакие сообщения не приходят). Если убрать фокус с окна (кликнув, например, на рабочем столе), то окно снова начинает принимать сообщения и всё работает.
Данная проблема была также обнаружена в uTorrent, Radmin, Notepad++ (WinRAR, IE - частично, там всех спасает контекстное меню, которое появляется после клика правой кнопкой мыши, но кнопки остаются залипшими).
Вот кусок кода с инициализацией тулбара:
Код:
Написал небольшую консольную программку чтобы выводить сообщения, которые приходят окну в данный момент. Вот результат её работы:
Код:
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
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
Буду очень благодарен если кто-то обьяснит что я делаю не так и что нужно сделать чтобы этого не происходило.
Заранее спасибо.
Скорее всего баг кепчуринга в Common Controls. Напишите в Microsoft.