Results 1 to 14 of 14

Thread: multiple instances of a form?

  1. #1

    Thread Starter
    Frenzied Member
    Join Date
    Aug 2000
    Posts
    1,091
    Hi,

    How do I allows opening multiple instances of a form? For example, through a menu button, a form gets loaded. Even if the form is already loaded, I would like to allows the user to start up another instance of the form through the same menu button the loaded the original form... Kinda like you can do in Outlook Express when you create a new message.. You can launch several instances of the new message form..

    any help and examples would be appreciated..

    Dan

  2. #2
    Guest
    Instead of going:
    Code:
    Load frmTest
    frmTest.Show
    try going:

    Code:
    Dim lfrm as frmTest
    
    Set lfrm = new frmTest
    lfrm.Show
    cheers

    - gaffa

  3. #3
    Frenzied Member
    Join Date
    Jan 2000
    Location
    Bellevue, WA, USA
    Posts
    1,357

    Talking Try this...

    Here ya go...

    Start a project with a form (Form1) and put a command button on it (Command1). Then paste the following code into the Form's code window:
    Code:
    Private Sub Command1_Click()
        Dim NewForm As New Form1
        
        NewForm.Show
    End Sub
    Hope that helps...

    [Edited by seaweed on 11-08-2000 at 02:03 AM]
    ~seaweed

  4. #4

    Thread Starter
    Frenzied Member
    Join Date
    Aug 2000
    Posts
    1,091
    Thanks guys, worked like a charm!! Now, for another, related question..

    When the user does have a couple of these forms open and the user tries to exit the program without first closing the forms, how can I detect this and pop up a msgbox which tells the user to first close all open forms? I don't want to force them closed because I don't want them to lose any unsaved changes..

    thanks again,

    Dan

  5. #5
    Hyperactive Member
    Join Date
    Aug 2000
    Posts
    258
    Collections!

    Code:
     Dim frmTempForm as form
    
            For Each frmTempForm In Forms
                Unload frmTempForm
                Set frmTempForm = Nothing
            
            Next

    []P
    Visual Basic 6 SP4 on win98se

    QUIT THE RAT RACE BECAUSE YOUR MESSING THE WORLD UP !!!!!

  6. #6
    Guest
    You might want to think about exposing an IsDirty or Unsaved property in the form, which would allow you to check to see if there are unsaved changes. That way you can kill any forms that don't need to be saved.

    Also, if you expose the Save function, then you could easily save the data in each form without the user's intervention (this of course assumes that the current data on a given form is valid)

    - gaffa

  7. #7
    Fanatic Member
    Join Date
    Jun 1999
    Location
    California, USA
    Posts
    662
    Also take a look at the QueryUnload event. When you unload a form, the QueryUnload event is fired. From this event, you can check to see if changes need to be saved. If you want to leave this form open, set cancel to true.

  8. #8

    Thread Starter
    Frenzied Member
    Join Date
    Aug 2000
    Posts
    1,091
    Thanks everyone for all the input!! Here's another one for you..

    How do I refer to a particular instance of the form? I would assume that each form is assigned a number starting from 0 just like an array but I don't know how to reference the form via it's number or let alone how to determine the form's number..

    For example: I have two instances of Form1 open. Form1 contains a button on it which pops open a small modal form to allow the user to select a category. That form contains a text box named Text1. When the user hit's the okay button on this form, I need the the contents of Text1.Text to be copied over to a text box on Form1.

    This was working before by using the following code on the modal form:

    Code:
    Private Sub Command1_Click()
      '-- copy category number
      Form1.Text1.Text = Me.Text1.Text
      Unload Me
    End Sub
    But now that I'm opening Form1 like:

    Code:
    Dim frm as New Form1
    frm.Show
    instead of:

    Code:
    Form1.Show
    I can't figure out how to reference the form any longer..

    Any and all help would be appreciated..

    Dan


  9. #9
    Frenzied Member
    Join Date
    Jan 2000
    Location
    Bellevue, WA, USA
    Posts
    1,357
    The long answer:
    What you are doing is a little unorthodox, in that when you are copying forms, you are also copying the underlying code in each form. This means (I think...and I'm not positive on this one) that your forms should be self-contained and not have to reference one another.

    The short answer:
    Use the name of the form that you want to manipulate.
    example:
    Code:
    Option Explicit
    
    Private FormOne As New Form1
    Private FormTwo As New Form1
    
    Private Sub Command1_Click()
        ' You can manipulate the two forms by using their names, but once you 
        ' start clicking the command buttons over and over it will be 
        ' hard to keep track of which form is which...
        FormOne.Show
        FormOne.Move 0, 0
        FormTwo.Show
        FormTwo.Move Screen.Width - FormTwo.Width, Screen.Height - FormTwo.Height
    End Sub
    Now I have a question for you:

    Why are you doing this? It smells like trouble to me. I bet there is a better way...
    ~seaweed

  10. #10
    Frenzied Member
    Join Date
    Jan 2000
    Location
    Bellevue, WA, USA
    Posts
    1,357

    Another idea...

    You can also access the Forms collection from any form in your project. If you know the index of the form you want to manipulate, you can manipulate a particular form from any other form in your project.

    The Forms collection has a single property, Count. You can access the forms in the collection by using the index:
    Code:
    Private Sub Command2_Click()
        ' This is a nonsense example of how you can manipulate forms in your project
        
        Dim nCounter As Integer
        
        For nCounter = Forms.Count - 1 To 0 Step -1
            Select Case nCounter
                Case 0, 1
                    ' This will move the first two forms to the upper left corner
                    Forms(nCounter).Move 0, 0
                Case Else
                    ' This will unload any other forms that are hanging around
                    ' except this form.
                    If Forms(nCounter).hWnd <> Me.hWnd Then
                        Unload Forms(nCounter)
                    End If
            End Select
        Next ' nCounter
        
    End Sub
    Noticed what else is implied here...all forms (and all windows, for that matter) have a unique property called hWnd (short for "handle"). Using this property along with the forms collection, you should be able to grab any form you want. You will probably have to add a module and create a Public Collection of Longs to hold the hWnd's of the forms you load so you can keep track of which is which.

    Still, this kind of manipulation screams for a better methodology in the first place. Im sure Outlook express doesn't have much concern over what it's compose-email windows are doing. They just act as input forms and send info to the parent window when the user clicks send or save...

    [Edited by seaweed on 11-08-2000 at 06:29 PM]
    ~seaweed

  11. #11
    Lively Member
    Join Date
    Mar 2000
    Posts
    87
    The aim is to keep forms as self contained as possible. If I want a form to 'return' information, I treat the form as a function. So I create a method on the Form call .Display

    The user can enter information and do whatever on the form and it then return the information. The trick is that you have to show this form modally, and you have to capture the contents of text boxes etc...before the form unloads, or else the data is lost.

    Form Code returning the data (frmReturn)
    Code:
    Private m_sText             As String
    
    Public Function Display() As String
        Me.Show vbModal
        Display = m_sText
    End Function
    
    Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)
        m_sText = Text1.Text
    End Sub
    Form code wanting the data
    Code:
    Private Sub Command1_Click()
      Text1.Text = frmReturn.Display
      Unload Me
    End Sub

    Hope this Help


  12. #12
    Guest
    The approacj I've used in numerous systems (all of which load the form multiple times, or at least have the ability to), is to assign a key to the form.

    So, pop a Key property in the form:
    Code:
    'Module level variable
    Private mstrKey as String 
    
    Public Property Get Key() as String
        Key = mstrKey
    End Property
    
    Public Property Let Key(pstrNewKey as String)
        mstrKey = pstrNewKey
    End Property
    Then, when I load the form, I assign a unique key value (usually made up from the database ID of the record being displayed, and some of state info:

    Code:
    Private sub LoadCustomer()
        Dim lfrm as New frmCustomer
    
        set lfrm = new frmCustomer
        lfrm.Key = "Customer_123" 'where 123 is the record primary
                                  'key for the cutomer being displayed
        lfrm.Show
    
        'Kill the local reference. This doesn't close the form
        'but merely decrements the reference count.
        set lfrm = nothing
    End Sub
    Now, when I want to locate that particular form, just loop through the forms collection:

    Code:
    Dim lfrm as Form
    
    For Each lfrm in Forms
        If lfrm.Key = "Customer_123" then
            'dom whatever you need to do to the form here
        End If
    Next lfrm
    'Kill the local variable and release the memory
    Set lfrm = nothing
    And that about does it. you can now easily reference the form through the key property, and if ypu expose the Save or other methods of the form, you can have some sort of control over the form from outside the form.

    The reason I use a property inseatd of just exposing a public variable (ie, making mstrKey public instead of private) is that I can also perform validation when the key is set to make sure that chaging the key value (in the Property Let) isn't going to wreak havoc on the form function.

    Hope that gives you soem new ideas.

    - gaffa

  13. #13

    Thread Starter
    Frenzied Member
    Join Date
    Aug 2000
    Posts
    1,091
    Ruxpin,

    Your code did exactly what I wanted!!!

    Thanks a bunch,

    Dan

  14. #14
    New Member
    Join Date
    Nov 2000
    Location
    Chicago, Illinois
    Posts
    1

    Wink

    Hi guys,

    Seeing your solution to multiple form instances gave me some hope. I have been battling with dynamic menus and Form instances over last few weeks.

    My problem is as follows:

    I create multiple instances of a Form through a menu option.
    Now this form has a button which opens a dialog box. After the user finishes working there, the dialog box returns a string back to this calling form.

    Now i initiate all instances of the Form from the Menu. Whenever I click on the button which opens the dialog box and returns a string to the calling form, rather than this happening to every instance, it all goes to only one form. If I do this to every instance of the Form, it only goes to one form rather than the specific instances which called the dialog box via the button.

    I wish the string values to be returned to every instance rather than one common form. Other thing it displays n+1 when n instances are invoked. I understand there is a reason for it, but can that one extra form be made non-visible.

    Regards,

    Ajay Raina.

    Ajay Raina

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width