2016-01-20 8 views
1

Использование C++ Builder 10 Seattle (CX10).Показать тему справки из CHM на VCL TPanel?

У меня есть .chm с идентификаторами карты для определенных тем. Я могу загрузить темы во внешнее окно, как это:

#include "Vcl.HTMLHelpViewer.hpp" 

#pragma link "Vcl.HTMLHelpViewer" 

// In the main form constructor: 
Application->HelpFile = ExtractFilePath(Application->ExeName) + "MyHelp.chm"; 

// In button click event handler: 
Application->HelpContext(10001); 

Это отлично подходит для многих ситуаций, но иногда я хочу, чтобы встроить контекстно-конкретную помощь в моей TForm, например, на TPanel. Я нашел фрагменты информации об использовании функций WinAPI FindWindow и SetParent. Так что я попытался это:

HWND t_hwnd = FindWindow(NULL, "My Help File"); 
if (t_hwnd) 
{ 
    // HelpPanel is a TPanel with no properties adjusted from default 
    ::SetParent(t_hwnd, HelpPanel->Handle); 
} 

Что компилируется, ссылки, прогонов и не откажет ... но последующий вызов APPLICATION-> HelpContext (10001) по-прежнему отображает тему во внешнем окне, а не в HelpPanel.

Я предполагаю, что простой в использовании Application-> HelpContext вызов не является тем, что мне нужно для перенаправления на элемент управления VCL, но я не знаю, где искать дальше.

Вслед за комментариями, вот где я: Я узнал ошибку ilink32 (см мой комментарий ниже) потому, что мне нужно загрузить hhctrl.ocx для того, чтобы сделать вызов HtmlHelpA. Итак, вот мой тестовый код проекта, форма с TRadioGroup и TPanel. Только одна радиокнопка пытается поместить тему в TPanel; остальные используют Application-> HelpContext. Все эти компиляции, ссылки и прогоны, но вызов для размещения справки на TPanel не делает ничего видимого.

Действительно надеясь, что кто-то может помочь ... спасибо.

// MainFrm.dfm 
object MainForm: TMainForm 
    Left = 0 
    Top = 0 
    Caption = 'MainForm' 
    ClientHeight = 486 
    ClientWidth = 686 
    Color = clBtnFace 
    Font.Charset = DEFAULT_CHARSET 
    Font.Color = clWindowText 
    Font.Height = -11 
    Font.Name = 'Tahoma' 
    Font.Style = [] 
    OldCreateOrder = False 
    PixelsPerInch = 96 
    TextHeight = 13 
    object FunctionsRadioGroup: TRadioGroup 
    Left = 8 
    Top = 8 
    Width = 185 
    Height = 105 
    Caption = 'EDITS Language Functions' 
    Items.Strings = (
     'LOOKUP' 
     'RLOOKUP' 
     'ILOOKUP' 
     'STRCPY') 
    TabOrder = 0 
    OnClick = FunctionsRadioGroupClick 
    end 
    object HelpPanel: TPanel 
    Left = 199 
    Top = 8 
    Width = 490 
    Height = 477 
    Caption = 'HelpPanel' 
    TabOrder = 1 
    end 
end 

// MainFrm.h 
#ifndef MainFrmH 
#define MainFrmH 
//--------------------------------------------------------------------------- 
#include <System.Classes.hpp> 
#include <Vcl.Controls.hpp> 
#include <Vcl.StdCtrls.hpp> 
#include <Vcl.Forms.hpp> 
#include <Vcl.ExtCtrls.hpp> 
//--------------------------------------------------------------------------- 

typedef HWND (WINAPI *FPHH) (HWND, LPCSTR, UINT, DWORD); 

// Map IDs in my CHM 
#define LANG_FUNC_LOOKUP 10001 
#define LANG_FUNC_RLOOKUP 10002 
#define LANG_FUNC_STRCPY 10004 
#define LANG_FUNC_ILOOKUP 10003 

class TMainForm : public TForm 
{ 
__published: // IDE-managed Components 
    TRadioGroup *FunctionsRadioGroup; 
    TPanel *HelpPanel; 
    void __fastcall FunctionsRadioGroupClick(TObject *Sender); 
private: // User declarations 
    HINSTANCE FHHCTRL_OCX_INST; 
    FPHH htmlHelp; 

