我生成的一个无边框对话框,添加了左键按下拖动的功能,这个实现方法如下:
void CDlgV1::OnLButtonDown ( UINT nFlags, CPoint point )
{
SendMessage( WM_NCLBUTTONDOWN, HTCAPTION, MAKELPARAM( point.x, point.y ) ); 
CDialog::OnLButtonDown(nFlags, point);
}
网上介绍说这个是通过模拟按下了标题栏实现的拖动的效果,我现在问题正是拖动对话框到屏幕左边,右边,底部,对话框都能拖出屏幕外,但是在往屏幕顶端拖动的话,即使拖出去较多,对话框也会自动弹回来,在屏幕外的部分只有标题栏那么宽。
这个操作就像是按住了标题栏在拖动对话框,因为是相当于按在了标题栏上,因此怎么也不可能将对话框标题栏以下的部分拖出带屏幕的顶端以外(左、右、下都能拖出),所以想寻求解决的办法。各位开始出招吧。
如果想通过鼠标左键按下记住标志,左键弹起时再移动窗口的放啊实现拖动的就不用了,因为我的对话框在相应左键弹起消息时出现了问题,必须连续点击两次左键才能响应左键谈起消息,这个方法实现不了。我调试后发现,之所以左键弹起不响应,正是和在左键按下中所添加的 SendMessage( WM_NCLBUTTONDOWN, HTCAPTION, MAKELPARAM( point.x, point.y ) )有关,如果不调用这句话倒是可以每次都响应左键弹起消息。但是这样的话拖动就没有了对话框当前被拖动的位置的虚线框的效果了(我在windows效果里面设置的是对话框在移动的时候不显示内容,只显示虚线框)。
高手快来支招啊!

