Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chris Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

a message box question

Status
Not open for further replies.

19790203

Programmer
Oct 7, 2005
13
PL
is it possible that VB displays a message box with some description of activity while doing this activity? for instance, the program is processing huge amount of data and it is consuming huge amount of time and displays a msgbox with info like that: "I am processing the data, please wait!
 
The easiest way to do this is to use a form to design your own messagebox, rather than to use the MsgBox method.
 
strongm is correct.

1. On the main form provide the code to show the new form. The new form will display your message. Make sure when you show the form that you show it as modal...so that it will always be on top.

2. On the (message) form within onload, put in the code you want to run. You can even put a progress bar on this form as well. I can dig you up some old code if you want me to.

3. Put in the command to "unload me" in the (message) form.

HINT: When you create the new form, it is best (in my opinion) to not have the form resizable or even have a bar on top that displayes an icon or an "X". Also, make sure that when it is displayed, that it appears centered on the owner..makes a more professional look...again, my own personal opinion.

Good Luck!
 
Well, the problem with the solution proposed by mmbsports is that if the message box form is shown as modal (ShowModal=True) then the program stops the execution until the message box is closed (not really what is needed!). On the other hand, if the message box form is made non modal (ShowModal=False), it cannot be called from a modal form. So, in my opinion, the problem remains unsolved.

I have found a solution (in the FAQ of the VBA forum here) that is quite near to the desired solution (calling the Window API: but still you have to click on a button to hide the message (and I would like it to close automatically when the calculation is finished).

Any ideas?
 

??? ShowModal=True ?? That appears to be a snippet of Excel VBA applied to a UserForm - this is VB6 we're talking about.

Just use FormX.Show vbModal

That certainly doesn't stop execution of other processes

________________________________________________________________
If you want to get the best response to a question, please check out FAQ222-2244 first.
'If we're supposed to work in Hex, why have we only got A fingers?'
Drive a Steam Roller
 
Yes, you are right: ShowModal=True comes from Excel VBA UserForms. It has the same effect as calling a form with FormX.Show vbModal.

FormX.Show vbModal DOES stop execution of the program until the FormX is closed. (Otherwise, you are right, other processes are not stopped. I am still able to consult this forum while the modal form of my VB6 application is open on my computer! But I would like a message box which do not pause the program that called it...)
 

I believe that setting a Form to show as Modal merely prevents user interaction with that program, except on the modal form - it doesn't stop it from running.
I just set up a quick test. Form1 with a cmd button, a timer and a textbox, form2 as the 'msgbox'.
Form1 just has:
Code:
Private Sub Command1_Click()
Form2.Show vbModal
End Sub
Private Sub Timer1_Timer()
Text1.Text = Val(Text1.Text) + 1
If Val(Text1.Text) > 15 Then
Form2.Hide
End If
End Sub
Run the code - Form1 comes up and the textbox counter runs. Click the cmd button - Form2 appears, and the counter on Form1 continues. When counter reaches 15, Form2 hides.

________________________________________________________________
If you want to get the best response to a question, please check out FAQ222-2244 first.
'If we're supposed to work in Hex, why have we only got A fingers?'
Drive a Steam Roller
 
The counter on Form1 continues because the timer process started before you click on the cmd button. Here you are right: Form2.Show vbModal does not stop other processes. But it does stop the process that called Form2.Show vbModal.
Try this modification of your example (without the timer):

Private Sub Command1_Click()
Form2.Show vbModal
MsgBox "The process continues..."
Form2.Hide
End Sub

I wish I could see Form2 and then immediately the message "The process continues...". But I can see the message only if I close Form2 manually...

Maybe the solution is to call Form2.Show vbModal by a process other than that that calls MsgBox "The process continues..." ?
 
Is a dialog really the best way to handle this?

I assume there is a form acting as the primary UI window for this application. This seems like a job for the good old status bar concept: Put the "working" message in the status and disable all controls except an "interrupt process" (i.e. "cancel") button.

For that matter I use non-modal forms a lot for things like process logging and I never have trouble with them. Why do you want a modal dialog in the first place? I must have missed that one.
 
>I wish I could see Form2 and then immediately the message "The process continues...".

But then, of course, it wouldn't actually be modal ...
 
I would just display a large Label control with the text "I am processing the data, please wait!"

When the process is done, just hide the label.
 
I think that at this point I need to explain better the context. I have a method (called "service" hereafter) that makes a lot of calculations, organized in several steps. This service can be called by a user interface (a modal user form) or by a batch. I want that
1) the user be informed which step is being executed (for this the information cannot be shown on a nonmodal form) and
2) the information should not stop the execution and should not need manual actions (like clicking on a button).

This context rejects many possibilities (modal and nonmodal forms, labels, status bars, etc.)
Of course, I can pass a variable to the service saying in which mode it is called (i.e., interactive or batch) and adding ifs in it, but this is not elegant: a service should have no informations about its clients (otherwise, each time another client needs this service, you should modify the service - not a good solution!).

What I need is a kind of MsgBox without buttons, that does not stop execution and that can be hidden by a call to a "hide" method. This is possible - I saw it in other programming languages. Maybe the solution is in a Window API? I do not know well this domain - maybe somebody here has an idea?
 
