From 7d75cfed7634a83d5ef1578c3876a40432d20e80 Mon Sep 17 00:00:00 2001 From: Eric Pouech Date: Mon, 18 Nov 2002 19:48:11 +0000 Subject: [PATCH] Added support for window information from the .hlp file. Added support for window numbers in link. --- programs/winhelp/hlpfile.c | 65 ++++++++-- programs/winhelp/hlpfile.h | 23 +++- programs/winhelp/macro.c | 39 +++++- programs/winhelp/winhelp.c | 260 ++++++++++++++++++++++--------------- programs/winhelp/winhelp.h | 10 +- 5 files changed, 268 insertions(+), 129 deletions(-) diff --git a/programs/winhelp/hlpfile.c b/programs/winhelp/hlpfile.c index ef16b371151..ea53270363d 100644 --- a/programs/winhelp/hlpfile.c +++ b/programs/winhelp/hlpfile.c @@ -227,6 +227,9 @@ HLPFILE *HLPFILE_ReadHlpFile(LPCSTR lpszPath) hlpfile->numFonts = 0; hlpfile->fonts = NULL; + hlpfile->numWindows = 0; + hlpfile->windows = NULL; + strcpy(hlpfile->lpszPath, lpszPath); first_hlpfile = hlpfile; @@ -800,21 +803,20 @@ static BOOL HLPFILE_AddParagraph(HLPFILE *hlpfile, BYTE *buf, BYTE *end, unsigne strcpy((char*)paragraph->link->lpszString, attributes.link.lpszString); paragraph->link->lHash = attributes.link.lHash; paragraph->link->bClrChange = attributes.link.bClrChange; + paragraph->link->window = attributes.link.window; - WINE_TRACE("Link[%d] to %s@%08lx\n", - paragraph->link->cookie, paragraph->link->lpszString, paragraph->link->lHash); + WINE_TRACE("Link[%d] to %s@%08lx:%d\n", + paragraph->link->cookie, paragraph->link->lpszString, + paragraph->link->lHash, paragraph->link->window); } -#if 0 - memset(&attributes, 0, sizeof(attributes)); -#else attributes.hBitmap = 0; attributes.link.lpszString = NULL; attributes.link.bClrChange = FALSE; attributes.link.lHash = 0; + attributes.link.window = -1; attributes.wVSpace = 0; attributes.wHSpace = 0; attributes.wIndent = 0; -#endif } /* else: null text, keep on storing attributes */ text += textsize; @@ -969,7 +971,7 @@ static BOOL HLPFILE_AddParagraph(HLPFILE *hlpfile, BYTE *buf, BYTE *end, unsigne attributes.link.bClrChange = !(*format & 1); if (type == 1) - {WINE_FIXME("Unsupported wnd number %d for link\n", *ptr); ptr++;} + attributes.link.window = *ptr++; if (type == 4 || type == 6) { attributes.link.lpszString = ptr; @@ -978,7 +980,20 @@ static BOOL HLPFILE_AddParagraph(HLPFILE *hlpfile, BYTE *buf, BYTE *end, unsigne else attributes.link.lpszString = hlpfile->lpszPath; if (type == 6) - WINE_FIXME("Unsupported wnd name '%s' for link\n", ptr); + { + int i; + + for (i = 0; i < hlpfile->numWindows; i++) + { + if (!strcmp(ptr, hlpfile->windows[i].name)) + { + attributes.link.window = i; + break; + } + } + if (attributes.link.window == -1) + WINE_WARN("Couldn't find window info for %s\n", ptr); + } } format += 3 + GET_USHORT(format, 1); break; @@ -1257,10 +1272,35 @@ static BOOL HLPFILE_SystemCommands(HLPFILE* hlpfile) case 6: if (GET_USHORT(ptr, 2) != 90) {WINE_WARN("system6\n");break;} - WINE_FIXME("System-Window: flags=%4x type=%s name=%s caption=%s (%d,%d)x(%d,%d)\n", - GET_USHORT(ptr, 4), ptr + 6, ptr + 16, ptr + 25, - GET_SHORT(ptr, 76), GET_USHORT(ptr, 78), - GET_SHORT(ptr, 80), GET_USHORT(ptr, 82)); + hlpfile->windows = HeapReAlloc(GetProcessHeap(), 0, hlpfile->windows, + sizeof(HLPFILE_WINDOWINFO) * ++hlpfile->numWindows); + if (hlpfile->windows) + { + unsigned flags = GET_USHORT(ptr, 4); + HLPFILE_WINDOWINFO* wi = &hlpfile->windows[hlpfile->numWindows - 1]; + + if (flags & 0x0001) strcpy(wi->type, ptr + 6); else wi->type[0] = '\0'; + if (flags & 0x0002) strcpy(wi->name, ptr + 16); else wi->name[0] = '\0'; + if (flags & 0x0004) strcpy(wi->caption, ptr + 25); else strncpy(wi->caption, hlpfile->lpszTitle, sizeof(wi->caption)); + wi->origin.x = (flags & 0x0008) ? GET_USHORT(ptr, 76) : CW_USEDEFAULT; + wi->origin.y = (flags & 0x0010) ? GET_USHORT(ptr, 78) : CW_USEDEFAULT; + wi->size.cx = (flags & 0x0020) ? GET_USHORT(ptr, 80) : CW_USEDEFAULT; + wi->size.cy = (flags & 0x0040) ? GET_USHORT(ptr, 82) : CW_USEDEFAULT; + wi->style = (flags & 0x0080) ? GET_USHORT(ptr, 84) : SW_SHOW; + wi->sr_color = (flags & 0x0100) ? GET_UINT(ptr, 86) : 0xFFFFFF; + wi->nsr_color = (flags & 0x0200) ? GET_UINT(ptr, 90) : 0xFFFFFF; + WINE_FIXME("System-Window: flags=%c%c%c%c%c%c%c%c type=%s name=%s caption=%s (%ld,%ld)x(%ld,%ld)\n", + flags & 0x0001 ? 'T' : 't', + flags & 0x0002 ? 'N' : 'n', + flags & 0x0004 ? 'C' : 'c', + flags & 0x0008 ? 'X' : 'x', + flags & 0x0010 ? 'Y' : 'y', + flags & 0x0020 ? 'W' : 'w', + flags & 0x0040 ? 'H' : 'h', + flags & 0x0080 ? 'S' : 's', + wi->type, wi->name, wi->caption, wi->origin.x, wi->origin.y, + wi->size.cx, wi->size.cy); + } break; default: WINE_WARN("Unsupported SystemRecord[%d]\n", GET_USHORT(ptr, 0)); @@ -1790,6 +1830,7 @@ void HLPFILE_FreeHlpFile(HLPFILE* hlpfile) HLPFILE_DeletePage(hlpfile->first_page); HLPFILE_DeleteMacro(hlpfile->first_macro); + if (hlpfile->numWindows) HeapFree(GetProcessHeap(), 0, hlpfile->windows); if (hlpfile->Context) HeapFree(GetProcessHeap(), 0, hlpfile->Context); if (hlpfile->lpszTitle) HeapFree(GetProcessHeap(), 0, hlpfile->lpszTitle); if (hlpfile->lpszCopyright) HeapFree(GetProcessHeap(), 0, hlpfile->lpszCopyright); diff --git a/programs/winhelp/hlpfile.h b/programs/winhelp/hlpfile.h index e96be837c58..f8a6f07561b 100644 --- a/programs/winhelp/hlpfile.h +++ b/programs/winhelp/hlpfile.h @@ -21,12 +21,26 @@ struct tagHelpFile; +typedef struct +{ + char type[10]; + char name[9]; + char caption[51]; + POINT origin; + SIZE size; + int style; + DWORD win_style; + COLORREF sr_color; /* color for scrollable region */ + COLORREF nsr_color; /* color for non scrollable region */ +} HLPFILE_WINDOWINFO; + typedef struct { enum {hlp_link_none, hlp_link_link, hlp_link_popup, hlp_link_macro} cookie; - LPCSTR lpszString; - LONG lHash; - BOOL bClrChange; + LPCSTR lpszString; + LONG lHash; + BOOL bClrChange; + unsigned window; } HLPFILE_LINK; enum para_type {para_normal_text, para_debug_text, para_image}; @@ -113,6 +127,9 @@ typedef struct tagHlpFileFile unsigned numFonts; HLPFILE_FONT* fonts; + + unsigned numWindows; + HLPFILE_WINDOWINFO* windows; } HLPFILE; HLPFILE *HLPFILE_ReadHlpFile(LPCSTR lpszPath); diff --git a/programs/winhelp/macro.c b/programs/winhelp/macro.c index 3884146bc67..fb3b39696a3 100644 --- a/programs/winhelp/macro.c +++ b/programs/winhelp/macro.c @@ -535,7 +535,12 @@ void MACRO_FileOpen(void) openfilename.lpTemplateName = 0; if (GetOpenFileName(&openfilename)) - WINHELP_CreateHelpWindowByHash(szPath, 0, "main", FALSE, 0, NULL, SW_SHOWNORMAL); + { + HLPFILE* hlpfile = WINHELP_LookupHelpFile(szPath); + + WINHELP_CreateHelpWindowByHash(hlpfile, 0, + WINHELP_GetWindowInfo(hlpfile, "main"), SW_SHOWNORMAL); + } } void MACRO_Find(void) @@ -643,8 +648,13 @@ BOOL MACRO_IsNotMark(LPCSTR str) void MACRO_JumpContents(LPCSTR lpszPath, LPCSTR lpszWindow) { + HLPFILE* hlpfile; + WINE_TRACE("(\"%s\", \"%s\")\n", lpszPath, lpszWindow); - WINHELP_CreateHelpWindowByHash(lpszPath, 0, lpszWindow, FALSE, 0, NULL, SW_NORMAL); + hlpfile = WINHELP_LookupHelpFile(lpszPath); + WINHELP_CreateHelpWindowByHash(hlpfile, 0, + WINHELP_GetWindowInfo(hlpfile, lpszWindow), + SW_NORMAL); } void MACRO_JumpContext(LPCSTR lpszPath, LPCSTR lpszWindow, LONG context) @@ -654,8 +664,13 @@ void MACRO_JumpContext(LPCSTR lpszPath, LPCSTR lpszWindow, LONG context) void MACRO_JumpHash(LPCSTR lpszPath, LPCSTR lpszWindow, LONG lHash) { + HLPFILE* hlpfile; + WINE_TRACE("(\"%s\", \"%s\", %lu)\n", lpszPath, lpszWindow, lHash); - WINHELP_CreateHelpWindowByHash(lpszPath, lHash, lpszWindow, FALSE, 0, NULL, SW_NORMAL); + hlpfile = WINHELP_LookupHelpFile(lpszPath); + WINHELP_CreateHelpWindowByHash(hlpfile, lHash, + WINHELP_GetWindowInfo(hlpfile, lpszWindow), + SW_NORMAL); } void MACRO_JumpHelpOn(void) @@ -699,9 +714,14 @@ void MACRO_MPrintID(LPCSTR str) void MACRO_Next(void) { + HLPFILE_PAGE* page; + WINE_TRACE("()\n"); - if (Globals.active_win->page->next) - WINHELP_CreateHelpWindowByPage(Globals.active_win->page->next, "main", FALSE, 0, NULL, SW_NORMAL); + if ((page = Globals.active_win->page->next) != NULL) + { + page->file->wRefCount++; + WINHELP_CreateHelpWindow(page, Globals.active_win->info, SW_NORMAL); + } } void MACRO_NoShow(void) @@ -731,9 +751,14 @@ void MACRO_PositionWindow(LONG i1, LONG i2, LONG u1, LONG u2, LONG u3, LPCSTR st void MACRO_Prev(void) { + HLPFILE_PAGE* page; + WINE_TRACE("()\n"); - if (Globals.active_win->page->prev) - WINHELP_CreateHelpWindowByPage(Globals.active_win->page->prev, "main", FALSE, 0, NULL, SW_NORMAL); + if ((page = Globals.active_win->page->prev) != NULL) + { + page->file->wRefCount++; + WINHELP_CreateHelpWindow(page, Globals.active_win->info, SW_NORMAL); + } } void MACRO_Print(void) diff --git a/programs/winhelp/winhelp.c b/programs/winhelp/winhelp.c index 8c1f36900d7..8fa8446f544 100644 --- a/programs/winhelp/winhelp.c +++ b/programs/winhelp/winhelp.c @@ -20,6 +20,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include #include #include #include "winbase.h" @@ -47,7 +48,102 @@ static WINHELP_LINE_PART* WINHELP_IsOverLink(HWND hWnd, WPARAM wParam, LPARAM lP WINHELP_GLOBALS Globals = {3, 0, 0, 0, 1, 0, 0}; -static BOOL MacroTest = FALSE; +/*********************************************************************** + * + * WINHELP_LookupHelpFile + */ +HLPFILE* WINHELP_LookupHelpFile(LPCSTR lpszFile) +{ + HLPFILE* hlpfile; + + hlpfile = HLPFILE_ReadHlpFile(lpszFile); + + /* Add Suffix `.hlp' */ + if (!hlpfile && lstrcmpi(lpszFile + strlen(lpszFile) - 4, ".hlp") != 0) + { + char szFile_hlp[MAX_PATHNAME_LEN]; + + lstrcpyn(szFile_hlp, lpszFile, sizeof(szFile_hlp) - 4); + szFile_hlp[sizeof(szFile_hlp) - 5] = '\0'; + lstrcat(szFile_hlp, ".hlp"); + + hlpfile = HLPFILE_ReadHlpFile(szFile_hlp); + } + if (!hlpfile) + { + WINHELP_MessageBoxIDS_s(STID_HLPFILE_ERROR_s, lpszFile, STID_WHERROR, MB_OK); + if (Globals.win_list) return NULL; + } + return hlpfile; +} + +/****************************************************************** + * WINHELP_GetWindowInfo + * + * + */ +HLPFILE_WINDOWINFO* WINHELP_GetWindowInfo(HLPFILE* hlpfile, LPCSTR name) +{ + static HLPFILE_WINDOWINFO mwi; + int i; + + if (!name || !name[0]) + name = Globals.active_win->lpszName; + + for (i = 0; i < hlpfile->numWindows; i++) + if (!strcmp(hlpfile->windows[i].name, name)) + return &hlpfile->windows[i]; + + if (strcmp(name, "main") != 0) + { + WINE_FIXME("Couldn't find window info for %s\n", name); + assert(0); + return NULL; + } + if (!mwi.name[0]) + { + strcpy(mwi.type, "primary"); + strcpy(mwi.name, "main"); + 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; + } + return &mwi; +} + +/****************************************************************** + * HLPFILE_GetPopupWindowInfo + * + * + */ +HLPFILE_WINDOWINFO* WINHELP_GetPopupWindowInfo(HLPFILE* hlpfile, HWND hParentWnd, POINT* mouse) +{ + static HLPFILE_WINDOWINFO wi; + + RECT parent_rect; + + wi.type[0] = wi.name[0] = wi.caption[0] = '\0'; + + /* Calculate horizontal size and position of a popup window */ + GetWindowRect(hParentWnd, &parent_rect); + wi.size.cx = (parent_rect.right - parent_rect.left) / 2; + wi.size.cy = 10; /* need a non null value, so that border are taken into account while computing */ + + wi.origin = *mouse; + ClientToScreen(hParentWnd, &wi.origin); + wi.origin.x -= wi.size.cx / 2; + wi.origin.x = min(wi.origin.x, GetSystemMetrics(SM_CXSCREEN) - wi.size.cx); + wi.origin.x = max(wi.origin.x, 0); + + wi.style = SW_SHOW; + wi.win_style = WS_POPUPWINDOW; + wi.sr_color = wi.sr_color = 0xFFFFFF; + + return &wi; +} /*********************************************************************** * @@ -57,6 +153,7 @@ int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE prev, LPSTR cmdline, int show) { MSG msg; LONG lHash = 0; + HLPFILE* hlpfile; Globals.hInstance = hInstance; @@ -85,10 +182,6 @@ int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE prev, LPSTR cmdline, int show) Globals.wVersion = option - '0'; break; - case 't': - MacroTest = TRUE; - break; - case 'x': show = SW_HIDE; Globals.isBook = FALSE; @@ -102,7 +195,9 @@ int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE prev, LPSTR cmdline, int show) /* Create primary window */ WINHELP_RegisterWinClasses(); - WINHELP_CreateHelpWindowByHash(cmdline, lHash, "main", FALSE, NULL, NULL, show); + hlpfile = WINHELP_LookupHelpFile(cmdline); + WINHELP_CreateHelpWindowByHash(hlpfile, lHash, + WINHELP_GetWindowInfo(hlpfile, "main"), show); /* Message loop */ while (GetMessage(&msg, 0, 0, 0)) @@ -219,54 +314,25 @@ static LRESULT WINHELP_HandleCommand(HWND hSrcWnd, LPARAM lParam) * * WINHELP_CreateHelpWindow */ - -static BOOL WINHELP_CreateHelpWindow(HLPFILE_PAGE* page, LPCSTR lpszWindow, - BOOL bPopup, HWND hParentWnd, LPPOINT mouse, INT nCmdShow) +BOOL WINHELP_CreateHelpWindow(HLPFILE_PAGE* page, HLPFILE_WINDOWINFO* wi, + int nCmdShow) { - CHAR szCaption[MAX_STRING_LEN]; - SIZE size = {CW_USEDEFAULT, 0/*CW_USEDEFAULT*/}; - POINT origin = {240, 0}; - LPSTR ptr; WINHELP_WINDOW *win, *oldwin; - HLPFILE_MACRO *macro; HWND hWnd; BOOL bPrimary; - if (bPopup) - lpszWindow = NULL; - else if (!lpszWindow || !lpszWindow[0]) - lpszWindow = Globals.active_win->lpszName; - bPrimary = lpszWindow && !lstrcmpi(lpszWindow, "main"); - - /* Calculate horizontal size and position of a popup window */ - if (bPopup) - { - RECT parent_rect; - GetWindowRect(hParentWnd, &parent_rect); - size.cx = (parent_rect.right - parent_rect.left) / 2; - size.cy = 10; /* need a non null value, so that border are taken into account while computing */ - - origin = *mouse; - ClientToScreen(hParentWnd, &origin); - origin.x -= size.cx / 2; - origin.x = min(origin.x, GetSystemMetrics(SM_CXSCREEN) - size.cx); - origin.x = max(origin.x, 0); - } + bPrimary = !lstrcmpi(wi->name, "main"); /* Initialize WINHELP_WINDOW struct */ win = HeapAlloc(GetProcessHeap(), 0, - sizeof(WINHELP_WINDOW) + (lpszWindow ? strlen(lpszWindow) + 1 : 0)); + sizeof(WINHELP_WINDOW) + strlen(wi->name) + 1); if (!win) return FALSE; win->next = Globals.win_list; Globals.win_list = win; - if (lpszWindow) - { - ptr = (char*)win + sizeof(WINHELP_WINDOW); - lstrcpy(ptr, (LPSTR) lpszWindow); - win->lpszName = ptr; - } - else win->lpszName = NULL; + + win->lpszName = (char*)win + sizeof(WINHELP_WINDOW); + lstrcpy((char*)win->lpszName, wi->name); win->page = page; win->first_button = 0; @@ -279,11 +345,11 @@ static BOOL WINHELP_CreateHelpWindow(HLPFILE_PAGE* page, LPCSTR lpszWindow, win->hArrowCur = LoadCursorA(0, IDC_ARROWA); win->hHandCur = LoadCursorA(0, IDC_HANDA); + win->info = wi; + Globals.active_win = win; /* Initialize default pushbuttons */ - if (MacroTest && !bPopup) - MACRO_CreateButton("BTN_TEST", "&Test", "MacroTest"); if (bPrimary && page) { CHAR buffer[MAX_STRING_LEN]; @@ -301,14 +367,19 @@ static BOOL WINHELP_CreateHelpWindow(HLPFILE_PAGE* page, LPCSTR lpszWindow, } /* Initialize file specific pushbuttons */ - if (!bPopup && page) + if (!(wi->win_style & WS_POPUP) && page) + { + HLPFILE_MACRO *macro; for (macro = page->file->first_macro; macro; macro = macro->next) MACRO_ExecuteMacro(macro->lpszMacro); + } /* Reuse existing window */ - if (lpszWindow) + if (!(wi->win_style & WS_POPUP)) + { for (oldwin = win->next; oldwin; oldwin = oldwin->next) - if (oldwin->lpszName && !lstrcmpi(oldwin->lpszName, lpszWindow)) + { + if (!lstrcmpi(oldwin->lpszName, wi->name)) { WINHELP_BUTTON *button; @@ -317,9 +388,9 @@ static BOOL WINHELP_CreateHelpWindow(HLPFILE_PAGE* page, LPCSTR lpszWindow, 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); + SetWindowLong(win->hMainWnd, 0, (LONG)win); + SetWindowLong(win->hButtonBoxWnd, 0, (LONG)win); + SetWindowLong(win->hTextWnd, 0, (LONG)win); WINHELP_InitFonts(win->hMainWnd); @@ -340,13 +411,12 @@ static BOOL WINHELP_CreateHelpWindow(HLPFILE_PAGE* page, LPCSTR lpszWindow, WINHELP_DeleteWindow(oldwin); return TRUE; } + } + } - /* Create main Window */ - if (!page) LoadString(Globals.hInstance, STID_WINE_HELP, szCaption, sizeof(szCaption)); - hWnd = CreateWindow(bPopup ? TEXT_WIN_CLASS_NAME : MAIN_WIN_CLASS_NAME, - page ? page->file->lpszTitle : szCaption, - bPopup ? WS_POPUPWINDOW | WS_BORDER : WS_OVERLAPPEDWINDOW, - origin.x, origin.y, size.cx, size.cy, + hWnd = CreateWindow((wi->win_style & WS_POPUP) ? 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, Globals.hInstance, win); @@ -356,55 +426,20 @@ static BOOL WINHELP_CreateHelpWindow(HLPFILE_PAGE* page, LPCSTR lpszWindow, return TRUE; } -/*********************************************************************** - * - * WINHELP_CreateHelpWindowByPage - */ -BOOL WINHELP_CreateHelpWindowByPage(HLPFILE_PAGE* page, LPCSTR lpszWindow, - BOOL bPopup, HWND hParentWnd, LPPOINT mouse, INT nCmdShow) -{ - if (page) page->file->wRefCount++; - return WINHELP_CreateHelpWindow(page, lpszWindow, bPopup, hParentWnd, mouse, nCmdShow); -} - /*********************************************************************** * * WINHELP_CreateHelpWindowByHash */ -BOOL WINHELP_CreateHelpWindowByHash(LPCSTR lpszFile, LONG lHash, LPCSTR lpszWindow, - BOOL bPopup, HWND hParentWnd, LPPOINT mouse, INT nCmdShow) +BOOL WINHELP_CreateHelpWindowByHash(HLPFILE* hlpfile, LONG lHash, + HLPFILE_WINDOWINFO* wi, int nCmdShow) { HLPFILE_PAGE* page = NULL; - /* Read help file */ - if (lpszFile[0]) - { - HLPFILE* hlpfile; - - hlpfile = HLPFILE_ReadHlpFile(lpszFile); - - /* Add Suffix `.hlp' */ - if (!hlpfile && lstrcmpi(lpszFile + strlen(lpszFile) - 4, ".hlp") != 0) - { - CHAR szFile_hlp[MAX_PATHNAME_LEN]; - - lstrcpyn(szFile_hlp, lpszFile, sizeof(szFile_hlp) - 4); - szFile_hlp[sizeof(szFile_hlp) - 5] = '\0'; - lstrcat(szFile_hlp, ".hlp"); - - hlpfile = HLPFILE_ReadHlpFile(szFile_hlp); - } - if (!hlpfile) - { - WINHELP_MessageBoxIDS_s(STID_HLPFILE_ERROR_s, lpszFile, STID_WHERROR, MB_OK); - if (Globals.win_list) return FALSE; - } - else - page = lHash ? HLPFILE_PageByHash(hlpfile, lHash) : - HLPFILE_Contents(hlpfile); - } - else page = NULL; - return WINHELP_CreateHelpWindowByPage(page, lpszWindow, bPopup, hParentWnd, mouse, nCmdShow); + if (hlpfile) + page = lHash ? HLPFILE_PageByHash(hlpfile, lHash) : + HLPFILE_Contents(hlpfile); + if (page) page->file->wRefCount++; + return WINHELP_CreateHelpWindow(page, wi, nCmdShow); } /*********************************************************************** @@ -599,7 +634,7 @@ static LRESULT CALLBACK WINHELP_TextWndProc(HWND hWnd, UINT msg, WPARAM wParam, win = (WINHELP_WINDOW*) ((LPCREATESTRUCT) lParam)->lpCreateParams; SetWindowLong(hWnd, 0, (LONG) win); win->hTextWnd = hWnd; - if (!win->lpszName) Globals.hPopupWnd = win->hMainWnd = hWnd; + if (win->info->win_style & WS_POPUP) Globals.hPopupWnd = win->hMainWnd = hWnd; WINHELP_InitFonts(hWnd); break; @@ -607,7 +642,7 @@ static LRESULT CALLBACK WINHELP_TextWndProc(HWND hWnd, UINT msg, WPARAM wParam, win = (WINHELP_WINDOW*) GetWindowLong(hWnd, 0); /* Calculate vertical size and position of a popup window */ - if (!win->lpszName) + if (win->info->win_style & WS_POPUP) { POINT origin; RECT old_window_rect; @@ -773,6 +808,9 @@ static LRESULT CALLBACK WINHELP_TextWndProc(HWND hWnd, UINT msg, WPARAM wParam, part = WINHELP_IsOverLink(hWnd, wParam, lParam); if (part) { + HLPFILE* hlpfile; + HLPFILE_WINDOWINFO* wi; + mouse.x = LOWORD(lParam); mouse.y = HIWORD(lParam); @@ -781,12 +819,24 @@ static LRESULT CALLBACK WINHELP_TextWndProc(HWND hWnd, UINT msg, WPARAM wParam, case hlp_link_none: break; case hlp_link_link: - WINHELP_CreateHelpWindowByHash(part->link.lpszString, part->link.lHash, NULL, - FALSE, hWnd, &mouse, SW_NORMAL); + hlpfile = WINHELP_LookupHelpFile(part->link.lpszString); + if (part->link.window == -1) + wi = win->info; + else if (part->link.window < hlpfile->numWindows) + wi = &hlpfile->windows[part->link.window]; + else + { + WINE_WARN("link to window %d/%d\n", part->link.window, hlpfile->numWindows); + break; + } + WINHELP_CreateHelpWindowByHash(hlpfile, part->link.lHash, wi, + SW_NORMAL); break; case hlp_link_popup: - WINHELP_CreateHelpWindowByHash(part->link.lpszString, part->link.lHash, NULL, - TRUE, hWnd, &mouse, SW_NORMAL); + hlpfile = WINHELP_LookupHelpFile(part->link.lpszString); + WINHELP_CreateHelpWindowByHash(hlpfile, part->link.lHash, + WINHELP_GetPopupWindowInfo(hlpfile, hWnd, &mouse), + SW_NORMAL); break; case hlp_link_macro: MACRO_ExecuteMacro(part->link.lpszString); @@ -932,6 +982,7 @@ static BOOL WINHELP_AppendText(WINHELP_LINE ***linep, WINHELP_LINE_PART ***partp part->link.cookie = link->cookie; part->link.lHash = link->lHash; part->link.bClrChange = link->bClrChange; + part->link.window = link->window; } else part->link.cookie = hlp_link_none; @@ -1009,6 +1060,7 @@ static BOOL WINHELP_AppendBitmap(WINHELP_LINE ***linep, WINHELP_LINE_PART ***par part->link.cookie = link->cookie; part->link.lHash = link->lHash; part->link.bClrChange = link->bClrChange; + part->link.window = link->window; } else part->link.cookie = hlp_link_none; diff --git a/programs/winhelp/winhelp.h b/programs/winhelp/winhelp.h index 2020914b004..9669561b955 100644 --- a/programs/winhelp/winhelp.h +++ b/programs/winhelp/winhelp.h @@ -85,7 +85,7 @@ typedef struct tagHelpButton typedef struct tagWinHelp { - LPCSTR lpszName; + LPCSTR lpszName; WINHELP_BUTTON* first_button; HLPFILE_PAGE* page; @@ -102,6 +102,8 @@ typedef struct tagWinHelp HCURSOR hArrowCur; HCURSOR hHandCur; + HLPFILE_WINDOWINFO* info; + struct tagWinHelp* next; } WINHELP_WINDOW; @@ -118,10 +120,12 @@ typedef struct extern WINHELP_GLOBALS Globals; -BOOL WINHELP_CreateHelpWindowByHash(LPCSTR, LONG, LPCSTR, BOOL, HWND, LPPOINT, INT); -BOOL WINHELP_CreateHelpWindowByPage(HLPFILE_PAGE*, LPCSTR, BOOL, HWND, LPPOINT, INT); +BOOL WINHELP_CreateHelpWindowByHash(HLPFILE*, LONG, HLPFILE_WINDOWINFO*, int); +BOOL WINHELP_CreateHelpWindow(HLPFILE_PAGE*, HLPFILE_WINDOWINFO*, int); INT WINHELP_MessageBoxIDS(UINT, UINT, WORD); INT WINHELP_MessageBoxIDS_s(UINT, LPCSTR, UINT, WORD); +HLPFILE* WINHELP_LookupHelpFile(LPCSTR lpszFile); +HLPFILE_WINDOWINFO* WINHELP_GetWindowInfo(HLPFILE* hlpfile, LPCSTR name); extern char MAIN_WIN_CLASS_NAME[]; extern char BUTTON_BOX_WIN_CLASS_NAME[];