cHHCtrlLib text "HHCTRL.OCX"
cHtmlHelpA text "HtmlHelpA"
; cFreshHelp db "%fresh%\"
; cFreshDefHelp db "doc\freshguide.chm", 0
; .size = $ - cFreshDefHelp
uglobal
HtmlHelp dd ?
hHHCtrl dd ?
ptrHelpFiles dd ? ; points to array of dwords with handles of strings with help filenames.
endg
proc InitHelp
begin
invoke LoadLibraryA, cHHCtrlLib
mov [hHHCtrl],eax
or eax,eax
jz .finish
invoke GetProcAddress, eax, cHtmlHelpA
.finish:
mov [HtmlHelp],eax
return
endp
finalize FreeHelpList
begin
push eax
xor eax, eax
xchg eax, [ptrHelpFiles]
test eax, eax
jz .finish
stdcall ListFree, eax, StrDel
.finish:
pop eax
return
endp
proc RebuildHelpFilesList
begin
pushad
stdcall FreeHelpList
stdcall CreateArray, 4
mov [ptrHelpFiles], eax
stdcall ConvertPath, '%FreshHelp%/index.help'
mov esi, eax
stdcall FileOpenAccess, esi, faReadOnly
jc .finish
mov ebx, eax
.readloop:
stdcall FileReadLine, ebx
jc .eof
test eax, eax
jz .eof
push eax
stdcall StrClipSpacesR, eax
stdcall StrClipSpacesL, eax
stdcall StrPtr, eax
cmp byte [eax], ';'
je .next
stdcall AddArrayItems, [ptrHelpFiles], 1
mov [ptrHelpFiles], edx
pop dword [eax]
jmp .readloop
.next:
stdcall StrDel ; from the stack
jmp .readloop
.eof:
stdcall FileClose, ebx
.finish:
popad
return
endp
;proc _AddOneHelpFile, .ptrName, .dummy
;begin
; stdcall StrDup, [.ptrName]
; push eax
; stdcall AddArrayItems, [ptrHelpFiles], 1
; mov [ptrHelpFiles], edx
; popd [eax]
; clc
; return
;endp
proc OnHelp, .wparam, .lparam
.cursor dd ?
.filecount dd ?
.str rb 256
begin
invoke LoadCursorA, 0, IDC_WAIT
invoke SetCursor, eax
mov [.cursor], eax
stdcall GetCurrentAsmEdit
jc .finish_help
lea ebx, [.str]
invoke SendMessageA, eax, AEM_GETWORDATCARET, 256, ebx
mov esi, [ptrHelpFiles]
test esi, esi
jz .search_inet
push [esi+TArray.count]
pop [.filecount]
cmp [.filecount], 0
je .search_inet
xor edi, edi
.searchloop:
stdcall SearchOneHelp, [esi+TArray.array+4*edi], ebx, FALSE
jc .finish_help
inc edi
cmp edi, [.filecount]
jne .searchloop
;; Now check the project "Documents" folder:
;.search_project:
; cmp [hProjManager], 0
; je .project_help_not_found
;
; invoke SendMessageA, [hProjManager], PMM_GETCATEGORY, 0, 'Documents'
;
; test eax, eax
; jz .project_help_not_found
;
; mov esi, eax
; mov ecx, [esi+TArray.count]
; lea esi, [esi+TArray.array]
; jecxz .project_help_not_found
;
;.proj_help:
; mov eax, [esi]
; add esi, 4
;
; stdcall SearchOneHelp, [eax+TOpenFile.hFileName], ebx, FALSE
; jc .finish_help
;
; dec ecx
; jnz .proj_help
;
;
;.project_help_not_found:
; The offline help failed, so search in internet.
.search_inet:
stdcall CfgGetInt, [hIniFileName], cParamSection, cGoogleKey, 0
test eax, eax
jz .finish_help
stdcall StrDupMem, 'http://www.google.com/search?q='
mov esi, eax
stdcall StrURLEncode, ebx
stdcall StrCat, esi, eax
stdcall StrDel, eax
stdcall CfgGetInt, [hIniFileName], cParamSection, cFeelingKey, 0
test eax, eax
jnz .feeling
stdcall StrCat, esi, '&btnG=1'
jmp .exec
.feeling:
stdcall StrCat, esi, '&btnI=1&gbv=1'
.exec:
stdcall OpenWebPage, esi
stdcall StrDel, esi
.finish_help:
invoke SetCursor, [.cursor]
return
endp
cMarkdownHelpHeader text '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">', CRLF, \
'<html xmlns="http://www.w3.org/1999/xhtml">', CRLF, \
' <head>', CRLF, \
' <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />', CRLF, \
' <meta http-equiv="Content-Style-Type" content="text/css" />', CRLF, \
' <title>Fres IDE help</title>', CRLF, \
' <link rel="stylesheet" href="help.css" type="text/css" />', CRLF, \
' </head>', CRLF, \
' <body>', CRLF
proc SearchOneHelp, .hFileName, .ptrWord, .flagIndex
.aklink HH_AKLINK
.fullname dd ?
begin
push ebx ecx esi edi
stdcall ConvertPath, '%FreshHelp%/'
stdcall StrCat, eax, [.hFileName]
mov [.fullname], eax
stdcall StrLen, [.hFileName]
mov ecx, eax
stdcall StrPtr, [.hFileName]
.extloop:
dec ecx
js .notfound
cmp byte [eax+ecx], '.'
jne .extloop
mov ecx, dword [eax+ecx] ; get the extension
or ecx, $20202000 ; case insensitive
cmp ecx, '.hlp'
je .winhelp
cmp ecx, '.chm'
je .htmlhelp
cmp ecx, '.idx' ; text index file of keyword = URL for adding external documents.
je .index
cmp ecx, '.htm'
je .html
cmp ecx, '.md '
je .text_markdown
.notfound:
clc
pop edi esi ecx ebx
return
;....................................................
; scan the markdown formatted text file for the keyword...
.text_markdown:
cmp [.ptrWord], 0
jne .search_keyword_md
cmp [.flagIndex], 0
je .notfound
jmp .md_found
.search_keyword_md:
stdcall LoadBinaryFile, [.fullname]
jc .notfound
mov esi, eax
stdcall SearchKeywordMarkdown, esi, [.ptrWord]
pushf
stdcall FreeMem, esi
popf
jnc .notfound
mov edi, eax
.md_found:
stdcall StrDup, [cfgHelpURL]
stdcall StrCat, eax, [.hFileName]
cmp [.ptrWord], 0
je @f
stdcall StrCharCat, eax, '#'
stdcall StrCat, eax, edi
stdcall StrDel, edi
@@:
; now show the markdown file....
stdcall OpenWebPage, eax
stdcall StrDel, eax
jmp .found
;....................................................
; scan the html file for the keyword...
.html:
cmp [.ptrWord], 0
jne .search_keyword
cmp [.flagIndex], 0
je .notfound
jmp .keyword_ok
.search_keyword:
stdcall LoadBinaryFile, [.fullname]
jc .notfound
mov ebx, eax
stdcall SearchKeywordHTML, ebx, [.ptrWord]
stdcall FreeMem, ebx
cmp ebx, eax
je .notfound ; SearchKeywordHTML changes eax only if the keyword has been found.
mov esi, eax
.keyword_ok:
stdcall StrDup, [cfgHelpURL]
mov edi, eax
stdcall StrCat, edi, [.hFileName]
cmp [.ptrWord], 0
je @f
stdcall StrCharCat, edi, '#'
stdcall StrCat, edi, esi
stdcall StrDel, esi
@@:
stdcall OpenWebPage, edi
stdcall StrDel, edi
jmp .found
;....................................................
.index:
cmp [.ptrWord], 0
jne .scan_index
cmp [.flagIndex], 0
je .notfound
movx [.ptrWord], '__index_main_file'
; stdcall OpenFileByName, [.fullname], 0, TRUE
; jmp .found
.scan_index:
stdcall FileOpenAccess, [.fullname], faReadOnly
mov ebx, eax
jc .notfound
.read_line:
stdcall FileReadLine, ebx
jc .end_index
test eax, eax
jz .end_index
mov edx, eax
stdcall StrClipSpacesR, edx
stdcall StrClipSpacesL, edx
stdcall StrPtr, edx
cmp byte [eax], ';' ; comment?
jne .not_comment
stdcall StrDel, edx
jmp .read_line
.not_comment:
stdcall StrSplitList, edx, '=', FALSE
stdcall StrDel, edx
mov esi, eax
cmp [esi+TArray.count], 2
jne .next_line
stdcall StrClipSpacesR, [esi+TArray.array]
stdcall StrClipSpacesR, [esi+TArray.array+4]
stdcall StrClipSpacesL, [esi+TArray.array]
stdcall StrClipSpacesL, [esi+TArray.array+4]
stdcall StrDupMem, [.ptrWord]
stdcall StrCharCat, eax, '*'
stdcall StrMatchPatternNoCase, eax, [esi+TArray.array]
stdcall StrDel, eax
jc .line_found
.next_line:
stdcall ListFree, esi, StrDel
jmp .read_line
.line_found:
stdcall CheckAbsURL, [esi+TArray.array+4]
jnc .relative
stdcall StrDup, [esi+TArray.array+4]
mov edi, eax
jmp .path_ok
.relative:
stdcall StrDup, [cfgHelpURL]
mov edi, eax
stdcall StrDup, [.hFileName]
mov ecx, eax
stdcall StrSplitFilename, ecx
stdcall StrDel, eax
stdcall StrCat, ecx, [esi+TArray.array+4]
stdcall StrCat, edi, ecx
stdcall StrDel, ecx
.path_ok:
stdcall OpenWebPage, edi
stdcall StrDel, edi
stdcall FileClose, ebx
stdcall ListFree, esi, StrDel
jmp .found
.end_index:
stdcall FileClose, ebx
jmp .notfound
;....................................................
.htmlhelp:
cmp [HtmlHelp], NULL
je .notfound
xor eax, eax
mov [.aklink.cbStruct], sizeof.HH_AKLINK
mov [.aklink.fReserved], eax
mov [.aklink.pszUrl], eax
mov [.aklink.pszMsgText], eax
mov [.aklink.pszMsgTitle], eax
mov [.aklink.pszWindow], eax
push [.ptrWord]
pop [.aklink.pszKeywords]
push [.flagIndex]
pop [.aklink.fIndexOnFail]
stdcall StrPtr, [.fullname]
mov ebx,eax
lea eax, [.aklink]
mov ecx, HH_KEYWORD_LOOKUP
cmp [eax+HH_AKLINK.pszKeywords], 0
jne @f
mov ecx, HH_DISPLAY_TOC
@@:
invoke HtmlHelp, NULL, ebx, ecx, eax
test eax,eax ; if eax==0 then given word doesn't exist in the help
jz .notfound ; file - so we search in user defined help file
.found:
stc
pop edi esi ecx ebx
return
.winhelp:
stdcall StrPtr, [.fullname]
cmp [.ptrWord], 0
jne @f
invoke WinHelpA, [hEditorsHost], eax, HELP_FINDER, 0
jmp .found
@@:
invoke WinHelpA, [hEditorsHost], eax, HELP_PARTIALKEY, [.ptrWord]
cmp [.flagIndex], 0
jne .found
invoke FindWindowA, cWinHelpName, 0
mov ebx, eax
invoke SendMessageA, ebx, WM_GETTEXTLENGTH, 0, 0
invoke IsWindowVisible, ebx
test eax, eax
jnz .found
stdcall StrPtr, [.fullname]
invoke WinHelpA, [hEditorsHost], eax, HELP_QUIT, 0
.waitforclose:
invoke FindWindowA, cWinHelpName, 0
test eax, eax
jnz .waitforclose
jmp .notfound
endp
cWinHelpName text 'MS_WINHELP'
proc OpenWebPage, .hURL
begin
pushad
stdcall GetParamFromINI, cWebBrowserKey
jc .finish
mov ebx, eax
stdcall StrCharCat, ebx, ' '
stdcall StrCat, ebx, [.hURL]
stdcall Exec, ebx
jc .finish2
stdcall FreeProcessID, eax
stdcall FreeThreadID, edx
clc
.finish2:
stdcall StrDel, ebx
.finish:
popad
return
endp
; Returns CF=1 if the URL is absolute
; CF=0 if the URL is relative
proc CheckAbsURL, .hURL
begin
pushad
stdcall StrPtr, [.hURL]
mov esi, eax
.start_loop:
lodsb
test al,al
jz .relative
cmp al, 'A'
jb .found
cmp al, 'Z'
jbe .start_loop
cmp al, 'a'
jb .found
cmp al, 'z'
jb .start_loop
.found:
cmp al, ':'
jne .relative
cmp word [esi], '//'
jne .relative
stc
popad
return
.relative:
clc
popad
return
endp
cID text 'id'
cName text 'name'
; Returns:
; CF=1 the keyword has been found in this document. eax contains an anchor link.
; CF=0 the keyword has not been found.
proc SearchKeywordHTML, .hHTML, .hKeyword
begin
pushad
stdcall StrPtr, [.hHTML]
mov esi, eax
.parse:
lodsb
test al, al
jz .not_found
cmp al, '<'
jne .parse
; tag begin
lodsb
cmp al, '/'
je .parse
or al, $20
cmp al, 'a'
jne .parse
;................................................
.anchor:
lodsb
test al, al
jz .not_found
cmp al, ' '
ja .anchor
.anchor2:
lodsb
test al, al
jz .not_found
cmp al, ' '
jbe .anchor2
.start_found:
dec esi
mov ebx, esi
.search_end:
lodsb
test al, al
jz .not_found
cmp al, '>'
jne .search_end
mov ecx, esi
sub ecx, ebx
dec ecx
jz .parse ; there is no parameters
stdcall StrExtract, ebx, 0, ecx
push eax
stdcall SplitTagParams, eax
stdcall StrDel ; from the stack
mov edi, eax ; TArray with name, value pairs
xor ecx, ecx
.param_loop:
cmp ecx, [edi+TArray.count]
je .end_params
stdcall StrCompNoCase, [edi+TArray.array+8*ecx], cID
jc .indexfound
stdcall StrCompNoCase, [edi+TArray.array+8*ecx], cName
jc .indexfound
inc ecx
jmp .param_loop
.indexfound:
stdcall StrDup, [.hKeyword]
stdcall StrCharCat, eax, '*'
stdcall StrMatchPatternNoCase, eax, [edi+TArray.array+8*ecx+4]
stdcall StrDel, eax
jc .found
.end_params:
stdcall FreeParamArray, edi
jmp .parse
.found:
stdcall StrDup, [edi+TArray.array+8*ecx+4]
stdcall FreeParamArray, edi
mov [esp+4*regEAX], eax
stc
popad
return
.not_found:
clc
popad
return
endp
; Returns:
; CF=1 the keyword has been found in this document. eax contains an anchor link.
; CF=0 the keyword has not been found.
proc SearchKeywordMarkdown, .hText, .hKeyword
begin
pushad
stdcall StrPtr, [.hText]
mov esi, eax
.parse:
lodsb
cmp al, $0d
je .new_line
cmp al, $0a
je .new_line
test al, al
jnz .parse
.not_found:
clc
popad
return
.new_line:
xor al, $0d xor $0a
cmp byte [esi], al
jne @f
inc esi
@@:
cmp word [esi], '[#' ; start of the markdown anchor.
jne .parse
add esi, 2
mov edi, esi
; search the end:
.end_loop:
lodsb
test al, al
jz .not_found
cmp al, ']'
jne .end_loop
sub esi, edi
dec esi
stdcall StrExtract, edi, 0, esi
mov edx, eax
stdcall StrDup, [.hKeyword]
stdcall StrCharCat, eax, '*'
stdcall StrMatchPatternNoCase, eax, edx
stdcall StrDel, eax
jc .found
stdcall StrDel, edx
add esi, edi
jmp .parse
.found:
mov [esp+4*regEAX], edx
stc
popad
return
endp
proc SplitTagParams, .hParamStr
.start dd ?
begin
pushad
stdcall CreateArray, 8
mov edx, eax
stdcall StrPtr, [.hParamStr]
mov esi, eax
mov [.start], eax
.eq_loop:
lodsb
test al, al
jz .finish
cmp al, '='
jne .eq_loop
stdcall AddArrayItems, edx, 1
mov edi, eax
dec esi
mov ecx, esi
.left:
dec ecx
mov al, [ecx]
cmp al, ' '
je .start_found2
cmp ecx, [.start]
je .start_found
jmp .left
.start_found2:
inc ecx
.start_found:
mov eax, esi
sub eax, ecx
stdcall StrExtract, ecx, 0, eax
mov [edi], eax
.search_val:
lodsb
test al, al
jz .finish
cmp al, '"'
jne .search_val
mov ecx, esi
.end_loop:
lodsb
test al, al
jz .end_found
cmp al, '"'
jne .end_loop
.end_found:
push eax
mov eax, esi
sub eax, ecx
dec eax
stdcall StrExtract, ecx, 0, eax
mov [edi+4], eax
pop eax
test al, al
jnz .eq_loop
.finish:
mov [esp+4*regEAX], edx
popad
return
endp
proc FreeParamArray, .pArray
begin
pushf
pushad
mov esi, [.pArray]
mov ecx, [esi+TArray.count]
lea esi, [esi+TArray.array]
jecxz .freemem
.loop:
stdcall StrDel, [esi]
stdcall StrDel, [esi+4]
add esi, 8
loop .loop
.freemem:
stdcall FreeMem, [.pArray]
popad
popf
return
endp