How to change class of a file object ("Become" page functionality)? - OS2

This is a discussion on How to change class of a file object ("Become" page functionality)? - OS2 ; On Sun, 29 Jun 2008 10:50:53 UTC, "Lars Erdmann" wrote: > I tried to figure out camQueryBecomeableClasses parameters. OK, I finally got it: rc = camQueryBecomeableClasses( ClassAssociationManager * pCAM, SOMObject * theObj, SOMClass ** aClasses, ULONG cntClassPtrs); cntClassPtrs specifies the ...

+ Reply to Thread
Page 2 of 2 FirstFirst 1 2
Results 21 to 35 of 35

Thread: How to change class of a file object ("Become" page functionality)?

  1. Re: How to change class of a file object ("Become" page functionality) ?

    On Sun, 29 Jun 2008 10:50:53 UTC, "Lars Erdmann" wrote:

    > I tried to figure out camQueryBecomeableClasses parameters.


    OK, I finally got it:

    rc = camQueryBecomeableClasses( ClassAssociationManager * pCAM,
    SOMObject * theObj,
    SOMClass ** aClasses,
    ULONG cntClassPtrs);

    cntClassPtrs specifies the size of the 'aClasses' array. When it's
    zero, rc identifies the total number of class pointers that could
    be returned. When it's non-zero, rc is always zero (at least if
    the call is successful).

    Your call succeeded in returning the class count even though you
    didn't specify cntClassPtrs because of a peculiarity/optimization
    in RWS that causes it to push zeros onto the stack in some cases.

    Here's an example using the venerable "macaw.avi":

    -Type- -Size- -Value-
    -> Proc: RWSP_MNAMI camQueryBecomeableClasses
    Arg1: RWSI_ASIS 0 135dad4 [ptr to my CAM object]
    Arg2: RWSI_OPATH 0 F:\MMOS2\MOVIES\MACAW.AVI
    Arg3: RWSI_PBUF 32 [supply an empty 32-byte buffer]
    Arg4: RWSI_ASIS 0 8 [return a max of 8 class ptrs]
    Return: RWSR_ASIS 0

    Result:
    pHdr= 18530040
    arg0 - value= 0
    arg1 - value= 135dad4
    arg2 - value= 4790fe8
    arg3 - size= 32 value*= 18530104
    00ae6f78 00cdd1e4 00d05950 00000000
    00000000 00000000 00000000 00000000
    arg4 - value= 8


    > Is there any other way to look into the buffer apart form using
    > Theseus ?


    As you can see, if your buffer is <= 128 bytes, RwsTest will display it.
    Otherwise, it's Theseus (note that arg3 shows the address of the buffer).

    BTW... the 3 class pointers are: WPDataFile, MMAVI, and MMVideo. I used
    my "RWX - Class Explorer" to identify them, but you could also use RwsTest
    like this:

    -Type- -Size- -Value-
    -> Proc: RWSP_CONV
    Arg1: RWSC_CLASS_CNAME 0 00ae6f78
    Arg2: RWSC_CLASS_CNAME 0 00cdd1e4
    Arg3: RWSC_CLASS_CNAME 0 00d05950
    Return: RWSR_ASIS 0

    Result:
    pHdr= 18530040
    arg0 - value= 3
    arg1 - string= WPDataFile
    arg2 - string= MMAVI
    arg3 - string= MMVideo




    --
    == == almost usable email address: Rich AT E-vertise.Com == ==
    __________________________________________________ _________________
    |
    | DragText v3.9 with NLS support
    Rich Walsh | A Distinctly Different Desktop Enhancement
    Ft Myers, FL | http://e-vertise.com/dragtext/
    __________________________________________________ _________________


  2. Re: How to change class of a file object ("Become" page functionality) ?

    Thank you very much for the info !

    Lars

    "Rich Walsh" schrieb im Newsbeitrag
    news:brddYgxvE0gm-pn2-MUdShdknEMih@localhost...
    > On Sun, 29 Jun 2008 10:50:53 UTC, "Lars Erdmann"
    > wrote:
    >
    >> I tried to figure out camQueryBecomeableClasses parameters.

    >
    > OK, I finally got it:
    >
    > rc = camQueryBecomeableClasses( ClassAssociationManager * pCAM,
    > SOMObject * theObj,
    > SOMClass ** aClasses,
    > ULONG cntClassPtrs);
    >
    > cntClassPtrs specifies the size of the 'aClasses' array. When it's
    > zero, rc identifies the total number of class pointers that could
    > be returned. When it's non-zero, rc is always zero (at least if
    > the call is successful).
    >
    > Your call succeeded in returning the class count even though you
    > didn't specify cntClassPtrs because of a peculiarity/optimization
    > in RWS that causes it to push zeros onto the stack in some cases.
    >
    > Here's an example using the venerable "macaw.avi":
    >
    > -Type- -Size- -Value-
    > -> Proc: RWSP_MNAMI camQueryBecomeableClasses
    > Arg1: RWSI_ASIS 0 135dad4 [ptr to my CAM object]
    > Arg2: RWSI_OPATH 0 F:\MMOS2\MOVIES\MACAW.AVI
    > Arg3: RWSI_PBUF 32 [supply an empty 32-byte buffer]
    > Arg4: RWSI_ASIS 0 8 [return a max of 8 class ptrs]
    > Return: RWSR_ASIS 0
    >
    > Result:
    > pHdr= 18530040
    > arg0 - value= 0
    > arg1 - value= 135dad4
    > arg2 - value= 4790fe8
    > arg3 - size= 32 value*= 18530104
    > 00ae6f78 00cdd1e4 00d05950 00000000
    > 00000000 00000000 00000000 00000000
    > arg4 - value= 8
    >
    >
    >> Is there any other way to look into the buffer apart form using
    >> Theseus ?

    >
    > As you can see, if your buffer is <= 128 bytes, RwsTest will display it.
    > Otherwise, it's Theseus (note that arg3 shows the address of the buffer).
    >
    > BTW... the 3 class pointers are: WPDataFile, MMAVI, and MMVideo. I used
    > my "RWX - Class Explorer" to identify them, but you could also use RwsTest
    > like this:
    >
    > -Type- -Size- -Value-
    > -> Proc: RWSP_CONV
    > Arg1: RWSC_CLASS_CNAME 0 00ae6f78
    > Arg2: RWSC_CLASS_CNAME 0 00cdd1e4
    > Arg3: RWSC_CLASS_CNAME 0 00d05950
    > Return: RWSR_ASIS 0
    >
    > Result:
    > pHdr= 18530040
    > arg0 - value= 3
    > arg1 - string= WPDataFile
    > arg2 - string= MMAVI
    > arg3 - string= MMVideo
    >
    >
    >
    >
    > --
    > == == almost usable email address: Rich AT E-vertise.Com == ==
    > __________________________________________________ _________________
    > |
    > | DragText v3.9 with NLS support
    > Rich Walsh | A Distinctly Different Desktop Enhancement
    > Ft Myers, FL | http://e-vertise.com/dragtext/
    > __________________________________________________ _________________
    >




  3. Re: How to change class of a file object ("Become" page functionality)?

    Hi Rich,
    >
    > RwsTest will display "Error getting result!" for Arg0 but you can
    > ignore it - apparently it doesn't handle void returns correctly
    > (RWS itself doesn't have this problem).
    >
    >
    > -> Proc: RWSP_MNAM wpUnlockObject
    > Arg1: RWSI_ASIS 0 45064c4 [ptr to my file object]
    > Return: RWSR_ASIS 0
    >
    > I have no idea if this is needed or even works. It often seems
    > as though objects don't go dormant anymore. (Note: RWS does
    > *not* unlock objects on its own because it has no way of knowing
    > whether you'll be using them again.)
    >
    > If you'd like to see this rendered in C, let me know.


    Sorry to bother again. I want the equivalent of :

    PSZ fileType;
    PFILEFINDBUF3 pF;
    ....
    fileType =
    _wpQueryType(_WPFileSystem->wpclsQueryObjectFromPath(pF->achName));

    I thought this would be:

    rc = RwsCall(&rwsHdr,
    RWSP_MNAM,(ULONG)"wpQueryType",
    RWSR_PSTR,0UL,1UL,
    RWSI_OPATH,pF->cchName,pF->achName);

    fileType = (PSZ)RwsGetResult(rwsHdr,0UL,0UL);


    but for "rc" I get error RWSSRV_ARGGIVECONVFAILED. Could you tell me
    what I am doing wrong ? By the way: pF (as much as pF->achName) points
    to BSS memory (in other words: not on the stack).

    Lars


  4. Re: How to change class of a file object ("Become" page functionality) ?

    On Wed, 2 Jul 2008 16:56:44 UTC, Lars Erdmann wrote:

    > I want the equivalent of :
    >
    > PSZ fileType;
    > PFILEFINDBUF3 pF;
    > ...
    > fileType =
    > _wpQueryType(_WPFileSystem->wpclsQueryObjectFromPath(pF->achName));
    >
    > I thought this would be:
    >
    > rc = RwsCall(&rwsHdr,
    > RWSP_MNAM,(ULONG)"wpQueryType",
    > RWSR_PSTR,0UL,1UL,
    > RWSI_OPATH,pF->cchName,pF->achName);
    >
    > fileType = (PSZ)RwsGetResult(rwsHdr,0UL,0UL);
    >
    >
    > but for "rc" I get error RWSSRV_ARGGIVECONVFAILED. Could you tell
    > me what I am doing wrong ?


    The most likely reason is that the filename is unqualified, so it
    can't be found. Add a path and it should work.

    > By the way: pF (as much as pF->achName) points to BSS memory
    > (in other words: not on the stack).


    It doesn't matter where the string is because RwsClient has to copy
    it into shared memory so the WPS process can access it. Also, you
    don't need to specify the string's length since RwsClient will do
    a strlen() and ignore what you specified. This is an unfortunate
    design flaw given what follows...

    Below is some sample code that shows how to greatly increase RWS's
    efficiency & virtually eliminate its overhead when you call it in
    a loop (in this example, to change the class of multiple files).

    The key is to reuse the data structure that RWS creates on the
    first call. When it returns, all of the info that RWS had to
    look up is now stored in the struct. To reuse the method PFN
    and class pointer, you just change those items' 'type' fields to
    have RWS use their existing values. Since the name of the file
    object in the sample changes from call to call, you won't change
    that one's type. Instead, you'll just copy the name into the
    appropriate buffer yourself before each call.

    Here's the "unfortunate" part: the filename buffer really should
    be CCHMAXPATH, but when you specify a string argument, RwsClient
    only allocates enough space for that string. To work around this
    flaw, the code asks for an empty buffer then changes the argument's
    type to what it should be & copies in the first filename.


    ----------------------------------------------------------------------

    ULONG ReClass( char * pszClass, char ** apszFiles, ULONG cntFiles)
    {
    ULONG rc;
    ULONG ctr = 0;
    ULONG camObj = 0;
    PRWSHDR pHdr = 0;
    PRWSDSC pArg;
    char * pBuf;

    do {
    // create a ClassAssociationManager object
    rc = RwsCall( &pHdr,
    RWSP_MNAM, (ULONG)"somNew", // call type
    RWSR_ASIS, 0, // return type
    1, // nbr of args
    RWSI_CNAME, 0, "ClassAssociationManager"); // class name
    if (rc)
    break;

    // get a pointer to the struct containing the return;
    // save its value, then free the RWS request structure
    pArg = CALCRTNPTR( pHdr);
    camObj = pArg->value;
    RwsFreeMem( pHdr);
    pHdr = 0;

    // build a new request structure but don't dispatch it
    rc = RwsBuild( &pHdr,
    RWSP_MNAM, (ULONG)"camBecomeInstanceOf", // call type
    RWSR_ASIS, 0, // return type
    3, // nbr of args
    RWSI_ASIS, 0, camObj, // C-A-Mgr object
    RWSI_PBUF, 260, 0, // filename buffer
    RWSI_CNAME, 0, (ULONG)"IWFProject"); // new class name
    if (rc)
    break;

    // get a pointer to Arg2 (the filename buffer)
    rc = RwsGetArgPtr( pHdr, 2, &pArg);
    if (rc)
    break;

    // change its type to "convert file path to object"; get a ptr to
    // the buffer where it stores the path, then copy in the first file
    pArg->type = RWSI_OPATH;
    pBuf = CALCGIVEPTR( pArg);
    strcpy( pBuf, apszFiles[ctr++]);

    // dispatch the request to RwsServer; if there's only 1 file, exit
    rc = RwsDispatch( pHdr);
    if (rc || ctr >= cntFiles)
    break;

    // the struct containing the method name now has a ptr to the
    // function that implements it, so change the type to "method PFN"
    pArg = CALCPROCPTR( pHdr);
    pArg->type = RWSP_MPFN;

    // the struct containing the class name now has a ptr to the
    // class object, so change the type to "use value as-is"
    rc = RwsGetArgPtr( pHdr, 3, &pArg);
    if (rc)
    break;
    pArg->type = RWSI_ASIS;

    // for the remaining files, copy the name into place,
    // then dispatch the request to RwsServer
    while (ctr < cntFiles) {
    strcpy( pBuf, apszFiles[ctr++]);
    rc = RwsDispatch( pHdr);
    if (rc)
    break;
    }

    } while (0);

    // if we created a C-A-Mgr object, delete it
    if (camObj) {
    if (pHdr)
    RwsFreeMem( pHdr);
    pHdr = 0;

    RwsCall( &pHdr,
    RWSP_MNAMI, (ULONG)"somFree", // call type
    RWSR_VOID, 0, // return type
    1, // nbr of args
    RWSI_ASIS, 0, camObj); // C-A-Mgr object
    }

    // free the RWS request structure
    if (pHdr)
    RwsFreeMem( pHdr);

    return (rc);
    }

    ----------------------------------------------------------------------

    --
    == == almost usable email address: Rich AT E-vertise.Com == ==
    __________________________________________________ _________________
    |
    | DragText v3.9 with NLS support
    Rich Walsh | A Distinctly Different Desktop Enhancement
    Ft Myers, FL | http://e-vertise.com/dragtext/
    __________________________________________________ _________________


  5. Re: How to change class of a file object ("Become" page functionality)?

    Hi,


    Rich Walsh schrieb:
    > On Wed, 2 Jul 2008 16:56:44 UTC, Lars Erdmann wrote:
    >
    >> I want the equivalent of :
    >>
    >> PSZ fileType;
    >> PFILEFINDBUF3 pF;
    >> ...
    >> fileType =
    >> _wpQueryType(_WPFileSystem->wpclsQueryObjectFromPath(pF->achName));
    >>
    >> I thought this would be:
    >>
    >> rc = RwsCall(&rwsHdr,
    >> RWSP_MNAM,(ULONG)"wpQueryType",
    >> RWSR_PSTR,0UL,1UL,
    >> RWSI_OPATH,pF->cchName,pF->achName);
    >>
    >> fileType = (PSZ)RwsGetResult(rwsHdr,0UL,0UL);
    >>
    >>
    >> but for "rc" I get error RWSSRV_ARGGIVECONVFAILED. Could you tell
    >> me what I am doing wrong ?

    >
    > The most likely reason is that the filename is unqualified, so it
    > can't be found. Add a path and it should work.


    Ah right. Yes that was the problem.

    >
    >> By the way: pF (as much as pF->achName) points to BSS memory
    >> (in other words: not on the stack).

    >
    > It doesn't matter where the string is because RwsClient has to copy
    > it into shared memory so the WPS process can access it. Also, you
    > don't need to specify the string's length since RwsClient will do
    > a strlen() and ignore what you specified. This is an unfortunate
    > design flaw given what follows...
    >
    > Below is some sample code that shows how to greatly increase RWS's
    > efficiency & virtually eliminate its overhead when you call it in
    > a loop (in this example, to change the class of multiple files).
    >
    > The key is to reuse the data structure that RWS creates on the
    > first call. When it returns, all of the info that RWS had to
    > look up is now stored in the struct. To reuse the method PFN
    > and class pointer, you just change those items' 'type' fields to
    > have RWS use their existing values. Since the name of the file
    > object in the sample changes from call to call, you won't change
    > that one's type. Instead, you'll just copy the name into the
    > appropriate buffer yourself before each call.
    >
    > Here's the "unfortunate" part: the filename buffer really should
    > be CCHMAXPATH, but when you specify a string argument, RwsClient
    > only allocates enough space for that string. To work around this
    > flaw, the code asks for an empty buffer then changes the argument's
    > type to what it should be & copies in the first filename.

    Do you plan to remove that design flaw :-) ?

    anyway: Yes that seems to be simple for ONE wps method call. But how about:

    pCAM = SOMClassMgrObject->somClassFromId(id1 =
    somIdFromString("ClassAssociationManager"))->somNew();
    pClass = SOMClassMgrObject->somClassFromId(id2 =
    somIdFromString("IWFProject"));

    for (i in allFiles)
    {
    pFileObj = _WPFileSystem->wpclsQueryObjectFromPath(fileSpec[i]);
    ulAttrs = pFileObj->wpQueryAttr();
    pFileObj->wpSetAttr(ulAttrs &
    ~(FILE_READONLY|FILE_HIDDEN|FILE_SYSTEM));
    pFileObj->wpSetup("DEFAULTVIEW=DEFAULT");
    pCAM->camBecomeInstanceOf(pFileObj,pClass);
    pFileObj->wpUnlockObject();
    }
    pCAM->somFree();
    SOMFree(id2);
    SOMFree(id1);

    As I understand, I will need to call RwsBuild for each method in the
    "for" loop (and keeping track of that many RWS headers):
    "wpQueryAttr","wpSetAttr","wpSetup","camBecomeInstanceOf","wpUnlockObject"
    correct ?
    (I understand that "somIdFromString","somClassFromId",
    "wpclsQueryObjectFromPath" are called by RWS implicitely. How about
    SOMFree to free the somId ?).

    or does RWS provide a way to set up a whole sequence of methods with a
    single "Build" call (and receive all the converted values when invoking
    the RwsDispatch call) ?


    Lars



  6. Re: How to change class of a file object ("Become" page functionality) ?

    On Mon, 7 Jul 2008 19:10:21 UTC, Lars Erdmann wrote:
    > Rich Walsh schrieb:


    > > when you specify a string argument, RwsClient
    > > only allocates enough space for that string.

    >
    > Do you plan to remove that design flaw :-) ?


    If there's ever an RWS v0.90 then yes, certainly.

    > or does RWS provide a way to set up a whole sequence of methods with a
    > single "Build" call (and receive all the converted values when invoking
    > the RwsDispatch call) ?


    The ability to chain methods like that would be my primary reason for
    developing RWS further.

    > that [the sample code] seems to be simple for ONE wps method call.
    > But how about:
    >
    > pCAM = SOMClassMgrObject->somClassFromId(id1 =
    > somIdFromString("ClassAssociationManager"))->somNew();
    > pClass = SOMClassMgrObject->somClassFromId(id2 =
    > somIdFromString("IWFProject"));
    >
    > for (i in allFiles)
    > {
    > pFileObj = _WPFileSystem->wpclsQueryObjectFromPath(fileSpec[i]);
    > ulAttrs = pFileObj->wpQueryAttr();
    > pFileObj->wpSetAttr(ulAttrs &
    > ~(FILE_READONLY|FILE_HIDDEN|FILE_SYSTEM));
    > pFileObj->wpSetup("DEFAULTVIEW=DEFAULT");
    > pCAM->camBecomeInstanceOf(pFileObj,pClass);
    > pFileObj->wpUnlockObject();
    > }
    > pCAM->somFree();
    > SOMFree(id2);
    > SOMFree(id1);


    Below are two implementations of the above: one that's very minimally
    optimized and one where everything is optimized. Not surprisingly,
    the first is pretty straight-forward while the second is ..uhh.. messy.
    OTOH, when you get to the loop that handles the 2nd & subsequent files,
    it's extremely simple. The first would be suitable for occassionally
    changing the class of a few files; the second would be appropriate if
    you plan to change hundreds of files on a regular basis.

    In both cases, a prime optimization is eliminating calls that don't
    have to be done by the WPS, namely getting & setting file attributes.
    Instead of wpQuery/SetAttr(), I used DosQuery/SetPathInfo().

    I also made a small but important change: camBecomeInstanceOf() is
    called *before* the other WPS calls. This is very important in the
    maximally optimized version because it applies the first file object's
    methods to every subsequent file. Before camBecome, you can't be sure
    every file is of the same class and uses the same method implementation.
    After camBecome, you're guaranteed that each object's wpSetup & wpUnlock
    is identical.

    BTW... I haven't compiled these samples, so they could have stupid
    errors (i.e. they're just like IBM's samples :-)


    /************************************************** *************************/

    // minimal optimization - should be OK for a few dozen files

    ULONG ReClassMin( char * pszClass, char ** apszFiles, ULONG cntFiles)
    {
    ULONG rc;
    ULONG ctr;
    ULONG camObj = 0;
    ULONG clsObj;
    ULONG newObj;
    FILESTATUS3 fs3;
    PRWSHDR pHdr = 0;
    PRWSDSC pArg;

    do {
    // create a ClassAssociationManager object, save the
    // returned value, then free the RWS request structure
    rc = RwsCall( &pHdr,
    RWSP_MNAM, (ULONG)"somNew", // call type
    RWSR_ASIS, 0, // return type
    1, // nbr of args
    RWSI_CNAME, 0, "ClassAssociationManager"); // class name
    if (rc) break;
    camObj = RwsGetResult( pHdr, 0, 0);
    RwsFreeMem( pHdr);
    pHdr = 0;

    // convert the classname into a class object ptr, save
    // the result, then free the RWS request structure
    rc = RwsCall( &pHdr,
    RWSP_CONV, 0, // call type
    RWSR_ASIS, 0, // return type
    1, // nbr of args
    RWSC_CNAME_CLASS, 0, pszClass); // class name
    if (rc) break;
    clsObj = RwsGetResult( pHdr, 1, 0);
    RwsFreeMem( pHdr);
    pHdr = 0;

    for (ctr = 0; ctr < cntFiles; ctr++) {

    // reset the file's attributes
    rc = DosQueryPathInfo( apszFiles[ctr], FIL_STANDARD, &fs3, sizeof(fs3));
    if (rc) break;
    fs3.attrFile &= ~(FILE_READONLY|FILE_HIDDEN|FILE_SYSTEM);
    rc = DosSetPathInfo( apszFiles[ctr], FIL_STANDARD, &fs3, sizeof(fs3), 0);
    if (rc) break;

    // execute "camBecomeInstanceOf" on the file,
    // then save the new object ptr created by the call
    rc = RwsCall( &pHdr,
    RWSP_MNAM, (ULONG)"camBecomeInstanceOf", // call type
    RWSR_ASIS, 0, // return type
    3, // nbr of args
    RWSI_ASIS, 0, camObj, // C-A-Mgr object
    RWSI_OPATH, 0, apszFiles[ctr], // filename buffer
    RWSI_ASIS, 0, clsObj); // new class name
    if (rc) break;
    newObj = RwsGetResult( pHdr, 0, 0);
    RwsFreeMem( pHdr);
    pHdr = 0;

    // execute "wpSetup" on the new object
    rc = RwsCall( &pHdr,
    RWSP_MNAM, (ULONG)"wpSetup", // call type
    RWSR_ASIS, 0, // return type
    2, // nbr of args
    RWSI_ASIS, 0, newObj, // file object
    RWSI_PSTR, 0, "DEFAULTVIEW=OPEN_RUNNING"); // setup string
    if (rc) break;
    RwsFreeMem( pHdr);
    pHdr = 0;

    // execute "wpUnlockObject" on the new object
    rc = RwsCall( &pHdr,
    RWSP_MNAM, (ULONG)"wpUnlockObject", // call type
    RWSR_ASIS, 0, // return type
    1, // nbr of args
    RWSI_ASIS, 0, newObj); // file object
    if (rc) break;
    RwsFreeMem( pHdr);
    pHdr = 0;
    }

    } while (0);

    // if we created a C-A-Mgr object, delete it
    if (camObj) {
    if (pHdr)
    RwsFreeMem( pHdr);
    pHdr = 0;

    RwsCall( &pHdr,
    RWSP_MNAMI, (ULONG)"somFree", // call type
    RWSR_VOID, 0, // return type
    1, // nbr of args
    RWSI_ASIS, 0, camObj); // C-A-Mgr object
    }

    // free the RWS request structure
    if (pHdr)
    RwsFreeMem( pHdr);

    return (rc);
    }

    /************************************************** *************************/

    // maximal optimization - appropriate for hundreds or thousands of files

    ULONG ReClassMax( char * pszClass, char ** apszFiles, ULONG cntFiles)
    {
    ULONG rc;
    ULONG ctr;
    ULONG camObj = 0;
    FILESTATUS3 fs3;
    PULONG pNewObj;
    PULONG pSetupObj;
    PULONG pUnlockObj;
    PRWSHDR pHdr = 0;
    PRWSHDR pHdrBecome = 0;
    PRWSHDR pHdrSetup = 0;
    PRWSHDR pHdrUnlock = 0;
    PRWSDSC pArg;
    char * pBuf;

    do {
    // create a ClassAssociationManager object
    rc = RwsCall( &pHdr,
    RWSP_MNAM, (ULONG)"somNew", // call type
    RWSR_ASIS, 0, // return type
    1, // nbr of args
    RWSI_CNAME, 0, "ClassAssociationManager"); // class name
    if (rc) break;

    // get return value, then free the RWS request structure
    camObj = CALCRTNPTR( pHdr)->value;
    RwsFreeMem( pHdr);
    pHdr = 0;

    // reset the first file's attributes
    rc = DosQueryPathInfo( apszFiles[0], FIL_STANDARD, &fs3, sizeof(fs3));
    if (rc) break;
    fs3.attrFile &= ~(FILE_READONLY|FILE_HIDDEN|FILE_SYSTEM);
    rc = DosSetPathInfo( apszFiles[0], FIL_STANDARD, &fs3, sizeof(fs3), 0);
    if (rc) break;

    // build a request structure for "camBecomeInstanceOf"
    // but don't dispatch it
    rc = RwsBuild( &pHdrBecome,
    RWSP_MNAM, (ULONG)"camBecomeInstanceOf", // call type
    RWSR_ASIS, 0, // return type
    3, // nbr of args
    RWSI_ASIS, 0, camObj, // C-A-Mgr object
    RWSI_PBUF, 260, 0, // filename buffer
    RWSI_CNAME, 0, (ULONG)pszClass); // new class name
    if (rc) break;

    // fix arg2's type, then copy the first filename into its buffer
    rc = RwsGetArgPtr( pHdrBecome, 2, &pArg);
    if (rc) break;
    pArg->type = RWSI_OPATH;
    pBuf = CALCGIVEPTR( pArg);
    strcpy( pBuf, apszFiles[0]);

    // dispatch the call - it destroys the original file object
    // and returns a ptr to a newly created object
    rc = RwsDispatch( pHdrBecome);
    if (rc) break;

    // lock in the classname & method ptrs, then
    // save a ptr to the return value (the new object)
    pArg->pnext->type = RWSI_ASIS;
    CALCPROCPTR( pHdrBecome)->type = RWSP_MPFN;
    pNewObj = &(CALCRTNPTR( pHdrBecome)->value);

    // execute "wpSetup" on the new object
    rc = RwsCall( &pHdrSetup,
    RWSP_MNAM, (ULONG)"wpSetup", // call type
    RWSR_ASIS, 0, // return type
    2, // nbr of args
    RWSI_ASIS, 0, *pNewObj, // new object
    RWSI_PSTR, 0, "DEFAULTVIEW=OPEN_RUNNING"); // setup string
    if (rc) break;

    // lock in the method ptr & save a ptr to arg1's value field
    pArg = CALCPROCPTR( pHdrSetup);
    pArg->type = RWSP_MPFN;
    pSetupObj = &(pArg->pnext->pnext->value);

    // execute wpUnlockObject on the new object
    rc = RwsCall( &pHdrUnlock,
    RWSP_MNAM, (ULONG)"wpUnlockObject", // call type
    RWSR_ASIS, 0, // return type
    1, // nbr of args
    RWSI_ASIS, 0, *pNewObj); // new object
    if (rc) break;

    // lock in the method ptr & save a ptr to arg1's value field
    pArg = CALCPROCPTR( pHdrUnlock);
    pArg->type = RWSP_MPFN;
    pUnlockObj = &(pArg->pnext->pnext->value);

    // perform low-overhead operations on remaining files
    for (ctr = 1; ctr < cntFiles; ctr++) {

    rc = DosQueryPathInfo( apszFiles[ctr], FIL_STANDARD, &fs3, sizeof(fs3));
    if (rc) break;
    fs3.attrFile &= ~(FILE_READONLY|FILE_HIDDEN|FILE_SYSTEM);
    rc = DosSetPathInfo( apszFiles[ctr], FIL_STANDARD, &fs3, sizeof(fs3), 0);
    if (rc) break;

    strcpy( pBuf, apszFiles[ctr]);
    rc = RwsDispatch( pHdrBecome);
    if (rc) break;

    *pSetupObj = *pNewObj;
    rc = RwsDispatch( pHdrSetup);
    if (rc) break;

    *pUnlockObj = *pNewObj;
    rc = RwsDispatch( pHdrUnlock);
    if (rc) break;
    }

    } while (0);

    // free the RWS structs used by the methods in the loop
    if (pHdrUnlock)
    RwsFreeMem( pHdrUnlock);
    if (pHdrSetup)
    RwsFreeMem( pHdrSetup);
    if (pHdrBecome)
    RwsFreeMem( pHdrBecome);

    // if we created a C-A-Mgr object, delete it
    if (camObj) {
    if (pHdr)
    RwsFreeMem( pHdr);
    pHdr = 0;

    RwsCall( &pHdr,
    RWSP_MNAMI, (ULONG)"somFree", // call type
    RWSR_VOID, 0, // return type
    1, // nbr of args
    RWSI_ASIS, 0, camObj); // C-A-Mgr object
    }

    // free the first RWS struct
    if (pHdr)
    RwsFreeMem( pHdr);

    return (rc);
    }

    /************************************************** *************************/


    --
    == == almost usable email address: Rich AT E-vertise.Com == ==
    __________________________________________________ _________________
    |
    | DragText v3.9 with NLS support
    Rich Walsh | A Distinctly Different Desktop Enhancement
    Ft Myers, FL | http://e-vertise.com/dragtext/
    __________________________________________________ _________________


  7. Re: How to change class of a file object ("Become" page functionality) ?

    [A complimentary Cc of this posting was NOT [per weedlist] sent to
    Rich Walsh
    ], who wrote in article :
    > The ability to chain methods like that would be my primary reason for
    > developing RWS further.


    > Below are two implementations of the above: one that's very minimally
    > optimized and one where everything is optimized. Not surprisingly,
    > the first is pretty straight-forward while the second is ..uhh.. messy.


    IMO, the "proper" way to implement such a client/server design is to
    embed a tiny "standard" command interpreter in the server, and make
    the client send "programs" as strings to interpret in the server.

    The interpreter of choice would be Tcl - 15 years ago it would take
    about 25K of executable space. Nowadays Tcl grew to a major monster
    (comparable to Perl in size; I'm afraid today the interpreter would
    take about 1M of executable). I've heard about some newer contenders
    (Lua?), but never investigated them further. Maybe somebody else
    would be able to comment...

    Hope this helps,
    Ilya

  8. Re: How to change class of a file object ("Become" page functionality) ?

    On Wed, 9 Jul 2008 02:00:00 UTC, Ilya Zakharevich wrote:
    > Rich Walsh wrote in article :


    > > The ability to chain methods like that would be my primary reason for
    > > developing RWS further.

    >
    > IMO, the "proper" way to implement such a client/server design is to
    > embed a tiny "standard" command interpreter in the server, and make
    > the client send "programs" as strings to interpret in the server.


    If the goal had been a "WPS Command Language", that might have been the
    way to go - but it wasn't. The goal was a versatile RPC facility that
    is capable of executing _any_ SOM/WPS method or SOM Kernel function
    using whatever data/data structures the call requires.

    By design, RWS is completely ignorant of what it's actually doing
    (i.e. invoking a method using known arguments to accomplish some end).
    Its operation is completely mechanical: it only "knows" how to massage
    data in & data out (as instructed), and how to invoke methods. I would
    think this is the opposite of how a command interpreter is designed.

    BTW... since you mention "tiny": RWS's client & server dlls are
    roughly 25k each (including the statically linked C RTL), so I think
    they merit the "tiny" appellation.


    --
    == == almost usable email address: Rich AT E-vertise.Com == ==
    __________________________________________________ _________________
    |
    | DragText v3.9 with NLS support
    Rich Walsh | A Distinctly Different Desktop Enhancement
    Ft Myers, FL | http://e-vertise.com/dragtext/
    __________________________________________________ _________________


  9. Re: How to change class of a file object ("Become" page functionality) ?

    [A complimentary Cc of this posting was NOT [per weedlist] sent to
    Rich Walsh
    ], who wrote in article :
    > > IMO, the "proper" way to implement such a client/server design is to
    > > embed a tiny "standard" command interpreter in the server, and make
    > > the client send "programs" as strings to interpret in the server.

    >
    > If the goal had been a "WPS Command Language", that might have been the
    > way to go - but it wasn't. The goal was a versatile RPC facility that
    > is capable of executing _any_ SOM/WPS method or SOM Kernel function
    > using whatever data/data structures the call requires.


    Yes, it WAS. But NOW the discussion is about how to limit
    client/server communication overhead. And the solution is to let
    client to make server preserve a lot of info, and use the preserved
    info in future calls (or loop explicitly).

    You can raise a home-grown way to do this; what I suggest is just use
    a tested well debugged library to handle the data living in the server.

    > By design, RWS is completely ignorant of what it's actually doing
    > (i.e. invoking a method using known arguments to accomplish some end).
    > Its operation is completely mechanical: it only "knows" how to massage
    > data in & data out (as instructed), and how to invoke methods. I would
    > think this is the opposite of how a command interpreter is designed.


    I do not think so. Even if your command interpreter supports ONE
    custom function (e.g., wps_exec()), the way to temporarily store its
    return value(s) in the server, and reuse/free the stuff later (using
    loops running in the server) would simplify the mess (one we currently
    see) a lot.

    > BTW... since you mention "tiny": RWS's client & server dlls are
    > roughly 25k each (including the statically linked C RTL), so I think
    > they merit the "tiny" appellation.


    Yes, this is what I suspected. There MUST be a small embeddable
    interpreter around...

    Yours,
    Ilya

  10. Re: How to change class of a file object ("Become" page functionality) ?

    An FYI...

    I was playing with camBecomeInstanceOf() and found that it works
    with folders as well as files. I took a generic folder and changed
    it into an instance of MMFolder, WPUrlFolder, WPStartup, & WPDesktop.

    In a few cases the WPS crashed but I couldn't identify the exact
    circumstances because the same transformation usually caused no
    problems when repeated later. I should mention that my config.sys
    contains SET SHELLEXCEPTIONHANDLER=OFF. Without this, the WPS
    might have handled whatever the problem was more gracefully.


    --
    == == almost usable email address: Rich AT E-vertise.Com == ==
    __________________________________________________ _________________
    |
    | DragText v3.9 with NLS support
    Rich Walsh | A Distinctly Different Desktop Enhancement
    Ft Myers, FL | http://e-vertise.com/dragtext/
    __________________________________________________ _________________


  11. Re: How to change class of a file object ("Become" page functionality) ?

    Hi,

    "Rich Walsh" schrieb im Newsbeitrag
    news:brddYgxvE0gm-pn2-c8BIQ64GbD1H@localhost...
    > An FYI...
    >
    > I was playing with camBecomeInstanceOf() and found that it works
    > with folders as well as files. I took a generic folder and changed
    > it into an instance of MMFolder, WPUrlFolder, WPStartup, & WPDesktop.


    Yeah, that's funny, the WPS does not offer a user interface to change
    folders (WPFolder and derived), only data files (WPDataFile and derived).

    >
    > In a few cases the WPS crashed but I couldn't identify the exact
    > circumstances because the same transformation usually caused no
    > problems when repeated later. I should mention that my config.sys
    > contains SET SHELLEXCEPTIONHANDLER=OFF. Without this, the WPS
    > might have handled whatever the problem was more gracefully.



    Maybe that's why they did not offer the user interface for Folders. They
    couldn't get it stable with WPFolder ...


    P.S.: Many thanks for your sample code.



    Lars



  12. Re: How to change class of a file object ("Become" page functionality)?

    Lars Erdmann wrote:
    > Hi,
    >
    > "Rich Walsh" schrieb im Newsbeitrag
    > news:brddYgxvE0gm-pn2-c8BIQ64GbD1H@localhost...
    >
    >>In a few cases the WPS crashed but I couldn't identify the exact
    >>circumstances because the same transformation usually caused no
    >>problems when repeated later. I should mention that my config.sys
    >>contains SET SHELLEXCEPTIONHANDLER=OFF. Without this, the WPS
    >>might have handled whatever the problem was more gracefully.

    >
    > Maybe that's why they did not offer the user interface for Folders. They
    > couldn't get it stable with WPFolder ...


    Not meaning to be overly negative, but the MM Folder class itself was a
    bit of a turd when it came to stability, with or without re-classing.

    Becoming a URL folder sounds like a strange idea with not very
    predictable behavior.

    Becoming a desktop and becoming a startup folder could probably be
    confusing to the legacy IBM code (although XWorkplace and such handle it
    very well).

    So I guess I'm not particularly surprised that they didn't fully
    implement this code path down to the user level.

    --
    [Reverse the parts of the e-mail address to reply.]

  13. Re: How to change class of a file object ("Become" page functionality) ?

    On Fri, 11 Jul 2008 20:13:46 UTC, "Lars Erdmann" wrote:
    > "Rich Walsh" schrieb im Newsbeitrag news:brddYgxvE0gm-pn2-c8BIQ64GbD1H@localhost...


    > > I was playing with camBecomeInstanceOf() and found that it works
    > > with folders as well as files.

    >
    > Yeah, that's funny, the WPS does not offer a user interface to change
    > folders (WPFolder and derived), only data files (WPDataFile and derived).


    There are only a few classes (e.g. MMFolder & WPUrlFolder) where this
    ability even makes sense for the average user. For most system-supplied
    subclasses, it would probably be considered dangerous (e.g. WPDesktop).
    Still it might be handy to have a utility that could repair your
    Desktop or Startup folder.

    > P.S.: Many thanks for your sample code.


    Creating and discussing it made me realize that RWS could use another
    function or two to make optimization cleaner & simpler. While I may
    be familiar with its internals, there's no reason why you should have
    to know its inner workings to get good results.

    BTW... something I failed to mention: In the optimized version,
    the primary performance gain occurs on the client side. Not having
    to allocate, build, and populate a request structure for every call
    probably saves more time than reusing object & method pointers
    (though reusing them will certainly improve performance even more).



    --
    == == almost usable email address: Rich AT E-vertise.Com == ==
    __________________________________________________ _________________
    |
    | DragText v3.9 with NLS support
    Rich Walsh | A Distinctly Different Desktop Enhancement
    Ft Myers, FL | http://e-vertise.com/dragtext/
    __________________________________________________ _________________


  14. Re: How to change class of a file object ("Become" page functionality) ?


    "Rich Walsh" schrieb im Newsbeitrag
    news:brddYgxvE0gm-pn2-RQgfLHsLdOYw@localhost...
    > On Fri, 11 Jul 2008 20:13:46 UTC, "Lars Erdmann"
    > wrote:
    >> "Rich Walsh" schrieb im Newsbeitrag
    >> news:brddYgxvE0gm-pn2-c8BIQ64GbD1H@localhost...

    >
    >> > I was playing with camBecomeInstanceOf() and found that it works
    >> > with folders as well as files.

    >>
    >> Yeah, that's funny, the WPS does not offer a user interface to change
    >> folders (WPFolder and derived), only data files (WPDataFile and derived).

    >
    > There are only a few classes (e.g. MMFolder & WPUrlFolder) where this
    > ability even makes sense for the average user. For most system-supplied
    > subclasses, it would probably be considered dangerous (e.g. WPDesktop).
    > Still it might be handy to have a utility that could repair your
    > Desktop or Startup folder.


    Ok, that's true. You could easily screw up your complete system.

    >
    >> P.S.: Many thanks for your sample code.

    >
    > Creating and discussing it made me realize that RWS could use another
    > function or two to make optimization cleaner & simpler. While I may
    > be familiar with its internals, there's no reason why you should have
    > to know its inner workings to get good results.


    Yes I also had that feeling, for some things you have a macro, for others,
    you have a function etc. On the other hand, it's very stable and powerful
    and a lot better then DSOM which seems to have been abandoned even before
    SOM. At least, DSOM has some shortcomings that makes it not very suitable to
    communicate with WPS objects (SOMObject derived classes might work a lot
    better).
    Examples: it does not support "somID" as a parameter (that data type cannot
    be passed across process borders), it gets confused if you replace WPS
    classes (I have XWorkplace installed and all of a sudden, you are not able
    to access any WPS object because XWorkplace replaces some pretty fundamental
    classes. The same program works fine if you deinstall XWorkplace), you
    possibly need to adjust the configuration (interface repository,
    implementation repository) in order to get your application to run OK, etc.
    The one thing I liked about DSOM was that proxy object concept that allows
    you to write code just like for any WPS class. You talk to objects and
    that's that ...
    RWS is really different but now that I understand how it works, it's also
    fine with me ...


    > BTW... something I failed to mention: In the optimized version,
    > the primary performance gain occurs on the client side. Not having
    > to allocate, build, and populate a request structure for every call
    > probably saves more time than reusing object & method pointers
    > (though reusing them will certainly improve performance even more).



    I am not too worried about performance. I just have the problem that my VAC
    3.x projects that I backup every now and then always "loose" their
    "IWFProject" class and fall back to being of class "WPDataFile". Somehow
    this seems to depend on the file type which is saved in the files EAs
    ("IWFProject" objects have a very distinct file type). So, every now and
    then I need to restore those VAC 3.x projects and they are too numerous (or
    I am too lazy) to do it by hand. On the other hand I guess I would just need
    to preserve their EAs. I just saved those files (because that's what
    "IWFProject" objects are physically) to CD-ROM. Maybe I have to dig deeper
    into ZIP and see how I can preserve EAs (apart from running something like
    EAUTIL).


    Lars



  15. Re: How to change class of a file object ("Become" page functionality) ?


    > Maybe I have to dig deeper into ZIP and see how I can preserve EAs
    > (apart from running something like EAUTIL).


    YMMV, but LH32.EXE (in LH2* @ Hobbes?) is rather easy to use, with a
    limited number of switches. E.g.:

    LH32.EXE a Projects.LZH D:\Projects\* /e /a /s

    You'll need to replace the "a"(dd) with an "x" to extract, and this is
    a help for remembering the (also ea-related) switches: "/e /a /s"



    ---

+ Reply to Thread
Page 2 of 2 FirstFirst 1 2