
/*
 *@@sourcefile xfdataf.c:
 *      This file contains SOM code for the following XWorkplace classes:
 *
 *      --  XFldDataFile (WPDataFile replacement)
 *
 *      XFldDataFile is responsible for menu manipulation
 *      and default icon replacements for data files.
 *      Since we should not override WPFileSystem to implement
 *      this functionality for folders and data files altogether,
 *      we must add this to WPDataFile separately.
 *
 *      Installation of this class is now optional (V0.9.0).
 *
 *      Starting with V0.9.0, the files in classes\ contain only
 *      i.e. the methods themselves.
 *      The implementation for this class is mostly in filesys\filesys.c
 *      and (for extended file types) in filesys\filetype.c.
 *
 *      <B>Extended File Associations</B>
 *
 *      -- To get the new associated programs into the "Open" menu,
 *         we override wpDisplayMenu (Warp 3) and wpModifyMenu
 *         (Warp 4).
 *
 *      -- For general WPS support (including icons), we override
 *         XFldDataFile::wpQueryAssociatedProgram.
 *
 *      -- The new selections are intercepted in XFldDataFile::wpOpen.
 *
 *@@somclass XFldDataFile xdf_
 *@@somclass M_XFldDataFile xdfM_
 */

/*
 *      Copyright (C) 1997-2013 Ulrich M”ller.
 *
 *      This file is part of the XWorkplace source package.
 *      XWorkplace is free software; you can redistribute it and/or modify
 *      it under the terms of the GNU General Public License as published
 *      by the Free Software Foundation, in version 2 as it comes in the
 *      "COPYING" file of the XWorkplace main distribution.
 *      This program is distributed in the hope that it will be useful,
 *      but WITHOUT ANY WARRANTY; without even the implied warranty of
 *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *      GNU General Public License for more details.
 */

/*
 *  This file was generated by the SOM Compiler and Emitter Framework.
 *  Generated using:
 *      SOM Emitter emitctm: 2.41
 */

#ifndef SOM_Module_xfdataf_Source
#define SOM_Module_xfdataf_Source
#endif
#define XFldDataFile_Class_Source
#define M_XFldDataFile_Class_Source

#pragma strings(readonly)

/*
 *  Suggested #include order:
 *  1)  os2.h
 *  2)  C library headers
 *  3)  setup.h (code generation and debugging options)
 *  4)  headers in helpers\
 *  5)  at least one SOM implementation header (*.ih)
 *  6)  dlgids.h, headers in shared\ (as needed)
 *  7)  headers in implementation dirs (e.g. filesys\, as needed)
 *  8)  #pragma hdrstop and then more SOM headers which crash with precompiled headers
 */

#define INCL_DOSPROCESS
#define INCL_DOSEXCEPTIONS
#define INCL_DOSSEMAPHORES
#define INCL_DOSERRORS

#define INCL_WINPOINTERS
#define INCL_WINMENUS
#define INCL_WINPROGRAMLIST     // needed for wppgm.h
#define INCL_WINSHELLDATA       // Prf* functions

#define INCL_GPILOGCOLORTABLE
#include <os2.h>

// C library headers
#include <stdio.h>
#include <setjmp.h>

// generic headers
#include "setup.h"                      // code generation and debugging options

// headers in /helpers
#include "helpers\dosh.h"               // Control Program helper routines
#include "helpers\except.h"             // exception handling
#include "helpers\gpih.h"               // GPI helper routines
#include "helpers\linklist.h"           // linked list helper routines
#include "helpers\prfh.h"               // INI file helper routines
#include "helpers\standards.h"          // some standard macros
#include "helpers\winh.h"               // PM helper routines

// SOM headers which don't crash with prec. header files
#include "xfdataf.ih"

// XWorkplace implementation headers
#include "dlgids.h"                     // all the IDs that are shared with NLS
#include "shared\classtest.h"           // some cheap funcs for WPS class checks
#include "shared\common.h"              // the majestic XWorkplace include file
#include "shared\helppanels.h"          // all XWorkplace help panel IDs
#include "shared\kernel.h"              // XWorkplace Kernel
#include "shared\notebook.h"            // generic XWorkplace notebook handling
#include "shared\wpsh.h"                // some pseudo-SOM functions (WPS helper routines)

#include "filesys\filesys.h"            // various file-system object implementation code
#include "filesys\fileops.h"            // file operations implementation
#include "filesys\filetype.h"           // extended file types implementation
#include "filesys\folder.h"             // XFolder implementation
#include "filesys\fdrcommand.h"         // folder command handling
#include "filesys\fdrhotky.h"           // folder hotkey handling
#include "filesys\fdrmenus.h"           // shared folder menu logic
#include "filesys\icons.h"              // icons handling
#include "filesys\object.h"             // XFldObject implementation
#include "filesys\program.h"            // program implementation; WARNING: this redefines macros

// other SOM headers
#pragma hdrstop                 // VAC++ keeps crashing otherwise

#include <wpimage.h>

/* ******************************************************************
 *
 *   Global variables
 *
 ********************************************************************/

static HMTX G_hmtxThumbnails = NULLHANDLE;

/* ******************************************************************
 *
 *   Helpers
 *
 ********************************************************************/

/*
 *@@ LockThumbnails:
 *      requests the global mutex for protecting instance
 *      thumbnails. This has been added to avoid requesting the
 *      object mutex, which can cause deadlocks.
 *
 *@@added V1.0.1 (2003-01-29) [umoeller]
 */

BOOL LockThumbnails(VOID)
{
    if (G_hmtxThumbnails)
        return !DosRequestMutexSem(G_hmtxThumbnails, SEM_INDEFINITE_WAIT);

    // first call:
    return !DosCreateMutexSem(NULL,
                              &G_hmtxThumbnails,
                              0,
                              TRUE);
}

/*
 *@@ UnlockThumbnails:
 *
 *@@added V1.0.1 (2003-01-29) [umoeller]
 */

VOID UnlockThumbnails(VOID)
{
    DosReleaseMutexSem(G_hmtxThumbnails);
}

/* ******************************************************************
 *
 *   XFldDataFile instance methods
 *
 ********************************************************************/

/*
 *@@ BUILDSTACK:
 *      temp struct for fncbBuildAssocsList.
 *
 *@@added V0.9.20 (2002-07-25) [umoeller]
 */

typedef struct _BUILDSTACK
{
    WPObject    **papObjects;
    PULONG      pcAssocs;
    ULONG       ulBuildMax;
    PBOOL       pfDone;
} BUILDSTACK, *PBUILDSTACK;

#ifndef __NOTURBOFOLDERS__

/*
 *@@ fncbBuildAssocsList:
 *      callback set from BuildAssocsList for ftypForEachAutoType.
 *
 *@@added V0.9.20 (2002-07-25) [umoeller]
 */

BOOL _Optlink fncbBuildAssocsList(PCSZ pcszType,
                                  ULONG ulTypeLen,
                                  PVOID pvUser)
{
    PBUILDSTACK pb = (PBUILDSTACK)pvUser;
    _xwpclsListAssocsForType(_XFldDataFile,
                             pb->papObjects,
                             pb->pcAssocs,
                             (PSZ)pcszType,
                             pb->ulBuildMax,
                             pb->pfDone);

    // return TRUE to keep going
    return !(*(pb->pfDone));
}

#endif

/*
 *@@ xwpQueryAssociations:
 *      this helper instance method builds a list of all
 *      associated WPProgram and WPProgramFile objects
 *      and returns it in the array that is passed in.
 *
 *      This is the heart of the extended associations
 *      engine. This function gets called whenever
 *      extended associations are needed.
 *
 *      --  From ftypQueryAssociatedProgram, this gets
 *          called with (fUsePlainTextAsDefault == FALSE),
 *          mostly (inheriting that func's param).
 *          Since that method is called during folder
 *          population to find the correct icon for the
 *          data file, we do NOT want all data files to
 *          receive the icons for plain text files.
 *
 *      --  From ftypModifyDataFileOpenSubmenu, this gets
 *          called with (fUsePlainTextAsDefault == TRUE).
 *          We do want the items for "plain text" in the
 *          "Open" context menu if no other type has been
 *          assigned.
 *
 *      The list (which is of type PLINKLIST, containing
 *      plain WPObject* pointers) is returned.
 *
 *      This returns NULL if an error occurred or no
 *      associations were added.
 *
 *      NOTE: This locks each object instantiated as a
 *      result of the call. After this function
 *      returns, run through the array that was filled
 *      and unlock each object once.
 *
 *@@added V0.9.0 (99-11-27) [umoeller]
 *@@changed V0.9.6 (2000-10-16) [umoeller]: now returning a PLINKLIST
 *@@changed V0.9.7 (2001-01-11) [umoeller]: no longer using plain text always
 *@@changed V0.9.9 (2001-03-27) [umoeller]: no longer creating list if no assocs exist, returning NULL now
 *@@changed V0.9.16 (2002-01-05) [umoeller]: this never added "plain text" if the object had a type but no associations
 *@@changed V0.9.16 (2002-01-26) [umoeller]: added ulBuildMax, mostly rewritten for MAJOR speedup
 *@@changed V0.9.20 (2002-07-25) [umoeller]: adjustments for getting rid of caches and mutexes
 *@@changed V0.9.20 (2002-07-25) [umoeller]: made function private
 *@@changed V0.9.20 (2002-07-25) [umoeller]: got rid of linked list
 *@@changed V1.0.1 (2002-12-14) [umoeller]: turned this into a method
 */

SOM_Scope ULONG  SOMLINK xdf_xwpQueryAssociations(XFldDataFile *somSelf,
                                                  WPObject** papObjects,
                                                  ULONG ulBuildMax,
                                                  BOOL fUsePlainTextAsDefault)
{
    ULONG cAssocs = 0;

#ifndef __NOTURBOFOLDERS__
    // XFldDataFileData *somThis = XFldDataFileGetData(somSelf);
    XFldDataFileMethodDebug("XFldDataFile","xdf_xwpQueryAssociations");

    TRY_LOUD(excpt1)
    {
        BOOL        fDone = FALSE;
        PSZ pszExplicitTypes;

        if (    (ulBuildMax == -1)
             || (ulBuildMax > MAX_ASSOCS_PER_OBJECT)
           )
            // caller wants all assocs:
            // delimit anyway to not crash the array
            ulBuildMax = MAX_ASSOCS_PER_OBJECT;

        // 1) run thru the types that were assigned explicitly
        if (    (pszExplicitTypes = _wpQueryType(somSelf))
             && (*pszExplicitTypes)
           )
        {
            // yes, explicit type(s):
            // decode those (separated by '\n')
            PSZ pszTypesCopy;
            if (pszTypesCopy = strdup(pszExplicitTypes))
            {
                PSZ     pTypeThis = pszExplicitTypes;
                PSZ     pLF = 0;

                // loop thru types list
                while (pTypeThis && *pTypeThis && !fDone)
                {
                    // get next line feed
                    if (pLF = strchr(pTypeThis, '\n'))
                        // line feed found:
                        *pLF = '\0';

                    _xwpclsListAssocsForType(_XFldDataFile,
                                             papObjects,
                                             &cAssocs,
                                             pTypeThis,
                                             ulBuildMax,
                                             &fDone);

                    if (pLF)
                        // next type (after LF)
                        pTypeThis = pLF + 1;
                    else
                        break;
                }

                free(pszTypesCopy);
            }
        }

        if (!fDone)
        {
            // 2) run thru automatic (extended) file types based on
            //    the object title
            BUILDSTACK bs;
            bs.papObjects = papObjects;
            bs.pcAssocs = &cAssocs;
            bs.ulBuildMax = ulBuildMax;
            bs.pfDone = &fDone;

            ftypForEachAutoType(_wpQueryTitle(somSelf),
                                fncbBuildAssocsList,
                                &bs);
        }

        // V0.9.16 (2002-01-05) [umoeller]:
        // moved the following "plain text" addition down...
        // previously, "plain text" was only added if no _types_
        // were present, but that isn't entirely correct... really
        // it should be added if no _associations_ were found,
        // so check this here instead!
        if (    (fUsePlainTextAsDefault)
             && (!cAssocs)
           )
        {
            _xwpclsListAssocsForType(_XFldDataFile,
                                     papObjects,
                                     &cAssocs,
                                     "Plain Text",
                                     ulBuildMax,
                                     NULL);
        }
    }
    CATCH(excpt1)
    {
    } END_CATCH();
#endif

    return cAssocs;
}

