Использование 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
//---------------------------------------------------------------------------
Спасибо за это.Я согласен с тем, что второе окно справки желательно для многих/большинства ситуаций, но у меня есть одна форма, в которой перечислены темы, и требуется, чтобы связанная справка для каждого отображалась в соседней панели, когда пользователь перемещается вверх/вниз по списку. Однако я могу найти другой способ добраться туда. Я перейду к переводу примера Delphi на C++ ... если я получу работу присоски, я отправлю его здесь. Еще раз спасибо. – Kathleen
У меня есть перевод кода Delphi (в том же тестовом приложении, которое использует Vcl.HtmlHelpViewer.hpp), добавлено #include и оно компилируется, но теперь получите ** [ilink32 Error]: Unresolved external 'HtmlHelpA' ** Добавлено на мой путь к библиотекам ** $ (BDSLIB) \ win32 \ release \ psdk **, где I _see_ htmlhelp.lib, но никаких изменений. Что мне нужно сделать? –
Kathleen