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+
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[];