/*
 *@@ xwpRequestContentMutexSem:
 *      this new XFldDataFile method requests the object's
 *      "content" mutex semaphore, which has been introduced
 *      to protect the file's contents.
 *
 *      As far as I can tell, the WPS has no way of preventing
 *      multiple threads from accessing a file at the same time.
 *      This leads to race conditions with the WPImageFile
 *      methods for loading bitmap data, for example. This is
 *      why XWorkplace only calls these methods under the
 *      protection of this semaphore.
 *
 *      If this returns NO_ERROR, the object's contents are locked.
 *      It thus has the same semantics as WPObject::wpRequestObjectMutexSem.
 *
 *@@added V1.0.1 (2003-01-29) [umoeller]
 */

SOM_Scope APIRET  SOMLINK xdf_xwpRequestContentMutexSem(XFldDataFile *somSelf,
                                                        ULONG ulTimeout)
{
    XFldDataFileData *somThis = XFldDataFileGetData(somSelf);
    XFldDataFileMethodDebug("XFldDataFile","xdf_xwpRequestContentMutexSem");

    if (_hmtxContent)
        return DosRequestMutexSem(_hmtxContent, ulTimeout);

    return DosCreateMutexSem(NULL,
                             &_hmtxContent,
                             0,
                             TRUE);     // initial request
}

/*
 *@@ xwpReleaseContentMutexSem:
 *      this new XFldDataFile method releases the object's
 *      "content" mutex semaphore that was previously
 *      requested via XFldObject::xwpRequestContentMutexSem.
 *
 *@@added V1.0.1 (2003-01-29) [umoeller]
 */

SOM_Scope APIRET  SOMLINK xdf_xwpReleaseContentMutexSem(XFldDataFile *somSelf)
{
    XFldDataFileData *somThis = XFldDataFileGetData(somSelf);
    XFldDataFileMethodDebug("XFldDataFile","xdf_xwpReleaseContentMutexSem");

    return DosReleaseMutexSem(_hmtxContent);
}

/*
 *@@ xwpQueryThumbnail:
 *      this new XFldDataFile method returns the current thumbnail
 *      bitmap of the object.
 *
 *      It returns NULLHANDLE if no thumbnail bitmap has yet been
 *      created.
 *
 *      As a special error code, it may return -1 if creating the
 *      thumbnail bitmap previously failed and should not be
 *      attempted again. Check for that -1 handle and do not pass
 *      it to PM calls!
 *
 *@@added V1.0.1 (2003-01-29) [umoeller]
 */

SOM_Scope HBITMAP  SOMLINK xdf_xwpQueryThumbnail(XFldDataFile *somSelf)
{
    HBITMAP hbm = -1;
    XFldDataFileData *somThis = XFldDataFileGetData(somSelf);
    XFldDataFileMethodDebug("XFldDataFile","xdf_xwpQueryThumbnail");

    if (LockThumbnails())
    {
        hbm = _hbmThumbnail;
        UnlockThumbnails();
    }

    return hbm;
}

/*
 *@@ xwpSetThumbnail:
 *      this new XFldDataFile method sets a new thumbnail bitmap
 *      for the object and repaints the object in all open views.
 *
 *      If you set NULLHANDLE for the thumbnail handle, the object's
 *      thumbnail is deleted.
 *
 *      As a special error code, you may set a -1 handle to signal
 *      that an error occurred creating the thumbnail (for example,
 *      because reading the object's data failed) and the system
 *      should not attempt to create a thumbnail again.
 *
 *      Returns TRUE if the thumbnail changed and the object was
 *      thus invalidated.
 *
 *@@added V1.0.1 (2003-01-29) [umoeller]
 */

SOM_Scope BOOL  SOMLINK xdf_xwpSetThumbnail(XFldDataFile *somSelf,
                                            HBITMAP hbmThumbnail)
{
    BOOL    brc = FALSE,
            fLocked = FALSE;
    XFldDataFileData *somThis = XFldDataFileGetData(somSelf);
    XFldDataFileMethodDebug("XFldDataFile","xdf_xwpSetThumbnail");

    TRY_LOUD(excpt1)
    {
        if (fLocked = LockThumbnails())
        {
            if (_hbmThumbnail != hbmThumbnail)
            {
                // delete old bitmap, if present
                if (    (_hbmThumbnail)
                     && (_hbmThumbnail != -1)       // error flag
                   )
                {
                    GpiDeleteBitmap(_hbmThumbnail);
                    _hbmThumbnail = NULLHANDLE;
                }

                // set new thumbnail
                _hbmThumbnail = hbmThumbnail;

                brc = TRUE;
            }
        }
    }
    CATCH(excpt1)
    {
        brc = FALSE;
    } END_CATCH();

    if (fLocked)
        UnlockThumbnails();

    if (brc)
        _xwpForceRepaint(somSelf,
                         REFRESH_RECORDREPAINT);

    return brc;
}

/*
 *@@ xwpLazyLoadThumbnail:
 *      this new XFldDataFile instance method gets called on
 *      the thumbnail thread if XFldObject::xwpOwnerDrawIcon
 *      returned the OWDRFL_LAZYLOADTHUMBNAIL bit set. If this
 *      method can display itself as a bitmap, it must create
 *      one and return it.
 *
 *      This method is similar to XFldObject::xwpLazyLoadIcon
 *      in that it is called asynchronously on a background
 *      thread to defer thumbnail loading. However, there
 *      are differences:
 *
 *      --  This method actually gets called from the
 *          XFldDataFile::xwpLazyLoadIcon override and is
 *          thus specific to data files. In other words,
 *          only data files can ever have thumbnails.
 *
 *      --  It must create the bitmap with the given width
 *          and height, which are the current settings for
 *          folder thumbnails. If those are changed by the
 *          user, this method must get called again.
 *
 *      --  The caller takes care of repainting the object,
 *          which is different from XFldObject::xwpLazyLoadIcon,
 *          where the method must invalidate itself.
 *
 *      If this returns NULLHANDLE, this means that the
 *      method could not understand the file's format, and
 *      regular lazy icon processing takes place, i.e. the
 *      object will then receive an icon according to the
 *      usual data file rules. It will only get called
 *      again on explicit refresh.
 *
 *      The XFldDataFile base implementation calls
 *      _wpQueryBitmapHandle for instances of WPImageFile
 *      only and will return NULLHANDLE otherwise.
 *
 *@@added V1.0.1 (2003-01-29) [umoeller]
 */

SOM_Scope HBITMAP  SOMLINK xdf_xwpLazyLoadThumbnail(XFldDataFile *somSelf,
                                                    ULONG ulWidth,
                                                    ULONG ulHeight,
                                                    BOOL* pbQuitEarly)
{
    HBITMAP hbm;
    HPAL    hpal = NULLHANDLE;

    // XFldDataFileData *somThis = XFldDataFileGetData(somSelf);
    XFldDataFileMethodDebug("XFldDataFile","xdf_xwpLazyLoadThumbnail");

    _PmpfF(("entering"));

    if (    (ctsIsImageFile(somSelf))
         && (_wpQueryBitmapHandle(somSelf,
                                  &hbm,
                                  &hpal,            // we _must_ specify hpal, or the brain-dead MMPM classes crash
                                  ulWidth,
                                  ulHeight,
                                  0,
                                  0,
                                  pbQuitEarly))
       )
    {
        if (hpal)
            GpiDeletePalette(hpal);

        return hbm;
    }

    return NULLHANDLE;
}

/*
 *@@ wpInitData:
 *      this WPObject instance method gets called when the
 *      object is being initialized (on wake-up or creation).
 *      We initialize our additional instance data here.
 *      Always call the parent method first.
 *
 *@@added V0.9.18 (2002-03-19) [umoeller]
 */

SOM_Scope void  SOMLINK xdf_wpInitData(XFldDataFile *somSelf)
{
    // XFldDataFileData *somThis = XFldDataFileGetData(somSelf);
    XFldDataFileMethodDebug("XFldDataFile","xdf_wpInitData");

    XFldDataFile_parent_WPDataFile_wpInitData(somSelf);

    // _fHasIconEA = FALSE;

    // cache this V0.9.19 (2002-06-15) [umoeller]
    if (    (ctsIsIcon(somSelf))
         || (ctsIsPointer(somSelf))
       )
        _xwpModifyFlags(somSelf,
                        OBJFL_WPDATAFILE | OBJFL_WPICONORPOINTER,
                        OBJFL_WPDATAFILE | OBJFL_WPICONORPOINTER);
    // do a hard test for WPImageFile here for compatibility
    // if XWPImageFile is not replacing WPImageFile
    // V1.0.1 (2003-01-29) [umoeller]
    else if (ctsIsImageFile(somSelf))
        // we can do thumbnails
        _xwpModifyFlags(somSelf,
                        OBJFL_WPDATAFILE | OBJFL_OWNERDRAWTHUMBNAIL,
                        OBJFL_WPDATAFILE | OBJFL_OWNERDRAWTHUMBNAIL);
    else
        _xwpModifyFlags(somSelf,
                        OBJFL_WPDATAFILE,
                        OBJFL_WPDATAFILE);
}

/*
 *@@ wpUnInitData:
 *      this WPObject instance method is called when the object
 *      is destroyed as a SOM object, either because it's being
 *      made dormant (via wpMakeDormant) or being deleted for
 *      good (via wpFree). All allocated in-memory resources
 *      should be freed here, but to destroy the physical
 *      representation of the object, override wpDestroyObject
 *      instead.
 *
 *      The parent method must always be called last.
 *
 *@@added V0.9.18 (2002-03-24) [umoeller]
 *@@changed V1.0.10 (2013-03-15) [pr]: @@fixes 336
 */

SOM_Scope void  SOMLINK xdf_wpUnInitData(XFldDataFile *somSelf)
{
    XFldDataFileData *somThis = XFldDataFileGetData(somSelf);
    XFldDataFileMethodDebug("XFldDataFile","xdf_wpUnInitData");

    // we have a problem with our replacement icons in that
    // the WPS frees the pointer handle in WPObject::wpUnInitData
    // if the object has the OBJSTYLE_NOTDEFAULTICON or OBJSTYLE_TEMPLATE
    // flags set... so in these cases, check if the object has one
    // of our standard icons WHICH MUST NOT BE FREED under any circumstances,
    // or the shared icon would disappear globally
    // V0.9.16 (2001-12-31) [umoeller]
    #ifdef __DEBUG__
    {
        PMINIRECORDCORE pmrc = _wpQueryCoreRecord(somSelf);
        PMPF_ICONREPLACEMENTS(("[%s] OBJSTYLE_NOTDEFAULTICON %lX",
                _wpQueryTitle(somSelf),
                _wpQueryStyle(somSelf) & OBJSTYLE_NOTDEFAULTICON));
        PMPF_ICONREPLACEMENTS(("    OBJSTYLE_TEMPLATE %lX",
                _wpQueryStyle(somSelf) & OBJSTYLE_TEMPLATE));
        PMPF_ICONREPLACEMENTS(("    hptrIcon %lX",
                pmrc->hptrIcon));
        PMPF_ICONREPLACEMENTS(("    cmnIsStandardIcon %lX",
                cmnIsStandardIcon(pmrc->hptrIcon)));
    }
    #endif

    _xwpSetThumbnail(somSelf, -1);
    icomUnqueueLazyIcon(somSelf);  // V1.0.10

    XFldDataFile_parent_WPDataFile_wpUnInitData(somSelf);
}

/*
 *@@ wpDestroyObject:
 *      this undocumented WPObject method gets called during
 *      wpFree processing to destroy the physical storage of
 *      an object (for file-system objects, the file or folder,
 *      for abstracts, the INI data).
 *
 *      Starting with V0.9.20, we are now able to override this
 *      undocumented WPS method too, so the previous overhead
 *      with xwpDestroyStorage has been removed.
 *
 *      This implementation actually deletes the data file using
 *      DosDelete.
 *
 *      As opposed to the WPS, we are smart enough NOT to
 *      display a message box here if deletion failed. In
 *      addition, if the file is already gone, we return
 *      TRUE, since the file was obviously already deleted.
 *
 *@@added V0.9.20 (2002-07-25) [umoeller]
 *@@changed V1.0.0 (2002-09-09) [umoeller]: added wpSetError on errors
 */

