11.07.2015 Views

in PowerBuilder - sys-con.com's archive of magazines - SYS-CON ...

in PowerBuilder - sys-con.com's archive of magazines - SYS-CON ...

in PowerBuilder - sys-con.com's archive of magazines - SYS-CON ...

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

Word Excel OutlookOffice 97 VBAWRD8.HLP VBAXL8.HLP VBAOUTL.HLPOffice 2000 VBAWRD9.CHM VBAXL9.CHM VBAOUTL9.CHMOffice XP VBAWD10.CHM VBAXL10.CHM VBAOL10.CHMTABLE 1 | VBA Help Files for Micros<strong>of</strong>t Office ApplicationsFIGURE 1 | The VBA script<strong>in</strong>g utility available with<strong>in</strong> Micros<strong>of</strong>t Officeproducts+++...n_cst_ole_word_97<strong>of</strong>_<strong>con</strong>nect ()<strong>of</strong>_visible (boolean ab_status)<strong>of</strong>_open (str<strong>in</strong>g as_filename)...: <strong>in</strong>teger: <strong>in</strong>teger: <strong>in</strong>teger...n_cst_word+ <strong>in</strong>v_word : n_cst_ole_word+ <strong>of</strong>_<strong>con</strong>nect (): <strong>in</strong>teger+ <strong>of</strong>_dis<strong>con</strong>nect () : <strong>in</strong>teger+ <strong>of</strong>_visible: <strong>in</strong>teger(boolean ab_status)... ......<strong>in</strong>v_wordn_cst_ole_word# <strong>in</strong>v_word : oleobject# <strong>in</strong>v_<strong>con</strong>st : n_cst_<strong>con</strong>stants_word_ole+ <strong>of</strong>_<strong>con</strong>nect (): <strong>in</strong>teger+ <strong>of</strong>_dis<strong>con</strong>nect (): <strong>in</strong>teger+ <strong>of</strong>_visible (boolean ab_status) : <strong>in</strong>teger... ......+++...n_cst_ole_word_2000<strong>of</strong>_<strong>con</strong>nect (): <strong>in</strong>teger<strong>of</strong>_visible (boolean ab_status) : <strong>in</strong>teger<strong>of</strong>_open (str<strong>in</strong>g as_filename) : <strong>in</strong>teger......n_cst_<strong>con</strong>stants_word_oleis because it’s not <strong>in</strong>stalled by default but <strong>in</strong>stead requires a custom<strong>in</strong>stallation <strong>of</strong> Micros<strong>of</strong>t Office. The documentation is provided as a set<strong>of</strong> help files as <strong>in</strong>dicated <strong>in</strong> Table 1.The VBA script<strong>in</strong>g utility that comes with those products also <strong>con</strong>ta<strong>in</strong>san object browser that can be used to determ<strong>in</strong>e which functionsare accessible on different objects and the syntax for us<strong>in</strong>g them (seeFigure 1). You access the VBA script<strong>in</strong>g utility from Tools->Macro->Visual Basic Editor with<strong>in</strong> the application, and then the object browseris available from the toolbar, from the View menu item, or by hitt<strong>in</strong>gF2. From with<strong>in</strong> the VBA Script<strong>in</strong>g utility you can br<strong>in</strong>g up the documentationfor a particular method, property, or event by hitt<strong>in</strong>g F1after select<strong>in</strong>g it (assum<strong>in</strong>g that the help files have been <strong>in</strong>stalled).The se<strong>con</strong>d issue raised above is the compatibility between versions<strong>of</strong> the same target application. Fortunately, at least with theMicros<strong>of</strong>t products, there is a fairly easy way to determ<strong>in</strong>e which version<strong>of</strong> the target application is <strong>in</strong>stalled. (This will be demonstratedonce we get <strong>in</strong>to the source code.) In addition, the OLE Automation+++...+++...wd100Wordswd10Percentwd10Sentences...: long: long: long...<strong>in</strong>v_<strong>con</strong>stn_cst_ole_word_XP<strong>of</strong>_<strong>con</strong>nect ()<strong>of</strong>_visible (boolean ab_status)<strong>of</strong>_open (str<strong>in</strong>g as_filename))...FIGURE 2 | Class diagram for OLE automation implementation objects= -4= -6= -2...: <strong>in</strong>teger: <strong>in</strong>teger: <strong>in</strong>teger...syntax for these applications is highly backward-compatible. Whenobjects (or methods, properties, or events <strong>of</strong> an object) are depreciatedby Micros<strong>of</strong>t <strong>in</strong> a new version <strong>of</strong> the application, they usually markthose as “hidden.” Hidden objects (or methods, properties, or events)still work with the newer version, but they don’t appear <strong>in</strong> the objectmodel for that new version. Obviously, because each new version <strong>of</strong>the application adds additional features that were not present <strong>in</strong> earlierversions, the syntax developed us<strong>in</strong>g a newer version <strong>of</strong> the objectmodel will not always work for an older version.As mentioned previously, <strong>PowerBuilder</strong> uses late b<strong>in</strong>d<strong>in</strong>g to <strong>in</strong>terfacewith OLE Automation objects, so we are unable to use the <strong>con</strong>stantsprovided <strong>in</strong> the Word type library. However, Micros<strong>of</strong>t does providean Excel spreadsheet on their MSDN site that <strong>con</strong>ta<strong>in</strong>s all <strong>of</strong> the<strong>con</strong>stants and their values used with<strong>in</strong> Office. (Those <strong>con</strong>stants arealso def<strong>in</strong>ed <strong>in</strong> the Micros<strong>of</strong>t supplied help files and can be browsedus<strong>in</strong>g the VBA script<strong>in</strong>g utility.) I downloaded that file and used that<strong>in</strong>formation to create an auto<strong>in</strong>stantiat<strong>in</strong>g nonvisual user object thatcould be used for a similar purpose as the type library, at least withrespect to the <strong>con</strong>stants (see Figure 2).The n_cst_<strong>con</strong>stants_word_ole class <strong>con</strong>ta<strong>in</strong>s the <strong>con</strong>stants and isdef<strong>in</strong>ed as an <strong>in</strong>stance variable on another class, n_cst_ole_word. Thatclass is basically a “virtual” class; it’s never actually called directly.Instead, descendants <strong>of</strong> it are created to handle each <strong>of</strong> the differentversions <strong>of</strong> Word we might actually <strong>in</strong>teract with. The virtual classdeterm<strong>in</strong>es which methods we are go<strong>in</strong>g to make available, and thedescendants actually implement those methods as appropriate. Thevirtual class returns an error message if the method is called, so if themethod is not implemented on a descendant, it implies that particularversion <strong>of</strong> Word does not support the method. This allows us to addadditional methods to the virtual class as new versions <strong>of</strong> Word, andadd new functions and implement them <strong>in</strong> whichever descendantsactually support them without hav<strong>in</strong>g to modify the classes represent<strong>in</strong>gearlier versions <strong>of</strong> Word. n_cst_word acts as a wrapper class so thatthe <strong>in</strong>stantiation <strong>of</strong> the appropriate descendant <strong>of</strong> n_cst_ole_word andcalls to its methods are handled automatically.In the <strong>of</strong>_<strong>con</strong>nect method <strong>of</strong> n_cst_word, the object determ<strong>in</strong>eswhich version <strong>of</strong> Word the user has <strong>in</strong>stalled and creates the appropriatedescendant <strong>of</strong> n_cst_ole_word (see List<strong>in</strong>g 1).Prior to version 8 <strong>of</strong> <strong>PowerBuilder</strong>, the standard method for handl<strong>in</strong>gerrors <strong>in</strong> OLE Automation was to create a user object that <strong>in</strong>heritedfrom the OLEObject class and then code its Error and ExternalExceptionevents. Then that class, rather than the OLEObject class, wouldbe used for the ConnectToObject or ConnectToNewObject call. Oneproblem with that approach is that some OLE Automation propertiesand method returns are themselves OLEObjects, and would not allowthemselves to be cast <strong>in</strong>to the descendant user object. Instead, a userobject based on OLEObject would have to be used, and then theSetAutomationPo<strong>in</strong>ter function <strong>of</strong> that object would be used to redirectprocess<strong>in</strong>g to an <strong>in</strong>stance <strong>of</strong> the custom class.That was all very complicated. It also tended to disassociate theerror-handl<strong>in</strong>g logic from the code that was mak<strong>in</strong>g the call to theobject that caused the error, which made recovery from the errorsomewhat problematic.Fortunately version 8 <strong>of</strong> <strong>PowerBuilder</strong> <strong>in</strong>troduced structured exceptionhandl<strong>in</strong>g, which greatly simplifies this for us. The object that weare us<strong>in</strong>g <strong>in</strong> this sample to <strong>in</strong>teract with Word is the <strong>in</strong>v_word <strong>in</strong>stancevariable <strong>in</strong> the n_cst_word class, and you can see from Figure 3 thatthe class we are us<strong>in</strong>g for it is OLEObject. We simply wrap our OLEAutomation calls <strong>in</strong> a try...catch...end try block and can deal with anyerrors that occur with<strong>in</strong> that block.We’re go<strong>in</strong>g to review some <strong>of</strong> the code from the sample application(which can be downloaded from www.pbdj.<strong>sys</strong>-<strong>con</strong>.com), certa<strong>in</strong>ly notall <strong>of</strong> it, just certa<strong>in</strong> code that illustrates some important <strong>con</strong>cepts.The <strong>of</strong>_visible function determ<strong>in</strong>es whether or not Word will actuallybe visible to the end user. It’s fairly straightforward, simply sett<strong>in</strong>gthe visible property <strong>of</strong> the Word application (not a <strong>PowerBuilder</strong> objectvisible property).10 PBDJ volume12 issue11pbdj.<strong>sys</strong>-<strong>con</strong>.com

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!