home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: WPS_PM
/
WPS_PM.zip
/
xfld085s.zip
/
main
/
xfobj.c
< prev
next >
Wrap
C/C++ Source or Header
|
1999-02-26
|
83KB
|
1,946 lines
/*
*@@sourcefile xfobj.c:
* This file contains the following major XFolder parts:
*
* -- XFldObject SOM stuff
*
* Check the other files starting with xf* for the
* other XFolder classes.
*
* XFldObject gives the other classes access to WPS
* internals that cannot be reached otherwise. It
* also initializes the whole XFolder environment
* at WPS bootup by overriding M_XFldObject::wpclsInitData.
*
* This class must always be installed.
*
*@@somclass XFldObject xfobj_
*@@somclass M_XFldObject xfobjM_
*/
/*
* Copyright (C) 1997-99 Ulrich Möller.
* This file is part of the XFolder source package.
* XFolder 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 XFolder 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.42
*/
#ifndef SOM_Module_xfobj_Source
#define SOM_Module_xfobj_Source
#endif
#define XFldObject_Class_Source
#define M_XFldObject_Class_Source
/*
* Suggested #include order:
* 1) os2.h
* 2) C library headers
* 3) SOM headers which work with precompiled header files
* 4) headers in /helpers
* 5) headers in /main with dlgids.h and common.h first
* 6) #pragma hdrstop to prevent VAC++ crashes
* 7) other needed SOM headers
* 8) for non-SOM-class files: corresponding header (e.g. classlst.h)
*/
#define INCL_DOSFILEMGR
#define INCL_DOSMODULEMGR
#define INCL_DOSPROCESS // DosSleep, priorities, PIDs etc.
#define INCL_DOSSEMAPHORES // needed for xthreads.h
#define INCL_DOSEXCEPTIONS
#define INCL_DOSERRORS
#define INCL_WINWINDOWMGR
#define INCL_WINPROGRAMLIST // needed for WPProgram
#define INCL_WINFRAMEMGR // WM_FORMATFRAME, SC_CLOSE etc.
#define INCL_WINSYS // presparams, WinQuerySysValue()
#define INCL_WINCOUNTRY // WinCompareStrings, WinUpper
#define INCL_WINPOINTERS
#define INCL_WINSHELLDATA // profile funcs
#define INCL_WINTIMER
#define INCL_WINCLIPBOARD
#define INCL_WININPUT // WinQueryFocus etc.
#define INCL_WINDIALOGS
#define INCL_WINMENUS // needed for menus.h
#define INCL_WINENTRYFIELDS
#define INCL_WINBUTTONS
#define INCL_WINSTDBOOK // notebooks
#define INCL_WINSTDCNR // needed for winh.h
#include <os2.h>
// C library headers
#include <stdio.h>
#include <malloc.h>
// headers in /helpers
#include "dosh.h" // Control Program helper routines
#include "winh.h" // PM helper routines
#include "linklist.h" // linked list helper routines
#include "procstat.h" // DosQProcStat handling
#include "stringh.h" // string helper routines
#include "undoc.h" // some undocumented stuff
#include "wphandle.h" // Henk Kelder's HOBJECT handling
// SOM headers which don't crash with prec. header files
#pragma hdrstop // VAC++ keeps crashing otherwise
#include "xfobj.ih"
// headers in /main
#include "dlgids.h" // all the IDs that are shared with NLS
#include "common.h" // the majestic XFolder include file
#include "classlst.h" // SOM logic for "WPS Classes" page
#include "cnrsort.h" // container sort comparison functions
#include "xthreads.h" // XFolder threads; this includes threads.h
// other SOM headers
#include "xfldr.h" // needed for XFolder SOM methods
#include "xfpgmf.ih"
#include <wpdesk.h> // WPDesktop
#include <wpshadow.h>
#include "xwps.h" // XFolder pseudo SOM functions
/*
* Global variables::
*
*/
VOID FillCnrWithObjectUsage(HWND hwndCnr, WPObject *pObject);
MRESULT EXPENTRY fnwpObjectUsage(HWND hwndDlg, ULONG msg, MPARAM mp1, MPARAM mp2);
/*
* XFOBJWINDATA:
* structure for data exchange with XFolder instance data.
* Created in WM_INITDLG.
*/
typedef struct _XFOBJWINDATA
{
SOMAny *somSelf;
CHAR szOldID[CCHMAXPATH];
HWND hwndCnr;
CHAR szOldObjectID[256];
BOOL fEscPressed;
PRECORDCORE preccExpanded;
} XFOBJWINDATA, *PXFOBJWINDATA;
/*
* fnwpSettingsObjDetails:
* notebook dlg func for XFldObject "Details" page.
* Here's a trick how to interface the corresponding
* SOM (WPS) object from within this procedure:
* 1) declare a structure with all the data which is
* needed in this wnd proc (see XFOBJWINDATA below)
* 2) when inserting the notebook page, specify
* somSelf as the pCreateParams parameter in the
* PAGEINFO structure;
* 3) somSelf is then passed in mp2 of WM_INITDLG;
* with that message, we create our structure on
* the heap and store the address to it in the
* notebook's window words. We can then access
* our structure from later messages too.
* 4) Don't forget to free the structure at WM_DESTROY.
*
*@@changed 0.85 fixed object ID error message
*/
MRESULT EXPENTRY fnwpSettingsObjDetails(HWND hwndDlg, ULONG msg, MPARAM mp1, MPARAM mp2)
{
PXFOBJWINDATA pWinData = (PXFOBJWINDATA)WinQueryWindowULong(hwndDlg, QWL_USER);
MRESULT mrc = FALSE;
switch(msg)
{
case WM_INITDLG: {
// we need to initialize SOM stuff to be able to
// access instance variables later
PSZ pszObjectID;
CNRINFO CnrInfo;
pWinData = (PXFOBJWINDATA)_wpAllocMem((SOMAny*)mp2, sizeof(XFOBJWINDATA), NULL);
WinSetWindowPtr(hwndDlg, QWL_USER, pWinData);
// somSelf is given to us in mp2 (see pCreateParams
// in XFldObject::xfAddObjectInternalsPage below)
pWinData->somSelf = (SOMAny*)mp2;
// initialize the fields in the structure
pszObjectID = _wpQueryObjectID(pWinData->somSelf);
if (pszObjectID)
strcpy(pWinData->szOldID, pszObjectID);
else
strcpy(pWinData->szOldID, "");
// make Warp 4 notebook buttons and move controls
winhAssertWarp4Notebook(hwndDlg,
100, // ID threshold
WARP4_NOTEBOOK_OFFSET); // move other controls offset (common.h)
// setup container
pWinData->hwndCnr = WinWindowFromID(hwndDlg, ID_XSDI_DTL_CNR);
WinSendMsg(pWinData->hwndCnr, CM_QUERYCNRINFO,
&CnrInfo, (MPARAM)sizeof(CnrInfo));
CnrInfo.pSortRecord = (PVOID)fnCompareName;
CnrInfo.flWindowAttr = CV_TREE | CV_TEXT | CA_TREELINE;
CnrInfo.cxTreeIndent = 30;
WinSendMsg(pWinData->hwndCnr, CM_SETCNRINFO,
&CnrInfo,
(MPARAM)(CMA_PSORTRECORD | CMA_FLWINDOWATTR | CMA_CXTREEINDENT));
WinPostMsg(hwndDlg, WM_SETTINGS2DLG, 0, 0);
mrc = WinDefDlgProc(hwndDlg, msg, mp1, mp2);
break; }
case WM_SETTINGS2DLG: {
HPOINTER hptrOld = WinQueryPointer(HWND_DESKTOP);
WinSetPointer(HWND_DESKTOP, WinQuerySysPointer(HWND_DESKTOP, SPTR_WAIT, FALSE));
FillCnrWithObjectUsage(pWinData->hwndCnr, pWinData->somSelf);
WinSetPointer(HWND_DESKTOP, hptrOld);
} // continue, no break
case WM_ENABLEITEMS:
break;
case WM_DLG2SETTINGS: {
break; }
/*
* WM_TIMER:
* timer for tree view auto-scroll
*/
case WM_TIMER: {
if ( ( pWinData->preccExpanded->flRecordAttr & CRA_EXPANDED) != 0 ) {
PRECORDCORE preccLastChild;
WinStopTimer(WinQueryAnchorBlock(hwndDlg),
hwndDlg,
1);
// scroll the tree view properly
preccLastChild = WinSendMsg(pWinData->hwndCnr,
CM_QUERYRECORD,
pWinData->preccExpanded, // expanded PRECORDCORE from CN_EXPANDTREE
MPFROM2SHORT(CMA_LASTCHILD, CMA_ITEMORDER));
if (preccLastChild) {
// ULONG ulrc;
winhCnrScrollToRecord(pWinData->hwndCnr,
(PRECORDCORE)preccLastChild,
CMA_TEXT, // record text rectangle only
TRUE); // keep parent visible
}
}
}
/*
* WM_CONTROL:
*
*/
case WM_CONTROL:
{
if (SHORT1FROMMP(mp1) == ID_XSDI_DTL_CNR)
switch (SHORT2FROMMP(mp1)) {
/*
* CN_EXPANDTREE:
* do tree-view auto scroll
*/
case CN_EXPANDTREE: {
PGLOBALSETTINGS pGlobalSettings = cmnQueryGlobalSettings();
mrc = WinDefDlgProc(hwndDlg, msg, mp1, mp2);
if (pGlobalSettings->TreeViewAutoScroll) {
pWinData->preccExpanded = (PRECORDCORE)mp2;
WinStartTimer(WinQueryAnchorBlock(hwndDlg),
hwndDlg,
1,
100);
}
break; }
/*
* CN_BEGINEDIT:
* when user alt-clicked on a recc
*/
case CN_BEGINEDIT: {
pWinData->fEscPressed = TRUE;
mrc = (MPARAM)0;
break;}
/*
* CN_REALLOCPSZ:
* just before the edit MLE is closed
*/
case CN_REALLOCPSZ: {
PCNREDITDATA pced = (PCNREDITDATA)mp2;
PSZ pszChanging = *(pced->ppszText);
strcpy(pWinData->szOldObjectID, pszChanging);
pWinData->fEscPressed = FALSE;
mrc = (MPARAM)TRUE;
break; }
/*
* CN_ENDEDIT:
* recc text changed: update our data
*/
case CN_ENDEDIT: {
if (!pWinData->fEscPressed) {
PCNREDITDATA pced = (PCNREDITDATA)mp2;
PSZ pszNew = *(pced->ppszText);
BOOL fChange = FALSE;
// has the object ID changed?
if (strcmp(pWinData->szOldObjectID, pszNew) != 0)
{
// is this a valid object ID?
if ( (pszNew[0] != '<')
|| (*(pszNew + strlen(pszNew)-1) != '>')
)
cmnMessageBoxMsg(hwndDlg, 104, 108, MB_OK);
// fixed (V0.85)
else
// valid: confirm change
if (cmnMessageBoxMsg(hwndDlg, 107, 109, MB_YESNO) == MBID_YES)
fChange = TRUE;
if (fChange)
_wpSetObjectID(pWinData->somSelf, pszNew);
else
{
// change aborted: restore old recc text
strcpy(((POBJECTUSAGERECORDCORE)(pced->pRecord))->szText,
pWinData->szOldObjectID);
WinSendMsg(pWinData->hwndCnr, CM_INVALIDATERECORD,
(MPARAM)pced->pRecord,
MPFROM2SHORT(1, CMA_TEXTCHANGED));
}
}
}
mrc = (MPARAM)0;
break; }
default:
mrc = WinDefDlgProc(hwndDlg, msg, mp1, mp2);
} // end switch
else
mrc = WinDefDlgProc(hwndDlg, msg, mp1, mp2);
break; } // end of WM_CONTROL
case WM_COMMAND: {
switch (SHORT1FROMMP(mp1))
{
case DID_REFRESH: { // "Refresh" button
HPOINTER hptrOld = WinQueryPointer(HWND_DESKTOP);
WinSetPointer(HWND_DESKTOP, WinQuerySysPointer(HWND_DESKTOP, SPTR_WAIT, FALSE));
WinSendMsg(pWinData->hwndCnr,
CM_REMOVERECORD,
NULL,
MPFROM2SHORT(0, // remove all reccs
CMA_FREE));
FillCnrWithObjectUsage(pWinData->hwndCnr, pWinData->somSelf);
WinSetPointer(HWND_DESKTOP, hptrOld);
break; }
}
break; } // end of WM_COMMAND
case WM_HELP: {
PSZ pszHelpLibrary = cmnQueryHelpLibrary();
// always display help for the whole page, not for single items
if (!_wpDisplayHelp(pWinData->somSelf,
ID_XSH_SETTINGS_OBJINTERNALS,
pszHelpLibrary))
{
cmnMessageBoxMsg(HWND_DESKTOP, 104, 134, MB_OK);
}
break; }
default:
mrc = WinDefDlgProc(hwndDlg, msg, mp1, mp2);
}
return (mrc);
}
/* ******************************************************************
* *
* here come the XFldObject instance methods *
* *
********************************************************************/
/*
*@@ xfAddObjectInternalsPage:
* this actually adds the "Internals" pages into all object notebooks,
* if the Global Settings allow it
*/
SOM_Scope ULONG SOMLINK xfobj_xfAddObjectInternalsPage(XFldObject *somSelf,
HWND hwndNotebook)
{
PAGEINFO pi;
PSZ pszHelpLibrary = cmnQueryHelpLibrary();
/* XFldObjectData *somThis = XFldObjectGetData(somSelf); */
XFldObjectMethodDebug("XFldObject","xfobj_xfAddObjectInternalsPages");
// insert Shutdown settings page
memset((PCH)&pi, 0, sizeof(PAGEINFO));
pi.cb = sizeof(PAGEINFO);
pi.hwndPage = NULLHANDLE;
pi.pfnwp = fnwpSettingsObjDetails;
pi.resid = NLS_MODULE;
pi.pCreateParams = somSelf;
// passed to fnwpSettingsObjDetails in mp2
pi.dlgid = ID_XSD_OBJECTDETAILS;
pi.usPageStyleFlags = BKA_STATUSTEXTON | BKA_MAJOR; // major tab;
pi.usPageInsertFlags = BKA_FIRST;
pi.usSettingsFlags = 0; // don't enumerate in status line
pi.pszName = cmnQueryNLSStrings()->pszInternals;
pi.pszHelpLibraryName = pszHelpLibrary;
pi.idDefaultHelpPanel = ID_XSH_SETTINGS_OBJINTERNALS;
return (_wpInsertSettingsPage(somSelf, hwndNotebook, &pi));
}
/*
*@@ wpObjectReady:
* this instance method is called by the system when
* object awakening is complete and object data seems
* to be stable in memory;
* we will have this object's pointer stored
* in a global list (maintained by the Worker thread)
* so that XShutdown knows which objects are currently awake
*/
/*
*@@ wpObjectReady:
* this instance method is called by the system when
* object awakening is complete and object data seems
* to be stable in memory.
* We will have this object's pointer stored
* in a global list (maintained by the Worker thread)
* so that XShutdown knows which objects are currently awake.
*/
SOM_Scope void SOMLINK xfobj_wpObjectReady(XFldObject *somSelf,
ULONG ulCode, WPObject* refObject)
{
// XFldObjectData *somThis = XFldObjectGetData(somSelf);
XFldObjectMethodDebug("XFldObject","xfobj_wpObjectReady");
XFldObject_parent_WPObject_wpObjectReady(somSelf, ulCode,
refObject);
/* if ( (_somIsA(somSelf, _WPFolder))
|| (_somIsA(somSelf, _WPAbstract))
) */
{
xthrPostWorkerMsg(WOM_ADDAWAKEOBJECT,
(MPARAM)somSelf,
MPNULL);
// _fAddedToAwakeList = TRUE;
} /* else
_fAddedToAwakeList = FALSE; */
}
/*
*@@ wpUnInitData:
* reverse to wpInitData, this instance method is
* called by the system when an object is made
* dormant; we will have this object removed from our
* global list of awake objects
*/
/*
*@@ wpUnInitData:
* reverse to XFldObject::wpObjectReady, this instance
* method is called by the system when an object is made
* dormant. We will have this object removed from our
* global list of awake objects.
*/
SOM_Scope void SOMLINK xfobj_wpUnInitData(XFldObject *somSelf)
{
// XFldObjectData *somThis = XFldObjectGetData(somSelf);
XFldObjectMethodDebug("XFldObject","xfobj_wpUnInitData");
// if (_fAddedToAwakeList)
xthrPostWorkerMsg(WOM_REMOVEAWAKEOBJECT,
(MPARAM)somSelf,
MPNULL);
XFldObject_parent_WPObject_wpUnInitData(somSelf);
}
/*
*@@ wpFilterPopupMenu:
* remove default entries according to global settings
*/
/*
*@@ wpFilterPopupMenu:
* remove default entries according to global settings.
*/
SOM_Scope ULONG SOMLINK xfobj_wpFilterPopupMenu(XFldObject *somSelf,
ULONG ulFlags,
HWND hwndCnr,
BOOL fMultiSelect)
{
ULONG ulMenuFilter = 0;
PGLOBALSETTINGS pGlobalSettings = cmnQueryGlobalSettings();
// XFldObjectData *somThis = XFldObjectGetData(somSelf);
XFldObjectMethodDebug("XFldObject","xfobj_wpFilterPopupMenu");
ulMenuFilter = XFldObject_parent_WPObject_wpFilterPopupMenu(somSelf,
ulFlags,
hwndCnr,
fMultiSelect);
#ifdef DEBUG_MENUS
_Pmpf(("XFldObject::wpFilterPopupMenu: ulMenuFilter & CTXT_CRANOTHER: 0x%lX %d",
ulMenuFilter, ((ulMenuFilter) & CTXT_CRANOTHER)));
#endif
// 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
return ((ulMenuFilter
// first we add "Create another", because for
// some reason it's always disabled if XFolder
// is installed; I don't know why
| CTXT_CRANOTHER )
// then disable items, this may include CTXT_CRANOTHER
& ~(pGlobalSettings->DefaultMenuItems)
);
}
/*
*@@ wpModifyPopupMenu:
* add my own popup menu entries
*/
/*
*@@ wpModifyPopupMenu:
* add my own popup menu entries.
*/
SOM_Scope BOOL SOMLINK xfobj_wpModifyPopupMenu(XFldObject *somSelf,
HWND hwndMenu,
HWND hwndCnr,
ULONG iPosition)
{
HWND hwndSettingsMenu;
BOOL rc;
MENUITEM mi;
PGLOBALSETTINGS pGlobalSettings = cmnQueryGlobalSettings();
PNLSSTRINGS pNLSStrings = cmnQueryNLSStrings();
// XFldObjectData *somThis = XFldObjectGetData(somSelf);
XFldObjectMethodDebug("XFldObject","xfobj_wpModifyPopupMenu");
rc = (XFldObject_parent_WPObject_wpModifyPopupMenu(somSelf,
hwndMenu,
hwndCnr,
iPosition));
if (pGlobalSettings->RemoveLockInPlaceItem) {
// first we need a handle to the WPObject's "Lock in place"
// submenu in the the folder's popup menu
WinSendMsg(hwndMenu, MM_REMOVEITEM,
MPFROM2SHORT(ID_WPM_LOCKINPLACE, FALSE),
0);
}
return rc;
}
/*
*@@ wpMenuItemSelected:
* process input when any menu item was selected
*/
/*
*@@ wpMenuItemSelected:
* process input when any menu item was selected.
*/
SOM_Scope BOOL SOMLINK xfobj_wpMenuItemSelected(XFldObject *somSelf,
HWND hwndFrame,
ULONG ulMenuId)
{
PGLOBALSETTINGS pGlobalSettings = cmnQueryGlobalSettings();
BOOL brc = FALSE;
// XFldObjectData *somThis = XFldObjectGetData(somSelf);
XFldObjectMethodDebug("XFldObject","xfobj_wpMenuItemSelected");
switch (ulMenuId) {
#ifdef DEBUG_CONTEXT
case ID_XFMI_RECORDCORE: {
int i;
CHAR szMsg[1024] = "No record core.",
szTitle[1024],
szBuf[20] = "0x00000000";
PMINIRECORDCORE pMRC = _wpQueryCoreRecord(somSelf);
PCLASSFIELDINFO pCFI, pCFI2;
ULONG ulCFISize = 0, ulErr;
strcpy(szTitle, "Record core for ");
strcat(szTitle, _wpQueryTitle(somSelf));
strcpy(szMsg, "Size of core record (cb): ");
UL2H(szBuf+2, pMRC->cb);
strcat(szMsg, szBuf);
strcat(szMsg, "\nSize of MINIRECORDCORE: ");
UL2H(szBuf+2, sizeof(MINIRECORDCORE));
strcat(szMsg, szBuf);
strcat(szMsg, "\nSize of RECORDCORE: ");
UL2H(szBuf+2, sizeof(RECORDCORE));
strcat(szMsg, szBuf);
strcat(szMsg, "\nNext record: ");
UL2H(szBuf+2, (ULONG)pMRC->preccNextRecord);
strcat(szMsg, szBuf);
strcat(szMsg, "\nIcon X pos: ");
UL2H(szBuf+2, pMRC->ptlIcon.x);
strcat(szMsg, szBuf);
strcat(szMsg, "\nIcon Y pos: ");
UL2H(szBuf+2, pMRC->ptlIcon.y);
strcat(szMsg, szBuf);
strcat(szMsg, "\n\nDetails CLASSFIELDINFO:");
strcat(szMsg, "\nSize of structure: ");
_wpQueryDetailsData(somSelf, NULL, &ulCFISize);
UL2H(szBuf+2, ulCFISize);
strcat(szMsg, szBuf);
pCFI = (PCLASSFIELDINFO)_wpAllocMem(somSelf, ulCFISize, &ulErr);
pCFI2 = pCFI;
_wpQueryDetailsData(somSelf, (PVOID)&pCFI2, &ulCFISize);
_wpFreeMem(somSelf, (PVOID)pCFI);
DebugBox(szTitle, szMsg);
brc = TRUE;
break; }
case ID_XFMI_SHOWFOLDERDATA: {
xthrPostWorkerMsg(WM_SHOWFOLDERDATA,
(MPARAM)somSelf,
MPNULL);
brc = TRUE;
break; }
#endif
default:
brc = XFldObject_parent_WPObject_wpMenuItemSelected(somSelf,
hwndFrame,
ulMenuId);
}
return (brc);
}
/*
*@@ wpAddSettingsPages:
* this instance method inserts all the settings
* pages into an object's settings notebook.
* We will add the object's "Internals" page here.
*/
SOM_Scope BOOL SOMLINK xfobj_wpAddSettingsPages(XFldObject *somSelf,
HWND hwndNotebook)
{
PGLOBALSETTINGS pGlobalSettings = cmnQueryGlobalSettings();
// XFldObjectData *somThis = XFldObjectGetData(somSelf);
XFldObjectMethodDebug("XFldObject","xfobj_wpAddSettingsPages");
if (pGlobalSettings->ShowInternals)
_xfAddObjectInternalsPage(somSelf, hwndNotebook);
return (XFldObject_parent_WPObject_wpAddSettingsPages(somSelf,
hwndNotebook));
}
/*
*@@ fnwpTitleClashDlg:
* dlg proc for the "File exists" dialog.
* Most of the logic for that dialog is in the
* XFldObject::wpConfirmObjectTitle method actually; this
* function is only responsible for adjusting the dialog items'
* keyboard focus and such.
*/
MRESULT EXPENTRY fnwpTitleClashDlg(HWND hwndDlg, ULONG msg, MPARAM mp1, MPARAM mp2)
{
#define WM_DELAYEDFOCUS WM_USER+1
MRESULT mrc = (MRESULT)0;
switch (msg) {
/*
* WM_CONTROL:
* intercept focus messages and
* set focus to what we really want
*/
case WM_CONTROL: {
switch (SHORT2FROMMP(mp1)) // usNotifyCode
{
case EN_SETFOCUS: {
// == BN_CLICKED
if (SHORT1FROMMP(mp1) == ID_XFDI_CLASH_RENAMENEWTXT) {
winhSetDlgItemChecked(hwndDlg, ID_XFDI_CLASH_RENAMENEW, TRUE);
} else if (SHORT1FROMMP(mp1) == ID_XFDI_CLASH_RENAMEOLDTXT) {
winhSetDlgItemChecked(hwndDlg, ID_XFDI_CLASH_RENAMEOLD, TRUE);
} else if (SHORT1FROMMP(mp1) == ID_XFDI_CLASH_RENAMENEW) {
WinPostMsg(hwndDlg, WM_DELAYEDFOCUS,
(MPARAM)ID_XFDI_CLASH_RENAMENEWTXT, MPNULL);
} else if (SHORT1FROMMP(mp1) == ID_XFDI_CLASH_RENAMEOLD) {
WinPostMsg(hwndDlg, WM_DELAYEDFOCUS,
(MPARAM)ID_XFDI_CLASH_RENAMEOLDTXT, MPNULL);
}
}
}
break; }
case WM_DELAYEDFOCUS: {
winhSetDlgItemFocus(hwndDlg, (HWND)mp1);
break; }
/*
* WM_COMMAND:
* intercept "OK"/"Cancel" buttons
*/
case WM_COMMAND: {
mrc = (MRESULT)0;
switch ((ULONG)mp1)
{
case DID_OK: {
ULONG ulSelection = DID_CANCEL,
ulLastFocusID = 0;
CHAR szLastFocusID[20] = "";
if (winhIsDlgItemChecked(hwndDlg, ID_XFDI_CLASH_RENAMENEW)) {
ulSelection = ID_XFDI_CLASH_RENAMENEW;
ulLastFocusID = ID_XFDI_CLASH_RENAMENEWTXT;
} else if (winhIsDlgItemChecked(hwndDlg, ID_XFDI_CLASH_RENAMEOLD)) {
ulSelection = ID_XFDI_CLASH_RENAMEOLD;
ulLastFocusID = ID_XFDI_CLASH_RENAMEOLDTXT;
} else {
ulSelection = ID_XFDI_CLASH_REPLACE;
ulLastFocusID = ID_XFDI_CLASH_REPLACE;
}
// store focus
sprintf(szLastFocusID, "%d",
ulLastFocusID);
PrfWriteProfileString(HINI_USER, INIAPP_XFOLDER,
INIKEY_NAMECLASHFOCUS,
szLastFocusID);
// store window pos
winhSaveWindowPos(hwndDlg,
HINI_USER,
INIAPP_XFOLDER, INIKEY_WNDPOSNAMECLASH);
WinDismissDlg(hwndDlg, ulSelection);
break; }
case DID_CANCEL:
WinDismissDlg(hwndDlg, DID_CANCEL);
break;
}
break; }
case WM_HELP: {
WPObject *pHelpSomSelf = _wpclsQueryActiveDesktop(_WPDesktop);
if (pHelpSomSelf) {
PSZ pszHelpLibrary;
BOOL fProcessed = FALSE;
if (pszHelpLibrary = cmnQueryHelpLibrary())
// path found: display help panel
if (_wpDisplayHelp(pHelpSomSelf, ID_XFH_TITLECLASH, pszHelpLibrary))
fProcessed = TRUE;
if (!fProcessed)
cmnMessageBoxMsg(HWND_DESKTOP, 104, 134, MB_OK);
}
break; }
default:
mrc = WinDefDlgProc(hwndDlg, msg, mp1, mp2);
}
return (mrc);
}
// the return codes are only #define'd in the Warp 4 Toolkit,
// so we might need to define them here:
#ifndef NAMECLASH_CANCEL
#define NAMECLASH_CANCEL 0
#endif
#ifndef NAMECLASH_NONE
#define NAMECLASH_NONE 1
#endif
#ifndef NAMECLASH_RENAME
#define NAMECLASH_RENAME 2
#endif
#ifndef NAMECLASH_REPLACE
#define NAMECLASH_REPLACE 8
#endif
/*
*@@ wpConfirmObjectTitle:
* this instance method is called by the WPS during file
* operations (copy, move, rename etc.) for every single
* file that is being processed. This method must verify
* that the operation is valid WRT name clashes and display
* a confirmation dialog in case it is not.
* Apparently, this method is not overridden by subclasses,
* not even WPFileSystem.
* XFolder implements its own "Object exists" dialog here,
* if the Global Settings allow it.
* Like most interesting methods in the WPS, this thing is
* barely documented, so this is what I found out.
*
* Parameters:
* -- *somSelf in: the object being worked on
* -- *Folder in: the folder being worked on
* -- **ppDuplicate out: if we return NAMECLASH_REPLACE,
* we need to set this to the object to
* be replaced
* -- pszTitle out: if we return NAMECLASH_RENAME,
* we need to set this to somSelf's new title
* -- cbTitle in: sizeof(*pszTitle)
* -- menuID in: the user's operation, which is:
* 0x006B move
* 0x006C copy
* 0x006E rename
* 0x013C create shadow
*
* Returns:
* -- NAMECLASH_CANCEL (0):
* abort processing, have the WPS do nothing ("Cancel"
* button pressed in confirmation dialog); this will
* just skip the current file;
* -- NAMECLASH_NONE (1):
* continue processing, but perform no further
* renaming etc.; we return this if no duplicate file
* exists;
* -- NAMECLASH_RENAME (2):
* have the WPS change the title to pszTitle, which we
* need to set here; note that this does NOT change
* the real name! So we do the renaming ourselves here;
* -- NAMECLASH_REPLACE (8):
* have the WPS delete *ppDuplicate, which we need to
* set here if we return this code; we need to find the
* duplicate in this method then.
*/
SOM_Scope ULONG SOMLINK xfobj_wpConfirmObjectTitle(XFldObject *somSelf,
WPFolder* Folder,
WPObject** ppDuplicate,
PSZ pszTitle,
ULONG cbTitle,
ULONG menuID)
{
ULONG ulrc = NAMECLASH_NONE;
PGLOBALSETTINGS pGlobalSettings = cmnQueryGlobalSettings();
// XFldObjectData *somThis = XFldObjectGetData(somSelf);
XFldObjectMethodDebug("XFldObject","xfobj_wpConfirmObjectTitle");
#ifdef DEBUG_TITLECLASH
{
CHAR szFolder2[CCHMAXPATH];
_Pmpf(("Entering wpConfirmObjectTitle"));
_Pmpf((" somSelf == 0x%lX", somSelf));
_Pmpf((" pszTitle: %s", pszTitle));
_wpQueryFilename(_wpQueryFolder(somSelf), szFolder2, TRUE);
_Pmpf((" in folder: %s", szFolder2));
_Pmpf((" menuID: 0x%lX", menuID));
}
#endif
// first of all, check whether the confirmation
// dialogs have been replaced in the global settings;
// if not, we call the default method
if (pGlobalSettings->ReplConfirms)
{
// nameclashs are only a problem for file-system objects,
// and only if we're not creating shadows
if ( (_somIsA(somSelf, _WPFileSystem))
&& (menuID != 0x13C) // "create shadow" code
)
{
WPFileSystem *pobjExisting = NULL;
CHAR szNewRealName[CCHMAXPATH],
szTemp[600],
szFolder[CCHMAXPATH];
BOOL fFAT;
// check whether the target folder is valid
if (Folder) {
if (!_wpQueryFilename(Folder, szFolder, TRUE))
return (NAMECLASH_CANCEL);
} else
return (NAMECLASH_CANCEL);
// before checking names, determine whether
// the folder is on a FAT drive; we need this
// flag for title-to-realname translations later
fFAT = doshIsFileOnFAT(szFolder);
// this is not trivial, since we need to take
// in account all the FAT and HPFS file name
// conversion.
// 1) get real name, unless we're renaming;
// we then need to check for pszTitle
if (menuID != 0x6E) // not "rename" code
_wpQueryFilename(somSelf, szTemp, FALSE);
// (V0.84) this now does work for FAT to FAT;
// HPFS to FAT needs to be checked
else
strcpy(szTemp, pszTitle);
// 2) if the file is on FAT, make this 8+3
doshMakeRealName(szNewRealName, // buffer
szTemp,
'!', // replace-with char
fFAT);
// this should mimic the default WPS behavior close enough
#ifdef DEBUG_TITLECLASH
_Pmpf((" Checking for existence of %s", szNewRealName));
#endif
// does this file exist in pFolder?
pobjExisting = xwpsContainsFile(Folder, szNewRealName);
if (pobjExisting)
{
#ifdef DEBUG_TITLECLASH
CHAR szFolder2[CCHMAXPATH];
_Pmpf((" pObjExisting == 0x%lX", pobjExisting));
_Pmpf((" Title: %s", _wpQueryTitle(pobjExisting) ));
_wpQueryFilename(_wpQueryFolder(pobjExisting), szFolder2, TRUE);
_Pmpf((" in folder: %s", szFolder2));
#endif
// file exists: now we need to differentiate.
// 1) If we're copying, we need to always
// display the confirmation.
// 2) If we're renaming somSelf, we only
// display the confirmation if the
// existing object is != somSelf, because
// otherwise we have no problem.
/* if ( (menuID != 0x6E) // not "rename" code
|| ( (menuID == 0x6E)
&& (somSelf != pobjExisting)
)
) */
if ( (somSelf != pobjExisting)
|| (menuID != 0x6E) // not "rename"
)
{
CHAR szProposeTitle[CCHMAXPATH],
szProposeRealName[CCHMAXPATH],
szFileCount[20],
szSelfFilename[CCHMAXPATH],
szExistingFilename[CCHMAXPATH];
ULONG ulDlgReturn = 0,
ulLastFocusID = 0,
ulLastDot = 0;
PSZ p, p2;
BOOL fReplaceValid = TRUE,
fFileExists = FALSE;
LONG lFileCount = -1;
HWND hwndConfirm;
// prepare file date/time etc. for
// display in window
FILESTATUS3 fs3;
ULONG ulDateFormat =
PrfQueryProfileInt(HINI_USER, "PM_National", "iDate", 0);
ULONG ulTimeFormat =
PrfQueryProfileInt(HINI_USER, "PM_National", "iTime", 0);
CHAR szDateSep[10],
szTimeSep[10],
szThousand[10];
PrfQueryProfileString(HINI_USER, "PM_National", "sDate", "/",
szDateSep, sizeof(szDateSep)-1);
PrfQueryProfileString(HINI_USER, "PM_National", "sTime", ":",
szTimeSep, sizeof(szTimeSep)-1);
PrfQueryProfileString(HINI_USER, "PM_Default_National", "sThousand",
",", szThousand, sizeof(szThousand)-1);
// *** load confirmation dialog
hwndConfirm = WinLoadDlg(HWND_DESKTOP, HWND_DESKTOP,
fnwpTitleClashDlg,
NLS_MODULE, ID_XFD_TITLECLASH,
NULL);
// disable window updates for the following changes
WinEnableWindowUpdate(hwndConfirm, FALSE);
WinQueryDlgItemText(hwndConfirm, ID_XFDI_CLASH_TXT1,
sizeof(szTemp)-1, szTemp);
strhReplace(szTemp, "%1", szNewRealName);
strhReplace(szTemp, "%2", szFolder);
WinSetDlgItemText(hwndConfirm, ID_XFDI_CLASH_TXT1,
szTemp);
// set object information fields
// _wpQueryDateInfo(pobjExisting, &ffb4);
_wpQueryFilename(pobjExisting, szExistingFilename, TRUE);
DosQueryPathInfo(szExistingFilename,
FIL_STANDARD,
&fs3, sizeof(fs3));
strhFileDate(szTemp, &(fs3.fdateLastWrite), ulDateFormat, szDateSep[0]);
WinSetDlgItemText(hwndConfirm, ID_XFDI_CLASH_DATEOLD,
szTemp);
strhFileTime(szTemp, &(fs3.ftimeLastWrite), ulTimeFormat, szTimeSep[0]);
WinSetDlgItemText(hwndConfirm, ID_XFDI_CLASH_TIMEOLD,
szTemp);
// strhThousandsULong(szTemp, (_wpQueryFileSize(pobjExisting)+512) / 1024,
strhThousandsULong(szTemp, ((fs3.cbFile)+512) / 1024,
szThousand[0]);
WinSetDlgItemText(hwndConfirm, ID_XFDI_CLASH_SIZEOLD,
szTemp);
if (pobjExisting != somSelf) {
// if we're not copying within the same folder,
// i.e. if the two objects are different,
// give info on ourselves too
// _wpQueryDateInfo(somSelf, &ffb4);
_wpQueryFilename(somSelf, szSelfFilename, TRUE);
DosQueryPathInfo(szSelfFilename,
FIL_STANDARD,
&fs3, sizeof(fs3));
strhFileDate(szTemp, &(fs3.fdateLastWrite), ulDateFormat, szDateSep[0]);
WinSetDlgItemText(hwndConfirm, ID_XFDI_CLASH_DATENEW,
szTemp);
strhFileTime(szTemp, &(fs3.ftimeLastWrite), ulTimeFormat, szTimeSep[0]);
WinSetDlgItemText(hwndConfirm, ID_XFDI_CLASH_TIMENEW,
szTemp);
// strhThousandsULong(szTemp, (_wpQueryFileSize(somSelf)+512) / 1024,
strhThousandsULong(szTemp, ((fs3.cbFile)+512) / 1024,
szThousand[0]);
WinSetDlgItemText(hwndConfirm, ID_XFDI_CLASH_SIZENEW,
szTemp);
} else {
// if we're copying within the same folder,
// set the "new object" fields empty
WinSetDlgItemText(hwndConfirm, ID_XFDI_CLASH_DATENEW, "");
WinSetDlgItemText(hwndConfirm, ID_XFDI_CLASH_TIMENEW, "");
WinSetDlgItemText(hwndConfirm, ID_XFDI_CLASH_SIZENEW, "");
}
// propose new name; we will use the title and
// add a ":num" before the extension and then
// transform that one into a real name and keep
// increasing "num" until no file with that
// real name exists (as the WPS does it too)
strcpy(szTemp, pszTitle);
// check if title contains a ':num' already
p2 = strchr(szTemp, ':');
if (p2) {
lFileCount = atoi(p2+1);
if (lFileCount) {
// if we have a valid number following ":", remove it
p = strchr(szTemp, '.');
if (p)
strcpy(p2, p);
else
*p2 = '\0';
}
}
// insert new number
p = strrchr(szTemp, '.'); // last dot == extension
lFileCount = 1;
do {
WPFileSystem *pExistingFile2;
sprintf(szFileCount, ":%d", lFileCount);
if (p) {
// has extension: insert
ULONG ulBeforeDot = (p - szTemp);
// we don't care about FAT, because
// we propose titles, not real names
// (V0.84)
/* if ( (fFAT)
&& ((ulBeforeDot+strlen(szFileCount)) > 8)
)
ulBeforeDot = 8 - strlen(szFileCount); */
strncpy(szProposeTitle, szTemp, ulBeforeDot);
szProposeTitle[ulBeforeDot] = '\0';
strcat(szProposeTitle, szFileCount);
strcat(szProposeTitle, p);
}
else {
// has no extension: append
strncpy(szProposeTitle, szTemp, 255);
// we don't care about FAT, because
// we propose titles, not real names
// (V0.84)
/* (fFAT) ? 8 : 255);
if (fFAT)
szProposeTitle[8] = '\0'; */
strcat(szProposeTitle, szFileCount);
}
lFileCount++;
if (lFileCount > 99)
// avoid endless loops
break;
// now go through the folder content and
// check whether we already have a file
// with the proposed title (not real name!)
// (V0.84)
fFileExists = FALSE;
for ( pExistingFile2 = _wpQueryContent(Folder, NULL, (ULONG)QC_FIRST);
(pExistingFile2);
pExistingFile2 = _wpQueryContent(Folder, pExistingFile2, (ULONG)QC_NEXT)
)
{
fFileExists = (stricmp(_wpQueryTitle(pExistingFile2),
szProposeTitle) == 0);
if (fFileExists)
break;
}
/*
// make real name from this title and check
// if that file exists; if so, try the next
// ":num"
doshMakeRealName(szProposeRealName, szProposeTitle, '!',
// FAT filenames?
fFAT);
// extended file exists check (V0.84); we
// need to compare titles, not real names
pExistingFile2 = xwpsContainsFile(Folder, szProposeRealName);
if (pExistingFile2)
{
if (lFileCount > 99)
// avoid endless loops
fFileExists = FALSE;
else
fFileExists = (stricmp(_wpQueryTitle(pExistingFile2),
szProposeTitle) == 0);
} else
fFileExists = FALSE; */
} while (fFileExists);
// OK, we've found a new filename: set dlg items
WinSendDlgItemMsg(hwndConfirm, ID_XFDI_CLASH_RENAMENEWTXT,
EM_SETTEXTLIMIT,
(MPARAM)(250), MPNULL);
WinSetDlgItemText(hwndConfirm, ID_XFDI_CLASH_RENAMENEWTXT,
szProposeTitle);
WinSendDlgItemMsg(hwndConfirm, ID_XFDI_CLASH_RENAMEOLDTXT,
EM_SETTEXTLIMIT,
(MPARAM)(250), MPNULL);
WinSetDlgItemText(hwndConfirm, ID_XFDI_CLASH_RENAMEOLDTXT,
szProposeTitle);
// select the first characters up to the extension
// in the edit field
p = strrchr(szProposeTitle, '.'); // last dot == extension
if (p)
ulLastDot = (p-szProposeTitle);
else
ulLastDot = 300; // too large == select all
WinSendDlgItemMsg(hwndConfirm, ID_XFDI_CLASH_RENAMENEWTXT,
EM_SETSEL,
MPFROM2SHORT(0, ulLastDot), MPNULL);
WinSendDlgItemMsg(hwndConfirm, ID_XFDI_CLASH_RENAMEOLDTXT,
EM_SETSEL,
MPFROM2SHORT(0, ulLastDot), MPNULL);
// find the selection the user has made last time;
// this INI key item is maintained by fnwpTitleClashDlg above
ulLastFocusID = PrfQueryProfileInt(HINI_USER, INIAPP_XFOLDER,
INIKEY_NAMECLASHFOCUS,
ID_XFDI_CLASH_RENAMENEWTXT); // default value if not set
// disable "Replace" and "Rename old"
// if we're copying within the same folder
// or if we're copying a folder to its parent
if ( (pobjExisting == somSelf)
|| (pobjExisting == _wpQueryFolder(somSelf))
)
{
winhEnableDlgItem(hwndConfirm, ID_XFDI_CLASH_REPLACE, FALSE);
winhEnableDlgItem(hwndConfirm, ID_XFDI_CLASH_RENAMEOLD, FALSE);
winhEnableDlgItem(hwndConfirm, ID_XFDI_CLASH_RENAMEOLDTXT, FALSE);
// if the last focus is one of the disabled items,
// change it
if ( (ulLastFocusID == ID_XFDI_CLASH_REPLACE)
|| (ulLastFocusID == ID_XFDI_CLASH_RENAMEOLDTXT)
)
ulLastFocusID = ID_XFDI_CLASH_RENAMENEWTXT;
}
// disable "Replace" for "Rename" mode; this is
// not allowed
else if (menuID == 0x006E)
{
winhEnableDlgItem(hwndConfirm, ID_XFDI_CLASH_REPLACE, FALSE);
// if the last focus is one of the disabled items,
// change it
if (ulLastFocusID == ID_XFDI_CLASH_REPLACE)
ulLastFocusID = ID_XFDI_CLASH_RENAMENEWTXT;
}
// set focus to that item
winhSetDlgItemFocus(hwndConfirm, ulLastFocusID);
// this will automatically select the corresponding
// radio button, see fnwpTitleClashDlg above
// *** go!
winhRestoreWindowPos(hwndConfirm,
HINI_USER,
INIAPP_XFOLDER, INIKEY_WNDPOSNAMECLASH,
// move only, no resize
SWP_MOVE | SWP_SHOW | SWP_ACTIVATE);
ulDlgReturn = WinProcessDlg(hwndConfirm);
// check return value
switch (ulDlgReturn) {
case ID_XFDI_CLASH_RENAMENEW: {
// rename new: copy user's entry to buffer
// provided by the method
WinQueryDlgItemText(hwndConfirm, ID_XFDI_CLASH_RENAMENEWTXT,
cbTitle-1, pszTitle);
ulrc = NAMECLASH_RENAME;
break; }
case ID_XFDI_CLASH_RENAMEOLD: {
// rename old: use wpSetTitle on existing object
WinQueryDlgItemText(hwndConfirm, ID_XFDI_CLASH_RENAMEOLDTXT,
sizeof(szTemp)-1, szTemp);
_wpSetTitleAndRenameFile(pobjExisting, szTemp, 0);
if (menuID == 0x6E) // "rename" code
{
CHAR szNewRealName[CCHMAXPATH];
doshMakeRealName(szNewRealName, pszTitle, '!', TRUE);
_wpSetTitleAndRenameFile(somSelf, pszTitle, 0);
}
ulrc = NAMECLASH_NONE;
break; }
case ID_XFDI_CLASH_REPLACE:
*ppDuplicate = pobjExisting;
ulrc = NAMECLASH_REPLACE;
break;
case DID_CANCEL:
ulrc = NAMECLASH_CANCEL;
break;
}
WinDestroyWindow(hwndConfirm);
} // end if ( (menuID != 0x6E) // "rename" code
// || (somSelf != pobjExisting)
// )
}
else if (menuID == 0x6E) // "rename" code
{
// if (!pobjExisting) and we're renaming
CHAR szNewRealName[CCHMAXPATH];
doshMakeRealName(szNewRealName, pszTitle, '!', TRUE);
if (_wpSetTitleAndRenameFile(somSelf, pszTitle, 0))
// no error:
ulrc = NAMECLASH_NONE;
else
ulrc = NAMECLASH_CANCEL;
}
} // end if (_somIsA(somSelf, _WPFileSystem))
} // end if (pGlobalSettings->ReplConfirms)
else {
// global settings do not allow dialog
// replacement: call default
#ifdef DEBUG_TITLECLASH
_Pmpf((" Calling original"));
#endif
ulrc = XFldObject_parent_WPObject_wpConfirmObjectTitle(somSelf,
Folder,
ppDuplicate,
pszTitle,
cbTitle,
menuID);
}
#ifdef DEBUG_TITLECLASH
{
CHAR szFolder2[CCHMAXPATH];
_Pmpf((" Return value: %d", ulrc));
_Pmpf((" New somSelf == 0x%lX", somSelf));
_Pmpf((" New pszTitle: %s", pszTitle));
_wpQueryFilename(_wpQueryFolder(somSelf), szFolder2, TRUE);
_Pmpf((" in folder: %s", szFolder2));
if (ppDuplicate) {
_Pmpf((" ppDuplicate neu != NULL"));
if (*ppDuplicate) {
_Pmpf((" *ppDuplicate neu == 0x%lX", *ppDuplicate));
_Pmpf((" Title neu: %s", _wpQueryTitle(*ppDuplicate) ));
_wpQueryFilename(_wpQueryFolder(*ppDuplicate), szFolder2, TRUE);
_Pmpf((" in folder: %s", szFolder2));
}
}
_Pmpf(("Done."));
}
#endif
return (ulrc);
}
/* ******************************************************************
* *
* here come the XFldObject class methods *
* *
********************************************************************/
BOOL fThreadsInitialized = FALSE;
/*
*@@ wpclsInitData:
* we override this to initialize XFolder altogether.
* This is probably the first SOM method called on the
* system (for M_WPObject, that is), so we use this
* to set up some stuff, most notably, start the
* additional XFolder threads.
*/
/*
*@@ wpclsInitData:
* we override this to initialize XFolder altogether.
* This is probably the first SOM method called on the
* system (for M_WPObject, that is), so we use this
* to set up some stuff, most notably, start the
* additional XFolder threads by calling
* xthrInitializeThreads (xthreads.c).
*/
SOM_Scope void SOMLINK xfobjM_wpclsInitData(M_XFldObject *somSelf)
{
PGLOBALSETTINGS pGlobalSettings = cmnQueryGlobalSettings();
// M_XFldObjectData *somThis = M_XFldObjectGetData(somSelf);
// M_XFldObjectMethodDebug("M_XFldObject","xfobjM_wpclsInitData");
#ifdef DEBUG_SOMMETHODS
_Pmpf(("M_XFldObject::xfobjM_wpclsInitData for class %s",
_somGetName(somSelf) ));
#endif
M_XFldObject_parent_M_WPObject_wpclsInitData(somSelf);
// since this code is reached for every single WPS class
// that gets initialized, we need to check if we're being
// called for the first time
if (!fThreadsInitialized)
{
fThreadsInitialized = TRUE;
// initialize all the thread stuff (xthreads.c)
xthrInitializeThreads();
}
// even if not first invocation (i.e. some class other
// than WPObject gets initialized): notify Quick thread
// of class initialization
if (pGlobalSettings->ShowBootupStatus)
xthrPostQuickMsg(QM_BOOTUPSTATUS, (MPARAM)somSelf, MPNULL);
}
/* ******************************************************************
* *
* "Object usage" dialog *
* *
********************************************************************/
/*
*@@ AddObjectUsage2Cnr:
* shortcut for the "object usage" functions below
* to add one cnr record core
*/
POBJECTUSAGERECORDCORE AddObjectUsage2Cnr(HWND hwndCnr,
POBJECTUSAGERECORDCORE preccParent, PSZ pszTitle, ULONG flAttrs)
{
POBJECTUSAGERECORDCORE preccNew = (POBJECTUSAGERECORDCORE)
winhCnrAllocRecord(hwndCnr, sizeof(OBJECTUSAGERECORDCORE));
strcpy(preccNew->szText, pszTitle);
winhCnrInsertRecord(hwndCnr, (PRECORDCORE)preccParent, (PRECORDCORE)preccNew,
preccNew->szText, flAttrs);
return (preccNew);
}
#ifdef DEBUG_MEMORY
LONG lObjectCount,
lTotalObjectSize,
lFreedObjectCount,
lHeapStatus;
/*
* fncbHeapWalk:
* callback func for _heap_walk function used for
* object usage (FillCnrWithObjectUsage)
*/
int fncbHeapWalk(const void *pObject, size_t Size, int useflag, int status,
const char *filename, size_t line)
{
if (status != _HEAPOK) {
lHeapStatus = status;
}
if (useflag == _USEDENTRY) {
// object not freed
lObjectCount++;
lTotalObjectSize += Size;
} else
lFreedObjectCount++;
return 0;
}
#endif
/*
*@@ FillCnrWithObjectUsage:
* adds all the object details into a given
* container window
*/
VOID FillCnrWithObjectUsage(HWND hwndCnr, WPObject *pObject)
{
POBJECTUSAGERECORDCORE
preccRoot, preccLevel2, preccLevel3;
CHAR szTemp1[100], szText[300];
PUSEITEM pUseItem;
CHAR szObjectHandle[20];
HOBJECT hObject;
PSZ pszObjectID;
ULONG ul;
PTHREADGLOBALS pThreadGlobals = xthrQueryGlobals();
// printf("Cnr: %d\n", hwndCnr);
if (pObject) {
sprintf(szText, "%s (Class: %s)",
_wpQueryTitle(pObject), _somGetClassName(pObject));
preccRoot = AddObjectUsage2Cnr(hwndCnr, NULL, szText,
CRA_RECORDREADONLY | CRA_EXPANDED);
// object ID
preccLevel2 = AddObjectUsage2Cnr(hwndCnr, preccRoot, "Object ID",
CRA_RECORDREADONLY | CRA_EXPANDED);
pszObjectID = _wpQueryObjectID(pObject);
if (pszObjectID)
AddObjectUsage2Cnr(hwndCnr, preccLevel2, pszObjectID,
(strcmp(pszObjectID, "<WP_DESKTOP") != 0
? 0 // editable!
: CRA_RECORDREADONLY)); // for the Desktop
else
AddObjectUsage2Cnr(hwndCnr, preccLevel2, "none set", 0); // editable!
// object handle
preccLevel2 = AddObjectUsage2Cnr(hwndCnr, preccRoot, "Object handle",
CRA_RECORDREADONLY | CRA_EXPANDED);
if (_somIsA(pObject, _WPFileSystem)) {
CHAR szPath[CCHMAXPATH];
_wpQueryFilename(pObject, szPath,
TRUE); // fully qualified
hObject = wphQueryHandleFromPath(HINI_USER, HINI_SYSTEM,
szPath);
} else if (_somIsA(pObject, _WPAbstract)) {
hObject = _wpQueryHandle(pObject);
}
if ((LONG)hObject > 0)
sprintf(szObjectHandle, "0x%lX", hObject);
else
sprintf(szObjectHandle, "(none queried)");
AddObjectUsage2Cnr(hwndCnr, preccLevel2, szObjectHandle, CRA_RECORDREADONLY);
// object style
preccLevel2 = AddObjectUsage2Cnr(hwndCnr, preccRoot, "Object style",
CRA_RECORDREADONLY);
ul = _wpQueryStyle(pObject);
if (ul & OBJSTYLE_CUSTOMICON)
AddObjectUsage2Cnr(hwndCnr, preccLevel2,
"Custom icon (destroy icon when object goes dormant)",
CRA_RECORDREADONLY);
if (ul & OBJSTYLE_NOCOPY)
AddObjectUsage2Cnr(hwndCnr, preccLevel2, "no copy",
CRA_RECORDREADONLY);
if (ul & OBJSTYLE_NODELETE)
AddObjectUsage2Cnr(hwndCnr, preccLevel2, "no delete",
CRA_RECORDREADONLY);
if (ul & OBJSTYLE_NODRAG)
AddObjectUsage2Cnr(hwndCnr, preccLevel2, "no drag",
CRA_RECORDREADONLY);
if (ul & OBJSTYLE_NODROPON)
AddObjectUsage2Cnr(hwndCnr, preccLevel2, "no drop-on",
CRA_RECORDREADONLY);
if (ul & OBJSTYLE_NOLINK)
AddObjectUsage2Cnr(hwndCnr, preccLevel2, "no link (cannot have shadows)",
CRA_RECORDREADONLY);
if (ul & OBJSTYLE_NOMOVE)
AddObjectUsage2Cnr(hwndCnr, preccLevel2, "no move",
CRA_RECORDREADONLY);
if (ul & OBJSTYLE_NOPRINT)
AddObjectUsage2Cnr(hwndCnr, preccLevel2, "no print",
CRA_RECORDREADONLY);
if (ul & OBJSTYLE_NORENAME)
AddObjectUsage2Cnr(hwndCnr, preccLevel2, "no rename",
CRA_RECORDREADONLY);
if (ul & OBJSTYLE_NOSETTINGS)
AddObjectUsage2Cnr(hwndCnr, preccLevel2, "no settings",
CRA_RECORDREADONLY);
if (ul & OBJSTYLE_NOSETTINGS)
AddObjectUsage2Cnr(hwndCnr, preccLevel2, "not visible",
CRA_RECORDREADONLY);
if (ul & OBJSTYLE_TEMPLATE)
AddObjectUsage2Cnr(hwndCnr, preccLevel2, "template",
CRA_RECORDREADONLY);
/* if (ul & OBJSTYLE_LOCKEDINPLACE)
AddObjectUsage2Cnr(hwndCnr, preccLevel2, "locked in place",
CRA_RECORDREADONLY); */
// folder data
if (_somIsA(pObject, _WPFolder)) {
preccLevel2 = AddObjectUsage2Cnr(hwndCnr, preccRoot, "Folder flags",
CRA_RECORDREADONLY);
ul = _wpQueryFldrFlags(pObject);
if (ul & FOI_POPULATEDWITHALL)
AddObjectUsage2Cnr(hwndCnr, preccLevel2, "Fully populated",
CRA_RECORDREADONLY);
if (ul & FOI_POPULATEDWITHFOLDERS)
AddObjectUsage2Cnr(hwndCnr, preccLevel2, "Populated with folders",
CRA_RECORDREADONLY);
if (ul & FOI_FIRSTPOPULATE)
AddObjectUsage2Cnr(hwndCnr, preccLevel2, "Populated with first objects",
CRA_RECORDREADONLY);
if (ul & FOI_WORKAREA)
AddObjectUsage2Cnr(hwndCnr, preccLevel2, "Work area",
CRA_RECORDREADONLY);
if (ul & FOI_CHANGEFONT)
AddObjectUsage2Cnr(hwndCnr, preccLevel2, "FOI_CHANGEFONT",
CRA_RECORDREADONLY);
if (ul & FOI_NOREFRESHVIEWS)
AddObjectUsage2Cnr(hwndCnr, preccLevel2, "FOI_NOREFRESHVIEWS",
CRA_RECORDREADONLY);
if (ul & FOI_ASYNCREFRESHONOPEN)
AddObjectUsage2Cnr(hwndCnr, preccLevel2, "FOI_ASYNCREFRESHONOPEN",
CRA_RECORDREADONLY);
if (ul & FOI_REFRESHINPROGRESS)
AddObjectUsage2Cnr(hwndCnr, preccLevel2, "FOI_REFRESHINPROGRESS",
CRA_RECORDREADONLY);
if (ul & FOI_WAMCRINPROGRESS)
AddObjectUsage2Cnr(hwndCnr, preccLevel2, "FOI_WAMCRINPROGRESS",
CRA_RECORDREADONLY);
if (ul & FOI_CNRBKGNDOLDFORMAT)
AddObjectUsage2Cnr(hwndCnr, preccLevel2, "FOI_CNRBKGNDOLDFORMAT",
CRA_RECORDREADONLY);
if (ul & FOI_DELETEINPROGRESS)
AddObjectUsage2Cnr(hwndCnr, preccLevel2, "FOI_DELETEINPROGRESS",
CRA_RECORDREADONLY);
// Desktop: add WPS data
if (pObject == _wpclsQueryActiveDesktop(_WPDesktop)) {
PRCPROCESS prcp;
PTIB ptib;
PPIB ppib;
TID tidWorkerThread = 0,
tidQuickThread = 0;
preccLevel2 = AddObjectUsage2Cnr(hwndCnr, preccRoot, "Workplace Shell status",
CRA_RECORDREADONLY);
// we use a conditional compile flag here because
// _heap_walk adds additional overhead to malloc()
#ifdef DEBUG_MEMORY
lObjectCount = 0;
lTotalObjectSize = 0;
lFreedObjectCount = 0;
lHeapStatus = _HEAPOK;
// get heap info using the callback above
_heap_walk(fncbHeapWalk);
strths(szTemp1, lTotalObjectSize, ',');
sprintf(szText, "XFolder memory consumption: %s bytes\n"
"(%d objects used, %d objects freed)",
szTemp1,
lObjectCount,
lFreedObjectCount);
AddObjectUsage2Cnr(hwndCnr, preccLevel2, szText,
CRA_RECORDREADONLY);
sprintf(szText, "XFolder memory heap status: %s",
(lHeapStatus == _HEAPOK) ? "OK"
: (lHeapStatus == _HEAPBADBEGIN) ? "Invalid heap (_HEAPBADBEGIN)"
: (lHeapStatus == _HEAPBADNODE) ? "Damaged memory node"
: (lHeapStatus == _HEAPEMPTY) ? "Heap not initialized"
: "unknown error"
);
AddObjectUsage2Cnr(hwndCnr, preccLevel2, szText,
CRA_RECORDREADONLY);
#endif
sprintf(szText, "Currently awake WPS objects: %d",
pThreadGlobals->lAwakeObjectsCount);
AddObjectUsage2Cnr(hwndCnr, preccLevel2, szText,
CRA_RECORDREADONLY);
DosGetInfoBlocks(&ptib, &ppib);
sprintf(szText, "Workplace Shell process ID: 0x%lX", ppib->pib_ulpid);
AddObjectUsage2Cnr(hwndCnr, preccLevel2, szText,
CRA_RECORDREADONLY);
prcQueryProcessInfo(ppib->pib_ulpid, &prcp);
sprintf(szText, "Workplace Shell thread count: %d", prcp.usThreads);
AddObjectUsage2Cnr(hwndCnr, preccLevel2, szText,
CRA_RECORDREADONLY);
tidWorkerThread = thrQueryID(pThreadGlobals->ptiWorkerThread);
sprintf(szText, "XFolder Worker thread: TID 0x%lX, prty 0x%04lX",
tidWorkerThread,
prcQueryThreadPriority(ppib->pib_ulpid, tidWorkerThread));
AddObjectUsage2Cnr(hwndCnr, preccLevel2, szText,
CRA_RECORDREADONLY);
tidQuickThread = thrQueryID(pThreadGlobals->ptiQuickThread);
sprintf(szText, "XFolder Quick thread: TID 0x%lX, prty 0x%04lX",
tidQuickThread,
prcQueryThreadPriority(ppib->pib_ulpid, tidQuickThread));
AddObjectUsage2Cnr(hwndCnr, preccLevel2, szText,
CRA_RECORDREADONLY);
sprintf(szText, "Last Workplace Shell startup: %02d:%02d:%02d",
pThreadGlobals->StartupDateTime.hours,
pThreadGlobals->StartupDateTime.minutes,
pThreadGlobals->StartupDateTime.seconds);
AddObjectUsage2Cnr(hwndCnr, preccLevel2, szText,
CRA_RECORDREADONLY);
sprintf(szText, "XFolder sound status: %s",
(pThreadGlobals->ulMMPM2Working == MMSTAT_UNKNOWN)
? "not initialized"
: (pThreadGlobals->ulMMPM2Working == MMSTAT_WORKING)
? "OK"
: (pThreadGlobals->ulMMPM2Working == MMSTAT_MMDIRNOTFOUND)
? "MMPM/2 directory not found"
: (pThreadGlobals->ulMMPM2Working == MMSTAT_SOUNDLLNOTFOUND)
? "SOUND.DLL not found"
: (pThreadGlobals->ulMMPM2Working == MMSTAT_SOUNDLLNOTLOADED)
? "SOUND.DLL could not be loaded"
: (pThreadGlobals->ulMMPM2Working == MMSTAT_SOUNDLLFUNCERROR)
? "SOUND.DLL functions could not be imported"
: (pThreadGlobals->ulMMPM2Working == MMSTAT_CRASHED)
? "Quick thread crashed"
: "unknown"
);
AddObjectUsage2Cnr(hwndCnr, preccLevel2, szText,
CRA_RECORDREADONLY);
}
} // end WPFolder
else if (_somIsA(pObject, _XFldProgramFile))
{
ULONG ulAppType = _xfQueryProgType(pObject);
preccLevel2 = AddObjectUsage2Cnr(hwndCnr, preccRoot,
"Program file data",
CRA_RECORDREADONLY);
sprintf(szText, "DosQueryAppType return value: 0x%lX",
XFldProgramFileGetData(pObject)->ulDosAppType);
AddObjectUsage2Cnr(hwndCnr, preccLevel2, szText,
CRA_RECORDREADONLY);
sprintf(szText, "Using custom icon: %s",
(XFldProgramFileGetData(pObject)->fProgIconSet)
? "yes" : "no");
AddObjectUsage2Cnr(hwndCnr, preccLevel2, szText,
CRA_RECORDREADONLY);
strcpy(szText, "Determined AppType: ");
switch (ulAppType)
{
case PROG_PM:
strcat(szText, "PM"); break;
case PROG_WINDOW_REAL :
case PROG_30_STD :
case PROG_WINDOW_AUTO :
case PROG_30_STDSEAMLESSVDM :
case PROG_30_STDSEAMLESSCOMMON:
case PROG_31_STDSEAMLESSVDM :
case PROG_31_STDSEAMLESSCOMMON:
case PROG_31_ENHSEAMLESSVDM :
case PROG_31_ENHSEAMLESSCOMMON:
case PROG_31_ENH :
case PROG_31_STD :
sprintf(szText+strlen(szText),
"Win-OS/2 (0x%lX)",
XFldProgramFileGetData(pObject)->ulAppType);
break;
case PROG_WINDOWABLEVIO:
strcat(szText, "OS/2 VIO window"); break;
case PROG_FULLSCREEN:
strcat(szText, "OS/2 fullscreen"); break;
case PROG_WINDOWEDVDM:
strcat(szText, "DOS window"); break;
case PROG_VDM: // == PROG_REAL
strcat(szText, "DOS fullscreen"); break;
case PROG_XF_DLL:
strcat(szText, "Dynamic Link Library"); break;
case PROG_XF_DRIVER:
strcat(szText, "Device Driver"); break;
default:
sprintf(szText+strlen(szText),
"unknown (0x%lX)",
XFldProgramFileGetData(pObject)->ulAppType);
break;
}
AddObjectUsage2Cnr(hwndCnr, preccLevel2, szText,
CRA_RECORDREADONLY);
}
// object usage
preccLevel2 = AddObjectUsage2Cnr(hwndCnr, preccRoot, "Object usage",
CRA_RECORDREADONLY);
preccLevel3 = NULL;
for (pUseItem = _wpFindUseItem(pObject, USAGE_OPENVIEW, NULL);
pUseItem;
pUseItem = _wpFindUseItem(pObject, USAGE_OPENVIEW, pUseItem))
{
PVIEWITEM pViewItem = (PVIEWITEM)(pUseItem+1);
switch (pViewItem->view) {
case OPEN_SETTINGS: strcpy(szTemp1, "Settings"); break;
case OPEN_CONTENTS: strcpy(szTemp1, "Icon"); break;
case OPEN_DETAILS: strcpy(szTemp1, "Details"); break;
case OPEN_TREE: strcpy(szTemp1, "Tree"); break;
case OPEN_RUNNING: strcpy(szTemp1, "Program running"); break;
case OPEN_PROMPTDLG:strcpy(szTemp1, "Prompt dialog"); break;
case OPEN_PALETTE: strcpy(szTemp1, "Palette"); break;
default: sprintf(szTemp1, "unknown (0x%lX)", pViewItem->view); break;
}
if (pViewItem->view != OPEN_RUNNING) {
PID pid;
TID tid;
WinQueryWindowProcess(pViewItem->handle, &pid, &tid);
sprintf(szText, "%s (HWND: 0x%lX, thread ID: 0x%lX)",
szTemp1, pViewItem->handle, tid);
} else {
sprintf(szText, "%s (HWND: 0x%lX)",
szTemp1, pViewItem->handle);
}
if (!preccLevel3)
preccLevel3 = AddObjectUsage2Cnr(hwndCnr, preccLevel2, "Currently open views",
CRA_RECORDREADONLY | CRA_EXPANDED);
AddObjectUsage2Cnr(hwndCnr, preccLevel3, szText, CRA_RECORDREADONLY);
}
preccLevel3 = NULL;
for (pUseItem = _wpFindUseItem(pObject, USAGE_MEMORY, NULL);
pUseItem;
pUseItem = _wpFindUseItem(pObject, USAGE_MEMORY, pUseItem))
{
PMEMORYITEM pMemoryItem = (PMEMORYITEM)(pUseItem+1);
sprintf(szText, "Size: %d", pMemoryItem->cbBuffer);
if (!preccLevel3)
preccLevel3 = AddObjectUsage2Cnr(hwndCnr, preccLevel2, "Allocated memory",
CRA_RECORDREADONLY);
AddObjectUsage2Cnr(hwndCnr, preccLevel3, szText, CRA_RECORDREADONLY);
}
preccLevel3 = NULL;
for (pUseItem = _wpFindUseItem(pObject, USAGE_LINK, NULL);
pUseItem;
pUseItem = _wpFindUseItem(pObject, USAGE_LINK, pUseItem))
{
PLINKITEM pLinkItem = (PLINKITEM)(pUseItem+1);
CHAR szShadowPath[CCHMAXPATH];
if (pLinkItem->LinkObj) {
_wpQueryFilename(_wpQueryFolder(pLinkItem->LinkObj),
szShadowPath, CRA_RECORDREADONLY | CRA_EXPANDED);
sprintf(szText, "%s in \n%s", _wpQueryTitle(pLinkItem->LinkObj),
szShadowPath);
} else
strcpy(szText, "broken");
if (!preccLevel3)
preccLevel3 = AddObjectUsage2Cnr(hwndCnr, preccLevel2,
"Awake shadows of this object",
CRA_RECORDREADONLY | CRA_EXPANDED);
AddObjectUsage2Cnr(hwndCnr, preccLevel3, szText, CRA_RECORDREADONLY);
}
preccLevel3 = NULL;
for (pUseItem = _wpFindUseItem(pObject, USAGE_RECORD, NULL);
pUseItem;
pUseItem = _wpFindUseItem(pObject, USAGE_RECORD, pUseItem))
{
PRECORDITEM pRecordItem = (PRECORDITEM)(pUseItem+1);
CHAR szFolderTitle[256];
WinQueryWindowText(WinQueryWindow(pRecordItem->hwndCnr, QW_PARENT),
sizeof(szFolderTitle)-1,
szFolderTitle);
sprintf(szText, "Container HWND: 0x%lX\n(\"%s\")",
pRecordItem->hwndCnr,
szFolderTitle);
if (!preccLevel3)
preccLevel3 = AddObjectUsage2Cnr(hwndCnr, preccLevel2,
"Folder windows containing this object",
CRA_RECORDREADONLY | CRA_EXPANDED);
AddObjectUsage2Cnr(hwndCnr, preccLevel3, szText, CRA_RECORDREADONLY);
}
preccLevel3 = NULL;
for (pUseItem = _wpFindUseItem(pObject, USAGE_OPENFILE, NULL);
pUseItem;
pUseItem = _wpFindUseItem(pObject, USAGE_OPENFILE, pUseItem))
{
PVIEWFILE pViewFile = (PVIEWFILE)(pUseItem+1);
sprintf(szText, "Open handle: 0x%lX", pViewFile->handle);
if (!preccLevel3)
preccLevel3 = AddObjectUsage2Cnr(hwndCnr, preccLevel2,
"Applications which opened this object",
CRA_RECORDREADONLY | CRA_EXPANDED);
AddObjectUsage2Cnr(hwndCnr, preccLevel3, szText, CRA_RECORDREADONLY);
}
preccLevel3 = NULL;
for (ul = 0; ul < 100; ul++)
if ( (ul != USAGE_OPENVIEW)
&& (ul != USAGE_MEMORY)
&& (ul != USAGE_LINK)
&& (ul != USAGE_RECORD)
&& (ul != USAGE_OPENFILE)
)
{
for (pUseItem = _wpFindUseItem(pObject, ul, NULL);
pUseItem;
pUseItem = _wpFindUseItem(pObject, ul, pUseItem))
{
sprintf(szText, "Type: 0x%lX", pUseItem->type);
if (!preccLevel3)
preccLevel3 = AddObjectUsage2Cnr(hwndCnr, preccLevel2,
"Undocumented usage types",
CRA_RECORDREADONLY | CRA_EXPANDED);
AddObjectUsage2Cnr(hwndCnr, preccLevel3, szText, CRA_RECORDREADONLY);
}
}
}
}
/*
* fnwpObjectUsage:
* dlg proc for "Object usage" dlg
*/
MRESULT EXPENTRY fnwpObjectUsage(HWND hwndDlg, ULONG msg, MPARAM mp1, MPARAM mp2)
{
MRESULT mrc;
POBJECTUSAGEDATA poud = (POBJECTUSAGEDATA)WinQueryWindowULong(hwndDlg, QWL_USER);
switch(msg) {
case WM_INITDLG: {
CNRINFO CnrInfo;
WinSetWindowULong(hwndDlg, QWL_USER, (ULONG)mp2);
poud = (POBJECTUSAGEDATA)mp2;
WinSetWindowText(hwndDlg, poud->szDlgTitle);
WinSetDlgItemText(hwndDlg, ID_XSDI_SC_INTROTEXT, poud->szIntroText);
// setup container
poud->hwndCnr = WinWindowFromID(hwndDlg, ID_XSDI_SC_CNR);
WinSendMsg(poud->hwndCnr, CM_QUERYCNRINFO, &CnrInfo, (MPARAM)sizeof(CnrInfo));
CnrInfo.pSortRecord = (PVOID)fnCompareName;
CnrInfo.flWindowAttr = CV_TREE | CV_TEXT | CA_TREELINE;
CnrInfo.cxTreeIndent = 30;
WinSendMsg(poud->hwndCnr, CM_SETCNRINFO,
&CnrInfo,
(MPARAM)(CMA_PSORTRECORD | CMA_FLWINDOWATTR | CMA_CXTREEINDENT));
if (poud->ulHelpPanel == 0)
winhShowDlgItem(hwndDlg, DID_HELP, FALSE);
WinPostMsg(hwndDlg, WM_FILLCNR, MPNULL, MPNULL);
mrc = WinDefDlgProc(hwndDlg, msg, mp1, mp2);
break; }
case WM_FILLCNR: {
HPOINTER hptrOld = WinQueryPointer(HWND_DESKTOP);
WinSetPointer(HWND_DESKTOP, WinQuerySysPointer(HWND_DESKTOP, SPTR_WAIT, FALSE));
FillCnrWithObjectUsage(poud->hwndCnr, poud->pObject);
WinSetPointer(HWND_DESKTOP, hptrOld);
break; }
case WM_CONTROL: {
mrc = WinDefDlgProc(hwndDlg, msg, mp1, mp2);
if (SHORT1FROMMP(mp1) == ID_XSDI_SC_CNR) {
switch (SHORT2FROMMP(mp1)) { // notify code
case CN_EMPHASIS: {
PNOTIFYRECORDEMPHASIS pnre = (PNOTIFYRECORDEMPHASIS)mp2;
if (pnre)
if (pnre->fEmphasisMask & CRA_SELECTED) {
}
break; }
}
}
break; }
case WM_DESTROY: {
mrc = WinDefDlgProc(hwndDlg, msg, mp1, mp2);
break; }
default:
mrc = WinDefDlgProc(hwndDlg, msg, mp1, mp2);
}
return (mrc);
}