WinHelp

Eric Pouech eric.pouech at wanadoo.fr
Tue Nov 19 14:01:12 CST 2002


another patch for winhelp
this one should correctly implement the history and back features, as
well as prev/next buttons
read the changelog for all the details

A+
-------------- next part --------------
Name:          wh_nav
ChangeLog:     wrote back & history support
correctly implemented << and >> buttons
added support for page level macros
License:       X11
GenDate:       2002/11/19 19:54:41 UTC
ModifiedFiles: programs/winhelp/hlpfile.c programs/winhelp/hlpfile.h programs/winhelp/macro.c programs/winhelp/string.c programs/winhelp/winhelp.c programs/winhelp/winhelp.h
AddedFiles:    
===================================================================
RCS file: /home/cvs/cvsroot/wine/wine/programs/winhelp/hlpfile.c,v
retrieving revision 1.14
diff -u -u -r1.14 hlpfile.c
--- programs/winhelp/hlpfile.c	18 Nov 2002 19:48:11 -0000	1.14
+++ programs/winhelp/hlpfile.c	19 Nov 2002 17:51:47 -0000
@@ -86,23 +86,6 @@
 
 /***********************************************************************
  *
- *           HLPFILE_Contents
- */
-HLPFILE_PAGE *HLPFILE_Contents(HLPFILE *hlpfile)
-{
-    if (!hlpfile) return 0;
-#if 1
-    return hlpfile->first_page;
-#else
-    if (hlpfile->contents_start) 
-        return HLPFILE_PageByHash(hlpfile, hlpfile->contents_start);
-    else
-        return hlpfile->first_page;
-#endif
-}
-
-/***********************************************************************
- *
  *           HLPFILE_PageByNumber
  */
 HLPFILE_PAGE *HLPFILE_PageByNumber(LPCSTR lpszPath, UINT wNum)
@@ -119,55 +102,82 @@
     return page;
 }
 
-/***********************************************************************
+/* FIXME:
+ * this finds the page containing the offset. The offset can either
+ * refer to the top of the page (offset == page->offset), or
+ * to some paragraph inside the page...
+ * As of today, we only return the page... we should also return
+ * a paragraph, and then, while opening a new page, compute the
+ * y-offset of the paragraph to be shown and scroll the window
+ * accordinly
+ */
+/******************************************************************
+ *		HLPFILE_PageByOffset
+ *
  *
- *           HLPFILE_HlpFilePageByHash
  */
-HLPFILE_PAGE *HLPFILE_PageByHash(HLPFILE* hlpfile, LONG lHash)
+HLPFILE_PAGE *HLPFILE_PageByOffset(HLPFILE* hlpfile, LONG offset)
 {
     HLPFILE_PAGE*       page;
     HLPFILE_PAGE*       found;
-    int                 i;
-
-    WINE_TRACE("path<%s>[%lx]\n", hlpfile->lpszPath, lHash);
 
     if (!hlpfile) return 0;
 
+    WINE_TRACE("<%s>[%lx]\n", hlpfile->lpszPath, offset);
+
+    if (offset == 0xFFFFFFFF) return NULL;
     page = NULL;
-    for (i = 0; i < hlpfile->wContextLen; i++)
+
+    for (found = NULL, page = hlpfile->first_page; page; page = page->next)
     {
-        if (hlpfile->Context[i].lHash != lHash) continue;
+        if (page->offset <= offset && (!found || found->offset < page->offset))
+            found = page;
+    }
+    if (!found)
+        WINE_ERR("Page of offset %lu not found in file %s\n",
+                 offset, hlpfile->lpszPath);
+    return found;
+}
 