SOM_Scope BOOL  SOMLINK xdf_wpDestroyObject(XFldDataFile *somSelf)
{
    BOOL    brc = FALSE;
    CHAR    szFilename[CCHMAXPATH];

    // XFldDataFileData *somThis = XFldDataFileGetData(somSelf);
    XFldDataFileMethodDebug("XFldDataFile","xdf_wpDestroyObject");

    if (_wpQueryFilename(somSelf, szFilename, TRUE))
    {
        // use DosForceDelete if the file is in \trash
        // V0.9.20 (2002-07-12) [umoeller]
        APIRET arc;
        if (fopsUseForceDelete(szFilename))
            arc = DosForceDelete(szFilename);
        else
            arc = DosDelete(szFilename);

        PMPF_FOPS(("DosDelete(%s) returned %d", szFilename, arc));

        switch (arc)
        {
            case NO_ERROR:
            case ERROR_FILE_NOT_FOUND:
            case ERROR_PATH_NOT_FOUND:
                brc = TRUE;
            break;

            default:
                // anything else is truly an error, so set an error
                // code on the object so fops_bottom.c can figure
                // out what went wrong; wpFree has called
                // wpSetError(NO_ERROR) previously
                // V1.0.0 (2002-09-09) [umoeller]
                _wpSetError(somSelf, arc);
        }
    }

    PMPF_FOPS(("returning %s", (brc) ? "TRUE" : "FALSE"));

    return brc;

    // return (XFldDataFile_parent_WPDataFile_wpDestroyObject(somSelf));
}

/*
 *@@ wpRestoreState:
 *      this WPObject instance method gets called during object
 *      initialization (after wpInitData) to restore the data
 *      which was stored with wpSaveState.
 *
 *      The WPDataFile implementation has a _major_ bug in here
 *      in that it turns _on_ the OBJSTYLE_NOTDEFAULTICON bit
 *      even if no icon was loaded from the EAs. As a result,
 *      another rewrite was in order here.
 *
 *      The interesting thing is that the ulReserved parameter
 *      points to a MAKEAWAKEFS structure (filesys.h) which
 *      was passed to wpclsMakeAwake by wpPopulate. As a result,
 *      we can use it to build an icon from the EAs that were
 *      loaded during populate.
 *
 *@@added V0.9.16 (2001-12-08) [umoeller]
 *@@changed V0.9.18 (2002-03-24) [umoeller]: fixed disappearing standard icons on copy
 */

SOM_Scope BOOL  SOMLINK xdf_wpRestoreState(XFldDataFile *somSelf,
                                           ULONG ulReserved)
{
    BOOL    brc = FALSE;
    somTD_WPObject_wpRestoreState pwpRestoreState = NULL;

    XFldDataFileMethodDebug("XFldDataFile","xdf_wpRestoreState");

#ifdef __DEBUG__
    TRY_LOUD(dbgexc)
#endif
    {
        PMPF_ICONREPLACEMENTS(("pre: hptr: 0x%lX, OBJSTYLE_NOTDEFAULTICON: %lX",
                _wpQueryCoreRecord(somSelf)->hptrIcon,
                _wpQueryStyle(somSelf) & OBJSTYLE_NOTDEFAULTICON));

    #ifndef __NOTURBOFOLDERS__
        if (cmnQuerySetting(sfTurboFolders))     // V1.0.1 (2002-12-14) [umoeller]
        {
            PMAKEAWAKEFS pFSData = (PMAKEAWAKEFS)ulReserved;

            // find the WPFileSystem method by skipping the
            // buggy WPDataFile implementation
            if (pwpRestoreState = (somTD_WPObject_wpRestoreState)wpshResolveFor(
                                         somSelf,
                                         _WPFileSystem,     // class to resolve for
                                         "wpRestoreState"))
            {
                // found it: then it's safe to run our replacement
                PMINIRECORDCORE prec = _wpQueryCoreRecord(somSelf);
                ULONG           flNewStyle = 0;
                // XFldDataFileData *somThis = XFldDataFileGetData(somSelf);

                PMPF_ICONREPLACEMENTS(("obj 0x%lX: pFSData is 0x%lX", somSelf, pFSData));

                if (    (!prec->hptrIcon)
                     && (pFSData)
                     && (pFSData->pFea2List)
                   )
                {
                    APIRET          arc;
                    HPOINTER        hptrNew;

                    if (!(arc = icoBuildPtrFromFEA2List(pFSData->pFea2List,
                                                        &hptrNew,
                                                        NULL,
                                                        NULL)))
                    {
                        _wpSetIcon(somSelf, hptrNew);

                        // set icon style below
                        // V0.9.18 (2002-03-24) [umoeller]
                        flNewStyle = OBJSTYLE_NOTDEFAULTICON;

                        PMPF_ICONREPLACEMENTS(("    custom prec->hptrIcon is 0x%lX", prec->hptrIcon));

                        // set our instance data flag so that we know that
                        // we should NEVER EVER use an association icon
                        // here... dumb WPS keeps looking for the
                        // OBJSTYLE_NOTDEFAULTICON and always assumes that
                        // if this is set, the data file uses an assoc
                        // icon, which is simply not true any more
                        // V0.9.18 (2002-03-19) [umoeller]
                        _xwpModifyFlags(somSelf,
                                        OBJFL_HASICONEA,
                                        OBJFL_HASICONEA);   // V1.0.1 (2003-01-25) [umoeller]
                    }
                }

                brc = pwpRestoreState(somSelf, ulReserved);

                // moved this down here because parent restore state
                // overwrites this sucker, and then we might have
                // an erroneous OBJSTYLE_NOTDEFAULTICON set that
                // causes icons to be freed during copy...
                // V0.9.18 (2002-03-24) [umoeller]
                // situation was this:
                // copy command file via ctrl-drag
                // 1) wpCopyObject first instantiates a new SOM object
                // 2) calls wpRestoreState (this one here) to
                //    set up the new object's instance data
                // 3) checks if the source object has a non-default icon;
                //    if so, it is copied again... unfortunately, if we
                //    had the OBJSTYLE_NOTDEFAULTICON bit set here,
                //    our standard icon was nuked!!
                // This only happened for files with .ICON EAs, where
                // first we set a standard icon (!) and then the parent
                // wpRestoreState set the OBJSTYLE_NOTDEFAULTICON flag --
                // not a good idea.

                // Long story: set the flag only below so it will be
                // correct when we come out of restore.
                _wpModifyStyle(somSelf,
                               OBJSTYLE_NOTDEFAULTICON,
                               flNewStyle);
            }
            else
                cmnLog(__FILE__, __LINE__, __FUNCTION__,
                       "Cannot resolve WPFileSystem::wpRestoreState.");
        }

        if (!pwpRestoreState)
    #endif
            brc = XFldDataFile_parent_WPDataFile_wpRestoreState(somSelf,
                                                                ulReserved);

        PMPF_ICONREPLACEMENTS(("post: hptr: 0x%lX, OBJSTYLE_NOTDEFAULTICON: %lX",
                _wpQueryCoreRecord(somSelf)->hptrIcon,
                _wpQueryStyle(somSelf) & OBJSTYLE_NOTDEFAULTICON));
    }
#ifdef __DEBUG__
    CATCH(dbgexc) {} END_CATCH();
#endif

    return brc;
}

/*
 *@@ wpSetDefaultView:
 *
 */

SOM_Scope BOOL  SOMLINK xdf_wpSetDefaultView(XFldDataFile *somSelf,
                                             ULONG ulView)
{
    BOOL brc;

    // XFldDataFileData *somThis = XFldDataFileGetData(somSelf);
    XFldDataFileMethodDebug("XFldDataFile","xdf_wpSetDefaultView");

#ifdef __DEBUG__
    TRY_LOUD(dbgexc)
#endif
    {
        PMPF_ASSOCS(("[%s] entering, hptr: 0x%lX, OBJSTYLE_NOTDEFAULTICON: %lX",
                _wpQueryTitle(somSelf),
                _wpQueryCoreRecord(somSelf)->hptrIcon,
                (_wpQueryStyle(somSelf) & OBJSTYLE_NOTDEFAULTICON)));

        brc = XFldDataFile_parent_WPDataFile_wpSetDefaultView(somSelf,
                                                              ulView);

        PMPF_ASSOCS(("[%s] leaving, hptr: 0x%lX, OBJSTYLE_NOTDEFAULTICON: %lX",
                _wpQueryTitle(somSelf),
                _wpQueryCoreRecord(somSelf)->hptrIcon,
                (_wpQueryStyle(somSelf) & OBJSTYLE_NOTDEFAULTICON)));
    }
#ifdef __DEBUG__
    CATCH(dbgexc) {} END_CATCH();
#endif

    return brc;
}

/*
 *@@ wpQueryIcon:
 *      this WPObject instance method returns the HPOINTER
 *      with the current icon of the object. For some WPS
 *      classes, icon loading is deferred until the first
 *      call to this method.
 *      See icons.c for an introduction.
 *
 *      With data files and all subclasses, this turns out
 *      to be a major mess. When being made awake, all
 *      data files initially receive a NULLHANDLE pointer.
 *      In WPDataFile::wpRestoreState, the WPS checks if
 *      the file-system data has an .ICON EA so this can
 *      be quickly set.
 *      Only in that case will the icon already be set
 *      when wpQueryIcon is called for the first time.
 *
 *      So I guess what is done here is the following:
 *
 *      --  If the icon has already been set (either in
 *          wpRestoreState or by a previous call to
 *          wpQueryIcon), return it.
 *
 *      --  If not, call wpSetIcon with the return value
 *          from wpQueryAssociatedProgram or, if no association
 *          exists, from wpclsQueryIcon of the file's class.
 *          Then return that new icon.
 *
 *          With V0.9.20, lazy icon loading was introduced.
 *          If enabled, in this case, we pass the object to
 *          the "lazy icons" thread to defer icon loading and
 *          only set a temporary default icon here.
 *
 *      Unfortunately the WPS always sets OBJSTYLE_NOTDEFAULTICON
 *      in here, which is not a good idea with our replacement
 *      associations.
 *
 *      Remarks for WPProgramFile:
 *
 *      --  WPProgramFile apparently overrides this method
 *          to call wpSetProgIcon directly. It also overrides
 *          wpSetAssociatedFileIcon to call wpSetProgIcon.
 *
 *      --  We thus "only" have to override XWPProgramFile::wpSetProgIcon
 *          to replace the executable icons. However, with V0.9.20
 *          we override XWPProgramFile::wpQueryIcon also to
 *          support lazy icons there too.
 *
 *      --  Since WPCommandFile is derived from WPProgramFile,
 *          this affects command files as well.
 *
 *      What a mess.
 *
 *@@added V0.9.16 (2001-12-08) [umoeller]
 */

SOM_Scope HPOINTER  SOMLINK xdf_wpQueryIcon(XFldDataFile *somSelf)
{
    BOOL        fCallDefault = TRUE;
    HPOINTER    hptrReturn = NULLHANDLE;

    /* XFldDataFileData *somThis = XFldDataFileGetData(somSelf); */
    XFldDataFileMethodDebug("XFldDataFile","xdf_wpQueryIcon");

#ifdef __DEBUG__
    TRY_LOUD(dbgexc)
#endif
    {
        PMPF_ICONREPLACEMENTS(("[%s] entering, hptr: 0x%lX, OBJSTYLE_NOTDEFAULTICON: %lX",
                _wpQueryTitle(somSelf),
                _wpQueryCoreRecord(somSelf)->hptrIcon,
                (_wpQueryStyle(somSelf) & OBJSTYLE_NOTDEFAULTICON)));

    #ifndef __NOTURBOFOLDERS__
        if (cmnQuerySetting(sfTurboFolders))     // V1.0.1 (2002-12-14) [umoeller]
        {
            PMINIRECORDCORE prec = _wpQueryCoreRecord(somSelf);

            fCallDefault = FALSE;       // V1.0.1 (2002-12-14) [umoeller]

            TRY_LOUD(excpt1)
            {
                // do we have an icon yet?
                // this is set if either
                // -- the icon was already set from an .ICON EA in wpRestoreState or
                // -- this is not the first call to wpQueryIcon
                if (!(hptrReturn = prec->hptrIcon))
                {
                    ULONG flNewStyle = 0;
                    // XFldDataFileData *somThis = XFldDataFileGetData(somSelf);
                    // first call, and icon wasn't set in wpRestoreState:
                    // be smart now...

                    // 1) if we're an icon or pointer file, load
                    //    the icon from there
                    //    @@todo this never gets called since WPIcon
                    //    overrides wpQueryIcon
                    if (objQueryFlags(somSelf) & OBJFL_WPICONORPOINTER) // V1.0.1 (2003-01-25) [umoeller]
                    {
                        CHAR szFilename[CCHMAXPATH];
                        _wpQueryFilename(somSelf, szFilename, TRUE);
                        if (!icoLoadICOFile(szFilename,
                                            &hptrReturn,
                                            NULL,
                                            NULL))
                            flNewStyle = OBJSTYLE_NOTDEFAULTICON;
                    }

                    // no need to do special checks for WPProgramFile
                    // because it overrides wpQueryIcon to call wpSetProgIcon
                    // instead

                    if (    (!hptrReturn)
                         && (!(hptrReturn = _wpQueryAssociatedFileIcon(somSelf)))
                       )
                    {
                        // no association found:
                        hptrReturn = _wpclsQueryIcon(_somGetClass(somSelf));
                        PMPF_ICONREPLACEMENTS(("    using class hptr: 0x%lX",
                                hptrReturn));
                    }

                    _wpSetIconHandle(somSelf, hptrReturn);
                    _wpSetIcon(somSelf, hptrReturn);
                    _wpModifyStyle(somSelf,
                                   OBJSTYLE_NOTDEFAULTICON,
                                   flNewStyle);
                }
            }
            CATCH(excpt1)
            {
            } END_CATCH();
        }

    #endif

        if (fCallDefault)
            hptrReturn = XFldDataFile_parent_WPDataFile_wpQueryIcon(somSelf);

        PMPF_ICONREPLACEMENTS(("[%s] leaving, hptr: 0x%lX, OBJSTYLE_NOTDEFAULTICON: %lX",
                _wpQueryTitle(somSelf),
                _wpQueryCoreRecord(somSelf)->hptrIcon,
                (_wpQueryStyle(somSelf) & OBJSTYLE_NOTDEFAULTICON)));
    }
#ifdef __DEBUG__
    CATCH(dbgexc) {} END_CATCH();
#endif

    PMPF_ASSOCS(("[%s] leaving",
            _wpQueryTitle(somSelf)));

    return hptrReturn;
}

