Visual Basic Explorer
Visual Basic Explorer
 Navigation
 Home


 Coding
 Source Code

 FAQ Center

 VB Tips

 Downloads

 ToolBox

 Tutorials

 VB Games

 VB News

 VB Award

 VB Forums



 Affiliates
 Planet Source Code

 Rent a Coder

 DirectX4VB


 Misc
 Search

 Feedback

 Advertise

 About


Need to hire
a VB coder?

Please support our sponsor:

 Home 
 Site Map 
 Forums 
 News 
 Feedback 

Setting Up The Dialog Automation Objects

We need to install the Dialog Automation Objects before we can use them. Since there’s no setup program for them, follow these steps:

 

1 Copy the file dlgobjs.dll from the \Tools\Unsupprt\Dlgobj directory on the Visual Basic CD to your \Windows\System directory. If you’re installing this under Windows NT, copy dlgobjs.dll to the \System32 directory.

 

2 While you’re still looking at the contents of the CD, right click on the file \Tools\Unsupprt\DlgObj\dlgobjs.reg and left-click on 'Merge' from the popup menu. This registers the design-time license.

 

3 To register the DLL itself , select ‘Run’ from the Windows ‘Start’ menu. In the text box, type "regsvr32.exe c:\windows\system\dlgobjs.dll". Under Windows NT, this should be "regsvr32.exe c:\windows\system32\dlgobjs.dll". A message should appear telling you you’ve succeeded.

 

4 Back in the VB5 IDE, select "Microsoft Dialog Automation Objects" in the Project | References Dialog in Visual Basic. This makes the objects available to the current project.

Available Objects, Their Properties and Functions

Once we have the reference to Microsoft Dialog Automation Objects, we only need to open the Object Browser DialogObjects to view the various objects available to us. There are 5 dialog objects, each one giving us access to a specific dialog box. The available objects are:

ChooseColor

ChooseFile

ChooseFont

PageSetup

PrintDialog

There are also 5 helper objects which are used by the dialog objects:

Colors

FileNames

Filters

PrinterDevice

Rectangle

We’ll be looking at the dialog objects individually, and within those discussions, we’ll also look at how the helper objects are used.

The Dialog Objects

In order to use any of the Dialog objects, we need to create an instance of the object we want to use. This can be accomplished quite simply using the Set statement:

Set ChooseFile1 = New ChooseFile

Now we can use any of the properties and functions of the new object, in this case, ChooseFile1.

We’re going to be looking at these dialogs in their order of difficulty, starting with the Color Palette, and continuing through to the Font dialog.

ChooseColor

The ChooseColor object implements the Color Palette dialog, allowing the user to change the color of something in an application. This dialog is implemented with all of its custom color functions intact, and can even be opened with custom colors being loaded from somewhere else, either a set list or from the registry:

The object’s properties and single function are rather easy to understand, due to some correctly-named properties:

Property/Function

Description

Property Center As Boolean

Centers the dialog on the screen

Property Color As Long

The currently selected color, or the one to start out with

Property CustomColors As Colors

A collection of up to 16 custom colors

Property hWnd As Long

The window this dialog will act modally against, with 0 being the desktop

Property PreventCustomColors As Boolean

Disables the "Define Custom Colors>>" button

Property ShowCustomColors As Boolean

Opens the dialog with the custom colors extended

Function Show() As Boolean

Shows the dialog

The helper object named Colors is a collection of custom colors used by the CustomColor property of the ChooseColor object. This helper object has two properties:

Property

Description

Property Count As Long

Provides a count of the custom colors

Property Item(Index As Long) As Long

Provides an index of the individual custom colors

At this point in each of the following descriptions, we’re going to be looking at examples of the dialogs. Each of the examples will listing each property or function at least once. This way, you can see a little clearer how to use each one.

 

Try It Out - Calling The Color Palette

This is the first dialog we’ll be calling from a function in a module. In doing so, we can call it more than once without having to rewrite it each time. This is particularly important when it comes to custom colors. Otherwise, we end up with a number of custom color arrays in the registry, one for each form we call the Color dialog from!

Add a module to the project Chapter6.vbp and add the following function to it:

Public Function SelectColor(ColorNumber As Long) As Long

    Dim n As Integer, i As Integer

    ' Create an instance of the ChooseColor object
    Set ChooseColor1 = New ChooseColor

    With ChooseColor1
      ' Get the custom colors from the registry
      For n = 0 To 15
        .CustomColors(n) = GetSetting("Chapter6", _
          "Startup", "CustomColors(" & n & ")", "0")
      Next n

      ' Center the dialog on the screen
      .Center = True

      ' Set the initial color
      .Color = ColorNumber

      ' The window this dialog will operate
      ' modally against (0 = desktop)
      .hWnd = 0

      ' Indicate whether or not the user can
      ' expand the custom colors
      .PreventCustomColors = False

      ' Whether or not the custom colors are
      ' expanded by default
      .ShowCustomColors = False

      ' Show the dialog
      .Show

      ' Write the custom colors to the registry
      For i = 0 To 15
        SaveSetting "Chapter6", "Startup", _
          "CustomColors(" & i & ")", .CustomColors(i)
      Next i

  End With

  ' Return the selection
  SelectColor = ChooseColor1.Color

End Function

This function creates a new ChooseColor object, then loads the 16 custom colors from the registry. If the registry settings don’t exist yet, all of the individual colors are set to "0", or black. The dialog is centered on the screen, and the initial color is set to the variable "ColorNumber". This is the variable that is passed to this function from the procedure calling it, and is the current color of the item to have its color changed. Three other properties are set before showing the form. The hWnd property is set to 0 so the Color dialog acts modally against the desktop. The PreventCustomColors is set to False. Doing so allows the custom colors to be shown, enabling the "Define Custom Colors>>" button. ShowCustomColors is also set to False, meaning the custom colors are not extended when the dialog is first displayed. Then, the Color dialog is finally shown.

The function continues once the Color dialog is closed. Immediately, the custom colors are written to the registry. Then, the newly selected color is returned to the calling procedure and the function ends.

 

Try It Out - Implementing The SelectColor Function

Add the following code to the Load event of Form1 in Calendar.vbp:

Private Sub Form_Load()

  SaveSetting "Chapter6", "Startup", "TestSetting", "Test"

  With Calendar1
    ' Set the calendar to today's date
    .Year = Format(Now, "yyyy")
    .Month = Format(Now, "m")
    .Day = Format(Now, "d")

    ' Set the colors
    .DayColor = GetSetting("Chapter6", "Startup", "DayColor", "0")
    .DayNameColor = GetSetting("Chapter6", "Startup", "DayNameColor", "0")

    ' Update the settings
    .Refresh
  End With

End Sub

This will retrieve the colors we save to the registry for the calendar’s DayColor and DayNameColor properties. Using the Refresh method ensures the properties are updated every time the calendar is opened. This routine also writes a test setting to the registry, which we’ll be discussing shortly.

Add this code to the mnuViewColorDayColor_Click event:

Private Sub mnuViewColorDayColor_Click()
  
  ' Set the calendar's DayColor property via the Color dialog
  Calendar1.DayColor = SelectColor(Calendar1.DayColor)

  ' Save the DayColor property to the registry
  SaveSetting "Chapter6", "Startup", "DayColor", Calendar1.DayColor

End Sub

To ensure the same functionality is available for the calendar’s day names, add the following code to the mnuViewColorDayNameColor_Click event:

Private Sub mnuViewColorDayNameColor_Click()

  ' Set the calendar's DayNameColor property via the Color dialog
  Calendar1.DayNameColor = SelectColor(Calendar1.DayNameColor)

  ' Save the DayNameColor property to the registry
  SaveSetting "Chapter6", "Startup", "DayNameColor", Calendar1.DayNameColor

End Sub

Now, add this code to the click event of the mnuToolsRestoreDefaults menu item:

Private Sub mnuToolsRestoreDefaults_Click()

  Dim TestItem As String

  ' Check the test setting
  TestItem = GetSetting("Chapter6", "Startup", "TestSetting", "")

  ' If the test setting is clear, the settings don't exist
  If TestItem = "" Then
    ' Do Nothing

  Else
    ' Clear the settings if there are any
    DeleteSetting "Chapter6", "Startup"
  End If

  With Calendar1

    ' Reset the colors to black
    .DayColor = 0
    .DayNameColor = 0

  End With

End Sub

 

This last routine erases any of the registry settings we’ve previously written in this section. This way, remnants from this chapter aren’t taking up space in your registry forever! It also restores the color properties to their default setting of "black" (0).

This is also where the TestSetting in the registry is used, which was mentioned a short while ago. If the test setting is returned as an empty string, this indicates this area of the registry is empty and the DeleteSettings procedure is not called (if it were called, an error would result). Otherwise, the DeleteSettings procedure deletes the entire section.

The individual procedures mnuViewColorDayColor_Click() and mnuViewColorDayNameColor_Click() save their particular setting to the registry. This would be difficult to do in the SelectColor function without passing a number of parameters to it.

Press F5, or select Start from Visual Basic’s Run menu. Click on the Day Name Color menu item:

The Color dialog will appear, with the black color selected, the custom colors all set to black, and the custom color selection area not extended. Change the current selection, making sure to load up some of the 16 custom colors boxes with new colors. Once you close the dialog, the calendar’s day names will be changed to the selected color.

Now select Day Color from the form’s menu. When the Color dialog appears, the custom colors will be loaded with the ones you’d previously selected. Select a new color and close the Color dialog. The colors of the days in the calendar grid will be changed to the new selection.

Finally, click Restore Default Settings from the Tools menu. The DayColor and DayName color properties will return to black.

Color Palette GUI Notes

The selected color is normally assigned to a particular item in our application. Keeping in mind that the user may have selected some overall Windows color scheme having some semblance of weirdness, we really don't want to assign custom colors to controls. In this case, we need to open the Color Palette dialog without the custom colors being extended, and having the "Define Custom Colors>>" button being disabled.

Note that the menu items are designed with Day Name Color being above Day Color. This follows the layout of the calendar itself, where the day names are at the top of the grid. In the code for the calendar, these items were seen in reverse order from this due to alphabetization by Visual Basic and whoever originally wrote the code. It would be easy to accidentally design the menu items to follow the structure of the code, which would be confusing to the user. Be sure to place first things first and last things last as the user will see them to prevent this kind of confusion.

 

How It All Works

Since the Dialog Automation Objects are not supplied as source code, we need to determine how they are were developed, in case they’re not supplied to us in the future. The API Viewer on the Add-In’s menu in the IDE provides this information.

The Dialog Automation Objects are implemented as an ActiveX DLL. The individual dialog objects are declared via the Windows API, such as the following declaration for ChooseColor:

Declare Function ChooseColor Lib "comdlg32.dll" Alias "ChooseColorA" _

(pChoosecolor As CHOOSECOLOR) As Long

The type CHOOSECOLOR is declared in the same area of the DLL’s source code as the above API declaration:

Type CHOOSECOLOR
        lStructSize As Long
        hwndOwner As Long
        hInstance As Long
        rgbResult As Long
        lpCustColors As Long
        flags As Long
        lCustData As Long
        lpfnHook As Long
        lpTemplateName As String
End Type

Using this information, the entire ChooseColor class, including the individual properties, is developed. The properties we’re using fill in the blanks in the CHOOSECOLOR type. The ChooseColor.Show property we’ve used in our own code calls the API through the ChooseColorA function, which then uses the CHOOSECOLOR type, and everything is set up correctly to display the Color dialog.

ChooseFile

The ChooseFile object gives us access to both the Open and Save As dialog boxes. We’ll go ahead and take a look at both of these dialogs so we can be clear on the differences between the two implementations.

There are a few more properties for this object than for ChooseColor, but still only the one .Show function:

Property/Function

Description

Property Center As Boolean

Centers the dialog on the screen

Property Directory As String

The directory to open, or the chosen directory

Property FileMustExist As Boolean

Whether or not the file must exist to be chosen (Open dialog only)

Property FileName As String

The name of the file to look for, or the file selected

Property FileNames As FileNames

A collection of file names in a multiselect dialog

Property Filters As Filters

A collection of file extension filters

Property HideReadOnly As Boolean

Whether or not to show the Read-only checkbox (Open dialog only)

Property hWnd As Long

The window the dialog will act modally against, with 0 being the desktop

Property MultiSelect As Boolean

Whether or not the dialog permit the selection of multiple files

Property OverwritePrompt As Boolean

Whether or not the system will prompt the user prior to overwriting a file

Property ReadOnly As Boolean

True if the file is Read-only

Property Save As Boolean

True to show the Save dialog, False for Open

Property Title As String

The new title of the dialog

Function Show() As Boolean

Shows the dialog

Two more of the helper objects are used by ChooseFile. The first one is FileNames, and is used for multiple file selections:

FileNames

Property

Description

Property Count As Long

A count of the multiple file names

Property Item(Index As Long) As String

The index of each individual file name

The second helper object is Filters, which we’ll use to load the Type drop-down box in the dialog via a collection of Filter items:

Filters

Property

Description

Property Count As Long

A count of the filters in the collection

Property Item(Index As Long) As String

The index of each individual filter

Sub Add(bstrNew As String)

Adds a filter to the collection

Sub Remove(Index As Long)

Remove a filter from the collection

Try It Out - The "Save As" Dialog

There are quite a few items in this dialog which will change depending on the specific usage. The directory is one item, as are the file name, filters, title, and multiple file selections. It makes more sense to place individualized code under each Save As menu item than to have a common function and pass all of these variables to and from the function.

Place the following code under the mnuFileSaveAs_Click event in our Chapter6 sample:

Private Sub mnuFileSaveAs_Click()

  ' Create the new object
  Set ChooseFile1 = New ChooseFile

  With ChooseFile1

    ' Center the dialog
    .Center = True

    ' Specify the default directory
    .Directory = GetSetting("Chapter6", "Startup", _
      "SaveAsDirectory", "c:\windows\system\")

    ' Does not apply to the Save dialog
    '.FileMustExist = True

    ' File to be initially selected
    .filename = "dlgobjs.dll"

    ' Load the Filter drop-down box
    With .Filters
      .Add "Executables (*.exe,*.dll):*.exe;*.dll"
      .Add "Documents (*.doc,*.txt):*.doc;*.txt"
      .Add "Stuff (*.stf):*.stf"
      .Add "All Files (*.*):*.*"
    End With

    ' Does not apply to the Save dialog
    '.HideReadOnly = True

    ' The window this dialog will operate
    ' modally against (0 = desktop)
    .hWnd = 0

    ' Allow the user to select more than one file
    .MultiSelect = True

    ' Prompt before overwriting a file
    .OverwritePrompt = True

    ' Does not apply to Save As
    '.ReadOnly = False

    ' Save?  Or Open?
    .Save = True

    ' Retitle the dialog
    .Title = "Save This Stuff As..."

    ' Show the dialog
    .Show

    ‘ Save the new default directory
    SaveSetting "Chapter6", "Startup", "SaveAsDirectory", .Directory

    If (.filename = "") Then
      ' Handler in case 'Cancel' is selected
      Exit Sub
    Else
      ' Place save code here
    End If

  End With

End Sub

Since we’re not actually saving anything at this point, toward the bottom you’ll see "Place save code here". We’ll replace this comment with code to save something in a later chapter.

Start the Chapter6 project and select Save As from the File menu. The Save As dialog will appear as it was shown at the beginning of this section. Change the directory to something different than the default of c:\windows\system\, which is given in the GetSettings statement. Close the dialog, then open it again. Since the SaveSettings statement wrote the directory you chose to the registry, this is the directory which is selected when you open the dialog again.

 

Try It Out - The "Open" Dialog

The Open dialog is almost identical to the Save As dialog in its implementation. Place the following code in the mnuFileOpen_Click event:

Private Sub mnuFileOpen_Click() ' Create the new object Set ChooseFile1 = New ChooseFile With ChooseFile1 ' Center the dialog .Center = True ' Specify the default directory .Directory = GetSetting("Chapter6", "Startup", _ "OpenDirectory", "c:\windows\system\") ' Does not apply to the Save dialog .FileMustExist = True ' File to be initially selected .filename = "dlgobjs.dll" ' Load the Filter drop-down box With .Filters .Add "Executables (*.exe,*.dll):*.exe;*.dll" .Add "Documents (*.doc,*.txt):*.doc;*.txt" .Add "Stuff (*.stf):*.stf" .Add "All Files (*.*):*.*" End With ' Hide the Read-only checkbox? .HideReadOnly = False ' The window this dialog will operate ' modally against (0 = desktop) .hWnd = 0 ' Allow the user to select more than one file .MultiSelect = True ' Prompt before overwriting a file .OverwritePrompt = True ' Read-only checkbox checked? .ReadOnly = True ' Save? Or Open? .Save = False ' Retitle the dialog .Title = "Open Some Stuff" ' Show the dialog .Show

' Save the new default directory SaveSetting "Chapter6", "Startup", "OpenDirectory", .Directory If (.filename = "") Then ' Handler in case 'Cancel' is selected Exit Sub Else ‘ Place open code here End If End With

End Sub

Notice the same point about the directory as in the Save As dialog. The GetSetting and SaveSetting statements are, in fact, identical in both cases, except for the registry key being "SaveAsDialog" in one instance, and "OpenDialog" in the other.

 

How It Works

After creating the new dialog object ChooseFile1, we make sure it will be centered on the screen. The GetSetting statement does its job to get the default directory, and we specify that the file must exist (which seems strange since we’re looking at a current list of the directory!) Following the naming of the file we’re looking for, we lay out the collection of filters, making sure to include the filter for "All Files *.*". The HideReadOnly property is set to False so the Read-only check box will be shown. The hWnd property is set as in the Color dialog, and we also set MultiSelect to True so the user can select more than one file. Setting OverwritePrompt to True provides a message box to appear before the user overwrites a file that already exists. The Save property sets the dialog for Save or Open functionality, and we also retitle the dialog to something appropriate to the application.

After the dialog is closed, SaveSetting is used to write the directory to the registry, and the procedure finishes with the open statement we’ll fill in later.

PageSetup

The Page Setup dialog is an extra dialog available from the Dialog Automation Objects. Since this dialog is not available from the CommonDialog control, we’ll do a little extra with it.

The properties are, once again, appropriately named for their functions. Notice there are fewer properties for this dialog than even for the Color dialog:

Property/Function

Description

Property Center As Boolean

Centers the dialog on the screen

Property DisableMargins As Boolean

Whether or not the Margins section of the dialog is disabled

Property DisableOrientation As Boolean

Whether or not the Orientation section of the dialog is disabled

Property DisablePaper As Boolean

Whether or not the Paper section of the dialog is disabled

Property DisablePrinter As Boolean

Whether or not the Printer section of the dialog is disabled

Property hWnd As Long

The handle of the window this dialog will act modally against, with 0 being the desktop

Property Margins As Rectangle

The margins set by the user, relative to the top and left edges of the paper

Property MinimumMargins As Rectangle

The minimum margins allowed, relative to the top and left edges of the paper

Property PreventWarning As Boolean

Whether or not a message will appear if no default printer is selected

Property PrinterDevice As PrinterDevice

The actual printer device (see below)

Function Show() As Boolean

Shows the dialog

Printer Device

The PrinterDevice object is used for returning the specifics for the printer to be used. At the end of our sample procedure, we’ll enumerate this to see exactly what the values become for our selection:

Property

Description

Property Copies As Integer

Number of copies to be printed

Property Default As Boolean

Whether or not the selected printer is the default

Property Driver As String

The OEM name of the printer driver

Property DriverVersion As Integer

The driver’s version number

Property Name As String

Common name for the selected printer

Property Orientation As Integer

1 = portrait, 2 = landscape

Property Output As String

Port to be printed to (i.e., LPT1) or "FILE"

Property PaperSize As Integer

Size of the paper, as designated by the OEM (i.e., Hewlett-Packard 8 ½ x 11 inch = 1)

 

Rectangle

The Rectangle object is used to set the MinimumMargin and Margin properties, relative to the edge of the selected paper size:

Property Bottom As Long

Property Left As Long

Property Right As Long

Property Top As Long

Try It Out - The Page Setup Dialog

Add the following code to the mnuFilePageSetup_Click event of the form in Chapter6.vbp:

Private Sub mnuFilePageSetup_Click()

  ' Create the new object
  Set PageSetup1 = New PageSetup

  With PageSetup1

    ' Center the dialog
    .Center = True

    ' Set the Disable properties
    .DisableMargins = False
    .DisableOrientation = False
    .DisablePaper = False
    .DisablePrinter = False

    ' Window the dialog will act
    ' modally against (0 = desktop)
    .hWnd = 0

    'Set the margins (in 1/1000ths of an inch)
    With .Margins
      .Top = 500
      .Left = 500
      .Right = 500
      .Bottom = 1000
    End With

    'Set the minimum margins
    ' (in 1/1000ths of an inch)
    With .MinimumMargins
      .Top = 250
      .Left = 250
      .Right = 250
      .Bottom = 750
    End With

    ' Suppress "No default printer" warning
    .PreventWarning = False

    ' Show the dialog
    .Show

    If (.PrinterDevice.Name = "") Then

      ' Handler if Cancel is selected
      Exit Sub

    Else
      With .PrinterDevice
      ' Return the selected settings
        MsgBox "You selected:" & Chr(10) & _
          Chr(9) & "Copies: " & .Copies & Chr(10) & _
          Chr(9) & "Default: " & .Default & Chr(10) & _
          Chr(9) & "Driver: " & .Driver & Chr(10) & _
          Chr(9) & "Driver Version: " & .DriverVersion & Chr(10) & _
          Chr(9) & "Printer Name: " & .Name & Chr(10) & _
          Chr(9) & "Orientation: " & .Orientation & Chr(10) & _
          Chr(9) & "Output: " & .Output & Chr(10) & _
          Chr(9) & "Paper Size: " & .PaperSize & Chr(10) & _
          Chr(9) & "Top Margin: " & PageSetup1.Margins.Top & Chr(10) & _
          Chr(9) & "Left Margin: " & PageSetup1.Margins.Left & Chr(10) & _
          Chr(9) & "Right Margin: " & PageSetup1.Margins.Right & Chr(10) & _
          Chr(9) & "Bottom Margin: " & PageSetup1.Margins.Bottom
      End With
    End If
  End With
End Sub

This isn’t a very complicated procedure, but the list of information it returns is quite large. Because of this, we can’t very well create a function out of it in any practical manner.

When you start the project from the Run menu and select File | Page Setup, the dialog box will appear as specified:

Go through this dialog and make changes to its settings. This dialog acts in the same way as it does in Microsoft Word and other Windows 95 programs. If you change the Margin settings, you’ll notice that it’s not possible to set the margins smaller than the MinimumMargin property settings. Also, the Printer button shows the PrinterSelection dialog:

Selecting a printer is as simple as making a new selection from the Name dropdown box. Pressing the Properties button calls the OEM property page for the selected printer.

When you close all the other dialogs and select the OK button on the Page Setup dialog, a message box will appear, showing all of the selections we made, which are necessary for the printing of a document:

This information is then used to setup whatever document we’re going to print.

A few of these items seem rather cryptic and need a bit of explanation. For instance, the WINSPOOL driver indicates we’re spooling the printing through the Windows Print Manager. The orientation is 1 for portrait, whereas 2 would be for landscape. And Paper Size? For this printer, there are a large number of sizes. 1 is for letter size, or 8 ½ x 11 inches, 5 is for legal size, which is 8 ½ x 14 inches, 9 gives us A4 size paper, being 210 x 297 mm, and so on.

PrintDialog

The Print dialog is quite similar to the Page Setup dialog in many respects, to the point where it uses the same type of PrinterDevice object to relay information about the printer. It does have a few more properties to get the job done:

Property/Function

Description

Property Center As Boolean

Centers the dialog on the screen

Property DisablePageNumbers As Boolean

Disables the Page Numbers section of the dialog

Property DisablePrintToFile As Boolean

Disables the Print To File section of the dialog

Property DisableSelection As Boolean

Disables the Page Selection section of the dialog

Property hWnd As Long

Handle of the window this dialog will act modally against, with 0 being the desktop

Property MaxPage As Long

Maximum page the user can select for printing

Property MinPage As Long

Minimum page the user can select for printing

Property PreventWarning As Boolean

Whether or not a message will appear if no default printer is selected

Property PrinterDevice As PrinterDevice

The actual printer device (see description in the Page Setup section)

Property PrintRange As Long

Declaration of which pages to print

Property PrintToFile As Boolean

Whether or not to print to a file

Property ShowPrintToFile As Boolean

Whether or not to show the Print To File check box

Function Show() As Boolean

Shows the dialog

 

Try It Out - The Print Dialog

Place the following code under the mnuFilePrint_Click event on the form in our Chapter6 sample:

Private Sub mnuFilePrint_Click()

 ' Create the new object
  Set PrintDialog1 = New PrintDialog

  With PrintDialog1

    ' Center the dialog
    .Center = True

    ' Set the Disable properties
    .DisablePageNumbers = False
    .DisablePrintToFile = False
    .DisableSelection = False

    ' Window the dialog will act
    ' modally against (0 = desktop)
    .hWnd = 0

    ' Suppress "No default printer" warning
    .PreventWarning = False

    ' Set the Print To File characteristics
    .PrintToFile = True
    .ShowPrintToFile = True

    .PrintRange = 2

    ' Show the dialog
    .Show

    If (.PrinterDevice.Name = "") Then

      ' Handler if Cancel is selected
      Exit Sub

    Else

      ' Place print code here

    End If
  End With

End Sub

When you start the Chapter6 sample from the Visual Basic IDE and click the File | Print command, you’ll see this dialog box:

Compared with some of the other dialogs in this group, this one was rather simple.

Following is the discussion for the Font dialog, likely the most complicated one of them all.

ChooseFont

As complex as the Font dialog can be, we can still implement it as a function and call the single function from anywhere in our program. This is accomplished through the use of the StdFont object, which encapsulates all of the properties of a font into a single object. All we need to do is call the function that calls the Font dialog, and the font is returned as a StdFont object.

The Font dialog is implemented without any helper objects … except the IFontDisp type for the GetFont() function. We don’t need to worry about this one since Visual Basic takes care of it through OLE:

Property/Function

Description

Property Center As Boolean

Centers the dialog on the screen

Property Color As Long

The color to be applied to the font

Property FaceName As String

Name of the font (i.e., "MS Sans Serif")

Property FixedPitchOnly As Boolean

If True, only shows fixed-pitch fonts

Property ForceFontExist As Boolean

Whether or not the font must exist

Property Height As Long

Height of the font (i.e., 10)

Property hWnd As Long

Handle of the window this dialog will act modally against, with 0 being the desktop

Property Italic As Boolean

Whether or not the font is italicized

Property ShowEffects As Boolean

If True, show the Effects section of the dialog

Property ShowPrinterFonts As Boolean

Whether or not to show printer fonts in the listing

Property ShowScreenFonts As Boolean

Whether or not to show screen fonts in the listing

Property ShowVerticalFonts As Boolean

Whether or not to show vertical fonts in the listing

Property SizeMax As Long

Maximum size allowed (also refered to as Height)

Property SizeMin As Long

Minimum size allowed (also refered to as Height)

Property StrikeOut As Boolean

Whether or not the selected font has the Strikeout effect applied

Property TrueTypeOnly As Boolean

If True, only shows True Type fonts

Property Underline As Boolean

Whether or not the selected font has the Underline effect applied

Property Width As Long

Width of the font, for style (i.e., 400 = Regular, 700 = Bold, etc.)

Function GetFont() As IFontDisp

Gets the selected font from the dialog as a Font object

Function Show() As Boolean

Shows the dialog

 

The ShowEffects setting must be set to True prior to setting the StrikeOut, Underline, or Color effects. Otherwise, an error will occur.

 

Try It Out - Using The Font Dialog

Add the following function to the module we created earlier in the Chapter6 project:

Public Function SelectFont() As StdFont

  Dim NewFont As New StdFont

  'Create the new object
  Set ChooseFont1 = New ChooseFont

  With ChooseFont1

    ' Center the dialog on the screen
    .Center = True

    ' Window the dialog will act
    ' modally against (desktop = 0)
    .hWnd = 0

    ' Set the dialog properties
    .FixedPitchOnly = False
    .ShowPrinterFonts = True
    .ShowScreenFonts = True
    .ShowVerticalFonts = True

    ' Show Effects selections
    .ShowEffects = True

    ' Set whether or not to display an error
    ' message if the selected font does not
    ' exist (i.e., no selection made = Error)
    .ForceFontExist = True

    ' Set the Size properties
    .SizeMin = 10
    .SizeMax = 36

    .StrikeOut = False
    .Underline = False

    ' Set the Color property
    .Color = 0

    ' Show the dialog
    .Show

    ' After the dialog is closed,
    ' change the label to the selected font
    With NewFont
      .Bold = ChooseFont1.GetFont.Bold
      .Charset = ChooseFont1.GetFont.Charset
      .Italic = ChooseFont1.GetFont.Italic
      .Name = ChooseFont1.GetFont.Name
      .Size = ChooseFont1.GetFont.Size
      .Strikethrough = ChooseFont1.GetFont.Strikethrough
      .Weight = ChooseFont1.GetFont.Weight
    End With
  End With

  Set SelectFont = NewFont

End Function

Place the following code under the mnuViewFontDayNameFont_Click event on the form:

Private Sub mnuViewFontDayNameFont_Click()

  ' Creat a new font object
  Dim NewDayNameFont As New StdFont

  ' Set the new font object via the Font dialog
  Set NewDayNameFont = SelectFont

  ' Update the calendar's DayNameFont property
  Set Calendar1.DayNameFont = NewDayNameFont

  ' Write the new DayNameFont property to the registry
  SaveSetting "Chapter6", "Startup", "DayNameFontBold", Calendar1.DayNameFont.Bold
  SaveSetting "Chapter6", "Startup", _
    "DayNameFontCharset", Calendar1.DayNameFont.Charset
  SaveSetting "Chapter6", "Startup", _
    "DayNameFontItalic", Calendar1.DayNameFont.Italic
  SaveSetting "Chapter6", "Startup", _
    "DayNameFontName", Calendar1.DayNameFont.Name
  SaveSetting "Chapter6", "Startup", "DayNameFontSize", Calendar1.DayNameFont.Size
  SaveSetting "Chapter6", "Startup", _
    "DayNameFontStrikethrough", Calendar1.DayNameFont.Strikethrough
  SaveSetting "Chapter6", "Startup", _
    "DayNameFontUnderline", Calendar1.DayNameFont.Underline

  ' Update the calendar
  Calendar1.Refresh

End Sub

Place the following code under the mnuViewFontDayFont_Click event on the form:

Private Sub mnuViewFontDayFont_Click()

  ' Create a new font object
  Dim NewDayFont As New StdFont

  ' Set the new font object via the Font dialog
  Set NewDayFont = SelectFont

  ' Update the calendar's DayFont property
  Set Calendar1.DayFont = NewDayFont

  ' Write the new DayFont property to the registry
  SaveSetting "Chapter6", "Startup", "DayFontBold", Calendar1.DayFont.Bold
  SaveSetting "Chapter6", "Startup", "DayFontCharset", Calendar1.DayFont.Charset
  SaveSetting "Chapter6", "Startup", "DayFontItalic", Calendar1.DayFont.Italic
  SaveSetting "Chapter6", "Startup", "DayFontName", Calendar1.DayFont.Name
  SaveSetting "Chapter6", "Startup", "DayFontSize", Calendar1.DayFont.Size
  SaveSetting "Chapter6", "Startup", _
    "DayFontStrikethrough", Calendar1.DayFont.Strikethrough
  SaveSetting "Chapter6", "Startup", "DayFontUnderline", Calendar1.DayFont.Underline

  ' Update the calendar
  Calendar1.Refresh

End Sub

Finally, change the forms Load event by adding the following code:

Private Sub Form_Load()

  SaveSetting "Chapter6", "Startup", "TestSetting", "Test"

  With Calendar1
    ' Set the calendar to today's date
    .Year = Format(Now, "yyyy")
    .Month = Format(Now, "m")
    .Day = Format(Now, "d")

    ' Set the colors
    .DayColor = GetSetting("Chapter6", "Startup", "DayColor", "0")
    .DayNameColor = GetSetting("Chapter6", "Startup", "DayNameColor", "0")

    ' Retrieve the calendar's DayFont settings from the registry
    With .DayFont
      .Bold = GetSetting("Chapter6", "Startup", "DayFontBold", "False")
      .Charset = GetSetting("Chapter6", "Startup", "DayFontCharset", "77")
      .Italic = GetSetting("Chapter6", "Startup", "DayFontItalic", "False")
      .Name = GetSetting("Chapter6", "Startup", "DayFontName", "MS Sans Serif")
      .Size = GetSetting("Chapter6", "Startup", "DayFontSize", "10")
      .Strikethrough = GetSetting("Chapter6", "Startup", _
        "DayFontStrikethrough", "False")
      .Underline = GetSetting("Chapter6", "Startup", "DayFontUnderline", "False")
    End With

    ' Retrieve the calendar's DayNameFont settings from the registry
    With .DayNameFont
      .Bold = GetSetting("Chapter6", "Startup", "DayNameFontBold", "False")
      .Charset = GetSetting("Chapter6", "Startup", "DayNameFontCharset", "77")
      .Italic = GetSetting("Chapter6", "Startup", "DayNameFontItalic", "False")
      .Name = GetSetting("Chapter6", "Startup", "DayNameFontName", "MS Sans Serif")
      .Size = GetSetting("Chapter6", "Startup", "DayNameFontSize", "10")
      .Strikethrough = GetSetting("Chapter6", "Startup", _
       "DayNameFontStrikethrough", "False")
      .Underline = GetSetting("Chapter6", "Startup", "DayNameFontUnderline", "False")
    End With

  End With

End Sub

When you start the program, everything will look as it has before. This is because the default settings we’ve added in the Load event are the same as the calendar’s default settings. Select View | Fonts | Day Name Font from the form’s menu bar, and the Font dialog will appear:

Select a new font from the dialog and click OK. The newly selected font will be transferred into the DayNameFont property and the calendar’s appearance will be changed. Repeat the process with the DayFont property.

You may have noticed that changing the color of the selected font in the dialog has no effect on the font in the calendar.

The StdFont object makes no provision for encapsulation of the color of the selected font. If we want to still call the Font dialog via a function, extra code must be written to do so.

This could easily be implemented by adding another parameter to be passed to and from the SelectFont function.

Overall Common Dialog GUI Notes

While the Windows 95 Common Dialogs are well-implemented and perform their jobs admirably, occasionally we have need to take them a bit further. This is particularly true for the Open dialog. Many custom implementations exist for this box in various programs. For instance, when looking for an icon file, the 16 x 16 versions of the icons are made to show in the standard common dialog. But, in certain programs, the Open dialog has an extension on it to show a "thumbnail", or representation, of graphics files prior to opening them.

Visual C++, and other development packages, provide the common dialogs to developers as templates. These templates are then modified directly for the appropriate usage, and any extensions or other modifications are accomplished on the dialog itself.

In Visual Basic, we don’t have this luxury. We can still do it, but it involves quite a bit of programming to accomplish. For those who feel ambitious, I offer the following steps:

 

1 Cause the dialog you want to modify to be displayed in a program. It doesn’t matter which program, as long as the correct dialog is displayed.

2 Take a "screen shot" of the dialog. This is accomplished through pressing the ALT and Print Screen keys, which saves an image of the active window to the clipboard.

3 Open a graphics program, such as Microsoft Paint, and click on Edit | Paste on the menubar. The image of the dialog will appear for editing. Save this as a bitmap and close the graphics program.

4 In Visual Basic, add a blank form to your project. Add the image of the dialog to the form via the Image control.

5 Using the Drive, Directory, and File Window controls, some Command buttons, and the Windows API, re-implement the dialog box as it originally was. This is done by drawing these controls directly over their counterparts on the bitmap.

6 Once the dialog is completely operational, implement the desired custom functionality.

Users are used to the layout and operation of the common dialogs. To prevent confusion, it’s important not to deviate too much from the "pre-packaged" layouts. We can make extensions to these layouts, but we shouldn’t completely rearrange the original components.

The System Tray Icon Control

The System Tray Icon Control, Systray.ocx, encapsulates everything necessary to place an icon in the system tray at any time. It has very few properties and even fewer events, but since the control itself is to be placed on a form, the control can set any properties or call any event for the form it’s placed on. Just like the MSVBCalendar control, this control is supplied as source code , so the first thing we’ll need to do is build it.



[Home Page] [Next Lesson] [Previous Lesson] [Dave Liske's Site] [Wrox Web-Developer]





Home | About | What's New | Source Code | FAQ | Tips & Tricks | Downloads | ToolBox | Tutorials | Game Programming | VB Award | Search | VB Forums | Feedback | VBNews | Copyright & Disclaimer | Advertise | Privacy Policy |

Quick searches: Site Search | Advanced Site Search 

Copyright 2002 by Exhedra Solutions, Inc.
By using this site you agree to its terms and conditions
VB Explorer and VBExplorer.com are trademarks of Exhedra Solutions, Inc.