    bool __fastcall load_HHCTRL_OCX(); 

public:  // User declarations 
    __fastcall TMainForm(TComponent* Owner); 
    __fastcall ~TMainForm(); 

    void __fastcall DoShowEmbeddedHelp(TPanel* ThePanel, NativeInt TheTopicID); 
}; 
//--------------------------------------------------------------------------- 
extern PACKAGE TMainForm *MainForm; 
//--------------------------------------------------------------------------- 
#endif 

// MainFrm.cpp 
#include <vcl.h> 
#pragma hdrstop 

#include "MainFrm.h" 
#include <Vcl.HTMLHelpViewer.hpp> 
#include <HtmlHelp.h> 

//--------------------------------------------------------------------------- 
#pragma package(smart_init) 
#pragma link "Vcl.HTMLHelpViewer" 
//#pragma link "htmlhelp.lib" 
#pragma resource "*.dfm" 
TMainForm *MainForm; 
//--------------------------------------------------------------------------- 
__fastcall TMainForm::TMainForm(TComponent* Owner) 
    : TForm(Owner) 
{ 
    Application->HelpFile = ExtractFilePath(Application->ExeName) + 
     "MyHelpFile.chm"; 

    FHHCTRL_OCX_INST = 0; 

} // ctor 
//--------------------------------------------------------------------------- 
__fastcall TMainForm::~TMainForm() 
{ 
    if (FHHCTRL_OCX_INST > 0) 
    { 
     FreeLibrary(FHHCTRL_OCX_INST); 
    } 
}// dtor 
//--------------------------------------------------------------------------- 
void __fastcall TMainForm::FunctionsRadioGroupClick(TObject *Sender) 
{ 
    TRadioGroup* t_radio = dynamic_cast<TRadioGroup*>(Sender); 

    if (t_radio) 
    { 

     switch (t_radio->ItemIndex) 
     { 
      case 0: 
       //Application->HelpContext(LANG_FUNC_LOOKUP); 
       DoShowEmbeddedHelp(HelpPanel, LANG_FUNC_LOOKUP); 
       break; 

      case 1: 
       Application->HelpContext(LANG_FUNC_RLOOKUP); 
       break; 

      case 2: 
       Application->HelpContext(LANG_FUNC_ILOOKUP); 
       break; 

      case 3: 
       Application->HelpContext(LANG_FUNC_STRCPY); 
       break; 

     } 
    } 
} 
//--------------------------------------------------------------------------- 
bool __fastcall TMainForm::load_HHCTRL_OCX() 
{ 
    bool t_is_loaded = (FHHCTRL_OCX_INST > 0); 
    if (!t_is_loaded) 
    { 
     FHHCTRL_OCX_INST = LoadLibrary("HHCTRL.OCX"); 
     if (FHHCTRL_OCX_INST > 0) 
     { 
      (FARPROC&) htmlHelp = GetProcAddress(FHHCTRL_OCX_INST, "HtmlHelpA"); 
      if (htmlHelp) 
      { 
       t_is_loaded = true; 
      } 
     } 
    } 

    return t_is_loaded; 
} 
//--------------------------------------------------------------------------- 
void __fastcall TMainForm::DoShowEmbeddedHelp(TPanel* ThePanel, NativeInt TheTopicID) 
{ 
    HH_WINTYPE wintypedef; 
    AnsiString t_helpfile = ExtractFilePath(Application->ExeName) + "MyHelpFile.chm"; 
    AnsiString TheWinName = "HelpPanel"; 

    if (!FileExists(t_helpfile)) 
    { 
     MessageDlg(AnsiString("Help file not found: ") + t_helpfile, 
      mtError, TMsgDlgButtons() << mbOK, 0); 
     return; 
    } 

    // Zero the structure 
    memset(&wintypedef, 0, sizeof(HH_WINTYPE)); 
    // Prepare the properties 
    wintypedef.cbStruct = sizeof(wintypedef); 
    wintypedef.fUniCodeStrings = false; 
    wintypedef.pszType = TheWinName.c_str(); 
    wintypedef.fsValidMembers = 
      HHWIN_PARAM_PROPERTIES | 
      HHWIN_PARAM_STYLES | 
      HHWIN_PARAM_EXSTYLES | 
      HHWIN_PARAM_RECT | 
      HHWIN_PARAM_NAV_WIDTH | 
      HHWIN_PARAM_SHOWSTATE | 
      HHWIN_PARAM_TB_FLAGS | 
      HHWIN_PARAM_EXPANSION; 

    wintypedef.fsWinProperties = 
      HHWIN_PROP_NOTITLEBAR | 
      HHWIN_PROP_NO_TOOLBAR | 
      HHWIN_PROP_NODEF_STYLES | 
      HHWIN_PROP_NODEF_EXSTYLES | 
      HHWIN_PROP_TRI_PANE; 

    wintypedef.pszCaption = ""; 
    wintypedef.dwStyles = WS_VISIBLE | WS_CHILDWINDOW; 
    wintypedef.dwExStyles = WS_EX_LEFT; 
    wintypedef.rcWindowPos = 
     Rect(0, 0, ThePanel->ClientWidth, ThePanel->ClientHeight); 

    wintypedef.nShowState = SW_SHOW; 
    wintypedef.fsToolBarFlags = HHWIN_BUTTON_PRINT | HHWIN_BUTTON_BACK ; 
    wintypedef.fNotExpanded = true; 

    if (load_HHCTRL_OCX()) 
    { 
     if ((int)htmlHelp(0, NULL, HH_SET_WIN_TYPE, (DWORD)&wintypedef) < 0) 
     { 
      ShowMessage("Help failed on topic"); 
     } 
     else 
     { 
      /* NOTE: This was close, but wrong. 
      int HelpWinHandle = 
       (int)htmlHelp(ThePanel->Handle, "HelpPanel", HH_HELP_CONTEXT, TheTopicID); 
      */ 

      AnsiString t_fn = t_helpfile + AnsiString(">HelpPanel"); 
      int HelpWinHandle = 
       (int)htmlHelp(ThePanel->Handle, t_fn.c_str(), HH_HELP_CONTEXT, TheTopicID); 


     } 


    } 
} // DoShowEmbeddedHelp 
//--------------------------------------------------------------------------- 