/*
 *@@ wpQueryIconData:
 *      this WPObject instance method can be called to find out the
 *      object's icon data.
 *
 *      See XWPProgramFile::wpQueryIconData for more information.
 *
 *      We need to override this too to fully support our replacement
 *      extended association icons in the WPS. Up to V0.9.18, the "Icon"
 *      notebook page was severly broken for data files.
 *
 *@@added V0.9.18 (2002-03-19) [umoeller]
 */

SOM_Scope ULONG  SOMLINK xdf_wpQueryIconData(XFldDataFile *somSelf,
                                             PICONINFO pIconInfo)
{
    BOOL        fCallDefault = TRUE;
    ULONG       cbRequired = sizeof(ICONINFO);

    /* XFldDataFileData *somThis = XFldDataFileGetData(somSelf); */
    XFldDataFileMethodDebug("XFldDataFile","xdf_wpQueryIconData");

#ifdef __DEBUG__
    TRY_LOUD(dbgexc)
#endif
    {
    #ifndef __NOTURBOFOLDERS__
        // turbo folders enabled?
        if (cmnQuerySetting(sfTurboFolders))     // V1.0.1 (2002-12-14) [umoeller]
        {
            fCallDefault = FALSE;       // V1.0.1 (2002-12-14) [umoeller]

            TRY_LOUD(excpt1)
            {
                BOOL            fFound = FALSE;
                CHAR            szFilename[CCHMAXPATH];

                // FIRST of all, check if we have a non-default icon
                // from an .ICON EA... if so, this overrides anything else
                if (_wpQueryFilename(somSelf, szFilename, TRUE))
                    if (!icoBuildPtrFromEAs(szFilename,
                                            NULL,              // no HPOINTER
                                            &cbRequired,
                                            pIconInfo))        // can be NULL
                            // returns NO_ERROR only if we have an .ICON EA
                        fFound = TRUE;

                if (!fFound)
                {
                    // .ICON EA not found, or bad data:
                    // XFldDataFileData *somThis = XFldDataFileGetData(somSelf);

                    // if we're an icon or pointer file, support
                    // ICON_DATA format for compatibility
                    if (objQueryFlags(somSelf) & OBJFL_WPICONORPOINTER) // V1.0.1 (2003-01-25) [umoeller]
                    {
                        PBYTE pbData = NULL;
                        ULONG cbData;
                        if (pIconInfo)
                            pbData = (PBYTE)(pIconInfo + 1);

                        if (!icoLoadICOFile(szFilename,
                                            NULL,
                                            &cbData,
                                            pbData))     // can be NULL
                        {
                            cbRequired += cbData;

                            if (pIconInfo)
                            {
                                ZERO(pIconInfo);
                                pIconInfo->cb = cbRequired;
                                pIconInfo->fFormat = ICON_DATA;
                                pIconInfo->cbIconData = cbData;
                                pIconInfo->pIconData = pbData;
                            }

                            fFound = TRUE;
                        }
                    }

                    if (!fFound)
                    {
                        // not icon file, or format not supported:
                        // check if we have an association
                        ULONG ulView = _wpQueryDefaultView(somSelf);
                                    // should return 0x1000 unless the user
                                    // has changed the data file's default view
                        WPObject *pobjAssoc = ftypQueryAssociatedProgram(somSelf,
                                                                         &ulView,
                                                                         // do not use "plain text" as default,
                                                                         // this affects the icon:
                                                                         FALSE);
                                                // locks the object

                        if (pobjAssoc)
                        {
                            // call the assoc object's wpQueryIconData
                            cbRequired = _wpQueryIconData(pobjAssoc,
                                                          pIconInfo);

                            _wpUnlockObject(pobjAssoc);
                        }
                        else
                        {
                            // no assoc object:
                            // use class default
                            cbRequired = _wpclsQueryIconData(_somGetClass(somSelf),
                                                             pIconInfo);
                        }
                    }
                }
            }
            CATCH(excpt1)
            {
                cbRequired = 0;
            } END_CATCH();
        }
    #endif

        if (fCallDefault)
            cbRequired = XFldDataFile_parent_WPDataFile_wpQueryIconData(somSelf,
                                                                        pIconInfo);
    }
#ifdef __DEBUG__
    CATCH(dbgexc) {} END_CATCH();
#endif

    return cbRequired;
}

/*
 *@@ wpSetIconData:
 *      this WPObject method sets a new persistent icon for
 *      the object and stores the new icon permanently.
 *
 *      We need to override this for our icon replacements
 *      because the WPS will do evil things to our standard
 *      icons again.
 *
 *      Note that we only handle the ICON_CLEAR case here
 *      to reload the exe default icon. The other cases
 *      are handled by our XWPFileSystem::wpSetIconData
 *      override.
 *
 *@@added V0.9.18 (2002-03-19) [umoeller]
 *@@changed V1.0.0 (2002-09-12) [umoeller]: fixed missing _fHasIconEA adjustment
 */

SOM_Scope BOOL  SOMLINK xdf_wpSetIconData(XFldDataFile *somSelf,
                                          PICONINFO pIconInfo)
{
    BOOL    brc = FALSE;
    CHAR    szFilename[CCHMAXPATH];
    BOOL    fExt;

    // XFldDataFileData *somThis = XFldDataFileGetData(somSelf);
    XFldDataFileMethodDebug("XFldDataFile","xdf_wpSetIconData");

#ifdef __DEBUG__
    TRY_LOUD(dbgexc)
#endif
    {
    #ifndef __NOTURBOFOLDERS__
        // turbo folders enabled?
        if (cmnQuerySetting(sfTurboFolders))     // V1.0.1 (2002-12-14) [umoeller]
        {
            if (    (pIconInfo)
                 && (pIconInfo->fFormat == ICON_CLEAR)
                 && (_wpQueryFilename(somSelf, szFilename, TRUE))
               )
            {
                // this case is now overridden by XFldDataFile
                // and XWPProgramFile
                if (WinSetFileIcon(szFilename, pIconInfo))
                {
                    // clear private flag so that
                    // _wpSetAssociatedFileIcon works
                    _xwpModifyFlags(somSelf,
                                    OBJFL_HASICONEA,
                                    0);

                    // use default assoc icon
                    _wpSetAssociatedFileIcon(somSelf);
                    brc = TRUE;
                }
            }
        }
    #endif

        if (!brc)
        {
            // all other cases, or icon replacements disabled:
            // call parent, which will end up in XWPFileSystem
            // (WPProgramFile doesn't override this)
            if (XFldDataFile_parent_WPDataFile_wpSetIconData(somSelf,
                                                             pIconInfo))
            {
                // success:
                if (    (pIconInfo)
                     && (pIconInfo->fFormat != ICON_CLEAR)
                   )
                    _xwpModifyFlags(somSelf,
                                    OBJFL_HASICONEA,
                                    OBJFL_HASICONEA);

                brc = TRUE;
            }
        }
    }
#ifdef __DEBUG__
    CATCH(dbgexc) {} END_CATCH();
#endif

    return brc;
}

/*
 *@@ xwpPrepareInsertRecord:
 *      this new XFldObject instance method gets called from
 *      our XFldObject::wpCnrInsertObject override to set up
 *      the MINIRECORDCORE of an object just before the object
 *      actually gets inserted into a container.
 *
 *      See XFldObject::xwpPrepareInsertRecord for details.
 *
 *      We override this to enable owner-drawing for all
 *      data files that want to draw thumbnails.
 *
 *@@added V1.0.1 (2003-01-29) [umoeller]
 */

SOM_Scope PUSEITEM  SOMLINK xdf_xwpPrepareInsertRecord(XFldDataFile *somSelf,
                                                       HWND hwndCnr,
                                                       PMINIRECORDCORE pmrc,
                                                       ULONG flObjectStyle,
                                                       BOOL fFirstInsert)
{
    PUSEITEM pui;
    // XFldDataFileData *somThis = XFldDataFileGetData(somSelf);
    XFldDataFileMethodDebug("XFldDataFile","xdf_xwpPrepareInsertRecord");

    if (    (pui = XFldDataFile_parent_WPDataFile_xwpPrepareInsertRecord(somSelf,
                                                                         hwndCnr,
                                                                         pmrc,
                                                                         flObjectStyle,
                                                                         fFirstInsert))
         && (cmnQuerySetting(sflOwnerDrawIcons) & OWDRFL_LAZYLOADTHUMBNAIL)
         && (_xwpQueryFlags(somSelf) & OBJFL_OWNERDRAWTHUMBNAIL)
       )
        pmrc->flRecordAttr |= CRA_OWNERDRAW;

    return pui;
}

/*
 *@@ xwpOwnerDrawIcon:
 *      this new XFldObject instance method gets called from the
 *      XWorkplace container owner-draw routines if global
 *      settings are enabled that require XWorkplace to take
 *      over owner draw for specific objects _and_ if this object's
 *      MINIRECORDCORE.flRecordAttr has the CRA_OWNERDRAW bit set.
 *
 *      See XFldObject::xwpOwnerDrawIcon for details.
 *
 *@@added V1.0.1 (2003-01-29) [umoeller]
 */

SOM_Scope ULONG  SOMLINK xdf_xwpOwnerDrawIcon(XFldDataFile *somSelf,
                                              PMINIRECORDCORE pmrc,
                                              HPS hps,
                                              ULONG flOwnerDraw,
                                              PRECTL prcl)
{
    // XFldDataFileData *somThis = XFldDataFileGetData(somSelf);
    XFldDataFileMethodDebug("XFldDataFile","xdf_xwpOwnerDrawIcon");

    if (    (flOwnerDraw & OWDRFL_LAZYLOADTHUMBNAIL)
         && (_xwpQueryFlags(somSelf) & OBJFL_OWNERDRAWTHUMBNAIL)
       )
    {
        HBITMAP hbmThumbnail = _xwpQueryThumbnail(somSelf);

        if (hbmThumbnail != -1)       // no error previously?
        {
            // return flags: preserve the OWDRFL_RGBMODE from input
            ULONG       flReturn = (flOwnerDraw & OWDRFL_RGBMODE);

            if (hbmThumbnail)
            {
                // thumbnail already loaded in xwpLazyLoadIcon:
                WinDrawBitmap(hps,
                              hbmThumbnail,
                              NULL,
                              (PPOINTL)prcl,
                              0,
                              0,
                              DBM_STRETCH);
            }
            else
            {
                if (!(flOwnerDraw & OWDRFL_RGBMODE))
                {
                    gpihSwitchToRGB(hps);
                    flReturn |= OWDRFL_RGBMODE;
                }

                WinFillRect(hps,
                            prcl,
                            RGBCOL_RED);

                flReturn |= OWDRFL_LAZYLOADTHUMBNAIL;
            }

            return flReturn;

        } // if (hbmThumbnail != -1)       // no error previously?
    }

    return XFldDataFile_parent_WPDataFile_xwpOwnerDrawIcon(somSelf,
                                                           pmrc,
                                                           hps,
                                                           flOwnerDraw,
                                                           prcl);
}

/*
 *@@ xwpLazyLoadIcon:
 *      this new XFldObject instance method gets called on
 *      the lazy icon thread if XFldObject::xwpOwnerDrawIcon
 *      returned the OWDRFL_LAZYLOADICON bit set. This must
 *      then load the icon of the object and invalidate the
 *      object in all containers where it is currently
 *      inserted.
 *
 *      We override this for thumbnail support.
 *
 *@@added V1.0.1 (2003-01-29) [umoeller]
 */

