Экспертная система Delphi.int.ru

Сообщество программистов
Общение, помощь, обмен опытом

Логин:
Пароль:
Регистрация | Забыли пароль?

Delphi.int.ru Expert

Другие разделы портала

Переход к вопросу:

#   

Статистика за сегодня:  


Лучшие эксперты

Подробнее »



Вопрос # 1 635

Раздел: Delphi » Прочее
/ вопрос решён /

Здравствуйте! Я хочу сделать справку в своей программе(или с расширением hlp или chm). Не могли бы Вы по пунктам разложить весь порядок её создания и код её подключения. Если для создания нужны программы дайте ссылки.

GAZ Вопрос решён, но можно продолжить его обсуждение в мини-форуме

Вопрос задал: GAZ (статус: Посетитель)
Вопрос отправлен: 30 мая 2008, 07:48
Состояние вопроса: решён, ответов: 3.

Ответ #1. Отвечает эксперт: min@y™

Мне не раз приходилось делать хэлпы к своим программам. В детстве я их делал в формате HLP, а когда подрос, перешел на CHM.
Для изготовления CHM-файла я использовал:


  1. cвои знания HTML;
  2. текстовый редактор с подсветкой синтаксиса HTML и CSS;
  3. Photoshop (для редактирования картинок/скриншотов);
  4. Microsoft Help Workshop (для сборки CHM-файла из набора HTML и картинок);
  5. прямые руки и трезвую голову.


В текстовом редакторе (или в визуальном редакторе HTML) пишутся страницы будущего файла справки. Делаются ссылки, вставляются картинки и пр. Потом всю структуру можно оттестировать с помощью браузера. Далее, в Microsoft Help Workshop создаётся проект, туда добавляются изготовленные файлы HTML, делается оглавление (ну, это дерево разделов), затем собирается в готовый CHM-файл.
Естественно, информации, которую я тут тебе изложил, будет недостаточно. Поэтому, я нашёл тебе статью по сабжу.

Для прицепляния изготовленного файла справки к своему приложению есть много способов. Я, например, использовал класс THHComp. Прицепляю этот компонент к ответу. Там и пример есть, как его юзать.
К ответу прикреплён файл. Загрузить » (срок хранения: 60 дней с момента отправки ответа)

Ответ отправил: min@y™ (статус: Доктор наук)
Время отправки: 30 мая 2008, 08:26
Оценка за ответ: 5

Ответ #2. Отвечает эксперт: Feniks

Здравствуйте, GAZ!
Как в дополнение...
В Приложении пример по использованию CHM файлов.
Всё, что вам надо сделать, это сохранить ниже приведенный модуль на диске и добавить его в Uses вашего проекта. После этого Вы сможете использовать CHM файлы точно так же как и обычные HLP файлы.