解决方案 »

  1.   

    这个是 Windows就这样设计的   就算有标题栏 你也不能吧窗口全拖到上面,它一会弹回来的
      

  2.   

    可以这样,捕获 WM_MOUSEMOVE 事件,用函数GetAsyncKeyState(GetKeyState)判断左键是否按下,如果按下使用 MoveWindow 移动窗口,这样的话就不需要虚线了,只要鼠标移动窗口也会立刻移动
      

  3.   

    GetAsyncKeyState(VK_LBUTTON) 失误了
      

  4.   

    谢谢回复,我现在就是不想用MoveWindow在OnMouseMove中来移动窗口,这样的话是可以移动,但是我说了,我现在所有窗口的移动风格是窗口在移动过程中是不显示内容的,这个是Windows风格,你可以功过 我的电脑->属性->详细设定->设定->拉动窗口时不显示窗口内容(这样的话你在拖动窗口的过程中只有个虚线框在移动,这个过程中是不响应OnMove的,可以减少处理,只有在鼠标左键松开时才响应),这个我必须和我其他的所有窗口保持一致的风格,所以你说的这种方法不适用于我这种情况。因为按照你说的这种方法,窗口在OnMouseMove中是不断的移动窗口位置的,这不是我要的窗口移动风格。
        其实如你所说,因为我实现的拖动就是模拟在标题栏上拖动窗口,所以就想windows下的所有窗口,你想拖动,只能按住标题栏拖,自然,窗口标题栏以下的部分是不可能移到屏幕顶部上面的。貌似windows下的所有窗口都只能按住标题栏,才能进行拖动,在别的地方是拖不了的。
        我就是想找一种方法,在我设置的窗口拖动时不显示内容,只显示虚线框的风格下,再进行窗口的拖动,能拖出屏幕顶端,不知道有没有别的系统消息可以实现。
      

  5.   

    我Win7 找半天没找到你说的那个设置
    你的意思是 只移动一次对吧?   那就捕获 WM_LBUTTONDOWN 和 WM_LBUTTONUP 按下的时候记录坐标,放开的时候计算移动的方向和距离,然后只 MoveWindow一次  至于虚线框可以自己实现
      

  6.   


    我的是XP系统,就是我前面说的那么设置就行,我的电脑->属性->详细设定->设定->拉动窗口时不显示窗口内容(这个勾去掉),Win7应该也有吧。
     WM_LBUTTONDOWN 和 WM_LBUTTONUP 是可以实现,但是这个虚线框貌似也不好画,我就是想尽可能利用windows中实现了的东西,我也想结合这两种方法,拖动仍然利用如下添加的代码实现,
    我在无边框对话框加了 OnLButtonDown ( UINT nFlags, CPoint point )
    {
    SendMessage( WM_NCLBUTTONDOWN, HTCAPTION, MAKELPARAM( point.x, point.y ) );
    CDialog::OnLButtonDown(nFlags, point);

    就可以实现拖动,但是因为加了这个 SendMessage( WM_NCLBUTTONDOWN, HTCAPTION, MAKELPARAM( point.x, point.y ), 
    WM_LBUTTONUP 消息每次都要连续点击两次鼠标才响应一次。
    另外,不光是对话框框而已被拖出到屏幕顶端之外,还有一种改变size也可能将对话框,这个是因为我设置了窗口在四个角上进行拉伸时,宽和高的比例保持不变(我在OnSizing中做的判断和处理),因此对话框在屏幕顶端的位置时,你按住左上或者右上角进行拉伸时,对话框的高会随着宽的增加而增加,因此对话框的上半部分可能就到屏幕外面去了,这种情况下,我发现对话框超出屏幕顶端一点点(一个标题栏宽度25)之后,对话框的高就不会增加了,只有宽会增加,也就是说宽高比例变化了,而事实上,我在OnSizing响应中,求得的对话框top的坐标并没有错,但是窗口的top和我在OnSizing中求的的值就是不一样。换句话说,我求得的top可能为 -100, -200,但是窗口的top最多只能到达-25,也就是说我为了保持纵横比(假设比例为 1 ),宽增加100,求得的高也增加了100(假设此时的top为-100时能满足比例关系),而系统会自动将我的窗口的top改为 - 25,这样宽和高的比例就变了。这个不符合我的要求。
      

  7.   

    突然发现你的 SendMessage 是不是少一个参数 第一个参数是窗口句柄
    不过无所谓了 我猜测,鼠标通过点击标题栏移动窗口,在内部实际也调用了MoveWindow,但为了防止标题栏跑出屏幕而无法再移动回来,所以做了判断,如果超出屏幕一定数量就弹回来
    在对话框过程中 捕获 WM_NCLBUTTONUP, 如果响应的是  HTCAPTION  那么直接使用函数 MoveWindow移动到计算好的地点,对于第二点 也可以显示的调用 MoveWindow改变窗口大小
      

  8.   


    谢谢回复。
    首先、SendMessage并没错,因为是在对话框中调用此函数,给自己发消息是可以不要窗口句柄 的。
    第二、你说的利用WM_NCLBUTTONUP,我也想过,问题是这个消息的响应存在问题,昨天我百度了下,触发这个消息的方式很奇怪。你直接在窗口边界上点击左键,弹起的时候是不会响应的,必须双击,或者在客户区按下,在非客户区弹起才会响应这个消息,所以这个做法也不行。
    另外,当对话框在屏幕顶端的位置时,你按住左上或者右上角进行拉伸时,为了保持高宽的固定比例,对话框的高会随着宽的增加而增加,因此对话框的上半部分可能就到屏幕外面去了,这个我通过在OnSizing中实时的记下窗口应该在的位置,在Onsize响应中MoveWindow到合适的位置,这样窗口能到任意位置。
    但是我未解决的问题是,鼠标左键按下拖动窗口到屏幕顶端以外时,窗口会自动弹回来。我也考虑在OnLButtonDown中记下鼠标位置,在OnLButtonUp中判断窗口size是否变化,变化了,则肯定是因为到了顶部的原因,我再调用MoveWindow改变窗口size和位置。但是同样,我的窗口的 OnLButtonUp 也需要双击才能响应了,单击根本不好使。
    单击不好使的原因,就是因为我在void CDlgV1::OnLButtonDown ( UINT nFlags, CPoint point )
    {
    SendMessage( WM_NCLBUTTONDOWN, HTCAPTION, MAKELPARAM( point.x, point.y ) );
    CDialog::OnLButtonDown(nFlags, point);

    就是因为发送了WM_NCLBUTTONDOWN,加了这个就不能响应 WM_LBUTTONUP,但是不加这个我的窗口没法拖动,谁知道能让这两个消息同时都响应的方法啊。
      

  9.   

    话说我很久没用c++了  MFC也只是简单的学了学估计你的 SendMessage 被重载了 不废话了 自己亲自调试了一下,有点意思,系统捕捉从按下到释放整个过程,我还以为是分开来做的呢,那么这样解决
    在原有基础之上 再捕捉 WM_NCLBUTTONDOWN 消息
    case WM_NCLBUTTONDOWN:
    {
    DefWindowProc(hDlg,message,wParam,lParam);
    MoveWindow(hDlg,-100,-100,500,500,TRUE); //移动到合适的位置
    return TRUE;//返回真表示此事件已有自己处理
    }
      

  10.   

    换成  PostMessage() 看
    SendMessage( WM_NCLBUTTONDOWN, HTCAPTION, MAKELPARAM( point.x, point.y ) ); 这个换一下看SendMessage需要处理完毕才返回。
      

  11.   

    我有相同的问题,win7怎么搞的,winxp都可以往上移不会弹回。持续关注,那位大牛来解决下