SOM_Scope void  SOMLINK xdf_xwpLazyLoadIcon(XFldDataFile *somSelf,
                                            ULONG flOwnerDraw,
                                            BOOL* pbQuitEarly)
{
    HBITMAP hbmThumbnail = NULLHANDLE;

    // XFldDataFileData *somThis = XFldDataFileGetData(somSelf);
    XFldDataFileMethodDebug("XFldDataFile","xdf_xwpLazyLoadIcon");

    if (    (flOwnerDraw & OWDRFL_LAZYLOADTHUMBNAIL)
         && (_xwpQueryFlags(somSelf) & OBJFL_OWNERDRAWTHUMBNAIL)
       )
    {
        // check that thumbnail is not loaded yet and no
        // error occurred (hbmThumbnail is -1 then)
        if (!(hbmThumbnail = _xwpQueryThumbnail(somSelf)))
        {
            BOOL    fLocked = FALSE;

            // set error flag for now
            hbmThumbnail = -1;

            TRY_LOUD(excpt1)
            {
                if (fLocked = !_xwpRequestContentMutexSem(somSelf, 2000))
                    // if this fails, make sure we set a -1 handle,
                    // or we'll keep looping in here!
                    if (!(hbmThumbnail = _xwpLazyLoadThumbnail(somSelf,
                                                               80,
                                                               80,
                                                               pbQuitEarly)))
                        hbmThumbnail = -1;
                    // if the method returns -1 itself, that's fine too
            }
            CATCH(excpt1)
            {
                hbmThumbnail = -1;
            } END_CATCH();

            if (fLocked)
                _xwpReleaseContentMutexSem(somSelf);

            _xwpSetThumbnail(somSelf, hbmThumbnail);
                    // this repaints the object
        }
    }

    if (    (!hbmThumbnail)
         || (hbmThumbnail == -1)
       )
        XFldDataFile_parent_WPDataFile_xwpLazyLoadIcon(somSelf,
                                                       flOwnerDraw,
                                                       pbQuitEarly);
}

/*
 *@@ wpQueryAssociatedProgram:
 *      this method returns the associated WPProgram or
 *      WPProgramFile object for the specified view ID of
 *      a data file.
 *
 *      The WPS docs say that this should be overridden
 *      to introduce new association mechanisms.
 *
 *      Yeah, right. Per default, this gets called from
 *      XFldDataFile::wpQueryAssociatedFileIcon -- that
 *      is, only while a folder is being populated, but
 *      _not_ when a context menu is opened. There seems
 *      to be a second association mechanism in wpModifyPopupMenu
 *      somewhere to add all the associated programs to
 *      the "Open" submenu. I have tested this by returning
 *      NULL in this method, and all the program objects
 *      still appear in the "Open" menu -- it's just the
 *      data file icons which get set to the default icon
 *      then.
 *
 *      Soooo... to give the data files new icons, we need
 *      to override this method since it gets called from
 *      wpQueryAssociatedFileIcon (which normally gets called
 *      during folder populate).
 *
 *      See XFldDataFile::wpQueryIcon for an introduction
 *      to the data file icon mess.
 *
 *      From what I see, ulView is normally 0x1000, which
 *      is the WPS-internal code for the first associated
 *      program. This is only > 1000 if the default
 *      association has been changed on the "Menu" page
 *      of a data file (1001 for the second assoc, 1002
 *      for the third, etc.).
 *
 *      However, this also needs to support OPEN_RUNNING
 *      and OPEN_DEFAULT.
 *
 *      This returns NULL if there's no associated program
 *      for the specified view. Otherwise it returns a
 *      WPProgram or WPProgramFile, which has been locked
 *      once.
 *
 *      The caller should unlock the object after it's
 *      done using it. AFAIK, WPS wpQueryAssociatedFileIcon
 *      does this.
 *
 *@@added V0.9.0 [umoeller]
 */

SOM_Scope WPObject*  SOMLINK xdf_wpQueryAssociatedProgram(XFldDataFile *somSelf,
                                                          ULONG ulView,
                                                          PULONG pulHowMatched,
                                                          PSZ pszMatchString,
                                                          ULONG cbMatchString,
                                                          PSZ pszDefaultType)
{
    WPObject* pobj = 0;

    /* XFldDataFileData *somThis = XFldDataFileGetData(somSelf); */
    // XFldDataFileMethodDebug("XFldDataFile","xdf_wpQueryAssociatedProgram");

#ifdef __DEBUG__
    TRY_LOUD(dbgexc)
#endif
    {
        PMPF_ASSOCS(("[%s] entering; ulView = %lX, "
                   "*pulHowMatched = 0x%lX, "
                   "pszMatchString = %s, pszDefaultType = %s",
                   _wpQueryTitle(somSelf),
                   ulView,
                   (    (pulHowMatched)
                                ? (*pulHowMatched)
                                : 0
                   ),
                   pszMatchString, pszDefaultType
                   ));

    #ifndef __NOTURBOFOLDERS__
        if (cmnQuerySetting(sfTurboFolders))        // V1.0.1 (2002-12-15) [umoeller]
        {
            // "extended associations" allowed:
            // use our replacement mechanism...
            // this does NOT use "plain text" as the default
            ULONG   ulView2 = ulView;
            pobj = ftypQueryAssociatedProgram(somSelf,
                                              &ulView2,
                                              // do not use "plain text" as default,
                                              // this affects the icon:
                                              FALSE);
                            // locks the object
        }
        else
    #endif
            pobj = XFldDataFile_parent_WPDataFile_wpQueryAssociatedProgram(somSelf,
                                                                           ulView,
                                                                           pulHowMatched,
                                                                           pszMatchString,
                                                                           cbMatchString,
                                                                           pszDefaultType);

        PMPF_ASSOCS(("[%s] leaving", _wpQueryTitle(somSelf)));
    }
#ifdef __DEBUG__
    CATCH(dbgexc) {} END_CATCH();
#endif

    return pobj;
}

/*
 *@@ wpQueryAssociatedFileIcon:
 *      this WPDataFile method should return the icon of
 *      the program that the data file is associated with
 *      or NULLHANDLE if we can't find an association.
 *
 *      This gets called on the first call to wpQueryIcon,
 *      even if turbo folders are not enabled.
 *
 *      See XFldDataFile::wpQueryIcon for an introduction
 *      to the data file icon mess.
 *
 *      We override this for speed to call
 *      ftypQueryAssociatedProgram directly.
 *
 *@@added V0.9.16 (2002-01-26) [umoeller]
 *@@changed V0.9.18 (2002-02-06) [umoeller]: fixed broken icons in PMMail
 *@@changed V0.9.20 (2002-07-25) [umoeller]: now using XFldObject::xwpShareIcon
 */

SOM_Scope HPOINTER  SOMLINK xdf_wpQueryAssociatedFileIcon(XFldDataFile *somSelf)
{
    HPOINTER    hptrReturn = NULLHANDLE;
    BOOL        fCallDefault = TRUE;

    /* XFldDataFileData *somThis = XFldDataFileGetData(somSelf); */
    XFldDataFileMethodDebug("XFldDataFile","xdf_wpQueryAssociatedFileIcon");

#ifdef __DEBUG__
    TRY_LOUD(dbgexc)
#endif
    {
        PMPF_ASSOCS(("[%s] entering",
                _wpQueryTitle(somSelf)));

    #ifndef __NOTURBOFOLDERS__
        if (cmnQuerySetting(sfTurboFolders))        // V1.0.1 (2002-12-15) [umoeller]
        {
            fCallDefault = FALSE;

            TRY_LOUD(excpt1)
            {
                ULONG ulView = _wpQueryDefaultView(somSelf);
                            // should return 0x1000 unless the user
                            // has changed the data file's default view

                WPObject *pobjAssoc;

                PMPF_ASSOCS(("   getting associated program for default view 0x%lX", ulView));

                if (pobjAssoc = ftypQueryAssociatedProgram(somSelf,
                                                           &ulView,
                                                           // do not use "plain text" as default,
                                                           // this affects the icon:
                                                           FALSE))
                        // locks the object
                {
                    PMPF_ASSOCS(("   got associated program [%s]", _wpQueryTitle(pobjAssoc)));

                    // get the assoc icon
                    // V0.9.20 (2002-07-25) [umoeller]
                    // now using the new icon sharing mechanism!
                    hptrReturn = icomShareIcon(pobjAssoc,
                                               somSelf,
                                               TRUE);         // make global

                    // we have locked the object twice now (once in
                    // ftypQueryAssociatedProgram, once in icomShareIcon),
                    // so unlock once now
                    _wpUnlockObject(pobjAssoc);
                }
            }
            CATCH(excpt1)
            {
            } END_CATCH();

            PMPF_ASSOCS(("done, returning 0x%lX",
                         hptrReturn));
        }
    #endif

        if (fCallDefault)
            hptrReturn = XFldDataFile_parent_WPDataFile_wpQueryAssociatedFileIcon(somSelf);
    }
#ifdef __DEBUG__
    CATCH(dbgexc) {} END_CATCH();
#endif

    return hptrReturn;
}

/*
 *@@ wpSetAssociatedFileIcon:
 *      this method gets called by the WPS when a data
 *      file object is being initialized, to have it
 *      set its icon to that of the default association.
 *
 *      This gets called from various places in the WPS
 *      whenever data file attributes change so that
 *      the association might have changed. Note that
 *      WPDataFile::wpQueryIcon does _not_ call this,
 *      but wpQueryAssociatedFileIcon instead.
 *
 *      The problem with this method is that it appears
 *      to check internally for the OBJSTYLE_NOTDEFAULTICON
 *      flag, which is rarely set any more since we
 *      share the association icons with the executables.
 *
 *      Since WPProgramFile overrides this method (but not
 *      wpQueryAssociatedFileIcon), this never gets called
 *      for program files.
 *
 *      See XFldDataFile::wpQueryIcon for an introduction
 *      to the data file icon mess.
 *
 *@@added V0.9.18 (2002-03-19) [umoeller]
 */

SOM_Scope void  SOMLINK xdf_wpSetAssociatedFileIcon(XFldDataFile *somSelf)
{
    BOOL        fCallDefault = TRUE;

    XFldDataFileMethodDebug("XFldDataFile","xdf_wpSetAssociatedFileIcon");

#ifdef __DEBUG__
    TRY_LOUD(dbgexc)
#endif
    {
    #ifndef __NOTURBOFOLDERS__
        // only call the parent if we don't have an .ICON EA,
        // otherwise do nothing
        // V0.9.18 (2002-03-19) [umoeller]
        if (cmnQuerySetting(sfTurboFolders))    // V1.0.1 (2002-12-15) [umoeller]
        {
            // XFldDataFileData *somThis = XFldDataFileGetData(somSelf);
            ULONG   flObject = _xwpQueryFlags(somSelf);

            fCallDefault = FALSE;

            if (!(flObject & OBJFL_HASICONEA))
            {
                // for WPIcon and WPPointer, we want no association icons
                // (_wpQueryIcon loads the icon then)
                if (!(flObject & OBJFL_WPICONORPOINTER)) // V1.0.1 (2003-01-25) [umoeller]
                {
                    HPOINTER hptr;

                    if (!(hptr = _wpQueryAssociatedFileIcon(somSelf)))
                        // use class icon then
                        hptr = _wpclsQueryIcon(_somGetClass(somSelf));

                    if (hptr)
                    {
                        _wpSetIcon(somSelf, hptr);

                        // make sure this is turned off!!!
                        _wpModifyStyle(somSelf,
                                       OBJSTYLE_NOTDEFAULTICON,
                                       0);
                    }
                }
            }
        }
    #endif

        if (fCallDefault)
            XFldDataFile_parent_WPDataFile_wpSetAssociatedFileIcon(somSelf);
    }
#ifdef __DEBUG__
    CATCH(dbgexc) {} END_CATCH();
#endif
}

/*
 *@@ wpFilterPopupMenu:
 *      this WPObject instance method allows the object to
 *      filter out unwanted menu items from the context menu.
 *      This gets called before wpModifyPopupMenu.
 *
 *      We remove default entries according to Global Settings;
 *      even though XFldObject does this already, we need to
 *      override this for XFldDataFile again, because the
 *      WPS does it too for WPDataFile.
 *
 *      Also we need to do some fiddling with the "Open"
 *      submenu for the extended associations mechanism.
 *
 *@@changed V0.9.19 (2002-04-17) [umoeller]: adjusted for new menu handling
 */