Here is an idea for you to consider. It may not be what you are looking for, but I urge you to try it.

1. Create a blank VB project (Standard EXE).

2. on the form, add a command button and a label

3. Add a class module. Name it clsTest.

The work in the class module would represent your calculation process. In the class module, add this code.

Code:
Option Explicit

Public Event ProcessingStep(ByVal StepNumber As Integer, ByRef Cancel As Boolean)

Public Sub Process()
    
    Dim iStart As Single
    Dim bCancel As Boolean
    
    RaiseEvent ProcessingStep(0, bCancel)
    
    iStart = Timer
    
    While (Timer - iStart) < 10
    Wend
    
    RaiseEvent ProcessingStep(1, bCancel)
    
    If bCancel Then
        Exit Sub
    End If
    
    iStart = Timer
    
    While (Timer - iStart) < 10
    Wend
    
    RaiseEvent ProcessingStep(2, bCancel)
    
    iStart = Timer
    
    While (Timer - iStart) < 10
    Wend
    
    
End Sub

You'll notice that I have a couple of loops that just wait a specified period of time. This, obviously, would be replaced with your calculation process.

Now, back to the form. Add this code.

Code:
Option Explicit

Public WithEvents oTest As clsTest

Private Sub Command1_Click()
    
    Set oTest = New clsTest
    
    Call oTest.Process
    Label1.Caption = "Process Complete"
    Set oTest = Nothing

End Sub

Private Sub oTest_ProcessingStep(ByVal StepNumber As Integer, Cancel As Boolean)
        
    Label1.Caption = "Processing step " & CStr(StepNumber)
    Label1.Refresh
    
End Sub

You'll notice that the command button begins the process. After each step in the process, an event is raised. In the event, we update the caption property of the label. then we refresh the label (so that it repaints). As each step is completed, the label is updated so the user knows something is still happening.

I hope this helps.

-George

Strong and bitter words indicate a weak cause. - Fortune cookie wisdom
 
George,

Thank you very much for this working example of Events. I am not familiar with them so I appreciate a lot this example which is placed in the context of my present problem.

I am affraid, however, that this does not solve my problem (at least directly). Your solution still needs a form to display the message on. But, on the other hand, in the batch mode it is not really necessary to see the messages, so maybe I can leave the calculation method rise the events which, in the batch mode, are not caught and just ignored. This idea looks interesting. I will try to encapsulate this an will keep you informed!
 
I'm still missing something here.

I don't know where your long-running code is located module-wise, but I still don't see why you can't have it write into a modeless "status" form (or a control on such a form).

Example:

New project. Two forms: Form1 and Form1. Two buttons on Form1, Command1 and Command2.

Form1.frm
Code:
Private Sub Command1_Click()
    'Print some "Stuff" on Form2.
    Dim i As Long
    
    For i = 1 To 10
        Form2.Print Rnd()
    Next
    Form2.SetFocus
    DoEvents
End Sub

Private Sub Command2_Click()
    Form2.Cls
    Form2.SetFocus
    DoEvents
End Sub

Private Sub Form_Load()
    With Form2
        .Show vbModeless, Me
        .BackColor = vbWhite
        .ForeColor = vbBlack
        .FontName = "Courier New"
        .FontSize = 12
    End With
End Sub
The [tt]DoEvents[/tt] calls aren't necessary here, but if you had long-running code in Form1 doing the [tt]Print[/tt] calls on Form2 you'd probably want them.
 
dilettante,

This is me that missed something, not you! I missed mentionning that my startup form (which is modal) is a user form in a VBA Excel application. And in Excel (but not in pure VB), you cannot call a modeless form from a modal form (By the way, I do not see why this should be forbidden! Maybe it has been judged too dangerous in hands of Excel users?). In my ignorance I thought that the same was true for pure VB forms. I am really sorry for the confusion I created.

Your code works well (except the commands Form2.SetFocus - I had to remove them). Thank you!

 
George,

Thank you again for your code. I have played with it and learned a lot. Unfortunately, it would be too difficult to use events in my context, where the application exists already: introducing events would need to reorganize the existing code into class modules and changing methods calls in many places. Too risky!
 
Maybe we could have all saved a lot of time and misunderstanding if you had posted a new question in forum707 which is specifically for VBA. Have a look at faq222-2244 for guidelines on forum usage

________________________________________________________________
If you want to get the best response to a question, please check out FAQ222-2244 first.
'If we're supposed to work in Hex, why have we only got A fingers?'
Drive a Steam Roller
 
jmi44,

Actually, my method does work...I use it often. You misunderstood WHERE I state to place your process code.

I do not program in VBA, so this may not work in VBA...then again, I didn't know that you were asking a VBA question.

You state: "Well, the problem with the solution proposed by mmbsports is that if the message box form is shown as modal (ShowModal=True) then the program stops the execution until the message box is closed (not really what is needed!)."

If you use my method, then while the message box form is open, your process will run BECAUSE all the code that makes your process run is within the message box form. Please re-read my original post.

Waytech2003 also provides a viable solution. Before you run your long process on the main form, you would make a label visible, then when the process is complete, hide the label.

In a standard VB6 app, both suggestions will work. Don't know about VBA.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top