396 lines
10 KiB
C
396 lines
10 KiB
C
/*++
|
|
|
|
Copyright (c) 1993 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
sphelp.c
|
|
|
|
Abstract:
|
|
|
|
Routines for displaying on-line help during text setup.
|
|
|
|
Author:
|
|
|
|
Ted Miller (tedm) 2-Aug-1993
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
|
|
#include "spprecmp.h"
|
|
#pragma hdrstop
|
|
|
|
|
|
#define MAX_HELP_SCREENS 100
|
|
|
|
PWSTR HelpScreen[MAX_HELP_SCREENS+1];
|
|
|
|
|
|
VOID
|
|
SpHelp(
|
|
IN ULONG MessageId, OPTIONAL
|
|
IN PCWSTR FileText, OPTIONAL
|
|
IN ULONG Flags
|
|
)
|
|
{
|
|
UCHAR StatusAttribute, BackgroundAttribute, HeaderAttribute,
|
|
ClientAttribute, ClientIntenseAttribute;
|
|
PWSTR HelpText,p,q;
|
|
ULONG ScreenCount;
|
|
ULONG ValidKeys[8];
|
|
ULONG CurrentScreen;
|
|
ULONG y;
|
|
BOOLEAN Intense;
|
|
BOOLEAN Done;
|
|
unsigned kc;
|
|
|
|
//
|
|
// Pick the video attributes we want
|
|
//
|
|
if(Flags & SPHELP_LICENSETEXT) {
|
|
|
|
StatusAttribute = DEFAULT_STATUS_ATTRIBUTE;
|
|
BackgroundAttribute = DEFAULT_BACKGROUND;
|
|
HeaderAttribute = DEFAULT_ATTRIBUTE;
|
|
ClientAttribute = DEFAULT_ATTRIBUTE;
|
|
ClientIntenseAttribute = (ATT_FG_INTENSE | ATT_BG_INTENSE);
|
|
|
|
} else {
|
|
|
|
StatusAttribute = (ATT_FG_WHITE | ATT_BG_BLUE);
|
|
BackgroundAttribute = ATT_WHITE;
|
|
HeaderAttribute = (ATT_FG_BLUE | ATT_BG_WHITE);
|
|
ClientAttribute = (ATT_FG_BLACK | ATT_BG_WHITE);
|
|
ClientIntenseAttribute = (ATT_FG_BLUE | ATT_BG_WHITE);
|
|
}
|
|
|
|
//
|
|
// Retreive the help text.
|
|
//
|
|
if (FileText) {
|
|
HelpText = (PWSTR)FileText;
|
|
} else {
|
|
HelpText = SpRetreiveMessageText(NULL,MessageId,NULL,0);
|
|
if (!HelpText) { // no way to return an error code, so fail quietly
|
|
goto s0;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Shop off extra blank lines in the text.
|
|
//
|
|
p = HelpText + wcslen(HelpText);
|
|
while((p > HelpText) && SpIsSpace(*(p-1))) {
|
|
p--;
|
|
}
|
|
if(q = wcschr(p,L'\n')) {
|
|
*(++q) = 0;
|
|
}
|
|
|
|
//
|
|
// Break up the help text into screens.
|
|
// The maximum length of a help screen will be the client screen size
|
|
// minus two lines for spacing. A %P alone at the beginning of a line
|
|
// forces a page break.
|
|
//
|
|
for(p=HelpText,ScreenCount=0; *p; ) {
|
|
|
|
//
|
|
// Mark the start of a new screen.
|
|
//
|
|
HelpScreen[ScreenCount++] = p;
|
|
|
|
//
|
|
// Count lines in the help text.
|
|
//
|
|
for(y=0; *p; ) {
|
|
|
|
//
|
|
// Determine whether this line is really a hard page break
|
|
// or if we have exhausted the number of lines allowed on a screen.
|
|
//
|
|
if(((p[0] == L'%') && (p[1] == 'P')) || (++y == CLIENT_HEIGHT-2)) {
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Find next line start.
|
|
//
|
|
if(q = wcschr(p,L'\r')) {
|
|
p = q + 2;
|
|
} else {
|
|
p = wcschr(p,0);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Find the end of the line that broke us out of the loop
|
|
// and then the start of the next line (if any).
|
|
//
|
|
if(q = wcschr(p,L'\r')) {
|
|
p = q + 2;
|
|
} else {
|
|
p = wcschr(p,0);
|
|
}
|
|
|
|
if(ScreenCount == MAX_HELP_SCREENS) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Sentinal value: point to the terminating nul byte.
|
|
//
|
|
HelpScreen[ScreenCount] = p;
|
|
|
|
//
|
|
// Display header text in blue on white.
|
|
//
|
|
SpvidClearScreenRegion(0,0,VideoVars.ScreenWidth,HEADER_HEIGHT,BackgroundAttribute);
|
|
if(Flags & SPHELP_LICENSETEXT) {
|
|
SpDisplayHeaderText(SP_HEAD_LICENSE,HeaderAttribute);
|
|
} else {
|
|
SpDisplayHeaderText(SP_HEAD_HELP,HeaderAttribute);
|
|
}
|
|
|
|
//
|
|
// The first screen to display is screen 0.
|
|
//
|
|
CurrentScreen = 0;
|
|
|
|
Done = FALSE;
|
|
do {
|
|
|
|
SpvidClearScreenRegion(
|
|
0,
|
|
HEADER_HEIGHT,
|
|
VideoVars.ScreenWidth,
|
|
VideoVars.ScreenHeight-(HEADER_HEIGHT+STATUS_HEIGHT),
|
|
BackgroundAttribute
|
|
);
|
|
|
|
//
|
|
// Display the current screen.
|
|
//
|
|
for(y=HEADER_HEIGHT+1, p=HelpScreen[CurrentScreen]; *p && (p < HelpScreen[CurrentScreen+1]); y++) {
|
|
|
|
Intense = FALSE;
|
|
if(p[0] == L'%') {
|
|
if(p[1] == L'I') {
|
|
Intense = TRUE;
|
|
p += 2;
|
|
} else {
|
|
if(p[1] == L'P') {
|
|
p += 2; // don't display %P
|
|
}
|
|
}
|
|
}
|
|
|
|
q = wcschr(p,L'\r');
|
|
if(q) {
|
|
*q = 0;
|
|
}
|
|
|
|
SpvidDisplayString(
|
|
p,
|
|
(UCHAR)(Intense ? ClientIntenseAttribute : ClientAttribute),
|
|
3,
|
|
y
|
|
);
|
|
|
|
if(q) {
|
|
*q = '\r';
|
|
p = q + 2;
|
|
} else {
|
|
p = wcschr(p,0);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Construct a list of valid keypresses from the user, depending
|
|
// on whether this is the first, last, etc. screen.
|
|
//
|
|
// If there are previous screens, BACKSPACE=Read Last Help is an option.
|
|
// If there are additional screens, ENTER=Continue Reading Help is an option.
|
|
// ESC=Cancel Help is always an option for help text.
|
|
//
|
|
// For licensing text, we allow pageup/pagedown when appropriate,
|
|
// and on the last page we allow accept/reject.
|
|
//
|
|
kc = 0;
|
|
|
|
if(Flags & SPHELP_LICENSETEXT) {
|
|
|
|
ValidKeys[kc++] = KEY_F8;
|
|
ValidKeys[kc++] = ASCI_ESC;
|
|
|
|
if(CurrentScreen) {
|
|
ValidKeys[kc++] = KEY_PAGEUP;
|
|
}
|
|
if(CurrentScreen < ScreenCount-1) {
|
|
ValidKeys[kc++] = KEY_PAGEDOWN;
|
|
}
|
|
|
|
} else {
|
|
|
|
ValidKeys[kc++] = ASCI_ESC;
|
|
|
|
if(CurrentScreen) {
|
|
ValidKeys[kc++] = ASCI_BS;
|
|
ValidKeys[kc++] = KEY_PAGEUP;
|
|
}
|
|
if(CurrentScreen < ScreenCount-1) {
|
|
ValidKeys[kc++] = ASCI_CR;
|
|
ValidKeys[kc++] = KEY_PAGEDOWN;
|
|
}
|
|
}
|
|
|
|
ValidKeys[kc] = 0;
|
|
|
|
if(CurrentScreen && (CurrentScreen < ScreenCount-1)) {
|
|
//
|
|
// There are screens before and after this one.
|
|
//
|
|
if(Flags & SPHELP_LICENSETEXT) {
|
|
|
|
SpDisplayStatusOptions(
|
|
StatusAttribute,
|
|
SP_STAT_X_EQUALS_ACCEPT_LICENSE,
|
|
SP_STAT_X_EQUALS_REJECT_LICENSE,
|
|
SP_STAT_PAGEDOWN_EQUALS_NEXT_LIC,
|
|
SP_STAT_PAGEUP_EQUALS_PREV_LIC,
|
|
0
|
|
);
|
|
|
|
} else {
|
|
|
|
SpDisplayStatusOptions(
|
|
StatusAttribute,
|
|
SP_STAT_ENTER_EQUALS_CONTINUE_HELP,
|
|
SP_STAT_BACKSP_EQUALS_PREV_HELP,
|
|
SP_STAT_ESC_EQUALS_CANCEL_HELP,
|
|
0
|
|
);
|
|
}
|
|
} else {
|
|
if(CurrentScreen) {
|
|
//
|
|
// This is the last page but not the only page.
|
|
//
|
|
if(Flags & SPHELP_LICENSETEXT) {
|
|
|
|
SpDisplayStatusOptions(
|
|
StatusAttribute,
|
|
SP_STAT_X_EQUALS_ACCEPT_LICENSE,
|
|
SP_STAT_X_EQUALS_REJECT_LICENSE,
|
|
SP_STAT_PAGEUP_EQUALS_PREV_LIC,
|
|
0
|
|
);
|
|
|
|
} else {
|
|
|
|
SpDisplayStatusOptions(
|
|
StatusAttribute,
|
|
SP_STAT_BACKSP_EQUALS_PREV_HELP,
|
|
SP_STAT_ESC_EQUALS_CANCEL_HELP,
|
|
0
|
|
);
|
|
}
|
|
} else {
|
|
if(CurrentScreen < ScreenCount-1) {
|
|
//
|
|
// This is the first page but additional pages exist.
|
|
//
|
|
if(Flags & SPHELP_LICENSETEXT) {
|
|
|
|
SpDisplayStatusOptions(
|
|
StatusAttribute,
|
|
SP_STAT_X_EQUALS_ACCEPT_LICENSE,
|
|
SP_STAT_X_EQUALS_REJECT_LICENSE,
|
|
SP_STAT_PAGEDOWN_EQUALS_NEXT_LIC,
|
|
0
|
|
);
|
|
|
|
} else {
|
|
|
|
SpDisplayStatusOptions(
|
|
StatusAttribute,
|
|
SP_STAT_ENTER_EQUALS_CONTINUE_HELP,
|
|
SP_STAT_ESC_EQUALS_CANCEL_HELP,
|
|
0
|
|
);
|
|
}
|
|
} else {
|
|
//
|
|
// This is the only page.
|
|
//
|
|
if(Flags & SPHELP_LICENSETEXT) {
|
|
|
|
SpDisplayStatusOptions(
|
|
StatusAttribute,
|
|
SP_STAT_X_EQUALS_ACCEPT_LICENSE,
|
|
SP_STAT_X_EQUALS_REJECT_LICENSE,
|
|
0
|
|
);
|
|
|
|
} else {
|
|
|
|
SpDisplayStatusOptions(
|
|
StatusAttribute,
|
|
SP_STAT_ESC_EQUALS_CANCEL_HELP,
|
|
0
|
|
);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
switch(SpWaitValidKey(ValidKeys,NULL,NULL)) {
|
|
|
|
case ASCI_ESC:
|
|
|
|
if(Flags & SPHELP_LICENSETEXT) {
|
|
SpDone(0,FALSE,TRUE);
|
|
}
|
|
|
|
// ELSE FALL THROUGH
|
|
|
|
case KEY_F8:
|
|
|
|
Done = TRUE;
|
|
break;
|
|
|
|
case KEY_PAGEUP:
|
|
case ASCI_BS:
|
|
|
|
ASSERT(CurrentScreen);
|
|
CurrentScreen--;
|
|
break;
|
|
|
|
case KEY_PAGEDOWN:
|
|
case ASCI_CR:
|
|
|
|
ASSERT(CurrentScreen < ScreenCount-1);
|
|
CurrentScreen++;
|
|
break;
|
|
}
|
|
} while(!Done);
|
|
|
|
//
|
|
// Clean up.
|
|
//
|
|
if(!FileText) {
|
|
SpMemFree(HelpText);
|
|
}
|
|
|
|
s0:
|
|
CLEAR_ENTIRE_SCREEN();
|
|
|
|
SpDisplayHeaderText(
|
|
SpGetHeaderTextId(),
|
|
DEFAULT_ATTRIBUTE
|
|
);
|
|
}
|