SOM_Scope ULONG  SOMLINK xdf_wpFilterPopupMenu(XFldDataFile *somSelf,
                                               ULONG ulFlags,
                                               HWND hwndCnr,
                                               BOOL fMultiSelect)
{
    ULONG ulMenuFilter = 0;
    /* XFldDataFileData *somThis = XFldDataFileGetData(somSelf); */
    XFldDataFileMethodDebug("XFldDataFile","xdf_wpFilterPopupMenu");

    ulMenuFilter = XFldDataFile_parent_WPDataFile_wpFilterPopupMenu(somSelf,
                                                                    ulFlags,
                                                                    hwndCnr,
                                                                    fMultiSelect);

    PMPF_MENUS(("flags %08X, parent flags: %08X, ", ulFlags, ulMenuFilter));
    // now suppress default menu items according to
    // Global Settings;
    // the DefaultMenuItems field in pGlobalSettings is
    // ready-made for this function; the "Workplace Shell"
    // notebook page for removing menu items sets this field with
    // the proper CTXT_xxx flags
    ulMenuFilter &= ~(cmnQuerySetting(mnuQueryMenuWPSSetting(somSelf)));

    return ulMenuFilter;
}

/*
 *@@ wpModifyMenu:
 *      this WPObject instance method was new with Warp 4 and
 *      allows the object to manipulate its menu in a more
 *      fine-grained way than wpModifyPopupMenu.
 *
 *      With V1.0.0, while adding support for the split view
 *      to the menu methods, I finally got tired of all the
 *      send-msg hacks to get Warp 4 menu items to work and
 *      decided to finally break Warp 3 support for XWorkplace.
 *      It's been fun while it lasted, but enough is enough.
 *      We are now overriding this method directly through
 *      the IDL files.
 *
 *      ulMenuType will be one of the following:
 *
 *      --  MENU_OBJECTPOPUP: Pop-up menu for the object icon.
 *          This can come in for any object.
 *
 *      --  MENU_OPENVIEWPOPUP: Pop-up menu for an open view.
 *          I think this can reasonably only come in for folders,
 *          although it seems to be handled by the WPObject method.
 *
 *      --  MENU_FOLDERPULLDOWN: Pull-down menu for a folder.
 *          This comes in for folders only.
 *
 *      --  MENU_EDITPULLDOWN: Pull-down menu for the Edit menu option.
 *          This comes in TWICE, first on the selected object in
 *          the view's container (if any) with ulView == CLOSED_ICON,
 *          and then a second time on the view's folder with ulView
 *          set to the folder's current view.
 *
 *      --  MENU_VIEWPULLDOWN: Pull-down menu for the View menu option.
 *          This comes in for folders only.
 *
 *      --  MENU_SELECTEDPULLDOWN: Pull-down menu for the Selected menu option.
 *          This comes in for non-folder objects also to let the object
 *          decide what options it wants to present in the folder's
 *          "Selected" pulldown.
 *
 *      --  MENU_HELPPULLDOWN: Pull-down menu for the Help menu option.
 *          This comes in for folders only.
 *
 *      --  MENU_TITLEBARPULLDOWN: this is listed in the toolkit headers,
 *          but not described in WPSREF. I think this is what comes in
 *          if the system menu is being built for an open object view.
 *
 *@@added V1.0.0 (2002-08-31) [umoeller]
 */

SOM_Scope BOOL  SOMLINK xdf_wpModifyMenu(XFldDataFile *somSelf,
                                         HWND hwndMenu,
                                         HWND hwndCnr,
                                         ULONG iPosition,
                                         ULONG ulMenuType,
                                         ULONG ulView,
                                         ULONG ulReserved)
{
    BOOL    brc;

    // XFldDataFileData *somThis = XFldDataFileGetData(somSelf);
    XFldDataFileMethodDebug("XFldDataFile","xdf_wpModifyMenu");

#ifdef __DEBUG__
    TRY_LOUD(dbgexc)
#endif
    {
        if (brc = XFldDataFile_parent_WPDataFile_wpModifyMenu(somSelf,
                                                              hwndMenu,
                                                              hwndCnr,
                                                              iPosition,
                                                              ulMenuType,
                                                              ulView,
                                                              ulReserved))
        {
            PMPF_MENUS(("[%s]",
                        _wpQueryTitle(somSelf)));
            PMPF_MENUS(("   type = 0x%lX (%s), view = 0x%lX (%s)",
                        ulMenuType,
                        (ulMenuType == MENU_OBJECTPOPUP) ? "MENU_OBJECTPOPUP"
                        : (ulMenuType == MENU_OPENVIEWPOPUP) ? "MENU_OPENVIEWPOPUP"
                        : (ulMenuType == MENU_TITLEBARPULLDOWN) ? "MENU_TITLEBARPULLDOWN"
                        : (ulMenuType == MENU_TITLEBARPULLDOWNINT) ? "MENU_TITLEBARPULLDOWNINT"
                        : (ulMenuType == MENU_FOLDERPULLDOWN) ? "MENU_FOLDERPULLDOWN"
                        : (ulMenuType == MENU_VIEWPULLDOWN) ? "MENU_VIEWPULLDOWN"
                        : (ulMenuType == MENU_HELPPULLDOWN) ? "MENU_HELPPULLDOWN"
                        : (ulMenuType == MENU_EDITPULLDOWN) ? "MENU_EDITPULLDOWN"
                        : (ulMenuType == MENU_SELECTEDPULLDOWN) ? "MENU_SELECTEDPULLDOWN"
                        : (ulMenuType == MENU_FOLDERMENUBAR) ? "MENU_FOLDERMENUBAR"
                        : (ulMenuType == MENU_USER) ? "MENU_USER"
                        : "unknown",
                        ulView,
                        cmnIdentifyView(ulView)
                        ));

            // now check which type of menu we have
            switch (ulMenuType)
            {
                case MENU_OPENVIEWPOPUP:
                case MENU_TITLEBARPULLDOWN:
                case MENU_OBJECTPOPUP:
                case MENU_SELECTEDPULLDOWN:

                    mnuModifyDataFilePopupMenu(somSelf,
                                               hwndMenu,
                                               hwndCnr);

    #ifndef __NOTURBOFOLDERS__
                    if (cmnQuerySetting(sfTurboFolders))    // V1.0.1 (2002-12-15) [umoeller]
                    {
                        // extended assocs have been enabled:
                        // this means we need to manually tweak some of the data file
                        // settings, as WPDataFile would normally do it...
                        MENUITEM        mi;

                        // find "Open" submenu
                        if (WinSendMsg(hwndMenu,
                                       MM_QUERYITEM,
                                       MPFROM2SHORT(WPMENUID_OPEN, TRUE),
                                       (MPARAM)&mi))
                        {
                            // found:

                            // check for program files hack
                            LONG    lDefaultView = _wpQueryDefaultView(somSelf);

                            if (    (lDefaultView == OPEN_RUNNING)
                                 && (!progIsProgramOrProgramFile(somSelf))
                               )
                            {
                                // this is not a program file,
                                // but this doesn't have its default view set yet:
                                // set it then
                                _wpSetDefaultView(somSelf, 0x1000);
                                lDefaultView = 0x1000;
                            }
                            // but skip program files with OPEN_RUNNING

                            ftypModifyDataFileOpenSubmenu(somSelf,
                                                          mi.hwndSubMenu);
                        }
                    }
    #endif
                break;
            }

            fdrAddHotkeysToMenu(somSelf,
                                hwndCnr,
                                hwndMenu,
                                ulMenuType);
        }
    }
#ifdef __DEBUG__
    CATCH(dbgexc) {} END_CATCH();
#endif

    return brc;
}

/*
 *@@ wpMenuItemHelpSelected:
 *      display help for a context menu item.
 */

SOM_Scope BOOL  SOMLINK xdf_wpMenuItemHelpSelected(XFldDataFile *somSelf,
                                                   ULONG MenuId)
{
    /* XFldDataFileData *somThis = XFldDataFileGetData(somSelf); */
    XFldDataFileMethodDebug("XFldDataFile","xdf_wpMenuItemHelpSelected");

    // call the common help processor in fdrmenus.c;
    if (fcmdMenuItemHelpSelected(somSelf, MenuId))
        // if this returns TRUE, help was requested for one
        // of the new menu items
        return TRUE;

    // else: none of our menu items, call default
    return XFldDataFile_parent_WPDataFile_wpMenuItemHelpSelected(somSelf,
                                                                 MenuId);
}

/*
 *@@ wpOpen:
 *      this WPObject instance method gets called when
 *      a new view needs to be opened. Normally, this
 *      gets called after wpViewObject has scanned the
 *      object's USEITEMs and has determined that a new
 *      view is needed.
 *
 *      This _normally_ runs on thread 1 of the WPS, but
 *      this is not always the case. If this gets called
 *      in response to a menu selection from the "Open"
 *      submenu or a double-click in the folder, this runs
 *      on the thread of the folder (which _normally_ is
 *      thread 1). However, if this results from WinOpenObject
 *      or an OPEN setup string, this will not be on thread 1.
 *
 *      Of course, for data files, the "views" are the
 *      various associations in the "Open" submenu, which
 *      have ulView IDs >= 0x1000. If the default view
 *      has been manually set for the object, wpOpen
 *      always receives this ID.
 *
 *      By contrast, we can also get OPEN_RUNNING or
 *      OPEN_DEFAULT. I think OPEN_RUNNING comes in
 *      for "standard" data files which have been
 *      double-clicked on.
 *
 *      There are two more problems with starting the
 *      associated program (damn it, IBM, do you ever
 *      read the specs that you've written yourself?):
 *
 *      --  The WPS always uses its internal list of
 *          associations, no matter what we return from
 *          XFldDataFile::wpQueryAssociatedProgram, so
 *          we need to override this method as well and
 *          intercept the new menu items that we have changed.
 *
 *      --  We cannot use the WPProgram/WPProgramFile classes
 *          to start the associated programs. These things do
 *          not accept parameters, and of course there's no
 *          export for resolving all the parameter placeholders.
 *          So we need to start the program ourselves with
 *          the data file as the parameter, using progOpenProgram.
 *
 *@@added V0.9.6 (2000-10-16) [umoeller]
 *@@changed V1.0.5 (2006-05-14) [pr]: Call parent if Ext. Assocs. enabled and no. assoc. found @@fixes 14
 */

SOM_Scope HWND  SOMLINK xdf_wpOpen(XFldDataFile *somSelf,
                                   HWND hwndCnr,
                                   ULONG ulView,
                                   ULONG param)
{
    HWND        hwnd = NULLHANDLE;
    BOOL        fCallParent = TRUE;
    ULONG       ulView2 = ulView;
    WPObject    *pAssocObject;
    /* XFldDataFileData *somThis = XFldDataFileGetData(somSelf); */
    XFldDataFileMethodDebug("XFldDataFile","xdf_wpOpen");

#ifdef __DEBUG__
    TRY_LOUD(dbgexc)
#endif
    {
        PMPF_ASSOCS(("[%s] entering, ulView: 0x%lX", _wpQueryTitle(somSelf), ulView));

        /*
         *      Hmm, problem with WPIcon if both turbo folders
         *      and ext assocs are off: when you double-click on
         *      an ICO file, the icon changes to the association
         *      icon...
         *
         *      Call flow seems like this:
         *
         *      --  parent wpOpen calls wpQueryAssociatedProgram
         *
         *      --  wpQueryAssociatedProgram (our replacement)
         *          calls parent since ext assocs are disabled
         *
         *      --  parent wpQueryAssociatedProgram
         */


    #ifndef __NOTURBOFOLDERS__
        if (cmnQuerySetting(sfTurboFolders))    // V1.0.1 (2002-12-15) [umoeller]
        {
            // "extended associations" allowed:
            if (    ((ulView >= 0x1000) && (ulView < 0x1100))
                 || (ulView == OPEN_RUNNING)    // double-click on data file
                 || (ulView == OPEN_DEFAULT)
               )
                // use our replacement mechanism
                fCallParent = FALSE;
        }

        // V1.0.5 (2006-05-14) [pr]: Rejigged this to call the parent if no assoc. found
        if (!fCallParent)
        {
            // replacement desired:
            pAssocObject = ftypQueryAssociatedProgram(somSelf,
                                                      &ulView2,
                                                      // use "plain text" as default:
                                                      TRUE);
                                                         // we've used "plain text" as default
                                                         // in wpModifyMenu, so we need to do
                                                         // the same again here
                                // object is locked now

            if (!pAssocObject)
                fCallParent = TRUE;
        }

        if (!fCallParent)
        {
            CHAR szFailing[CCHMAXPATH];
            APIRET arc;

            if (arc = progOpenProgram(pAssocObject,
                                      somSelf,
                                      ulView2,
                                      &hwnd,
                                      sizeof(szFailing),
                                      szFailing))
            {
                if (cmnProgramErrorMsgBox(NULLHANDLE,
                                          pAssocObject,
                                          szFailing,
                                          arc)
                            == MBID_YES)
                    krnPostThread1ObjectMsg(T1M_OPENOBJECTFROMPTR,
                                            (MPARAM)pAssocObject,
                                            (MPARAM)OPEN_SETTINGS);
            }
                    // _wpUnlockObject(pAssocObject);
                    // do not unlock the assoc object...
                    // this is still needed in the use list!!!
        }
        else
    #endif
            hwnd = XFldDataFile_parent_WPDataFile_wpOpen(somSelf,
                                                         hwndCnr,
                                                         ulView,
                                                         param);

        PMPF_ASSOCS(("[%s] returning hwnd 0x%lX", _wpQueryTitle(somSelf), hwnd));
    }
#ifdef __DEBUG__
    CATCH(dbgexc) {} END_CATCH();
#endif

    return hwnd;

}

