wxWidgets and WM_NCHITTEST
I am using wxWidgets with Visual C++ 2010.
One of my goals is being able to move a frame I created with any part of the window (client or otherwise). For this purpose, I have used WM_NCHITTEST in the past to fo开发者_开发技巧ol Windows into thinking every part of my window is the title bar. How should that be done in wxWidgets?After extensive research, due to inactivity on the answering department, I've found a somewhat acceptable (although not portable) solution:
WXLRESULT [your-wxWindow-inheriting-objectname-here]::MSWWindowProc(WXUINT message,WXWPARAM wParam,WXLPARAM
lParam)
{
if(message==WM_NCHITTEST) { return HTCAPTION; }
return wxFrame::MSWWindowProc(message,wParam,lParam);
}
This can be used for any WINAPI message.
another portable solution maybe like this:
//assume your frame named wxUITestFrame
//headers
class wxUITestFrame : public wxFrame
{
DECLARE_EVENT_TABLE()
protected:
void OnMouseMove(wxMouseEvent& event);
void OnLeftMouseDown(wxMouseEvent& event);
void OnLeftMouseUp(wxMouseEvent& event);
void OnMouseLeave(wxMouseEvent& event);
private:
bool m_isTitleClicked;
wxPoint m_mousePosition; //mouse position when title clicked
};
//cpp
BEGIN_EVENT_TABLE(wxUITestFrame, wxFrame)
EVT_MOTION(wxUITestFrame::OnMouseMove)
EVT_LEFT_DOWN(wxUITestFrame::OnLeftMouseDown)
EVT_LEFT_UP(wxUITestFrame::OnLeftMouseUp)
EVT_LEAVE_WINDOW(wxUITestFrame::OnMouseLeave)
END_EVENT_TABLE()
void wxUITestFrame::OnMouseMove( wxMouseEvent& event )
{
if (event.Dragging())
{
if (m_isTitleClicked)
{
int x, y;
GetPosition(&x, &y); //old window position
int mx, my;
event.GetPosition(&mx, &my); //new mouse position
int dx, dy; //changed mouse position
dx = mx - m_mousePosition.x;
dy = my - m_mousePosition.y;
x += dx;
y += dy;
Move(x, y); //move window to new position
}
}
}
void wxUITestFrame::OnLeftMouseDown( wxMouseEvent& event )
{
if (event.GetY() <= 40) //40 is the height you want to set for title bar
{
m_isTitleClicked = true;
m_mousePosition.x = event.GetX();
m_mousePosition.y = event.GetY();
}
}
void wxUITestFrame::OnLeftMouseUp( wxMouseEvent& event )
{
if (m_isTitleClicked)
{
m_isTitleClicked = false;
}
}
void wxUITestFrame::OnMouseLeave( wxMouseEvent& event )
{
//if mouse dragging too fase, we will not get mouse move event
//instead of mouse leave event here.
if (m_isTitleClicked)
{
int x, y;
GetPosition(&x, &y);
int mx, my;
event.GetPosition(&mx, &my);
int dx, dy;
dx = mx - m_mousePosition.x;
dy = my - m_mousePosition.y;
x += dx;
y += dy;
Move(x, y);
}
}
Actually, the solution mentioned by John Locke at 1st Floor is more
suggested in wxMSW, and in linux like system we can simulate ALT BUTTON DOWN message when title is clicked.
精彩评论