不是MDI结构的情况下,希望让form2始终覆盖在form1之上(假设form2总比form1小),并让form2跟随form1移动和缩放(就好像form2是form1的子窗体一样的效果)。必须保证其平级关系,不能为“父子”关系。我现在想到的是用WM_MOVE来保证跟随移动,WM_SIZE跟随缩放,剩余的就不知道了。比如当鼠标左键按住form1非客户区不放的时候,form2就沉到form1之后去了,这是不符合要求的……总之就是本质上不是MDI,但操作起来像MDI。(不用考虑form1标题栏变灰这些细节,也不用考虑用户移动form2)欢迎讨论,谢谢。

解决方案 »

  1.   

    http://www.baidu.com/s?ie=gb2312&bs=vb+winamp+%B4%B0%BF%DA%B8%FA%CB%E6&sr=&z=&cl=3&f=8&tn=baidu&wd=vb+winamp+%B4%C5%D0%D4%B4%B0%CC%E5&ct=0
      

  2.   

    '关闭最大化与最小化按钮
    Private Sub Form_Load()
    Form2.Show
    l = Form1.Left + (Form1.Width - Form2.Width) / 2
    t = Form1.Top + 800
    Form2.Move l, t
    Timer1.Interval = 10
    End SubPrivate Sub Form_Unload(Cancel As Integer)
    Unload Form2
    End SubPrivate Sub Timer1_Timer()
    'If Form1.WindowState = 2 Or Form2.WindowState = 2 Or Form1.WindowState = 1 Or Form2.WindowState = 1 Then Exit Sub
    If Form2.Width > Form1.Width Then Form2.Width = Form1.Width - 1000
    If Form2.Height > Form1.Height Then Form2.Height = Form1.Height - 1000
    Form2.Show
    l = Form1.Left + (Form1.Width - Form2.Width) / 2
    t = Form1.Top + (Form1.Height - Form2.Height) / 2
    Form2.Move l, t
    Form2.ZOrderEnd Sub
      

  3.   

    Timer的话效率是个问题,一直在检测……
      

  4.   

    回1楼:
     '-- 打开从属窗体
        Dim oChild As New fChild
        
        '-- 显示载入
        Call oChild.Show(vbModeless, Me)类似这样的就不是平级关系了。
      

  5.   

    'Module1里:'=====---猴哥---=====---2007.10.01---=====---无线监控共用模块(setWindow.bas)---
    '----------------------------------将窗口置于顶层-----------------------------
    Option Explicit
          Public Const SWP_NOMOVE = 2
          Public Const SWP_NOSIZE = 1
          Public Const FLAGS = SWP_NOMOVE Or SWP_NOSIZE
          Public Const HWND_TOPMOST = -1
          Public Const HWND_NOTOPMOST = -2      Declare Function SetWindowPos Lib "user32" _
                (ByVal hwnd As Long, _
                ByVal hWndInsertAfter As Long, _
                ByVal X As Long, _
                ByVal Y As Long, _
                ByVal cx As Long, _
                ByVal cy As Long, _
                ByVal wFlags As Long) As Long                  Public Function SetTopMostWindow(hwnd As Long, Topmost As Boolean) _
             As Long         If Topmost = True Then 'Make the window topmost
                SetTopMostWindow = SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, _
                   0, FLAGS)
             Else
                SetTopMostWindow = SetWindowPos(hwnd, HWND_NOTOPMOST, 0, 0, _
                   0, 0, FLAGS)
                SetTopMostWindow = False
             End If
          End Function'form2里以下这样,可以保证form2在form1前面
    Private Sub Form_Load()
         SetTopMostWindow Me.hwnd, True     
    End Sub'或者form1里以下这样,也可以保证form2在form1前面
    Private Sub Form_Load()
         SetTopMostWindow Form1.hwnd, True     
    End Sub
      

  6.   

    只要按照下面的方式启动窗体,自然会保持前后关系。
    Sub Main()
        Form1.Show
        Form2.Show vbModeless, Form1
    End Sub
    缩放可以在 Form1 的 Resize() 事件中处理。
    所以你需要用 SubClass 处理的就只有 Form1 的 WM_MOVE 消息。
      

  7.   

    HWND_TOPMOST就不是在form1前面的问题了,是在所有窗体前面,都置顶了……
      

  8.   

    回9楼:Form2.Show vbModeless, Form1其实已经不平级了。Form1为Form2的容器了。
      

  9.   

    个人认为无法实现.原因是,你的要求逻辑上冲突.一,要求两个窗体"始终平级".二,要求窗体2"始终在窗体1上面的固定区域".要实现一,则两个窗体肯定可以互相前置.而要实现二,两个窗体肯定又不在同一级了,要么是show vbmodeless,me这样的父子关系,要么是MDI那种容器包容关系....你是自己做窗体外观吗?参考一下别人的代码吧.不过好象没实现你的要求的.
      

  10.   


    我在CSDN搜索到的。谁对谁错,再讨论
    语法:窗体名.Show [Modal][,Owerner]说明:Modal:指定窗体显示的模式,可以为vbModal(=1)或vbModeless(=0,默认值),vbModal表示将窗体作为模式对话框显示,这种情况下,Show方法后的代码要等到模式对话框关闭之后才能执行,且焦点也不能移动到其他窗体;vbModeless表示将窗体作为无模式对话框显示,这种情况下,焦点能在其他窗体之间转移。Owner:指定窗体的拥有者,可将某个窗体的窗体名传给这个参数,使得这个窗体成为新窗体的拥有者。使用该参数,可以确保对话框在它的父窗体最小化时它也最小化,或者在其父窗体关闭时它也卸载。例:frm1.Show vbModal
    frm1.Show vbModeless
    frm1.Show vbModal,Me本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/lixianlin/archive/2007/04/10/1558515.aspx
      

  11.   

    回14楼:是需要这种结构。实际使用中form2为一activex exe窗体,我是为了方便描述才简单的说成是两个窗体的。之所以有这种怪异的需求,是希望一个“子”窗体假死(如大循环,例子而已)的时候,用户还能操作主窗体。
      

  12.   

    如果是这样的需求,我的选择可能是会将有可能假死的代码放另一线程(也许这就是你使用ActiveX EXE的原因?),然后将UI仍然做到主窗体上,组织好通讯过程即可.个人觉得没必要将整个窗体都放另一线程....不过呢,仔细想了想,估计也只有vbmodeless,Me最接近你的要求了.但是反正你那个窗体都是要假死的,显示出来给用户看,不如隐藏起来,在主窗体上报告其执行状态,不是能得到更好的用户体验么?
      

  13.   

    如果是这样的需求,我的选择可能是会将有可能假死的代码放另一线程(也许这就是你使用ActiveX EXE的原因?),然后将UI仍然做到主窗体上,组织好通讯过程即可.个人觉得没必要将整个窗体都放另一线程....不过呢,仔细想了想,估计也只有vbmodeless,Me最接近你的要求了.但是反正你那个窗体都是要假死的,显示出来给用户看,不如隐藏起来,在主窗体上报告其执行状态,不是能得到更好的用户体验么?
      

  14.   


    同意!!
    Show方法简单实用,满不满意,那就看效果了。剩下的事,就是过滤消息,实现窗体移动与缩放!
      

  15.   

    Form1为启动窗体,Command1是Form1的一个按钮:
    Option ExplicitPrivate Sub Command1_Click()
        Form2.Show vbModal
    End Sub
      

  16.   

    form2出现,则form1不能操作.
      

  17.   

    能实现, 需要子类化主窗体,然后处理WM_WINDOWPOSCHANGED消息。 我在VC下做了一个简单测试,WM_WINDOWPOSCHANGED 消息处理VC的大致代码如下:LRESULT CMainDlg::OnWindowPosChanged(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam , BOOL& /*bHandled*/)
    {
    LPWINDOWPOS lppos = (LPWINDOWPOS)lParam; if (m_about.IsWindow())
    m_about.SetWindowPos(HWND_TOP,lppos->x ,lppos->y + 22,200,100, SWP_SHOWWINDOW | SWP_NOACTIVATE );
    return 0;
    }其中m_about为跟随的子窗体。
    你在VB中修改,在form_Load事件中子类化主窗体,并显示子窗体,然后在VB中load 更随的窗体,无模式显示,然后处理WM_WINDOWPOSCHANGED或WM_WINDOWPOSCHANGING消息。注意一点: 调用SetWindowPos()API设置子窗体时最后一个参数一定要使用SWP_NOACTIVATE参数,不然可能陷入死循环或主窗体不可获得焦点
      

  18.   

    估计搂主想要的应该是Photoshop工具窗口或调色板窗口的那种效果把,
    应该很容易呀,用
    form1启动后就像普通的方法显示form2,如Private Sub Form_Load()
       form2.Show
    End Sub在 form2 的 Form_Load 事件中加上Private Declare Function SetWindowWord Lib "user32" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal wNewWord As Long) As Long
    Private Const GWL_HWNDPARENT = (-8)
    Private Sub Form_Load()
       Call SetWindowWord(hwnd, GWL_HWNDPARENT, 主程序.hwnd)
    End Sub就可以实现了,然后要做跟随移动可以用 Timer 事件或窗口消息捕获来
    处理,也很简单呀。
      

  19.   

      Call SetWindowWord(me.hwnd, GWL_HWNDPARENT, form1.hwnd)
      

  20.   

    老虎的这个可能比较好
    Sub Main()
        Form1.Show
        Form2.Show vbModeless, Form1
    End Sub
      

  21.   

    我测试的结果还是原样,form2并没有因为Call SetWindowWord(me.hwnd, GWL_HWNDPARENT, form1.hwnd) 
    而保持在form1上方.(姑且不论跟随移动)。也许是我没理解您的意思?
      

  22.   

    若要求在同一高度:
    f1.top=f2.top
    若要求在同一宽度:
    f1.left=f2.left就那么简单,不要新那些人的,他们的有可能看不动.
      

  23.   

    现在在做的东西也需要这个效果,本来想解惑wm_move事件的,在处理时间的代码中不能控制其他窗体。