/*** mhlook - Help Look-Up code. * * Copyright 1988, Microsoft Corporation * * This module contains routines dealing with searching for and (hopefully) * finding help information * * Revision History (most recent first): * * 30-Mar-1989 ln pass popup flag around correctly. * [] 12-Mar-1989 LN Split off of mhdisp.c * *************************************************************************/ #include /* string functions */ #include "mh.h" /* help extension include file */ /*** fHelpCmd - Display topic text or execute command. * * Input: * szCur = context string * fStay = TRUE => keep focus in current window, else move focus to * newly opened help window. * fWantPopUp = TRUE => display as popup window. (Ignored in non-CW) * * Exit: * returns TRUE on success. * *************************************************************************/ flagType pascal near fHelpCmd ( char *szCur, flagType fStay, flagType fWantPopUp ) { int i; /* index while checking for helpfiles*/ nc ncCur = {0,0}; /* nc found */ // // If a command to display a context (!C), just remove the command // if (*(ushort UNALIGNED *)szCur == 0x4321) { szCur += 2; } // // If the command starts with an exclamation point, then go execute it. // if (*szCur == '!') { return fContextCommand (szCur+1); } stat(szCur); debmsg ("Searching:"); // // search algorithm: // 1) if help is not up, or we're looking for a different string than the // last string we found, or it's a local context, try the same help file // as the last look-up, if there was a last lookup. // 2) If that fails, and it's not a local context, and we're not to present // a list, then look in the help file(s) that are associated with the // current file extension. // 3) If that fails, and it's not a local context, then search all the help // files. // 4) If THAT fails, then check to see if there are any help files open // at all, and return an appropriate error message on that. // if (ncInitLast.mh && ncInitLast.cn && (strcmp (szCur, szLastFound) || !(*szCur))) { ncCur = ncSearch (szCur, NULL, ncInitLast, FALSE, FALSE); } if (!ncCur.mh && !ncCur.cn && *szCur && fnExtCur && !fList) { nc ncTmp = {0,0}; ncCur = ncSearch (szCur, fnExtCur, ncTmp, FALSE, FALSE); } if (!ncCur.mh && !ncCur.cn && *szCur) { nc ncTmp = {0,0}; ncCur = ncSearch (szCur, NULL, ncTmp, FALSE, fList); } if (!ncCur.mh && !ncCur.cn) { for (i=MAXFILES-1; i; i--) { if ((files[i].ncInit.mh || files[i].ncInit.cn)) { return errstat ("Help on topic not found:",szCur); } } return errstat ("No Open Help Files", NULL); } // // Save this as the last context string actually found // xrefCopy (szLastFound, szCur); debend (TRUE); return fDisplayNc ( ncCur /* nc to display */ , TRUE /* add to backtrace list */ , fStay /* keep focus in current win? */ , fWantPopUp); /* as a pop-up? */ } /*** fContextCommand - execute context command * * Input: * szCur = pointer to context command * * Output: * Returns TRUE if it was executed * *************************************************************************/ flagType pascal near fContextCommand ( char *szCur ) { switch (*szCur++) { case ' ': /* exeute DOS command */ case '!': /* exeute DOS command */ strcpy(buf,"arg \""); strcat(buf,szCur); strcat(buf,"\" shell"); fExecute(buf); /* execute as shell cmd */ break; case 'm': /* execute editor macro */ fExecute(szCur); break; default: return FALSE; } Display (); return TRUE; /* end fContextCommand */} /** ncSearch - find help on context string * * search all the currently active help files for help on a particular * topic. If desired, restricts the search to those files which are * associated with a particular extension. * * Entry: * pText = text to get help on * pExt = If non-null, the extension to restrict the search to. * ncInit = if non-null, ncInit of the only help file to look in * fAgain = If non-null, skip helpfiles until ncInit found, then * pick up the search. * fList = if true, present a list box of the posibilities. * * Exit: * returns nc found, or NULL * *************************************************************************/ nc pascal near ncSearch ( uchar far *pText, uchar far *pExt, nc ncInit, flagType fAgain, flagType fList ) { int iHelp; /* index into helpfile table */ int j; nc ncRet = {0,0}; /* nc found */ UNREFERENCED_PARAMETER( fList ); debmsg (" ["); debmsg (pText); debmsg ("]:"); /* * If this is just a single search (ncInit specified, and not a search * "again"), then JUST look in the single file. */ if ((ncInit.mh || ncInit.cn) && !fAgain) ncRet = HelpNc(pText,ncInit); /* * If fList is specified, then search ALL the databases for ALL ocurrances * of the string, and make a list of the nc's we find. */ #if defined(PWB) else if (fList) { iHelp = ifileCur; cList = 0; do { if (files[iHelp].ncInit) { ncRet = files[iHelp].ncInit; while ( (cList < CLISTMAX) && (rgncList[cList] = HelpNc(pText,ncRet))) { ncRet = rgncList[cList++]; ncRet.cn++; } } iHelp += iHelp ? -1 : MAXFILES-1; } while ((iHelp != ifileCur) && (cList < CLISTMAX)); if (cList == 0) { ncRet.mh = ncRet.cn = 0; return ncRet; } if (cList == 1) return rgncList[0]; return ncChoose(pText); } #endif else { iHelp = ifileCur; /* start with current file */ do { if ((files[iHelp].ncInit.mh) && (files[iHelp].ncInit.cn)) { /* if helpfile open */ if (pExt) { /* if an extension was specified*/ for (j=0; j