Я переписываю старое приложение, написанное на C ++ и MFC. Одна из новых функций, которую я добавляю, — это помощь, основанная на .chm
файл. Допустим, этот файл называется myHelp.chm
, Когда я открываю его как пользователя из папки, дважды щелкнув по нему, все в порядке. Но если я начну с помощью:
::HtmlHelp( NULL, _T("myHelp.chm"), HH_HELP_CONTEXT, uiNumber )
в моем приложении внутренние ссылки между частями справки не работают (все справки в одном файле .chm).
Что я имею:
В InitInstance()
у меня есть:
EnableHtmlHelp();
И я запускаю мой HtmlHelp в CMainFrame::OnHelp()
,
Проблема, вероятно, не в файле .chm — я заменил его другим, из рабочего приложения, и он работает так же — он открывается, но не внутренние ссылки работают.
Может быть, это что-то в конфигурации или инициализации проекта? Проект действительно старый — 1995 год — и сейчас я переписываю его в VS2012
, Я работаю под win 10.
В вашем InitInstance
Обработчик вы можете сделать что-то вроде этого:
#ifdef _WIN64 // AJT v11.3.4
CString strHelp = m_pszHelpFilePath;
strHelp.MakeLower();
strHelp.Replace(_T("_x64.chm"), _T(".chm"));
free((void*)m_pszHelpFilePath);//Change the name of the .HLP file.
m_pszHelpFilePath = _tcsdup(strHelp);
#endif // _WIN64
Таким образом, вы можете обновить путь к файлу справки.
Затем в различных окнах, в которых вы хотите показать справку, вы можете сделать это:
void CMinistryInfoDlg::OnButtonHelp()
{
HtmlHelp( (DWORD_PTR)_T("HelpMinistry.htm"),HH_DISPLAY_TOPIC );
}
Это подходит для меня.
Ваш вопрос намекает на контекстную помощь. В моем приложении я делаю это так:
BOOL CCommunityTalksApp::ShowContextHelp(CWnd *pParent, HELPINFO* pHelpInfo)
{
CPoint ptControl ;
CRect rctControl ;
CWnd *pControl ;
CString strNoHelp, strHelpCommand ;
HWND hPopup ;
HH_POPUP sPop;
BOOL bOK = FALSE;
if( pParent != NULL && pHelpInfo != NULL )
{
memset( &sPop, 0, sizeof(sPop) );
sPop.clrBackground = GetSysColor( COLOR_INFOBK );
sPop.clrForeground = -1;
sPop.rcMargins.top = 5;
sPop.rcMargins.left = 5;
sPop.rcMargins.bottom = 5;
sPop.rcMargins.right = 5;
sPop.pt = pHelpInfo->MousePos;
sPop.idString = pHelpInfo->iCtrlId;
sPop.pszFont = NULL;
pControl = pParent->GetDlgItem( pHelpInfo->iCtrlId );
if( pControl != NULL )
{
pControl->GetWindowRect( &rctControl ); // Screen co-ords.
ptControl.x = rctControl.left + (rctControl.Width() / 2);
ptControl.y = rctControl.bottom ; // Below control.
sPop.pt = ptControl;
}
if( pHelpInfo->iCtrlId == IDC_STATIC ||
pHelpInfo->iCtrlId == IDOK ||
pHelpInfo->iCtrlId == IDCANCEL ||
pHelpInfo->iCtrlId == IDCLOSE ||
pHelpInfo->iCtrlId == IDC_HOME_STATIC ||
pHelpInfo->iCtrlId == IDC_AWAY_STATIC ||
pHelpInfo->iCtrlId == IDC_TALK_STATIC ||
pHelpInfo->iCtrlId == ID_STATIC_WEEKS ||
pHelpInfo->iCtrlId == IDC_STATIC_ENTRIES ||
pHelpInfo->iCtrlId == IDC_STATIC_AWAY ||
pHelpInfo->iCtrlId == IDC_STATIC_HOME ||
pHelpInfo->iCtrlId == IDC_STATIC_TALK_HIST ||
pHelpInfo->iCtrlId == IDC_LBL_STATIC ||
pHelpInfo->iCtrlId == IDC_LBL_STATIC2 ||
pHelpInfo->iCtrlId == ID_LBL_SORT_FIELD_LEGEND ||
pHelpInfo->iCtrlId == IDC_STATIC_CONG_NOTES ||
pHelpInfo->iCtrlId == IDC_STATIC_SPK_NOTES ||
pHelpInfo->iCtrlId == IDC_STATIC_ADD_NEW_TALK ||
pHelpInfo->iCtrlId == IDC_STATIC_MODIFY_NEW_TALK ||
pHelpInfo->iCtrlId == ID_BTN_CONGS_SHOW_BOOKED)
{
// These control IDs do not have any associated help strings
// so we use our own, otherwise we get a nasty HtmlHelp
// error message displayed to the user.
strNoHelp.LoadString( IDS_STR_NO_CONTEXT_HELP );
sPop.idString = 0;
sPop.pszText = strNoHelp;
hPopup = ::HtmlHelp((HWND)pHelpInfo->hItemHandle,
m_pszHelpFilePath,
HH_DISPLAY_TEXT_POPUP,
(DWORD_PTR)&sPop );
}
else
{
// This control ID _should_ be in the help strings.
switch( GetProgramLanguage() )
{
case LANGUAGE_SPANISH:
strHelpCommand.Format( _T("%s::/cshelpESP.txt"), m_pszHelpFilePath );
break;
case LANGUAGE_GERMAN:
strHelpCommand.Format( _T("%s::/cshelpDEU.txt"), m_pszHelpFilePath );
break;
case LANGUAGE_ITALIAN:
strHelpCommand.Format( _T("%s::/cshelpITA.txt"), m_pszHelpFilePath );
break;
case LANGUAGE_DUTCH:
strHelpCommand.Format( _T("%s::/cshelpDEU.txt"), m_pszHelpFilePath );
break;
case LANGUAGE_PORTUGUESE:
strHelpCommand.Format( _T("%s::/cshelpPTB.txt"), m_pszHelpFilePath );
break;
case LANGUAGE_SWEDISH:
strHelpCommand.Format( _T("%s::/cshelpSVE.txt"), m_pszHelpFilePath );
break;
case LANGUAGE_DANISH:
strHelpCommand.Format( _T("%s::/cshelpDAN.txt"), m_pszHelpFilePath );
break;
case LANGUAGE_RUSSIAN:
strHelpCommand.Format( _T("%s::/cshelpRUS.txt"), m_pszHelpFilePath );
break;
case LANGUAGE_TURKISH:
strHelpCommand.Format( _T("%s::/cshelpTRK.txt"), m_pszHelpFilePath );
break;
case LANGUAGE_FRENCH:
strHelpCommand.Format( _T("%s::/cshelpFRA.txt"), m_pszHelpFilePath );
break;
case LANGUAGE_FINNISH:
strHelpCommand.Format( _T("%s::/cshelpFIN.txt"), m_pszHelpFilePath );
break;
case LANGUAGE_ALBANIAN:
strHelpCommand.Format( _T("%s::/cshelpALB.txt"), m_pszHelpFilePath );
break;
case LANGUAGE_ROMANIAN:
strHelpCommand.Format( _T("%s::/cshelpROM.txt"), m_pszHelpFilePath );
break;
case LANGUAGE_ENGLISH:
default:
strHelpCommand.Format( _T("%s::/cshelpENG.txt"), m_pszHelpFilePath );
break;
}
hPopup = ::HtmlHelp( (HWND)pHelpInfo->hItemHandle,
strHelpCommand,
HH_DISPLAY_TEXT_POPUP,
(DWORD_PTR)&sPop );
}
if( hPopup != NULL )
bOK = TRUE;
}
return bOK;
}
Мой метод длинный, потому что я поддерживаю несколько переводов. Но вы должны быть в состоянии увидеть принципы.
Я вижу, вы используете HH_HELP_CONTEXT который работает немного по-другому. Я больше не использую этот вызов, но когда я это сделал:
void CMainFrame::HtmlHelp(DWORD_PTR dwData, UINT nCmd)
{
HWND hWnd;
hWnd = ::HtmlHelp(GetDesktopWindow()->GetSafeHwnd(), theApp.m_pszHelpFilePath,
HH_HELP_CONTEXT, nCmd == HELP_CONTEXT ? dwData : 0);
if(hWnd == NULL) // show default topic
::HtmlHelp(GetDesktopWindow()->GetSafeHwnd(), theApp.m_pszHelpFilePath,
HH_HELP_FINDER, 0 );
// CMDIFrameWndEx::HtmlHelp(dwData, nCmd);
}
Других решений пока нет …