9

I ask this partly because I want to know the best practice way of doing this, and partly because the top google result I got was a forum thread from 2002 in which the question wasn't even answered.

I inherited some VB6 code, and there are some MsgBox calls in said code, many of which display messages that end users would probably find very annoying after a short time (e.g. "Printing Complete," "Record Added," etc.)

I would like to add the standard user interface control of a checkbox on the MsgBox saying "Don't ask me this again", so that when checked and OK is clicked, a setting is saved that lets the program know, you know...to never ask that again. Pretty standard control, the idea is fairly self-explanatory.

What I would like to know is what is the best practice way of doing this in VB6. There is the obvious way of just making a new form for these type of msgboxen and replacing the old MsgBox call with a .Show on that form, but do the VB6 gurus on Stack Overflow have a better way?

Thanks in advance

4 Answers4

9

As far as I know, there is no other way. You need to make your own message box form with the check box. Of course, you'll also need to modify the code to store and retrieve this setting (and acting appropriately based on the setting).

I have done this in my own application many times. One thing to think about.... suppose the user checks the box "don't show me this again". In my opinion, there should be a way to reset the setting. Since the message box form won't show again, I added this to the configuration form (for my app).

One thing you may want to consider is sub-classing the MSGBOX function. You could create a function within your app that has a similar parameter list, but with a couple extra. If the extra parameters are missing, simply call vba.MsgBox (to get the standard behaviour). If you pass in extra parameters, you could call your new form instead.

George Mastros
  • 24,112
  • 4
  • 51
  • 59
  • good point about being able to undo the "don't bother me anymore" setting. –  Jun 24 '09 at 19:46
  • Thanks - this is what I figured the answer was, and you put it much better than I could. Hopefully this will become the canonical answer on google instead of some lame forum thread from 7 years ago. :) –  Jun 24 '09 at 19:49
  • @GSerg: Your answer is good and I upvoted it. But I'll be honest, I would tend to use this answer first, because of all the issues associated with using undocumented/unsupported APIs. – Oorang Jun 25 '09 at 01:28
8

Well... You are not absolutely correct guys ;)

Starting from Win2000, there's SHMessageBoxCheck function that does the trick. VB6 declaration:

Private Declare Function SHMessageBoxCheck Lib "shlwapi" Alias "#185" (ByVal hWnd As Long, ByVal lpszText As String, ByVal lpszTitle As String, ByVal dwType As VbMsgBoxStyle, ByVal iDefault As Long, ByVal lpszId As String) As Long

For everything else follow the link :)

GSerg
  • 76,472
  • 17
  • 159
  • 346
  • 3
    Okay, that's cool. :-) But there's a pretty glaring problem. It's apparently deprecated already? The docs say it may be missing in post-Server2003 versions of Windows. Anyone tried this on Vista or w7? – Karl E. Peterson Jun 24 '09 at 23:07
  • +1 For gratuitous use of awesome:) I can confirm it still works in Vista. Just tested it out and it works fine. But it looks like the key the values are in moved to HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\DontShowMeThisDialogAgain. Obviously that would matter for anyone wanting to read/alter those keys to restore the messages. I feel obligated to give all the usual warnings about the use of undocumented APIs though:) – Oorang Jun 25 '09 at 01:26
  • Another interesting thing I noticed is that while it says not all the style flags are supported, they all seem to work on Vista. Can you confirm they all work on XP? – Oorang Jun 25 '09 at 01:38
  • Another thing I noticed is that the documentation indicates if the user "x"s out of the dialog that vbCancel is returned even if Cancel was not a possible button. In Vista, there is no "x" button available unless cancel is an option. – Oorang Jun 25 '09 at 01:42
  • @GSerg: You ought to declare iDefault as VbMsgBoxResult. (Sorry to spam the comments. I tried to consolidate but ran out of characters.) – Oorang Jun 25 '09 at 01:52
  • Hmmm one thing that looks like it's not supported is the help button will appear, but it doesn't look like there is a way to hook it to anything. – Oorang Jun 25 '09 at 01:57
  • Another problem with this is that you need to look out for accidentally overlapping IDs. Since you have no way of know what other applications are using this API, even if you run a check against the registry to make sure you don't pick an ID that has already been turned off. You have no way to verify that some application didn't pick a colliding ID turning off their message, turns off yours (or vice-versa). Unless that problem can be solved I don't think I would use this. – Oorang Jun 25 '09 at 02:06
  • 1
    Oorang: use a GUID to avoid collisions. – GSerg Jun 25 '09 at 07:28
0

If you provide such a functionality, it might require "turning-on" of showing messagebox.
i.e. user should have an option to see the msgbox again using some setting.

Instead of that, you could use statusbar to display notifications OR have a label with the notification messages and turn it off after a few seconds.

shahkalpesh
  • 33,172
  • 3
  • 63
  • 88
0

This was my down and dirty solution:

Private Sub Workbook_BeforeClose(Cancel As Boolean)
myfile = Workbooks.Application.ActiveWorkbook.Path & "\noprompt.txt"
If Dir(myfile) <> "" Then Exit Sub
exportData = MsgBox("Export data?" & vbCrLf & "Select Cancel (or × top right) to prevent this prompt from displaying again.", vbYesNoCancel, "Close Workbook")
If exportData = vbYes Then
    Call ExportValues 'a separate function...
ElseIf exportData = vbCancel Then
    'create file noprompt.txt
    Open myfile For Output As #1
    Write #1, "Delete this file to restore prompt to Export Data when workbook is closed."
    Close #1
    Exit Sub
ElseIf exportData = vbNo Then
    Exit Sub

End If


End Sub

Documentation for my app explains that deleting the file restores the prompt.