Как разместить панель инструментов внутри элемента управления редактирования?

мой первоначальная цель должен был поместить кнопку X внутри элемента управления редактирования (позже выяснилось, что этот элемент управления редактирования сам по себе должен быть частью поля со списком). Мне предложили использовать Эта статья в качестве руководства.

Чтобы он выглядел немного «красивее», я решил вместо этого использовать панель инструментов для этой кнопки X. Поэтому я придумал следующий код. Вот как инициализируется элемент управления внутри ComboBox:

//Initialization
#define EDIT_X_TOOLBAR_BTN_W 10
#define EDIT_X_TOOLBAR_BTN_H 11

//Find edit control handle using GetComboBoxInfo() API
COMBOBOXINFO cbi2 = {0};
cbi2.cbSize = sizeof(cbi2);
GetComboBoxInfo(hComboWnd, &cbi2);
HWND hEditCtrl = cbi2.hwndItem;

HINSTANCE hInst = ::GetModuleHandle(NULL);

//Create toolbar as a child of the edit control
hWndToolbar = ::CreateWindowEx(0, TOOLBARCLASSNAME, NULL,
WS_CHILD | WS_VISIBLE |
CCS_NODIVIDER | CCS_NOPARENTALIGN |
CCS_NORESIZE | CCS_NOMOVEY | TBSTYLE_FLAT | TBSTYLE_TRANSPARENT,
0, 0, 0, 0,
hEditCtrl,
(HMENU)ID_CMD_EDIT_X_TOOLBAR, hInst, 0);

::SendMessage(hWndToolbar, TB_BUTTONSTRUCTSIZE, (WPARAM) sizeof(TBBUTTON), 0);
::SendMessage(hWndToolbar, TB_SETBITMAPSIZE, 0, MAKELONG(EDIT_X_TOOLBAR_BTN_W, EDIT_X_TOOLBAR_BTN_H));
::SendMessage(hWndToolbar, TB_SETBUTTONSIZE, 0, MAKELONG(EDIT_X_TOOLBAR_BTN_W, EDIT_X_TOOLBAR_BTN_H));

//Load bitmap
TBADDBITMAP tbab = {0};
tbab.hInst = hInst;
tbab.nID = IDB_BITMAP_TOOLBAR_X;
VERIFY(::SendMessage(hWndToolbar, TB_ADDBITMAP, 1, (LPARAM)&tbab) != -1);

TBBUTTON tbbs[1] = {0};
tbbs[0].iBitmap = 0;
tbbs[0].idCommand = CMD_EDIT_X_TOOLBAR_CLOSE;
tbbs[0].fsState = TBSTATE_ENABLED;
tbbs[0].fsStyle = TBSTYLE_BUTTON;
tbbs[0].iString = -1;

VERIFY(::SendMessage(hWndToolbar, TB_ADDBUTTONS, SIZEOF(tbbs), (LPARAM)tbbs));

//Subclass edit control
oldProc = (WNDPROC)::SetWindowLong(hEditCtrl, GWL_WNDPROC, (LONG)wndProcEditCtrl);

//And redraw the edit control
::SetWindowPos(hEditCtrl, NULL, 0, 0, 0, 0,
SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOZORDER);

И это проклассированное окно proc для элемента управления редактирования:

CRect rcToolbar;

LRESULT CALLBACK wndProcEditCtrl(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_NCCALCSIZE:
{
if(wParam)
{
//First let edit box process it
::CallWindowProc(oldProc, hWnd, msg, wParam, lParam);

RECT* pRc = (RECT*)lParam;

//Define toolbar size & move it
int nTB_w = pRc->bottom - pRc->top;
int nTB_h = nTB_w;

//Adjust the edit's client area
pRc->right -= nTB_w;

//Set toolbar rect
rcToolbar.SetRect(pRc->right, pRc->top, pRc->right + nTB_w, pRc->top + nTB_h);

//And move the toolbar
::MoveWindow(hWndToolbar, pRc->right, pRc->top, nTB_w, nTB_h, TRUE);

return 0;
}
}
break;

case WM_NCHITTEST:
{
POINT pnt;
pnt.x = GET_X_LPARAM(lParam);
pnt.y = GET_Y_LPARAM(lParam);

if(::ScreenToClient(hWnd, &pnt))
{
if(rcToolbar.PtInRect(pnt))
{
return HTBORDER;
}
}
}
break;
}

return ::CallWindowProc(oldProc, hWnd, msg, wParam, lParam);
}

Проблема в том, что я вижу, что панель инструментов создана (через Spy ++), но она остается неактивной, и я не вижу свою кнопку (все, что я получаю, это серый прямоугольник справа):

введите описание изображения здесь

Чтобы убедиться, что я могу создать саму панель инструментов, если я изменю ее родительское окно из элемента управления редактирования (т.е. hEditCtrl) к главному диалоговому окну, оно отображается (в неправильном месте) и прекрасно реагирует на нажатия. Поэтому я пришел к выводу, что я должен блокировать некоторые сообщения в своем подклассе. Вопрос в том, какие?

Есть идеи, что мне здесь не хватает?

3

Решение

Задача ещё не решена.

Другие решения


По вопросам рекламы [email protected]