|
-
Nov 8th, 2000, 01:52 AM
#1
Thread Starter
Frenzied Member
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
-
Nov 8th, 2000, 01:59 AM
#2
Instead of going:
Code:
Load frmTest
frmTest.Show
try going:
Code:
Dim lfrm as frmTest
Set lfrm = new frmTest
lfrm.Show
cheers
- gaffa
-
Nov 8th, 2000, 02:00 AM
#3
Frenzied Member
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]
-
Nov 8th, 2000, 02:20 AM
#4
Thread Starter
Frenzied Member
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
-
Nov 8th, 2000, 02:31 AM
#5
Hyperactive Member
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 !!!!!
-
Nov 8th, 2000, 02:35 AM
#6
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
-
Nov 8th, 2000, 03:16 AM
#7
Fanatic Member
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.
-
Nov 8th, 2000, 05:53 PM
#8
Thread Starter
Frenzied Member
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:
I can't figure out how to reference the form any longer..
Any and all help would be appreciated..
Dan
-
Nov 8th, 2000, 06:04 PM
#9
Frenzied Member
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...
-
Nov 8th, 2000, 06:24 PM
#10
Frenzied Member
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]
-
Nov 8th, 2000, 07:47 PM
#11
Lively Member
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
-
Nov 8th, 2000, 08:07 PM
#12
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
-
Nov 9th, 2000, 10:52 AM
#13
Thread Starter
Frenzied Member
Ruxpin,
Your code did exactly what I wanted!!!
Thanks a bunch,
Dan
-
Nov 16th, 2000, 05:04 PM
#14
New Member
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.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|