-        /* FIXME:
-         * this finds the page containing the offset. The offset can either
-         * refer to the top of the page (offset == page->offset), or
-         * to some paragraph inside the page...
-         * As of today, we only return the page... we should also return
-         * a paragraph, and then, while opening a new page, compute the
-         * y-offset of the paragraph to be shown and scroll the window
-         * accordinly
-         */
-        found = NULL;
-        for (page = hlpfile->first_page; page; page = page->next)
-        {
-            if (page->offset <= hlpfile->Context[i].offset)
-            {
-                if (!found || found->offset < page->offset)
-                    found = page;
-            }
-        }
-        if (found) return found;
+/***********************************************************************
+ *
+ *           HLPFILE_HlpFilePageByHash
+ */
+HLPFILE_PAGE *HLPFILE_PageByHash(HLPFILE* hlpfile, LONG lHash)
+{
+    int                 i;
 
-        WINE_ERR("Page of offset %lu not found in file %s\n",
-                  hlpfile->Context[i].offset, hlpfile->lpszPath);
-        return NULL;
+    if (!hlpfile) return 0;
+
+    WINE_TRACE("<%s>[%lx]\n", hlpfile->lpszPath, lHash);
+
+    for (i = 0; i < hlpfile->wContextLen; i++)
+    {
+        if (hlpfile->Context[i].lHash == lHash)
+            return HLPFILE_PageByOffset(hlpfile, hlpfile->Context[i].offset);
     }
+
     WINE_ERR("Page of hash %lx not found in file %s\n", lHash, hlpfile->lpszPath);
     return NULL;
 }
 
 /***********************************************************************
  *
+ *           HLPFILE_Contents
+ */
+HLPFILE_PAGE* HLPFILE_Contents(HLPFILE *hlpfile)
+{
+    HLPFILE_PAGE*       page = NULL;
+
+    if (!hlpfile) return NULL;
+
+    page = HLPFILE_PageByOffset(hlpfile, hlpfile->contents_start);
+    if (!page) page = hlpfile->first_page;
+    return page;
+}
+
+/***********************************************************************
+ *
  *           HLPFILE_Hash
  */
 LONG HLPFILE_Hash(LPCSTR lpszContext)
@@ -216,7 +226,7 @@
     hlpfile->first_macro        = NULL;
     hlpfile->wContextLen        = 0;
     hlpfile->Context            = NULL;
-    hlpfile->contents_start     = 0;
+    hlpfile->contents_start     = 0xFFFFFFFF;
     hlpfile->prev               = NULL;
     hlpfile->next               = first_hlpfile;
     hlpfile->wRefCount          = 1;
@@ -338,35 +348,37 @@
     HLPFILE_PAGE* page;
     BYTE*         title;
     UINT          titlesize;
+    char*         ptr;
+    HLPFILE_MACRO*macro;
 
     if (buf + 0x31 > end) {WINE_WARN("page1\n"); return FALSE;};
     title = buf + GET_UINT(buf, 0x10);
     if (title > end) {WINE_WARN("page2\n"); return FALSE;};
 
