home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: WPS_PM
/
WPS_PM.zip
/
xfld085s.zip
/
main
/
common.c
< prev
next >
Wrap
C/C++ Source or Header
|
1999-03-15
|
90KB
|
2,211 lines
/*
*@@sourcefile common.c:
* common.c contains functions that are common to all
* parts of XFolder. As opposed to /helpers/*, these
* functions work with XFolder only, while the helper
* functions will work with any PM application.
*
* These functions mainly deal with the following features:
* -- global settings;
* -- NLS management;
* -- folder hotkeys;
* -- subclassing folder frame windows. The actual
* window proc for that is fnwpSubclassedFolderFrame
* in xfldr.c though;
* -- extended XFolder message boxes (cmnMessageBox);
* -- querying system sounds (cmnQuerySystemSound).
*
*@@include #define INCL_WINWINDOWMGR
*@@include #define INCL_DOSMODULEMGR
*@@include #include <os2.h>
*@@include #include "xfldr.h" // only for some functions
*@@include #include "common.h"
*/
/*
* 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.
*/
/*
* 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_DOSMODULEMGR
#define INCL_DOSEXCEPTIONS // needed for except.h
#define INCL_DOSSEMAPHORES // needed for xthreads.h
#define INCL_DOSMISC // DosGetMessage etc.
#define INCL_DOSERRORS
#define INCL_WINWINDOWMGR
#define INCL_WINSHELLDATA // profile funcs
#define INCL_WINSYS // presparams, WinQuerySysValue()
#define INCL_WININPUT // WM_BUTTON1DOWN etc.
#define INCL_WINDIALOGS
#define INCL_WINBUTTONS
#define INCL_WINSTDCNR // needed for winh.h
#define INCL_WINLISTBOXES
#define INCL_GPILOGCOLORTABLE
#include <os2.h>
// C library headers
#include <stdio.h>
#include <stdlib.h>
#include <string.h> // mem*, str* functions
#include <setjmp.h> // needed for except.h
#include <assert.h> // needed for except.h
#include <io.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 "undoc.h" // some undocumented stuff
// SOM headers which don't crash with prec. header files
#pragma hdrstop // VAC++ keeps crashing otherwise
#include "xfldr.h"
// headers in /main
#include "dlgids.h" // all the IDs that are shared with NLS
#include "common.h" // the majestic XFolder include file
#include "module.h" // XFolder main DLL information
#include "sound.h" // declarations for SOUND.DLL
#include "except.h" // XFolder exception handling
#include "statbars.h" // status bar translation logic
#include "xshutdwn.h" // needed for default settings
#include "xwps.h" // XFolder pseudo SOM functions
// other SOM headers
#include <wpdesk.h> // WPDesktop
CHAR szHelpLibrary[CCHMAXPATH] = "";
CHAR szMessageFile[CCHMAXPATH] = "";
HMODULE hmodNLS = NULLHANDLE;
PVOID pNLSStringsGlobal = NULL;
PGLOBALSETTINGS pGlobalSettings = NULL;
HMODULE hmodIconsDLL = NULLHANDLE;
CHAR szLanguageCode[20] = "";
ULONG ulCurHelpPanel = 0; // holds help panel for dialog
CHAR szStatusBarFont[100];
CHAR szSBTextNoneSel[CCHMAXMNEMONICS],
szSBTextMultiSel[CCHMAXMNEMONICS];
ULONG ulStatusBarHeight;
/*-------------------------------------------------------------------
* *
* XFolder debugging helpers *
* *
********************************************************************/
#ifdef _PMPRINTF_
/*
*@@ cmnDumpMemoryBlock:
* if _PMPRINTF_ has been #define'd in common.h,
* this will dump a block of memory to the PMPRINTF
* output window. Useful for debugging internal
* structures.
* If _PMPRINTF_ has been NOT #define'd in common.h,
* no code will be produced. :-)
*/
void cmnDumpMemoryBlock(PBYTE pb, // in: start address
ULONG ulSize, // in: size of block
ULONG ulIndent) // in: how many spaces to put
// before each output line
{
PBYTE pbCurrent = pb;
ULONG ulCount = 0,
ulLineCount = 0;
CHAR szLine[400] = "",
szAscii[30] = " ";
PSZ pszLine = szLine,
pszAscii = szAscii;
for (pbCurrent = pb;
ulCount < ulSize;
pbCurrent++, ulCount++)
{
if (ulLineCount == 0) {
memset(szLine, ' ', ulIndent);
pszLine += ulIndent;
}
pszLine += sprintf(pszLine, "%02lX ", *pbCurrent);
if ((*pbCurrent > 31) && (*pbCurrent < 127))
*pszAscii = *pbCurrent;
else
*pszAscii = '.';
pszAscii++;
ulLineCount++;
if ( (ulLineCount > 7) || (ulCount == ulSize-1) )
{
_Pmpf(("%04lX: %s %s",
ulCount-7,
szLine,
szAscii));
pszLine = szLine;
pszAscii = szAscii;
ulLineCount = 0;
}
}
}
#else
// _PMPRINTF not #define'd: do nothing
#define cmnDumpMemoryBlock(pb, ulSize, ulIndent)
#endif
/*-------------------------------------------------------------------
* *
* XFolder module handling *
* *
********************************************************************/
/*
* The following routines are for querying the XFolder
* installation path and similiar routines, such as
* querying the current NLS module, changing it, loading
* strings, the help file and all that sort of stuff.
*/
/*
*@@ cmnQueryXFolderBasePath:
* this routine returns the path of where XFolder was installed,
* i.e. the parent directory of where the xfldr.dll file
* resides, without a trailing backslash (e.g. "C:\XFolder").
* The buffer to copy this to is assumed to be CCHMAXPATH in size.
* As opposed to versions before V0.81, OS2.INI is no longer
* needed for this to work. The path is retrieved from the
* DLL directly by evaluating what was passed to _DLL_InitModule
* (module.*).
*/
BOOL cmnQueryXFolderBasePath(PSZ pszPath)
{
BOOL brc = FALSE;
PSZ pszDLL = modQueryFile();
if (pszDLL) {
// copy until last backslash minus four characters
// (leave out "\bin\xfldr.dll")
PSZ pszLastSlash = strrchr(pszDLL, '\\');
#ifdef DEBUG_LANGCODES
_Pmpf(( "modQueryFile: %s", pszDLL));
#endif
strncpy(pszPath, pszDLL, (pszLastSlash-pszDLL)-4);
pszPath[(pszLastSlash-pszDLL-4)] = '\0';
brc = TRUE;
}
#ifdef DEBUG_LANGCODES
_Pmpf(( "cmnQueryXFolderBasePath: %s", pszPath ));
#endif
return (brc);
}
/*
*@@ cmnQueryLanguageCode:
* returns PSZ to three-digit language code (e.g. "001").
*/
PSZ cmnQueryLanguageCode(VOID)
{
if (szLanguageCode[0] == '\0')
PrfQueryProfileString(HINI_USERPROFILE,
INIAPP_XFOLDER, INIKEY_LANGUAGECODE,
DEFAULT_LANGUAGECODE,
(PVOID)szLanguageCode,
sizeof(szLanguageCode));
szLanguageCode[3] = '\0';
#ifdef DEBUG_LANGCODES
_Pmpf(( "cmnQueryLanguageCode: %s", szLanguageCode ));
#endif
return (szLanguageCode);
}
/*
*@@ cmnSetLanguageCode:
* changes XFolder's language to three-digit language code in
* pszLanguage (e.g. "001"). This does not reload the NLS DLL,
* but only change the setting.
*/
BOOL cmnSetLanguageCode(PSZ pszLanguage)
{
strcpy(szLanguageCode, pszLanguage);
return (PrfWriteProfileString(HINI_USERPROFILE, INIAPP_XFOLDER, INIKEY_LANGUAGECODE,
szLanguageCode));
}
/*
*@@ cmnQueryHelpLibrary:
* returns PSZ to full help library path in XFolder directory,
* depending on where XFolder was installed and on the current
* language (e.g. "C:\XFolder\help\xfldr001.hlp").
*/
PSZ cmnQueryHelpLibrary(VOID)
{
if (cmnQueryXFolderBasePath(szHelpLibrary)) {
// path found: append helpfile
sprintf(szHelpLibrary+strlen(szHelpLibrary),
"\\help\\xfldr%s.hlp",
cmnQueryLanguageCode());
#ifdef DEBUG_LANGCODES
_Pmpf(( "cmnQueryHelpLibrary: %s", szHelpLibrary ));
#endif
return (szHelpLibrary);
} else
return (NULL);
}
/*
*@@ cmnQueryMessageFile:
* returns PSZ to full message file path in XFolder directory,
* depending on where XFolder was installed and on the current
* language (e.g. "C:\XFolder\help\xfldr001.msg").
*/
PSZ cmnQueryMessageFile(VOID)
{
if (cmnQueryXFolderBasePath(szMessageFile)) {
// path found: append message file
sprintf(szMessageFile+strlen(szMessageFile),
"\\help\\xfldr%s.msg",
cmnQueryLanguageCode());
#ifdef DEBUG_LANGCODES
_Pmpf(( "cmnQueryMessageFile: %s", szMessageFile));
#endif
return (szMessageFile);
} else
return (NULL);
}
/*
*@@ cmnQueryIconsDLL:
* this returns the HMODULE of XFolder ICONS.DLL
* (new with V0.84).
* If this is queried for the first time, the DLL
* is loaded from the /BIN directory.
* In this case, this routine also checks if
* ICONS.DLL exists in the /ICONS directory. If
* so, it is copied to /BIN before loading the
* DLL. This allows for replacing the DLL using
* the REXX script in /ICONS.
*
* New with V0.84.
*/
HMODULE cmnQueryIconsDLL(VOID)
{
// first query?
if (hmodIconsDLL == NULLHANDLE)
{
CHAR szIconsDLL[CCHMAXPATH],
szIconsDLL2[CCHMAXPATH];
cmnQueryXFolderBasePath(szIconsDLL);
strcpy(szIconsDLL2, szIconsDLL);
sprintf(szIconsDLL+strlen(szIconsDLL),
"\\bin\\icons.dll");
sprintf(szIconsDLL2+strlen(szIconsDLL2),
"\\icons\\icons.dll");
// first check for /ICONS/ICONS.DLL
if (access(szIconsDLL2, 0) == 0)
{
// exists: then move to /BIN
DosDelete(szIconsDLL);
DosMove(szIconsDLL2, szIconsDLL);
}
// now load /BIN/ICONS.DLL
if (DosLoadModule(NULL,
0,
szIconsDLL,
&hmodIconsDLL))
hmodIconsDLL = NULLHANDLE;
}
return (hmodIconsDLL);
}
/*
*@@ cmnLoadString:
* pretty similar to WinLoadString, but allocates
* necessary memory as well. *ppsz is a pointer
* to a PSZ; if this PSZ is != NULL, whatever it
* points to will be free()d, so you should set this
* to NULL if you initially call this function.
* This is used at WPS startup and when XFolder's
* language is changed later to load all the strings
* from a NLS DLL.
*/
void cmnLoadString(HAB habDesktop, HMODULE hmodResource, ULONG ulID, PSZ *ppsz)
{
CHAR szBuf[200];
if (*ppsz)
free(*ppsz);
if (WinLoadString(habDesktop, hmodResource, ulID , sizeof(szBuf), szBuf))
*ppsz = strcpy(malloc(strlen(szBuf)+1), szBuf);
else
*ppsz = "Error: String resource not found";
}
/*
*@@ cmnQueryNLSModuleHandle:
* returns the module handle of the language-dependent XFolder
* national language support DLL.
*
* This is called in two situations:
* 1) with fEnforceReload == FALSE everytime some part
* of XFolder needs the NLS resources (e.g. for dialogs);
* on the first call, the NLS DLL is loaded into memory.
* 2) with fEnforceReload == TRUE when the user changes
* XFolder's language in the "Workplace Shell" object.
*
* If the DLL is (re)loaded, this function also initializes
* all language-dependent XFolder parts such as the NLSSTRINGS
* structure, which can always be accessed using cmnQueryNLSStrings.
* This function also checks for whether the NLS DLL has a
* decent version level to support this XFolder version.
*/
HMODULE cmnQueryNLSModuleHandle(BOOL fEnforceReload)
{
CHAR szResourceModuleName[CCHMAXPATH];
ULONG ulCopied;
HMODULE hmodOldResource = hmodNLS;
// load resource DLL if it's not loaded yet or a reload is enforced
if ((hmodNLS == NULLHANDLE) || (fEnforceReload))
{
PNLSSTRINGS pNLSStrings = cmnQueryNLSStrings();
// get the XFolder path first
if (cmnQueryXFolderBasePath(szResourceModuleName))
{
// now compose module name from language code
strcat(szResourceModuleName, "\\bin\\xfldr");
strcat(szResourceModuleName, cmnQueryLanguageCode());
strcat(szResourceModuleName, ".dll");
// try to load the module
if (DosLoadModule(NULL,
0,
szResourceModuleName,
&hmodNLS))
{
DebugBox("XFolder: Couldn't Find Resource DLL",
szResourceModuleName);
} else {
// module loaded alright!
HAB habDesktop = WinQueryAnchorBlock(HWND_DESKTOP);
if (habDesktop)
{
if (fEnforceReload) {
// if fEnforceReload == TRUE, we will load a test string from
// the module to see if it has at least the version level which
// this XFolder version requires. This is done using a #define
// in dlgids.h: XFOLDER_VERSION is compiled into both the NLS
// DLL (as a string resource) and into the main DLL (this file),
// so we always have the versions in there automatically.
// MINIMUM_NLS_VERSION (dlgids.h too) contains the minimum
// NLS version level that this XFolder version requires.
CHAR szTest[30] = "";
LONG lLength;
lLength = WinLoadString(habDesktop,
hmodNLS,
ID_XSSI_XFOLDERVERSION,
sizeof(szTest), szTest);
#ifdef DEBUG_LANGCODES
_Pmpf(("%s version: %s", szResourceModuleName, szTest));
#endif
if ( (lLength == 0)
|| (memcmp(szTest, MINIMUM_NLS_VERSION, 4) < 0)
// szTest has NLS version (e.g. "0.81 beta"),
// MINIMUM_NLS_VERSION has minimum version required
// (e.g. "0.90")
)
{
DosBeep(1500, 100);
cmnSetHelpPanel(-1);
if (lLength == 0) {
// version string not found: complain
DebugBox("XFolder", "The requested file is not an XFolder National Language Support DLL.");
DosFreeModule(hmodNLS);
hmodNLS = hmodOldResource;
return NULLHANDLE;
}
else
{
// version level not sufficient:
// load dialog from previous NLS DLL which says
// that the DLL is too old; if user presses
// "Cancel", we abort loading the DLL
DosBeep(1700, 100);
if (WinDlgBox(HWND_DESKTOP,
HWND_DESKTOP,
(PFNWP)fnwpDlgGeneric,
hmodOldResource,
ID_XFD_WRONGVERSION,
(PVOID)NULL)
== DID_CANCEL)
{
DebugBox("XFolder", "The new National Language Support DLL was not loaded.");
// unload new NLS DLL
DosFreeModule(hmodNLS);
hmodNLS = hmodOldResource;
return NULLHANDLE;
}
}
}
}
// now let's load strings
cmnLoadString(habDesktop, hmodNLS, ID_XSSI_NOTDEFINED, &(pNLSStrings->pszNotDefined));
cmnLoadString(habDesktop, hmodNLS, ID_XSSI_PRODUCTINFO, &(pNLSStrings->pszProductInfo));
cmnLoadString(habDesktop, hmodNLS, ID_XSSI_REFRESHNOW, &(pNLSStrings->pszRefreshNow));
cmnLoadString(habDesktop, hmodNLS, ID_XSSI_SNAPTOGRID, &(pNLSStrings->pszSnapToGrid));
cmnLoadString(habDesktop, hmodNLS, ID_XSSI_FLDRCONTENT, &(pNLSStrings->pszFldrContent));
cmnLoadString(habDesktop, hmodNLS, ID_XSSI_COPYFILENAME, &(pNLSStrings->pszCopyFilename));
cmnLoadString(habDesktop, hmodNLS, ID_XSSI_BORED , &(pNLSStrings->pszBored));
cmnLoadString(habDesktop, hmodNLS, ID_XSSI_FLDREMPTY , &(pNLSStrings->pszFldrEmpty));
cmnLoadString(habDesktop, hmodNLS, ID_XSSI_SELECTSOME , &(pNLSStrings->pszSelectSome));
cmnLoadString(habDesktop, hmodNLS, ID_XFSI_QUICKSTATUS , &(pNLSStrings->pszQuickStatus));
cmnLoadString(habDesktop, hmodNLS, ID_XSSI_SV_NAME , &(pNLSStrings->pszSortByName));
cmnLoadString(habDesktop, hmodNLS, ID_XSSI_SV_TYPE , &(pNLSStrings->pszSortByType));
cmnLoadString(habDesktop, hmodNLS, ID_XSSI_SV_CLASS , &(pNLSStrings->pszSortByClass));
cmnLoadString(habDesktop, hmodNLS, ID_XSSI_SV_REALNAME , &(pNLSStrings->pszSortByRealName));
cmnLoadString(habDesktop, hmodNLS, ID_XSSI_SV_SIZE , &(pNLSStrings->pszSortBySize));
cmnLoadString(habDesktop, hmodNLS, ID_XSSI_SV_WRITEDATE, &(pNLSStrings->pszSortByWriteDate));
cmnLoadString(habDesktop, hmodNLS, ID_XSSI_SV_ACCESSDATE, &(pNLSStrings->pszSortByAccessDate));
cmnLoadString(habDesktop, hmodNLS, ID_XSSI_SV_CREATIONDATE, &(pNLSStrings->pszSortByCreationDate));
cmnLoadString(habDesktop, hmodNLS, ID_XSSI_SV_EXT , &(pNLSStrings->pszSortByExt));
cmnLoadString(habDesktop, hmodNLS, ID_XSSI_SV_FOLDERSFIRST, &(pNLSStrings->pszSortFoldersFirst));
cmnLoadString(habDesktop, hmodNLS, ID_XSSI_KEY_CTRL , &(pNLSStrings->pszCtrl));
cmnLoadString(habDesktop, hmodNLS, ID_XSSI_KEY_Alt , &(pNLSStrings->pszAlt));
cmnLoadString(habDesktop, hmodNLS, ID_XSSI_KEY_SHIFT , &(pNLSStrings->pszShift));
cmnLoadString(habDesktop, hmodNLS, ID_XSSI_KEY_BACKSPACE , &(pNLSStrings->pszBackspace));
cmnLoadString(habDesktop, hmodNLS, ID_XSSI_KEY_TAB , &(pNLSStrings->pszTab));
cmnLoadString(habDesktop, hmodNLS, ID_XSSI_KEY_BACKTABTAB , &(pNLSStrings->pszBacktab));
cmnLoadString(habDesktop, hmodNLS, ID_XSSI_KEY_ENTER , &(pNLSStrings->pszEnter));
cmnLoadString(habDesktop, hmodNLS, ID_XSSI_KEY_ESC , &(pNLSStrings->pszEsc));
cmnLoadString(habDesktop, hmodNLS, ID_XSSI_KEY_SPACE , &(pNLSStrings->pszSpace));
cmnLoadString(habDesktop, hmodNLS, ID_XSSI_KEY_PAGEUP , &(pNLSStrings->pszPageup));
cmnLoadString(habDesktop, hmodNLS, ID_XSSI_KEY_PAGEDOWN , &(pNLSStrings->pszPagedown));
cmnLoadString(habDesktop, hmodNLS, ID_XSSI_KEY_END , &(pNLSStrings->pszEnd));
cmnLoadString(habDesktop, hmodNLS, ID_XSSI_KEY_HOME , &(pNLSStrings->pszHome));
cmnLoadString(habDesktop, hmodNLS, ID_XSSI_KEY_LEFT , &(pNLSStrings->pszLeft));
cmnLoadString(habDesktop, hmodNLS, ID_XSSI_KEY_UP , &(pNLSStrings->pszUp));
cmnLoadString(habDesktop, hmodNLS, ID_XSSI_KEY_RIGHT , &(pNLSStrings->pszRight));
cmnLoadString(habDesktop, hmodNLS, ID_XSSI_KEY_DOWN , &(pNLSStrings->pszDown));
cmnLoadString(habDesktop, hmodNLS, ID_XSSI_KEY_PRINTSCRN , &(pNLSStrings->pszPrintscrn));
cmnLoadString(habDesktop, hmodNLS, ID_XSSI_KEY_INSERT , &(pNLSStrings->pszInsert));
cmnLoadString(habDesktop, hmodNLS, ID_XSSI_KEY_DELETE , &(pNLSStrings->pszDelete));
cmnLoadString(habDesktop, hmodNLS, ID_XSSI_KEY_SCRLLOCK , &(pNLSStrings->pszScrlLock));
cmnLoadString(habDesktop, hmodNLS, ID_XSSI_KEY_NUMLOCK , &(pNLSStrings->pszNumLock));
cmnLoadString(habDesktop, hmodNLS, ID_XSSI_KEY_WINLEFT , &(pNLSStrings->pszWinLeft));
cmnLoadString(habDesktop, hmodNLS, ID_XSSI_KEY_WINRIGHT , &(pNLSStrings->pszWinRight));
cmnLoadString(habDesktop, hmodNLS, ID_XSSI_KEY_WINMENU , &(pNLSStrings->pszWinMenu));
cmnLoadString(habDesktop, hmodNLS, ID_SDSI_FLUSHING , &(pNLSStrings->pszSDFlushing));
cmnLoadString(habDesktop, hmodNLS, ID_SDSI_CAD , &(pNLSStrings->pszSDCAD));
cmnLoadString(habDesktop, hmodNLS, ID_SDSI_REBOOTING , &(pNLSStrings->pszSDRebooting));
cmnLoadString(habDesktop, hmodNLS, ID_SDSI_CLOSING , &(pNLSStrings->pszSDClosing));
cmnLoadString(habDesktop, hmodNLS, ID_SDSI_SHUTDOWN , &(pNLSStrings->pszShutdown));
cmnLoadString(habDesktop, hmodNLS, ID_SDSI_RESTARTWPS , &(pNLSStrings->pszRestartWPS));
cmnLoadString(habDesktop, hmodNLS, ID_SDSI_RESTARTINGWPS , &(pNLSStrings->pszSDRestartingWPS));
cmnLoadString(habDesktop, hmodNLS, ID_SDSI_SAVINGDESKTOP , &(pNLSStrings->pszSDSavingDesktop));
cmnLoadString(habDesktop, hmodNLS, ID_SDSI_SAVINGPROFILES , &(pNLSStrings->pszSDSavingProfiles));
cmnLoadString(habDesktop, hmodNLS, ID_SDSI_STARTING , &(pNLSStrings->pszStarting));
cmnLoadString(habDesktop, hmodNLS, ID_XSSI_POPULATING , &(pNLSStrings->pszPopulating));
cmnLoadString(habDesktop, hmodNLS, ID_XSSI_1GENERIC , &(pNLSStrings->psz1Generic));
cmnLoadString(habDesktop, hmodNLS, ID_XSSI_2REMOVEITEMS , &(pNLSStrings->psz2RemoveItems));
cmnLoadString(habDesktop, hmodNLS, ID_XSSI_25ADDITEMS , &(pNLSStrings->psz25AddItems));
cmnLoadString(habDesktop, hmodNLS, ID_XSSI_26CONFIGITEMS , &(pNLSStrings->psz26ConfigFolderMenus));
cmnLoadString(habDesktop, hmodNLS, ID_XSSI_27STATUSBAR , &(pNLSStrings->psz27StatusBar));
cmnLoadString(habDesktop, hmodNLS, ID_XSSI_3SNAPTOGRID , &(pNLSStrings->psz3SnapToGrid));
cmnLoadString(habDesktop, hmodNLS, ID_XSSI_4ACCELERATORS , &(pNLSStrings->psz4Accelerators));
cmnLoadString(habDesktop, hmodNLS, ID_XSSI_5INTERNALS , &(pNLSStrings->psz5Internals));
cmnLoadString(habDesktop, hmodNLS, ID_XSSI_FILEOPS , &(pNLSStrings->pszFileOps));
cmnLoadString(habDesktop, hmodNLS, ID_XSSI_SORT , &(pNLSStrings->pszSort));
cmnLoadString(habDesktop, hmodNLS, ID_XSSI_SV_ALWAYSSORT , &(pNLSStrings->pszAlwaysSort));
cmnLoadString(habDesktop, hmodNLS, ID_XSSI_INTERNALS , &(pNLSStrings->pszInternals));
cmnLoadString(habDesktop, hmodNLS, ID_XSSI_SB_CLASSMNEMONICS , &(pNLSStrings->pszSBClassMnemonics));
cmnLoadString(habDesktop, hmodNLS, ID_XSSI_SB_CLASSNOTSUPPORTED, &(pNLSStrings->pszSBClassNotSupported));
cmnLoadString(habDesktop, hmodNLS, ID_XSSI_WPSCLASSES , &(pNLSStrings->pszWpsClasses));
cmnLoadString(habDesktop, hmodNLS, ID_XSSI_WPSCLASSLOADED , &(pNLSStrings->pszWpsClassLoaded));
cmnLoadString(habDesktop, hmodNLS, ID_XSSI_WPSCLASSLOADINGFAILED, &(pNLSStrings->pszWpsClassLoadingFailed));
cmnLoadString(habDesktop, hmodNLS, ID_XSSI_WPSCLASSREPLACEDBY, &(pNLSStrings->pszWpsClassReplacedBy));
cmnLoadString(habDesktop, hmodNLS, ID_XSSI_WPSCLASSORPHANS , &(pNLSStrings->pszWpsClassOrphans));
cmnLoadString(habDesktop, hmodNLS, ID_XSSI_WPSCLASSORPHANSINFO, &(pNLSStrings->pszWpsClassOrphansInfo));
cmnLoadString(habDesktop, hmodNLS, ID_XSSI_SCHEDULER , &(pNLSStrings->pszScheduler));
cmnLoadString(habDesktop, hmodNLS, ID_XSSI_MEMORY , &(pNLSStrings->pszMemory));
cmnLoadString(habDesktop, hmodNLS, ID_XSSI_ERRORS , &(pNLSStrings->pszErrors));
cmnLoadString(habDesktop, hmodNLS, ID_XSSI_WPS , &(pNLSStrings->pszWPS));
cmnLoadString(habDesktop, hmodNLS, ID_XSSI_PROCESSCONTENT , &(pNLSStrings->pszProcessContent));
cmnLoadString(habDesktop, hmodNLS, ID_XFSI_SETTINGS , &(pNLSStrings->pszSettings));
cmnLoadString(habDesktop, hmodNLS, ID_XFSI_SETTINGSNOTEBOOK,&(pNLSStrings->pszSettingsNotebook));
cmnLoadString(habDesktop, hmodNLS, ID_XFSI_ATTRIBUTES , &(pNLSStrings->pszAttributes));
cmnLoadString(habDesktop, hmodNLS, ID_XFSI_ATTR_ARCHIVED , &(pNLSStrings->pszAttrArchived));
cmnLoadString(habDesktop, hmodNLS, ID_XFSI_ATTR_SYSTEM , &(pNLSStrings->pszAttrSystem));
cmnLoadString(habDesktop, hmodNLS, ID_XFSI_ATTR_HIDDEN , &(pNLSStrings->pszAttrHidden));
cmnLoadString(habDesktop, hmodNLS, ID_XFSI_ATTR_READONLY , &(pNLSStrings->pszAttrReadOnly));
cmnLoadString(habDesktop, hmodNLS, ID_XFSI_FLDRSETTINGS , &(pNLSStrings->pszWarp3FldrView));
cmnLoadString(habDesktop, hmodNLS, ID_XFSI_SMALLICONS , &(pNLSStrings->pszSmallIcons ));
cmnLoadString(habDesktop, hmodNLS, ID_XFSI_FLOWED , &(pNLSStrings->pszFlowed));
cmnLoadString(habDesktop, hmodNLS, ID_XFSI_NONFLOWED , &(pNLSStrings->pszNonFlowed));
cmnLoadString(habDesktop, hmodNLS, ID_XFSI_NOGRID , &(pNLSStrings->pszNoGrid));
cmnLoadString(habDesktop, hmodNLS, ID_XFSI_SHOWSTATUSBAR , &(pNLSStrings->pszShowStatusBar));
}
// after all this, unload the old resource module
DosFreeModule(hmodOldResource);
} // end else
}
}
// return (new?) module handle
return (hmodNLS);
}
/*
*@@ cmnQueryNLSStrings:
* returns pointer to global NLSSTRINGS structure which contains
* all the language-dependent XFolder strings from the resource
* files.
*/
PNLSSTRINGS cmnQueryNLSStrings(VOID)
{
if (pNLSStringsGlobal == NULL) {
pNLSStringsGlobal = malloc(sizeof(NLSSTRINGS));
memset(pNLSStringsGlobal, 0, sizeof(NLSSTRINGS));
}
return (pNLSStringsGlobal);
}
/*-------------------------------------------------------------------
* *
* XFolder Global Settings *
* *
********************************************************************/
/*
*@@ cmnQueryStatusBarSetting:
* returns a PSZ to a certain status bar setting, which
* may be:
* -- SBS_STATUSBARFONT font (e.g. "9.WarpSans")
* -- SBS_TEXTNONESEL mnemonics for no-object mode
* -- SBS_TEXTMULTISEL mnemonics for multi-object mode
*
* Note that there is no key for querying the mnemonics for
* one-object mode, because this is now handled by the
* functions in statbars.c
* to provide different data depending on the
* class of the selected object.
*/
PSZ cmnQueryStatusBarSetting(USHORT usSetting)
{
switch (usSetting) {
case SBS_STATUSBARFONT:
return (szStatusBarFont);
case SBS_TEXTNONESEL:
return (szSBTextNoneSel);
case SBS_TEXTMULTISEL:
return (szSBTextMultiSel);
default:
return (NULL);
}
}
/*
*@@ cmnSetStatusBarSetting:
* sets usSetting to pszSetting. If pszSetting == NULL, the
* default value will be loaded from the XFolder NLS DLL.
* usSetting works just like in cmnQueryStatusBarSetting.
*/
BOOL cmnSetStatusBarSetting(USHORT usSetting, PSZ pszSetting)
{
HAB habDesktop = WinQueryAnchorBlock(HWND_DESKTOP);
HMODULE hmodResource = cmnQueryNLSModuleHandle(FALSE);
switch (usSetting) {
case SBS_STATUSBARFONT: {
CHAR szDummy[CCHMAXMNEMONICS];
if (pszSetting) {
strcpy(szStatusBarFont, pszSetting);
PrfWriteProfileString(HINI_USERPROFILE, INIAPP_XFOLDER, INIKEY_STATUSBARFONT,
szStatusBarFont);
} else
strcpy(szStatusBarFont, "8.Helv");
sscanf(szStatusBarFont, "%d.%s", &(ulStatusBarHeight), &szDummy);
ulStatusBarHeight += 15;
break; }
case SBS_TEXTNONESEL: {
if (pszSetting) {
strcpy(szSBTextNoneSel, pszSetting);
PrfWriteProfileString(HINI_USERPROFILE, INIAPP_XFOLDER, INIKEY_SBTEXTNONESEL,
szSBTextNoneSel);
} else
WinLoadString(habDesktop, hmodResource, ID_XSSI_SBTEXTNONESEL,
sizeof(szSBTextNoneSel), szSBTextNoneSel);
break; }
case SBS_TEXTMULTISEL: {
if (pszSetting) {
strcpy(szSBTextMultiSel, pszSetting);
PrfWriteProfileString(HINI_USERPROFILE, INIAPP_XFOLDER, INIKEY_SBTEXTMULTISEL,
szSBTextMultiSel);
} else
WinLoadString(habDesktop, hmodResource, ID_XSSI_SBTEXTMULTISEL,
sizeof(szSBTextMultiSel), szSBTextMultiSel);
break; }
default:
return (FALSE);
}
return (TRUE);
}
/*
*@@ cmnQueryStatusBarHeight:
* returns the height of the status bars according to the
* current settings in pixels. This was calculated when
* the status bar font was set.
*/
ULONG cmnQueryStatusBarHeight(VOID)
{
return (ulStatusBarHeight);
}
/*
*@@ cmnLoadGlobalSettings:
* this loads the Global Settings from the INI files; should
* not be called directly, because this is done automatically
* by cmnQueryGlobalSettings, if necessary.
*/
PGLOBALSETTINGS cmnLoadGlobalSettings(VOID)
{
ULONG ulCopied1;
if (pGlobalSettings == NULL) {
pGlobalSettings = malloc(sizeof(GLOBALSETTINGS));
memset(pGlobalSettings, 0, sizeof(GLOBALSETTINGS));
}
// first set default settings for each settings page;
// we only load the "real" settings from OS2.INI afterwards
// because the user might have updated XFolder, and the
// settings struct in the INIs might be too short
cmnSetDefaultSettings(SP_1GENERIC );
cmnSetDefaultSettings(SP_2REMOVEITEMS );
cmnSetDefaultSettings(SP_25ADDITEMS );
cmnSetDefaultSettings(SP_26CONFIGITEMS );
cmnSetDefaultSettings(SP_27STATUSBAR );
cmnSetDefaultSettings(SP_3SNAPTOGRID );
cmnSetDefaultSettings(SP_4ACCELERATORS );
cmnSetDefaultSettings(SP_5INTERNALS );
cmnSetDefaultSettings(SP_DTP1 );
cmnSetDefaultSettings(SP_DTP2 );
cmnSetDefaultSettings(SP_FLDRSORT_GLOBAL );
cmnSetDefaultSettings(SP_FILEOPS );
// set global settings w/out settings page
pGlobalSettings->ShowBootupStatus = 0;
pGlobalSettings->WpsShowClassInfo = 1;
PrfQueryProfileString(HINI_USERPROFILE, INIAPP_XFOLDER, INIKEY_STATUSBARFONT,
"8.Helv", &(szStatusBarFont), sizeof(szStatusBarFont));
sscanf(szStatusBarFont, "%d.*%s", &(ulStatusBarHeight));
ulStatusBarHeight += 15;
PrfQueryProfileString(HINI_USERPROFILE, INIAPP_XFOLDER, INIKEY_SBTEXTNONESEL,
NULL, &(szSBTextNoneSel), sizeof(szSBTextNoneSel));
PrfQueryProfileString(HINI_USERPROFILE, INIAPP_XFOLDER, INIKEY_SBTEXTMULTISEL,
NULL, &(szSBTextMultiSel), sizeof(szSBTextMultiSel));
ulCopied1 = sizeof(GLOBALSETTINGS);
// get global XFolder settings from OS2.INI
PrfQueryProfileData(HINI_USERPROFILE, INIAPP_XFOLDER, INIKEY_GLOBALSETTINGS,
pGlobalSettings, &ulCopied1);
return (pGlobalSettings);
}
/*
*@@ cmnQueryGlobalSettings:
* returns pointer to the GLOBALSETTINGS structure which
* contains the XFolder Global Settings valid for all
* classes. Loads the settings from the INI files if this
* hasn't been done yet. Used all the time throughout XFolder.
*/
PGLOBALSETTINGS cmnQueryGlobalSettings(VOID)
{
if (pGlobalSettings == NULL) {
cmnLoadGlobalSettings();
}
return (pGlobalSettings);
}
/*
*@@ cmnStoreGlobalSettings:
* stores the current Global Settings back into the INI files;
* returns TRUE if successful.
*/
BOOL cmnStoreGlobalSettings(VOID)
{
return (PrfWriteProfileData(HINI_USERPROFILE, INIAPP_XFOLDER, INIKEY_GLOBALSETTINGS,
pGlobalSettings, sizeof(GLOBALSETTINGS)));
}
/*
*@@ cmnSetDefaultSettings:
* resets those Global Settings which correspond to usSettingsPage
* in the System notebook to the default values; usSettingsPage
* may have 1 thru the number of XFolder Settings pages in the
* System notebook (SP_* flags). This is used to initialize
* XFolder settings at startup and by the "Default" buttons on
* the notebook settings pages.
*/
BOOL cmnSetDefaultSettings(USHORT usSettingsPage)
{
// HMODULE hmodResource = cmnQueryNLSModuleHandle(FALSE);
switch(usSettingsPage) {
case SP_1GENERIC: {
pGlobalSettings->ShowInternals = 1;
pGlobalSettings->ReplIcons = 1;
pGlobalSettings->FullPath = 1;
pGlobalSettings->KeepTitle = 1;
pGlobalSettings->MaxPathChars = 25;
pGlobalSettings->TreeViewAutoScroll = 1;
break; }
case SP_2REMOVEITEMS: {
pGlobalSettings->DefaultMenuItems = 0;
pGlobalSettings->RemoveLockInPlaceItem = 0;
pGlobalSettings->RemoveCheckDiskItem = 0;
pGlobalSettings->RemoveFormatDiskItem = 0;
pGlobalSettings->RemoveViewMenu = 0;
pGlobalSettings->RemovePasteItem = 0;
break; }
case SP_25ADDITEMS: {
pGlobalSettings->FileAttribs = 1;
pGlobalSettings->AddCopyFilenameItem = 1;
pGlobalSettings->ExtendFldrViewMenu = 1;
pGlobalSettings->MoveRefreshNow = (doshIsWarp4() ? 1 : 0);
pGlobalSettings->AddSelectSomeItem = 1;
pGlobalSettings->AddFolderContentItem = 1;
pGlobalSettings->FCShowIcons = 0;
break; }
case SP_26CONFIGITEMS: {
pGlobalSettings->MenuCascadeMode = 0;
pGlobalSettings->RemoveX = 1;
pGlobalSettings->AppdParam = 1;
pGlobalSettings->TemplatesOpenSettings = BM_INDETERMINATE;
pGlobalSettings->TemplatesReposition = 1;
break; }
case SP_27STATUSBAR: {
pGlobalSettings->StatusBar = 0;
pGlobalSettings->SBStyle = (doshIsWarp4() ? SBSTYLE_WARP4MENU : SBSTYLE_WARP3RAISED);
pGlobalSettings->SBForViews = SBV_ICON | SBV_DETAILS;
pGlobalSettings->lSBBgndColor = WinQuerySysColor(HWND_DESKTOP, SYSCLR_INACTIVEBORDER, 0);
pGlobalSettings->lSBTextColor = WinQuerySysColor(HWND_DESKTOP, SYSCLR_OUTPUTTEXT, 0);
cmnSetStatusBarSetting(SBS_TEXTNONESEL, NULL);
cmnSetStatusBarSetting(SBS_TEXTMULTISEL, NULL);
break; }
case SP_3SNAPTOGRID: {
pGlobalSettings->AddSnapToGridItem = 1;
pGlobalSettings->GridX = 15;
pGlobalSettings->GridY = 10;
pGlobalSettings->GridCX = 20;
pGlobalSettings->GridCY = 35;
break; }
case SP_4ACCELERATORS: {
pGlobalSettings->Accelerators = 1;
break; }
case SP_5INTERNALS: {
pGlobalSettings->VarMenuOffset = 300;
pGlobalSettings->NoWorkerThread = 0;
pGlobalSettings->NoSubclassing = 0;
pGlobalSettings->ShowXFolderAnim = 1;
break; }
case SP_DTP1: { // shutdown page
pGlobalSettings->ulXShutdownFlags =
XSD_RESTARTWPS | XSD_WPS_CLOSEWINDOWS | XSD_CONFIRM | XSD_REBOOT | XSD_ANIMATE;
break; }
case SP_DTP2: {
pGlobalSettings->ShowStartupProgress = 1;
pGlobalSettings->ulStartupDelay = 1000;
break; }
case SP_FLDRSORT_GLOBAL: {
pGlobalSettings->ReplaceSort = 0;
pGlobalSettings->DefaultSort = SV_NAME;
pGlobalSettings->AlwaysSort = 0;
break; }
case SP_FILEOPS: {
pGlobalSettings->ReplConfirms = 1;
pGlobalSettings->CleanupINIs = 1;
break; }
}
return (TRUE);
}
/*-------------------------------------------------------------------
* *
* Folder hotkey functions *
* *
********************************************************************/
/*
* The folder hotkeys are stored in a static array which
* is is FLDRHOTKEYCOUNT items in size. This is calculated
* at compile time according to the items which were
* declared in dlgids.h.
*
* The following functions give the other XFolder parts
* access to this data and/or manipulate it.
*/
// XFolder folder hotkeys static array
XFLDHOTKEY FolderHotkeys[FLDRHOTKEYCOUNT];
/*
*@@ cmnQueryFldrHotkeys:
* this returns the address of the static
* folder hotkeys array in common.c. The
* size of that array is FLDRHOTKEYSSIZE (common.h).
*/
PXFLDHOTKEY cmnQueryFldrHotkeys(VOID) {
return (&FolderHotkeys[0]);
}
/*
*@@ cmnLoadDefaultFldrHotkeys:
* this resets the folder hotkeys to the default
* values.
*/
void cmnLoadDefaultFldrHotkeys(VOID)
{
// Ctrl+A: Select all
FolderHotkeys[0].usKeyCode = (USHORT)'a';
FolderHotkeys[0].usFlags = KC_CTRL;
FolderHotkeys[0].usCommand = WPMENUID_SELALL;
// F5
FolderHotkeys[1].usKeyCode = VK_F5;
FolderHotkeys[1].usFlags = KC_VIRTUALKEY;
FolderHotkeys[1].usCommand = WPMENUID_REFRESH,
// Backspace
FolderHotkeys[2].usKeyCode = VK_BACKSPACE;
FolderHotkeys[2].usFlags = KC_VIRTUALKEY;
FolderHotkeys[2].usCommand = ID_XFMI_OFS_OPENPARENT;
// Ctrl+D: De-select all
FolderHotkeys[3].usKeyCode = (USHORT)'d';
FolderHotkeys[3].usFlags = KC_CTRL;
FolderHotkeys[3].usCommand = WPMENUID_DESELALL;
// Ctrl+Shift+D: Details view
FolderHotkeys[4].usKeyCode = (USHORT)'D';
FolderHotkeys[4].usFlags = KC_CTRL+KC_SHIFT;
FolderHotkeys[4].usCommand = WPMENUID_DETAILS;
// Ctrl+Shift+I: Icon view
FolderHotkeys[5].usKeyCode = (USHORT)'I';
FolderHotkeys[5].usFlags = KC_CTRL+KC_SHIFT;
FolderHotkeys[5].usCommand = WPMENUID_ICON;
// Ctrl+Shift+S: Open Settings
FolderHotkeys[6].usKeyCode = (USHORT)'S';
FolderHotkeys[6].usFlags = KC_CTRL+KC_SHIFT;
FolderHotkeys[6].usCommand = WPMENUID_PROPERTIES;
// Ctrl+N: Sort by name
FolderHotkeys[7].usKeyCode = (USHORT)'n';
FolderHotkeys[7].usFlags = KC_CTRL;
FolderHotkeys[7].usCommand = ID_WPMI_SORTBYNAME;
// Ctrl+Z: Sort by size
FolderHotkeys[8].usKeyCode = (USHORT)'z';
FolderHotkeys[8].usFlags = KC_CTRL;
FolderHotkeys[8].usCommand = ID_WPMI_SORTBYSIZE;
// Ctrl+E: Sort by extension (NPS)
FolderHotkeys[9].usKeyCode = (USHORT)'e';
FolderHotkeys[9].usFlags = KC_CTRL;
FolderHotkeys[9].usCommand = ID_XFMI_OFS_SORTBYEXT;
// Ctrl+W: Sort by write date
FolderHotkeys[10].usKeyCode = (USHORT)'w';
FolderHotkeys[10].usFlags = KC_CTRL;
FolderHotkeys[10].usCommand = ID_WPMI_SORTBYWRITEDATE;
// Ctrl+Y: Sort by type
FolderHotkeys[11].usKeyCode = (USHORT)'y';
FolderHotkeys[11].usFlags = KC_CTRL;
FolderHotkeys[11].usCommand = ID_WPMI_SORTBYTYPE;
// Shift+Backspace
FolderHotkeys[12].usKeyCode = VK_BACKSPACE;
FolderHotkeys[12].usFlags = KC_VIRTUALKEY+KC_SHIFT;
FolderHotkeys[12].usCommand = ID_XFMI_OFS_OPENPARENTANDCLOSE;
// Ctrl+S: Select by name
FolderHotkeys[13].usKeyCode = (USHORT)'s';
FolderHotkeys[13].usFlags = KC_CTRL;
FolderHotkeys[13].usCommand = ID_XFMI_OFS_SELECTSOME;
// Ctrl+insert: copy filename (w/out path)
FolderHotkeys[14].usKeyCode = VK_INSERT;
FolderHotkeys[14].usFlags = KC_VIRTUALKEY+KC_CTRL;
FolderHotkeys[14].usCommand = ID_XFMI_OFS_COPYFILENAME_SHORT;
FolderHotkeys[15].usCommand = 0;
}
/*
*@@ cmnLoadFolderHotkeys:
* this initializes the folder hotkey array with
* the data which was previously stored in OS2.INI.
*/
void cmnLoadFolderHotkeys(VOID)
{
ULONG ulCopied2 = sizeof(FolderHotkeys);
if (!PrfQueryProfileData(HINI_USERPROFILE, INIAPP_XFOLDER, INIKEY_ACCELERATORS,
&FolderHotkeys, &ulCopied2))
cmnLoadDefaultFldrHotkeys();
}
/*
*@@ cmnStoreFldrHotkeys:
* this stores the folder hotkeys in OS2.INI.
*/
void cmnStoreFldrHotkeys(VOID)
{
SHORT i2 = 0;
// store only the accels that are actually used
while (FolderHotkeys[i2].usCommand)
i2++;
PrfWriteProfileData(HINI_USERPROFILE, INIAPP_XFOLDER, INIKEY_ACCELERATORS,
&FolderHotkeys, (i2+1) * sizeof(XFLDHOTKEY));
}
/*
*@@ cmnProcessFldrHotkey:
* this is called by the subclassed folder frame wnd proc
* to check for whether a given WM_CHAR message matches
* one of the folder hotkeys.
*
* The parameters are those of the WM_CHAR message. This
* returns TRUE if the pressed key was a hotkey; in that
* case, the corresponding WM_COMMAND message is
* automatically posted to the folder frame, which will
* cause the defined action to occur.
*/
BOOL cmnProcessFldrHotkey(HWND hwndFrame, MPARAM mp1, MPARAM mp2)
{
USHORT us;
USHORT usFlags = SHORT1FROMMP(mp1);
USHORT usch = SHORT1FROMMP(mp2);
USHORT usvk = SHORT2FROMMP(mp2);
USHORT usKeyCode = 0;
PGLOBALSETTINGS pGlobalSettings = cmnQueryGlobalSettings();
// now check if the key is relevant: filter out KEY UP
// messages and check if either a virtual key (such as F5)
// or Ctrl or Alt was pressed
if ( ((usFlags & KC_KEYUP) == 0)
&& ( ((usFlags & KC_VIRTUALKEY) != 0)
// Ctrl pressed?
|| ((usFlags & KC_CTRL) != 0)
// Alt pressed?
|| ((usFlags & KC_ALT) != 0)
// or one of the Win95 keys?
|| ( ((usFlags & KC_VIRTUALKEY) == 0)
&& ( (usch == 0xEC00)
|| (usch == 0xED00)
|| (usch == 0xEE00)
)
)
)
)
{
if (usFlags & KC_VIRTUALKEY)
usKeyCode = usvk;
else
usKeyCode = usch;
usFlags &= (KC_VIRTUALKEY | KC_CTRL | KC_ALT | KC_SHIFT);
us = 0;
#ifdef DEBUG_KEYS
_Pmpf(("cmnProcessFldrHotkey: usKeyCode: 0x%lX, usFlags: 0x%lX", usKeyCode, usFlags));
#endif
// now go through the global accelerator list and check
// if the pressed key was assigned an action to
while (FolderHotkeys[us].usCommand)
{
USHORT usCommand;
if (
( (FolderHotkeys[us].usFlags == usFlags)
&& (FolderHotkeys[us].usKeyCode == usKeyCode)
)
)
{ // OK: this is a hotkey; find the corresponding
// "command" (= menu ID) and post it to the frame
// window, which will execute it
usCommand = FolderHotkeys[us].usCommand;
if ( (usCommand >= WPMENUID_USER) &&
(usCommand < WPMENUID_USER+FIRST_VARIABLE) )
usCommand += pGlobalSettings->VarMenuOffset;
WinPostMsg(hwndFrame,
WM_COMMAND,
(MPARAM)usCommand,
MPFROM2SHORT(CMDSRC_MENU,
FALSE) ); // results from keyboard operation
#ifdef DEBUG_KEYS
_Pmpf((" Posting command 0x%lX", usCommand));
#endif
return (TRUE);
}
us++;
}
}
return (FALSE);
}
/*
*@@ cmnDescribeKey:
* this stores a description of a certain
* key into pszBuf, using the NLS DLL strings.
* usFlags must contain usFlags from WM_CHAR,
* usKeyCode must be either usch (char code)
* or, with virtual keys, usvk (vk code).
* Returns TRUE if this was a valid key combo.
*/
BOOL cmnDescribeKey(PSZ pszBuf, USHORT usFlags, USHORT usKeyCode)
{
BOOL rc = TRUE;
PNLSSTRINGS pNLSStrings = cmnQueryNLSStrings();
*pszBuf = 0;
if (usFlags & KC_CTRL)
strcpy(pszBuf, pNLSStrings->pszCtrl);
if (usFlags & KC_SHIFT)
strcat(pszBuf, pNLSStrings->pszShift);
if (usFlags & KC_ALT)
strcat(pszBuf, pNLSStrings->pszAlt);
if (usFlags & KC_VIRTUALKEY) {
switch (usKeyCode) {
case VK_BACKSPACE: strcat(pszBuf, pNLSStrings->pszBackspace); break;
case VK_TAB: strcat(pszBuf, pNLSStrings->pszTab); break;
case VK_BACKTAB: strcat(pszBuf, pNLSStrings->pszBacktab); break;
case VK_NEWLINE: strcat(pszBuf, pNLSStrings->pszEnter); break;
case VK_ESC: strcat(pszBuf, pNLSStrings->pszEsc); break;
case VK_SPACE: strcat(pszBuf, pNLSStrings->pszSpace); break;
case VK_PAGEUP: strcat(pszBuf, pNLSStrings->pszPageup); break;
case VK_PAGEDOWN: strcat(pszBuf, pNLSStrings->pszPagedown); break;
case VK_END: strcat(pszBuf, pNLSStrings->pszEnd); break;
case VK_HOME: strcat(pszBuf, pNLSStrings->pszHome); break;
case VK_LEFT: strcat(pszBuf, pNLSStrings->pszLeft); break;
case VK_UP: strcat(pszBuf, pNLSStrings->pszUp); break;
case VK_RIGHT: strcat(pszBuf, pNLSStrings->pszRight); break;
case VK_DOWN: strcat(pszBuf, pNLSStrings->pszDown); break;
case VK_PRINTSCRN: strcat(pszBuf, pNLSStrings->pszPrintscrn); break;
case VK_INSERT: strcat(pszBuf, pNLSStrings->pszInsert); break;
case VK_DELETE: strcat(pszBuf, pNLSStrings->pszDelete); break;
case VK_SCRLLOCK: strcat(pszBuf, pNLSStrings->pszScrlLock); break;
case VK_NUMLOCK: strcat(pszBuf, pNLSStrings->pszNumLock); break;
case VK_ENTER: strcat(pszBuf, pNLSStrings->pszEnter); break;
case VK_F1: strcat(pszBuf, "F1"); break;
case VK_F2: strcat(pszBuf, "F2"); break;
case VK_F3: strcat(pszBuf, "F3"); break;
case VK_F4: strcat(pszBuf, "F4"); break;
case VK_F5: strcat(pszBuf, "F5"); break;
case VK_F6: strcat(pszBuf, "F6"); break;
case VK_F7: strcat(pszBuf, "F7"); break;
case VK_F8: strcat(pszBuf, "F8"); break;
case VK_F9: strcat(pszBuf, "F9"); break;
case VK_F10: strcat(pszBuf, "F10"); break;
case VK_F11: strcat(pszBuf, "F11"); break;
case VK_F12: strcat(pszBuf, "F12"); break;
case VK_F13: strcat(pszBuf, "F13"); break;
case VK_F14: strcat(pszBuf, "F14"); break;
case VK_F15: strcat(pszBuf, "F15"); break;
case VK_F16: strcat(pszBuf, "F16"); break;
case VK_F17: strcat(pszBuf, "F17"); break;
case VK_F18: strcat(pszBuf, "F18"); break;
case VK_F19: strcat(pszBuf, "F19"); break;
case VK_F20: strcat(pszBuf, "F20"); break;
case VK_F21: strcat(pszBuf, "F21"); break;
case VK_F22: strcat(pszBuf, "F22"); break;
case VK_F23: strcat(pszBuf, "F23"); break;
case VK_F24: strcat(pszBuf, "F24"); break;
default: break;
}
} // end virtualkeys
else {
switch (usKeyCode) {
case 0xEC00: strcat(pszBuf, pNLSStrings->pszWinLeft); break;
case 0xED00: strcat(pszBuf, pNLSStrings->pszWinRight); break;
case 0xEE00: strcat(pszBuf, pNLSStrings->pszWinMenu); break;
default: {
CHAR szTemp[2];
if (usKeyCode >= 'a')
szTemp[0] = (CHAR)usKeyCode-32;
else
szTemp[0] = (CHAR)usKeyCode;
szTemp[1] = '\0';
strcat(pszBuf, szTemp);
}
}
}
#ifdef DEBUG_KEYS
_Pmpf(("Key: %s, usKeyCode: 0x%lX, usFlags: 0x%lX", pszBuf, usKeyCode, usFlags));
#endif
return (rc);
}
/*-------------------------------------------------------------------
* *
* Folder frame window subclassing *
* *
********************************************************************/
// root of linked list to remember original window
// procedures when subclassing frame windows for folder hotkeys;
// this list is maintained by wpOpen of XFolder
PSUBCLASSEDLISTITEM psliSubclassed = NULL;
// mutex semaphore for access to this list
HMTX hmtxSubclassed = NULLHANDLE;
/*
*@@ cmnInitPSLI:
* this is called once from M_XFolder::wpclsInitData
* to initialize the SUBCLASSEDLISTITEM list.
*/
VOID cmnInitPSLI(VOID)
{
if (DosCreateMutexSem(NULL,
&hmtxSubclassed, 0, FALSE) != NO_ERROR)
{
DosBeep(100, 300);
hmtxSubclassed = -1;
}
}
/*
*@@ cmnQueryPSLI:
* this retrieves the PSUBCLASSEDLISTITEM from the
* global linked list of subclassed frame windows,
* according to a given frame wnd handle. One of these
* structs is maintained for each open folder view
* to store window data which is needed everywhere.
*/
PSUBCLASSEDLISTITEM cmnQueryPSLI(HWND hwndFrame)
{
PSUBCLASSEDLISTITEM psli = NULL;
BOOL fSemOwned = FALSE;
TRY_QUIET(excpt1)
{
if (hwndFrame)
{
fSemOwned = (DosRequestMutexSem(hmtxSubclassed, 4000) == NO_ERROR);
if (fSemOwned)
{
psli = psliSubclassed;
while (psli) {
if (psli->hwndFrame == hwndFrame) {
/* pfnwpLast = pfnwpOriginal;
hwndLast = hwndFrame;
somSelfLast = somSelf; */
break; // while
}
else
psli = psli->pNext;
}
DosReleaseMutexSem(hmtxSubclassed);
fSemOwned = FALSE;
}
}
}
CATCH(excpt1)
{
if (fSemOwned) {
DosReleaseMutexSem(hmtxSubclassed);
fSemOwned = FALSE;
}
} END_CATCH;
return (psli);
}
/*
*@@ cmnSubclassFolderFrame:
* this routine is used by both XFolder::wpOpen and
* XFldDisk::wpOpen to subclass a new frame window
* to allow for extra XFolder features.
*
* For this, this routines maintains a global linked
* list of subclassed windows (SUBCLASSEDLISTITEM
* structures), whose first item is stored in the global
* psliSubclassed variable. This is protected internally
* by a mutex semaphore; you should therefore always
* use cmnQueryPSLI to access that list.
*
* Every list item contains (among other things) the
* original wnd proc of the subclassed window, which the
* subclassed wnd proc (fnwpSubclassedFolderFrame, xfldr.c)
* needs to call the the original folder wnd proc for a
* given frame window, because these procs might differ
* depending on the class or view type or installed WPS
* enhancers.
*
* These list items are also used for various other frame
* data, such as the handles of the status bar and
* supplementary object windows.
* We cannot store this data elsewhere, because QWL_USER
* in the wnd data seems to be used by the WPS already.
*
* Note: when called from XFolder::wpOpen, somSelf and
* pRealObject both point to the folder. However, when
* called from XFldDisk::wpOpen, somSelf has the
* disk object's root folder, while pRealObject has the
* disk object. Both are stored in the SUBCLASSEDLISTITEM
* structure.
*
* This func returns the newly created SUBCLASSEDLISTITEM.
*/
PSUBCLASSEDLISTITEM cmnSubclassFolderFrame(HWND hwndFrame,
// in: frame wnd of new view (returned by wpOpen)
XFolder *somSelf,
// in: folder; either XFolder's somSelf
// or XFldDisk's root folder
WPObject *pRealObject,
// in: the "real" object; for XFolder, this is == somSelf,
// for XFldDisk, this is the disk object (needed for object handles)
ULONG ulView)
// OPEN_CONTENTS et al.
{
BOOL fSemOwned = FALSE;
PFNWP pfnwpCurrent, pfnwpOriginal;
HWND hwndCnr;
PSUBCLASSEDLISTITEM pNewItem = NULL;
PGLOBALSETTINGS pGlobalSettings = cmnQueryGlobalSettings();
TRY_QUIET(excpt1)
{
// subclass only if the user hasn't disabled
// subclassing globally
if (pGlobalSettings->NoSubclassing == 0)
{
// exclude other views, such as settings notebooks and
// possible user views
if ( (hwndFrame)
&& ( (ulView == OPEN_CONTENTS)
|| (ulView == OPEN_TREE)
|| (ulView == OPEN_DETAILS)
)
)
{
// get container wnd handle
hwndCnr = xwpsQueryCnrFromFrame(hwndFrame);
if (hwndCnr)
// only subclass frame window if it contains a container;
// just a security check
{
// now check if frame wnd has already been subclassed;
// just another security check
pfnwpCurrent = (PFNWP)WinQueryWindowPtr(hwndFrame, QWP_PFNWP);
if (pfnwpCurrent != (PFNWP)fnwpSubclassedFolderFrame)
{
if (!(pfnwpOriginal = WinSubclassWindow(hwndFrame, (PFNWP)fnwpSubclassedFolderFrame)))
// error occured subclassing:
DebugBox("XFolder", "Folder subclassing failed.");
// should never happen
else
{
// subclassing succeeded: now remember the old wnd proc
// and other data in the global linked list
pNewItem = malloc(sizeof(SUBCLASSEDLISTITEM));
pNewItem->pfnwpOriginal = pfnwpOriginal;
// store various other data here
pNewItem->hwndFrame = hwndFrame;
pNewItem->somSelf = somSelf;
pNewItem->pRealObject = pRealObject;
pNewItem->hwndCnr = hwndCnr;
pNewItem->ulView = ulView;
pNewItem->fRemoveSrcEmphasis = FALSE;
// set status bar hwnd to zero at this point;
// this will be created elsewhere
pNewItem->hwndStatusBar = NULLHANDLE;
// create a supplementary object window
// for this folder frame (see
// fnwpSupplObject for details)
pNewItem->hwndSupplObject = WinCreateWindow(
HWND_OBJECT,
WNDCLASS_SUPPLOBJECT, // class name
(PSZ)"SupplObject", // title
0, // style
0,0,0,0, // position
0, // owner
HWND_BOTTOM, // z-order
0, // window id
pNewItem, // pass the struct to WM_CREATE
NULL); // pres params
// append to global list
fSemOwned = (DosRequestMutexSem(hmtxSubclassed, 4000) == NO_ERROR);
if (fSemOwned) {
lstAppendItem((PLISTITEM*)&psliSubclassed, NULL,
(PLISTITEM)pNewItem);
DosReleaseMutexSem(hmtxSubclassed);
fSemOwned = FALSE;
}
}
}
}
}
}
}
CATCH(excpt1)
{
if (fSemOwned) {
DosReleaseMutexSem(hmtxSubclassed);
fSemOwned = FALSE;
}
} END_CATCH;
return (pNewItem);
}
/*
*@@ cmnRemovePSLI:
* reverse to cmnSubclassFolderFrame, this removes
* a PSUBCLASSEDLISTITEM from the global list again.
* Called upon WM_CLOSE in folder frames.
*/
VOID cmnRemovePSLI(PSUBCLASSEDLISTITEM psli)
{
BOOL fSemOwned = FALSE;
TRY_QUIET(excpt1)
{
fSemOwned = (DosRequestMutexSem(hmtxSubclassed, 4000) == NO_ERROR);
if (fSemOwned) {
lstRemoveItem((PLISTITEM*)&psliSubclassed, NULL,
(PLISTITEM)psli);
DosReleaseMutexSem(hmtxSubclassed);
fSemOwned = FALSE;
}
}
CATCH(excpt1)
{
if (fSemOwned) {
DosReleaseMutexSem(hmtxSubclassed);
fSemOwned = FALSE;
}
} END_CATCH;
}
/*-------------------------------------------------------------------
* *
* Miscellaneous *
* *
********************************************************************/
/*
*@@ fnwpAutoSizeStatic:
* dlg proc for the subclassed static text control in msg box;
* automatically resizes the msg box window when text changes
*/
PFNWP pfnwpOrigStatic = NULL;
MRESULT EXPENTRY fnwpAutoSizeStatic(HWND hwndStatic, ULONG msg, MPARAM mp1, MPARAM mp2)
{
MRESULT mrc = NULL;
switch (msg) {
/*
* WM_SETLONGTEXT:
* this arrives here when the window text changes,
* especially when fnwpMessageBox sets the window
* text; we will now reposition all the controls.
* mp1 is a PSZ to the new text.
*/
case WM_SETLONGTEXT: {
CHAR szFont[300];
PSZ p = (PSZ)WinQueryWindowULong(hwndStatic, QWL_USER);
if (p)
free(p);
p = strdup((PSZ)mp1);
WinSetWindowULong(hwndStatic, QWL_USER, (ULONG)p);
// WinPostMsg(hwndStatic, WM_UPDATE, MPNULL, MPNULL);
PrfQueryProfileString(HINI_USER, INIAPP_XFOLDER, INIKEY_DLGFONT, "9.WarpSans",
szFont, sizeof(szFont)-1);
WinSetPresParam(hwndStatic, PP_FONTNAMESIZE,
(ULONG)strlen(szFont) + 1, (PVOID)szFont);
// this will also update the display
/* PSZ pwp = (PWNDPARAMS)mp1;
_Pmpf(( "WM_SETWINDOWPARAMS" ));
mrc = (*pfnwpOrigStatic)(hwndStatic, msg, mp1, mp2);
if (pwp) {
} */
break; }
/*
* WM_PRESPARAMCHANGED:
* if a font has been dropped on the window, store
* the information and enforce control repositioning
* also
*/
case WM_PRESPARAMCHANGED: {
// _Pmpf(( "PRESPARAMCHANGED" ));
switch ((ULONG)mp1) {
case PP_FONTNAMESIZE: {
ULONG attrFound; //, abValue[32];
CHAR szFont[100];
HWND hwndDlg = WinQueryWindow(hwndStatic, QW_PARENT);
WinQueryPresParam(hwndStatic,
PP_FONTNAMESIZE,
0,
&attrFound,
(ULONG)sizeof(szFont),
(PVOID)&szFont,
0);
PrfWriteProfileString(HINI_USER, INIAPP_XFOLDER, INIKEY_DLGFONT,
szFont);
// now also change the buttons
WinSetPresParam(WinWindowFromID(hwndDlg, 1),
PP_FONTNAMESIZE,
(ULONG)strlen(szFont) + 1, (PVOID)szFont);
WinSetPresParam(WinWindowFromID(hwndDlg, 2),
PP_FONTNAMESIZE,
(ULONG)strlen(szFont) + 1, (PVOID)szFont);
WinSetPresParam(WinWindowFromID(hwndDlg, 3),
PP_FONTNAMESIZE,
(ULONG)strlen(szFont) + 1, (PVOID)szFont);
WinPostMsg(hwndStatic, WM_UPDATE, MPNULL, MPNULL);
break; }
}
break; }
/*
* WM_UPDATE:
* this actually does all the calculations to reposition
* all the msg box controls
*/
case WM_UPDATE: {
RECTL rcl, rcl2;
SWP swp;
HWND hwndIcon, hwndDlg;
PSZ pszText;
HPS hps = WinGetPS(hwndStatic);
// _Pmpf(( "WM_UPDATE" ));
pszText = (PSZ)WinQueryWindowULong(hwndStatic, QWL_USER);
if (pszText) {
WinQueryWindowRect(hwndStatic, &rcl); // get window dimensions
// rcl.yTop = 1000;
memcpy(&rcl2, &rcl, sizeof(rcl));
winhDrawFormattedText(hps, &rcl, pszText, DT_LEFT | DT_TOP | DT_QUERYEXTENT);
WinEndPaint(hps);
if ((rcl.yTop - rcl.yBottom) < 40)
rcl.yBottom -= 40 - (rcl.yTop - rcl.yBottom);
// printfRtl(" Original rect:", &rcl2);
// printfRtl(" New rect: ", &rcl);
// reposition the text
WinQueryWindowPos(hwndStatic, &swp);
swp.cy -= rcl.yBottom;
WinSetWindowPos(hwndStatic, 0,
swp.x, swp.y, swp.cx, swp.cy,
SWP_SIZE);
// reposition the icon
hwndIcon = WinWindowFromID(WinQueryWindow(hwndStatic, QW_PARENT),
ID_XFDI_GENERICDLGICON);
WinQueryWindowPos(hwndIcon, &swp);
swp.y -= rcl.yBottom;
WinSetWindowPos(hwndIcon, 0,
swp.x, swp.y, swp.cx, swp.cy,
SWP_MOVE);
// resize the dlg frame window
hwndDlg = WinQueryWindow(hwndStatic, QW_PARENT);
WinQueryWindowPos(hwndDlg, &swp);
swp.cy -= rcl.yBottom;
swp.y += (rcl.yBottom / 2);
WinInvalidateRect(hwndDlg, NULL, FALSE);
WinSetWindowPos(hwndDlg, 0,
swp.x, swp.y, swp.cx, swp.cy,
SWP_SIZE | SWP_MOVE);
}
break; }
/*
* WM_PAINT:
* draw the formatted text
*/
case WM_PAINT: {
RECTL rcl;
PSZ pszText = (PSZ)WinQueryWindowULong(hwndStatic, QWL_USER);
HPS hps = WinBeginPaint(hwndStatic, NULLHANDLE, &rcl);
if (pszText) {
WinQueryWindowRect(hwndStatic, &rcl); // get window dimensions
// switch to RGB mode
GpiCreateLogColorTable(hps, 0, LCOLF_RGB, 0, 0, NULL);
// set "static text" color
GpiSetColor(hps,
WinQuerySysColor(HWND_DESKTOP, SYSCLR_WINDOWSTATICTEXT, 0));
winhDrawFormattedText(hps, &rcl, pszText, DT_LEFT | DT_TOP);
}
WinEndPaint(hps);
break; }
case WM_DESTROY: {
PSZ pszText = (PSZ)WinQueryWindowULong(hwndStatic, QWL_USER);
free(pszText);
mrc = (*pfnwpOrigStatic)(hwndStatic, msg, mp1, mp2);
break; }
default:
mrc = (*pfnwpOrigStatic)(hwndStatic, msg, mp1, mp2);
}
return (mrc);
}
/*
*@@ fnwpMessageBox:
* dlg proc for cmnMessageBox below
*/
MRESULT EXPENTRY fnwpMessageBox(HWND hwndDlg, ULONG msg, MPARAM mp1, MPARAM mp2)
{
MRESULT mrc = NULL;
switch (msg) {
case WM_INITDLG: {
// CHAR szFont[CCHMAXPATH];
HWND hwndStatic = WinWindowFromID(hwndDlg,
ID_XFDI_GENERICDLGTEXT);
/* PrfQueryProfileString(HINI_USER, INIAPP_XFOLDER, INIKEY_DLGFONT,
"9.WarpSans", szFont, sizeof(szFont)-1);
WinSetPresParam(hwndStatic, PP_FONTNAMESIZE,
(ULONG)strlen(szFont)+1, (PVOID)szFont); */
// set string to 0
WinSetWindowULong(hwndStatic, QWL_USER, (ULONG)NULL);
pfnwpOrigStatic = WinSubclassWindow(hwndStatic,
fnwpAutoSizeStatic);
mrc = fnwpDlgGeneric(hwndDlg, msg, mp1, mp2);
break; }
default:
mrc = fnwpDlgGeneric(hwndDlg, msg, mp1, mp2);
break;
}
return (mrc);
}
/*
*@@ cmnMessageBox:
* this is the generic function for displaying XFolder
* message boxes. This is very similar to WinMessageBox,
* but a few new features are introduced:
* -- an XFolder icon is displayed;
* -- fonts can be dropped on the window, upon which the
* window will resize itself and store the font in OS2.INI.
*
* Returns MBID_* codes like WinMessageBox.
*/
ULONG cmnMessageBox(HWND hwndOwner, // in: owner
PSZ pszTitle, // in: msgbox title
PSZ pszMessage, // in: msgbox text
ULONG flStyle) // in: MB_* flags
{
HAB hab = WinQueryAnchorBlock(hwndOwner);
HMODULE hmod = NLS_MODULE;
HWND hwndDlg = NULLHANDLE, hwndStatic = NULLHANDLE;
PSZ pszButton = NULL;
ULONG ulrcDlg, ulrc = DID_CANCEL;
REGREC2 RegRec2;
ULONG ulExcpt;
APIRET rc;
// set our extended exception handler
RegRec2.pfnHandler = (PFN)excHandlerQuiet;
if ( rc = DosSetExceptionHandler((PEXCEPTIONREGISTRATIONRECORD)&RegRec2) )
DosBeep(100, 1000);
// store a known thread state
ulExcpt = setjmp(RegRec2.jmpThread);
if (ulExcpt)
{
DosBeep(100, 1000);
} else {
ULONG flButtons = flStyle & 0xF; // low nibble contains MB_YESNO etc.
hwndDlg = WinLoadDlg(HWND_DESKTOP, hwndOwner,
fnwpMessageBox,
hmod,
ID_XFD_GENERICDLG,
NULL);
hwndStatic = WinWindowFromID(hwndDlg, ID_XFDI_GENERICDLGTEXT);
// now work on the three buttons of the dlg template:
// give them proper titles or hide them
if (flButtons == MB_YESNO) {
cmnLoadString(hab, hmod, ID_XSSI_DLG_YES, &pszButton);
WinSetDlgItemText(hwndDlg, 1, pszButton);
cmnLoadString(hab, hmod, ID_XSSI_DLG_NO, &pszButton);
WinSetDlgItemText(hwndDlg, 2, pszButton);
winhShowDlgItem(hwndDlg, 3, FALSE);
free(pszButton);
}
else if (flButtons == MB_OK) {
cmnLoadString(hab, hmod, ID_XSSI_DLG_OK, &pszButton);
WinSetDlgItemText(hwndDlg, 1, pszButton);
winhShowDlgItem(hwndDlg, 2, FALSE);
winhShowDlgItem(hwndDlg, 3, FALSE);
free(pszButton);
}
else if (flButtons == MB_CANCEL) {
cmnLoadString(hab, hmod, ID_XSSI_DLG_CANCEL, &pszButton);
WinSetDlgItemText(hwndDlg, 1, pszButton);
winhShowDlgItem(hwndDlg, 2, FALSE);
winhShowDlgItem(hwndDlg, 3, FALSE);
free(pszButton);
}
else if (flButtons == MB_OKCANCEL) {
cmnLoadString(hab, hmod, ID_XSSI_DLG_OK, &pszButton);
WinSetDlgItemText(hwndDlg, 1, pszButton);
cmnLoadString(hab, hmod, ID_XSSI_DLG_CANCEL, &pszButton);
WinSetDlgItemText(hwndDlg, 2, pszButton);
winhShowDlgItem(hwndDlg, 3, FALSE);
free(pszButton);
}
else if (flButtons == MB_RETRYCANCEL) {
cmnLoadString(hab, hmod, ID_XSSI_DLG_RETRY, &pszButton);
WinSetDlgItemText(hwndDlg, 1, pszButton);
cmnLoadString(hab, hmod, ID_XSSI_DLG_CANCEL, &pszButton);
WinSetDlgItemText(hwndDlg, 2, pszButton);
winhShowDlgItem(hwndDlg, 3, FALSE);
free(pszButton);
}
else if (flButtons == MB_ABORTRETRYIGNORE) {
cmnLoadString(hab, hmod, ID_XSSI_DLG_ABORT, &pszButton);
WinSetDlgItemText(hwndDlg, 1, pszButton);
cmnLoadString(hab, hmod, ID_XSSI_DLG_RETRY, &pszButton);
WinSetDlgItemText(hwndDlg, 2, pszButton);
cmnLoadString(hab, hmod, ID_XSSI_DLG_IGNORE, &pszButton);
WinSetDlgItemText(hwndDlg, 3, pszButton);
free(pszButton);
}
if (flStyle & MB_DEFBUTTON2)
WinSetWindowBits(WinWindowFromID(hwndDlg, 2), QWL_STYLE,
BS_DEFAULT,
1);
else if (flStyle & MB_DEFBUTTON3)
WinSetWindowBits(WinWindowFromID(hwndDlg, 3), QWL_STYLE,
BS_DEFAULT,
1);
else
WinSetWindowBits(WinWindowFromID(hwndDlg, 1), QWL_STYLE,
BS_DEFAULT,
1);
WinSetWindowText(hwndDlg, pszTitle);
WinSendMsg(hwndStatic, WM_SETLONGTEXT, pszMessage, MPNULL);
winhCenterWindow(hwndDlg);
if (flStyle & MB_SYSTEMMODAL)
WinSetSysModalWindow(HWND_DESKTOP, hwndDlg);
ulrcDlg = WinProcessDlg(hwndDlg);
WinDestroyWindow(hwndDlg);
if (flButtons == MB_YESNO)
switch (ulrcDlg) {
case 1: ulrc = MBID_YES; break;
default: ulrc = MBID_NO; break;
}
else if (flButtons == MB_OK)
ulrc = MBID_OK;
else if (flButtons == MB_CANCEL)
ulrc = MBID_CANCEL;
else if (flButtons == MB_OKCANCEL)
switch (ulrcDlg) {
case 1: ulrc = MBID_OK; break;
default: ulrc = MBID_CANCEL; break;
}
else if (flButtons == MB_RETRYCANCEL)
switch (ulrcDlg) {
case 1: ulrc = MBID_RETRY; break;
default: ulrc = MBID_CANCEL; break;
}
else if (flButtons == MB_ABORTRETRYIGNORE)
switch (ulrcDlg) {
case 2: ulrc = MBID_RETRY; break;
case 3: ulrc = MBID_IGNORE; break;
default: ulrc = MBID_ABORT; break;
}
}
DosUnsetExceptionHandler((PEXCEPTIONREGISTRATIONRECORD)&RegRec2);
return (ulrc);
}
/*
*@@ cmnGetMessage:
* like DosGetMessage, but automatically uses the
* (NLS) XFolder message file.
* The parameters are exactly like with DosGetMessage.
*/
APIRET cmnGetMessage(PCHAR *pTable, // in: replacement PSZ table or NULL
ULONG ulTable, // in: size of that table or 0
PSZ pszBuf, // out: buffer to hold message string
ULONG cbBuf, // in: size of pszBuf
ULONG ulMsgNumber) // in: msg number to retrieve
{
PSZ pszMessageFile = cmnQueryMessageFile();
ULONG ulReturned;
BOOL fCont = FALSE;
APIRET arc;
arc = DosGetMessage(pTable, ulTable,
pszBuf, cbBuf,
ulMsgNumber, pszMessageFile, &ulReturned);
pszBuf[ulReturned] = '\0';
// remove trailing newlines
do {
PSZ p = pszBuf + strlen(pszBuf) - 1;
if ( (*p == '\n')
|| (*p == '\r')
)
{
*p = '\0';
fCont = TRUE;
} else
fCont = FALSE;
} while (fCont);
return (arc);
}
/*
*@@ cmnMessageBoxMsg:
* calls cmnMessageBox, but this one accepts ULONG indices
* into the XFolder message file (XFLDRxxx.MSG) instead
* of real PSZs. This calls cmnGetMessage for retrieving
* the messages, but placeholder replacement does not work
* here (use cmnMessageBoxMsgExt for that).
*/
ULONG cmnMessageBoxMsg(HWND hwndOwner,
ULONG ulTitle, // in: msg index for dlg title
ULONG ulMessage, // in: msg index for message
ULONG flStyle) // in: like cmnMsgBox
{
CHAR szTitle[200], szMessage[2000];
cmnGetMessage(NULL, 0,
szTitle, sizeof(szTitle)-1,
ulTitle);
cmnGetMessage(NULL, 0,
szMessage, sizeof(szMessage)-1,
ulMessage);
return (cmnMessageBox(hwndOwner, szTitle, szMessage, flStyle));
}
/*
*@@ cmnMessageBoxMsgExt:
* like cmnMessageBoxMsg, but with string substitution
* (see cmnGetMessage for more); substitution only
* takes place for the message specified with ulMessage,
* not for the title.
*/
ULONG cmnMessageBoxMsgExt(HWND hwndOwner, // in: owner window
ULONG ulTitle, // in: msg number for title
PCHAR *pTable, // in: replacement table for ulMessage
ULONG ulTable, // in: sizeof *pTable
ULONG ulMessage, // in: msg number for message
ULONG flStyle) // in: msg box style flags (cmnMessageBox)
{
CHAR szTitle[200], szMessage[2000];
cmnGetMessage(NULL, 0,
szTitle, sizeof(szTitle)-1,
ulTitle);
cmnGetMessage(pTable, ulTable,
szMessage, sizeof(szMessage)-1,
ulMessage);
return (cmnMessageBox(hwndOwner, szTitle, szMessage, flStyle));
}
/*
*@@ cmnSetHelpPanel:
* sets help panel before calling fnwpDlgGeneric.
*/
VOID cmnSetHelpPanel(ULONG ulHelpPanel)
{
ulCurHelpPanel = ulHelpPanel;
}
/*
*@@ fnwpDlgGeneric:
* this is the dlg procedure for XFolder dlg boxes;
* it can process WM_HELP messages
*/
MRESULT EXPENTRY fnwpDlgGeneric(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
{
HOBJECT hobjRef = 0;
HWND hwndItem;
MRESULT mrc = NULL;
switch (msg) {
case WM_INITDLG:
if (hwndItem = WinWindowFromID(hwnd, ID_XFDI_XFLDVERSION)) {
CHAR szTemp[100];
WinQueryWindowText(hwndItem, sizeof(szTemp), szTemp);
strcpy(strstr(szTemp, "%a"), XFOLDER_VERSION);
WinSetWindowText(hwndItem, szTemp);
}
mrc = WinDefDlgProc(hwnd, msg, mp1, mp2);
break;
case WM_HELP: {
// HMODULE hmodResource = cmnQueryNLSModuleHandle(FALSE);
/* WM_HELP is received by this function when F1 or a "help" button
is pressed in a dialog window. */
if (ulCurHelpPanel > 0) {
WPObject *pHelpSomSelf = _wpclsQueryActiveDesktop(_WPDesktop);
/* ulCurHelpPanel is set by instance methods before creating a
dialog box in order to link help topics to the displayed
dialog box. Possible values are:
0: open online reference ("<XFOLDER_REF>", INF book)
> 0: open help topic in xfldr.hlp
-1: ignore WM_HELP */
if (pHelpSomSelf) {
PSZ pszHelpLibrary;
BOOL fProcessed = FALSE;
if (pszHelpLibrary = cmnQueryHelpLibrary())
// path found: display help panel
if (_wpDisplayHelp(pHelpSomSelf, ulCurHelpPanel, pszHelpLibrary))
fProcessed = TRUE;
if (!fProcessed)
cmnMessageBoxMsg(HWND_DESKTOP, 104, 134, MB_OK);
}
} else if (ulCurHelpPanel == 0)
{ // open online reference
ulCurHelpPanel = -1; // ignore further WM_HELP messages: this one suffices
hobjRef = WinQueryObject("<XFOLDER_REF>");
if (hobjRef) {
WinOpenObject(hobjRef, OPEN_DEFAULT, TRUE);
} else {
cmnMessageBoxMsg(HWND_DESKTOP, 104, 137, MB_OK);
/* WinDlgBox(HWND_DESKTOP,
hwnd, // destroy with first msg box
(PFNWP)fnwpDlgGeneric,
hmodResource, // load from resource file
ID_XFD_NOREF, // dialog resource id
(PVOID)NULL); // no dialog parameters
*/
}
} // end else; if ulCurHelpPanel is < 0, nothing happens
mrc = NULL;
break; } // end case WM_HELP
default:
mrc = WinDefDlgProc(hwnd, msg, mp1, mp2);
break;
}
return (mrc);
}
/*-------------------------------------------------------------------
* *
* System sounds *
* *
********************************************************************/
/*
*@@ cmnQuerySystemSound:
* this gets a system sound from the MMPM.INI file.
* usIndex must be the sound to query.
* Default system sounds:
* -- MMSOUND_WARNING 0
* -- MMSOUND_INFORMATION 1
* -- MMSOUND_ERROR 2
* -- MMSOUND_ANIMATEOPEN 3
* -- MMSOUND_ANIMATECLOSE 4
* -- MMSOUND_DRAG 5
* -- MMSOUND_DROP 6
* -- MMSOUND_SYSTEMSTARTUP 7
* -- MMSOUND_SHUTDOWN 8
* -- MMSOUND_SHREDDER 9
* -- MMSOUND_LOCKUP 10
* -- MMSOUND_ALARMCLOCK 11
* -- MMSOUND_PRINTERROR 12
*
* New XFolder system sounds:
* -- MMSOUND_XFLD_SHUTDOWN 555
* -- MMSOUND_XFLD_RESTARTWPS 556
* -- MMSOUND_XFLD_SORT 557
*
* The string buffers are recommended to be at least
* CCHMAXPATH in size.
*/
BOOL cmnQuerySystemSound(USHORT usIndex, // in: sound index to query
PSZ pszDescr, // out: address of buffer where to
// copy the sound description to, as displayed
// in the "Sound" object (may be NULL)
PSZ pszFile,
// address adress of buffer where to copy the
// sound file to (may be NULL)
PULONG pulVolume)
// address of ULONG where to copy the volume
// to (0-100). If the "Global volume" flag is
// set in MMPM.INI, this will return the global
// volume instead. May be NULL also.
{
// We inline this func because it's only used once.
HAB habDesktop = WinQueryAnchorBlock(HWND_DESKTOP);
HINI hiniMMPM;
CHAR szMMPM[CCHMAXPATH];
BOOL rc = FALSE;
#ifdef DEBUG_SOUNDS
_Pmpf(("cmnQuerySystemSound index %d", usIndex));
#endif
sprintf(szMMPM, "%c:\\MMOS2\\MMPM.INI", doshQueryBootDrive());
// _Pmpf(( "cmnQuerySystemSound: %s", szMMPM ));
hiniMMPM = PrfOpenProfile(habDesktop, szMMPM);
#ifdef DEBUG_SOUNDS
_Pmpf((" hiniMMPM: 0x%lX", hiniMMPM));
#endif
if (hiniMMPM) {
CHAR szData[1000];
CHAR szData2[100];
CHAR szKey[10];
sprintf(szKey, "%d", usIndex);
PrfQueryProfileString(hiniMMPM,
MMINIKEY_SOUNDSETTINGS, "EnableSounds",
"TRUE", // default string
szData2, sizeof(szData2));
#ifdef DEBUG_SOUNDS
_Pmpf((" sounds enabled: %s", szData2));
#endif
if (strcmp(szData2, "TRUE") == 0)
// sounds enabled at all?
if (PrfQueryProfileString(hiniMMPM,
MMINIKEY_SYSSOUNDS, szKey,
".",
szData, sizeof(szData)-1) > 3)
{
// each key data has the following format:
// <soundfile>#<description>#<volume>
PSZ p1 = szData, p2;
p2 = strchr(p1, '#');
if (pszFile) {
strncpy(pszFile, p1, p2-p1);
pszFile[p2-p1] = '\0';
#ifdef DEBUG_SOUNDS
_Pmpf((" found soundfile: %s", pszFile));
#endif
}
p1 = p2+1;
// _Pmpf(( " %s", p1 ));
p2 = strchr(p1, '#');
if (pszDescr) {
strncpy(pszDescr, p1, p2-p1);
pszDescr[p2-p1] = '\0';
}
p1 = p2+1;
if (pulVolume) {
// if "global volume" has been enabled,
// we do not return the value specified
// here, but the global value
PrfQueryProfileString(hiniMMPM,
MMINIKEY_SOUNDSETTINGS, "ApplyVolumeToAll",
"FALSE",
szData2, sizeof(szData2));
if (strcmp(szData2, "FALSE") == 0) {
// individual volume settings per sound
p2 = strchr(p1, '#');
sscanf(p1, "%d", pulVolume);
} else {
// global volume setting for all sounds
PrfQueryProfileString(hiniMMPM,
MMINIKEY_SOUNDSETTINGS, "Volume",
"100",
szData2, sizeof(szData2));
sscanf(szData2, "%d", pulVolume);
}
}
rc = TRUE;
}
PrfCloseProfile(hiniMMPM);
}
return (rc);
}
/*
*@@ cmnSetSystemSound:
* this sets a system sound in MMPM.INI.
* See cmnQuerySystemSound for the parameters.
*/
BOOL cmnSetSystemSound(USHORT usIndex, PSZ pszDescr, PSZ pszFile, BYTE bVolume)
{
HAB habDesktop = WinQueryAnchorBlock(HWND_DESKTOP);
HINI hiniMMPM;
CHAR szMMPM[CCHMAXPATH];
sprintf(szMMPM, "%c\\MMOS2\\MMPM.INI", doshQueryBootDrive());
hiniMMPM = PrfOpenProfile(habDesktop, szMMPM);
if (hiniMMPM) {
CHAR szData[1000];
CHAR szKey[10];
sprintf(szKey, "%d", usIndex);
sprintf(szData, "%s#%s#%d", pszFile, pszDescr, bVolume);
PrfWriteProfileString(hiniMMPM,
MMINIKEY_SYSSOUNDS, szKey,
szData);
PrfCloseProfile(hiniMMPM);
return (TRUE);
}
return (FALSE);
}