Then read on!
Despite HTMLhelp running remarkably well for it's age in windows 10, can't help wondering why AHK stuck with it when there are good and possibly more user friendly (and free) programs around based on it.
Pity MS never made it open source like they never did with the (possibly superior) original WinHlp32 system.
In reading user comments on HTMLHelp the general consensus appears to be don't bother unless one is not competent in HTML.
TBQH mine own knowledge of HTML isn't great either, which is why using it as the recommended help system presents itself somewhat as a challenge.
The other thing to watch out for is keeping one's code to HTML version 4 or less (edit: unless venturing down this path), and there are not many 3rd party programs today that do it well enough (Bluefish and Dreamweaver come to mind as being useful in that regard). And the dinky (oh so nineties) gui featuring the Notepad-like CTRL-Z undo/redo toggle.
As MS's own riff on how to use HTMLHelp cannot be surpassed, we are not offering a full-blown tutorial,- just a few points on ease of use.
To begin with, download and install it, then run the executable hhw.exe from the install directory- typically Program Files (x86)\HTML Help Workshop.
The in-built help file describes how to start a project and add HTML files to it. It's recommended at some stage decompiling the AHK help file to see how things are setup, so let's do that now.
After decompiling the project to an empty folder, we note there is no hpp file generated so download it from github and copy it to the location where the decompiled AHK chm resides along with the Table of Contents.hhc and index.hhk. Upon closing any current projects in the Help Gui, open the AHK project and double click the windows section in the sidebar pane.
Click the files tab to verify the file layout. Note the settings in the other tabs and that the HTMLHelp WM_Help context question mark doesn't trigger on the controls. Meh. Also note there is no in-house "browser preview" of the content until the project is compiled, which at least has since become an integral part of the Visual Studio environment. Double click on the Options section for the tabbed options dialog- perhaps checking "Support enhanced decompilation" under Compiler generates the above missing hhp?
Click over to the Index tab to view the vast indexed list, then return to the contents tab and double click on Quick Reference. Yep, the layout is as with any other HTML page- the most critical is the following:
Code: Select all
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<link href="static/theme.css" rel="stylesheet" type="text/css" />
<script src="static/content.js" type="text/javascript"></script>
The following line of code shows how an image in the project is linked:
Code: Select all
<img src="static/ahk_logo.png" alt="AutoHotkey"></a>
Lets now look at the entire stylesheet here with some extra (hopefully explanatory) comments- bearing in mind OP has been using CSS for barely five minutes:
Code: Select all
html, body { /*comma applies to both elements*/
margin: 0;
padding: 0;
height: 100%;
}
body {
margin: 0 8px 0 8px;
font-size: .875em; /*em is an HTML emphasis phrase tag. Here it is typographic font size with properties overridden below */
line-height: 1.75;
background-color: #fefefe;
padding-bottom: 3em;
}
html {
font-family: Arial, sans-serif;
}
img {
border: none;
}
img::selection { /*selects portion selected by user- "selection" is a pseudo-element*/
background: transparent;
}
img::-moz-selection { /*above for Firefox*/
background: transparent;
}
a { /*a element refers to all hyperlink tags*/
text-decoration: none;
}
a:link, a:active { /* :link looks to be a class selector, not a pseudo-element*/
color: #4280CA;
}
a:visited {
color: #AA00AA;
}
a:hover, a:focus {
text-decoration: underline;
color: #2A6496;
}
#MyApp img { /*hash before ID makes it unique*/
margin: 20px 0 20px 0;
}
input, select {
border: 1px solid #ccc;
}
pre, code { /*pre is pre-formatted*/
border-right: solid 1px #C8C8C8;
border-bottom: solid 1px #C8C8C8;
background-color: #F6F6E8;
}
pre, .Syntax { /* "Syntax: user defined class with following properties */
font-family: Consolas, Courier New, monospace;
}
.Syntax {
background-color: #FFFFAA;
border: solid 1px #E8E89A;
}
code, span.Syntax { /* span or inline element with class name of Syntax */
font-family: Consolas, Courier New, monospace;
padding: 0 1px;
}
pre {
background-color: #F6F6E8; /*#F3F3FF*/
margin: 0.7em 1.5em 0.7em 1.5em;
padding: 0.7em 0 0.7em 0.7em;
white-space: pre-wrap; /* works in IE8 but apparently not CHM viewer */
word-wrap: break-word; /* works in CHM viewer */
}
pre.Syntax {
margin: 0 0 1.0em 0;
padding: 12px 0 12px 4px;
line-height: 150%;
}
pre, pre.Short /*used with .Syntax -to enforce make Short a subclass?*/ {
line-height: 120%;
}
pre em, code em { /* em is a size factor of Font, em is some descendant of both pre and code */
color: #00A000;
font-style: normal;
}
.NoIndent {
margin-left: 0;
}
::selection {
color: #fff;
background: #6c7a95;
}
::-moz-selection {
color: #fff;
background: #6c7a95;
}
h1 {
font-size: 2em;
font-weight: bold;
border-bottom-color: #FFFFFF;
border-bottom-width: 2px;
margin-top: 8px;
color: #3F5770; /* Well known navy bluish header */
}
.navh1 { /* override of h1 in javascript main.js */
font-weight: normal;
background-color: #606060;
color: #FFF;
margin: 0px -8px 8px -8px;
padding: 7px 8px 0px 8px;
text-overflow: ellipsis;
overflow: hidden;
height: 43px;
border-bottom: 1px solid #ccc;
font-size: 1.5em;
white-space: nowrap;
}
.navh1 a {
color: #CCC !important;
}
h2 {
color: #A04040;
}
h3 {
color: #008800;
}
#headerbar { /* referenced in javascript main.js but not used in help files*/
background-color: #606060;
position: absolute;
top: 108px;
left: 0px;
width: 100%;
height: 50px;
z-index: -1;
border-bottom: 1px solid #ccc;
}
a:visited {
color: #7847b2;
}
h2:first-child {
margin-top: 0;
}
h4 {
margin-bottom: 0;
line-height: 1;
}
h1, h2, h3 {
border-bottom: 1px solid #ddd;
}
/* table of command parameters */
table {
margin-bottom: 1em;
}
table.info {
border: solid 2px #C0C0C0;
border-collapse: collapse;
width: 100%;
}
table.info td {
border: solid 1px #C0C0C0;
padding: 0.3em 0.5em;
}
table.info th {
background-color: #F6F6F6;
padding: 0.3em 0.5em;
}
/* heading note / version number/requirement tag */
.headnote,
h1 .ver, h2 .ver, h3 .ver {
color: #808080;
font-size: 65%;
font-weight: normal;
margin-left: 1em;
vertical-align: text-middle;
}
h4 .headnote,
h4 .ver {
font-weight: normal;
}
.ver, a.ver {
color: gray;
}
a.ver:hover, a.ver:focus {
text-decoration: none;
}
.dull {
color: gray;
}
.red {
color: red;
} /* used for highlight in various places */
.blue {
color: blue;
}
/* emphasized note */
.note {
border-left: 2px solid #99BB99;
background-color: #E6FFE6;
color: #005500;
padding: .5em 1em;
}
.warning {
border-left: 2px solid #FFA000;
background-color: #FFF8E6;
color: #C05500;
padding: .5em 1em;
}
/* styles for briefly documenting multiple methods on one page: */
.methodShort {
border: solid thin #C0C0C0;
padding: 0.5em;
margin-bottom: 1em;
}
.methodShort h2 {
margin-top: 0;
color: black;
border-bottom: 0px;
}
.methodShort table.info {
border: none;
}
.methodShort table.info td {
border: none;
vertical-align: text-top;
}
.methodShort:target { /* non-essential, but helpful if it works */
border-color: black;
}
/* sidebar - or navigation pane if you like */
ul.jqtree-tree {
margin-left: 20px;
}
ul.jqtree-tree,
ul.jqtree-tree ul.jqtree_common {
list-style: none outside;
margin-bottom: 0;
padding: 0;
}
ul.jqtree-tree ul.jqtree_common {
display: block;
margin-left: 12px;
margin-right: 0;
}
ul.jqtree-tree li {
line-height: 1.5em;
padding: .2em 0 .2em 0;
}
ul.jqtree-tree li.jqtree-closed > ul.jqtree_common {
display: none;
}
ul.jqtree-tree li.jqtree_common {
clear: both;
list-style-type: none;
}
ul.jqtree-tree .jqtree-toggler {
display: block;
position: absolute;
left: -1.5em;
top: 30%;
*top: 0; /* fix for ie7 */
font-size: 10px;
line-height: 12px;
font-family: arial; /* fix for ie9 */
border-bottom: none;
color: #333;
}
ul.jqtree-tree .jqtree-toggler:hover {
color: #000;
}
ul.jqtree-tree .jqtree-element {
cursor: pointer;
}
ul.jqtree-tree .jqtree-title {
vertical-align: middle;
}
ul.jqtree-tree li.jqtree-folder {
margin-bottom: 4px;
}
ul.jqtree-tree li.jqtree-folder.jqtree-closed {
margin-bottom: 1px;
}
ul.jqtree-tree li.jqtree-folder .jqtree-title {
margin-left: 0;
}
ul.jqtree-tree .jqtree-toggler.jqtree-closed {
background-position: 0 0;
}
ul.jqtree-tree .jqtree-element {
width: 100%; /* todo: why is this in here? */
*width: auto; /* ie7 fix; issue 41 */
position: relative;
}
ul.jqtree-tree li.jqtree-selected > .jqtree-element
{
font-weight: bold;
color: #dd4b39;
}
ul.jqtree-tree li > .jqtree-element:hover
{
background-color: #eee;
}
.main-content {
width: 100%;
min-height: 100%;
height: auto!important;
height: 100%;
}
#app-body {
width: 100%;
}
#app-body .left-col {
width: 231px;
float: left;
}
#app-body .right-col {
margin-left: 231px;
}
#main-content {
padding-left: 13px;
padding-right: 26px;
min-height: 230px;
max-width: 950px;
}
.right-col #main-content {
border-left: 1px solid #e5e5e5;
}
/* Header */
.header {
position: relative;
background: #333;
height: 67px;
padding: 20px 25px;
margin: 0 -8px 0 -8px;
border-bottom: 1px solid #e5e5e5;
z-index: 9999;
white-space: nowrap;
}
.hdr-table {
width: 100%;
max-width: 1180px;
height: 81px;
}
.hdr-table td {
margin: 0;
padding: 0;
}
.hdr-table .hdr-image, .hdr-table .hdr-image img {
width: 217px;
}
.hdr-table .hdr-search {
vertical-align: bottom;
padding-bottom: 13px;
}
.hdr-table .hdr-search form {
display: inline-block;
}
.hdr-table .hdr-search input {
padding-left: 5px;
font-size: 1em;
height: 25px;
font-family: Arial, sans-serif;
width:210px;
vertical-align: middle;
border: 1px solid #999;
margin-left: 8px;
}
.hdr-table .hdr-search #search-btn {
display: inline-block;
height: 27px;
line-height: 27px;
width: 70px;
color: #bbb;
background: #606060;
text-align: center;
vertical-align: middle;
border: 1px solid #808080;
text-transform: uppercase;
cursor: pointer;
margin: 0px 10px;
}
.hdr-table .hdr-search #search-btn:hover, .hdr-table .hdr-language li:hover {
color: #FFF;
background: #808080;
}
.hdr-table .hdr-language {
vertical-align: bottom;
text-align: right;
padding-bottom: 13px;
}
.hdr-table .hdr-language ul {
display: inline-block;
padding:0;
margin:0;
}
.hdr-table .hdr-language li {
border:1px solid #808080;
background: #606060;
color:#bbb;
cursor:pointer;
display:block;
width: 100px;
text-align: center;
vertical-align: middle;
height: 27px;
line-height: 27px;
position:relative;
text-transform: uppercase;
}
.hdr-table .hdr-language .second {
left:-1px;
position:absolute;
top:28px;
display: none;
}
.hdr-table .hdr-language .second li {
text-transform: none;
}
/* Footer */
.footer {
background: #333;
color: #fff;
line-height: 44px;
margin: 0 -8px 0 -8px;
padding: 0 26px;
}
.footer a {
color: #CCC;
}
.float-clear {
clear: both;
}
.nav {
width: 242px;
float: left;
margin-top: -2px;
margin-left: -10px;
padding: 0;
list-style: none;
background-color: #808080;
border-bottom: 1px solid #ccc;
border-top: 1px solid #ccc;
}
.nav li {
float: left;
width: 50%;
text-align: center;
cursor: pointer;
}
.nav .selected {
background-color: #bbb;
}
.nav .selected span {
color: #000;
}
.nav li span {
display: block;
padding: 8px 15px;
text-decoration: none;
color: #FFF;
border-right: 1px solid #ccc;
height: 35px;
text-transform: uppercase;
font-size: 1.5em;
}
.nav li span:hover {
color: #000;
background-color: #bbb;
}
#IndexEntry {
width: 214px;
font-size: 1em;
font-family: helvetica, Arial, sans-serif;
}
#indexcontainer {
width: 216px;
font-size: 1em;
font-family: helvetica, Arial, sans-serif;
height: 100%;
}
/* command parameters */
dt { /* param name */
color: #008800;
margin-left: 0.5em;
}
dd {
margin-left: 1.5em;
padding-left: 1.0em;
border-left: 0.3em solid #e0e0e0;
margin-bottom: 1em;
}
dd > p:first-child {
margin-top: 0.3em;
}
Let's populate them, but
note the following
Clicking Tags/Edit and the first empty slot, paste the following into the title edit box:
And paste this into the Text block:Standard link to file
Slot 2 title:<a href="Root/File.htm">Link_to_File.htm_text</a>
This into the Text block:Metas (used by AHK)
Slot 3 title:<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
Slot 3 Text:Java Source
Slot 4 title:<script src="static/content.js" type="text/javascript"></script>
Slot 4 Text:Tables
Slot 5 title:<h3>Table Title</h3>
<table class="info">
<tr id="Something label">
<td>Something</td>
<td>Info on something</td>
</tr>
</table>
Slot 5 Text:Unordered List
Slot 6 title:<ul>
<li>Something</li>
<li><a href="htm file">htm filename</a></li>
</ul>
Slot 6 Text:Span for Color
Slot 7 title:<span style="color:red">red</span>
Slot 7 Text:Standard paragraph
Slot 8 title:<p>Blah...Paragraph can be broken up with <br> no closing tag required</p>
Slot 8 Text:Description List (From W3 schools)
And lastly for slot 9 do something fancy like the well-known Select All/Download routine:<dl>
<dt>Coffee</dt>
<dd>Black hot drink</dd>
<dt>Milk</dt>
<dd>White cold drink</dd>
</dl>
And paste this into the Text block:Pre Code AHK style
Well not all that for Slot #9 really, but it's there if you wanted to know how it all works - or want to do something similar.<pre>Some Code like Text</pre>
In the CSS
pre, code {
border-right: solid 1px #C8C8C8;
border-bottom: solid 1px #C8C8C8;
background-color: #F6F6E8;
}
In the js file
// Show select and download buttons in lower right corner of a pre box
var divStyle = {fontSize: "11px", float: "right"};
var aStyle = {cursor: "pointer", color: $("a:not([href=])").css("color")};
var selectLink = $('<a id="selectCode"></a>').text(translate.cdSelectBtn).css(aStyle);
var downloadLink = $('<a id="downloadCode"></a>').text(translate.cdDownloadBtn).css(aStyle);
$('pre').each(function(index) {
if ($(this).is(".Syntax")) {
$.extend(divStyle, {marginTop: "-32px", marginRight: "7px"});
$(this).after($('<div>').css(divStyle).prepend(selectLink.clone()));
}
else {
$.extend(divStyle, {marginTop: "-28px", marginRight: "28px"});
$(this).after($('<div>').css(divStyle).prepend(selectLink.clone(), [' | ', downloadLink.clone()]));
}
});
// Select complete code when clicking
$('a#selectCode').each(function(index) {
$(this).on('click', function(e) {
var doc = document
, text = $(this).parent().prev('pre')[0]
, range, selection
;
if (doc.body.createTextRange) {
range = document.body.createTextRange();
range.moveToElementText(text);
range.select();
} else if (window.getSelection) {
selection = window.getSelection();
range = document.createRange();
range.selectNodeContents(text);
selection.removeAllRanges();
selection.addRange(range);
}
});
});
// Download complete code when clicking
$('a#downloadCode').each(function(index) {
$(this).on('click', function(e) {
var textToWrite = '\ufeff' + $(this).parent().prev('pre').text().replace(/\n/g, "\r\n");
var textFileAsBlob = new Blob([textToWrite], {type:'text/csv'});
var fileNameToSaveAs = location.pathname.match(/([^\/]+)(?=\.\w+$)/)[0] + "-Script.ahk";
var downloadLink = document.createElement("a");
downloadLink.download = fileNameToSaveAs;
downloadLink.innerHTML = "Download File";
if (window.webkitURL != null) {
// Chrome
downloadLink.href = window.webkitURL.createObjectURL(textFileAsBlob);
downloadLink.click();
}
else if (navigator.userAgent.indexOf("Trident")>-1) {
// IE 10+
navigator.msSaveBlob(textFileAsBlob, fileNameToSaveAs)
}
else {
// Firefox
downloadLink.href = window.URL.createObjectURL(textFileAsBlob);
downloadLink.style.display = "none";
document.body.appendChild(downloadLink);
downloadLink.click();
}
});
});
}
And the spanning tag can also be expanded to the following item via another element: e.g.h2
Take care if updating HHW for any reason as these, and other settings will be reset. To preserve the settings, backup the reg key:<li><a href="#Something">Something</a></li>
<span id="Something"></span><h2 id="Description_of_Something">Something</h2>
with
h2 {
color: #A04040; /* red */
in the css file
HKEY_CURRENT_USER\SOFTWARE\Microsoft\HTML Help Workshop\Settings
Inserting these blocks into the help pages saves a little bit of extra work:- evidenced when only one project can be loaded in one time. Sure other files from other projects can be loaded, but in doing so leaves one prone to errors or unwanted files in the project as it evolves.
To create a search tab include this line in the hpp file:
Code: Select all
Full-text search=Yes
Historical note
The info at chmspec is very useful.
So there we have it- if there is anything amiss with a project the compiler will let you know. To actually link the files into an application refer to WM_Help Context IDs for GUI Controls and chm invocation. Using Anchors with the hidden attribute for topic section jumps is a good idea as well.
Finally, the HelpWare group tabulates a history of Microsoft Help programs.
The AHK help file itself has been taken care of over the years by many hands, but some components still remain a mystery. e.g. the Footer. It doesn't use anything like a (floating) footer, yet the CSS definitions remain for it.
Good idea then to only keep the elements & classes that will be actually used in the chm.