-    titlesize = GET_UINT(buf, 4) + 1;
-    page = HeapAlloc(GetProcessHeap(), 0, sizeof(HLPFILE_PAGE) + titlesize);
+    titlesize = GET_UINT(buf, 4);
+    page = HeapAlloc(GetProcessHeap(), 0, sizeof(HLPFILE_PAGE) + titlesize + 1);
     if (!page) return FALSE;
     page->lpszTitle = (char*)page + sizeof(HLPFILE_PAGE);
 
     if (hlpfile->hasPhrases)
     {
-        HLPFILE_Uncompress2(title, end, page->lpszTitle, page->lpszTitle + titlesize - 1);
+        HLPFILE_Uncompress2(title, end, page->lpszTitle, page->lpszTitle + titlesize);
     }
     else
     {
         if (GET_UINT(buf, 0x4) > GET_UINT(buf, 0) - GET_UINT(buf, 0x10))
         {
             /* need to decompress */
-            HLPFILE_Uncompress3(page->lpszTitle, page->lpszTitle + titlesize - 1, 
+            HLPFILE_Uncompress3(page->lpszTitle, page->lpszTitle + titlesize, 
                                 title, end);
         }
         else
         {
-            memcpy(page->lpszTitle, title, titlesize - 1);
+            memcpy(page->lpszTitle, title, titlesize);
         }
     }
 
-    page->lpszTitle[titlesize - 1] = 0;
+    page->lpszTitle[titlesize] = '\0';
 
     if (hlpfile->first_page)
     {
@@ -385,14 +397,36 @@
     page->file            = hlpfile;
     page->next            = NULL;
     page->first_paragraph = NULL;
+    page->first_macro     = NULL;
     page->wNumber         = GET_UINT(buf, 0x21);
     page->offset          = offset;
 
-    WINE_TRACE("Added page[%d]: title='%s' offset=%08x\n",
-               page->wNumber, page->lpszTitle, page->offset);
+    page->browse_bwd = GET_UINT(buf, 0x19);
+    page->browse_fwd = GET_UINT(buf, 0x1D);
+
+    WINE_TRACE("Added page[%d]: title='%s' %08lx << %08x >> %08lx\n",
+               page->wNumber, page->lpszTitle, 
+               page->browse_bwd, page->offset, page->browse_fwd);
 
     memset(&attributes, 0, sizeof(attributes));
 
+    /* now load macros */
+    ptr = page->lpszTitle + strlen(page->lpszTitle) + 1;
+    while (ptr < page->lpszTitle + titlesize)
+    {
+        unsigned len = strlen(ptr);
+        WINE_TRACE("macro: %s\n", ptr);
+        macro = HeapAlloc(GetProcessHeap(), 0, sizeof(HLPFILE_MACRO) + len + 1);
+        macro->lpszMacro = (char*)(macro + 1);
+        memcpy((char*)macro->lpszMacro, ptr, len + 1);
+        /* FIXME: shall we really link macro in reverse order ??
+         * may produce strange results when played at page opening
+         */
+        macro->next = page->first_macro;
+        page->first_macro = macro;
+        ptr += len + 1;
+    }
+
     return TRUE;
 }
 
@@ -1764,34 +1802,35 @@
 
 /***********************************************************************
  *
- *           DeletePage
+ *           DeleteMacro
  */
-static void HLPFILE_DeletePage(HLPFILE_PAGE* page)
+static void HLPFILE_DeleteMacro(HLPFILE_MACRO* macro)
 {
-    HLPFILE_PAGE* next;
+    HLPFILE_MACRO*      next;
 
-    while (page)
+    while (macro)
     {
-        next = page->next;
-        HLPFILE_DeleteParagraph(page->first_paragraph);
-        HeapFree(GetProcessHeap(), 0, page);
-        page = next;
+        next = macro->next;
+        HeapFree(GetProcessHeap(), 0, macro);
+        macro = next;
     }
 }
 
 /***********************************************************************
  *
- *           DeleteMacro
+ *           DeletePage
  */
-static void HLPFILE_DeleteMacro(HLPFILE_MACRO* macro)
+static void HLPFILE_DeletePage(HLPFILE_PAGE* page)
 {
-    HLPFILE_MACRO*      next;
+    HLPFILE_PAGE* next;
 
-    while (macro)
+    while (page)
     {
-        next = macro->next;
-        HeapFree(GetProcessHeap(), 0, macro);
-        macro = next;
+        next = page->next;
+        HLPFILE_DeleteParagraph(page->first_paragraph);
+        HLPFILE_DeleteMacro(page->first_macro);
+        HeapFree(GetProcessHeap(), 0, page);
+        page = next;
     }
 }
 
@@ -1837,12 +1876,3 @@
     HeapFree(GetProcessHeap(), 0, hlpfile);
 }
 
-/***********************************************************************
- *
- *           FreeHlpFilePage
- */
-void HLPFILE_FreeHlpFilePage(HLPFILE_PAGE* page)
-{
-    if (!page) return;
-    HLPFILE_FreeHlpFile(page->file);
-}
Index: programs/winhelp/hlpfile.h
===================================================================
RCS file: /home/cvs/cvsroot/wine/wine/programs/winhelp/hlpfile.h,v
retrieving revision 1.6
diff -u -u -r1.6 hlpfile.h
--- programs/winhelp/hlpfile.h	18 Nov 2002 19:48:11 -0000	1.6
+++ programs/winhelp/hlpfile.h	19 Nov 2002 07:54:31 -0000
@@ -71,15 +71,26 @@
     struct tagHlpFileParagraph* next;
 } HLPFILE_PARAGRAPH;
 
+typedef struct tagHlpFileMacro
+{
+    LPCSTR                      lpszMacro;
+    struct tagHlpFileMacro*     next;
+} HLPFILE_MACRO;
+
 typedef struct tagHlpFilePage
 {
     LPSTR                       lpszTitle;
     HLPFILE_PARAGRAPH*          first_paragraph;
+    HLPFILE_MACRO*              first_macro;
 
     unsigned                    wNumber;
     unsigned                    offset;
     struct tagHlpFilePage*      next;
     struct tagHlpFilePage*      prev;
+
+    DWORD                       browse_bwd;
+    DWORD                       browse_fwd;
+
     struct tagHlpFileFile*      file;
 } HLPFILE_PAGE;
 
@@ -89,12 +100,6 @@
     unsigned long               offset;
 } HLPFILE_CONTEXT;
 
-typedef struct tagHlpFileMacro
-{
-    LPCSTR                      lpszMacro;
-    struct tagHlpFileMacro*     next;
-} HLPFILE_MACRO;
-
 typedef struct
 {
     LOGFONT                     LogFont;
@@ -132,9 +137,9 @@
     HLPFILE_WINDOWINFO*         windows;
 } HLPFILE;
 
-HLPFILE      *HLPFILE_ReadHlpFile(LPCSTR lpszPath);
-HLPFILE_PAGE *HLPFILE_Contents(HLPFILE* hlpfile);
-HLPFILE_PAGE *HLPFILE_PageByHash(HLPFILE* hlpfile, LONG wNum);
+HLPFILE*      HLPFILE_ReadHlpFile(LPCSTR lpszPath);
+HLPFILE_PAGE* HLPFILE_Contents(HLPFILE* hlpfile);
+HLPFILE_PAGE* HLPFILE_PageByHash(HLPFILE* hlpfile, LONG lHash);
+HLPFILE_PAGE* HLPFILE_PageByOffset(HLPFILE* hlpfile, LONG offset);
 LONG          HLPFILE_Hash(LPCSTR lpszContext);
-VOID          HLPFILE_FreeHlpFilePage(HLPFILE_PAGE*);
-VOID          HLPFILE_FreeHlpFile(HLPFILE*);
+void          HLPFILE_FreeHlpFile(HLPFILE*);
Index: programs/winhelp/macro.c
===================================================================
RCS file: /home/cvs/cvsroot/wine/wine/programs/winhelp/macro.c,v
retrieving revision 1.15
diff -u -u -r1.15 macro.c
--- programs/winhelp/macro.c	18 Nov 2002 19:48:11 -0000	1.15
+++ programs/winhelp/macro.c	19 Nov 2002 07:55:46 -0000
@@ -222,12 +222,32 @@
 
 void MACRO_Back(void)
 {
-    WINE_FIXME("()\n");
+    WINHELP_WINDOW* win = Globals.active_win;
+
+    WINE_TRACE("()\n");
+
+    if (win && win->backIndex >= 2)
+        WINHELP_CreateHelpWindow(win->back[--win->backIndex - 1],
+                                 win->info, SW_SHOW);
 }
 
 void MACRO_BackFlush(void)
 {
-    WINE_FIXME("()\n");
+    WINHELP_WINDOW* win = Globals.active_win;
+
+    WINE_TRACE("()\n");
+
+    if (win)
+    {
+        int     i;
+
+        for (i = 0; i < win->backIndex; i++)
+        {
+            HLPFILE_FreeHlpFile(win->back[i]->file);
+            win->back[i] = NULL;
+        }
+        win->backIndex = 0;
+    }
 }
 
 void MACRO_BookmarkDefine(void)
@@ -599,7 +619,14 @@
 
 void MACRO_History(void)
 {
-    WINE_FIXME("()\n");
+    WINE_TRACE("()\n");
+
+    if (Globals.active_win && !Globals.active_win->hHistoryWnd)
+    {
+        HWND hWnd = CreateWindow(HISTORY_WIN_CLASS_NAME, "History", WS_OVERLAPPEDWINDOW,
+                                 0, 0, 0, 0, 0, 0, Globals.hInstance, Globals.active_win);
+        ShowWindow(hWnd, SW_NORMAL);
+    }
 }
 
 void MACRO_IfThen(BOOL b, LPCSTR t)
@@ -717,7 +744,9 @@
     HLPFILE_PAGE*   page;
 
     WINE_TRACE("()\n");
-    if ((page = Globals.active_win->page->next) != NULL)
+    page = Globals.active_win->page;
+    page = HLPFILE_PageByOffset(page->file, page->browse_fwd);
+    if (page)
     {
         page->file->wRefCount++;
         WINHELP_CreateHelpWindow(page, Globals.active_win->info, SW_NORMAL);
@@ -754,7 +783,9 @@
     HLPFILE_PAGE*   page;
 
     WINE_TRACE("()\n");
-    if ((page = Globals.active_win->page->prev) != NULL)
+    page = Globals.active_win->page;
+    page = HLPFILE_PageByOffset(page->file, page->browse_bwd);
+    if (page)
     {
         page->file->wRefCount++;
         WINHELP_CreateHelpWindow(page, Globals.active_win->info, SW_NORMAL);
Index: programs/winhelp/string.c
===================================================================
RCS file: /home/cvs/cvsroot/wine/wine/programs/winhelp/string.c,v
retrieving revision 1.4
diff -u -u -r1.4 string.c
--- programs/winhelp/string.c	11 Nov 2002 22:20:47 -0000	1.4
+++ programs/winhelp/string.c	17 Nov 2002 20:54:59 -0000
@@ -24,6 +24,7 @@
 char BUTTON_BOX_WIN_CLASS_NAME[] = "WHButtonBox";
 char TEXT_WIN_CLASS_NAME[]       = "WHText";
 char SHADOW_WIN_CLASS_NAME[]     = "WHShadow";
+char HISTORY_WIN_CLASS_NAME[]    = "WHHistory";
 char STRING_BUTTON[]             = "BUTTON";
 
 /* Resource names */
Index: programs/winhelp/winhelp.c
===================================================================
RCS file: /home/cvs/cvsroot/wine/wine/programs/winhelp/winhelp.c,v
retrieving revision 1.21
diff -u -u -r1.21 winhelp.c
--- programs/winhelp/winhelp.c	18 Nov 2002 19:48:11 -0000	1.21
+++ programs/winhelp/winhelp.c	19 Nov 2002 19:53:08 -0000
@@ -38,6 +38,7 @@
 static LRESULT CALLBACK WINHELP_MainWndProc(HWND, UINT, WPARAM, LPARAM);
 static LRESULT CALLBACK WINHELP_TextWndProc(HWND, UINT, WPARAM, LPARAM);
 static LRESULT CALLBACK WINHELP_ButtonBoxWndProc(HWND, UINT, WPARAM, LPARAM);
+static LRESULT CALLBACK WINHELP_HistoryWndProc(HWND, UINT, WPARAM, LPARAM);
 static void    WINHELP_CheckPopup(UINT);
 static BOOL    WINHELP_SplitLines(HWND hWnd, LPSIZE);
 static void    WINHELP_InitFonts(HWND hWnd);
@@ -104,9 +105,9 @@
     {
         strcpy(mwi.type, "primary");
         strcpy(mwi.name, "main");
-        LoadString(Globals.hInstance, STID_WINE_HELP, 
-                   mwi.caption, sizeof(mwi.caption));
-        /*strcpy(mwi.caption, hlpfile->lpszTitle); */
+        if (!LoadString(Globals.hInstance, STID_WINE_HELP, 
+                        mwi.caption, sizeof(mwi.caption)))
+            strcpy(mwi.caption, hlpfile->lpszTitle);
         mwi.origin.x = mwi.origin.y = mwi.size.cx = mwi.size.cy = CW_USEDEFAULT;
         mwi.style = SW_SHOW;
         mwi.sr_color = mwi.sr_color = 0xFFFFFF;
@@ -214,7 +215,7 @@
  */
 static BOOL WINHELP_RegisterWinClasses(void)
 {
-    WNDCLASS class_main, class_button_box, class_text, class_shadow;
+    WNDCLASS class_main, class_button_box, class_text, class_shadow, class_history;
 
     class_main.style               = CS_HREDRAW | CS_VREDRAW;
     class_main.lpfnWndProc         = WINHELP_MainWndProc;
@@ -241,10 +242,15 @@
     class_shadow.hbrBackground     = GetStockObject(GRAY_BRUSH);
     class_shadow.lpszClassName     = SHADOW_WIN_CLASS_NAME;
 
+    class_history = class_main;
+    class_history.lpfnWndProc      = WINHELP_HistoryWndProc;
+    class_history.lpszClassName    = HISTORY_WIN_CLASS_NAME;
+
     return (RegisterClass(&class_main) &&
             RegisterClass(&class_button_box) &&
             RegisterClass(&class_text) &&
-            RegisterClass(&class_shadow));
+            RegisterClass(&class_shadow) &&
+            RegisterClass(&class_history));
 }
 
 typedef struct
@@ -310,6 +316,96 @@
     return 0L;
 }
 
+/******************************************************************
+ *		WINHELP_ReuseWindow
+ *
+ *
+ */
+static BOOL     WINHELP_ReuseWindow(WINHELP_WINDOW* win, WINHELP_WINDOW* oldwin, 
+                                    HLPFILE_PAGE* page, int nCmdShow)
+{
+    int                 i;
+
+    win->hMainWnd      = oldwin->hMainWnd;
+    win->hButtonBoxWnd = oldwin->hButtonBoxWnd;
+    win->hTextWnd      = oldwin->hTextWnd;
+    win->hHistoryWnd   = oldwin->hHistoryWnd;
+    oldwin->hMainWnd = oldwin->hButtonBoxWnd = oldwin->hTextWnd = oldwin->hHistoryWnd = 0;
+
+    SetWindowLong(win->hMainWnd,      0, (LONG)win);
+    SetWindowLong(win->hButtonBoxWnd, 0, (LONG)win);
+    SetWindowLong(win->hTextWnd,      0, (LONG)win);
+    SetWindowLong(win->hHistoryWnd,   0, (LONG)win);
+
+    WINHELP_InitFonts(win->hMainWnd);
+
+    if (page)
+        SetWindowText(win->hMainWnd, page->file->lpszTitle);
+
+    WINHELP_SetupText(win->hTextWnd);
+    InvalidateRect(win->hTextWnd, NULL, TRUE);
+    SendMessage(win->hMainWnd, WM_USER, 0, 0);
+    ShowWindow(win->hMainWnd, nCmdShow);
+    UpdateWindow(win->hTextWnd);
+
+    if (!(win->info->win_style & WS_POPUP))
+    {
+        unsigned        num;
+
+        memcpy(win->history, oldwin->history, sizeof(win->history));
+        win->histIndex = oldwin->histIndex;
+
+        /* FIXME: when using back, we shouldn't update the history... */
+
+        if (page)
+        {
+            for (i = 0; i < win->histIndex; i++)
+                if (win->history[i] == page) break;
+
+            /* if the new page is already in the history, do nothing */
+            if (i == win->histIndex)
+            {
+                num = sizeof(win->history) / sizeof(win->history[0]);
+                if (win->histIndex == num)
+                {
+                    /* we're full, remove latest entry */
+                    HLPFILE_FreeHlpFile(win->history[0]->file);
+                    memmove(&win->history[0], &win->history[1], 
+                            (num - 1) * sizeof(win->history[0]));
+                    win->histIndex--;
+                }
+                win->history[win->histIndex++] = page;
+                page->file->wRefCount++;
+                if (win->hHistoryWnd) InvalidateRect(win->hHistoryWnd, NULL, TRUE);
+            }
+        }
+
+        memcpy(win->back, oldwin->back, sizeof(win->back));
+        win->backIndex = oldwin->backIndex;
+
+        if (page)
+        {
+            num = sizeof(win->back) / sizeof(win->back[0]);
+            if (win->backIndex == num)
+            {
+                /* we're full, remove latest entry */
+                HLPFILE_FreeHlpFile(win->back[0]->file);
+                memmove(&win->back[0], &win->back[1], 
+                        (num - 1) * sizeof(win->back[0]));
+                win->backIndex--;
+            }
+            win->back[win->backIndex++] = page;
+            page->file->wRefCount++;
+        }
+    }
+    else
+        win->backIndex = win->histIndex = 0;
+
+    oldwin->histIndex = oldwin->backIndex = 0;
+    WINHELP_DeleteWindow(oldwin);
+    return TRUE;
+}
+
 /***********************************************************************
  *
  *           WINHELP_CreateHelpWindow
@@ -320,8 +416,10 @@
     WINHELP_WINDOW *win, *oldwin;
     HWND hWnd;
     BOOL bPrimary;
+    BOOL bPopup;
 
     bPrimary = !lstrcmpi(wi->name, "main");
+    bPopup = wi->win_style & WS_POPUP;
 
     /* Initialize WINHELP_WINDOW struct */
     win = HeapAlloc(GetProcessHeap(), 0,
@@ -341,6 +439,7 @@
     win->hButtonBoxWnd = 0;
     win->hTextWnd = 0;
     win->hShadowWnd = 0;
+    win->hHistoryWnd = 0;
 
     win->hArrowCur = LoadCursorA(0, IDC_ARROWA);
     win->hHandCur = LoadCursorA(0, IDC_HANDA);
@@ -372,49 +471,30 @@
         HLPFILE_MACRO  *macro;
         for (macro = page->file->first_macro; macro; macro = macro->next)
             MACRO_ExecuteMacro(macro->lpszMacro);
+
+        for (macro = page->first_macro; macro; macro = macro->next)
+            MACRO_ExecuteMacro(macro->lpszMacro);
     }
 
     /* Reuse existing window */
-    if (!(wi->win_style & WS_POPUP))
+    if (!bPopup)
     {
         for (oldwin = win->next; oldwin; oldwin = oldwin->next)
         {
             if (!lstrcmpi(oldwin->lpszName, wi->name))
             {
-                WINHELP_BUTTON *button;
-
-                win->hMainWnd      = oldwin->hMainWnd;
-                win->hButtonBoxWnd = oldwin->hButtonBoxWnd;
-                win->hTextWnd      = oldwin->hTextWnd;
-                oldwin->hMainWnd = oldwin->hButtonBoxWnd = oldwin->hTextWnd = 0;
-
-                SetWindowLong(win->hMainWnd,      0, (LONG)win);
-                SetWindowLong(win->hButtonBoxWnd, 0, (LONG)win);
-                SetWindowLong(win->hTextWnd,      0, (LONG)win);
-
-                WINHELP_InitFonts(win->hMainWnd);
-
-                if (page) {
-                    SetWindowText(win->hMainWnd, page->file->lpszTitle);
-                }
-
-                WINHELP_SetupText(win->hTextWnd);
-                InvalidateRect(win->hTextWnd, NULL, TRUE);
-                SendMessage(win->hMainWnd, WM_USER, 0, 0);
-                ShowWindow(win->hMainWnd, nCmdShow);
-                UpdateWindow(win->hTextWnd);
-
-
-                for (button = oldwin->first_button; button; button = button->next)
-                    DestroyWindow(button->hWnd);
-
-                WINHELP_DeleteWindow(oldwin);
-                return TRUE;
+                return WINHELP_ReuseWindow(win, oldwin, page, nCmdShow);
             }
         }
+
+        win->histIndex = win->backIndex = 1;
+        win->history[0] = win->back[0] = page;
+        page->file->wRefCount += 2;
     }
+    else
+        win->histIndex = win->backIndex = 0;
 
-    hWnd = CreateWindow((wi->win_style & WS_POPUP) ? TEXT_WIN_CLASS_NAME : MAIN_WIN_CLASS_NAME,
+    hWnd = CreateWindow(bPopup ? TEXT_WIN_CLASS_NAME : MAIN_WIN_CLASS_NAME,
                         wi->caption, wi->win_style,
                         wi->origin.x, wi->origin.y, wi->size.cx, wi->size.cy,
                         0, bPrimary ? LoadMenu(Globals.hInstance, MAKEINTRESOURCE(MAIN_MENU)) : 0,
@@ -854,7 +934,6 @@
         win = (WINHELP_WINDOW*) GetWindowLong(hWnd, 0);
 
         if (hWnd == Globals.hPopupWnd) Globals.hPopupWnd = 0;
-        if (win->hShadowWnd) DestroyWindow(win->hShadowWnd);
 
         bExit = (Globals.wVersion >= 4 && !lstrcmpi(win->lpszName, "main"));
 
@@ -870,6 +949,72 @@
     return DefWindowProc(hWnd, msg, wParam, lParam);
 }
 
+/******************************************************************
+ *		WINHELP_HistoryWndProc
+ *
+ *
+ */
+static LRESULT CALLBACK WINHELP_HistoryWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+    WINHELP_WINDOW*     win;
+    PAINTSTRUCT         ps;
+    HDC                 hDc;
+    TEXTMETRIC          tm;
+    int                 i;
+    RECT                r;
+
+    switch (msg)
+    {
+    case WM_NCCREATE:
+        win = (WINHELP_WINDOW*)((LPCREATESTRUCT)lParam)->lpCreateParams;
+        SetWindowLong(hWnd, 0, (LONG)win);
+        win->hHistoryWnd = hWnd;
+        break;
+    case WM_CREATE:
+        win = (WINHELP_WINDOW*) GetWindowLong(hWnd, 0);
+        hDc = GetDC(hWnd);
+        GetTextMetrics(hDc, &tm);
+        GetWindowRect(hWnd, &r);
+
+        r.right = r.left + 30 * tm.tmAveCharWidth;
+        r.bottom = r.top + (sizeof(win->history) / sizeof(win->history[0])) * tm.tmHeight;
+        AdjustWindowRect(&r, GetWindowLong(hWnd, GWL_STYLE), FALSE);
+        if (r.left < 0) {r.right -= r.left; r.left = 0;}
+        if (r.top < 0) {r.bottom -= r.top; r.top = 0;}
+
+        MoveWindow(hWnd, r.left, r.top, r.right, r.bottom, TRUE);
+        ReleaseDC(hWnd, hDc);
+        break;
+    case WM_LBUTTONDOWN:
+        win = (WINHELP_WINDOW*) GetWindowLong(hWnd, 0);
+        hDc = GetDC(hWnd);
+        GetTextMetrics(hDc, &tm);
+        i = HIWORD(lParam) / tm.tmHeight;
+        if (i < win->histIndex)
+            WINHELP_CreateHelpWindow(win->history[i], win->info, SW_SHOW);
+        ReleaseDC(hWnd, hDc);
+        break;
+    case WM_PAINT:
+        hDc = BeginPaint(hWnd, &ps);
+        win = (WINHELP_WINDOW*) GetWindowLong(hWnd, 0);
+        GetTextMetrics(hDc, &tm);
+
+        for (i = 0; i < win->histIndex; i++)
+        {
+            TextOut(hDc, 0, i * tm.tmHeight, win->history[i]->lpszTitle, 
+                    strlen(win->history[i]->lpszTitle));
+        }
+        EndPaint(hWnd, &ps);
+        break;
+    case WM_DESTROY:
+        win = (WINHELP_WINDOW*) GetWindowLong(hWnd, 0);
+        if (hWnd == win->hHistoryWnd)
+            win->hHistoryWnd = 0;
+        break;
+    }
+    return DefWindowProc(hWnd, msg, wParam, lParam);
+}
+
 /***********************************************************************
  *
  *           SetupText
@@ -1315,19 +1460,41 @@
  *
  *           WINHELP_DeleteWindow
  */
-static void WINHELP_DeleteWindow(WINHELP_WINDOW *win)
+static void WINHELP_DeleteWindow(WINHELP_WINDOW* win)
 {
-    WINHELP_WINDOW **w;
+    WINHELP_WINDOW**    w;
+    int                 i;
+    WINHELP_BUTTON*     b;
+    WINHELP_BUTTON*     bp;
 
     for (w = &Globals.win_list; *w; w = &(*w)->next)
+    {
         if (*w == win)
         {
             *w = win->next;
             break;
         }
+    }
+
+    for (b = win->first_button; b; b = bp)
+    {
+        DestroyWindow(b->hWnd);
+        bp = b->next;
+        HeapFree(GetProcessHeap(), 0, b);
+    }
 
     if (win->hShadowWnd) DestroyWindow(win->hShadowWnd);
-    HLPFILE_FreeHlpFilePage(win->page);
+    if (win->hHistoryWnd) DestroyWindow(win->hHistoryWnd);
+
+    for (i = 0; i < win->histIndex; i++)
+    {
+        HLPFILE_FreeHlpFile(win->history[i]->file);
+    }
+
+    for (i = 0; i < win->backIndex; i++)
+        HLPFILE_FreeHlpFile(win->back[i]->file);
+
+    if (win->page) HLPFILE_FreeHlpFile(win->page->file);
     WINHELP_DeleteLines(win);
     HeapFree(GetProcessHeap(), 0, win);
 }
@@ -1359,7 +1526,7 @@
     {
         INT i;
 
-        for(i = 0; i < FONTS_LEN; i++)
+        for (i = 0; i < FONTS_LEN; i++)
 	{
             fonts[i] = CreateFontIndirect(&logfontlist[i]);
 	}
Index: programs/winhelp/winhelp.h
===================================================================
RCS file: /home/cvs/cvsroot/wine/wine/programs/winhelp/winhelp.h,v
retrieving revision 1.8
diff -u -u -r1.8 winhelp.h
--- programs/winhelp/winhelp.h	18 Nov 2002 19:48:11 -0000	1.8
+++ programs/winhelp/winhelp.h	19 Nov 2002 07:58:15 -0000
@@ -95,6 +95,7 @@
     HWND                hButtonBoxWnd;
     HWND                hTextWnd;
     HWND                hShadowWnd;
+    HWND                hHistoryWnd;
 
     HFONT*              fonts;
     UINT                fonts_len;
@@ -104,6 +105,12 @@
 
     HLPFILE_WINDOWINFO* info;
 
+    /* FIXME: for now it's a fixed size */
+    HLPFILE_PAGE*       history[40];
+    unsigned            histIndex;
+    HLPFILE_PAGE*       back[40];
+    unsigned            backIndex;
+
     struct tagWinHelp*  next;
 } WINHELP_WINDOW;
 
@@ -131,6 +138,7 @@
 extern char BUTTON_BOX_WIN_CLASS_NAME[];
 extern char TEXT_WIN_CLASS_NAME[];
 extern char SHADOW_WIN_CLASS_NAME[];
+extern char HISTORY_WIN_CLASS_NAME[];
 extern char STRING_BUTTON[];
 extern char STRING_MENU_Xx[];
 extern char STRING_DIALOG_TEST[];


More information about the wine-patches mailing list