我在程序中用 SetWindowRgn() 改变了主窗口区域,隐藏了标题栏。又响应了窗口的 WM_NCHITTEST 事件:
UINT SMyWnd::OnNcHitTest(CPoint point)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
return HTCAPTION;
}
使得在窗口上任意一点都可以移动窗口。
但若将窗口向屏幕上方移动,使它一部分移出屏幕之外后,系统会自动将窗口下移,使原来标题栏的一部分移到屏幕中(虽然此时标题栏已不可见)。
我用过 RealOne Player ,发现它可以任意地移动,不会出现上面所说的现象。
请问这应该怎样实现?
UINT SMyWnd::OnNcHitTest(CPoint point)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
return HTCAPTION;
}
使得在窗口上任意一点都可以移动窗口。
但若将窗口向屏幕上方移动,使它一部分移出屏幕之外后,系统会自动将窗口下移,使原来标题栏的一部分移到屏幕中(虽然此时标题栏已不可见)。
我用过 RealOne Player ,发现它可以任意地移动,不会出现上面所说的现象。
请问这应该怎样实现?
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
..................
static bIsMoving = false;
switch(message)
{
case WM_LBUTTONDOWN:
static RECT r;
static POINT p;
::GetWindowRect(hWnd,&r);
::GetCursorPos(&p);
bIsMoving = true;
//该句保证鼠标消息始终发给该程序,如果注释掉该句和下面语句2,
//程序也能正常运行,但当在窗口边缘按下鼠标左键并迅速移到窗口外时
//就有问题了。
SetCapture(hWnd);
break;
case WM_MOUSEMOVE:
POINT p2;
if(bIsMoving)
{
::GetCursorPos(&p2);
r.left += p2.x-p.x;//计算鼠标移动距离,加到窗口的坐标上
r.top += p2.y-p.y;
p.x = p2.x;
p.y = p2.y;
SetWindowPos(hWnd,NULL,r.left,r.top,0,0,SWP_NOSIZE|SWP_NOZORDER);
}
break;
case WM_LBUTTONUP:
if(bIsMoving)
{
ReleaseCapture();//语句2
bIsMoving = false;
}
break;
default:
........
}
}
你仔细观察一下,用你写的代码移动窗口时移动的是一个虚线框(在显示属性中不选中“移动时显示窗口内容”,而有的程序则是跟着鼠标移动,比如Winamp和我的代码)
其实窗口并不是真的在移动,而是程序不停的根据鼠标位置调整窗口位置。
另:bIsMoving是bool型的,忘记写了,不过也没问题。
你的程序确实和 RealOne Player 看上去一样,而且如果你在标题栏或任务栏上点右键,选移动,再用箭头键将窗口向上移动,Enter,就又会出现我问题中的现象,这也和 RealOne Player 一样:-)
不知你是否有办法将用键盘移动的也搞定?