我vc程序里创建了多个子窗口,并且设置了叠放z次序,结果任意的一个子窗口拉伸时就会变成了顶层窗口,在xp下有这个问题,在win7下没有这个问题,请问那位大虾有解决办法。

解决方案 »

  1.   

    创建子窗口的代码如下:
    CRect rect;
    for (int i = 0 ; i < 4; i++)
    {
    CWnd* m_wnd = new CWnd();
    rect.left = 200*i;
    rect.right = 150+200*i;
    rect.top = 20;
    rect.bottom = rect.top+400;
    m_wnd->Create(NULL,_T("1"),WS_CLIPCHILDREN |WS_CLIPSIBLINGS|WS_BORDER|WS_CHILD|WS_VISIBLE,rect,this,WM_USER+i);
    wnd->SetWindowPos(&wndTop ,0,0,0,0,SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE); }
    创建了4个子窗口,分别设置了叠放z次序,后创建的窗口叠放在前面窗口的上方。但是进行拉伸操作时,被拉伸的子窗口跑到其他子窗口的上面来了,这不是我想要的效果,我希望拉伸时各个子窗口仍然保持原来的叠放次序,因为后面的控制需要保证各子窗口可以实现上移一层,下移一层,置顶,置底的操作。现在拉伸就变成顶层窗口,不是我想要的效果。
      

  2.   

    创建子窗口的代码如下:
    CRect rect;
    for (int i = 0 ; i < 4; i++)
    {
    CWnd* m_wnd = new CWnd();
    rect.left = 200*i;
    rect.right = 150+200*i;
    rect.top = 20;
    rect.bottom = rect.top+400;
    m_wnd->Create(NULL,_T("1"),WS_CLIPCHILDREN |WS_CLIPSIBLINGS|WS_BORDER|WS_CHILD|WS_VISIBLE,rect,this,WM_USER+i);
    wnd->SetWindowPos(&wndTop ,0,0,0,0,SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE); }
    创建了4个子窗口,分别设置了叠放z次序,后创建的窗口叠放在前面窗口的上方。但是进行拉伸操作时,被拉伸的子窗口跑到其他子窗口的上面来了,这不是我想要的效果,我希望拉伸时各个子窗口仍然保持原来的叠放次序,因为后面的控制需要保证各子窗口可以实现上移一层,下移一层,置顶,置底的操作。现在拉伸就变成顶层窗口,不是我想要的效果。
      

  3.   

    是在拉伸完成释放鼠标的那个时刻窗体跑到了顶端,如何规避这种自动获得焦点的情况呢,或者在获得焦点后保持原来叠放的z次序呢?这个问题在win7不会出现,拉伸窗体仍然保存z次序,不会跑到顶端来的。
      

  4.   

    我曾经帮人解决过拖动时Z次序改变的问题,只要简单的处理即可不改变原来Z次序,你参考一下我估计能解决,如下图:代码下载:http://www.kuaipan.cn/file/id_54645689245761784.htm我不想再在CSDN上上传资源了,太费劲,直接弄的下载地址。
      

  5.   


    呵呵,还是很感谢你,把你代码中的diloag属性设置为resizing,结果就是低层窗体拉伸后置顶了,比较麻烦的事情,我会好好考虑的,多谢。
      

  6.   

    不知道用wndTopmost 可以不还有,没有看到,你的拖动代码。。只看到创建窗口代码
    既然是在改变大小的时候出的问题
    应该贴出问题代码呀
      

  7.   


    我提供的代码有点问题,没有那么简单,其实其中的m_wnd 为我自定义的一个CWnd派生类,在该类中实现窗体的拉伸效果
    LRESULT CMyWnd::OnNcHitTest(CPoint point)
    {
    // TODO: Add your message handler code here and/or call default
    if (IsZoomed())
    return CWnd::OnNcHitTest(point); CRect rect;
    GetClientRect(&rect);
    CPoint pt = point;
    ScreenToClient(&pt);
    static int nFrame = 5; // 窗口边框的宽度
    if (!rect.PtInRect(pt))
    {
    if (pt.x <= nFrame && pt.y >= rect.bottom - nFrame)
    return HTBOTTOMLEFT;
    else if (pt.x <= nFrame && pt.y <= nFrame)
    return HTTOPLEFT;
    else if (pt.x >= rect.right - nFrame && pt.y <= nFrame)
    return HTTOPRIGHT;
    else if (pt.x >= rect.right - nFrame && pt.y >= rect.bottom-nFrame)
    return HTBOTTOMRIGHT;
    else if (pt.x <= nFrame)
    return HTLEFT;
    else if (pt.y <= nFrame)
    return HTTOP;
    else if (pt.y >= rect.bottom - nFrame)
    return HTBOTTOM;
    else if (pt.x >= rect.right - nFrame)
    return HTRIGHT;
    }
    else
    return HTCLIENT;
    return CWnd::OnNcHitTest(point);
    }
    拖动部分就不提供了,因为那部分代码没有问题,能拖动也不会置顶。zhllxt 提供的代码,将dialog属性设置为resizing就变成了能拉伸能拖动的效果,我现在做到的效果跟基本一样,你可以试一下,他创建的3个窗体如果拉伸底层的一个窗体就置顶显示了,我碰到的问题就是这个代码下载:http://www.kuaipan.cn/file/id_54645689245761784.htm
      

  8.   

    关键还是:
    SetWindowPos(&wndTop ,0,0,0,0,SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE);参数 &wnd 是 被 拉伸 窗口的 上一个 窗口(即 那个 覆盖 拉伸窗口的 那个 窗口。
    即 InsertAfter思路:
    CWnd* m_wnd = new CWnd();
    要 派生 一个 CMyWnd。
    加 static CWnd *m_pwnd【4】;
    初始化 CMyWnd::CWnd *m_pwnd【】={0};
     
    先在 Create 中 把 产生的 窗口 记录下来:
    Creat 后:
    m_pwnd【nID-WM_USER】=this;在 MyWnd 的 OnSize() 中。
    找到 那个 覆盖 拉伸窗口的 那个 窗口,pWnd
    int id=GetDlgConctrlId();// id < 3
    CWnd *pwnd=m_pwnd【nID-WM_USER+1】;// !!!!然后就是 SetWindowPos。第一个参数 为 pWnd。你 先 试试 吧,我在 vc6 上 已经 成功。
      

  9.   

    我按你思路试了一下好像还是不行,因为最后响应的不是OnSize,而是OnNcHitTest,它始终激活拉伸的窗体保持在最上面。
      

  10.   

    OnNcHitTest ?
    你的 CWnd是 child ,没 CAPTION 的。
    拉伸 是 WS_SIZEBOX。对应 OnSize 调:SetOrder();移动是:
    OnLButtoindow
    if(nFlags==MK_LBUTTON) SendMessage(WM_SYSCOMMAND,0xF012,0);
    // 设置 Zorder
    SetOrder();我 在 VC6 上 没问题。
      

  11.   


    我的问题解决了,不过不是以你说的方式,还是谢谢你了
    我是在OnNcHitTest中响应窗体拉伸操作的,当鼠标拉伸时窗体就自动激活置顶,所以需要不让窗体激活,也就是在响应WM_MOUSEACTIVATE消息中返回MA_NOACTIVATE,这时候OnSize中的设置窗体叠放位置操作也都不需要了。
    int OnMouseActivate(CWnd* pDesktopWnd, UINT nHitTest, UINT message)
    {
    return MA_NOACTIVATE;
    }参考一下文章:http://www.cnblogs.com/ywb-lv/articles/2213406.html
      

  12.   

    问题解决了,我在OnNcHitTest中响应窗体拉伸操作的,当鼠标拉伸时窗体就自动激活置顶,所以需要在得需要不让窗体激活,也就是在响应WM_MOUSEACTIVATE消息中返回MA_NOACTIVATE,这时候OnSize中的设置窗体叠放位置操作也不需要了。
    int OnMouseActivate(CWnd* pDesktopWnd, UINT nHitTest, UINT message)
    {
    return MA_NOACTIVATE;
    }参考一下文章:http://www.cnblogs.com/ywb-lv/articles/2213406.html