У меня проблемы с обнаружением зависания над статическим элементом управления Win32.
Это не повторяющаяся проблема, потому что здесь ищет несколько статических элементов управления, а не просто ищет один известный дескриптор статического элемента управления во время компиляции.
Хотя это можно сделать за несколько секунд на другом языке, я немного расстроился после того, как попробовал несколько часов. Я надеюсь получить ответ здесь.
Сначала я создал класс с именем Label. Я создаю статическое окно управления внутри него. Сейчас я буду называть статическую метку.
// Create the label's handle.
m_handle = CreateWindowEx(NULL, "static", m_text.c_str(),
WS_CHILD | SS_LEFT | SS_NOTIFY, m_x, m_y, m_width, m_height,
m_parentWindow, (HMENU)(UINT_PTR)m_id, m_hInstance, NULL);
if (m_handle == NULL)
return false;
Когда указатель мыши находится над этой меткой, должен вызываться следующий метод:
void Label::invokeOnMouseHover()
{
if (m_onMouseOver)
m_onMouseOver();
}
Это вызовет мой метод:
void lblName_onMouseOver()
{
MessageBox::show("Hovering!", "My Console",
MessageBoxButtons::Ok, MessageBoxIcon::Information);
}
Вот как я создаю его с верхнего уровня:
Label lblName("This is a label.", 0, 0);
lblName.setVisible(true);
lblName.OnMouseOver(lblName_onMouseOver);
frm.add(lblName);
Признайся, этот тонкий слой прекрасен.
В то время как мои обратные вызовы нормально работают для моих элементов управления Button и Checkbox, я заметил, что статика немного отличается.
Итак, давайте пройдемся по нескольким уровням:
Это в процедуре главного окна:
case WM_MOUSEMOVE:
{
int xPos = LOWORD(lParam);
int yPos = HIWORD(lParam);
frm.setMousePos(xPos, yPos);
// Get the static's id
int id = // ?? Which static control id is it out of several?
// Obtain the control associated with the id.
X3D::Windows::Control *ctrl = frm.getControls().find(id)->second;
if (ctrl == NULL)
return 0;
// Check if this is a X3D Label control.
if (typeid(*ctrl) == typeid(X3D::Windows::Label))
{
Label *lbl = dynamic_cast<X3D::Windows::Label*>(ctrl);
int xPos = GET_X_LPARAM(lParam);
int yPos = GET_Y_LPARAM(lParam);
if (xPos >= lbl->getX() &&
yPos >= lbl->getY() &&
(xPos < (lbl->getX() + lbl->getWidth())) &&
(yPos < (lbl->getY() + lbl->getHeight())))
{
if (lbl != NULL)
lbl->invokeOnMouseHover();
}
}
}
break;
То, что я пытаюсь сделать здесь, - это определить, какой идентификатор метки был обнаружен, а затем вызвать Label :: invokeOnMouseOver ().
Несмотря на то, что я понимаю, что в какой-то момент мне нужно использовать TRACKMOUSEEVENT, его член поля 'HWND' требует дескриптора метки. Но я не могу легко сказать, какая ручка будет, потому что коллекция может содержать одну или несколько меток.
В целом, я ищу предложения о том, как реструктурировать это или посмотреть, есть ли здесь простое решение. Я думаю, что я обдумываю это.
Спасибо.
Обновление:
Вот обновление кода после прочтения первого ответа с первым решением. Хотя это решает проблему наведения, я не вижу текст метки при исполнении.
case WM_MOUSEMOVE:
{
int xPos = LOWORD(lParam);
int yPos = HIWORD(lParam);
// Get the mouse position
frm.setMousePos(xPos, yPos);
// Check for labels
X3D::Windows::Control *ctrl = (X3D::Windows::Control*)GetWindowLongPtr(hWnd, GWLP_USERDATA);
if (ctrl)
{
// Check if this is a X3D Label control.
Label *lbl = dynamic_cast<X3D::Windows::Label*>(ctrl);
if (lbl)
lbl->invokeOnMouseHover();
return CallWindowProc(lbl->getOldProc(), hWnd, msg, wParam, lParam);
}
}
break;
И управление созданием:
// Create the label's handle.
m_handle = CreateWindowEx(NULL, TEXT("static"), m_text.c_str(),
WS_CHILD | SS_LEFT | SS_NOTIFY, m_x, m_y, m_width, m_height,
m_parentWindow, (HMENU)(UINT_PTR)m_id, m_hInstance, NULL);
if (!m_handle)
return false;
SetWindowLongPtr(m_handle, GWLP_USERDATA, (LONG_PTR)(X3D::Windows::Control*)this);
m_oldProc = (WNDPROC)SetWindowLongPtr(m_handle, GWLP_WNDPROC, (LONG_PTR)&wndProc);
Если это проблема с краской, это то, что у меня есть в WndProc.
case WM_PAINT:
{
hDC = BeginPaint(hWnd, &ps);
EndPaint(hWnd, &ps);
return 0;
}
break;
Обновление № 2:
Альтернативное решение исправило проблему.
Если у кого-то возникнут проблемы с неразрешенными внешними символами с помощью SetWindowSubclass () в будущем, не забудьте добавить в свой проект следующее или просто #pragma it:
#pragma comment(lib, "comctl32.lib")