ответ

0

Это глубокий переход в HTMLHelp API (написанный на C++ 20 лет назад Ральфом Уолденом). Вы, возможно, предупредили ...

У меня есть опыт в разработке справки, и я не программист на C++. Таким образом, HTMLHelp Viewer hh.exe является оболочкой для API Internet Explorer, отображающей темы HTML CHM в области содержимого справа.

Вы знаете «Приложение-> HelpContext (10001);» всегда вызывает средство просмотра справки с указанным тегом «10001». Встроенная справка меньше используется и сегодня не то, чего хотят пользователи. Конечно, второе окно справки легче.

Некоторые идеи и трюк, например. чтобы уменьшить зрителя проделанную помощью автора (создателя файла CHM) вы увидите на сайте: Microsoft HTML Help - Get the topic page URL from the topic ID

Дополнительная информация - извините Delphi - вы найдете по адресу: How to control/remove borders of embedded chm help file in delphi windows/vcl application?

HTH

+0

Спасибо за это.Я согласен с тем, что второе окно справки желательно для многих/большинства ситуаций, но у меня есть одна форма, в которой перечислены темы, и требуется, чтобы связанная справка для каждого отображалась в соседней панели, когда пользователь перемещается вверх/вниз по списку. Однако я могу найти другой способ добраться туда. Я перейду к переводу примера Delphi на C++ ... если я получу работу присоски, я отправлю его здесь. Еще раз спасибо. – Kathleen

+0

У меня есть перевод кода Delphi (в том же тестовом приложении, которое использует Vcl.HtmlHelpViewer.hpp), добавлено #include и оно компилируется, но теперь получите ** [ilink32 Error]: Unresolved external 'HtmlHelpA' ** Добавлено на мой путь к библиотекам ** $ (BDSLIB) \ win32 \ release \ psdk **, где I _see_ htmlhelp.lib, но никаких изменений. Что мне нужно сделать? – Kathleen

0

Хорошо, я, наконец, понял это.

В коде, который я отправил для функции TMainForm :: DoShowEmbeddedHelp, я неправильно подготовил второй параметр к HtmlHelpA. Это ДОЛЖНО быть таким:

AnsiString t_fn = t_helpfile + AnsiString(">HelpPanel"); 
HelpWinHandle = 
    (int)htmlHelp(ThePanel->Handle, t_fn.c_str(), HH_HELP_CONTEXT, TheTopicID); 

Теперь я получаю результат, который хотел.