HtmlHelp MS API строка поиска

Кто-нибудь в 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 не будет выполнен. Я открыл.chm файл с query.pszSearchQuery в списке на панели "Поиск" на моем экране, но я должен сам щелкнуть "Список тем", чтобы показать результаты поиска.

1 ответ

Решение

С помощью HTMLHelp API - VBA, VB6 и VB2003 я постараюсь ответить. Я считаю, что нет функции API для перечисления тем в vC++. Вы отправили событие нажатия кнопки в запущенное окно справки.

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++

Другие вопросы по тегам