diff --git a/dlls/hhctrl.ocx/chm.c b/dlls/hhctrl.ocx/chm.c
index f051feb57ab..cc92b89425e 100644
--- a/dlls/hhctrl.ocx/chm.c
+++ b/dlls/hhctrl.ocx/chm.c
@@ -20,6 +20,7 @@
*/
#include "hhctrl.h"
+#include "stream.h"
#include "winreg.h"
#include "shlwapi.h"
@@ -27,10 +28,6 @@
WINE_DEFAULT_DEBUG_CHANNEL(htmlhelp);
-#define BLOCK_BITS 12
-#define BLOCK_SIZE (1 << BLOCK_BITS)
-#define BLOCK_MASK (BLOCK_SIZE-1)
-
/* Reads a string from the #STRINGS section in the CHM file */
static LPCSTR GetChmString(CHMInfo *chm, DWORD offset)
{
@@ -413,6 +410,62 @@ IStream *GetChmStream(CHMInfo *info, LPCWSTR parent_chm, ChmPath *chm_file)
return stream;
}
+/*
+ * Retrieve a CHM document and parse the data from the
element to get the document's title.
+ */
+WCHAR *GetDocumentTitle(CHMInfo *info, LPCWSTR document)
+{
+ strbuf_t node, node_name, content;
+ WCHAR *document_title = NULL;
+ IStream *str = NULL;
+ IStorage *storage;
+ stream_t stream;
+ HRESULT hres;
+
+ TRACE("%s\n", debugstr_w(document));
+
+ storage = info->pStorage;
+ if(!storage) {
+ WARN("Could not open storage to obtain the title for a document.\n");
+ return NULL;
+ }
+ IStorage_AddRef(storage);
+
+ hres = IStorage_OpenStream(storage, document, NULL, STGM_READ, 0, &str);
+ IStorage_Release(storage);
+ if(FAILED(hres))
+ WARN("Could not open stream: %08x\n", hres);
+
+ stream_init(&stream, str);
+ strbuf_init(&node);
+ strbuf_init(&content);
+ strbuf_init(&node_name);
+
+ while(next_node(&stream, &node)) {
+ get_node_name(&node, &node_name);
+
+ TRACE("%s\n", node.buf);
+
+ if(!strcasecmp(node_name.buf, "title")) {
+ if(next_content(&stream, &content) && content.len > 1)
+ {
+ document_title = strdupnAtoW(&content.buf[1], content.len-1);
+ FIXME("magic: %s\n", debugstr_w(document_title));
+ break;
+ }
+ }
+
+ strbuf_zero(&node);
+ }
+
+ strbuf_free(&node);
+ strbuf_free(&content);
+ strbuf_free(&node_name);
+ IStream_Release(str);
+
+ return document_title;
+}
+
/* Opens the CHM file for reading */
CHMInfo *OpenCHM(LPCWSTR szFile)
{
diff --git a/dlls/hhctrl.ocx/help.c b/dlls/hhctrl.ocx/help.c
index 3acb024d299..87ea94fc41e 100644
--- a/dlls/hhctrl.ocx/help.c
+++ b/dlls/hhctrl.ocx/help.c
@@ -634,6 +634,8 @@ static LRESULT OnTopicChange(HHInfo *info, void *user_data)
IndexSubItem *item = &iiter->items[i];
WCHAR *name = iiter->keyword;
+ if(!item->name)
+ item->name = GetDocumentTitle(info->pCHMInfo, item->local);
if(item->name)
name = item->name;
memset(&lvi, 0, sizeof(lvi));
diff --git a/dlls/hhctrl.ocx/hhctrl.h b/dlls/hhctrl.ocx/hhctrl.h
index eea7f7f982b..8959748e28c 100644
--- a/dlls/hhctrl.ocx/hhctrl.h
+++ b/dlls/hhctrl.ocx/hhctrl.h
@@ -189,6 +189,7 @@ CHMInfo *CloseCHM(CHMInfo *pCHMInfo) DECLSPEC_HIDDEN;
void SetChmPath(ChmPath*,LPCWSTR,LPCWSTR) DECLSPEC_HIDDEN;
IStream *GetChmStream(CHMInfo*,LPCWSTR,ChmPath*) DECLSPEC_HIDDEN;
LPWSTR FindContextAlias(CHMInfo*,DWORD) DECLSPEC_HIDDEN;
+WCHAR *GetDocumentTitle(CHMInfo*,LPCWSTR) DECLSPEC_HIDDEN;
HHInfo *CreateHelpViewer(LPCWSTR) DECLSPEC_HIDDEN;
void ReleaseHelpViewer(HHInfo*) DECLSPEC_HIDDEN;
diff --git a/dlls/hhctrl.ocx/stream.h b/dlls/hhctrl.ocx/stream.h
index 524109f58ac..8d61ad54d51 100644
--- a/dlls/hhctrl.ocx/stream.h
+++ b/dlls/hhctrl.ocx/stream.h
@@ -19,7 +19,9 @@
#ifndef HHCTRL_STREAM_H
#define HHCTRL_STREAM_H
-#define BLOCK_SIZE 0x1000
+#define BLOCK_BITS 12
+#define BLOCK_SIZE (1 << BLOCK_BITS)
+#define BLOCK_MASK (BLOCK_SIZE-1)
typedef struct {
char *buf;