您的位置:首页 > 其它

MFC Windows 程序设计->实现客户区拖动

2011-04-02 18:01 561 查看
One problem with a window without a title bar is that it can't be
repositioned with the mouse. Windows are dragged by their title bars, and when
there's no title bar, the user has nothing to grab onto. Clock solves this
little dilemma by playing a trick with the window's WM_NCHITTEST handler so that
the window can be dragged by its client area, a feature Windows programmers call
client-area drag.

In Windows, every mouse message is preceded by a WM_NCHITTEST message
containing screen coordinates identifying the cursor location. The message is
normally handled by ::DefWindowProc, which returns a code that tells
Windows what part of the window the cursor is over. Windows uses the return
value to decide what type of mouse message to send. For example, if the left
mouse button is clicked over the window's title bar, ::DefWindowProc's
WM_NCHITTEST handler returns HTCAPTION and Windows sends the window a
WM_NCLBUTTONDOWN message. If ::DefWindowProc returns HTCLIENT instead,
Windows converts the cursor coordinates from screen coordinates to client
coordinates and passes them to the window in a WM_LBUTTONDOWN message.

The fact that an application sees mouse messages in raw form makes for some
interesting possibilities. The following OnNcHitTest handler implements
client-area drag by fooling Windows into thinking that the mouse is over the
title bar when in fact it's over the window's client area:

UINT CMainWindow::OnNcHitTest (CPoint point)
{
UINT nHitTest = CFrameWnd::OnNcHitTest (point);
if (nHitTest == HTCLIENT)
nHitTest = HTCAPTION;
return nHitTest;
}
[/code]
With this OnNcHitTest handler in place, a window is as easily dragged
by its client area as by its title bar. And it works even if the window doesn't
have a title bar. Try it: click the left mouse button in Clock's client
area, and move the mouse with the button held down. The window should go
wherever the mouse goes.

Clock uses an OnNcHitTest handler similar to the one shown above. The
only difference is that Clock verifies that the left mouse button is down before
replacing an HTCLIENT return code with HTCAPTION so that other mouse
messages—particularly right-button mouse messages that precede WM_CONTEXTMENU
messages—will get through unscathed:

UINT CMainWindow::OnNcHitTest (CPoint point)
{
UINT nHitTest = CFrameWnd::OnNcHitTest (point);
if ((nHitTest == HTCLIENT) &&
(::GetAsyncKeyState (MK_LBUTTON) < 0))
nHitTest = HTCAPTION;
return nHitTest;
}
[/code]
The call to ::GetAsyncKeyState checks the left mouse button and
returns a negative value if the button is currently down.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: