Q: Determine If Word is
Installed
My application needs to know if Microsoft Word is installed, and if so,
what version. I use this information to make the best possible use of
automation, when available. Can I dig this out of the Registry
somewhere?
A:
You could, but that sounds like an awful lot of work. You want to
optimize automation, so let's use that technique to answer this
question. The Application object exposed by Word offers a Version
property, which you can query like this:
Public Function WordVersion() As String
Dim obj As Object
' Quick test to determine if Word is
' installed, and return version.
On Error Resume Next
Set obj = _
CreateObject("Word.Application")
WordVersion = obj.Version
Set obj = Nothing
End Function
This function relies on ignoring an error that's triggered if Word
isn't installed. Test the return value first for length, as an empty
string indicates no response from (or no creation of) the queried
object. Now, you'll run into a slight problem if your specification
calls for automating Word 95 as well, because that version used
WordBasic rather than VBA. The good news is that newer versions of Word
continue to expose the Word.Basic object. So, to be as universal as
possible, you'd want to modify the preceding routine like this:
Public Function WordVersion() As String
Dim obj As Object
' Quick test to determine if Word is
' installed, and return version.
On Error Resume Next
Set obj = CreateObject("Word.Basic")
WordVersion = obj.AppInfo$(2)
obj.AppClose
Set obj = Nothing
End Function
Use either of these functions by examining the string returned. An
empty string indicates no automatable version of Word is installed;
otherwise, branch according to the string's contents (see
Table 1). The Office group has gone out of its way to maintain
backwards compatibility in this case. In fact, you can develop
automation code for Word 95, even if it's not installed on your machine,
by coding against the WordBasic model using whatever version of Word you
do have installed.
I recommend using WordBasic only in cases where you find Word 95
installed, however. Using the newer Word.Application object is
preferable, both in terms of speed and robustness of code. A further
disincentive might be the fact that Microsoft no longer supports the
WordBasic model actively. (My thanks to Jonathan West, Word MVP, for
his valuable input to this response.) —K.E.P.
Q: Force Painting of
Menu Checks
I like to set the Checked and Enabled properties of some dropdown menu
items when the top-level menu is selected. For example, I use a
checkmark to indicate that the current selection is Bold, and this
attribute is far easier to test on demand than to track continuously.
I've noticed that the checkmarks aren't always painted when the menu
first drops. Toggling the Enabled property doesn't display this paint
problem. As it is now, the user must wave the cursor over the item to
force a repaint as the highlight bar moves over the item. What can I do
programmatically to force VB to paint menu checkmarks properly?
A:
I've seen this same behavior, but never spent the time to track down
exactly when it was occurring. In other words, thanks for asking, as
this is something that's irritated me too! I wrote a little test applet
that toggles the Checked property value of two first-level menu items
each time the top-level menu is dropped:
Private Sub mMain_Click(Index As Integer)
mTest(0).Checked = Not mTest(0).Checked
mTest(1).Checked = Not mTest(1).Checked
End Sub
Some friends ran this sample on a number of systems, and we found the
behavior you've described to be a common trait on Windows 2000 and
Windows XP machines. It didn't matter what version of VB had compiled
the test app. Your observation that the painting occurred predictably
when Enabled was toggled led Jonathan Wood, VB MVP, to this crude, but
effective, workaround:
Private Sub mMain_Click(Index As Integer)
Dim i As Long
For i = 0 To 1
mTest(i).Checked = Not mTest(i).Checked
If Check1.Value = vbChecked Then
mTest(i).Enabled = Not mTest(i).Enabled
mTest(i).Enabled = Not mTest(i).Enabled
End If
Next i
End Sub
Toggling each affected menu item's Enabled property twice—to ensure
its return to its original state—did the trick. No observable menu
flicker resulted, so it's probably advisable that we all get in the
habit of using this hack anytime the Checked property is changed as the
menu is dropped. You could fine-tune by testing for OS, but why go to
that bother for something this simple? —K.E.P.
About the Author
Karl E. Peterson is a GIS analyst with a regional
transportation-planning agency and serves as a member of the Visual
Studio Magazine Technical Review and Editorial Advisory Boards.
Online, he's a Microsoft MVP and a section leader on several VSM
forums. Find more of Karl's VB samples at www.mvps.org/vb.
|