886 lines
24 KiB
C
886 lines
24 KiB
C
/************************************************************/
|
||
/* Windows Write, Copyright 1985-1992 Microsoft Corporation */
|
||
/************************************************************/
|
||
|
||
/* help.c -- MEMO Help handler */
|
||
|
||
#define NOCLIPBOARD
|
||
#define NOGDICAPMASKS
|
||
#define NOVIRTUALKEYCODES
|
||
#define NOSYSMETRICS
|
||
#define NOMENUS
|
||
#define NOCOMM
|
||
#define NOSOUND
|
||
#define NOMINMAX
|
||
#include <windows.h>
|
||
|
||
#include "mw.h"
|
||
#define NOUAC
|
||
#include "cmddefs.h"
|
||
#include "stdlib.h"
|
||
#include "docdefs.h"
|
||
#include "printdef.h" /* printdefs.h */
|
||
#include "dispdefs.h"
|
||
#include "fmtdefs.h"
|
||
#include "bitmaps.h"
|
||
|
||
#define NOIDISAVEPRINT
|
||
#define NOIDIFORMATS
|
||
#include "dlgdefs.h"
|
||
#include "wwdefs.h"
|
||
#define NOKCCODES
|
||
#include "ch.h"
|
||
#define NOSTRMERGE
|
||
#define NOSTRUNDO
|
||
#include "str.h"
|
||
|
||
extern HWND vhWndMsgBoxParent;
|
||
extern struct WWD rgwwd[];
|
||
extern struct DOD (**hpdocdod)[];
|
||
extern int vcchFetch;
|
||
extern int vccpFetch;
|
||
extern CHAR *vpchFetch;
|
||
extern typeCP vcpLimParaCache;
|
||
extern int vfCursorVisible;
|
||
extern HCURSOR vhcArrow;
|
||
extern struct FLI vfli;
|
||
|
||
int docHelp=docNil; /* this can be taken out if no online help */
|
||
|
||
#ifndef ONLINEHELP
|
||
#if 0
|
||
BOOL far PASCAL DialogHelp( hDlg, code, wParam, lParam )
|
||
HWND hDlg;
|
||
unsigned code;
|
||
WORD wParam;
|
||
LONG lParam;
|
||
{
|
||
switch(code)
|
||
{
|
||
case WM_INITDIALOG:
|
||
EnableOtherModeless(FALSE);
|
||
return(TRUE);
|
||
|
||
#if WINVER >= 0x300
|
||
case WM_PAINT:
|
||
if (vfli.rgdxp[1] == 0xFFFD)
|
||
FnSpecial(hDlg);
|
||
break;
|
||
#endif
|
||
|
||
case WM_COMMAND:
|
||
if ((wParam == idiOk) || (wParam == idiCancel))
|
||
{
|
||
OurEndDialog(hDlg, TRUE);
|
||
#if WINVER >= 0x300
|
||
if (vfli.rgdxp[1] == 0xFFFD)
|
||
vfli.rgdxp[1] = NULL;
|
||
#endif
|
||
return(TRUE);
|
||
}
|
||
break;
|
||
|
||
case WM_ACTIVATE:
|
||
if (wParam)
|
||
vhWndMsgBoxParent = hDlg;
|
||
if (vfCursorVisible)
|
||
ShowCursor(wParam);
|
||
break;
|
||
|
||
case WM_SETVISIBLE:
|
||
if (wParam)
|
||
EndLongOp(vhcArrow);
|
||
}
|
||
return(FALSE);
|
||
}
|
||
|
||
FnSpecial(hDlg)
|
||
{
|
||
#define randTo(x) (rand() / (32767/x))
|
||
|
||
HDC hDC = NULL;
|
||
HDC hMDC = NULL;
|
||
HFONT hFont, hFontPrev;
|
||
int c, cmode;
|
||
int x, y, x2, y2, s;
|
||
HPEN hPen, hPenPrev;
|
||
PAINTSTRUCT ps;
|
||
RECT rc;
|
||
BITMAPINFO DIBInfo;
|
||
|
||
srand((int) GetMessageTime());
|
||
cmode = randTo(3);
|
||
GetClientRect(hDlg, &rc);
|
||
if ((hDC = BeginPaint(hDlg, &ps)) == NULL)
|
||
goto LDone;
|
||
if ((hMDC = CreateCompatibleDC(hDC)) == NULL)
|
||
goto LDone;
|
||
|
||
for (c = 1; c < 100; c++)
|
||
{
|
||
int r, g, b, x, y;
|
||
x = randTo(rc.right)+50;
|
||
y = randTo(rc.bottom)+50;
|
||
switch(cmode)
|
||
{
|
||
case 0:
|
||
r = randTo(255);
|
||
g = randTo(100)+100;
|
||
b = 0;
|
||
break;
|
||
case 1:
|
||
g = randTo(255);
|
||
b = randTo(100)+100;
|
||
r = 0;
|
||
break;
|
||
default:
|
||
b = randTo(255);
|
||
r = randTo(100)+100;
|
||
g = 0;
|
||
break;
|
||
}
|
||
|
||
s = 3 + 4*randTo(10);
|
||
if ((hPen = CreatePen(PS_SOLID, s, RGB(r,g,b))) == NULL)
|
||
hPen = GetStockObject(BLACK_PEN);
|
||
hPenPrev = SelectObject(hDC, hPen);
|
||
Ellipse(hDC, x-50, y-50, x-50+s, y-50+s);
|
||
SelectObject(hDC, hPenPrev);
|
||
DeleteObject(hPen);
|
||
}
|
||
SetTextColor(hDC, RGB(255,255,255));
|
||
switch (cmode)
|
||
{
|
||
case 0:
|
||
SetBkColor(hDC, RGB(255,0,0));
|
||
break;
|
||
case 1:
|
||
SetBkColor(hDC, RGB(0,255,0));
|
||
break;
|
||
default:
|
||
SetBkColor(hDC, RGB(0,0,255));
|
||
break;
|
||
}
|
||
hFont = GetStockObject(ANSI_VAR_FONT);
|
||
hFontPrev = SelectObject(hDC, hFont);
|
||
if (vfli.rgch[2] == 0x30)
|
||
for (c = vfli.rgch[1]-1; c >= 0; c--)
|
||
vfli.rgch[c+2] -= 0x10;
|
||
TextOut(hDC, 6, rc.bottom-15, &vfli.rgch[2], vfli.rgch[1]);
|
||
SelectObject(hDC, hFontPrev);
|
||
|
||
DeleteDC(hMDC);
|
||
LDone:
|
||
EndPaint(hDlg, &ps);
|
||
}
|
||
#endif
|
||
|
||
#else /* ONLINE HELP */
|
||
|
||
#define cchMaxTopicName 80
|
||
|
||
#ifndef DEBUG
|
||
#define STATIC static
|
||
#else
|
||
#define STATIC
|
||
#endif
|
||
|
||
STATIC int fnHelpFile;
|
||
STATIC int iTopicChoice=-1;
|
||
STATIC int cTopic;
|
||
STATIC struct PGTB **hpgtbHelp=0;
|
||
STATIC HWND hwndHelpDoc;
|
||
|
||
|
||
NEAR CleanUpHelpPopUp( void );
|
||
NEAR CloseHelpDoc( void );
|
||
NEAR FOpenHelpDoc( void );
|
||
NEAR MoveHelpCtl( HWND, int, int, int, int, int );
|
||
|
||
fnHelp()
|
||
{
|
||
extern HANDLE hMmwModInstance;
|
||
extern HWND hParentWw;
|
||
extern FARPROC lpDialogHelp;
|
||
extern FARPROC lpDialogHelpInner;
|
||
int idi;
|
||
|
||
Assert( hpgtbHelp == 0 );
|
||
|
||
/* Loop until the user exits the "Help on this topic/Return to Topics" loop */
|
||
|
||
ClearInsertLine(); /* Because we use MdocSize, which sets vfInsertOn */
|
||
|
||
if (!FOpenHelpDoc())
|
||
{
|
||
CloseHelpDoc();
|
||
Error( IDPMTNoHelpFile );
|
||
return;
|
||
}
|
||
while (TRUE)
|
||
{
|
||
|
||
idi = DialogBox( hMmwModInstance, MAKEINTRESOURCE(dlgHelp), hParentWw,
|
||
lpDialogHelp );
|
||
if (idi == -1)
|
||
{
|
||
Error(IDPMTNoMemory);
|
||
return;
|
||
}
|
||
|
||
if ((idi == idiOk) && (iTopicChoice >= 0))
|
||
{ /* Help file was read OK & user chose a topic */
|
||
Assert( hpgtbHelp != 0);
|
||
if ( iTopicChoice + 1 < (**hpgtbHelp).cpgd )
|
||
{
|
||
idi = DialogBox( hMmwModInstance, MAKEINTRESOURCE(dlgHelpInner),
|
||
hParentWw, lpDialogHelpInner );
|
||
if (idi == -1)
|
||
{
|
||
Error(IDPMTNoMemory);
|
||
break;
|
||
}
|
||
if ( idi != idiHelpTopics )
|
||
break;
|
||
|
||
}
|
||
/* Not Enough Topics supplied in the help file */
|
||
else
|
||
{
|
||
Error( IDPMTNoHelpFile );
|
||
CloseHelpDoc();
|
||
break;
|
||
}
|
||
}
|
||
else
|
||
break;
|
||
}
|
||
iTopicChoice = -1;
|
||
DrawInsertLine();
|
||
CloseHelpDoc();
|
||
}
|
||
|
||
|
||
|
||
|
||
FInzHelpPopUp( hDlg )
|
||
HWND hDlg;
|
||
{ /* Build the Help popup Window */
|
||
extern CHAR szHelpDocClass[];
|
||
extern HANDLE hMmwModInstance;
|
||
extern int dxpScrlBar;
|
||
|
||
typedef struct { int yp, dyp; } VD; /* Vertical Dimension */
|
||
typedef struct { int xp, dxp; } HD; /* Horizontal Dimension */
|
||
|
||
HD hdUsable;
|
||
HD hdPopUp;
|
||
VD vdPopUp, vdTopic, vdHelpDoc, vdButton;
|
||
|
||
HDC hdcPopUp=NULL;
|
||
|
||
#define RectToHdVd( rc, hd, vd ) (hd.dxp=(rc.right - (hd.xp=rc.left)), \
|
||
vd.dyp=(rc.bottom - (vd.yp=rc.top)))
|
||
RECT rcPopUp;
|
||
RECT rcHelpDoc;
|
||
extern int dypMax; /* Screen Size */
|
||
int dxpMax=GetDeviceCaps( wwdCurrentDoc.hDC, HORZRES );
|
||
TEXTMETRIC tm;
|
||
unsigned dypChar;
|
||
unsigned xpButton;
|
||
unsigned dxpButton;
|
||
register struct WWD *pwwdHelp;
|
||
|
||
#define cButton 4 /* # of buttons across the bottom of the Dialog */
|
||
int rgidiButton[ cButton ];
|
||
int iidiButton;
|
||
|
||
rgidiButton [0] = idiHelpTopics;
|
||
rgidiButton [1] = idiHelpNext;
|
||
rgidiButton [2] = idiHelpPrev;
|
||
rgidiButton [3] = idiCancel;
|
||
|
||
#define dxpMargin (dxpMax/100)
|
||
#define dypMargin (dypMax/100)
|
||
|
||
Assert( docHelp != docNil );
|
||
|
||
/* Make a wwd entry for the Help document & initialize it */
|
||
if ((wwHelp=WwAlloc( (HWND)NULL, docHelp )) == wwNil)
|
||
goto ErrRet;
|
||
pwwdHelp = &rgwwd[ wwHelp ];
|
||
|
||
SetHelpTopic( hDlg, iTopicChoice );
|
||
|
||
/* Dialog box is centered and
|
||
2/3 of the size of the screen, plus the scroll bar width
|
||
This sizing method permits us to guarantee that the help document
|
||
display area width is at least some fixed percentage of the width
|
||
of the screen (currently 64.66 %) */
|
||
hdPopUp.dxp = ((dxpMax * 2) / 3) + dxpScrlBar;
|
||
hdPopUp.xp = (dxpMax - hdPopUp.dxp) / 2;
|
||
vdPopUp.dyp = dypMax - ((vdPopUp.yp = dypMax / 6) * 2);
|
||
MoveWindow( hDlg, hdPopUp.xp, vdPopUp.yp, hdPopUp.dxp, vdPopUp.dyp, TRUE );
|
||
|
||
/* Get Standard text height so we know how much space to allow
|
||
for Topic Name */
|
||
if ( ((hdcPopUp=GetDC( hDlg ))==NULL) ||
|
||
(SelectObject( hdcPopUp, GetStockObject( ANSI_FIXED_FONT ) )==0))
|
||
goto ErrRet;
|
||
GetTextMetrics( hdcPopUp, (LPTEXTMETRIC)&tm );
|
||
ReleaseDC( hDlg, hdcPopUp );
|
||
hdcPopUp = NULL;
|
||
dypChar = tm.tmHeight + tm.tmExternalLeading;
|
||
|
||
/* Obtain heights of button area, help doc display, and Topic Area by
|
||
splitting up Dialog Box client rect */
|
||
GetClientRect( hDlg, &rcPopUp );
|
||
RectToHdVd( rcPopUp, hdPopUp, vdPopUp );
|
||
vdButton.dyp = vdPopUp.dyp / 7;
|
||
vdButton.yp = vdPopUp.yp + vdPopUp.dyp - vdButton.dyp;
|
||
vdTopic.yp = vdPopUp.yp + dypMargin;
|
||
vdTopic.dyp = dypMargin + dypChar;
|
||
vdHelpDoc.yp = vdTopic.yp + vdTopic.dyp;
|
||
vdHelpDoc.dyp = vdButton.yp - vdHelpDoc.yp;
|
||
Assert( vdHelpDoc.dyp > dypChar + 2 );
|
||
|
||
/* Obtain usable horiz area within dialog box */
|
||
hdUsable.xp = hdPopUp.xp + dxpMargin;
|
||
hdUsable.dxp = hdPopUp.dxp - (2 * dxpMargin);
|
||
|
||
/* Create the Help Doc Window */
|
||
if ((hwndHelpDoc =
|
||
CreateWindow( (LPSTR)szHelpDocClass, (LPSTR) "",
|
||
WS_CHILD | WS_BORDER,
|
||
hdUsable.xp, vdHelpDoc.yp,
|
||
hdUsable.dxp - dxpScrlBar, vdHelpDoc.dyp,
|
||
hDlg, /* PARENT */
|
||
NULL, /* Help Document Window ID */
|
||
hMmwModInstance,
|
||
(LONG) 0)) == NULL)
|
||
/* Error Creating Help Document Window */
|
||
goto ErrRet;
|
||
pwwdHelp->wwptr = pwwdHelp->hHScrBar = hwndHelpDoc;
|
||
|
||
/* OK to GetDc and hang onto it since Help doc window class has ownDC */
|
||
if ((pwwdHelp->hDC = GetDC( hwndHelpDoc ))==NULL)
|
||
goto ErrRet;
|
||
|
||
/* Set up scroll bar control window */
|
||
SetScrollRange( pwwdHelp->hVScrBar = GetDlgItem( hDlg, idiHelpScroll ),
|
||
pwwdHelp->sbVbar = SB_CTL,
|
||
0, drMax-1, FALSE );
|
||
SetScrollPos( pwwdHelp->hVScrBar, SB_CTL, 0, FALSE );
|
||
MoveHelpCtl( hDlg, idiHelpScroll,
|
||
hdUsable.xp + hdUsable.dxp - dxpScrlBar, vdHelpDoc.yp,
|
||
dxpScrlBar, vdHelpDoc.dyp );
|
||
|
||
/* Move Button windows into place */
|
||
xpButton = hdUsable.xp;
|
||
dxpButton = (hdUsable.dxp - (dxpMargin*(cButton-1))) / cButton;
|
||
vdButton.yp += dypMargin;
|
||
vdButton.dyp -= (2 * dypMargin);
|
||
for ( iidiButton = 0; iidiButton < cButton; iidiButton++ )
|
||
{
|
||
MoveHelpCtl( hDlg, rgidiButton[ iidiButton ],
|
||
xpButton, vdButton.yp, dxpButton, vdButton.dyp );
|
||
xpButton += dxpButton + dxpMargin;
|
||
}
|
||
|
||
/* Move static text window into place */
|
||
MoveHelpCtl( hDlg, idiHelpName, hdUsable.xp, vdTopic.yp,
|
||
hdUsable.dxp, vdTopic.dyp );
|
||
|
||
/* The "real, final" size of the help doc window goes in rgwwd */
|
||
GetClientRect( hwndHelpDoc, (LPRECT) &rcHelpDoc );
|
||
pwwdHelp->xpMin = rcHelpDoc.left;
|
||
pwwdHelp->ypMin = rcHelpDoc.top;
|
||
pwwdHelp->xpMac = rcHelpDoc.right;
|
||
pwwdHelp->ypMac = rcHelpDoc.bottom;
|
||
|
||
/* Finally, we display the whole dialog box */
|
||
ShowWindow( hDlg, SHOW_OPENWINDOW );
|
||
ShowWindow( hwndHelpDoc, SHOW_OPENWINDOW );
|
||
return TRUE;
|
||
|
||
ErrRet:
|
||
if (hdcPopUp != NULL)
|
||
ReleaseDC( hDlg, hdcPopUp );
|
||
CleanUpHelpPopUp();
|
||
CloseHelpDoc();
|
||
|
||
return FALSE;
|
||
}
|
||
|
||
|
||
|
||
|
||
NEAR MoveHelpCtl( hDlg, id, left, top, right, bottom )
|
||
HWND hDlg;
|
||
int id;
|
||
int left, top, right, bottom;
|
||
{
|
||
MoveWindow( (HWND) GetDlgItem( hDlg, id ), left, top, right, bottom, TRUE );
|
||
}
|
||
|
||
|
||
|
||
|
||
SetHelpTopic( hDlg, iTopic )
|
||
HWND hDlg;
|
||
int iTopic;
|
||
{ /* Inz wwHelp entry in rgwwd for pending display of topic iTopic,
|
||
which means "printed page" iTopic, the way we handle help files.
|
||
We map iTopic==0 to "printed page 2", iTopic 1 to 3, etc.
|
||
This skips the first printed page, which is the list of topics.
|
||
Set the topic name of iTopic as the text for the idiHelpName
|
||
static text control in the hDlg dialog box */
|
||
|
||
extern typeCP cpMinCur, cpMacCur;
|
||
extern struct SEL selCur;
|
||
extern int wwCur;
|
||
|
||
int ipgd = iTopic + 1;
|
||
register struct WWD *pwwd=&rgwwd[ wwHelp ];
|
||
typeCP cpFirstTopic = (**hpgtbHelp).rgpgd [ ipgd ].cpMin;
|
||
typeCP cpLimTopic = (ipgd == (**hpgtbHelp).cpgd - 1) ?
|
||
CpMacText( docHelp ) :
|
||
(**hpgtbHelp).rgpgd [ ipgd + 1 ].cpMin;
|
||
typeCP cp;
|
||
int iTopicT;
|
||
typeCP cpLimParaCache;
|
||
RECT rc;
|
||
|
||
Assert( wwHelp != wwNil && docHelp != docNil );
|
||
|
||
cpLimTopic--; /* Ignore end-of-page char at the end of each page */
|
||
|
||
if (ipgd >= (**hpgtbHelp).cpgd)
|
||
{
|
||
Assert( FALSE );
|
||
|
||
pwwd->cpMin = pwwd->cpMac = cp0;
|
||
}
|
||
else
|
||
{
|
||
pwwd->cpMin = cpFirstTopic;
|
||
pwwd->cpMac = cpLimTopic;
|
||
}
|
||
pwwd->cpFirst = pwwd->cpMin;
|
||
/* So no selection shows */
|
||
pwwd->sel.cpFirst = pwwd->sel.cpLim = cpLimTopic + 1;
|
||
|
||
if (wwCur == wwHelp)
|
||
{
|
||
cpMinCur = pwwd->cpMin;
|
||
cpMacCur = pwwd->cpMac;
|
||
selCur = pwwd->sel;
|
||
}
|
||
|
||
TrashCache();
|
||
TrashWw( wwHelp );
|
||
GetClientRect( pwwd->wwptr, (LPRECT) &rc );
|
||
InvalidateRect( pwwd->wwptr, (LPRECT) &rc, TRUE );
|
||
|
||
/* Set Help Topic name into dialog box */
|
||
|
||
for ( iTopicT = 0, cp = (**hpgtbHelp).rgpgd [0].cpMin;
|
||
cp < (**hpgtbHelp).rgpgd [1].cpMin;
|
||
cp = cpLimParaCache, iTopicT++ )
|
||
{
|
||
int cch;
|
||
int cchTopicMac;
|
||
CHAR rgchTopic[ cchMaxTopicName ];
|
||
|
||
CachePara( docHelp, cp );
|
||
cpLimParaCache = vcpLimParaCache;
|
||
|
||
if (iTopicT == iTopic)
|
||
{ /* Found the topic we want */
|
||
cchTopicMac = imin( (int)(vcpLimParaCache - cp) - ccpEol,
|
||
cchMaxTopicName );
|
||
|
||
/* Build up a topic name string */
|
||
|
||
cch = 0;
|
||
while (cch < cchTopicMac)
|
||
{
|
||
int cchT;
|
||
|
||
FetchCp( docHelp, cp, 0, fcmChars );
|
||
cp += vccpFetch;
|
||
cchT = imin( vcchFetch, cchTopicMac - cch );
|
||
Assert( cchT > 0);
|
||
bltbyte( vpchFetch, rgchTopic + cch, cchT );
|
||
cch += cchT;
|
||
}
|
||
if ((cch == 0) || rgchTopic [0] == chSect)
|
||
/* End of Topics */
|
||
break;
|
||
|
||
rgchTopic[ cch ] = '\0';
|
||
|
||
SetDlgItemText( hDlg, idiHelpName, (LPSTR) rgchTopic );
|
||
return;
|
||
} /* end if */
|
||
} /* end for */
|
||
/* Not enough topic names */
|
||
Assert( FALSE );
|
||
}
|
||
|
||
|
||
|
||
|
||
NEAR CleanUpHelpPopUp()
|
||
{
|
||
extern int wwCur;
|
||
|
||
if (wwCur != wwDocument)
|
||
NewCurWw( wwDocument, TRUE );
|
||
|
||
if (wwHelp != wwNil)
|
||
FreeWw( wwHelp );
|
||
}
|
||
|
||
|
||
|
||
|
||
NEAR CloseHelpDoc()
|
||
{
|
||
if (docHelp != docNil)
|
||
KillDoc( docHelp );
|
||
|
||
if (hpgtbHelp != 0)
|
||
{
|
||
FreeH( hpgtbHelp );
|
||
hpgtbHelp = 0;
|
||
}
|
||
|
||
if (fnHelpFile != fnNil)
|
||
FreeFn( fnHelpFile );
|
||
docHelp = docNil;
|
||
fnHelpFile = fnNil;
|
||
}
|
||
|
||
|
||
NEAR FOpenHelpDoc()
|
||
{
|
||
CHAR szHelpFile[ cchMaxFile ];
|
||
CHAR (**hszHelpFile)[];
|
||
|
||
/* This call to fnOpenSz is the one time that we don't normalize
|
||
a filename before calling FnOpenSz. The reason for this is
|
||
that OpenFile (called in RfnAccess) will only search the path
|
||
if the filename passed to it has no path. We also get a side
|
||
benefit: if the sneaky user has WRITE.HLP open as a document,
|
||
it will get a different fn from FnOpenSz because the strings
|
||
will not match. */
|
||
|
||
return ( PchFillPchId( szHelpFile, IDSTRHELPF ) &&
|
||
((fnHelpFile=FnOpenSz( szHelpFile, dtyHlp, TRUE ))!=fnNil) &&
|
||
!FNoHeap(hszHelpFile=HszCreate( szHelpFile )) &&
|
||
((docHelp=DocCreate( fnHelpFile, hszHelpFile, dtyHlp )) != docNil) &&
|
||
(**hpdocdod)[ docHelp ].fFormatted);
|
||
}
|
||
|
||
/* Window Proc for Help document child window */
|
||
|
||
long FAR PASCAL HelpDocWndProc( hwnd, message, wParam, lParam )
|
||
HWND hwnd;
|
||
unsigned message;
|
||
WORD wParam;
|
||
LONG lParam;
|
||
{
|
||
extern struct WWD *pwwdCur;
|
||
extern int wwCur;
|
||
|
||
PAINTSTRUCT ps;
|
||
|
||
switch (message)
|
||
{
|
||
case WM_SIZE:
|
||
/* Window's size is changing. lParam contains the width
|
||
** and height, in the low and high words, respectively.
|
||
** wParam contains SIZENORMAL for "normal" size changes,
|
||
** SIZEICONIC when the window is being made iconic, and
|
||
** SIZEFULLSCREEN when the window is being made full screen. */
|
||
Assert( wParam == SIZENORMAL || wParam == SIZEFULLSCREEN );
|
||
if (lParam)
|
||
{ /* Not a NULL size request */
|
||
rgwwd[ wwHelp ].xpMac = LOWORD( lParam );
|
||
rgwwd[ wwHelp ].ypMac = HIWORD( lParam );
|
||
}
|
||
break;
|
||
|
||
case WM_PAINT:
|
||
/* Time for the window to draw itself. */
|
||
{
|
||
RECT rcSave;
|
||
|
||
/* To allow UpdateWw to refresh ALL parts of the screen it */
|
||
/* deems necessary, not just what Windows is telling us to */
|
||
/* paint, we invoke it AFTER the call to EndPaint so that */
|
||
/* the Vis region is not restricted. The only reason we call */
|
||
/* BeginPaint/EndPaint is to get the repaint rectangle */
|
||
BeginPaint(hwnd, (LPPAINTSTRUCT)&ps);
|
||
bltbyte( &ps.rcPaint, &rcSave, sizeof( RECT ) );
|
||
EndPaint(hwnd, (LPPAINTSTRUCT)&ps);
|
||
NewCurWw( wwHelp, TRUE );
|
||
InvalBand( pwwdCur, rcSave.top, rcSave.bottom );
|
||
UpdateWw( wwCur, FALSE );
|
||
NewCurWw( wwDocument, TRUE );
|
||
break;
|
||
}
|
||
|
||
default:
|
||
|
||
/* Everything else comes here. This call MUST exist
|
||
** in your window proc. */
|
||
|
||
return(DefWindowProc(hwnd, message, wParam, lParam));
|
||
break;
|
||
}
|
||
|
||
/* A window proc should always return something */
|
||
return(0L);
|
||
}
|
||
|
||
|
||
/* Dialog Box function for Inner Help box (shows the topic text) */
|
||
|
||
BOOL far PASCAL DialogHelpInner( hDlg, code, wParam, lParam )
|
||
HWND hDlg;
|
||
unsigned code;
|
||
WORD wParam;
|
||
LONG lParam;
|
||
{
|
||
extern int wwCur;
|
||
|
||
switch (code)
|
||
{
|
||
case WM_VSCROLL: /* Scroll in help document */
|
||
NewCurWw( wwHelp, TRUE );
|
||
MmwVertScroll( hwndHelpDoc, wParam, (int) lParam );
|
||
UpdateWw( wwCur, FALSE );
|
||
NewCurWw( wwDocument, TRUE );
|
||
break;
|
||
|
||
case WM_CLOSE:
|
||
goto Cancel;
|
||
case WM_INITDIALOG:
|
||
if (!FInzHelpPopUp( hDlg ))
|
||
{
|
||
goto Cancel;
|
||
}
|
||
EnableOtherModeless(FALSE);
|
||
break;
|
||
|
||
case WM_COMMAND:
|
||
switch (wParam)
|
||
{
|
||
default:
|
||
break;
|
||
case idiHelpNext:
|
||
if (++iTopicChoice >= cTopic)
|
||
{
|
||
iTopicChoice--;
|
||
beep();
|
||
}
|
||
else
|
||
SetHelpTopic( hDlg, iTopicChoice );
|
||
|
||
break;
|
||
case idiHelpPrev:
|
||
if (iTopicChoice == 0)
|
||
beep();
|
||
else
|
||
SetHelpTopic( hDlg, --iTopicChoice );
|
||
break;
|
||
|
||
case idiOk:
|
||
wParam = idiHelpTopics;
|
||
case idiHelpTopics:
|
||
CleanUpHelpPopUp();
|
||
goto Endit;
|
||
|
||
case idiCancel:
|
||
Cancel:
|
||
CleanUpHelpPopUp();
|
||
CloseHelpDoc();
|
||
Endit:
|
||
EndDialog(hDlg, wParam);
|
||
EnableOtherModeless(TRUE);
|
||
break;
|
||
}
|
||
break;
|
||
|
||
default:
|
||
return(FALSE);
|
||
}
|
||
return(TRUE);
|
||
}
|
||
|
||
|
||
|
||
|
||
BOOL far PASCAL DialogHelp( hDlg, code, wParam, lParam )
|
||
HWND hDlg;
|
||
unsigned code;
|
||
WORD wParam;
|
||
LONG lParam;
|
||
{
|
||
HWND hwndListBox;
|
||
|
||
switch (code)
|
||
{
|
||
case WM_INITDIALOG:
|
||
if (!FSetHelpList( hwndListBox=GetDlgItem( hDlg, idiHelp ) ))
|
||
{
|
||
Error( IDPMTNoHelpFile );
|
||
CloseHelpDoc();
|
||
goto EndIt;
|
||
}
|
||
|
||
/* Come up with the first string in the list box selected */
|
||
SendMessage( hwndListBox, LB_SETCURSEL, (WORD) 0, (LONG) 0);
|
||
|
||
{ /* Compute % of free memory, set that into dialog box */
|
||
extern cwHeapFree, cbTotQuotient, cbTot;
|
||
extern int vfOutOfMemory;
|
||
int pctHeapFree=0;
|
||
CHAR rgchPct[ 4 ];
|
||
int cchPct;
|
||
CHAR *pchT=&rgchPct[ 0 ];
|
||
|
||
if (!vfOutOfMemory)
|
||
{
|
||
pctHeapFree = cwHeapFree / cbTotQuotient;
|
||
if (pctHeapFree > 99)
|
||
pctHeapFree = (cwHeapFree*sizeof(int) == cbTot) ? 100 : 99;
|
||
}
|
||
cchPct = ncvtu( pctHeapFree, &pchT );
|
||
Assert( cchPct < 4);
|
||
rgchPct[ cchPct ] = '\0';
|
||
SetDlgItemText( hDlg, idiMemFree, (LPSTR) rgchPct );
|
||
}
|
||
|
||
EnableOtherModeless(FALSE);
|
||
break;
|
||
|
||
case WM_COMMAND:
|
||
switch (wParam)
|
||
{
|
||
case idiHelp:
|
||
/* This is received as part of the LBS_NOTIFY style */
|
||
/* whenever the user mouses up over a string */
|
||
/* LOWORD( lParam ) is the window handle of the list box */
|
||
/* HIWORD( lParam ) is 1 for single click, 2 for doubleclick */
|
||
|
||
switch( HIWORD( lParam ) ) {
|
||
default:
|
||
break;
|
||
case 1: /* SINGLE CLICK */
|
||
EnableWindow( GetDlgItem( hDlg, idiOk ),
|
||
SendMessage( (HWND)GetDlgItem( hDlg,
|
||
idiHelp ),
|
||
LB_GETCURSEL,
|
||
0,
|
||
(LONG) 0 ) >= 0 );
|
||
break;
|
||
case 2: /* DOUBLE CLICK */
|
||
wParam = idiOk;
|
||
goto Okay;
|
||
}
|
||
break;
|
||
|
||
case idiOk:
|
||
Okay:
|
||
iTopicChoice = SendMessage( (HWND)GetDlgItem( hDlg, idiHelp ),
|
||
LB_GETCURSEL, 0, (LONG) 0 );
|
||
goto EndIt;
|
||
|
||
case idiCancel:
|
||
/* Cancelled, get rid of Help Document info */
|
||
CloseHelpDoc();
|
||
EndIt:
|
||
EndDialog(hDlg, wParam);
|
||
EnableOtherModeless(TRUE);
|
||
break;
|
||
}
|
||
break;
|
||
|
||
default:
|
||
return(FALSE);
|
||
}
|
||
return(TRUE);
|
||
} /* end of DialogHelp */
|
||
|
||
|
||
|
||
FSetHelpList( hWndListBox )
|
||
HWND hWndListBox;
|
||
{ /* Open the MEMO Help File as a MEMO Document. Set docHelp, fnHelpFile.
|
||
Read the strings for the list box as the contents of the first
|
||
"printed" page (i.e. use the page table) and send them to the
|
||
list box with the passed window handle */
|
||
|
||
CHAR szTopicBuf[ cchMaxTopicName ];
|
||
typeCP cp;
|
||
typeCP cpLimParaCache;
|
||
int cch;
|
||
struct PGTB **hpgtbT;
|
||
|
||
Assert( docHelp != docNil );
|
||
|
||
cTopic = 0;
|
||
|
||
if ((hpgtbT=(**hpdocdod)[ docHelp ].hpgtb) != 0)
|
||
{
|
||
hpgtbHelp = hpgtbT;
|
||
(**hpdocdod)[ docHelp ].hpgtb = 0;
|
||
}
|
||
|
||
Assert( (hpgtbHelp != 0) && ((**hpgtbHelp).cpgd > 1) );
|
||
|
||
/* List of topics starts on the first page, 1 para per topic */
|
||
/* For each topic (paragraph), build a string and send it to the list box */
|
||
|
||
for ( cp = (**hpgtbHelp).rgpgd [0].cpMin;
|
||
cp < (**hpgtbHelp).rgpgd [1].cpMin;
|
||
cp = cpLimParaCache )
|
||
{
|
||
int cchTopicMac;
|
||
|
||
CachePara( docHelp, cp );
|
||
cpLimParaCache = vcpLimParaCache;
|
||
|
||
cchTopicMac = imin( (int)(vcpLimParaCache - cp) - ccpEol,
|
||
cchMaxTopicName );
|
||
|
||
/* Build up a topic name string */
|
||
cch = 0;
|
||
while (cch < cchTopicMac)
|
||
{
|
||
int cchT;
|
||
|
||
FetchCp( docHelp, cp, 0, fcmChars );
|
||
cp += vccpFetch;
|
||
cchT = imin( vcchFetch, cchTopicMac - cch );
|
||
Assert( cchT > 0);
|
||
bltbyte( vpchFetch, szTopicBuf + cch, cchT );
|
||
cch += cchT;
|
||
}
|
||
if ((cch == 0) || szTopicBuf [0] == chSect)
|
||
/* End of Topics */
|
||
break;
|
||
|
||
szTopicBuf[ cch ] = '\0';
|
||
SendMessage( hWndListBox, LB_INSERTSTRING, -1, (LONG)(LPSTR)szTopicBuf);
|
||
cTopic++;
|
||
} /* end for */
|
||
|
||
return (cTopic > 0);
|
||
}
|
||
#endif /* ONLINEHELP */
|
||
|
||
|