mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1769 lines
43 KiB
1769 lines
43 KiB
/*****************************************************************************
|
|
*
|
|
* HINIT.C
|
|
*
|
|
* Copyright (C) Microsoft Corporation 1990-1994.
|
|
* All Rights reserved.
|
|
*
|
|
******************************************************************************
|
|
*
|
|
* Module Intent
|
|
*
|
|
* All the necessary initialization code for WinHelp belongs here.
|
|
* This code should only be active (loaded in memory in real mode only
|
|
* during program initialization and termination. That means that no
|
|
* modules that will be needed at other times should be here.
|
|
* Similarly, this module should not have code that is needed only
|
|
* rarely; the size of this module impacts the disk-load time of every
|
|
* WinHelp initialization, even for new instances. Code used only when
|
|
* unhiding help should not be here.
|
|
*
|
|
*****************************************************************************/
|
|
|
|
|
|
#include "help.h"
|
|
|
|
#pragma hdrstop
|
|
|
|
#include "inc\hwproc.h"
|
|
#include "inc\hinit.h"
|
|
#include "inc\winclass.h"
|
|
#include "inc\printset.h"
|
|
#include <ctype.h>
|
|
#include "resource.h"
|
|
|
|
#include <mmsystem.h> // for mmInit
|
|
#include <commctrl.h>
|
|
|
|
#ifdef _DEBUG
|
|
#undef THIS_FILE
|
|
static const char THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
INLINE static void STDCALL FTerminate(void);
|
|
|
|
// Currently history and back still initialized in JumpTlp() (navsup.c)
|
|
|
|
#define chGID 'g' // Create .GID file
|
|
#define chHLPONHLP 'h' // Display help on help
|
|
#define chID 'i' // Jump to topic based on ctx string
|
|
#define chKEYWORD 'k' // Jump to topic based on keyword
|
|
#define chCONTEXTNO 'n' // Jump to topic based on ctx no
|
|
#define chWindow 'w' // window to use
|
|
#define chCompare '7' // running 2 WinHelp's side by side
|
|
#define chSilentGID 's' // Silent setup
|
|
|
|
#ifdef _DEBUG
|
|
#define chDEBUG 'd' // turns on DebugBreak()
|
|
#define chTESTERS 't' // make asserts app-modal
|
|
#define chFAKE 'f' // fake this as an app-called help
|
|
#endif
|
|
|
|
// Defined in core\inc\help.h
|
|
|
|
// #define HLP_POPUP 'p' // Execute WinHelp as a popup
|
|
// #define HLP_TRAININGCARD 'c' // Execute WinHelp as a training card
|
|
// #define HLP_APPLICATION 'x' // Execute WinHelp as application help
|
|
|
|
enum {
|
|
CMD_NOTHING,
|
|
CMD_CTX_NUMBER,
|
|
CMD_KEYWORD,
|
|
CMD_HELP_ON_HELP,
|
|
CMD_CTX_STRING,
|
|
};
|
|
|
|
#define SPACE ' '
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* Variables
|
|
*
|
|
*****************************************************************************/
|
|
|
|
/*------- Variables Used Globally in this Module -----------------------*/
|
|
|
|
WRECT rctHelpOrg; // Original setting for window pos
|
|
BOOL fMaxOrg; // Original setting for max flag
|
|
|
|
|
|
/*------- Variables Referenced in Other Modules ----------------------------*/
|
|
|
|
BOOL fButtonsBusy; // Used in hwproc.c, helper.c
|
|
|
|
/*------------------------------------------------------------*\
|
|
| Used as a default palette when no EWs have helped us out.
|
|
\*------------------------------------------------------------*/
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* Table of window classes. We walk this table and register all the window
|
|
* class definitions therein. Each entry in this table contains a subset of
|
|
* the infomation in a WNDCLASS structure. Note that near pointers to strings
|
|
* are kept, since staticly initailzed far pointers to data are a no-no in
|
|
* Windows.
|
|
*
|
|
*****************************************************************************/
|
|
|
|
// 25-Mar-1993 [ralphw] -- menus are not loaded anymore, since part of
|
|
// initialization reloads the menu.
|
|
|
|
extern BOOL fAppModal; // used in assertf.c
|
|
extern HFS hfsBM;
|
|
|
|
#ifndef NO_PRAGMAS
|
|
#pragma data_seg(".text", "CODE")
|
|
#endif
|
|
const char txtDocClass[] = "MS_WINDOC";
|
|
#ifndef NO_PRAGMAS
|
|
#pragma data_seg()
|
|
#endif
|
|
|
|
CLSINFO rgWndClsInfo[] = {
|
|
{ // Main help Window
|
|
0, // style
|
|
HelpWndProc, // lpfnWndProc
|
|
WE_HELP, // cbWndExtra
|
|
0, // hIcon
|
|
0, // hIconSm
|
|
NULL, // hbrBackground
|
|
0, // wMenuName
|
|
MS_WINHELP // szClassName
|
|
},
|
|
|
|
{ // Main help Window, when not help
|
|
0, // style
|
|
HelpWndProc, // lpfnWndProc
|
|
WE_HELP, // cbWndExtra
|
|
0, // hIcon
|
|
0, // hIconSm
|
|
NULL, // hbrBackground
|
|
0, // wMenuName
|
|
txtDocClass // szClassName
|
|
},
|
|
|
|
{ // Training Card Main Window
|
|
0, // style
|
|
HelpWndProc, // lpfnWndProc
|
|
WE_HELP, // cbWndExtra
|
|
0, // hIcon
|
|
0, // hIconSm
|
|
NULL, // hbrBackground
|
|
0, // wMenuName
|
|
MS_TCARDHELP // szClassName
|
|
},
|
|
|
|
{ // Right Mouse Popup main window
|
|
0, // style
|
|
HelpWndProc, // lpfnWndProc
|
|
WE_HELP, // cbWndExtra
|
|
0, // hIcon
|
|
0, // hIconSm
|
|
NULL, // hbrBackground
|
|
0, // wMenuName
|
|
MS_POPUPHELP // szClassName
|
|
},
|
|
|
|
{ // Topic Window
|
|
CS_VREDRAW | CS_HREDRAW, // style
|
|
TopicWndProc, // lpfnWndProc
|
|
WE_TOPIC, // cbWndExtra
|
|
NULL, // hIcon
|
|
0, // hIconSm
|
|
NULL, // hbrBackground
|
|
0, // wMenuName
|
|
"MS_WINTOPIC" // szClassName
|
|
},
|
|
|
|
{ // Note (popup) Window
|
|
CS_VREDRAW | CS_HREDRAW, // style
|
|
NoteWndProc, // lpfnWndProc
|
|
0, // cbWndExtra
|
|
NULL, // hIcon
|
|
0, // hIconSm
|
|
(HBRUSH) (COLOR_WINDOW + 1), // hbrBackground
|
|
0, // wMenuName
|
|
"MS_WINNOTE" // szClassName
|
|
},
|
|
|
|
{ // NSR Window
|
|
CS_VREDRAW | CS_HREDRAW, // style
|
|
NSRWndProc, // lpfnWndProc
|
|
WE_NSR, // cbWndExtra
|
|
NULL, // hIcon
|
|
0, // hIconSm
|
|
NULL, // hbrBackground
|
|
0, // wMenuName
|
|
"MS_WINNSR" // szClassName
|
|
},
|
|
|
|
{ // Icon (Button Bar) Window
|
|
0, // style
|
|
ButtonBarProc, // lpfnWndProc
|
|
WE_ICON, // cbWndExtra
|
|
NULL, // hIcon
|
|
0, // hIconSm
|
|
0, // hbrBackground
|
|
0, // wMenuName
|
|
"MS_WINICON" // szClassName
|
|
},
|
|
|
|
{ // Path Window (history)
|
|
CS_HREDRAW|CS_VREDRAW, // style
|
|
HistoryProc, // lpfnWndProc
|
|
0, // cbWndExtra
|
|
0, // hIcon
|
|
0, // hIconSm
|
|
(HBRUSH) (COLOR_WINDOW + 1), // hbrBackground
|
|
0, // wMenuName
|
|
"MS_WIN_PATH" // szClassName
|
|
},
|
|
|
|
{ // Secondary Window
|
|
CS_VREDRAW | CS_HREDRAW, // style
|
|
HelpWndProc, // lpfnWndProc
|
|
WE_HELP, // cbWndExtra
|
|
0, // hIcon
|
|
0, // hIconSm
|
|
0, // hbrBackground
|
|
0, // wMenuName
|
|
"MS_WINTOPIC_SECONDARY", // szClassName
|
|
},
|
|
};
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* Prototypes
|
|
*
|
|
*****************************************************************************/
|
|
|
|
static BOOL STDCALL AppInit( HINSTANCE, HINSTANCE );
|
|
static BOOL STDCALL CreateMainWindow(PSTR pszClass, BOOL fButtonBar);
|
|
static BOOL STDCALL FGetHelpRect(HWND);
|
|
static BOOL STDCALL FLoadResources(HINSTANCE, HINSTANCE);
|
|
static BOOL STDCALL RegHelpWinClasses(HINSTANCE);
|
|
static void STDCALL WriteProfile(void);
|
|
static PSTR STDCALL GetNextDigit(LONG* pdigit, PSTR pszCur);
|
|
INLINE static void STDCALL LoadOOMString(VOID);
|
|
INLINE void STDCALL ReadProfile(void);
|
|
|
|
#ifdef DEADCODE
|
|
INLINE static VOID STDCALL GetProfileWinPos(PSTR, LONG*, LONG*, LONG*, LONG*, BOOL*);
|
|
#endif
|
|
|
|
#pragma warning(disable:4113) // function parameter lists differed
|
|
|
|
/********************************************************************
|
|
-
|
|
- Name:
|
|
* FInitialize
|
|
*
|
|
* Purpose:
|
|
* Contains all of the initialization routines needed at program
|
|
* initialization. Returns FALSE if this cannot be done, and the
|
|
* program should then fail to run.
|
|
*
|
|
* Arguments:
|
|
* hinsThis This instance handle
|
|
* hinsPrev The last instance handle or hinsNil
|
|
* qchzCmdLine The execution command line
|
|
* wCmdShow show window type
|
|
*
|
|
* Returns;
|
|
* TRUE, if the program may go on
|
|
* else FALSE
|
|
*
|
|
********************************************************************/
|
|
|
|
extern HIMAGELIST (WINAPI *pImageList_LoadImage)(HINSTANCE, LPCSTR, int, int, COLORREF, UINT, UINT);
|
|
|
|
BOOL STDCALL FInitialize(
|
|
HINSTANCE hinsThis,
|
|
HINSTANCE hinsPrev,
|
|
LPSTR szCmdLine,
|
|
int wCmdShow
|
|
) {
|
|
OSVERSIONINFO osver;
|
|
BOOL fMax;
|
|
PSTR pszTmp, pszTmp2;
|
|
/* Buffer used for keywords and */
|
|
char pchBuffer[MAX_HELPONHELP]; // for help on help file load
|
|
BOOL fHasParam = FALSE;
|
|
int cmd = CMD_NOTHING;
|
|
CTX ctx;
|
|
char rgchName[MAX_PATH];
|
|
FM fm, fmSave;
|
|
PSTR pszCmdLine;
|
|
CHAR rgchCmdLine[MAX_PATH]; // Local Copy of command line
|
|
PSTR pszClass;
|
|
char szWindowName[cchWindowMemberMax];
|
|
HWND hwndOtherWinHelp;
|
|
BOOL fCompare = FALSE;
|
|
|
|
szWindowName[0] = '\0';
|
|
|
|
hinstPrevious = hinsPrev;
|
|
hInsNow = hinsThis;
|
|
pImageList_LoadImage = 0;
|
|
|
|
#ifdef STACK_CHECK
|
|
StackPrep();
|
|
#endif
|
|
|
|
// Make a local copy of the command line
|
|
|
|
ASSERT(lstrlen(szCmdLine) + 1 <= sizeof(rgchCmdLine));
|
|
lstrcpy(rgchCmdLine, szCmdLine);
|
|
pszCmdLine = FirstNonSpace(rgchCmdLine);
|
|
|
|
/*
|
|
* The fNoSwitches flag is used to determine whether to exit if its a
|
|
* bad file. If we got a switch, or no filename at all, then we stay
|
|
* put. But if all we got is a file, and its bad, we exit.
|
|
*/
|
|
|
|
fNoSwitches = (*pszCmdLine == '-' || !*pszCmdLine) ? FALSE : TRUE;
|
|
|
|
/*
|
|
* NOTE: Though we do not use the file name until the end of this
|
|
* function, we need to do the parsing here so that fHelp is is set
|
|
* correctly.
|
|
*/
|
|
|
|
hwndParent = FindWindow("hcw_class", NULL);
|
|
|
|
while (*pszCmdLine == '-') { // parse command line arguments
|
|
switch (tolower(pszCmdLine[1])) {
|
|
#ifdef _DEBUG
|
|
case chTESTERS: // 't'
|
|
fAppModal = TRUE;
|
|
break;
|
|
#endif
|
|
|
|
case chKEYWORD: // 'k'
|
|
case chID: // 'i'
|
|
cmd = (*(pszCmdLine + 1) == chKEYWORD) ? CMD_KEYWORD : CMD_CTX_STRING;
|
|
pszTmp = pszCmdLine + 2; // Parse out the keyword or the id
|
|
while (*pszTmp == SPACE)
|
|
pszTmp++;
|
|
pszTmp2 = pchBuffer; // and place it in pchBuffer
|
|
while((*pszTmp
|
|
&& (*pszTmp != SPACE))
|
|
&& (pszTmp2 < pchBuffer + MAX_HELPONHELP - 1)) {
|
|
#ifdef DBCS
|
|
if (IsDBCSLeadByte(*pszTmp2))
|
|
{
|
|
*pszTmp2++ = *pszTmp++;
|
|
*pszTmp2++ = *pszTmp++;
|
|
}
|
|
else
|
|
*pszTmp2++ = *pszTmp++;
|
|
#else
|
|
*pszTmp2++ = *pszTmp++;
|
|
#endif //DBCS
|
|
}
|
|
|
|
*pszTmp2 = '\0';
|
|
|
|
fHasParam = TRUE;
|
|
break;
|
|
|
|
case chCONTEXTNO: // 'n'
|
|
fNoHide = FALSE;
|
|
cmd = CMD_CTX_NUMBER;
|
|
pszTmp = pszCmdLine + 2;
|
|
while (*pszTmp == SPACE)
|
|
pszTmp++;
|
|
ctx = (CTX) atol(pszTmp);
|
|
fHasParam = TRUE;
|
|
break;
|
|
|
|
case chWindow:
|
|
pszTmp = pszCmdLine + 2;
|
|
while (*pszTmp == SPACE)
|
|
pszTmp++;
|
|
pszTmp2 = szWindowName;
|
|
while (*pszTmp != SPACE && *pszTmp &&
|
|
pszTmp2 < szWindowName + (cchWindowMemberMax - 1))
|
|
*pszTmp2++ = *pszTmp++;
|
|
*pszTmp2 = '\0';
|
|
while (*pszTmp == SPACE)
|
|
pszTmp++;
|
|
pszCmdLine = pszTmp - 2; // end of loop does pszCmdLine += 2
|
|
break;
|
|
|
|
case chCompare:
|
|
fCompare = TRUE;
|
|
break;
|
|
|
|
case chHLPONHLP: // 'h'
|
|
cmd = CMD_HELP_ON_HELP;
|
|
break;
|
|
|
|
#ifdef _DEBUG
|
|
case 'f':
|
|
fNoQuit = FALSE;
|
|
wCmdShow = SW_HIDE;
|
|
fHelp = STANDARD_HELP;
|
|
break;
|
|
#endif
|
|
|
|
case HLP_POPUP: // 'p' Was executed using WinHelp()
|
|
fHelp = POPUP_HELP;
|
|
wCmdShow = SW_HIDE;
|
|
break;
|
|
|
|
case HLP_APPLICATION: // 'x' Was executed using WinHelp()
|
|
fHelp = STANDARD_HELP;
|
|
|
|
fNoQuit = FALSE;
|
|
wCmdShow = SW_HIDE;
|
|
break;
|
|
|
|
case HLP_TRAININGCARD: // 'c' Was executed using WinHelp()
|
|
fHelp = TCARD_HELP;
|
|
wCmdShow = SW_HIDE;
|
|
break;
|
|
|
|
case '\0':
|
|
/*------------------------------------------------------------*\
|
|
| A special case for a command line terminated with '-'
|
|
\*------------------------------------------------------------*/
|
|
pszCmdLine--;
|
|
break;
|
|
|
|
case chSilentGID: // 's' create .GID file without animation window
|
|
fHiddenSetup = TRUE;
|
|
|
|
// deliberately fall through
|
|
|
|
case chGID: // 'g' create .GID file
|
|
{
|
|
int tab = 0;
|
|
pszTmp = pszCmdLine + 2;
|
|
if (isdigit(*pszTmp))
|
|
tab = atoi(pszTmp++);
|
|
|
|
while (*pszTmp == SPACE)
|
|
pszTmp++;
|
|
if (!*pszTmp)
|
|
return FALSE; // no filename was specified
|
|
fm = FmNew(pszTmp);
|
|
if (fm)
|
|
fmCreating = FmCopyFm(fm);
|
|
FindGidFile(fm, TRUE, tab);
|
|
DisposeFm(fm);
|
|
}
|
|
return FALSE;
|
|
|
|
default:
|
|
|
|
/*
|
|
* 29-Dec-1992 [ralphw] If there is no space after the switch,
|
|
* then we assume the switch took a paramter, and we want to throw
|
|
* away the parameter as well as the switch. If there is a space
|
|
* after the switch, then we really don't know if the switch had
|
|
* a paramter or not, so we leave it alone.
|
|
*/
|
|
|
|
if (pszCmdLine[2] != SPACE && pszCmdLine[2] != '\0')
|
|
fHasParam = TRUE;
|
|
break; // ignore what we can't understand
|
|
|
|
} // switch
|
|
|
|
pszCmdLine += 2; // skip white space
|
|
while (*pszCmdLine == SPACE)
|
|
pszCmdLine++;
|
|
if (fHasParam) { // If the argument has a parameter
|
|
// then we want to eat that param
|
|
while ((*pszCmdLine != SPACE) && *pszCmdLine)
|
|
pszCmdLine = CharNext(pszCmdLine);
|
|
while (*pszCmdLine == SPACE)
|
|
pszCmdLine++;
|
|
fHasParam = FALSE;
|
|
}
|
|
} // while *pszCmdLine
|
|
|
|
pszCaption = lcStrDup(GetStringResource(sidCaption));
|
|
|
|
if (fHelp != POPUP_HELP) {
|
|
if (GetHighContrastFlag() || GetSysColor(COLOR_WINDOW) != RGB(255, 255, 255) ||
|
|
GetSysColor(COLOR_WINDOWTEXT) != 0)
|
|
fDisableAuthorColors = TRUE;
|
|
|
|
GetAuthorFlag();
|
|
}
|
|
|
|
switch (fHelp) {
|
|
case STANDARD_HELP:
|
|
pszClass = pchHelp;
|
|
break;
|
|
|
|
case POPUP_HELP:
|
|
pszClass = pchPopup;
|
|
break;
|
|
|
|
case TCARD_HELP:
|
|
pszClass = pchTCard;
|
|
break;
|
|
|
|
default:
|
|
pszClass = pchDoc;
|
|
break;
|
|
}
|
|
|
|
/* Fix for bug 81 (kevynct)
|
|
*
|
|
* fFatalExit is set to FALSE in FInitialize, and set to
|
|
* TRUE in Error(), in the case that a DIE action is received.
|
|
* Setting fFatalExit to FALSE should be the first thing we do.
|
|
*/
|
|
|
|
fFatalExit = FALSE;
|
|
|
|
/* (kevynct)
|
|
* fButtonsBusy was introduced so that we do a minimal number of
|
|
* screen updates when changing files. The flag is used only in
|
|
* FReplaceCloneHde, and checked only by the WM_SIZE processing code.
|
|
* We use it to ignore resizes generated by the button code.
|
|
*/
|
|
|
|
fButtonsBusy = FALSE;
|
|
|
|
/*
|
|
* We have to initialize dll's even for popup help, since they might
|
|
* contain an imbedded window.
|
|
*/
|
|
|
|
InitDLL();
|
|
|
|
if (!AppInit(hinsThis, hinsPrev)) {
|
|
return(FALSE);
|
|
}
|
|
|
|
// See if there is another book instance of WinHelp
|
|
|
|
hwndOtherWinHelp = FindWindow(txtDocClass, NULL);
|
|
|
|
// create the windows used in help
|
|
|
|
if (!CreateMainWindow(pszClass, FALSE)) {
|
|
Error(wERRS_OOM, wERRA_RETURN);
|
|
return FALSE;
|
|
}
|
|
|
|
// Initialize the menu bar
|
|
|
|
if (fHelp != TCARD_HELP && fHelp != POPUP_HELP)
|
|
SendMessage(ahwnd[MAIN_HWND].hwndParent, MSG_CHANGEMENU, MNU_RESET, 0L);
|
|
|
|
hwndFocusCur = ahwnd[iCurWindow].hwndTitle;
|
|
|
|
// REVIEW: 30-Nov-1993 [ralphw] This doesn't make sense -- we don't specify
|
|
// scroll bars when the window is created. I changed this to ShowScrollBar.
|
|
|
|
if (ahwnd[iCurWindow].hwndTopic)
|
|
ShowScrollBar(ahwnd[iCurWindow].hwndTopic, SB_BOTH, FALSE);
|
|
|
|
if (fHelp != POPUP_HELP) {
|
|
fMax = FGetHelpRect(hwndOtherWinHelp);
|
|
#if defined(BIDI_MULT) // jgross - determine if vert scroll bars go on
|
|
// the left or right
|
|
{
|
|
LPARAM l;
|
|
|
|
SystemParametersInfo(SPI_GETMULTILINGUAL, 0, &l, 0);
|
|
RtoL = (HIWORD(l) == Arabic) || (HIWORD(l) == Hebrew);
|
|
MakeScrollBarsRtoL(hwndTopicMain, RtoL, TRUE);
|
|
}
|
|
#endif
|
|
|
|
}
|
|
else
|
|
fMax = FALSE;
|
|
|
|
hmnuHelp = GetMenu(ahwnd[iCurWindow].hwndParent);
|
|
|
|
osver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
|
|
|
|
GetVersionEx(&osver);
|
|
|
|
fIsThisChicago = (osver.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS);
|
|
fIsThisNewShell4 = (osver.dwMajorVersion >= 4 ) ;
|
|
|
|
if (fHelp != POPUP_HELP && !fIsThisNewShell4)
|
|
LoadCtl3d();
|
|
|
|
if (cmd == CMD_HELP_ON_HELP) { // We do not care what the command
|
|
JumpHOH(NULL); // line is if the user requested help on help
|
|
// request.
|
|
CloseHelp();
|
|
}
|
|
|
|
else {
|
|
if (*pszCmdLine == '\0') {
|
|
if (cmd)
|
|
PostErrorMessage(wERRS_NOHELP_FILE);
|
|
|
|
/*
|
|
* If help was started by running the executable, and no
|
|
* filename was specified, then put up the open file dialog box.
|
|
*/
|
|
|
|
if (fHelp == BOOK_HELP) {
|
|
ASSERT(iCurWindow == MAIN_HWND);
|
|
MoveWindow(ahwnd[iCurWindow].hwndParent, rctHelp.left,
|
|
rctHelp.top, rctHelp.cx, rctHelp.cy, TRUE);
|
|
ShowWindow(ahwnd[iCurWindow].hwndParent, wCmdShow);
|
|
|
|
fm = DlgOpenFile(ahwnd[iCurWindow].hwndParent, NULL, NULL);
|
|
if (!fm) {
|
|
EarlyTermination:
|
|
FlushMessageQueue(WM_USER);
|
|
if (pCtl3dUnregister)
|
|
pCtl3dUnregister(hInsNow);
|
|
return FALSE; // terminate
|
|
}
|
|
OpenBookHelp:
|
|
fDelayShow = TRUE;
|
|
fmSave = FmCopyFm(fm);
|
|
if (FReplaceHde("", &fm, NULL)) {
|
|
fDelayShow = FALSE;
|
|
SetOnTopState(iCurWindow, ahwnd[iCurWindow].fsOnTop);
|
|
if (!hfsGid || !cntFlags.cCntItems || fCompare) {
|
|
if (!cntFlags.fMainMax) {
|
|
MoveWindow(ahwnd[iCurWindow].hwndParent,
|
|
rctHelp.left, rctHelp.top,
|
|
rctHelp.cx, rctHelp.cy, TRUE);
|
|
ShowWindow(ahwnd[iCurWindow].hwndParent, wCmdShow);
|
|
}
|
|
else
|
|
ShowWindow(ahwnd[iCurWindow].hwndParent, SW_MAXIMIZE);
|
|
|
|
if (fCompare)
|
|
FWinHelp(fmSave, HELP_CONTENTS, 0);
|
|
else
|
|
FJumpIndex(fmSave);
|
|
}
|
|
else {
|
|
ShowWindow(ahwnd[iCurWindow].hwndParent, SW_HIDE);
|
|
fNoQuit = FALSE;
|
|
Finder();
|
|
}
|
|
}
|
|
else {
|
|
goto EarlyTermination;
|
|
}
|
|
RemoveFM(&fm);
|
|
RemoveFM(&fmSave);
|
|
}
|
|
}
|
|
else {
|
|
if (!(fm = FmNewExistSzDir(pszCmdLine,
|
|
DIR_CURRENT | DIR_INI | DIR_PATH | DIR_SILENT_REG))) {
|
|
lstrcpy(rgchName, pszCmdLine);
|
|
CharUpper(rgchName);
|
|
if (!strstr(rgchName, txtHlpExtension)) {
|
|
ChangeExtension(rgchName, txtHlpExtension);
|
|
fm = FmNewExistSzDir(rgchName,
|
|
DIR_CURRENT | DIR_INI | DIR_PATH | DIR_SILENT_REG);
|
|
if (fm)
|
|
lstrcpy(rgchName, fm);
|
|
}
|
|
}
|
|
if (!fm && !(fm = FindThisFile(pszCmdLine, TRUE))) {
|
|
goto EarlyTermination;
|
|
}
|
|
else {
|
|
if (cmd == CMD_NOTHING) {
|
|
ASSERT(fHelp == BOOK_HELP);
|
|
MoveWindow(ahwnd[iCurWindow].hwndParent, rctHelp.left,
|
|
rctHelp.top, rctHelp.cx, rctHelp.cy, FALSE);
|
|
goto OpenBookHelp;
|
|
}
|
|
|
|
switch(cmd) {
|
|
case CMD_KEYWORD:
|
|
if (fHelp == POPUP_HELP)
|
|
return FALSE; // can't use popups for keywords
|
|
FShowKey(fm, (LPSTR) pchBuffer);
|
|
break;
|
|
|
|
case CMD_CTX_NUMBER:
|
|
if (fHelp == POPUP_HELP)
|
|
FPopupCtx(fm, ctx);
|
|
else {
|
|
strcpy(rgchName, fm);
|
|
if (szWindowName[0]) {
|
|
lstrcat(rgchName, ">");
|
|
lstrcat(rgchName, szWindowName);
|
|
}
|
|
FJumpContext((LPSTR) rgchName, ctx);
|
|
}
|
|
break;
|
|
|
|
case CMD_CTX_STRING:
|
|
if (fHelp == POPUP_HELP)
|
|
FPopupId(fm, (LPSTR) pchBuffer);
|
|
else {
|
|
strcpy(rgchName, fm);
|
|
if (szWindowName[0]) {
|
|
lstrcat(rgchName, ">");
|
|
lstrcat(rgchName, szWindowName);
|
|
}
|
|
FJumpId((LPSTR) rgchName, (LPSTR) pchBuffer);
|
|
}
|
|
break;
|
|
|
|
default:
|
|
if (fHelp == POPUP_HELP)
|
|
return FALSE; // can't use popups without an id
|
|
FJumpIndex(fm);
|
|
break;
|
|
}
|
|
DisposeFm(fm);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (fHelp != TCARD_HELP) {
|
|
if (!IsZoomed(ahwnd[iCurWindow].hwndParent) &&
|
|
!IsIconic(ahwnd[iCurWindow].hwndParent))
|
|
MoveWindow(ahwnd[iCurWindow].hwndParent, rctHelp.left, rctHelp.top,
|
|
rctHelp.cx, rctHelp.cy, FALSE);
|
|
}
|
|
|
|
|
|
// Attempt to register as a pen-win aware application
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
/***************************************************************************
|
|
*
|
|
- Name: FTerminate( void )
|
|
-
|
|
* Purpose:
|
|
* Contains all of the termination routines needed when the program
|
|
* falls out of the main message loop. Returns FALSE if this cannot
|
|
* be done, though nothing can be done about it.
|
|
*
|
|
* Arguments:
|
|
* None.
|
|
*
|
|
* Returns:
|
|
* TRUE, if terminating seccessfully, else FALSE.
|
|
*
|
|
*
|
|
*
|
|
***************************************************************************/
|
|
|
|
typedef LPMMIOPROC (WINAPI *LPMMIOINSTALL)(FOURCC, LPMMIOPROC, DWORD);
|
|
extern LPMMIOINSTALL lpfnInstall;
|
|
|
|
INLINE static void STDCALL FTerminate(void)
|
|
{
|
|
if (hfsBM != NULL)
|
|
CloseAndCleanUpBMFS();
|
|
|
|
if (hbitLine)
|
|
DeleteObject(hbitLine);
|
|
|
|
if (hfontDefault != hfontSmallSys && hfontDefault) {
|
|
DeleteObject(hfontDefault);
|
|
hfontDefault = NULL;
|
|
}
|
|
|
|
if (hfontSmallSys != NULL) {
|
|
DeleteObject(hfontSmallSys);
|
|
hfontSmallSys = NULL;
|
|
}
|
|
|
|
// REVIEW: 08-Apr-1994 [ralphw] Make certain this happens BEFORE we unload
|
|
// any dll's.
|
|
|
|
// CleanupDlgPrint();
|
|
|
|
// De-initialize MM IOProc if we did it before.
|
|
|
|
if (lpfnInstall)
|
|
mmInit(FALSE);
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
* AppInit(HINSTANCE, HINSTANCE)
|
|
*
|
|
* Description:
|
|
* This function is called when the application is first loaded into
|
|
* memory. It performs all initalization which is not to be done once per
|
|
* instance.
|
|
*
|
|
* Arguments:
|
|
* 1. hIns - current instance handle
|
|
* 2. hPrev - previous instance handle
|
|
*
|
|
* Returns;
|
|
* TRUE, if successful
|
|
* else FALSE
|
|
*-----------------------------------------------------------------------------*/
|
|
|
|
static BOOL STDCALL AppInit(HINSTANCE hIns, HINSTANCE hPrev)
|
|
{
|
|
if (!FLoadResources(hIns, hPrev))
|
|
return FALSE;
|
|
|
|
// REVIEW: okay not to register classes for this instance?
|
|
|
|
if (!hPrev) {
|
|
if (!RegHelpWinClasses(hIns)) // Register window classes
|
|
return FALSE;
|
|
}
|
|
|
|
// REVIEW: why set the focus?
|
|
|
|
else
|
|
SetFocus(ahwnd[iCurWindow].hwndParent);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
/*******************
|
|
**
|
|
** Name: HfontGetSmallSysFont
|
|
**
|
|
** Purpose: Returns a handle to a suitable small helvetica font
|
|
**
|
|
** Arguments: none
|
|
**
|
|
** Returns: The handle to the font, if created.
|
|
**
|
|
** Notes: This uses a static variable to save time. Some provision
|
|
** for deleting this puppy at termination is needed.
|
|
**
|
|
*******************/
|
|
|
|
HFONT STDCALL HfontGetSmallSysFont(VOID)
|
|
{
|
|
if (hfontSmallSys == NULL) {
|
|
int dyHeight = 0;
|
|
PSTR pszFontName = GetStringResource(sidSmallFont);
|
|
|
|
if (defcharset == (WORD) -1) {
|
|
HWND hwndDesktop = GetDesktopWindow();
|
|
HDC hdc = GetDC(hwndDesktop);
|
|
if (hdc) {
|
|
TEXTMETRIC tm;
|
|
GetTextMetrics(hdc, &tm);
|
|
defcharset = (WORD) tm.tmCharSet;
|
|
YAspectMul = GetDeviceCaps(hdc, LOGPIXELSY);
|
|
XAspectMul = GetDeviceCaps(hdc, LOGPIXELSX);
|
|
ReleaseDC(hwndDesktop, hdc);
|
|
}
|
|
else
|
|
OOM();
|
|
}
|
|
{
|
|
PSTR pszPoint = StrRChrDBCS(pszFontName, ',');
|
|
if (pszPoint) {
|
|
*pszPoint = '\0';
|
|
pszPoint = FirstNonSpace(pszPoint + 1);
|
|
if (isdigit((BYTE) *pszPoint))
|
|
dyHeight = MulDiv(YAspectMul, atoi(pszPoint) * 2, 144);
|
|
}
|
|
}
|
|
if (!dyHeight)
|
|
dyHeight = YAspectMul / 6;
|
|
|
|
hfontSmallSys = CreateFont(-dyHeight, 0, 0, 0, 0, 0, 0, 0,
|
|
defcharset, OUT_DEFAULT_PRECIS,
|
|
CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
|
|
VARIABLE_PITCH | FF_MODERN, pszFontName);
|
|
ASSERT(hfontSmallSys);
|
|
hfontDefault = hfontSmallSys;
|
|
}
|
|
return hfontSmallSys;
|
|
}
|
|
|
|
/********************************************************************
|
|
-
|
|
- Name: RegHelpWinClasses(HINSTANCE)
|
|
*
|
|
* Purpose:
|
|
* This function registers Help's main window and note window and
|
|
* topic window classes.
|
|
*
|
|
* Arguments:
|
|
* 1. hIns - current instance handle
|
|
*
|
|
* Returns;
|
|
* TRUE, if successful
|
|
* else FALSE
|
|
*
|
|
************************************************************************/
|
|
|
|
static BOOL STDCALL RegHelpWinClasses (HINSTANCE hIns)
|
|
{
|
|
WNDCLASSEX wc;
|
|
int iCls;
|
|
int endClass;
|
|
HICON hIconSmDefault;
|
|
|
|
// Fill in fields determined at runtime which are unique to specific
|
|
// window classes.
|
|
|
|
wc.cbSize = sizeof(wc);
|
|
wc.cbClsExtra = 0;
|
|
|
|
if (fHelp != POPUP_HELP) {
|
|
rgWndClsInfo[IWNDCLSMAIN].hIcon = LoadIcon(hIns,
|
|
MAKEINTRESOURCE(IDICO_DOCICON));
|
|
rgWndClsInfo[IWNDCLSMAIN].hIconSm = LoadImage(hIns,
|
|
MAKEINTRESOURCE(IDICO_DOCICON), IMAGE_ICON, 16, 16, 0);
|
|
|
|
rgWndClsInfo[IWNDCLSDOC].hIcon = rgWndClsInfo[IWNDCLSMAIN].hIcon;
|
|
rgWndClsInfo[IWNDCLSDOC].hIconSm = rgWndClsInfo[IWNDCLSMAIN].hIconSm;
|
|
|
|
rgWndClsInfo[IWNDCLSTCARD].hIcon = rgWndClsInfo[IWNDCLSMAIN].hIcon;
|
|
rgWndClsInfo[IWNDCLSTCARD].hIconSm = rgWndClsInfo[IWNDCLSMAIN].hIconSm;
|
|
|
|
rgWndClsInfo[IWNDCLSPATH].hIcon = hIconDefault;
|
|
|
|
rgWndClsInfo[IWNDCLS2ND].hIcon = LoadIcon(hIns,
|
|
MAKEINTRESOURCE(IDICO_PAGEICON));
|
|
rgWndClsInfo[IWNDCLS2ND].hIconSm = LoadImage(hIns,
|
|
MAKEINTRESOURCE(IDICO_PAGEICON), IMAGE_ICON, 16, 16, 0);
|
|
|
|
rgWndClsInfo[IWNDCLSICON].hbrBackground =
|
|
(HBRUSH) GetStockObject(GRAY_BRUSH);
|
|
|
|
iCls = (fHelp == TCARD_HELP ? IWNDCLSTCARD : 0); // index into class table
|
|
endClass = sizeof(rgWndClsInfo) / sizeof(rgWndClsInfo[0]);
|
|
}
|
|
else {
|
|
iCls = IWNDCLSPOPUP;
|
|
endClass = IWNDCLSNSR + 1;
|
|
}
|
|
|
|
hIconSmDefault = LoadImage(hIns, MAKEINTRESOURCE(IDICO_HELPICON),
|
|
IMAGE_ICON, 16, 16, 0);
|
|
|
|
// Walk the class table and register each class.
|
|
|
|
for (; iCls < endClass; iCls++) {
|
|
|
|
// Fill in fields determined at runtime which are common to all classes
|
|
// we create.
|
|
|
|
wc.style = rgWndClsInfo[iCls].style;
|
|
wc.lpfnWndProc = (WNDPROC) rgWndClsInfo[iCls].lpfnWndProc;
|
|
wc.cbWndExtra = rgWndClsInfo[iCls].cbWndExtra;
|
|
wc.hIcon = rgWndClsInfo[iCls].hIcon;
|
|
|
|
wc.hIconSm = (wc.hIcon == hIconDefault) ? hIconSmDefault :
|
|
rgWndClsInfo[iCls].hIconSm;
|
|
wc.hbrBackground = rgWndClsInfo[iCls].hbrBackground;
|
|
wc.lpszMenuName = MAKEINTRESOURCE(rgWndClsInfo[iCls].wMenuName);
|
|
wc.lpszClassName = (LPSTR) rgWndClsInfo[iCls].szClassName;
|
|
|
|
wc.hInstance = hIns;
|
|
wc.hCursor = hcurArrow;
|
|
|
|
if (!RegisterClassEx(&wc)) {
|
|
#ifdef _DEBUG
|
|
GetLastError();
|
|
#endif
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
/********************************************************************
|
|
-
|
|
- Name:
|
|
- CreateMainWindow(HINSTANCE)
|
|
*
|
|
* Purpose:
|
|
* This function creates all the windows required to bring up basic
|
|
* help on a topic.
|
|
* a. Help Window
|
|
* b. Topic WIndow
|
|
* c. Button Bar (Icon) Window
|
|
* d. NSR/Title window
|
|
*
|
|
* Arguments:
|
|
* 1. hIns - current instance handle
|
|
*
|
|
* Returns;
|
|
* TRUE, if successful else FALSE
|
|
*
|
|
*********************************************************************/
|
|
|
|
#ifndef NO_PRAGMAS
|
|
#pragma data_seg(".text", "CODE")
|
|
#endif
|
|
const char txtWINHELP[] = "WM_WINHELP";
|
|
const char txtWINDOC[] = "WM_WINDOC";
|
|
#ifndef NO_PRAGMAS
|
|
#pragma data_seg()
|
|
#endif
|
|
|
|
static BOOL STDCALL CreateMainWindow(PSTR pszClass, BOOL fButtonBar)
|
|
{
|
|
// We have to maintain the registered message, even though we don't use
|
|
// it in order to be compatible with the shareres.dll help dll.
|
|
|
|
// REVIEW: will this registered message be available to 16-bit dlls?
|
|
|
|
msgWinHelp = RegisterWindowMessage(((fHelp) ?
|
|
txtWINHELP : txtWINDOC));
|
|
|
|
ahwnd[MAIN_HWND].hwndParent = CreateWindowEx(WS_EX_CLIENTEDGE,
|
|
pszClass,
|
|
pszCaption,
|
|
WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
|
|
rctHelp.left, rctHelp.top, rctHelp.cx, rctHelp.cy,
|
|
NULL, // no parent
|
|
NULL, // use class menu
|
|
hInsNow, // handle to window instance
|
|
NULL // no params to pass on
|
|
);
|
|
|
|
if (ahwnd[MAIN_HWND].hwndParent == NULL)
|
|
return FALSE;
|
|
|
|
ahwnd[MAIN_HWND].pszMemberName = (PSTR) txtMain;
|
|
|
|
/*
|
|
* REVIEW: 31-Mar-1994 [ralphw] -- no dice, you GPF because other
|
|
* code assumes the existance of hwndTitle. So we have to create all
|
|
* these child windows we don't use. We should figure out why and how to
|
|
* prevent it. We don't want this overhead for popup help either.
|
|
*/
|
|
|
|
// if (fHelp != TCARD_HELP) {
|
|
if (!CreateChildWindows(MAIN_HWND, NULL, fButtonBar))
|
|
return FALSE;
|
|
// }
|
|
return TRUE;
|
|
}
|
|
|
|
/***************************************************************************
|
|
|
|
FUNCTION: CreateChildWindows
|
|
|
|
PURPOSE: Create child windows of ahwnd[MAIN_HWND].hwndParent
|
|
|
|
PARAMETERS:
|
|
hwndParent
|
|
hinst
|
|
fButtonBar -- FALSE to suppress creation of buttons
|
|
|
|
RETURNS:
|
|
|
|
COMMENTS:
|
|
Breaking this out into a separate function makes it theoretically
|
|
possible to create these windows only when they would actually be
|
|
used. In the case of invoking only a popup or Training Card, these
|
|
windows aren't needed.
|
|
|
|
MODIFICATION DATES:
|
|
12-Mar-1993 [ralphw]
|
|
|
|
***************************************************************************/
|
|
|
|
BOOL STDCALL CreateChildWindows(int index, const WSMAG* pwsmag, BOOL fButtonBar)
|
|
{
|
|
// Create topic window
|
|
|
|
ASSERT(IsValidWindow(ahwnd[index].hwndParent));
|
|
|
|
if (!(ahwnd[index].hwndTopic = CreateWindow(pchTopic,
|
|
NULL, WS_CHILD | WS_VSCROLL | WS_HSCROLL,
|
|
0, 0, 0, 0, ahwnd[index].hwndParent, NULL, hInsNow, NULL)))
|
|
return FALSE ;
|
|
|
|
// Create a non-scrolling region window
|
|
|
|
if (!(ahwnd[index].hwndTitle =
|
|
CreateWindow(pchNSR, NULL, WS_CHILD,
|
|
0, 0, 0, 0, ahwnd[index].hwndParent, NULL, hInsNow, NULL)))
|
|
return FALSE;
|
|
|
|
if (fHelp == POPUP_HELP)
|
|
return TRUE;
|
|
|
|
// 4.0: we allow a button bar in a secondary window
|
|
|
|
if (!pwsmag || pwsmag->wMax >= FWSMAG_FIRST_BUTTON) {
|
|
if (!(ahwnd[index].hwndButtonBar = CreateWindow(pchIcon,
|
|
NULL, WS_CHILD, 0, 0, 0, 0, ahwnd[index].hwndParent,
|
|
NULL, hInsNow, NULL)))
|
|
return FALSE;
|
|
if (fButtonBar) {
|
|
fButtonsBusy = TRUE;
|
|
CreateCoreButtons(ahwnd[index].hwndButtonBar, pwsmag);
|
|
fButtonsBusy = FALSE;
|
|
}
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
/********************************************************************
|
|
-
|
|
- Name:
|
|
- FLoadResources(HINSTANCE, HINSTANCE)
|
|
*
|
|
* Purpose:
|
|
* This function creates all the windows used in help.
|
|
* a. Loads the accelarator table.
|
|
* b. Loads the arrow cursor
|
|
* c. Loads the hour glass cursor
|
|
* d. Loads the hand cursor used to idntify jump or glossary buttons
|
|
* within the topic.
|
|
* e. Load Bitmap line resource
|
|
* f. Load icon accelerator string
|
|
*
|
|
* Arguments:
|
|
* 1. hIns - current instance handle
|
|
* 2. hPrev - previous instance handle
|
|
*
|
|
* Returns;
|
|
* TRUE if successful
|
|
*********************************************************************/
|
|
|
|
static BOOL STDCALL FLoadResources(HINSTANCE hIns, HINSTANCE hPrev)
|
|
{
|
|
// REVIEW: hndAccel and hIconDefault aren't necessary for popup windows
|
|
|
|
hndAccel = LoadAccelerators(hIns, MAKEINTRESOURCE(HELPACCEL));
|
|
hIconDefault = LoadIcon(hIns, MAKEINTRESOURCE(IDICO_HELPICON));
|
|
|
|
hcurArrow = LoadCursor(NULL, IDC_ARROW);
|
|
hcurIBeam = LoadCursor(NULL, IDC_IBEAM);
|
|
|
|
hbitLine = LoadBitmap(hIns, MAKEINTRESOURCE(IDBMP_HELPLINE));
|
|
|
|
LoadOOMString(); // Load resident error strings
|
|
if (!hndAccel || !hcurArrow || !hIconDefault || !hbitLine) {
|
|
Error(wERRS_OOM_FLOADRESOURCES, wERRA_RETURN);
|
|
return FALSE;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
/***************************************************************************
|
|
|
|
FUNCTION: LoadOOMString
|
|
|
|
PURPOSE: Load Out of Memory string from the resource file.
|
|
|
|
PARAMETERS:
|
|
VOID
|
|
|
|
RETURNS:
|
|
|
|
COMMENTS:
|
|
|
|
MODIFICATION DATES:
|
|
12-Mar-1993 [ralphw]
|
|
|
|
***************************************************************************/
|
|
|
|
#define MAX_OOM_ERROR_STRING 250 // Max size of resident errors
|
|
|
|
INLINE static void STDCALL LoadOOMString(VOID)
|
|
{
|
|
pszOutOfMemory = LocalStrDup(GetStringResource(wERRS_OOM));
|
|
}
|
|
|
|
/********************************************************************
|
|
-
|
|
- Name: FGetHelpRect( )
|
|
*
|
|
* Purpose: This function sets the values of rctHelp, either
|
|
* offset from the previous instance, or from the win.ini
|
|
* file.
|
|
*
|
|
* Arguments: hIns - current instance handle
|
|
* hInsPrev - previous instance handle
|
|
*
|
|
* Returns: TRUE if previous instance of help was maximized
|
|
*
|
|
*********************************************************************/
|
|
|
|
// minimum width and height values
|
|
|
|
#define HELP_WIDTH_MINIMUM 200
|
|
#define HELP_HEIGHT_MINIMUM 200
|
|
|
|
static BOOL STDCALL FGetHelpRect(HWND hwndOtherWinHelp)
|
|
{
|
|
BOOL fMaximized;
|
|
if (!cxScreen)
|
|
GetScreenResolution();
|
|
|
|
if (hwndOtherWinHelp && !IsIconic(hwndOtherWinHelp)) {
|
|
GetWindowWRect(hwndOtherWinHelp, &rctHelp);
|
|
|
|
rctHelp.top += GetSystemMetrics(SM_CYCAPTION);
|
|
rctHelp.left += GetSystemMetrics(SM_CYFRAME);
|
|
|
|
CheckWindowPosition(&rctHelp, TRUE);
|
|
return IsZoomed(hwndOtherWinHelp);
|
|
}
|
|
|
|
ReadWinRect(&rctHelp, WCH_MAIN, &fMaximized);
|
|
|
|
rctHelpOrg = rctHelp;
|
|
fMaxOrg = fMaximized;
|
|
|
|
return fMaximized;
|
|
}
|
|
|
|
/********************************************************************
|
|
- Name:
|
|
- QuitHelp()
|
|
-
|
|
* Description:
|
|
* This function should be called to terminate the help session.
|
|
*
|
|
* Arguments:
|
|
* None.
|
|
*
|
|
* Returns;
|
|
* NULL
|
|
*
|
|
* Notes:
|
|
* If help is currently printing, help's termination will be
|
|
* delayed until the print job is over.
|
|
*
|
|
*********************************************************************/
|
|
|
|
void STDCALL QuitHelp(void)
|
|
{
|
|
KillOurTimers();
|
|
if (hdlgPrint == NULL) {
|
|
CloseHelp();
|
|
}
|
|
else
|
|
fQuitHelp = TRUE;
|
|
}
|
|
|
|
|
|
/********************************************************************
|
|
-
|
|
- Name:
|
|
- DestroyHelp()
|
|
*
|
|
* Purpose:
|
|
* This function cleans up help.
|
|
*
|
|
* Arguments:
|
|
* None.
|
|
*
|
|
* Returns;
|
|
* NULL
|
|
*
|
|
*********************************************************************/
|
|
|
|
void STDCALL DestroyHelp(void)
|
|
{
|
|
HDE hde;
|
|
|
|
// reset the icon to default and release the icon if required.
|
|
|
|
// ResetIcon();
|
|
|
|
// REVIEW: we should only call this if we invoked help
|
|
|
|
// if (!fHelp)
|
|
// WinHelp(ahwnd[MAIN_HWND].hwndParent, NULL, HELP_QUIT, 0L);
|
|
|
|
// We only write if the winpos has changed
|
|
// (fMaxOrg != IsZoomed(ahwnd[iCurWindow].hwndParent))) {
|
|
|
|
|
|
// (kevynct) Destroy all enlisted DEs (in random order)
|
|
|
|
while ((hde = HdeRemoveEnv()) != NULL)
|
|
DestroyHde(hde);
|
|
if (ppd) {
|
|
GlobalFree(ppd->hDevNames);
|
|
GlobalFree(ppd->hDevMode);
|
|
}
|
|
|
|
FTerminate();
|
|
|
|
if (hfsGid) {
|
|
SaveGidPositions();
|
|
CloseGid();
|
|
}
|
|
|
|
if (pCtl3dUnregister)
|
|
pCtl3dUnregister(hInsNow);
|
|
|
|
// Send Quit message to terminate message polling
|
|
|
|
if (hfShare)
|
|
CloseHandle(hfShare);
|
|
|
|
PostQuitMessage(0);
|
|
}
|
|
|
|
/***************************************************************************
|
|
|
|
FUNCTION: GetAuthorFlag
|
|
|
|
PURPOSE: Determine is Help Author mode is on or not
|
|
|
|
PARAMETERS:
|
|
void
|
|
|
|
RETURNS:
|
|
|
|
COMMENTS:
|
|
Avoid the temptation to put this in the registry. By leaving it in
|
|
win.ini, product support technicians can easily have a user turn it
|
|
on in order to more easily track down a help problem.
|
|
|
|
MODIFICATION DATES:
|
|
05-Apr-1995 [ralphw]
|
|
|
|
***************************************************************************/
|
|
|
|
#ifndef NO_PRAGMAS
|
|
#pragma data_seg(".text", "CODE")
|
|
#endif
|
|
|
|
static char txtHlpAuthor[] = "Help Author";
|
|
|
|
#ifndef NO_PRAGMAS
|
|
#pragma data_seg()
|
|
#endif
|
|
|
|
void STDCALL GetAuthorFlag(void)
|
|
{
|
|
fHelpAuthor = GetProfileInt(txtIniHelpSection, txtHlpAuthor, 0);
|
|
}
|
|
|
|
/***************************************************************************
|
|
|
|
FUNCTION: WriteProfile
|
|
|
|
PURPOSE:
|
|
|
|
PARAMETERS:
|
|
void
|
|
|
|
RETURNS:
|
|
|
|
COMMENTS:
|
|
|
|
MODIFICATION DATES:
|
|
28-Jan-1993 [ralphw]
|
|
|
|
***************************************************************************/
|
|
|
|
#if 0
|
|
static void STDCALL WriteProfile(void)
|
|
{
|
|
char szKeyBuf[80];
|
|
|
|
ASSERT (fHelp != TCARD_HELP && fHelp != POPUP_HELP && !hfsGid);
|
|
|
|
/*
|
|
* Note that we only save the on-top state if it was forced, not if it
|
|
* was set by the help author.
|
|
*/
|
|
|
|
wsprintf(szKeyBuf, "%u %u %u %d 1", INI_VERSION,
|
|
cntFlags.fsOnTop,
|
|
cntFlags.iFontAdjustment, cntFlags.fOverColor);
|
|
WriteProfileString(txtIniHelpSection, txtSettings, szKeyBuf);
|
|
}
|
|
#endif
|
|
|
|
/***************************************************************************
|
|
|
|
FUNCTION: FirstNonSpace
|
|
|
|
PURPOSE: Return a pointer to the first non-space character
|
|
|
|
RETURNS:
|
|
|
|
COMMENTS:
|
|
|
|
MODIFICATION DATES:
|
|
30-May-1989 [ralphw]
|
|
|
|
***************************************************************************/
|
|
|
|
PSTR STDCALL FirstNonSpace(PCSTR pszOrg)
|
|
{
|
|
// Assign to local because we're changing the pointer, not the contents.
|
|
|
|
PSTR psz = (PSTR) pszOrg;
|
|
|
|
if (psz != NULL) {
|
|
while (*psz == SPACE || *psz == '\t')
|
|
psz++;
|
|
}
|
|
|
|
return psz;
|
|
}
|
|
|
|
#if 0
|
|
|
|
/***************************************************************************
|
|
*
|
|
- Name ResetIcon()
|
|
-
|
|
* Purpose Used for resetting the default icon inside window class.
|
|
*
|
|
* Returns
|
|
* Nothing
|
|
*
|
|
* +++
|
|
*
|
|
* Notes
|
|
*
|
|
***************************************************************************/
|
|
|
|
void STDCALL ResetIcon()
|
|
{
|
|
HICON hIconOverLoad;
|
|
|
|
// Ensure that the window class actually refers to the correct icon
|
|
|
|
if (hIconDefault)
|
|
SetClassLong(ahwnd[iCurWindow].hwndParent, GCL_HICON, (LONG) hIconDefault);
|
|
|
|
// Now remove the icon which is help in the current window
|
|
|
|
hIconOverLoad = (HICON) GetWindowLong(ahwnd[iCurWindow].hwndParent, GHWL_HICON);
|
|
if (hIconOverLoad) {
|
|
GlobalFree(hIconOverLoad);
|
|
SetWindowLong(ahwnd[iCurWindow].hwndParent, GHWL_HICON, 0);
|
|
}
|
|
}
|
|
|
|
#endif
|
|
|
|
/***************************************************************************
|
|
|
|
FUNCTION: ReadWinRect
|
|
|
|
PURPOSE: Read a window position from .GID or WIN.INI.
|
|
Cannot be used for secondary windows.
|
|
|
|
PARAMETERS:
|
|
prc
|
|
ch
|
|
pfMax
|
|
|
|
RETURNS:
|
|
|
|
COMMENTS:
|
|
|
|
MODIFICATION DATES:
|
|
28-Dec-1993 [ralphw]
|
|
|
|
***************************************************************************/
|
|
|
|
void STDCALL ReadWinRect(WRECT* prc, char ch, BOOL* pfMax)
|
|
{
|
|
BOOL fGotRect = FALSE;
|
|
|
|
ASSERT(fHelp != POPUP_HELP)
|
|
|
|
if (hfsGid) {
|
|
switch (ch) {
|
|
case WCH_MAIN:
|
|
if (pPositions[POS_MAIN].rc.cx) {
|
|
*prc = pPositions[POS_MAIN].rc;
|
|
*pfMax = cntFlags.fMainMax;
|
|
fGotRect = TRUE;
|
|
}
|
|
break;
|
|
|
|
case WCH_HISTORY: // history window
|
|
if (pPositions[POS_HISTORY].rc.cx) {
|
|
*prc = pPositions[POS_HISTORY].rc;
|
|
fGotRect = TRUE;
|
|
}
|
|
break;
|
|
|
|
case WCH_TOPICS: // Finder dialog box
|
|
if (pPositions[POS_TOPICS].rc.cx) {
|
|
*prc = pPositions[POS_TOPICS].rc;
|
|
fGotRect = TRUE;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
if (!fGotRect) {
|
|
SetRectEmpty((PRECT) prc);
|
|
if (prc->left == 0 && prc->cx == 0) {
|
|
switch(ch) {
|
|
case WCH_HISTORY:
|
|
SetRect((PRECT) prc, 0, 0, 200, 200);
|
|
break;
|
|
|
|
case WCH_TOPICS:
|
|
SetRect((PRECT) prc, cxScreen / 4, 50, 200, 200);
|
|
break;
|
|
|
|
default:
|
|
case WCH_MAIN:
|
|
SetRect((PRECT) prc, rcWorkArea.left + RECT_WIDTH(rcWorkArea) / 8,
|
|
rcWorkArea.top + 4,
|
|
(RECT_WIDTH(rcWorkArea) / 8) * 6 + rcWorkArea.left,
|
|
RECT_HEIGHT(rcWorkArea) - 4);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
CheckWindowPosition(prc, TRUE);
|
|
}
|
|
|
|
/***************************************************************************
|
|
|
|
FUNCTION: CheckWindowPosition
|
|
|
|
PURPOSE: Ensure that the window is within the work area (that portion
|
|
of the desktop that is outside of the tray).
|
|
|
|
PARAMETERS:
|
|
prc
|
|
|
|
RETURNS:
|
|
|
|
COMMENTS:
|
|
|
|
MODIFICATION DATES:
|
|
28-Dec-1993 [ralphw]
|
|
|
|
***************************************************************************/
|
|
|
|
void STDCALL CheckWindowPosition(WRECT* prc, BOOL fAllowShrinkage)
|
|
{
|
|
int diff;
|
|
|
|
ASSERT(cxScreen);
|
|
|
|
// Make certain we don't go off the edge of the screen
|
|
|
|
if (prc->left < rcWorkArea.left)
|
|
prc->left = rcWorkArea.left;
|
|
if (prc->top < rcWorkArea.top)
|
|
prc->top = rcWorkArea.top;
|
|
|
|
/*
|
|
* If the right side of the window is off the work area, move the
|
|
* window to the left. If we don't have enough room for the window when
|
|
* moved all the way to the left, then shrink the window (won't work for
|
|
* dialogs).
|
|
*/
|
|
|
|
if (prc->cx > RECT_WIDTH(rcWorkArea)) {
|
|
diff = (prc->left + prc->cx) - RECT_WIDTH(rcWorkArea);
|
|
if (diff < prc->left)
|
|
prc->left -= diff;
|
|
else if (fAllowShrinkage) {
|
|
diff -= prc->left;
|
|
prc->left = rcWorkArea.left;
|
|
prc->cx -= diff;
|
|
}
|
|
else // Can't shrink, so shove to the left side
|
|
prc->left = rcWorkArea.left;
|
|
}
|
|
|
|
// Same question about the bottom of the window being off the work area
|
|
|
|
if (prc->cy > RECT_HEIGHT(rcWorkArea)) {
|
|
diff = (prc->top + prc->cy) - RECT_HEIGHT(rcWorkArea);
|
|
if (diff < prc->top)
|
|
prc->top -= diff;
|
|
else if (fAllowShrinkage) {
|
|
diff -= prc->top;
|
|
prc->top = rcWorkArea.top;
|
|
prc->cy -= diff;
|
|
}
|
|
else // Can't shrink, so shove to the top
|
|
prc->top = rcWorkArea.top;
|
|
}
|
|
|
|
// Force minimum window size
|
|
|
|
if (prc->cx < HELP_WIDTH_MINIMUM) {
|
|
prc->cx = HELP_WIDTH_MINIMUM;
|
|
|
|
// Width is now correct, but we could be off the work area. Start over
|
|
|
|
CheckWindowPosition(prc, fAllowShrinkage);
|
|
}
|
|
if (prc->cy < HELP_HEIGHT_MINIMUM) {
|
|
prc->cy = HELP_HEIGHT_MINIMUM;
|
|
|
|
// Height is now correct, but we could be off the work area. Start over
|
|
|
|
CheckWindowPosition(prc, fAllowShrinkage);
|
|
}
|
|
}
|
|
|
|
#if DEADCODE
|
|
|
|
/*******************
|
|
-
|
|
- Name: GetProfileWinPos
|
|
*
|
|
* Purpose: Gets a window position from the WIN.INI file
|
|
*
|
|
* Arguments: pch - name of variable to get
|
|
* px, py, pdx, pdy - pointer to places to load position into
|
|
* pfMax - pointer to max flag. May be NULL.
|
|
*
|
|
* Returns: nothing.
|
|
*
|
|
******************/
|
|
|
|
INLINE static VOID STDCALL GetProfileWinPos(PSTR pch, LONG* px, LONG* py,
|
|
LONG* pdx, LONG* pdy, BOOL* pfMax)
|
|
{
|
|
PSTR psz;
|
|
char szBuf[40];
|
|
|
|
if (!GetProfileString(txtIniHelpSection, pch, txtZeroLength, szBuf, sizeof(szBuf))) {
|
|
*px = *py = *pdx = *pdy = 0; // Initialize all positions to 0
|
|
if (pfMax != NULL)
|
|
*pfMax = 0;
|
|
return;
|
|
}
|
|
|
|
psz = GetNextDigit(px, szBuf);
|
|
psz = GetNextDigit(py, psz);
|
|
psz = GetNextDigit(pdx, psz);
|
|
psz = GetNextDigit(pdy, psz);
|
|
|
|
ASSERT(sizeof(BOOL) == sizeof(LONG));
|
|
if (pfMax != NULL)
|
|
GetNextDigit((LONG*) pfMax, psz);
|
|
}
|
|
|
|
#endif
|
|
|
|
static PSTR STDCALL GetNextDigit(LONG* pdigit, PSTR pszCur)
|
|
{
|
|
while (!isdigit((BYTE) *pszCur) && *pszCur)
|
|
pszCur++;
|
|
*pdigit = atoi(pszCur);
|
|
while (isdigit((BYTE) *pszCur))
|
|
pszCur++;
|
|
return pszCur;
|
|
}
|
|
|
|
/***************************************************************************
|
|
|
|
FUNCTION: GetScreenResolution
|
|
|
|
PURPOSE: Get the screen resolution
|
|
|
|
PARAMETERS:
|
|
void
|
|
|
|
RETURNS:
|
|
|
|
COMMENTS:
|
|
|
|
MODIFICATION DATES:
|
|
22-Mar-1993 [ralphw]
|
|
|
|
***************************************************************************/
|
|
|
|
#ifndef SPI_GETWORKAREA
|
|
#define SPI_GETWORKAREA 48
|
|
#endif
|
|
|
|
void STDCALL GetScreenResolution(void)
|
|
{
|
|
cxScreen = GetSystemMetrics(SM_CXSCREEN);
|
|
cyScreen = GetSystemMetrics(SM_CYSCREEN);
|
|
|
|
if (!SystemParametersInfo(SPI_GETWORKAREA, 0, &rcWorkArea, 0)) {
|
|
SetRectEmpty(&rcWorkArea);
|
|
}
|
|
|
|
if (IsRectEmpty(&rcWorkArea)) {
|
|
rcWorkArea.right = cxScreen;
|
|
rcWorkArea.bottom = cyScreen;
|
|
}
|
|
}
|
|
|
|
LPVOID (WINAPI* pWOWGetVDMPointerFix)(DWORD vp, DWORD dwBytes, BOOL fProtectMode);
|
|
VOID (WINAPI* pWOWGetVDMPointerUnfix)(DWORD vp);
|
|
LPVOID (WINAPI* pGlobalLock16)(HGLOBAL hMem);
|
|
BOOL (WINAPI* pGlobalUnlock16)(HGLOBAL hMem);
|
|
|
|
BOOL STDCALL LoadLockFunctions(void)
|
|
{
|
|
HLIBMOD hmodule;
|
|
if (fIsThisChicago) {
|
|
if ((hmodule = HFindDLL("wow32.dll", FALSE))) {
|
|
pWOWGetVDMPointerFix =
|
|
(WOWGETVDMPOINTERFIX) GetProcAddress(hmodule, "WOWGetVDMPointerFix");
|
|
pWOWGetVDMPointerUnfix =
|
|
(WOWGETVDMPOINTERUNFIX) GetProcAddress(hmodule, "WOWGetVDMPointerUnfix");
|
|
}
|
|
ASSERT(pWOWGetVDMPointerFix);
|
|
ASSERT(pWOWGetVDMPointerUnfix);
|
|
return (BOOL) pWOWGetVDMPointerFix;
|
|
}
|
|
else {
|
|
if ((hmodule = HFindDLL("wow32.dll", FALSE))) {
|
|
pGlobalLock16 =
|
|
(GLOBALLOCK16) GetProcAddress(hmodule, "WOWGlobalLock16");
|
|
pGlobalUnlock16 =
|
|
(GLOBALUNLOCK16) GetProcAddress(hmodule, "WOWGlobalUnlock6");
|
|
}
|
|
ASSERT(pGlobalLock16);
|
|
return (BOOL) pGlobalLock16;
|
|
}
|
|
}
|
|
|
|
void STDCALL SaveGidPositions(void)
|
|
{
|
|
if (fHelp == POPUP_HELP || fHelp == TCARD_HELP)
|
|
return;
|
|
|
|
ASSERT(IsValidWindow(ahwnd[MAIN_HWND].hwndParent));
|
|
|
|
cntFlags.fMainMax = IsZoomed(ahwnd[MAIN_HWND].hwndParent);
|
|
|
|
if (!cntFlags.fMainMax) {
|
|
if (!IsIconic(ahwnd[MAIN_HWND].hwndParent) &&
|
|
!EqualRect((PRECT) &rctHelp, (PRECT) &rctHelpOrg)) {
|
|
WriteWinPosHwnd(ahwnd[MAIN_HWND].hwndParent,
|
|
cntFlags.fMainMax, WCH_MAIN);
|
|
}
|
|
}
|
|
}
|
|
|
|
BOOL STDCALL GetHighContrastFlag(void)
|
|
{
|
|
HIGHCONTRAST highcontrast;
|
|
|
|
highcontrast.cbSize = sizeof(highcontrast);
|
|
|
|
if (fIsThisNewShell4 && SystemParametersInfo(SPI_GETHIGHCONTRAST,
|
|
sizeof(highcontrast),
|
|
&highcontrast, FALSE)) {
|
|
return (highcontrast.dwFlags & HCF_HIGHCONTRASTON);
|
|
}
|
|
else
|
|
return FALSE;
|
|
}
|