HTML ヘルプを表示する

以下の環境で動作確認しました。

CraftLaunchEx で、HTML Help API を使用して HTML ヘルプを表示します。

コード

config.py などに記述します。
Windows 2000/XP では Unicode 版 (HtmlHelpW) を使用し、2000/XP 以外では ANSI 版 (HtmlHelpA) を使用します。

def _IsWinNT5OrLater():
    import sys

    (major, platform) = sys.getwindowsversion()[0:4:3]
    # VER_PLATFORM_WIN32_NT: 2
    return ((platform == 2) and (major >= 5))

winNT5OrLater = _IsWinNT5OrLater()


def _T(string):
    if isinstance(string, str):
        string = unicode(string, 'utf-8')
    if not winNT5OrLater:
        return string.encode('mbcs')
    return string


import ctypes

class c_tchar_p(ctypes._SimpleCData):
    if winNT5OrLater:
        _type_ = 'Z' # c_wchar_p
    else:
        _type_ = 'z' # c_char_p


# WinUser.h
GetDesktopWindow = ctypes.windll.user32.GetDesktopWindow


# HtmlHelp.h
HH_DISPLAY_TOC    = 0x0001
HH_KEYWORD_LOOKUP = 0x000D
HH_CLOSE_ALL      = 0x0012


from ctypes.wintypes import BOOL

class HH_AKLINK(ctypes.Structure):
    _fields_ = [
        ('cbStruct',     ctypes.c_int), # sizeof this structure
        ('fReserved',    BOOL),         # must be FALSE (really!)
        ('pszKeywords',  c_tchar_p),    # semi-colon separated keywords
        ('pszUrl',       c_tchar_p),    # URL to jump to if no keywords found (may be NULL)
        ('pszMsgText',   c_tchar_p),    # Message text to display in MessageBox if pszUrl is NULL and no keyword match
        ('pszMsgTitle',  c_tchar_p),    # Message text to display in MessageBox if pszUrl is NULL and no keyword match
        ('pszWindow',    c_tchar_p),    # Window to display URL in
        ('fIndexOnFail', BOOL)          # Displays index if keyword lookup fails.
    ]


if winNT5OrLater:
    HtmlHelp = ctypes.windll.LoadLibrary('hhctrl.ocx').HtmlHelpW
else:
    HtmlHelp = ctypes.windll.LoadLibrary('hhctrl.ocx').HtmlHelpA


def HtmlHelpDisplayTOC(chmPath, data=None):
    u"""指定されたヘルプウィンドウでヘルプトピックを開く

引数  : chmPath - 文字列 - コンパイル済みヘルプまたはコンパイル済みヘルプファイ
        ル中のトピック
引数  : data - 数値 - コンパイル済みヘルプファイル中のトピックへのポインタ
戻り値: ヘルプウィンドウのハンドルを返す"""
    return HtmlHelp(GetDesktopWindow(), chmPath, HH_DISPLAY_TOC, data)

def HtmlHelpKeywordLookup(chmPath, kwd):
    u"""コンパイル済みヘルプファイルからキーワードを検索する

引数  : chmPath - 文字列 - コンパイル済みヘルプファイル
引数  : kwd - 文字列 -  検索するキーワード
        複数の項目はセミコロン `;' で区切る
戻り値: ヘルプウィンドウのハンドルを返す"""
    aklnk = HH_AKLINK(ctypes.sizeof(HH_AKLINK), False, kwd, None, None, None,
                      None, True)
    return HtmlHelp(GetDesktopWindow(), chmPath, HH_KEYWORD_LOOKUP,
                    ctypes.byref(aklnk))

def HtmlHelpCloseAll():
    u"""呼び出しプログラムによって開かれたヘルプウィンドウをすべて閉じる

戻り値: なし"""
    HtmlHelp(None, None, HH_CLOSE_ALL, 0)

コマンド定義の例

CraftLaunchEx Help』を表示します。引数があればキーワード検索します。
ControlShift を押しながら実行すると、ヘルプウィンドウを閉じます。

<switch name='Help'>
  <script mod='' paramlist='*args' format=''>
    <![CDATA[
import os.path

hwnd = FindWindow('HH Parent', 'CraftLaunchEx Help')
chm = _T(os.path.join(GetAppDir(), 'clnch.chm'))

if hwnd:
    SetForegroundWindow(hwnd)
else:
    HtmlHelpDisplayTOC(chm + _T('::/chapter-01.html#%82%CD%82%B6%82%DF%82%C9'))
if len(args):
    HtmlHelpKeywordLookup(chm, _T(args[0]))
      ]]>
  </script>
  <script mod='CS' paramlist='' format=''>
    <![CDATA[
HtmlHelpCloseAll()
      ]]>
  </script>
</switch>

最初の script 要素の paramlist 属性値が『*args』となっているのは、

config.py に以下を書いてみたら、paramlist に *args とか書いて
余分な引数をタプルとして受け取れるようにできたよ

def MyCmdScriptCall(self, mod, *args):
    if len(args) < len(self.format):
        raise CommandFailedException, 'parameter num mismatch.'

    param_objects = []
    for (f, a) in zip(self.format, args):
        if  f == 's': param_objects.append(a)
        elif f == 'i': param_objects.append(int(a))
        elif f == 'f': param_objects.append(float(a))
    param_objects.extend( args[len(self.format):] )

    self.func( *param_objects )

CmdScript.__call__ = MyCmdScriptCall
http://pc11.2ch.net/test/read.cgi/software/1118294183/533

で、引数をタプルで取得できるようにしているからです。
_T() は VC++ の _T マクロみたいなものです。Windows 2000/XP なら unicode に、2000/XP 以外なら mbcs にエンコードします。