/*
 *@@ wpAddFile1Page:
 *      this WPFileSystem method normally adds the first
 *      "File" page to the file's settings notebook; since we
 *      combine the three "File" pages into one,
 *      we'll remove this page, if allowed.
 *
 *      We cannot override this in XWPFileSystem because
 *      WPFolder overrides this too.
 *
 *@@added V0.9.0
 */

SOM_Scope ULONG  SOMLINK xdf_wpAddFile1Page(XFldDataFile *somSelf,
                                            HWND hwndNotebook)
{
    // XFldDataFileData *somThis = XFldDataFileGetData(somSelf);
    XFldDataFileMethodDebug("XFldDataFile","xdf_wpAddFile1Page");

#ifndef __ALWAYSREPLACEFILEPAGE__
    if (cmnQuerySetting(sfReplaceFilePage))
    {
#endif
        return fsysInsertFilePages(somSelf,
                                   hwndNotebook);
#ifndef __ALWAYSREPLACEFILEPAGE__
    }

    return XFldDataFile_parent_WPDataFile_wpAddFile1Page(somSelf,
                                                         hwndNotebook);
#endif
}

/*
 *@@ wpAddFile2Page:
 *      this WPFileSystem method normally adds the second
 *      "File" page to the file's settings notebook; since we
 *      combine the three "File" pages into one,
 *      we'll remove this page, if allowed.
 *
 *      We cannot override this in XWPFileSystem because
 *      WPFolder overrides this too.
 *
 *@@added V0.9.0
 */

SOM_Scope ULONG  SOMLINK xdf_wpAddFile2Page(XFldDataFile *somSelf,
                                            HWND hwndNotebook)
{
    // XFldDataFileData *somThis = XFldDataFileGetData(somSelf);
    XFldDataFileMethodDebug("XFldDataFile","xdf_wpAddFile2Page");

#ifndef __ALWAYSREPLACEFILEPAGE__
    if (cmnQuerySetting(sfReplaceFilePage))
#endif
        return SETTINGS_PAGE_REMOVED;

#ifndef __ALWAYSREPLACEFILEPAGE__
    return XFldDataFile_parent_WPDataFile_wpAddFile2Page(somSelf,
                                                         hwndNotebook);
#endif
}

/*
 *@@ wpAddFile3Page:
 *      this WPFileSystem method normally adds the third
 *      "File" page to the file's settings notebook; since we
 *      combine the three "File" pages into one,
 *      we'll remove this page, if allowed.
 *
 *      We cannot override this in XWPFileSystem because
 *      WPFolder overrides this too.
 *
 *@@added V0.9.0
 */

SOM_Scope ULONG  SOMLINK xdf_wpAddFile3Page(XFldDataFile *somSelf,
                                            HWND hwndNotebook)
{
    // XFldDataFileData *somThis = XFldDataFileGetData(somSelf);
    XFldDataFileMethodDebug("XFldDataFile","xdf_wpAddFile3Page");

#ifndef __ALWAYSREPLACEFILEPAGE__
    if (cmnQuerySetting(sfReplaceFilePage))
#endif
        return SETTINGS_PAGE_REMOVED;

#ifndef __ALWAYSREPLACEFILEPAGE__
    return XFldDataFile_parent_WPDataFile_wpAddFile3Page(somSelf,
                                                         hwndNotebook);
#endif
}

/*
 *@@ wpAddFileTypePage:
 *      this WPDataFile method normally adds the "Type"
 *      page to a data file's settings notebook.
 *
 *      If extended associations are enabled, we replace
 *      this with our own version to allow the user to
 *      view the automatic and explicit types separately.
 *
 *@@added V0.9.9 (2001-03-27) [umoeller]
 */

SOM_Scope ULONG  SOMLINK xdf_wpAddFileTypePage(XFldDataFile *somSelf,
                                               HWND hwndNotebook)
{
    /* XFldDataFileData *somThis = XFldDataFileGetData(somSelf); */
    XFldDataFileMethodDebug("XFldDataFile","xdf_wpAddFileTypePage");

#ifndef __NOTURBOFOLDERS__
    if (cmnQuerySetting(sfTurboFolders))    // V1.0.1 (2002-12-15) [umoeller]
    {
        INSERTNOTEBOOKPAGE inbp;
        memset(&inbp, 0, sizeof(INSERTNOTEBOOKPAGE));
        inbp.somSelf = somSelf;
        inbp.hwndNotebook = hwndNotebook;
        inbp.hmod = cmnQueryNLSModuleHandle(FALSE);
        inbp.ulDlgID = ID_XSD_DATAF_TYPES;
        inbp.ulPageID = SP_DATAFILE_TYPES;
        inbp.pampControlFlags = G_pampDatafileTypesPage;
        inbp.cControlFlags = G_cDatafileTypesPage;
        inbp.usPageStyleFlags = BKA_MAJOR;
        inbp.pcszName = cmnGetString(ID_XSSI_FILETYPESPAGE);  // pszFileTypesPage
        inbp.ulDefaultHelpPanel  = ID_XSH_DATAFILE_TYPES;
        inbp.pfncbInitPage    = ftypDatafileTypesInitPage;
        inbp.pfncbItemChanged = ftypDatafileTypesItemChanged;

        return ntbInsertPage(&inbp);
    }
#endif

    return XFldDataFile_parent_WPDataFile_wpAddFileTypePage(somSelf,
                                                            hwndNotebook);
}

/*
 *@@ wpSetRealName:
 *      this WPFileSystem instance method sets the real name
 *      for the object.
 *
 *      This code normally only gets called by WPS-internal
 *      implementations to update the internal representation
 *      of the file. WPFileSystem::wpSetRealName actually
 *      renames the file on disk.
 *
 *      See XWPFileSystem::wpSetRealName for details.
 *
 *      The WPDataFile parent method attempts to update
 *      the object's associated icon in all good intentions,
 *      but this won't work. See
 *      XFldDataFile::wpSetTitleAndRenameFile for a lengthy
 *      explanation. So we skip that parent implementation
 *      here and call the XWPFileSystem implementation directly.
 *
 *@@added V0.9.19 (2002-04-17) [umoeller]
 *@@changed V1.0.1 (2003-01-27) [umoeller]: rewritten
 */

SOM_Scope BOOL  SOMLINK xdf_wpSetRealName(XFldDataFile *somSelf,
                                          PSZ pszName)
{
    // XFldDataFileData *somThis = XFldDataFileGetData(somSelf);
    XFldDataFileMethodDebug("XFldDataFile","xdf_wpSetRealName");

#ifndef __NOTURBOFOLDERS__
    if (cmnQuerySetting(sfTurboFolders))
        // call this new XWPFileSystem method, which calls
        // the real _wpSetRealName, skipping the WPDataFile
        // implementation
        return _xwpSetRealNameNoOverride(somSelf, pszName);
#endif

    return XFldDataFile_parent_WPDataFile_wpSetRealName(somSelf,
                                                        pszName);
}

/*
 *@@ wpSetTitleAndRenameFile:
 *      this WPFileSystem method is responsible for setting
 *      the real name _and_ the title of a file-system object.
 *
 *      WPFileSystem::wpSetTitle only calls this method and
 *      does nothing else. In other words, this method is
 *      the implementation for WPFileSystem::wpSetTitle;
 *      fConfirmations is then set to what _wpQueryConfirmations
 *      returns.
 *
 *      Now, here is the code flow when data files get renamed
 *      in the WPS (without XWorkplace):
 *
 *      1)  wpSetTitle is overridden by WPFileSystem to call
 *          WPFileSystem::wpSetTitleAndRenameFile instead.
 *
 *      2)  WPFileSystem::wpSetTitleAndRenameFile goes thru
 *          a lot of hoops to verify the title and handle
 *          file system conflicts, but eventually calls
 *          wpSetRealName and then its parent's wpSetTitle:
 *
 *          a)  wpSetRealName is overridden by WPDataFile,
 *              which calls the parent (WPDataFile::wpSetRealName)
 *              to actually rename the file and then update
 *              the file's associations.
 *
 *          b)  The parent wpSetTitle is WPObject's, which
 *              refreshes MINIRECORDCORE.pszIcon and updates
 *              the object in all containers.
 *
 *      One permanent bug with this has been that
 *      WPDataFile::wpSetRealname (2-a above) calls
 *      wpSetAssociatedFileIcon to update the icon in case the
 *      assoc has changed. Great idea, but the assoc is
 *      determined according to the title, which is only changed
 *      afterwards (2-b above). So this appears to be the reason
 *      why this has never worked in the WPS.
 *
 *      To fix this, we do the following:
 *
 *      --  override XFldDataFile::wpSetRealName to _not_ call
 *          the WPDataFile implementation, by calling our new
 *          XWPFileSystem::wpSetRealNameNoOverride method,
 *          which ends up in the correct XWPFileSystem::wpSetRealName
 *          (without updating the associated file icon);
 *
 *      --  override XFldDataFile::wpSetTitleAndRenameFile
 *          (this method here) to update the associated file
 *          icon _after_ the title has successfully changed.
 *
 *@@added V1.0.1 (2003-01-27) [umoeller]
 */

SOM_Scope BOOL  SOMLINK xdf_wpSetTitleAndRenameFile(XFldDataFile *somSelf,
                                                    PSZ pszNewTitle,
                                                    ULONG fConfirmations)
{
    /* XFldDataFileData *somThis = XFldDataFileGetData(somSelf); */
    XFldDataFileMethodDebug("XFldDataFile","xdf_wpSetTitleAndRenameFile");

    if (XFldDataFile_parent_WPDataFile_wpSetTitleAndRenameFile(somSelf,
                                                               pszNewTitle,
                                                               fConfirmations))
    {
#ifndef __NOTURBOFOLDERS__
        PMINIRECORDCORE pmrc;
        if (    (cmnQuerySetting(sfTurboFolders))   // V1.0.1 (2002-12-15) [umoeller]
             && (pmrc = _wpQueryCoreRecord(somSelf))
             && (pmrc->hptrIcon)
             // avoid this if we have an .ICON EA
             && (!(_xwpQueryFlags(somSelf) & OBJFL_HASICONEA))
           )
            _wpSetAssociatedFileIcon(somSelf);
#endif

        return TRUE;
    }

    return FALSE;
}

/*
 *@@ wpCreateFromTemplate:
 *      this WPObject method creates a new object from
 *      somSelf, which is assumed to be a template.
 *
 *      The WPFileSystem override of this kills our
 *      shared icons, so this had to be rewritten as
 *      well for WPDataFile. Note that WPFolder still
 *      uses the original implementation so we do not
 *      have to bother with any subfolders here.
 *
 *@@added V0.9.18 (2002-03-24) [umoeller]
 */

SOM_Scope WPObject*  SOMLINK xdf_wpCreateFromTemplate(XFldDataFile *somSelf,
                                                      WPFolder* folder,
                                                      BOOL fLock)
{
    // XFldDataFileData *somThis = XFldDataFileGetData(somSelf);
    XFldDataFileMethodDebug("XFldDataFile","xdf_wpCreateFromTemplate");

#ifndef __NOTURBOFOLDERS__
    if (cmnQuerySetting(sfTurboFolders))    // V1.0.1 (2002-12-15) [umoeller]
    {
        WPObject *pNew = NULL;

        // all this doesn't make sense if we aren't a template
        // in the first place
        if (_wpQueryStyle(somSelf) & OBJSTYLE_TEMPLATE)
        {
            // I can't get this to work any other way...
            // apparently, create from template is so full of
            // ugly hacks that this is the best way to do it
            if (pNew = _wpCopyObject(somSelf,
                                     folder,
                                     fLock))
            {
                _wpModifyStyle(pNew,
                               OBJSTYLE_TEMPLATE,
                               0);
            }
        }

        return pNew;
    }
#endif

    return XFldDataFile_parent_WPDataFile_wpCreateFromTemplate(somSelf,
                                                               folder,
                                                               fLock);
}

