1

2017 年是否有人知道如何实现调用 HtmlHelp 函数,该函数将打开带有“搜索”窗格的 .chm 文件,并在其列表框中执行查询字符串,并且能够执行此查询?

我尝试以下:

HH_FTS_QUERY query;

query.cbStruct         = sizeof(HH_FTS_QUERY);
query.fUniCodeStrings  = TRUE;
query.pszSearchQuery   = szSearchStr;
query.iProximity       = HH_FTS_DEFAULT_PROXIMITY;
query.fStemmedSearch   = TRUE;
query.fTitleOnly       = TRUE;
query.fExecute         = TRUE;
query.pszWindow        = NULL;

HWND hHelpWnd = ::HtmlHelp(m_hWnd, szFile, HH_DISPLAY_SEARCH, (DWORD_PTR)&query);

但是 query.pszSearchQuery 中的查询不会被执行。我在屏幕上的“搜索”窗格的列表框中打开了带有 query.pszSearchQuery 的 .chm 文件,但我必须自己单击“列出主题”才能显示搜索结果。

4

1 回答 1

1

HTMLHelp API - VBA、VB6 和 VB2003的帮助下,我将尝试回复。我相信在 vc++ 中没有列出主题的 API 函数。您已将按钮单击事件发送到启动的帮助窗口。

LRESULT OnSearch(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
        TCHAR szBuf[128];
        GetDlgItem(IDC_EDIT1).GetWindowText(szBuf, sizeof(szBuf));

        if (!_tcslen(szBuf))
            return 0;

        //
        // First, invoke HtmlHelp with HH_DISPLAY_SEARCH. 
        // It doesn't execute search, but it's need for showing 'search' tab.
        //
        HH_FTS_QUERY fq;
        ZeroMemory(&fq, sizeof(fq));
        fq.cbStruct = sizeof(fq);
        fq.fUniCodeStrings = FALSE;
        fq.pszSearchQuery = (LPCTSTR)szBuf;
        fq.iProximity       = HH_FTS_DEFAULT_PROXIMITY;
        fq.fStemmedSearch   = FALSE;
        fq.fTitleOnly       = FALSE;
        fq.fExecute         = FALSE;
        fq.pszWindow        = NULL;
        HWND hwndHelp = ::HtmlHelp(NULL, _T("realplay.chm"), HH_DISPLAY_SEARCH, (DWORD)&fq);

        //
        // Find query combobox and set query text.
        // 
        HWND hPaneWnd, hPaneLast, hTabWnd, hDlgWnd, hCtlWnd;

        hPaneWnd = FindWindowEx(hwndHelp, NULL, _T("HH Child"), NULL);
        for (;;) // last HH Child
        {
            hPaneLast = FindWindowEx(hwndHelp, hPaneWnd, _T("HH Child"), NULL); // last HH Child
            if (!hPaneLast)
                break;
            hPaneWnd = hPaneLast;
        }
        ATLTRACE("hPaneWnd == %x", hPaneWnd);

        hCtlWnd = FindWindowEx(hPaneWnd, NULL, _T("Button"), NULL); // skip Tab Control
        //
        // There are two types of interfaces:
        //
        // 1.
        // Window hierarchy:
        // + Main window 
        //   + HH Child
        //     + Browser ...
        //   + HH Child       <- second "HH Child" window
        //         - Edit     <- we have to fill this edit
        //         - Buttons  <- and press this buttons
        //         ...
        if (hCtlWnd)
        {
            hCtlWnd = FindWindowEx(hPaneWnd, NULL, _T("Edit"), NULL); // skip Tab Control
            // Set window text
            ATLASSERT(hCtlWnd != NULL);
            ::SendMessage(hCtlWnd, WM_SETTEXT, 0, (LPARAM)szBuf);   // fill it by our query

            ::SendMessage(hwndHelp, WM_COMMAND, 0xbc7, 0); // 0x3ee -- 'List Topics' button, it runs search
            if (::SendMessage(GetDlgItem(IDC_CHECK1), BM_GETCHECK, 0, 0) == BST_CHECKED)
                ::SendMessage(hwndHelp, WM_COMMAND, 0xbbe, 0); // 0x3f1 -- 'Display' button, it shows first item
        }
        //2.
        // Window hierarchy:
        // + Main window 
        //   + HH Child
        //     + Browser ...
        //   + HH Child       <- second "HH Child" window
        //     + Tab Control
        //       + Dialog
        //         - Combobox <- we have to fill this combo
        //         - Buttons  <- and press this buttons
        //         ...
        else
        {

            hTabWnd = FindWindowEx(hPaneWnd, NULL, _T("SysTabControl32"), NULL); // skip Tab Control
            hDlgWnd = FindWindowEx(hTabWnd, NULL, NULL, NULL); // skip dialog

            TCHAR szClass[64];
            GetClassName(hDlgWnd, szClass, sizeof(szClass));
            ATLTRACE("hDlgWnd(1) == %x", hDlgWnd);
            if (!_tcsstr(szClass, "#")) // Is it dialog?
                hDlgWnd = FindWindowEx(hTabWnd, hDlgWnd, NULL, NULL); // skip dialog
            hCtlWnd = FindWindowEx(hDlgWnd, NULL, _T("ComboBox"), NULL); // well, it's combobox

            // Set window text
            ATLASSERT(hCtlWnd != NULL);
            ::SendMessage(hCtlWnd, WM_SETTEXT, 0, (LPARAM)szBuf);   // fill it by our query

            //
            // Run search and show first finded page
            //
            ::SendMessage(hwndHelp, WM_COMMAND, 0x3ee, 0); // 0x3ee -- 'List Topics' button, it runs search
            if (::SendMessage(GetDlgItem(IDC_CHECK1), BM_GETCHECK, 0, 0) == BST_CHECKED)
                ::SendMessage(hwndHelp, WM_COMMAND, 0x3f1, 0); // 0x3f1 -- 'Display' button, it shows first item
        }
        return 0;
}

编辑:

您可以通过 spy++ 获取 List Topic 的控制 ID 在此处输入图像描述

于 2017-06-09T05:03:07.667 回答