Source code of Windows XP (NT5)
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.

255 lines
6.7 KiB

  1. /*** mhlook - Help Look-Up code.
  2. *
  3. * Copyright <C> 1988, Microsoft Corporation
  4. *
  5. * This module contains routines dealing with searching for and (hopefully)
  6. * finding help information
  7. *
  8. * Revision History (most recent first):
  9. *
  10. * 30-Mar-1989 ln pass popup flag around correctly.
  11. * [] 12-Mar-1989 LN Split off of mhdisp.c
  12. *
  13. *************************************************************************/
  14. #include <string.h> /* string functions */
  15. #include "mh.h" /* help extension include file */
  16. /*** fHelpCmd - Display topic text or execute command.
  17. *
  18. * Input:
  19. * szCur = context string
  20. * fStay = TRUE => keep focus in current window, else move focus to
  21. * newly opened help window.
  22. * fWantPopUp = TRUE => display as popup window. (Ignored in non-CW)
  23. *
  24. * Exit:
  25. * returns TRUE on success.
  26. *
  27. *************************************************************************/
  28. flagType pascal near fHelpCmd (
  29. char *szCur,
  30. flagType fStay,
  31. flagType fWantPopUp
  32. ) {
  33. int i; /* index while checking for helpfiles*/
  34. nc ncCur = {0,0}; /* nc found */
  35. //
  36. // If a command to display a context (!C), just remove the command
  37. //
  38. if (*(ushort UNALIGNED *)szCur == 0x4321) {
  39. szCur += 2;
  40. }
  41. //
  42. // If the command starts with an exclamation point, then go execute it.
  43. //
  44. if (*szCur == '!') {
  45. return fContextCommand (szCur+1);
  46. }
  47. stat(szCur);
  48. debmsg ("Searching:");
  49. //
  50. // search algorithm:
  51. // 1) if help is not up, or we're looking for a different string than the
  52. // last string we found, or it's a local context, try the same help file
  53. // as the last look-up, if there was a last lookup.
  54. // 2) If that fails, and it's not a local context, and we're not to present
  55. // a list, then look in the help file(s) that are associated with the
  56. // current file extension.
  57. // 3) If that fails, and it's not a local context, then search all the help
  58. // files.
  59. // 4) If THAT fails, then check to see if there are any help files open
  60. // at all, and return an appropriate error message on that.
  61. //
  62. if (ncInitLast.mh && ncInitLast.cn && (strcmp (szCur, szLastFound) || !(*szCur))) {
  63. ncCur = ncSearch (szCur, NULL, ncInitLast, FALSE, FALSE);
  64. }
  65. if (!ncCur.mh && !ncCur.cn && *szCur && fnExtCur && !fList) {
  66. nc ncTmp = {0,0};
  67. ncCur = ncSearch (szCur, fnExtCur, ncTmp, FALSE, FALSE);
  68. }
  69. if (!ncCur.mh && !ncCur.cn && *szCur) {
  70. nc ncTmp = {0,0};
  71. ncCur = ncSearch (szCur, NULL, ncTmp, FALSE, fList);
  72. }
  73. if (!ncCur.mh && !ncCur.cn) {
  74. for (i=MAXFILES-1; i; i--) {
  75. if ((files[i].ncInit.mh || files[i].ncInit.cn)) {
  76. return errstat ("Help on topic not found:",szCur);
  77. }
  78. }
  79. return errstat ("No Open Help Files", NULL);
  80. }
  81. //
  82. // Save this as the last context string actually found
  83. //
  84. xrefCopy (szLastFound, szCur);
  85. debend (TRUE);
  86. return fDisplayNc ( ncCur /* nc to display */
  87. , TRUE /* add to backtrace list */
  88. , fStay /* keep focus in current win? */
  89. , fWantPopUp); /* as a pop-up? */
  90. }
  91. /*** fContextCommand - execute context command
  92. *
  93. * Input:
  94. * szCur = pointer to context command
  95. *
  96. * Output:
  97. * Returns TRUE if it was executed
  98. *
  99. *************************************************************************/
  100. flagType pascal near fContextCommand (
  101. char *szCur
  102. ) {
  103. switch (*szCur++) {
  104. case ' ': /* exeute DOS command */
  105. case '!': /* exeute DOS command */
  106. strcpy(buf,"arg \"");
  107. strcat(buf,szCur);
  108. strcat(buf,"\" shell");
  109. fExecute(buf); /* execute as shell cmd */
  110. break;
  111. case 'm': /* execute editor macro */
  112. fExecute(szCur);
  113. break;
  114. default:
  115. return FALSE;
  116. }
  117. Display ();
  118. return TRUE;
  119. /* end fContextCommand */}
  120. /** ncSearch - find help on context string
  121. *
  122. * search all the currently active help files for help on a particular
  123. * topic. If desired, restricts the search to those files which are
  124. * associated with a particular extension.
  125. *
  126. * Entry:
  127. * pText = text to get help on
  128. * pExt = If non-null, the extension to restrict the search to.
  129. * ncInit = if non-null, ncInit of the only help file to look in
  130. * fAgain = If non-null, skip helpfiles until ncInit found, then
  131. * pick up the search.
  132. * fList = if true, present a list box of the posibilities.
  133. *
  134. * Exit:
  135. * returns nc found, or NULL
  136. *
  137. *************************************************************************/
  138. nc pascal near ncSearch (
  139. uchar far *pText,
  140. uchar far *pExt,
  141. nc ncInit,
  142. flagType fAgain,
  143. flagType fList
  144. ) {
  145. int iHelp; /* index into helpfile table */
  146. int j;
  147. nc ncRet = {0,0}; /* nc found */
  148. UNREFERENCED_PARAMETER( fList );
  149. debmsg (" [");
  150. debmsg (pText);
  151. debmsg ("]:");
  152. /*
  153. * If this is just a single search (ncInit specified, and not a search
  154. * "again"), then JUST look in the single file.
  155. */
  156. if ((ncInit.mh || ncInit.cn) && !fAgain)
  157. ncRet = HelpNc(pText,ncInit);
  158. /*
  159. * If fList is specified, then search ALL the databases for ALL ocurrances
  160. * of the string, and make a list of the nc's we find.
  161. */
  162. #if defined(PWB)
  163. else if (fList) {
  164. iHelp = ifileCur;
  165. cList = 0;
  166. do {
  167. if (files[iHelp].ncInit) {
  168. ncRet = files[iHelp].ncInit;
  169. while ( (cList < CLISTMAX)
  170. && (rgncList[cList] = HelpNc(pText,ncRet))) {
  171. ncRet = rgncList[cList++];
  172. ncRet.cn++;
  173. }
  174. }
  175. iHelp += iHelp ? -1 : MAXFILES-1;
  176. }
  177. while ((iHelp != ifileCur) && (cList < CLISTMAX));
  178. if (cList == 0) {
  179. ncRet.mh = ncRet.cn = 0;
  180. return ncRet;
  181. }
  182. if (cList == 1)
  183. return rgncList[0];
  184. return ncChoose(pText);
  185. }
  186. #endif
  187. else {
  188. iHelp = ifileCur; /* start with current file */
  189. do {
  190. if ((files[iHelp].ncInit.mh) &&
  191. (files[iHelp].ncInit.cn)) { /* if helpfile open */
  192. if (pExt) { /* if an extension was specified*/
  193. for (j=0; j<MAXEXT; j++) { /* for all listed defaults */
  194. if (fAgain) {
  195. if ((ncInit.mh == files[iHelp].ncInit.mh) &&
  196. (ncInit.cn == files[iHelp].ncInit.cn)) {
  197. fAgain = FALSE;
  198. }
  199. }
  200. else if (strcmp(files[iHelp].exts[j],pExt) == 0) {
  201. debmsg (":");
  202. ncRet = HelpNc(pText,files[iHelp].ncInit);
  203. break;
  204. }
  205. }
  206. }
  207. else { /* no extension specified */
  208. if (fAgain && ((ncInit.mh == files[iHelp].ncInit.mh) &&
  209. (ncInit.cn == files[iHelp].ncInit.cn)))
  210. fAgain = FALSE;
  211. else {
  212. ncRet = HelpNc(pText,files[iHelp].ncInit);
  213. debmsg (":");
  214. }
  215. }
  216. }
  217. if (ncRet.mh || ncRet.cn)
  218. ncInitLastFile = files[iHelp].ncInit;
  219. iHelp += iHelp ? -1 : MAXFILES-1;
  220. }
  221. while ((iHelp != ifileCur) && ((ncRet.mh == 0) && (ncRet.cn == 0)));
  222. }
  223. debmsg ((ncRet.mh && ncRet.cn) ? "Y" : "N");
  224. return ncRet;
  225. /* end ncSearch */}