/* ******************************************************************
 *
 *   XFldDataFile class methods
 *
 ********************************************************************/

/*
 *@@ xwpclsListAssocsForType:
 *      this new M_XFldDataFile class method lists all
 *      associated WPProgram or WPProgramFile objects which
 *      have been assigned with the given file type.
 *
 *      For example, if "System editor" has been assigned to
 *      the "C Code" type, this would add the "System editor"
 *      program object to the given array.
 *
 *      V0.9.20 got rid of the linked list that used to be
 *      passed in. Instead, pass in an array of WPObject*
 *      pointers, which must be ulBuildMax in size, and pass
 *      in the current array item count in *pcAssocs.
 *      *pcAssocs gets raised with every object added, so
 *      you can call this several times to get the association
 *      array for multiple types.
 *
 *      NOTE: This locks each object instantiated as a
 *      result of the call.
 *
 *      This returns the no. of objects added to the list
 *      (0 if none). This will be less than the *pcAssocs
 *      output if there were objects in the array already.
 *
 *@@added V0.9.0 (99-11-27) [umoeller]
 *@@changed V0.9.9 (2001-03-27) [umoeller]: now avoiding duplicate assocs
 *@@changed V0.9.9 (2001-04-02) [umoeller]: now using objFindObjFromHandle, DRAMATICALLY faster
 *@@changed V0.9.16 (2002-01-01) [umoeller]: loop stopped after an invalid handle, fixed
 *@@changed V0.9.16 (2002-01-26) [umoeller]: added ulBuildMax, changed prototype, optimized
 *@@changed V0.9.20 (2002-07-25) [umoeller]: adjusted for getting rid of caches and mutexes
 *@@changed V1.0.1 (2002-12-14) [umoeller]: turned this into a class method
 */

SOM_Scope ULONG  SOMLINK xdfM_xwpclsListAssocsForType(M_XFldDataFile *somSelf,
                                                      WPObject** papObjects,
                                                      PULONG pcAssocs,
                                                      PSZ pcszType0,
                                                      ULONG ulBuildMax,
                                                      BOOL* pfDone)
{
    ULONG   ulrc = 0;

#ifndef __NOTURBOFOLDERS__
    CHAR    szTypeThis[100];
    PCSZ    pcszTypeThis = pcszType0;     // for now; later points to szTypeThis

    BOOL    fQuit = FALSE;

    /* M_XFldDataFileData *somThis = M_XFldDataFileGetData(somSelf); */
    M_XFldDataFileMethodDebug("M_XFldDataFile","xdfM_xwpclsListAssocsForType");

#ifdef __DEBUG__
    TRY_LOUD(dbgexc)
#endif
    {
        PMPF_ASSOCS((" entering with type %s", pcszTypeThis));

        // outer loop for climbing up the file type parents
        do // while TRUE
        {
            // get associations from WPS INI data
            CHAR    szObjectHandles[200];
            ULONG   cb = sizeof(szObjectHandles);
            ULONG   cHandles = 0;
            PCSZ    pAssoc;
            if (    (PrfQueryProfileData(HINI_USER,
                                         (PSZ)WPINIAPP_ASSOCTYPE, // "PMWP_ASSOC_TYPE"
                                         (PSZ)pcszTypeThis,
                                         szObjectHandles,
                                         &cb))
                 && (cb > 1)
               )
            {
                // null-terminate the data in any case  V0.9.20 (2002-07-25) [umoeller]
                szObjectHandles[sizeof(szObjectHandles) - 1] = '\0';

                // we got handles for this type, and it's not
                // just a null byte (just to name the type):
                // count the handles
                pAssoc = szObjectHandles;
                while (*pAssoc)
                {
                    HOBJECT hobjAssoc;
                    if (!(hobjAssoc = atoi(pAssoc)))
                        // invalid handle:
                        break;
                    else
                    {
                        WPObject *pobjAssoc;

                        if (pobjAssoc = objFindObjFromHandle(hobjAssoc))
                        {
                            // look if the object has already been added;
                            // this might happen if the same object has
                            // been defined for several types (inheritance!)
                            // V0.9.9 (2001-03-27) [umoeller]

                            ULONG   ul;
                            BOOL    fFound = FALSE;
                            for (ul = 0;
                                 ul < *pcAssocs;
                                 ++ul)
                            {
                                if (papObjects[ul] == pobjAssoc)
                                {
                                    fFound = TRUE;
                                    break;
                                }
                            }

                            if (!fFound)
                            {
                                // no:
                                papObjects[(*pcAssocs)++] = pobjAssoc;
                                ++ulrc;

                                // V0.9.16 (2002-01-26) [umoeller]
                                if (*pcAssocs >= ulBuildMax)
                                {
                                    // we have reached the max no. the caller wants:
                                    fQuit = TRUE;
                                    if (pfDone)
                                        *pfDone = TRUE;

                                    break;      // while (*pAssoc)
                                }
                            }
                        }
                    }

                    // go for next object handle (after the 0 byte)
                    pAssoc += strlen(pAssoc) + 1;
                    if (pAssoc >= szObjectHandles + cb)
                        break; // while (*pAssoc)

                } // end while (*pAssoc)
            }

            if (fQuit)
                break;
            else
            {
                // get parent type
                cb = sizeof(szTypeThis);
                if (    (PrfQueryProfileData(HINI_USER,
                                             (PSZ)INIAPP_XWPFILETYPES, // "XWorkplace:FileTypes"
                                             (PSZ)pcszTypeThis,        // key name: current type
                                             szTypeThis,
                                             &cb))
                     && (cb)
                   )
                {
                    pcszTypeThis = szTypeThis;

                    PMPF_ASSOCS(("   next round for %s", pcszTypeThis));
                }
                else
                    break;
            }

        } while (TRUE);
    }
#ifdef __DEBUG__
    CATCH(dbgexc) {} END_CATCH();
#endif

#endif

    return ulrc;
}

/*
 *@@ wpclsInitData:
 *      this M_WPObject class method gets called when a class
 *      is loaded by the WPS (probably from within a
 *      somFindClass call) and allows the class to initialize
 *      itself.
 *
 *@@changed V0.9.0 [umoeller]: added class object to KERNELGLOBALS
 *@@changed V0.9.6 (2000-10-16) [umoeller]: added method tables override
 *@@changed V1.0.0 (2002-08-31) [umoeller]: removed overrides
 */

SOM_Scope void  SOMLINK xdfM_wpclsInitData(M_XFldDataFile *somSelf)
{
    // M_XFldDataFileData *somThis = M_XFldDataFileGetData(somSelf);
    M_XFldDataFileMethodDebug("M_XFldDataFile","xdfM_wpclsInitData");

    M_XFldDataFile_parent_M_WPDataFile_wpclsInitData(somSelf);

    krnClassInitialized(G_pcszXFldDataFile);
}

/*
 *@@ wpclsCreateDefaultTemplates:
 *      this M_WPObject class method is called by the
 *      Templates folder to allow a class to
 *      create its default templates.
 *
 *      The default WPS behavior is to create new templates
 *      if the class default title is different from the
 *      existing templates.
 *
 *      Since we are replacing the class, we will have to
 *      suppress this in order not to crowd the Templates
 *      folder.
 */

SOM_Scope BOOL  SOMLINK xdfM_wpclsCreateDefaultTemplates(M_XFldDataFile *somSelf,
                                                         WPObject* Folder)
{
    // M_XFldDataFileData *somThis = M_XFldDataFileGetData(somSelf);
    M_XFldDataFileMethodDebug("M_XFldDataFile","xdfM_wpclsCreateDefaultTemplates");

    // we only override this class method if it is
    // being called for the _XFldDataFile class object itself.
    // If this is being called for a subclass, we use
    // the parent method, because we do not want to
    // break the default behavior for subclasses.
    // this is not working on Warp 3
    if (somSelf == _XFldDataFile)
        return TRUE;
        // means that the Templates folder should _not_ create templates
        // by itself; we pretend that we've done this

    return M_XFldDataFile_parent_M_WPDataFile_wpclsCreateDefaultTemplates(somSelf,
                                                                          Folder);

}

/*
 *@@ wpclsQueryTitle:
 *      this M_WPObject class method tells the WPS the clear
 *      name of a class, which is shown in the third column
 *      of a Details view and also used as the default title
 *      for new objects of a class.
 *
 *      We override the standard folder class name only if
 *      the user has enabled "fix class titles" in XWPSetup.
 *
 *@@added V0.9.12 (2001-05-22) [umoeller]
 */

SOM_Scope PSZ  SOMLINK xdfM_wpclsQueryTitle(M_XFldDataFile *somSelf)
{
    /* M_XFldDataFileData *somThis = M_XFldDataFileGetData(somSelf); */
    M_XFldDataFileMethodDebug("M_XFldDataFile","xdfM_wpclsQueryTitle");

#ifndef __ALWAYSFIXCLASSTITLES__
    if (!cmnQuerySetting(sfFixClassTitles))
        return M_XFldDataFile_parent_M_WPDataFile_wpclsQueryTitle(somSelf);
#endif

    return (PSZ)cmnGetString(ID_XSSI_CLASSTITLE_DATAFILE);
}

/*
 *@@ wpclsQueryDefaultHelp:
 *      this M_WPObject class method returns the default help
 *      panel for objects of this class. This gets called
 *      from WPObject::wpQueryDefaultHelp if no instance
 *      help settings (HELPLIBRARY, HELPPANEL) have been
 *      set for an individual object. It is thus recommended
 *      to override this method instead of the instance
 *      method to change the default help panel for a class
 *      in order not to break instance help settings (fixed
 *      with 0.9.20).
 *
 *      We replace the default data file help because,
 *      frankly, it sucks. The replacement was added
 *      with V0.9.16, but we rather have overridden the
 *      class method instead.
 *
 *@@added V0.9.19 (2002-04-17) [umoeller]
 */

SOM_Scope BOOL  SOMLINK xdfM_wpclsQueryDefaultHelp(M_XFldDataFile *somSelf,
                                                   PULONG pHelpPanelId,
                                                   PSZ pszHelpLibrary)
{
    /* M_XFldDataFileData *somThis = M_XFldDataFileGetData(somSelf); */
    M_XFldDataFileMethodDebug("M_XFldDataFile","xdfM_wpclsQueryDefaultHelp");

    strcpy(pszHelpLibrary, cmnQueryHelpLibrary());
    *pHelpPanelId = ID_XSH_DATAFILE_MAIN;
    return TRUE;
}

/*
 *@@ wpclsQueryIconData:
 *      this M_WPObject class method must return information
 *      about how to build the default icon for objects
 *      of a class. This gets called from various other
 *      methods whenever a class default icon is needed;
 *      most importantly, M_WPObject::wpclsQueryIcon
 *      calls this to build a class default icon, which
 *      is then cached in the class's instance data.
 *      If a subclass wants to change a class default icon,
 *      it should always override _this_ method instead of
 *      wpclsQueryIcon.
 *
 *      Note that the default WPS implementation does not
 *      allow for specifying the ICON_FILE format here,
 *      which is why we have overridden
 *      M_XFldObject::wpclsQueryIcon too. This allows us
 *      to return icon _files_ for theming too. For details
 *      about the WPS's crappy icon management, refer to
 *      src\filesys\icons.c.
 *
 *      We give data files a new default icon, if icon
 *      replacements are enabled. Note that this only
 *      affects data files that have no associations.
 */

SOM_Scope ULONG  SOMLINK xdfM_wpclsQueryIconData(M_XFldDataFile *somSelf,
                                                 PICONINFO pIconInfo)
{
    // M_XFldDataFileData *somThis = M_XFldDataFileGetData(somSelf);
    M_XFldDataFileMethodDebug("M_XFldDataFile","xdfM_wpclsQueryIconData");

#ifndef __NOICONREPLACEMENTS__
    if (cmnQuerySetting(sfIconReplacements))
    {
        // now using cmnGetStandardIcon
        // V0.9.16 (2002-01-13) [umoeller]
        ULONG cb = 0;
        if (!cmnGetStandardIcon(STDICON_DATAFILE,
                                NULL,            // no hpointer
                                &cb,
                                pIconInfo))      // can be NULL
            return cb;

        return 0;
    }
#endif

    // icon replacements not allowed: call default
    return M_XFldDataFile_parent_M_WPDataFile_wpclsQueryIconData(somSelf,
                                                                 pIconInfo);
}

