Benutzer mit den meisten Antworten
HTML Help (*.chm) in vorhandenes MFC Programm einbinden.

Frage
-
Guten Tag,
leider muß ich wieder mal um Hilfe bitten! Es gelingt mir einfach nicht meine schöne *.chm Datei in mein fertiges Programm einzubinden.
Auisgangssitution: Betriebssystem: Windows 10 Pro x64
Entwicklungssystem: Visual C++ 2010 Professional
Anwendung: RPwMgr.exe (Debugversion x86)
Hilfesystem: RPwMgrHelp.chmIch möchte mittels F1-Taste und aus einem Menue heraus nun nur die Hilfe mit Anzeige der Startseite anzeigen, mehr nicht. Es ist momentan keine Context sensitive Anzeige von Topics geplant. Diese soll sich der Benutzer nach der Gliederung selber aussuchen.
Bisher habe ich mir daran fast die Ohren gebrochen. Ich möchte hier nicht mit der Schilderung meiner diversen Versuche langweilen und stelle nur die zwei Fragen: Wie geht das? Gibt es dazu irgendwo vernünftige Beispiele?
K. H. Renders.
M. Thaddaeus
Antworten
-
Hallo nochmal,
für den Fall, dass der Aufruf der Hilfe noch nicht funktioniert, läßt sich auch eine Fehlermeldung ermitteln. Deshalb hier mal mein ganzes kleines Beispiel (MBCS-Variante):
#include <windows.h> #include <htmlhelp.h> struct HH_LAST_ERROR { int cbStruct; HRESULT hr; BSTR description; }; int WINAPI WinMain(HINSTANCE, HINSTANCE, char * cmdLine, int) { HWND hWnd; DWORD topicId = 0; HH_LAST_ERROR lastError; char * desc = 0; int len; hWnd = HtmlHelp(0, "filename.chm", topicId ? HH_HELP_CONTEXT : HH_DISPLAY_TOPIC, topicId); if (!hWnd) { memset(&lastError, 0, sizeof(HH_LAST_ERROR)); lastError.cbStruct = sizeof(HH_LAST_ERROR); hWnd = HtmlHelp(0, 0, HH_GET_LAST_ERROR, (DWORD)&lastError); if (hWnd && /* FAILED(lastError.hr) && */ lastError.description) { len = WideCharToMultiByte(CP_ACP, 0, lastError.description, -1, 0, 0, 0, 0); if (len) { desc = new char [len]; if (desc) { *desc = '\0'; len = WideCharToMultiByte(CP_ACP, 0, lastError.description, -1, desc, len, 0, 0); } } SysFreeString(lastError.description); } if (desc && *desc) MessageBox(0, desc, "HtmlHelp", MB_OK); else MessageBox(0, "Die Hilfe konnte nicht aufgerufen werden.", "HtmlHelp", MB_OK); if (desc) delete []desc; return -1; } while (IsWindow(hWnd)) Sleep(500); return 0; }
Gruß
Heiko- Als Antwort vorgeschlagen Dimitar DenkovMicrosoft contingent staff, Administrator Donnerstag, 28. Januar 2016 08:36
- Als Antwort markiert Dimitar DenkovMicrosoft contingent staff, Administrator Mittwoch, 3. Februar 2016 13:37
-
Also ich habe mal das Beispiel von Heiko genommen. Letztich funktioniert es so wie er gesagt hatte. Er hat nur ein paar Schreibfehler drin gehabt mit der Variablen topicId. Rein von der Funktionalität ist aber alles korrekt
#include <windows.h> #include <htmlhelp.h> #include <tchar.h> #pragma comment(lib, "htmlhelp.lib") int _cdecl _tmain (int argc, TCHAR *argv[]) { DWORD topicId = 0; HWND hWnd = HtmlHelp(0, _T("D:\\Verzeichnis\\noch einverzeichnis\\name_des_chmfiles.chm"), topicId ? HH_HELP_CONTEXT : HH_DISPLAY_TOPIC, topicId); while (IsWindow(hWnd)) Sleep(500); }
Wenn Du obigen code jetzt verwendest sollte das in einem Kommandozeilenprojekt problemlos funktionieren.
Best regards
Bordon
Note: Posted code pieces may not have a good programming style and may not perfect. It is also possible that they do not work in all situations. Code pieces are only indended to explain something particualar.- Als Antwort vorgeschlagen Dimitar DenkovMicrosoft contingent staff, Administrator Donnerstag, 28. Januar 2016 08:36
- Als Antwort markiert Dimitar DenkovMicrosoft contingent staff, Administrator Mittwoch, 3. Februar 2016 13:37
-
Guten Tag,
hiermit möchte ich Heiko und Bordon herzlich für Ihre Mühe danken. Sie haben mich auf die richtige Färte gesetzt.
Mit dem Beitrag von Bordon, welcher den Beitrag von Heiko ergänzte konnte ich tatsächlich meine Hilfe öffnem. Hierzu habe ich OnHelp überschrieben. Was mich allerdings störte, war die Tatsache, daß in der Hilfe von VC++ 2010 die Funktion HtmlHelp in der folgened Weise angegeben war:
CWinApp::HtmlHelp() oder CWnd::HtmlHelp(), in beiden Fällen ist die Funktion:
virtual void HtmlHelp(DWORD_PTR, UINT nCmd = 0x000F);
Dann stieß ich auf die Funktion CWinApp::EnableHlmlHelp(); weche ich nun im Constructor der Hauptfunktion meiner Anwendung aufrufe:
CRPwMgrApp::CRPwMgrApp()
{
EnableHtmlHelp();
// Neustart-Manager unterstützen
m_dwRestartManagerSupportFlags = AFX_RESTART_MANAGER_SUPPORT_RESTART;
}und in der Funktionhatte ich bereits die folgenden Zeilen eingefügt:
BOOL CRPMgrApp::InitInstance()
{
...
...m_scHelpFilespec = m_scModulePath + m_scApplName + _T("Help.chm");
strcpy_s(szHelpFilespec, MAX_PATH, m_scHelpFilespec.GetBuffer());
if (HelpFile.GetStatus(m_scHelpFilespec.GetBuffer(), tStatus))
{
free((void*)m_pszHelpFilePath);
m_pszHelpFilePath = _tcsdup(szHelpFilespec);
}
else
{
...
...
}
scHelpFilespec.ReleaseBuffer();
...
...}
und in meinem Dialog überschrieb ich die OnHelp Funktion:
BEGIN_MESSAGE_MAP(CRPasswordManagerDlg, CDialogEx)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
...
...
ON_COMMAND(ID_HELP, &CRPwMgrDlg::OnHelp)
END_MESSAGE_MAP()
void CRPwMgrDlg::OnHelp()
{
theApp.HtmlHelp(1000);
}
ich löschte
#include <windows.h> #include <htmlhelp.h>
und
#pragma comment(lib, "htmlhelp.lib")
aus meinem Code und der Hifesystem Aufruf funktionierte sowohl mit F1 als auch über das Hilfe Menue eiwandfrei! So einfach ist das --- wenn man es weiß und wenn man eine MFC-Anwendung verwendet.
Somit ist mein Problem gelöst! Mit nochmaligem Dank verbleibe ich
mit freundlichen Grüßen
K. H. RendersM. Thaddaeus
- Als Antwort markiert Dimitar DenkovMicrosoft contingent staff, Administrator Mittwoch, 3. Februar 2016 13:37
Alle Antworten
-
Hallo,
hilft dir vielleicht dieser Code-Schnipsel weiter:
#include <windows.h> #include <htmlhelp.h> { DWORD topicId = 0; HWND hWnd = HtmlHelp(0, "<CHM-Dateiname>", TopicId ? HH_HELP_CONTEXT : HH_DISPLAY_TOPIC, TopicId); while (IsWindow(hWnd)) Sleep(500); }
Gruß
Heiko
- Bearbeitet Heiko65456465 Sonntag, 24. Januar 2016 19:06
- Als Antwort vorgeschlagen Bordon Montag, 25. Januar 2016 11:10
-
Guten Tag Heiko,
Dank für Deine schnelle Antwot. Leider funktioniert das nicht!
void CRPwMgrDlg::OnHelp()
{
CString scStr = _T("RPwMgrHelp.chm");
DWORD TopicID = 0;
// 1 weder diese:
HWND hWnd = HtmlHelp(0, "RPwMgrHelp.chm", TopicId ? HH_HELP_CONTEXT : HH_DISPLAY_TOPIC, TopicId);
// 2 noch diese:
HWND hWnd = ::HtmlHelp(0, scStr.GetBuffer(), HH_DISPLAY_TOPIC, NULL);
}Nr. 1 läßt sich bei mir nicht compilieren und Nr. 2 bringt Linker Fehler "unresolved external ..."! Deine #includes habe ich drin. Was nun??? Wo steckt der Haken?
Gruß
K. H. Renders
M. Thaddaeus
-
Hallo,
ja, stimmt. In den Projekteingenschaften muß unter Linker/Eingabe/Zusätzliche Abhängigkeiten noch HtmlHelp.lib angefügt werden. Dann sollte es funktionieren.
Je nachdem, ob du Unicode oder MBCS verwendest, muß der Dateiname entsprechend übergeben werden.
Da du MFC verwendest, kannst du eventuell auch CWinApp::HtmlHelp() verwenden, welche die API-Funktion kapselt.
Gruß
Heiko -
Hallo nochmal,
für den Fall, dass der Aufruf der Hilfe noch nicht funktioniert, läßt sich auch eine Fehlermeldung ermitteln. Deshalb hier mal mein ganzes kleines Beispiel (MBCS-Variante):
#include <windows.h> #include <htmlhelp.h> struct HH_LAST_ERROR { int cbStruct; HRESULT hr; BSTR description; }; int WINAPI WinMain(HINSTANCE, HINSTANCE, char * cmdLine, int) { HWND hWnd; DWORD topicId = 0; HH_LAST_ERROR lastError; char * desc = 0; int len; hWnd = HtmlHelp(0, "filename.chm", topicId ? HH_HELP_CONTEXT : HH_DISPLAY_TOPIC, topicId); if (!hWnd) { memset(&lastError, 0, sizeof(HH_LAST_ERROR)); lastError.cbStruct = sizeof(HH_LAST_ERROR); hWnd = HtmlHelp(0, 0, HH_GET_LAST_ERROR, (DWORD)&lastError); if (hWnd && /* FAILED(lastError.hr) && */ lastError.description) { len = WideCharToMultiByte(CP_ACP, 0, lastError.description, -1, 0, 0, 0, 0); if (len) { desc = new char [len]; if (desc) { *desc = '\0'; len = WideCharToMultiByte(CP_ACP, 0, lastError.description, -1, desc, len, 0, 0); } } SysFreeString(lastError.description); } if (desc && *desc) MessageBox(0, desc, "HtmlHelp", MB_OK); else MessageBox(0, "Die Hilfe konnte nicht aufgerufen werden.", "HtmlHelp", MB_OK); if (desc) delete []desc; return -1; } while (IsWindow(hWnd)) Sleep(500); return 0; }
Gruß
Heiko- Als Antwort vorgeschlagen Dimitar DenkovMicrosoft contingent staff, Administrator Donnerstag, 28. Januar 2016 08:36
- Als Antwort markiert Dimitar DenkovMicrosoft contingent staff, Administrator Mittwoch, 3. Februar 2016 13:37
-
Also ich habe mal das Beispiel von Heiko genommen. Letztich funktioniert es so wie er gesagt hatte. Er hat nur ein paar Schreibfehler drin gehabt mit der Variablen topicId. Rein von der Funktionalität ist aber alles korrekt
#include <windows.h> #include <htmlhelp.h> #include <tchar.h> #pragma comment(lib, "htmlhelp.lib") int _cdecl _tmain (int argc, TCHAR *argv[]) { DWORD topicId = 0; HWND hWnd = HtmlHelp(0, _T("D:\\Verzeichnis\\noch einverzeichnis\\name_des_chmfiles.chm"), topicId ? HH_HELP_CONTEXT : HH_DISPLAY_TOPIC, topicId); while (IsWindow(hWnd)) Sleep(500); }
Wenn Du obigen code jetzt verwendest sollte das in einem Kommandozeilenprojekt problemlos funktionieren.
Best regards
Bordon
Note: Posted code pieces may not have a good programming style and may not perfect. It is also possible that they do not work in all situations. Code pieces are only indended to explain something particualar.- Als Antwort vorgeschlagen Dimitar DenkovMicrosoft contingent staff, Administrator Donnerstag, 28. Januar 2016 08:36
- Als Antwort markiert Dimitar DenkovMicrosoft contingent staff, Administrator Mittwoch, 3. Februar 2016 13:37
-
Guten Tag,
hiermit möchte ich Heiko und Bordon herzlich für Ihre Mühe danken. Sie haben mich auf die richtige Färte gesetzt.
Mit dem Beitrag von Bordon, welcher den Beitrag von Heiko ergänzte konnte ich tatsächlich meine Hilfe öffnem. Hierzu habe ich OnHelp überschrieben. Was mich allerdings störte, war die Tatsache, daß in der Hilfe von VC++ 2010 die Funktion HtmlHelp in der folgened Weise angegeben war:
CWinApp::HtmlHelp() oder CWnd::HtmlHelp(), in beiden Fällen ist die Funktion:
virtual void HtmlHelp(DWORD_PTR, UINT nCmd = 0x000F);
Dann stieß ich auf die Funktion CWinApp::EnableHlmlHelp(); weche ich nun im Constructor der Hauptfunktion meiner Anwendung aufrufe:
CRPwMgrApp::CRPwMgrApp()
{
EnableHtmlHelp();
// Neustart-Manager unterstützen
m_dwRestartManagerSupportFlags = AFX_RESTART_MANAGER_SUPPORT_RESTART;
}und in der Funktionhatte ich bereits die folgenden Zeilen eingefügt:
BOOL CRPMgrApp::InitInstance()
{
...
...m_scHelpFilespec = m_scModulePath + m_scApplName + _T("Help.chm");
strcpy_s(szHelpFilespec, MAX_PATH, m_scHelpFilespec.GetBuffer());
if (HelpFile.GetStatus(m_scHelpFilespec.GetBuffer(), tStatus))
{
free((void*)m_pszHelpFilePath);
m_pszHelpFilePath = _tcsdup(szHelpFilespec);
}
else
{
...
...
}
scHelpFilespec.ReleaseBuffer();
...
...}
und in meinem Dialog überschrieb ich die OnHelp Funktion:
BEGIN_MESSAGE_MAP(CRPasswordManagerDlg, CDialogEx)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
...
...
ON_COMMAND(ID_HELP, &CRPwMgrDlg::OnHelp)
END_MESSAGE_MAP()
void CRPwMgrDlg::OnHelp()
{
theApp.HtmlHelp(1000);
}
ich löschte
#include <windows.h> #include <htmlhelp.h>
und
#pragma comment(lib, "htmlhelp.lib")
aus meinem Code und der Hifesystem Aufruf funktionierte sowohl mit F1 als auch über das Hilfe Menue eiwandfrei! So einfach ist das --- wenn man es weiß und wenn man eine MFC-Anwendung verwendet.
Somit ist mein Problem gelöst! Mit nochmaligem Dank verbleibe ich
mit freundlichen Grüßen
K. H. RendersM. Thaddaeus
- Als Antwort markiert Dimitar DenkovMicrosoft contingent staff, Administrator Mittwoch, 3. Februar 2016 13:37