Приложение:
  1.  
  2. unit StoHtmlHelp;
  3. ////////////////////////////////////////////////////////////////
  4. // Implementation of context sensitive HTML help (.chm) for Delphi.
  5. //
  6. // Version: 1.2
  7. // Author: Martin Stoeckli
  8. // Homepage: www.martinstoeckli.ch/delphi
  9. // Copyright(c): Martin Stoeckli 2002
  10. //
  11. // Restrictions: - Works only under the Windows platform.
  12. // - Is written for Delphi v7, should work from v6 up.
  13. //
  14. // Description
  15. // ***********
  16. // This unit enables you to call ".chm" files from your Delphi projects.
  17. // You can use the normal Delphi VCL framework, write your projects the
  18. // same way, as you would using normal ".hlp" files.
  19. //
  20. // Installation
  21. // ************
  22. // Simply add this unit to your project, that's all.
  23. //
  24. // If your help project contains files with the extension ".html"
  25. // instead of ".htm", then you can either pass the filename with the
  26. // extension to Application.HelpJump(), or you can set the property
  27. // "HtmlExt" of the global object in this unit.
  28. // StoHelpViewer.HtmlExt := '.html';
  29. //
  30. // Examples
  31. // ********
  32. // // assign a helpfile, you could also select the helpfile at the
  33. // // options dialog "Project/Options.../Application".
  34. // Application.HelpFile := 'C:MyHelp.chm';
  35. // ...
  36. // // shows the contents of the helpfile
  37. // Application.HelpCommand(HELP_CONTENTS, 0);
  38. // // or
  39. // Application.HelpSystem.ShowTableOfContents;
  40. // ...
  41. // // opens the context sensitive help with a numerical id.
  42. // // you could do the same by setting the "HelpContext"
  43. // // property of a component and pressing the F1 key.
  44. // Application.HelpContext(1000);
  45. // // or with a string constant
  46. // Application.HelpJump('welcome');
  47. // ...
  48. // // opens the help index with a keyword.
  49. // // you could do the same by setting the "HelpKeyword"
  50. // // property of a component and pressing the F1 key.
  51. // Application.HelpKeyword('how to do');
  52. //
  53.  
  54. interface
  55. uses Classes, Windows, HelpIntfs;
  56.  
  57. type
  58. THtmlHelpA = function(hwndCaller: HWND; pszFile: LPCSTR; uCommand: UINT; dwData: DWORD): HWND; stdcall;
  59.  
  60. TStoHtmlHelpViewer = class(TInterfacedObject, ICustomHelpViewer,
  61. IExtendedHelpViewer, IHelpSelector)
  62. private
  63. FViewerID: Integer;
  64. FViewerName: String;
  65. FHtmlHelpFunction: THtmlHelpA;
  66. protected
  67. FHHCtrlHandle: THandle;
  68. FHelpManager: IHelpManager;
  69. FHtmlExt: String;
  70. function GetHelpFileName: String;
  71. function IsChmFile(const FileName: String): Boolean;
  72. procedure InternalShutdown;
  73. procedure CallHtmlHelp(const HelpFile: String; uCommand: UINT; dwData: DWORD);
  74. // ICustomHelpViewer
  75. function GetViewerName: String;
  76. function UnderstandsKeyword(const HelpString: String): Integer;
  77. function GetHelpStrings(const HelpString: String): TStringList;
  78. function CanShowTableOfContents: Boolean;
  79. procedure ShowTableOfContents;
  80. procedure ShowHelp(const HelpString: String);
  81. procedure NotifyID(const ViewerID: Integer);
  82. procedure SoftShutDown;
  83. procedure ShutDown;
  84. // IExtendedHelpViewer
  85. function UnderstandsTopic(const Topic: String): Boolean;
  86. procedure DisplayTopic(const Topic: String);
  87. function UnderstandsContext(const ContextID: Integer;
  88. const HelpFileName: String): Boolean;
  89. procedure DisplayHelpByContext(const ContextID: Integer;
  90. const HelpFileName: String);
  91. // IHelpSelector
  92. function SelectKeyword(Keywords: TStrings) : Integer;
  93. function TableOfContents(Contents: TStrings): Integer;
  94. public
  95. constructor Create; virtual;
  96. destructor Destroy; override;
  97. property HtmlExt: String read FHtmlExt write FHtmlExt;
  98. end;
  99.  
  100. var
  101. StoHelpViewer: TStoHtmlHelpViewer;
  102.  
  103. implementation
  104. uses Forms, SysUtils, WinHelpViewer;
  105.  
  106. const
  107. // imported from HTML Help Workshop
  108. HH_DISPLAY_TOPIC = $0000;
  109. HH_HELP_FINDER = $0000; // WinHelp equivalent
  110. HH_DISPLAY_TOC = $0001;
  111. HH_DISPLAY_INDEX = $0002;
  112. HH_DISPLAY_SEARCH = $0003;
  113. HH_KEYWORD_LOOKUP = $000D;
  114. HH_DISPLAY_TEXT_POPUP = $000E; // display string resource id or text in a popup window
  115. HH_HELP_CONTEXT = $000F; // display mapped numeric value in dwData
  116. HH_TP_HELP_CONTEXTMENU = $0010; // text popup help, same as WinHelp HELP_CONTEXTMENU
  117. HH_TP_HELP_WM_HELP = $0011; // text popup help, same as WinHelp HELP_WM_HELP
  118. HH_CLOSE_ALL = $0012; // close all windows opened directly or indirectly by the caller
  119. HH_ALINK_LOOKUP = $0013; // ALink version of HH_KEYWORD_LOOKUP
  120. HH_GET_LAST_ERROR = $0014; // not currently implemented // See HHERROR.h
  121.  
  122. type
  123. TStoWinHelpTester = class(TInterfacedObject, IWinHelpTester)
  124. protected
  125. // IWinHelpTester
  126. function CanShowALink(const ALink, FileName: String): Boolean;
  127. function CanShowTopic(const Topic, FileName: String): Boolean;
  128. function CanShowContext(const Context: Integer;
  129. const FileName: String): Boolean;
  130. function GetHelpStrings(const ALink: String): TStringList;
  131. function GetHelpPath : String;
  132. function GetDefaultHelpFile: String;
  133. function IsHlpFile(const FileName: String): Boolean;
  134. end;
  135.  
  136. ////////////////////////////////////////////////////////////////
  137. // like "Application.ExeName", but in a DLL you get the name of
  138. // the DLL instead of the application name
  139. function Sto_GetModuleName: String;
  140. var
  141. szFileName: array[0..MAX_PATH] of Char;
  142. begin
  143. FillChar(szFileName, SizeOf(szFileName), #0);
  144. GetModuleFileName(hInstance, szFileName, MAX_PATH);
  145. Result := szFileName;
  146. end;
  147.  
  148. ////////////////////////////////////////////////////////////////
  149. { TStoHtmlHelpViewer }
  150. ////////////////////////////////////////////////////////////////
  151.  
  152. procedure TStoHtmlHelpViewer.CallHtmlHelp(const HelpFile: String; uCommand: UINT; dwData: DWORD);
  153. begin
  154. if Assigned(FHtmlHelpFunction) then
  155. begin
  156. case uCommand of
  157. HH_CLOSE_ALL: FHtmlHelpFunction(0, nil, uCommand, dwData); // special parameters
  158. HH_GET_LAST_ERROR: ; // ignore
  159. else
  160. FHtmlHelpFunction(FHelpManager.GetHandle, PChar(HelpFile), uCommand, dwData);
  161. end;
  162. end;
  163. end;
  164.  
  165. function TStoHtmlHelpViewer.CanShowTableOfContents: Boolean;
  166. begin
  167. Result := True;
  168. end;
  169.  
  170. constructor TStoHtmlHelpViewer.Create;
  171. begin
  172. inherited Create;
  173. FViewerName := 'StoHtmlHelp';
  174. FHtmlExt := '.htm';
  175. // load dll
  176. FHHCtrlHandle := LoadLibrary('HHCtrl.ocx');
  177. if (FHHCtrlHandle <> 0) then
  178. FHtmlHelpFunction := GetProcAddress(FHHCtrlHandle, 'HtmlHelpA');
  179. end;
  180.  
  181. destructor TStoHtmlHelpViewer.Destroy;
  182. begin
  183. StoHelpViewer := nil;
  184. // free dll
  185. FHtmlHelpFunction := nil;
  186. if (FHHCtrlHandle <> 0) then
  187. FreeLibrary(FHHCtrlHandle);
  188. inherited Destroy;
  189. end;
  190.  
  191. procedure TStoHtmlHelpViewer.DisplayHelpByContext(const ContextID: Integer;
  192. const HelpFileName: String);
  193. var
  194. sHelpFile: String;
  195. begin
  196. sHelpFile := GetHelpFileName;
  197. if IsChmFile(sHelpFile) then
  198. CallHtmlHelp(sHelpFile, HH_HELP_CONTEXT, ContextID);
  199. end;
  200.  
  201. procedure TStoHtmlHelpViewer.DisplayTopic(const Topic: String);
  202. var
  203. sHelpFile: String;
  204. sTopic: String;
  205. sFileExt: String;
  206. begin
  207. sHelpFile := GetHelpFileName;
  208. if IsChmFile(sHelpFile) then
  209. begin
  210. // prepare topicname as a html page
  211. sTopic := Topic;
  212. sFileExt := LowerCase(ExtractFileExt(sTopic));
  213. if (sFileExt <> '.htm') and (sFileExt <> '.html') then
  214. sTopic := sTopic + FHtmlExt;
  215. CallHtmlHelp(sHelpFile + '::/' + sTopic, HH_DISPLAY_TOPIC, 0);
  216. end;
  217. end;
  218.  
  219. function TStoHtmlHelpViewer.GetHelpFileName: String;
  220. var
  221. sPath: String;
  222. begin
  223. Result := '';
  224. // ask for the helpfile name
  225. if Assigned(FHelpManager) then
  226. Result := FHelpManager.GetHelpFile;
  227. if (Result = '') then
  228. Result := Application.CurrentHelpFile;
  229. // if no path is specified, then add the application path
  230. // (otherwise the file won't be found if the current directory is wrong).
  231. if (Result <> '') then
  232. begin
  233. sPath := ExtractFilePath(Result);
  234. if (sPath = '') then
  235. Result := ExtractFilePath(Sto_GetModuleName) + Result;
  236. end;
  237. end;
  238.  
  239. function TStoHtmlHelpViewer.GetHelpStrings(const HelpString: String): TStringList;
  240. begin
  241. // create a tagged keyword
  242. Result := TStringList.Create;
  243. Result.Add(Format('%s: %s', [FViewerName, HelpString]));
  244. end;
  245.  
  246. function TStoHtmlHelpViewer.GetViewerName: String;
  247. begin
  248. Result := FViewerName;
  249. end;
  250.  
  251. procedure TStoHtmlHelpViewer.InternalShutdown;
  252. begin
  253. if Assigned(FHelpManager) then
  254. begin
  255. FHelpManager.Release(FViewerID);
  256. FHelpManager := nil;
  257. end;
  258. end;
  259.  
  260. function TStoHtmlHelpViewer.IsChmFile(const FileName: String): Boolean;
  261. var
  262. iPos: Integer;
  263. sFileExt: String;
  264. begin
  265. // find extension
  266. iPos := LastDelimiter('.', FileName);
  267. if (iPos > 0) then
  268. begin
  269. sFileExt := Copy(FileName, iPos, Length(FileName));
  270. Result := CompareText(sFileExt, '.chm') = 0;
  271. end
  272. else
  273. Result := False;
  274. end;
  275.  
  276. procedure TStoHtmlHelpViewer.NotifyID(const ViewerID: Integer);
  277. begin
  278. FViewerID := ViewerID;
  279. end;
  280.  
  281. function TStoHtmlHelpViewer.SelectKeyword(Keywords: TStrings): Integer;
  282. var
  283. i: Integer;
  284. sViewerName: String;
  285. begin
  286. Result := 0;
  287. i := 0;
  288. // find first tagged line (see GetHelpStrings)
  289. while (Result = 0) and (i <= Keywords.Count - 1) do
  290. begin
  291. sViewerName := Keywords.Strings[i];
  292. Delete(sViewerName, Pos(':', sViewerName), Length(sViewerName));
  293. if (FViewerName = sViewerName) then
  294. Result := i
  295. else
  296. Inc(i);
  297. end;
  298. end;
  299.  
  300. procedure TStoHtmlHelpViewer.ShowHelp(const HelpString: String);
  301. var
  302. sHelpFile: String;
  303. sHelpString: String;
  304. begin
  305. sHelpFile := GetHelpFileName;
  306. if IsChmFile(sHelpFile) then
  307. begin
  308. // remove the tag if necessary (see GetHelpStrings)
  309. sHelpString := HelpString;
  310. Delete(sHelpString, 1, Pos(':', sHelpString));
  311. sHelpString := Trim(sHelpString);
  312. CallHtmlHelp(sHelpFile, HH_DISPLAY_INDEX, DWORD(Pchar(sHelpString)));
  313. end;
  314. end;
  315.  
  316. procedure TStoHtmlHelpViewer.ShowTableOfContents;
  317. var
  318. sHelpFile: String;
  319. begin
  320. sHelpFile := GetHelpFileName;
  321. if IsChmFile(sHelpFile) then
  322. CallHtmlHelp(sHelpFile, HH_DISPLAY_TOC, 0);
  323. end;
  324.  
  325. procedure TStoHtmlHelpViewer.ShutDown;
  326. begin
  327. SoftShutDown;
  328. if Assigned(FHelpManager) then
  329. FHelpManager := nil;
  330. end;
  331.  
  332. procedure TStoHtmlHelpViewer.SoftShutDown;
  333. begin
  334. CallHtmlHelp('', HH_CLOSE_ALL, 0);
  335. end;
  336.  
  337. function TStoHtmlHelpViewer.TableOfContents(Contents: TStrings): Integer;
  338. begin
  339. // find line with viewer name
  340. Result := Contents.IndexOf(FViewerName);
  341. end;
  342.  
  343. function TStoHtmlHelpViewer.UnderstandsContext(const ContextID: Integer;
  344. const HelpFileName: String): Boolean;
  345. begin
  346. Result := IsChmFile(HelpFileName);
  347. end;
  348.  
  349. function TStoHtmlHelpViewer.UnderstandsKeyword(const HelpString: String): Integer;
  350. begin
  351. if IsChmFile(GetHelpFileName) then
  352. Result := 1
  353. else
  354. Result := 0;
  355. end;
  356.  
  357. function TStoHtmlHelpViewer.UnderstandsTopic(const Topic: String): Boolean;
  358. begin
  359. Result := IsChmFile(GetHelpFileName);
  360. end;
  361.  
  362. ////////////////////////////////////////////////////////////////
  363. { TStoWinHelpTester }
  364. //
  365. // delphi will call the WinHelpTester to determine, if the default
  366. // winhelp should handle the requests.
  367. // don't allow anything, because delphi (v7) will create an invalid
  368. // helpfile path, calling GetHelpPath (it puts a pathdelimiter
  369. // before the filename in "TWinHelpViewer.HelpFile").
  370. ////////////////////////////////////////////////////////////////
  371.  
  372. function TStoWinHelpTester.CanShowALink(const ALink,
  373. FileName: String): Boolean;
  374. begin
  375. Result := False;
  376. // Result := IsHlpFile(FileName);
  377. end;
  378.  
  379. function TStoWinHelpTester.CanShowContext(const Context: Integer;
  380. const FileName: String): Boolean;
  381. begin
  382. Result := False;
  383. // Result := IsHlpFile(FileName);
  384. end;
  385.  
  386. function TStoWinHelpTester.CanShowTopic(const Topic,
  387. FileName: String): Boolean;
  388. begin
  389. Result := False;
  390. // Result := IsHlpFile(FileName);
  391. end;
  392.  
  393. function TStoWinHelpTester.GetDefaultHelpFile: String;
  394. begin
  395. Result := '';
  396. end;
  397.  
  398. function TStoWinHelpTester.GetHelpPath: String;
  399. begin
  400. Result := '';
  401. end;
  402.  
  403. function TStoWinHelpTester.GetHelpStrings(
  404. const ALink: String): TStringList;
  405. begin
  406. // as TWinHelpViewer would do it
  407. Result := TStringList.Create;
  408. Result.Add(': ' + ALink);
  409. end;
  410.  
  411. function TStoWinHelpTester.IsHlpFile(const FileName: String): Boolean;
  412. var
  413. iPos: Integer;
  414. sFileExt: String;
  415. begin
  416. // file has extension '.hlp' ?
  417. iPos := LastDelimiter('.', FileName);
  418. if (iPos > 0) then
  419. begin
  420. sFileExt := Copy(FileName, iPos, Length(FileName));
  421. Result := CompareText(sFileExt, '.hlp') = 0;
  422. end
  423. else
  424. Result := False;
  425. end;
  426.  
  427. initialization
  428. StoHelpViewer := TStoHtmlHelpViewer.Create;
  429. RegisterViewer(StoHelpViewer, StoHelpViewer.FHelpManager);
  430. Application.HelpSystem.AssignHelpSelector(StoHelpViewer);
  431. WinHelpTester := TStoWinHelpTester.Create;
  432.  
  433. finalization
  434. // do not free StoHelpViewer, because the object is referenced by the
  435. // interface and will be freed automatically by releasing the last reference
  436. if Assigned(StoHelpViewer) then
  437. StoHelpViewer.InternalShutdown;
  438. end.


Ответ отправил: Feniks (статус: Бакалавр)
Время отправки: 30 мая 2008, 10:42
Оценка за ответ: 5

Ответ #3. Отвечает эксперт: ANBsoft

Здравствуйте, GAZ!
Для вызова CHM справки я использовал следующий код:
if Key=VK_F1 then ShowHelp('::/vydtov.htm');
А вот сама процедура вызова:
Procedure ShowHelp(HelpPageName:String);
Begin
WinExec(PChar('hh.exe '+HelpFileName+HelpPageName),SW_Show);
End;

Ответ отправил: ANBsoft (статус: Студент)
Время отправки: 30 мая 2008, 11:35
Оценка за ответ: 5


Мини-форум вопроса

Всего сообщений: 1; последнее сообщение — 30 мая 2008, 08:28; участников в обсуждении: 1.
min@y™

min@y™ (статус: Доктор наук), 30 мая 2008, 08:28 [#1]:

Пардон, ошибся.
Правильная статья тут.
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!

31 января 2011, 19:23: Статус вопроса изменён на решённый (изменил модератор Ерёмин А.А.): Автоматическая обработка (2 и более ответов с оценкой 5)

Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.

Версия движка: 2.6+ (26.01.2011)
Текущее время: 22 февраля 2025, 11:39
Выполнено за 0.03 сек.