home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: WPS_PM / WPS_PM.zip / howtowps.zip / howtowps.pod < prev   
Text File  |  2001-12-03  |  62KB  |  1,536 lines

  1. Ignore escapes (like B<this>), or convert this document to a formatted version
  2. as explained below.
  3.  
  4. =head1 NAME
  5.  
  6. HOWTO-wps-details - how to programmatically fight with WPS
  7.  
  8. =head1 SYNOPSIS
  9.  
  10. View this document as (depending on the format)
  11.  
  12.   perldoc HOWTO-wps-details.pod
  13.   view HOWTO-wps-details
  14.  
  15. Convert from POD to INF as
  16.  
  17.   pod2ipf HOWTO-wps-details.pod >HOWTO-wps-details.ipf
  18.   ipfc /INF HOWTO-wps-details.ipf
  19.  
  20. =head1 DESCRIPTION
  21.  
  22. Programmatic access to WPS is complicated due to several reasons:
  23.  
  24. =over
  25.  
  26. =item *
  27.  
  28. Most APIs are accessible only from I<inside> the WPS process (the
  29. second copy of F<PMSHELL.EXE>), or via DSOM/CORBA via remote method
  30. call.
  31.  
  32. =item *
  33.  
  34. To call things from I<inside> the WPS process one needs to "inject" a
  35. WPS class into the system; possible bugs in the object will jeopardize
  36. the WPS integrity, thus the usability of the computer.  This makes WPS
  37. classes much harder to design than "ordinary" applications.
  38.  
  39. =item *
  40.  
  41. The current implementation of DSOM lacks run-time
  42. method-dispatch-by-name, thus one needs to use CORBA (DII) to make
  43. I<arbitrary> method calls from scripts.  AFAIK, there is no scripting
  44. solution which uses DII for its operation.
  45.  
  46. =item *
  47.  
  48. Even with this hard-to-reach API, there is no API to fetch the data
  49. which allows reconstruction of the object state
  50. (serialization/deserialization, marshalling etc).  Thus one needs to use
  51. undocumented ways to fetch the object state.
  52.  
  53. =item *
  54.  
  55. There is a small subset of API (C<Win*Object*> (C) and C<Sys*Object*>
  56. (REXX) API) usable from outside of the WPS process.  However, the
  57. control provided by this API is very restricted.
  58.  
  59. =back
  60.  
  61. However, some stuff can be done even with such low-grade stuff as plain REXX.
  62.  
  63. =head1 TOOLS
  64.  
  65. =over
  66.  
  67. =item Object REXX
  68.  
  69. injects a class into WPS, so provides a direct access to WPS objects
  70. (with limitations w.r.t. marshalling etc).
  71.  
  72.  
  73. =item REXX without extensions
  74.  
  75. provides access (via and C<Sys*Object*> API) to the C<Win*Object*> (C)
  76. subset of API.
  77.  
  78. =item F<icon.exe> (GUI for F<WPTOOLS.DLL>)
  79.  
  80. (by Kelder) among others shows many things:
  81.  
  82. =over
  83.  
  84. =item *
  85.  
  86. 1/2-decyphered contents of .CLASSINFO
  87.  
  88. =item *
  89.  
  90. Init strings for objects;
  91.  
  92. =item *
  93.  
  94. Contents of F<NOWHERE>
  95.  
  96. =item *
  97.  
  98. Get/Set Object ID, location
  99.  
  100. =back
  101.  
  102. F<WPTOOLS.DLL> is also accessible from REXX.  Beware: there are tools
  103. which require uncompatible versions of this DLL...  F<WPTOOLS.DLL>
  104. uses undocumented hacks to get the object data for EA and F<.INI> files.
  105.  
  106. =item ObjectSpy
  107.  
  108. Class, class-DLL, ID, location, class ancessors, icon
  109. styles (no-delete etc), methods, interface.
  110.  
  111. =item WP Class list Application
  112.  
  113. Class Tree => create an object of the given class, (un)replace a class.
  114.  
  115. =item RWX
  116.  
  117. Class Tree => metaclass/parent, DLL, Cause?, instance/class methods/datasize.
  118.  
  119. =item Object Utility/2
  120.  
  121. D&D => Class, DLL, object-id, location, get/set style flags (no-delete etc).
  122.  
  123. =item Setup strings list
  124.  
  125.  http://www.os2ezine.com/v3n07/wpsetup.txt
  126.  
  127. a  complete  listing  of setup strings for common  object classes,
  128. along with a list of the values used with.
  129.  
  130. =item WPObjData
  131.  
  132.  http://www.os2ezine.com/v3n07/hammer.htm
  133.  
  134. tame WPObjData _and_ to put it to work doing something useful.
  135.  
  136. =item WPSTools:
  137.  
  138. =over
  139.  
  140. =item mo
  141.  
  142. create/modify-by-string-id objects
  143.  
  144. =item eo
  145.  
  146. modify by handle
  147.  
  148. =item fo
  149.  
  150. create shadows in TARGET by the *-pattern in ./
  151.  
  152. =item qo
  153.  
  154. report the handle by the string-id
  155.  
  156. =item wplist
  157.  
  158. list classes/dll
  159.  
  160. =item wpkill
  161.  
  162. delete class
  163.  
  164. =item wpmake
  165.  
  166. add class
  167.  
  168. =back
  169.  
  170.  
  171. =item Perl
  172.  
  173. has access to C<Win*Object*> API (C) (via OS2::WinObject module).  The
  174. module C<SOM> gives access to all the SOM objects and the object
  175. repository, but (currently) only a limited access to DSOM objects (due
  176. to the absense of an interface to DII).
  177.  
  178. =back
  179.  
  180. =head2 DragText
  181.  
  182. I<Are you saying I can hilite something that shows up in the VIO window
  183. that F<CHECKINI> runs in, and DragText will locate it elsewhere on the
  184. "real" desktop?>
  185.  
  186. Yes - if the object actually exists.  I just ran F<checkini> looking for
  187. an example and found two.  The first is sort of involved, the second
  188. is pretty straightforward.
  189.  
  190. B<Example 1:>
  191.  
  192.   =================================================
  193.    PM_Abstract:Objects & PM_Abstract:FldrContents
  194.   =================================================
  195.     OBJECTID <WP_TEMPS> (from 32DCB - G:\DESKTOP\ALL\OS!2 SYSTEM\TEMPLATES)
  196.     POINTS TO ANOTHER OBJECT 32968 - F:\DESKTOP\ALL\OS!2 System\TEMPLATES
  197.  
  198.   É╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓»
  199.   º Assign a new OBJECTID to G:\DESKTOP\ALL\OS!2 SYSTEM\TEMPLATES?  º
  200.   ÇÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ╢ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ⌠
  201.   º               YES              ⁿ              NO                º
  202.   ╘╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╪╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓¼
  203.  
  204. Honestly, I wasn't quite sure what this was telling me at first (I was
  205. up way too late last night).  I have an FP7 system on "F:" and an FP14
  206. system on "G:".  I was running F<checkini> against F:, so why was it
  207. identifying a problem on G:?
  208.  
  209. Then I remembered:  I had (foolishly) opened G:'s F<Templates> Folder
  210. while running F: and had seen the system populate it with shadows of
  211. F:'s templates.  This produced a record in F:'s F<os2.ini> describing the
  212. contents of G:'s F<templates> folder (in particular, those shadows).
  213.  
  214. Trying to make sense of it, I highlighted <WP_TEMPS> in the VIO window
  215. where F<checkini>'s output appears.  Clicking Ctrl+Shift MB2 caused DragText
  216. to pop up its WPS menu.  DT adds the object's name to the menu and puts
  217. its full path on a submenu (selecting either will open whichever folder
  218. contains the object).  Checking the path on the submenu confirmed that
  219. F:'s <WP_TEMPS> did point to the folder on F:.  I then did the same
  220. with the two object handles (32DCB & 32968), just to be sure.
  221.  
  222. Finally, it dawned on me:  when an object is assigned an ID, the info is
  223. stored in PM_Workplace:Location *and* in the object's data (in this case,
  224. in the folder's .CLASSINFO EA).  Apparently, whenever F<checkini> encounters
  225. an object whose data contains an Object ID, it cross-references this with
  226. the entry in PM_Workplace:Location.
  227.  
  228. F<G:\...\TEMPLATES>'s EA showed its ID to be <WP_TEMPS>, but PM...:Location
  229. said this was assigned to F<F:\...\TEMPLATES>, so F<checkini> wanted to be
  230. "helpful" and change G:'s ID.  Since this ID was perfectly valid when
  231. booting G:, and since my setup on G: would be screwed up if I removed it,
  232. I answered "No".
  233.  
  234. Now, without some of this prior knowledge, DT alone wouldn't have enabled
  235. me to figure this out completely.  However, being able to confirm that when
  236. booted to F:, <WP_TEMPS> pointed at the right folder on F:, and knowing that
  237. there is another setup on G: _should_ be enough info to cause any *cautious*
  238. user to answer "No" as well.
  239.  
  240. B<Example 2:>
  241.  
  242.   Folder : F:\DESKTOP\PRONEWS!2
  243.     Object 2E027 , Class WPProgram : Purchase ProNews/2
  244.     Exename: E:\PN15B4\PURCHASE.EXE<-UNABLE TO ACCESS! Curdir: E:\PN15B4
  245.  
  246.   É╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓»
  247.   º Remove this object which contains errors? º
  248.   ÇÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ╢ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ⌠
  249.   º         YES         ⁿ         NO          º
  250.   ╘╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╪╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓╓¼
  251.  
  252. I didn't doubt that F<checkini> was correct, but I still wanted to see for
  253. myself.  I selected the object handle (2E027), clicked Ctrl+Shift MB2 to
  254. display this program object's menu, then selected 'Properties'.  As reported,
  255. it pointed at PURCHASE.EXE.  Since this file had been included in previous
  256. distributions of ProNews/2, I decided to check the directory.  Again, I
  257. used DT to pop up the menu for E:\PN15B4 and selected 'Open'.  Scanning the
  258. directory, I found a PURCHASE.APP but no PURCHASE.EXE.  Satisfied that the
  259. object was unusable, I told F<checkini> to delete it.  (BTW... this is the
  260. only bug I've found in PN v1.51b4 so far.)
  261.  
  262. FWIW...  Example 1, along with my description in the original article
  263. of how I "lost" G:'s Desktop, suggests that it's a *bad* idea to look
  264. at one installation's standard system folders from another setup on the
  265. same machine.  Example 1 also suggests that you're not doing yourself
  266. any favors by having it automatically answer "Yes" to every question.
  267. User intervention *is* required for optimal results!
  268.  
  269. ______________________________________________________________
  270.  
  271. B<There is no official way to query the OBJECTID of a given object.
  272. However, my WPTOOLS.DLL does have some functions to do it. WPTOOLS.DLL
  273. is part of the WPTOOLxx.ZIP archive.
  274. Please look at: L<http://www.os2ss.com/information/kelder/>>
  275.  
  276. I<Hmmm.  You're right, I misread that, I guess :-(
  277. How 'bout this rexx instead:>
  278.  
  279.   /* OBJECTID.CMD - Display object ids known to Workplace Shell */
  280.   call rxfuncadd 'SysLoadFuncs', 'REXXUTIL', 'SysLoadFuncs'
  281.   call sysloadfuncs
  282.   call SysIni 'USER', 'PM_Workplace:Location', 'All:', 'ids.'
  283.     do i=1 to ids.0
  284.       Say ids.i
  285.     end
  286.  
  287. PMFJI...  but this is a perfect example of where my favorite DragText feature
  288. (WPS links) would be uncommonly helpful.
  289.  
  290. Once you have a listing of object IDs, you can use DragText to manipulate them
  291. as though you had a folder full of shadows rather than words in a window.  You
  292. can select an ID, then drag the object it refers to, or you can pop up its WPS
  293. menu.  DT adds the object's name to the top of the menu and gives it a submenu
  294. that shows the full path. This makes it easy to identify what <PDP_SMARTPFA>
  295. refers to (F:\Desktop\OS!2 System\Problem!!Determination Tools\Hard File Monito
  296. r).
  297. Selecting this menu item will take you directly to the named object.  Of course
  298. ,
  299. you can use most of the other menu entries too (Open as, Copy, etc).
  300.  
  301. You can skip the script if you have an ini editor that uses a listbox to
  302. display its info (most do, regedit2 doesn't).  Point it at PM_Workplace:Location
  303. in F<os2.ini>, then select an object ID from the list.  And, if you want skip the
  304. script but still have a listing, you can use DT to drag the entire contents of
  305. the listbox to somewhere more convenient - your editor, a file, etc.
  306.  
  307. =head2 Open View IDs
  308.  
  309. from L<http://www.os2ezine.com/v3n07/wpsetup.txt>, same as in
  310. L<Setup strings list>:
  311.  
  312.     -1  UNKNOWN
  313.      0  DEFAULT
  314.      1  CONTENTS (icon view)
  315.      2  SETTINGS
  316.      3  HELP
  317.      4  RUNNING (run pgm; for data files, run associated pgm)
  318.    101  TREE (tree view)
  319.    102  DETAILS (details view)
  320.    120  AUTO (WPDisk objects only)
  321.    121  PALETTE (color and font palettes, plus the LaunchPad)
  322.   4096  the 1st pgm associated with a data file (usually 1st on its Open menu)
  323.   4097  the 2nd pgm associated with a data file (usually 2nd on its Open menu)
  324.    etc
  325.   5000  the 1st pgm added to a data file's Open menu using the Menu page
  326.   5001  the 2nd pgm added via the Menu page
  327.    etc
  328.  25856  USER (proprietary view IDs start here;  USER+1 is most common)
  329.  42818  TextView (OD v1.0)
  330.  46914  TextView (OD v1.5)
  331.  
  332.  
  333. =head2 Boilerspace template
  334.  
  335. Change F<SETVIEW.CMD> to the name of your script.
  336.  
  337. Keep in mind that C</*> should I<start> the script, dependint on how
  338. you copy this script, you may need to unindent the first line.  In
  339. F<view.exe>, use C<Control-Insert> to B<Copy> the contents of this
  340. window to a clipboard, then B<Paste> into your favorite editor.
  341.  
  342.   /* SETVIEW.CMD */
  343.   /*   drop a file on this script's icon, or */
  344.   /*   invoke it from the command line passing the filename as an argument */
  345.  
  346.   call RxFuncAdd 'SysLoadFuncs', 'RexxUtil', 'SysLoadFuncs'
  347.   call SysLoadFuncs
  348.  
  349.   arg object
  350.   arg = strip(object,,'"')        /* Spaces in argument => quoted arg */
  351.  
  352. ... Put the code at this place!
  353.  
  354.   exit
  355.  
  356.   ReportRC:
  357.   parse arg rc
  358.   if rc
  359.   then
  360.      say "Success"
  361.   else
  362.      say "Failure"
  363.   return
  364.  
  365.  
  366. =head2 strip() in REXX for spaces in filenames
  367.  
  368. FYI #1...  because of limitations in REXX, you can only set the attributes
  369. for abstract objects like program objects or shadows if you have the object's
  370. Object ID (e.g. <WP_OS2WIN> for your OS/2 Window program object).  For
  371. files and folders, you can supply the fully qualified name instead.
  372.  
  373. FYI #2... the "strip" command in my REXX L<Boilerspace template>
  374. lets you drop files whose names contain spaces onto your cmd icon.
  375. Without it, these names will be passed to REXX with surrounding quotes
  376. that will cause functions to fail.
  377.  
  378. =head1 F<.CLASSINFO>, 90 sec delay, C<DEFAULTVIEW>
  379.  
  380. After deleting the CLASSINFO EA did you reboot, or at least restart the WPS?
  381.  
  382. The WPS only looks at this EA when it "awakens" an object (typically, when
  383. you open the folder containing the object);  thereafter, it uses its in-memory
  384. copy of this info.  Restarting the WPS clears this.
  385.  
  386. OTOH, If you close the folder in question, and you don't have anything open
  387. in tree-view which includes this folder, the WPS will put the objects to
  388. sleep after about 90 seconds (i.e. it will remove them from memory).  With
  389. the CLASSINFO gone and no memory of the objects' previous settings, the WPS
  390. should use the association currently in force.
  391.  
  392. If you're in a hurry <g>, use this (see L<Open View IDs> for 4096) in
  393. L<Boilerspace template>:
  394.  
  395.   call ReportRC(SysSetObjectData(object,"DEFAULTVIEW=4096;"))
  396.  
  397. =head2 Sample script to set F<.TYPE> and F<.CLASSINFO>
  398.  
  399.  
  400. I<I want to change all files with an extension of jar files to TSZipMgr
  401. so that jar files can be opened by the OD Zip Manager.>
  402. [snip]
  403. I<I'll come up with a REXX script that will perform at least part of the work.>
  404.  
  405. Paste or drag the following into a file named jarz.cmd, then drop objects on it
  406. or use it from a command line.  Your jar files should change class when you
  407. restart the WPS.  It may happen sooner if the folder containing the objects
  408. is closed for about 2 minutes.  YMMV.
  409.  
  410.   /*****************************************************************/
  411.   /* JARZ.CMD                                                      */
  412.   /* (C) Copyright R L Walsh 1999 - All Rights Reserved            */
  413.   /*                                                               */
  414.   /* JARZ resets .JAR .ZIP, and optionally .EXE files'             */
  415.   /* filetype to "ZIP File" and deletes their WPS class data.      */
  416.   /*                                                               */
  417.   /* Each file should become an instance of whatever WPS class     */
  418.   /* handles ZIP Files (a reboot may be needed).  It may also      */
  419.   /* become associated with programs that handle this file type.   */
  420.   /*                                                               */
  421.   /*****************************************************************/
  422.   /* DATA                                                          */
  423.   /*****************************************************************/
  424.   /* the list of acceptable extensions;  ext.0 sets the "last"     */
  425.   /* item in the list (e.g. '2' excludes EXEs, '3' includes them   */
  426.  
  427.   ext.0 = 2
  428.   ext.1 = '.jar'
  429.   ext.2 = '.zip'
  430.   ext.3 = '.exe'
  431.  
  432.   /* The          Curr one       8 data    EA                      */
  433.   /* EA:    MVMT CP   item ACSI chars     value                    */
  434.  
  435.   typeval = 'DFFF 0000 0100 FDFF 0800'X || 'ZIP File'
  436.  
  437.   /*****************************************************************/
  438.   /* CODE                                                          */
  439.   /*****************************************************************/
  440.  
  441.   parse upper arg junk
  442.   junk = strip(junk)
  443.  
  444.   if (junk = '' | junk = '?'  | junk = '/?' | junk = '/HELP') then
  445.   do
  446.       say ''
  447.       say '    JARZ resets .JAR .ZIP, and (optionally) .EXE files' || "'"
  448.       say '    filetype to "ZIP File" and deletes their WPS class data.'
  449.       say ''
  450.       say '    JARZ filespec [filespec [...]]'
  451.       say ''
  452.       say '         filespec = file name (wildcards OK), or'
  453.       say '                  = directory name (no wildcards)'
  454.       say ''
  455.       say '    See the comments in jarz.cmd for additional info.'
  456.       exit
  457.   end
  458.  
  459.   call RxFuncAdd 'SysLoadFuncs', 'RexxUtil', 'SysLoadFuncs'
  460.   call SysLoadFuncs
  461.  
  462.   /* the big loop that's executed for each file spec               */
  463.   do while junk \= ''
  464.  
  465.   /* deal with quoted names, then clean up string                  */
  466.       if left(junk, 1) = '"' then
  467.           parse var junk '"' filespec '" ' junk
  468.       else
  469.           parse var junk filespec junk
  470.       filespec = strip(filespec)
  471.       filespec = strip(filespec,,'"')
  472.       if filespec = '' then
  473.           iterate
  474.  
  475.   /* rustle up some files                                          */
  476.   /* note:  SaySFTErr performs an exit so it never returns         */
  477.       rc = SysFileTree(filespec,'file','FO')
  478.       if rc \= 0 then
  479.           call SaySFTErr
  480.  
  481.   /*  if that didn't work, see if the filespec is a directory      */
  482.       if file.0 = 0 then
  483.       do
  484.           rc = SysFileTree(filespec,'file','DO')
  485.           if rc \= 0 then
  486.               call SaySFTErr
  487.  
  488.   /* if we didn't get exactly one dir back, make this a no-op      */
  489.   /* else get a list of all files in this dir                      */
  490.           if file.0 \= 1 then
  491.               file.0 = 0
  492.           else
  493.           do
  494.               filespec = file.1 || '\*.*'
  495.               rc = SysFileTree(filespec,'file','FO')
  496.               if rc \= 0 then
  497.                 call SaySFTErr
  498.           end
  499.       end
  500.  
  501.   /* for each file, see if it's extension is on the list           */
  502.   /* if so, have DueDamage change its EAs                          */
  503.       ctr = 0
  504.       do i=1 to file.0
  505.           do j=1 to ext.0
  506.               if right(file.i,4) = ext.j then
  507.               do
  508.                   call DueDamage
  509.                   ctr = ctr + 1
  510.                   leave
  511.               end
  512.           end
  513.       end
  514.       say ctr 'files processed for <' || filespec || '>'
  515.  
  516.   end
  517.   /* bottom of the big loop                                        */
  518.  
  519.   say 'Exiting'
  520.   exit
  521.  
  522.   /*****************************************************************/
  523.  
  524.   DueDamage:
  525.  
  526.   /* write a null value for .CLASSINFO                             */
  527.       rc = SysPutEA(file.i,'.CLASSINFO','')
  528.       if rc \= 0 then
  529.           err = 'removing .CLASSINFO'
  530.       else
  531.   /* write new value for .TYPE                                     */
  532.       do
  533.           rc = SysPutEA(file.i,'.TYPE',typeval)
  534.           if rc \= 0 then
  535.               err = 'resetting .TYPE'
  536.       end
  537.  
  538.   /* display either the filename or an error message               */
  539.       if rc = 0 then
  540.           say Filespec('name',file.i)
  541.       else
  542.           say 'Error #' rc err 'for file' Filespec('name',file.i)
  543.  
  544.       return
  545.  
  546.   /*****************************************************************/
  547.  
  548.   SaySFTErr:
  549.       say 'Error #' rc 'in SYSFILETREE for <' || filespec ||'>'
  550.       say 'Exiting'
  551.       exit
  552.  
  553.   /*****************************************************************/
  554.  
  555. =head2 Effects of lost EA
  556.  
  557. You're right, the problem is the EAs - but why they aren't copied onto a
  558. floppy is beyond me.  Bad news:  you've lost 2 EAs.  Good news:  you can
  559. recover the one that counts and gain some functionality.
  560.  
  561. =over
  562.  
  563. =item .CLASSINFO
  564.  
  565. this identifies the file as a WebEx_Url to WPS.  Unlike most
  566. file-based classes, WebEx_Url doesn't reconstruct this, so when it's gone,
  567. it's gone.  No big loss:  you've lost the icon and special notebook.
  568.  
  569. =item .TYPE
  570.  
  571. this is set on the first page of a standard datafile's notebook and
  572. is what the WebEx app uses to identify Urls.  Set your copied files to type
  573. 'WebExplorer_Url' and they'll become acceptable to WebEx.  Open WebEx's
  574. notebook and associate it with objects of this type.  They'll get WebEx's
  575. icon and open WebEx when you doubleclick on them.
  576.  
  577. =back
  578.  
  579. The EAs for *most* files are completely superfluous.  The exceptions
  580. are those files which need their EAs to be recognized as belonging to
  581. a specialized WPS class or to be given special handling by an app.
  582. This usually applies to files without a distinguishing file extension.
  583. In these cases, the WPS relies on their .TYPE or .CLASSINFO EAs.
  584.  
  585. A good example is a URL object: see L<URL objects>.  (Effectively,
  586. different programs use .TYPE or .CLASSINFO EA to distinguish the URLs
  587. objects from data files.)
  588.  
  589. FYI...  The WPS uses a file's extension or filetype to assign it to
  590. a class only if it lacks a .CLASSINFO EA.  Once it has acquired this
  591. (typically by opening the object's Properties notebook), the extension
  592. or type no longer matters and can be changed or deleted without
  593. affecting the file's class assignment.
  594.  
  595. For folders, the only EA that really matters is .CLASSINFO, and then,
  596. primarily for folders in your F<Desktop> tree.  Folders such as F<Desktop>,
  597. F<Templates>, and F<Nowhere> only possess special properties because their
  598. CLASSINFO EA identifies them as belonging to a specialized class.
  599. Loss of their .CLASSINFO will cause serious system disruption.
  600.  
  601. Some of your F<Desktop> folders may be generic WPFolder objects, but
  602. their .CLASSINFO contains their Object ID which the system may rely
  603. upon. Since the Object IDs are also stored in os2.ini, loss of these
  604. EAs isn't that critical.  Checkini will identify the problem and fix
  605. it. For all other folders, all you'll lose is your customizations such
  606. as sort order, icon positioning, etc.
  607.  
  608. Miscellanea:
  609. If you have files or folders with longnames on a FAT drive, you'll lose
  610. the name when the .LONGNAME EA is stripped.  On any file system, titles
  611. that include illegal file characters like linefeeds or backslashes will
  612. be lost.  When restored, the titles will match the file or folder's
  613. real name and have exclamation points where the illegal characters were.
  614.  
  615. A very few exe's will lose their icons when their .ICON EA is removed.
  616. In most cases, the WPS can look in the file to get the icon, but in
  617. some cases this fails.  Other than this, you can safely strip the EAs
  618. from your application files and never notice the difference.
  619.  
  620. In those cases where the EAs _are_ critical, use EAUTIL to strip them
  621. before backup and to restore them when you return the files and
  622. directories to use.  Better yet, use backup and restore products that
  623. were designed for OS/2.  If all else fails, use Info-zip, then backup
  624. the zips.
  625.  
  626.  
  627. =head2 Menu items
  628.  
  629.  
  630. I<So you're saying there's no way to do what I want to do?  Those
  631. menu items have to be stored SOMEWHERE.  Even if I can't use
  632. a standard API, there's got to be a way to add these menu items.
  633. Are they part of the EA's for the F<Desktop> folder?>
  634.  
  635. Yes they are. They are stored in the .CLASSINFO ea.
  636.  
  637. As I recall well, there has been a beta toolkit for Warp 3 that even
  638. included the syntax for adding menues to objects of WPFileSystem or
  639. derived classes. Unfortunattely, this vanished again in the non-beta
  640. version. It didn't work anyway....
  641.  
  642. Theoretically, you could alter the .CLASSINFO EA, but I am not sure you
  643. will be able to keep the changes since the WPS tends to overwrite this
  644. EA on shutdown.
  645.  
  646. I can tell you where exactly it is stored. Should you want this, please
  647. first download my 'icontool' from my homepage since this will help you
  648. is understanding what I mean.
  649.  
  650. Still I wouldn't advise you to do this...
  651.  
  652. Henk Kelder
  653.  
  654.  
  655. =head1 PMWP entries in F<POPUPLOG.OS2>
  656.  
  657. I've been looking at this for quite a while, and have come up with a
  658. possible explanation and a cure that's worse than the disease.  AFAIK,
  659. the WPS uses "deferred parameter checking" - IOW, it doesn't check
  660. parameters for validity, it just uses them.  If they cause a trap, the
  661. WPS's exception handler cleans up, usually by aborting the current
  662. operation.  As such, PMWP isn't the "cause" of the problem, just the
  663. unsuspecting victim of bad data.  Overall, the system is working as
  664. designed.
  665.  
  666.  
  667. =head2 C<SHELLEXCEPTIONHANDLER>
  668.  
  669.  
  670. If you're really hell-bent on eliminating this, you can try adding this
  671. line to F<config.sys>:
  672.  
  673.   SET SHELLEXCEPTIONHANDLER=OFF
  674.  
  675. This turns off the WPS's exception handler, guaranteeing any errors
  676. will cause a crash.  It's normally used by developers of WPS classes
  677. to keep the WPS from covering up bugs in their code.  (That's why I've
  678. pursued this problem so vigorously: with the exception handler off, I
  679. couldn't keep the WPS up long enough to begin my debugging.)
  680.  
  681.  
  682. =head1 Lost/broken desktop or broken F<Templates> or F<Startup>
  683.  
  684. Where to begin...  How about a warning?  The best way to "lose"
  685. your Desktop (without suffering any real damage) is to access one
  686. installation's F<Desktop> from another setup on the same machine.
  687. E.g. I installed FP14 on my alternate setup, then later started
  688. looking at its F<Desktop> from my FP7 setup.  When I rebooted to the
  689. FP14 system, all I got was a command window on an empty F<Desktop>.
  690.  
  691. First step:  edit F<config.sys> and add this line, then reboot.
  692.  
  693.     SET DESKTOP=C:\DESKTOP
  694.  
  695. (see L<<< Order of C<DESKTOP> and C<< <WP_DESKTOP> >> >>>). If
  696. everything comes back as it should be, run the following code
  697.  
  698.   call ReportRC(SysSetObjectData("C:\DESKTOP","OBJECTID=<WP_DESKTOP>"))
  699.  
  700. (put this in L<Boilerspace template>); then "rem-out" the line in
  701. F<config.sys> until the next time it's needed.  You need to run the REXX
  702. script or else many installers will be unable to create Desktop
  703. objects; you'll want to disable the F<config.sys> entry so you'll know
  704. when a problem has occurred.  These two steps will solve most lost
  705. Desktop problems.
  706.  
  707. After rebooting, if your Desktop returns and all of the folders
  708. and files are present but all of the program objects, shadows,
  709. and miscellanea are missing, then F<os2sys.ini> is probably corrupted.
  710. If you have pgm objects or shadows that point at files on other
  711. disks, see if they're still good in order to guage the extent of
  712. the damage.  Also, pop up the Desktop menu and select 'System
  713. Setup'.  Does the folder open?
  714.  
  715. At this point, you have several options (see also L<Script to recreate
  716. all or some lost objects>).  The best would be to restore a *recent*
  717. archive of your Desktop from the Alt-F1 boot screen.  If you were able
  718. to open F<System Setup> from the Desktop menu, you may instead want to
  719. restore recent backups of F<os2.ini> & F<os2sys.ini>, such as those
  720. made by F<checkini>.  You can either reboot to a command line and copy
  721. them over, or you can edit F<config.sys> and (temporarily) change SET
  722. SYSTEM_INI= and SET USER_INI= to point to them, then reboot.  If you
  723. choose the latter option, you can copy & rename the files and reedit
  724. F<config.sys> after you're satisfied with the results.
  725.  
  726. Lacking recent backups, you still have some options.  First run
  727. F<checkini> in diagnostic mode (i.e. *without* the "/C" option).
  728. If you weren't able to open F<System Setup> from the Desktop menu,
  729. see if it offers to assign the object ID <WP_CONFIG> to the
  730. F<System Setup> folder (and makes similar offers for other standard
  731. folders as well).  This will determine whether you'll be forced
  732. to run F<MAKEINI>.  Also, see if it finds valid objects assigned to
  733. "missing" folders.  If so, you should be able to recover them when
  734. you run it again in "fixit" mode.
  735.  
  736. If opening F<System Setup> wasn't a problem, or if F<checkini> offered
  737. to fix it, you can rerun F<checkini> with "/C" to recover as much as
  738. possible.  Avoid letting it delete anything and skip the final
  739. filehandles check altogether.  After a reboot, see how things
  740. look.  You may have to drag a lot of recovered objects back to
  741. their proper folders, and some things may still be screwed up.
  742. By not deleting anything on the first run, you may have invalid
  743. program objects but at least you'll know what you used to have
  744. and what needs fixing.  When things are back to normal, then run
  745. F<checkini> again and let it do all the cleanup still required.
  746.  
  747. My repeated mention of opening F<System Setup> from the Desktop
  748. menu is simply a quick way to see if the standard folders have
  749. the object IDs they need for a properly functioning system.  If
  750. they don't, then you probably have other problems as well that
  751. need fixing.  For this you'll want to run a *non-destructive*
  752. F<MAKEINI> with this command line (after making a backup):
  753.  
  754.     MAKEINI OS2.INI INI.RC
  755.  
  756. Before doing so, you may want to customize F<INI.RC> and eliminate
  757. or comment-out things you don't want (e.g. all those tired URL
  758. objects, or, at the end of the file, the 3 lines that will reset
  759. your display to VGA).
  760.  
  761. When you reboot, the WPS will create a new Desktop with all new
  762. folders and objects, and will rename your current (defective) one
  763. as F<Previous Desktop>.  After another reboot (just in case), run
  764. F<checkini> and see what it can recover (in this case, let it remove
  765. any duplicate object IDs it finds from the previous Desktop's
  766. objects).  Chances are that you'll have to drag a lot of things
  767. from the old desktop to the new.
  768.  
  769. When this long ordeal is finally over, you can delete the previous or
  770. temporary Desktop folder(s).  Because they have the NODELETE style,
  771. you'll have to get rid of this before 'Delete' appears on their menus.
  772. One way is to plug this into the L<Boilerspace template>):
  773.  
  774.   rc = SysSetObjectData( "C:\PREVIOUS DESKTOP","NODELETE=NO")
  775.  
  776. Except for a few details here and there, AFAIK, that about covers
  777. it.  Did I answer your question, Barbara?
  778.  
  779. B<BTW...> since I haven't plugged DragText yet, I should mention that
  780. it can be a handy adjunct when dealing with these problems, e.g.,
  781. validating required object IDs (as found in F<INI.RC>), accessing &
  782. examining objects as F<checkini> finds them (via the numeric object
  783. handles it displays for each), etc.  See L<DragText>.
  784.  
  785. =head2 Order of C<DESKTOP> and C<< <WP_DESKTOP> >>
  786.  
  787.  
  788. If F<D:\DESKTOP> B<does> exist and your F<config.sys> says SET
  789. DESKTOP=D:\DESKTOP, the WPS will attempt to use it.  If that directory
  790. B<doesn't> exist, I<of course> you're going to have problems.
  791.  
  792. If this line is not in F<config.sys>, the WPS will try to locate the
  793. Desktop using F<os2.ini> info.  If that info is missing, you'll have
  794. your current problem.  Use the following REXX script to restore the
  795. info to F<os2.ini>.  Just be sure that it points to your current,
  796. *valid* Desktop path (and don't forget to delete the "set desktop="
  797. line in F<config.sys>).
  798.  
  799. =head2 Details on lost desktops
  800.  
  801. [More on L<Lost/broken desktop or broken F<Templates> or F<Startup>>.]
  802.  
  803. This problem comes in two flavors:  "plain vanilla" and "rocky road".
  804.  
  805. First, restore the backup ini files (even though they didn't work last time).
  806. In F<config.sys>, add "SET DESKTOP=E:\DESKTOP", then reboot.  This will
  807. point PM at your original F<Desktop> directory.  If all your program objects,
  808. shadows, and other non-filesystem objects reappear, you had the "plain
  809. vanilla" problem.  All you need to do now is run the REXX script below.
  810.  
  811. OTOH, if only files and folders reappear and/or you get unexpected objects
  812. in unexpected places, you've got "rocky road".  In this case, consider
  813. yourself lucky if you can recover any of your old setup.  If you don't already
  814. have it, get wptool19.zip so you can run F<checkini.exe>.  The first time you
  815. run it, you may want to omit the "/C" command line parameter so that it
  816. only reports errors and doesn't try to fix them.
  817.  
  818. The first time you have it try to fix things, your primary goal is to
  819. have it recover objects that it says are located in non-existent
  820. directories.  Say 'no' to most offers to fix other problems.  After a
  821. reboot, your F<Desktop> will be filled with folders full of found
  822. objects.  Retrieve and fix your own objects but skip system-supplied
  823. ones.  Things will be so messed up that you'd do well to run a
  824. nondestructive F<MAKEINI> to recreate your F<System Setup>, F<Startup>,
  825. etc. folders and the objects therein (see L<F<Startup> folder and
  826. ObjectID>, L<Hanging template folder>, L<Restoring F<System Setup> or
  827. F<Templates>>, L<F<ini.rc> and C<SysCreateObject>>, L<Script to recreate
  828. all or some lost objects>).  After that's done (and you've rebooted
  829. yet again), run F<checkini> again to clean up the mess that remains.
  830.  
  831. FYI... the "plain vanilla" problem is common and easy to fix: the
  832. F<Desktop> folder's Object ID (i.e. <WP_DESKTOP>) has disappeared, so the
  833. WPS can't find it.  The REXX line in L<Lost/broken desktop or broken
  834. F<Templates> or F<Startup>> restores it.  The "rocky road" problem is
  835. semi-catastrophic: the file handles table in F<os2sys.ini> got
  836. lost/corrupted and the system assigned all new handles to the files
  837. and folders on your E: drive.  The WPS uses these handles to associate
  838. abstract (i.e. non- filesystem) objects with particular folders.  Now
  839. that the folders' handles have changed, your abstract objects are no
  840. longer associated with any folder, so they're in limbo.  F<Checkini>
  841. will fix this by associating these objects with new folders it
  842. creates.
  843.  
  844.  
  845. =head2 F<Startup> folder and ObjectID
  846.  
  847. To actually do anything, your F<Startup> folder must be of class
  848. WPStartup and have the object ID "<WP_START>".
  849.  
  850. For future reference...  Chances are that this F<Startup> folder had lost
  851. either its ObjectID ("<WP_START>") or its .CLASSINFO extended
  852. attribute.  ObjectID is easy to fix: use SysSetObjectData in a REXX
  853. script to restore it.  Losing the EA that tells the WPS that this is a
  854. F<Startup> folder renders it useless, so you have to create a new F<Startup>
  855. folder.  If you search F<\os2\ini.rc>, you'll find any entry for this
  856. folder that contains all the parameters you'll need to recreate it
  857. using SysCreateObject.  Note that the parms are *not* listed in the
  858. order that SysCreateObject requires, so you'll have to do some
  859. transposition.  See L<F<ini.rc> and C<SysCreateObject>>, L<Script to
  860. recreate all or some lost objects>.
  861.  
  862. =head2 Hanging template folder
  863.  
  864. More than likely, there's some invalid object in there which
  865. is causing the hang - perhaps a template for some object class
  866. you've deregistered.  Here's a list of steps you can take to
  867. fix things, starting with the most benign:
  868.  
  869. =over
  870.  
  871. =item *
  872.  
  873. run F<checkini>.
  874.  
  875. No comment necessary :-)
  876.  
  877.  
  878. =item *
  879.  
  880. delete the F<Templates> Folder's .ICONPOS EA
  881.  
  882. I've seen invalid entries or references to nonexistent classes
  883. in here cause stuff to disappear
  884.  
  885.  
  886. =item *
  887.  
  888. delete "PM_Workplace:Templates" from F<os2.ini>
  889.  
  890. This provides the list of options on the Create Another submenu;
  891. it will be rebuilt as the WPS rediscovers your templates.
  892.  
  893.  
  894. =item *
  895.  
  896. delete the contents of F<Templates>
  897.  
  898. Obviously not an option here since you can't access them.
  899. It's worth noting that any class that provides a template will
  900. recreate it on demand - only the ones that are customized or
  901. "variations on a theme" will be lost.  If you do this, be sure
  902. to delete "PM_Workplace:Templates" from F<os2.ini> afterwards.
  903.  
  904.  
  905. =item *
  906.  
  907. delete the F<Templates> Folder, then recreate it
  908.  
  909. =over
  910.  
  911. =item -
  912.  
  913. Before doing so, use your filemanager to move any customized
  914. file templates to another directory.  For example, Lotus
  915. WordPro has a subfolder in there filled with specialized
  916. templates that will be lost otherwise.  The best place to
  917. put them is a folder deep in your directory tree where
  918. neither it nor it parent is likely to be accessed.
  919.  
  920.  
  921. =item -
  922.  
  923. After saving what you want, delete the remaining files and
  924. directories, then delete the F<Templates> folder itself.  I
  925. don't know if you'll be able to do this while the WPS is
  926. running.  Regardless, avoid accessing both F<Templates> and
  927. whatever folder it's in during the session you do all this.
  928.  
  929.  
  930. =item -
  931.  
  932. Delete "PM_Workplace:Templates" from F<os2.ini>.
  933.  
  934.  
  935. =item -
  936.  
  937. Kill the WPS or reboot, then run this script to recreate
  938. F<Templates> (the SysCreateObject call should all be on one line):
  939.  
  940.   /* script to recreate the TEMPLATEs folder */
  941.  
  942.   call RxFuncAdd 'SysLoadFuncs', 'RexxUtil', 'SysLoadFuncs'
  943.   call SysLoadFuncs
  944.   rc = SysCreateObject( "WPTemplates", "Templates", "<WP_OS2SYS>",
  945.        "HELPPANEL=15680;NODELETE=YES;OBJECTID=<WP_TEMPS>", "UPDATE")
  946.  
  947. (compare with L<Restoring F<System Setup> or F<Templates>>).
  948.  
  949. =item -
  950.  
  951. Finally, open your new F<Templates> folder.  There should be a
  952. lot of activity as the WPS recreates all of the standard
  953. templates.  Return any templates you saved *and* open every
  954. folder you know contains templates (this will repopulate
  955. "PM_Workplace:Templates" and your Create Another menus).
  956.  
  957. =back
  958.  
  959. =back
  960.  
  961. A final note:  if you've installed Feature Installer, you probably
  962. have a template labelled F<Data File:1> that shows a hammer and
  963. screwdriver.  Then see L<F<Data File:1> and C<NODELETE>>.
  964.  
  965. You can put this to good use if you want to delete
  966. undeletable templates.  Open this file in a text editor (you can
  967. Shift-drag its icon to your editor's icon, then Shift-drop it).
  968. Add this single line (without quotes), then save the file:
  969.  
  970.   "NODELETE=NO"
  971.  
  972. Whenever you need to delete an undeleteable template, just drop it
  973. on this template.  The dropped object will now have a Delete entry
  974. on its popup menu and can be deleted in any of the usual ways.
  975.  
  976.  
  977. =head2 can't choose properties of Desktop
  978.  
  979.   When I press RMB on the desktop I can't choose properties. Does anyone
  980.   know the reason? I used to be able to choose it. I have installed FP1
  981.   and FP3 on my Warp 4.
  982.  
  983. B<When you say you "can't choose properties", do you mean:>
  984.  
  985.  - that entry is missing from the menu?
  986.  - the entry is present but disabled (grayed-out)?
  987.  - you can select Properties but nothing happens?
  988.  
  989. I<I'm sorry...
  990. The properties entry is missing from the menu.>
  991.  
  992. OK...  Have you recently installed any WPS "enhancements", or more likely,
  993. any WPS security add-ons that are designed to keep users from changing
  994. things?  If not, try the following REXX script.  Either drop your F<Desktop>
  995. folder icon on it, or run it from the command line supplying the path of
  996. your Desktop folder as an argument (i.e.  C<settings c:\desktop>  ).
  997.  
  998. Put this in L<Boilerspace template>:
  999.  
  1000.   call ReportRC(SysSetObjectData(object,"NOSETTINGS=NO"))
  1001.  
  1002. =head2 Restoring F<System Setup> or F<Templates>
  1003.  
  1004. I<The desktop pop-up menu which displays the System Setup line to show the
  1005. particular folder is still there, but doesn't bring up the folder. System
  1006. setup itself is in the OS/2 system folder and is still there.>
  1007.  
  1008. I<Can anyone tell me how to "re-activate" the System Setup line in the pop
  1009. up menu?>
  1010.  
  1011. I hope I'm not too late and you haven't done a reinstall...  Try this
  1012. (Put this in L<Boilerspace template>):
  1013.  
  1014.   call ReportRC(SysSetObjectData("F:\Desktop\OS!2 System\System Setup","OBJECTID=<WP_CONFIG>"))
  1015.  
  1016. Similarly for F<templates>:
  1017.  
  1018.   call ReportRC(SysSetObjectData("F:\Desktop\OS!2 System\Templates","OBJECTID=<WP_TEMPS>"))
  1019.  
  1020.  
  1021. =head2 F<ini.rc> and C<SysCreateObject>
  1022.  
  1023. Whenever you damge or destroy a system-supplied object, go to F<\os2\ini.rc>,
  1024. find the entry for the object, then reformat the parameters for use with the
  1025. REXX SysCreateObject command.  In this case, the line from F<ini.rc> is:
  1026.  
  1027.   "PM_InstallObject" "Drives;WPDrives;<WP_CONNECTIONSFOLDER>;RELOCATE"
  1028.   "ALWAYSSORT=YES;NODELETE=YES;DEFAULTVIEW=ICON;OBJECTID=<WP_DRIVES>"
  1029.  
  1030. Below is a REXX script that uses these parms.  Note that neither "PM_InstallObject"
  1031. nor "RELOCATE" are applicable in a REXX script.  OTOH, the "REPLACE" parameter
  1032. included below is REXX-specific;  it is documented in your online REXX ref.
  1033. (N.B.  this is for Warp v4;  for v3, change <WP_CONNECTIONSFOLDER> to
  1034. <WP_OS2SYS>)
  1035.  
  1036. Put this in L<Boilerspace template>, SysCreateObject() call should be
  1037. all on the same line:
  1038.  
  1039.   /* REXX script to recreate the Drives folder*/
  1040.   call ReportRC(SysCreateObject("WPDrives", "Drives", "<WP_CONNECTIONSFOLDER>",
  1041.     "ALWAYSSORT=YES;NODELETE=YES;DEFAULTVIEW=ICON;OBJECTID=<WP_DRIVES>",
  1042.     "REPLACE"))
  1043.  
  1044.  
  1045. =head2 Script to recreate all or some lost objects
  1046.  
  1047.   /* ReCreate.CMD - restore lost desktop objects              */
  1048.   /* by Greg Czaja - July 29, 1992                            */
  1049.   /*               - April 9, 1993  ver.2                     */
  1050.   /*                 handle 2.1-style INI.RC                  */
  1051.   /* the July 1992 REXXUTIL version is required for 2.0 GA    */
  1052.   /* (look for REXX20 in Lib 17 in OS2SUPPORT)                */
  1053.   /* no additional requirements for GA+SP or 2.1              */
  1054.   Call RxFuncAdd 'SysLoadFuncs', 'RexxUtil', 'SysLoadFuncs'
  1055.   Call SysLoadFuncs;
  1056.   SysBootDrive=Filespec('Drive',Value('SYSTEM_INI',,'OS2ENVIRONMENT'));
  1057.   file_name=SysBootDrive||'\OS2\INI.RC';
  1058.   Say "The program will list all single standard objects from your desktop"
  1059.   Say "Reply Y(es) if you want recreate the listed object - E(nd) to end the program"
  1060.   Say "N(o) is the default if you press ENTER:"
  1061.   Do While Lines(file_name) > 0;
  1062.   line=Linein(file_name);
  1063.   If line='' Then Iterate;        /* skip blanks   */
  1064.   Parse Var line '"PM_InstallObject"' line;
  1065.   If line='' Then Iterate;        /* skip others   */
  1066.   Parse Var line '"'head'" 'line; /* get header    */
  1067.   Parse Var line '"'setup'"' .;   /* get setup string */
  1068.   Parse Var head title';'object';'location';' . ;
  1069.   Say title "- Yes/No/End ?";
  1070.   Pull reply ;
  1071.   If Left(reply,1) ='E' Then Leave;
  1072.   If Left(reply,1) <> 'Y' Then Iterate;
  1073.   If SysCreateObject(object,title,location,setup,'Update') = 0
  1074.      Then Say 'Error creating:' title;
  1075.      Else Say title 'created !';
  1076.   End;
  1077.   rc=Stream(file_name,'C','Close');
  1078.   Return 0        /* enjoy your desktop! */
  1079.   /*
  1080.   Did you delete your Command Prompts ? Shredded your Shredder ?
  1081.   This program restores the standard WPS desktop objects on 2.x.
  1082.   It will preserve any current settings/objects you may have created and this
  1083.   is its advantage over the Alt-F1 or MAKEINI method.
  1084.   You will need the latest REXX fixes (REXX20 available in library 17) to make
  1085.   it run correctly on 2.0 GA system, no fixes required on GA+SP or 2.1.
  1086.   */
  1087.  
  1088. =head1 URL objects
  1089.  
  1090. =head2 "Go to URL" action
  1091.  
  1092.  
  1093. I<Can anybody explain me how to permanently set the "Go to URL" action
  1094. on the "open" menu of the URL object?>
  1095.  
  1096. You can't under Warp v3.0.  The WebEx class explicitly resets the default
  1097. view each time a WebEx object is "awakened" (made visible when the folder
  1098. it's in is opened).  I know this for a fact because the code outputs this
  1099. debugging message:
  1100.  
  1101.     **WebExplorer:wpObjectReady(): wpSetDefaultView succeeded
  1102.  
  1103. Your only option under v3.0 is to use an EA editor to delete the .CLASSINFO
  1104. extended attribute.  Then the file will no longer be a WebExplorer_Url object
  1105. and can be associated with WebEx (or rather, WebEx can be associated with
  1106. files of type WebExplorer_Url).  The file can still be dropped on WebEx to
  1107. load the Url - WebEx looks at the type, not the object class, to determine
  1108. whether you're dropping a Url or a file.  (Confused?  See L<URL objects>.)
  1109.  
  1110. Under Warp v4.0 (Merlin), you won't have this problem because the new wpUrl
  1111. class doesn't mess with your choice of default open actions.  However, AFAIK,
  1112. you will have to manually change each old WebEx object to open the browser
  1113. you choose.
  1114.  
  1115.  
  1116. =head2 URL attribute: a guess
  1117.  
  1118. I think that this has to do with how the URL attribute is stored.
  1119. Rather and an EA, I think that it is an ini file thing <sigh>.  I
  1120. found that object desktop's package system will work to transport
  1121. URLs, or you can use a REXX program to rewrite 'em as webx URLs.
  1122.  
  1123. [Does L<URL objects> refute this?]
  1124.  
  1125. =head2 URL objects
  1126.  
  1127. The WPS uses its .TYPE EA of "UniformResourceLocator" to assign it to
  1128. the WPUrl class while NS/2 uses the EA to identify its special
  1129. function.  Without this EA, URL objects will revert to plain-text
  1130. files when copied back into your system.  You will have to reassign
  1131. them a type to restore their functionality.
  1132.  
  1133. Some file objects belong to a particular class solely because their
  1134. CLASSINFO EA says so.  Warp 3's WebExplorer_Url class is an example.
  1135. Even though these files have a .TYPE EA of "WebExplorer_Url" for NS/2's
  1136. benefit, this class wasn't written to associate the type with the class.
  1137. These files had to be explicitly created as "objects" (which always
  1138. results in a .CLASSINFO EA) in order to belong to the WebExplorer_Url
  1139. class.  Stripped of their .CLASSINFO EAs, WebExUrls will also revert
  1140. to plain-text files and you won't be able to restore them.
  1141.  
  1142. There's a frequent fundamental misunderstanding of what WebEx Url
  1143. objects really are.  They are nothing but files whose .TYPE EA is
  1144. "WebExplorer_Url ".  While WebEx and other apps may use PM's WPS
  1145. interface calls to create them, WebEx itself is wholely ignorant of
  1146. their object wrapper when it comes time to read them.  As long as the
  1147. app that originates a drag action identifies the file being dragged as
  1148. a WebExplorer_Url, WebEx will be happy to accept and read it.  The WPS
  1149. need not even be loaded.
  1150.  
  1151. In Merlin, these files have become "WPUrl" objects and may or may not have
  1152. the WebExplorer_Url .TYPE EA.  However, the WPS still identifies them as
  1153. such during a drag to keep WebEx happy.  (Unlike the WebExUrl class, Merlin's
  1154. WPUrl class is automatically associated with any file having this .TYPE EA.)
  1155.  
  1156. Here's an experiment or two to demonstrate the above:
  1157. - use EPM (or any editor that doesn't add a Ctrl-Z to the end of a file) to
  1158. create a file with a valid URL.  After saving it, open the file's settings
  1159. notebook, delete any Current Types, and add WebExplorer_Url from the list
  1160. of Available Types.  Now drag and drop the file on WebEx.  The URL will
  1161. be loaded, even though it isn't a "WebExplorer_Url" object.
  1162. - start Merlin, then look at the file's Object Class in a Details view of its
  1163. folder.  You'll see that it's WPUrl.  Open its properties notebook:  it should
  1164. be that of a Url object.  If it isn't, you'll have to use the "Become" tab to
  1165. make it one;  after a restart, it will belong to the WPUrl class.
  1166.  
  1167. BTW...  *no* WPS objects are "EAs hanging off the directory".  If an object
  1168. is filesystem-based, it has its own .CLASSINFO EA that is used by the WPS.
  1169. If the object is abstract (like a Program reference object), the classinfo is
  1170. stored in F<OS2.INI>.
  1171.  
  1172.  
  1173. =head1 C<WPObjData> and "Hammer and ..." icons
  1174.  
  1175. I<Just curious. Back when I applied FP1 to Warp 4, my e.exe lost its
  1176. pretty icon due to the ea glitch. I got the icon back from one of my
  1177. previous files & everything was fine. Now we have FP3. Things have
  1178. seemed to be golden since the service. Now I notice many of my *.txt
  1179. files that would normally be associated with e.exe (and still open
  1180. with it) have a new icon consisting of a rather drab looking
  1181. screw-driver and hammer. Is my system secretly trying to make me feel
  1182. more like a man or is this something to worry about? TIA.>
  1183.  
  1184. These files have been sucked up by the WPObjData class which is an adjunct
  1185. to the Feature Installer (WPInstall).  Apparently, the people who are writing
  1186. these WPS classes don't know how the WPS works.  The files WPObjData
  1187. creates are supposed to be of type "Plain Text".  However, the way they
  1188. wrote it, *any* Plain Text file becomes an instance of WPObjData if it isn't
  1189. already classified as a WPDataFile.  Your best bet is to deregister WPObjData
  1190. using this REXX script, then restart the WPS.
  1191.  
  1192. Put this in L<Boilerspace template>:
  1193.  
  1194.   call ReportRC(SysDeregisterObjectClass("WPObjData"))
  1195.  
  1196. =head2 Finally fixed!
  1197.  
  1198.  
  1199. You'll be pleased to know that IBM *has* finally addressed the problem:
  1200. the version of WPObjData that comes with WSeB no longer exhibits this
  1201. obnoxious behavior.  Let's see...  I first posted the script Tim cites on
  1202. Sept 20, 1997 and the fixed version of objdata.dll is dated April 5, 1999.
  1203. So, it only took 19+ months to correct - pretty good for "them" <g>.
  1204.  
  1205. FYI...  You may want to read my article in os2ezine, _Using That Hammer
  1206. and Screwdriver_ (L<http://www.os2ezine.com/v3n07/hammer.htm>), for a way
  1207. to both tame WPObjData I<and> to put it to work doing something useful.
  1208.  
  1209.  
  1210. =head2 WPInstall not registered
  1211.  
  1212.  
  1213. My guess is that the WPInstall class isn't registered.  You should be able to
  1214. restore it by installing the latest Feature Installer, or by using the following
  1215. script (I assume you have an INSTALL.DLL in C:\OS2\DLL).  Put this in
  1216. L<Boilerspace template>:
  1217.  
  1218.   /* REXX script to reregister the WPInstall class*/
  1219.   rc = SysDeregisterObjectClass("WPInstall")
  1220.  
  1221.   call ReportRC(SysRegisterObjectClass("WPInstall","C:\OS2\DLL\INSTALL.DLL"))
  1222.  
  1223. =head2 F<Data File:1> and C<NODELETE>
  1224.  
  1225.  
  1226. I<gobbled up a template and then everything froze. CAD brought me back
  1227. and the template had been deleted and the entry had been removed from
  1228. the ini (not by me).>
  1229.  
  1230. This needn't be so difficult.  You either have, or can have, an object that
  1231. will make other objects deleteable.  If you're running Warp 3 or 4.0 and
  1232. have installed Feature Installer, you probably have a template labeled
  1233. "Data File:1" whose icon shows a hammer & screwdriver.  If running MCP or
  1234. eCS, you have the required dll but the WPS class it contains (WPObjData)
  1235. is not yet registered.  Once this is set up, you'll be able to drop most
  1236. any object on your ObjData icon to restore the Delete option to its menu.
  1237. And, your system will not freeze up (well, it certainly shouldn't...).
  1238.  
  1239. If you don't have the "hammer & screwdriver" template, register the class
  1240. using the script below.  Doing so will create a new template.  While you
  1241. could create a normal object from the template, you'll probably have little
  1242. other use for it, so edit the template itself.  Drag the template to your
  1243. editor's icon, press Shift to make it droppable, then drop.  The object is
  1244. actually an empty datafile to which you will add this one line:
  1245.  
  1246.     NODELETE=NO
  1247.  
  1248. Save the file, then try out its template object.  Drop something that's
  1249. undeleteable on it, then pop up the dropped object's menu.  There should
  1250. now be a usable "Delete" entry on it.  I've found that some classes will
  1251. restore their NODELETE flag if you manipulate them or drag them to the
  1252. shredder, so delete the object ASAP after using your ObjData icon.
  1253.  
  1254. FYI... you could use a REXX script to do this for files and directories,
  1255. but REXX can't operate on abstract objects like Program Objects unless
  1256. they have an object ID.  A WPObjData object will work with any type of
  1257. object (if a file has its "read-only" or "system" attributes set, you
  1258. may have to turn these off first).
  1259.  
  1260. Put this in L<Boilerspace template>:
  1261.  
  1262.   /* OBJDATA.DLL _should_ be in your os2\dll directory and           */
  1263.   /* accessible via your LIBPATH statement.  If it isn't,            */
  1264.   /* it may be in your FISETUP directory;  in this case you          */
  1265.   /* must supply the dll's full path & filename, e.g.                */
  1266.   /* SysRegisterObjectClass('WPObjData','E:\FI\FISETUP\objdata.dll') */
  1267.   /* Be sure to use a file dated June 7, 1999 or later - earlier     */
  1268.   /* versions had a major bug and were a real PITA                   */
  1269.  
  1270.   call ReportRC(SysRegisterObjectClass('WPObjData','OBJDATA'))
  1271.  
  1272. =head1 C<WPVault>, F<x:/NOWHERE>, C<NOTVISIBLE>, C<SHOWALLINTREEVIEW>
  1273.  
  1274. B<Don't worry, you couldn't dereg/delete this class if you wanted to.
  1275. Normally, WPVault is only assigned to the F<Nowhere> folder; it is
  1276. intended to make it hard for you to mess this folder or its contents.
  1277. The WPS sets the physical directory's attributes to system and hidden,
  1278. and the WPS object's attributes to NoMove NoDelete NoPrint NoDrag
  1279. NotVisible NoRename.>
  1280.  
  1281. I<You can also try aplying the following setting against F<x:\NOWHERE>:>
  1282.  
  1283.  NOTVISIBLE=NO;SHOWALLINTREEVIEW=YES
  1284.  
  1285. I<(see the recipe in L<can't choose properties of Desktop>).  Suddenly
  1286. all objects in F<Nowhere> appear in the treeview and can be seen...>
  1287.  
  1288. That's an interesting way around the visibility problem.  However, I think
  1289. there's actually more there than meets the eye.
  1290.  
  1291. Under Warp 3, at least, <WP_NOWHERE> contained a lot of transient objects
  1292. of classes WPFilter, WPFinder, WPFolderCV, etc.  On my Warp 4 system,
  1293. I know these objects exist but I can't locate them.  Since each of these
  1294. classes has a style of "Private" (which means "hidden"), I'd assume they're
  1295. still in F<Nowhere> but totally inaccessible using conventional means.
  1296.  
  1297. In addition, some of the conventional objects in F<Nowhere> have an object style
  1298. of "NotVisible".  Most notable is <WP_VIEWINF> which is the default
  1299. viewer for *.INF files.  Most of the objects that are visible on my system
  1300. (other than the COM and LPT objects) appear to have been put there either
  1301. by WarpCenter or Object Desktop.
  1302.  
  1303.  
  1304.  
  1305. =head2 F<x:/NOWHERE> and C<NOTVISIBLE>
  1306.  
  1307. F<Nowhere> contains objects "they" don't want you to mess with, e.g. the
  1308. program object for F<view.exe> that's associated with F<*.INF>.  It also
  1309. contains WarpCenter & LaunchPad shadows, some Netscape helper apps,
  1310. plus objects for your COM, LPT, and remote printer ports.  It may
  1311. also contain junk - some people may still have remnants left by the
  1312. NSv4.61 beta.
  1313.  
  1314. In Warp v4 (at least), you can't open F<Nowhere>, display its menu, or
  1315. show its properties notebook.  However, you *can* see its contents
  1316. by running the script below, then opening your boot drive in tree
  1317. view and pressing the "plus" button next to F<Nowhere>'s icon.
  1318. (Note:  I've played with my system so much that YMMV greatly as
  1319. to what you can see.  For example, mine always shows some objects;
  1320. running the script below simply increases the number visible.)
  1321.  
  1322. If you have more than one F<Nowhere> directory, you should be able to
  1323. identify the one in use by the presence of the port objects (assuming
  1324. you can see them at all).  Another way is to use the folder's Object ID
  1325. (<WP_NOWHERE>) rather than its path the first time you run the script.
  1326. Whichever folder is expandable is the one in use.
  1327.  
  1328. Put this in L<Boilerspace template>:
  1329.  
  1330.   /* this makes visible two objects that are normally hidden */
  1331.   rc = SysSetObjectData( "<WP_VIEWINF>","NOTVISIBLE=NO")
  1332.   rc = SysSetObjectData( "<WP_RJAPPLETPROGREF>","NOTVISIBLE=NO")
  1333.  
  1334.   /* substitute <WP_NOWHERE> for the path on the first run to
  1335.      help identify which of several Nowhere folders the WPS is
  1336.      actually using */
  1337.   call ReportRC(SysSetObjectData( "C:\NOWHERE","SHOWALLINTREEVIEW=YES"))
  1338.  
  1339. =head2 C<SHOWALLINTREEVIEW>
  1340.  
  1341. I<SHOWALLINTREEVIEW=YES ?  What does this do, and where is this statement
  1342. placed ?
  1343. If this does what I think it does, I'll be wondering why the hell IBM didn't
  1344. make this default.>
  1345.  
  1346. This causes folders to display all their contents in Tree view, rather
  1347. than just subfolders.  You can apply this attribute to any folder using
  1348. this REXX script.  Supply the name of a directory when you run it
  1349. (e.g. C<SHOWALL C:\DESKTOP>), or simply drop a folder on its icon.
  1350.  
  1351. Put this in L<Boilerspace template>:
  1352.  
  1353.   call ReportRC(SysSetObjectData(object,"SHOWALLINTREEVIEW=YES"))
  1354.  
  1355. =head2 C<SHOWALLINTREEVIEW> and old (Warp 3) folders
  1356.  
  1357. The ability to show a folder's entire contents was added in Warp v4, but
  1358. nothing was added to the folder notebook to turn this on.  Instead, you have
  1359. to use REXX;  the script in L<C<SHOWALLINTREEVIEW>> will do the trick.
  1360.  
  1361. =head2 C<NODELETE> and F<Templates>
  1362.  
  1363.   | >I have several objects that were created by Devcon. They are extremely
  1364.   | >annoying and I would like to be rid of them. Simple deletion doesn't work,
  1365.  so
  1366.   | Go to the 'general' page of the settings notebook.  Uncheck the
  1367.   | template checkbox, close the notebook and delete 'em.
  1368.  
  1369. B<That's not enough for the Warp Toolkit objects:  they are created with the
  1370. object NODELETE attribute, which you can't get at from the WPS (unless you
  1371. use an object inspection utility).>
  1372.  
  1373. B<You *can* zap them with REXX, though:>
  1374.  
  1375.   call RxFuncAdd 'SysLoadFuncs', 'REXXUTIL', 'SYSLOADFUNCS'
  1376.   call SysLoadFuncs
  1377.   call SysSetObjectData 'C:\Desktop\OS!2 System\Templates\Carpp', 'NODELETE=NO;'
  1378.  
  1379. B<Remove the Template attribute as above, then you can delete them.>
  1380.  
  1381. I<Ok, that partially worked...it makes the objects "deletable", but they come
  1382. back after I delete them (i.e. Run script, Delete object, Close folder, Open folder,
  1383. B<IT'S BAAAACK>).  Any other ideas? Mayhaps a recommendation as to an
  1384. "object inspection utility"? Preferrably one that will let me kill the objects?>
  1385.  
  1386. Every time you open the F<Templates> folder, it populates itself with a template
  1387. for every class that supports "Create Another".  If the template for a class is
  1388. missing, it asks the class to create another.  The only way to permanently get
  1389. rid of them is to deregister the class.  If that's what you want to do, add
  1390. this line to the script above:
  1391.  
  1392.     Call SysDeregisterObjectClass "[name of class]"
  1393.  
  1394. Run the script, delete the object, close the folder, restart the WPS.
  1395. The template, the class, and any supporting F<os2.ini> entries will be gone for
  1396. good.
  1397.  
  1398.  
  1399. =head1 F<.HLP> not shown in F<view.exe>
  1400.  
  1401. B<IZ: applicable only to Warp 4 (F<view.exe> would not open hlp, use
  1402. F<viewhelp.exe>).>
  1403.  
  1404. OTOH, if you can't dblclick on a HLP to open it in the right app, it's
  1405. because HLP files don't have any pre-assigned association.  During
  1406. installation, OS/2 creates a hidden program object in your F<Nowhere> folder
  1407. (also hidden) and associates it with *.INF.  To access this object's
  1408. notebook so you can add *.HLP to its associations, run this REXX script
  1409. (Put this in L<Boilerspace template>):
  1410.  
  1411.   call ReportRC(SysSetObjectData("<WP_VIEWINF>","OPEN=SETTINGS"))
  1412.  
  1413. [Probably you need to make F<Nowhere> visible first, see
  1414. L<F<x:/NOWHERE> and C<NOTVISIBLE>>.]
  1415.  
  1416. =head1 Drag & Drop of F<.dev> and printers
  1417.  
  1418. I<If you drag and drop a printer file it will assume you want to install
  1419. it. I don't know the answer to your question though, but am also
  1420. curios to know. I would just drop to the command line & copy it from
  1421. there.>
  1422.  
  1423. When I responded to Timur's original posting, I suggested he go to the
  1424. "Become" page of the file's notebook and change its class to WPDataFile.
  1425. Contrary to my normal practice, I didn't fully test the results and was
  1426. later reminded why I (almost) always test before posting:  when I went
  1427. to drag my test file the next day, it wouldn't budge.  Even though the
  1428. object's class had changed, its "style" settings hadn't.  The following
  1429. REXX script fixes that.  Just replace "C:\junk\test.drv" with the name
  1430. of your problem file, then run it.
  1431.  
  1432. Put this in L<Boilerspace template>, see L<Open View IDs> for DEFAULTVIEW=4:
  1433.  
  1434.   call ReportRC(SysSetObjectData("C:\junk\test.drv", "NoMove=NO;NoLink=NO;NoCopy=NO;NoDrag=NO;DEFAULTVIEW=4;"))
  1435.  
  1436. BTW... do *not* move a real printer-driver file if you've installed
  1437. one of the printers it supports.
  1438.  
  1439.  
  1440. =head1 Start a VIO window with a changed font size
  1441.  
  1442. Here's a REXX script that does what's needed (on my system, at least).
  1443. YMMV because of timing issues (i.e. it's possible that the font could
  1444. get reset before the window uses this setting).
  1445.  
  1446. Notice that I've included two different ways to invoke scache:
  1447. by running it directly and by opening a program object that runs it.
  1448. I feel more comfortable with the latter, but it requires that the
  1449. pgm object have an Object ID (in this case "<SCACHE>").  I added
  1450. mine after the fact using a feature of DTProgram.
  1451.  
  1452.   /* SCACHE.CMD - saves old font size, sets a new size, */
  1453.   /* invokes smartcache, then restores old size         */
  1454.   /* note:  if the font is "14x8", y=14 & x=8           */
  1455.  
  1456.   call RxFuncAdd 'SysLoadFuncs', 'RexxUtil', 'SysLoadFuncs'
  1457.   call SysLoadFuncs
  1458.  
  1459.   x = 8
  1460.   y = 8
  1461.  
  1462.   sav = SysIni('USER','Shield','~Font Size...')
  1463.   new = d2c(x) || d2c(y)
  1464.   rc = SysIni('USER','Shield','~Font Size...', new)
  1465.  
  1466.   /* OPEN PROGRAM OBJECT */
  1467.   rc = SysOpenObject('<SCACHE>','4','TRUE')
  1468.  
  1469.   /* RUN DIRECTLY */
  1470.   /* 'CD F:\JAVA11\SCACHE'
  1471.   'START F:\JAVA11\BIN\JAVA.EXE -ms1m scache' */
  1472.  
  1473.   rc = SysIni('USER','Shield','~Font Size...', sav)
  1474.  
  1475. =head1 Desktop background
  1476.  
  1477.  
  1478. I<Is there a way to find where the desktop's background is stored and
  1479. change it?  I've heard it's possible with the WinSetObjectData()
  1480. function but I don't know how to do this?>
  1481.  
  1482. Yes, you do use WinSetObjectData(). You can find the relevant setup string in
  1483. the WPS Programming Reference.
  1484. e.g.
  1485.  
  1486.   WinSetObjectData(WinQueryObject("<WP_DESKTOP>"),
  1487.     "BACKGROUND=c:\somewhere\something.bmp,T,1,I;");
  1488.  
  1489.  
  1490. =head1 Properties of the root directory
  1491.  
  1492.  
  1493. The easiest way to clear up problems in a root directory is to erase
  1494. "WP ROOT. SF".  You'll have to turn off the hidden and system attributes
  1495. and you may have to Alt-F1/boot to a command line to actually delete it
  1496. (I don't recall).  After doing so, you'll have to open this drive's
  1497. notebook and reset whatever properties you normally change (e.g. sort
  1498. order, includes, etc).  Doing so will recreate this file.
  1499.  
  1500. FYI...  Root directories have no EAs, so "WP ROOT.SF" provides an
  1501. alternate means of storing WPS info.  The file itself contains
  1502. the root's .CLASSINFO.  Any other EAs that would be attached to
  1503. a directory (e.g. .ICONPOS) are attached to this file instead.
  1504.  
  1505. =head1 PM_Workplace:Location
  1506.  
  1507. See L<DragText>.
  1508.  
  1509. =head1 PM_Workplace:Templates
  1510.  
  1511. See L<Hanging template folder>.
  1512.  
  1513. =head1 AUTHOR
  1514.  
  1515. Compilation, editing, and tools info by Ilya Zakharevich.  The rest
  1516. obtained from Google using the search string
  1517.  
  1518.   classinfo extended attributes
  1519.  
  1520. and from Google groups with
  1521.  
  1522.   classinfo extended attributes group:*.os2.*
  1523.   classinfo wps group:*.os2.*
  1524.   sysloadfuncs group:*.os2.* author:walsh
  1525.   classinfo group:*.os2.* author:walsh
  1526.  
  1527. Most prolific info-producer is Rich Walsh (with a giant margin).
  1528.  
  1529.    http://www.usacomputers.net/personal/rlwalsh/
  1530.  
  1531. Particular chunks are not attributed to their authors, please look on
  1532. Google again.
  1533.  
  1534. =cut
  1535.  
  1536.