Wrote back & history support.

Correctly implemented << and >> buttons.
Added support for page level macros.
This commit is contained in:
Eric Pouech 2002-11-20 19:46:18 +00:00 committed by Alexandre Julliard
parent ff3dc34797
commit 2b855deddb
6 changed files with 378 additions and 141 deletions

View file

@ -84,23 +84,6 @@ static BOOL HLPFILE_Uncompress3(char*, const char*, const BYTE*, const BYTE*);
static void HLPFILE_UncompressRLE(const BYTE* src, unsigned sz, BYTE** dst); static void HLPFILE_UncompressRLE(const BYTE* src, unsigned sz, BYTE** dst);
static BOOL HLPFILE_ReadFont(HLPFILE* hlpfile); static BOOL HLPFILE_ReadFont(HLPFILE* hlpfile);
/***********************************************************************
*
* 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_PageByNumber
@ -119,53 +102,80 @@ HLPFILE_PAGE *HLPFILE_PageByNumber(LPCSTR lpszPath, UINT wNum)
return page; 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_PAGE *HLPFILE_PageByOffset(HLPFILE* hlpfile, LONG offset)
{
HLPFILE_PAGE* page;
HLPFILE_PAGE* found;
if (!hlpfile) return 0;
WINE_TRACE("<%s>[%lx]\n", hlpfile->lpszPath, offset);
if (offset == 0xFFFFFFFF) return NULL;
page = NULL;
for (found = NULL, page = hlpfile->first_page; page; page = page->next)
{
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;
}
/*********************************************************************** /***********************************************************************
* *
* HLPFILE_HlpFilePageByHash * HLPFILE_HlpFilePageByHash
*/ */
HLPFILE_PAGE *HLPFILE_PageByHash(HLPFILE* hlpfile, LONG lHash) HLPFILE_PAGE *HLPFILE_PageByHash(HLPFILE* hlpfile, LONG lHash)
{ {
HLPFILE_PAGE* page;
HLPFILE_PAGE* found;
int i; int i;
WINE_TRACE("path<%s>[%lx]\n", hlpfile->lpszPath, lHash);
if (!hlpfile) return 0; if (!hlpfile) return 0;
page = NULL; WINE_TRACE("<%s>[%lx]\n", hlpfile->lpszPath, lHash);
for (i = 0; i < hlpfile->wContextLen; i++) for (i = 0; i < hlpfile->wContextLen; i++)
{ {
if (hlpfile->Context[i].lHash != lHash) continue; if (hlpfile->Context[i].lHash == lHash)
return HLPFILE_PageByOffset(hlpfile, hlpfile->Context[i].offset);
/* 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;
WINE_ERR("Page of offset %lu not found in file %s\n",
hlpfile->Context[i].offset, hlpfile->lpszPath);
return NULL;
} }
WINE_ERR("Page of hash %lx not found in file %s\n", lHash, hlpfile->lpszPath); WINE_ERR("Page of hash %lx not found in file %s\n", lHash, hlpfile->lpszPath);
return NULL; 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 * HLPFILE_Hash
@ -216,7 +226,7 @@ HLPFILE *HLPFILE_ReadHlpFile(LPCSTR lpszPath)
hlpfile->first_macro = NULL; hlpfile->first_macro = NULL;
hlpfile->wContextLen = 0; hlpfile->wContextLen = 0;
hlpfile->Context = NULL; hlpfile->Context = NULL;
hlpfile->contents_start = 0; hlpfile->contents_start = 0xFFFFFFFF;
hlpfile->prev = NULL; hlpfile->prev = NULL;
hlpfile->next = first_hlpfile; hlpfile->next = first_hlpfile;
hlpfile->wRefCount = 1; hlpfile->wRefCount = 1;
@ -338,35 +348,37 @@ static BOOL HLPFILE_AddPage(HLPFILE *hlpfile, BYTE *buf, BYTE *end, unsigned off
HLPFILE_PAGE* page; HLPFILE_PAGE* page;
BYTE* title; BYTE* title;
UINT titlesize; UINT titlesize;
char* ptr;
HLPFILE_MACRO*macro;
if (buf + 0x31 > end) {WINE_WARN("page1\n"); return FALSE;}; if (buf + 0x31 > end) {WINE_WARN("page1\n"); return FALSE;};
title = buf + GET_UINT(buf, 0x10); title = buf + GET_UINT(buf, 0x10);
if (title > end) {WINE_WARN("page2\n"); return FALSE;}; if (title > end) {WINE_WARN("page2\n"); return FALSE;};
titlesize = GET_UINT(buf, 4) + 1; titlesize = GET_UINT(buf, 4);
page = HeapAlloc(GetProcessHeap(), 0, sizeof(HLPFILE_PAGE) + titlesize); page = HeapAlloc(GetProcessHeap(), 0, sizeof(HLPFILE_PAGE) + titlesize + 1);
if (!page) return FALSE; if (!page) return FALSE;
page->lpszTitle = (char*)page + sizeof(HLPFILE_PAGE); page->lpszTitle = (char*)page + sizeof(HLPFILE_PAGE);
if (hlpfile->hasPhrases) if (hlpfile->hasPhrases)
{ {
HLPFILE_Uncompress2(title, end, page->lpszTitle, page->lpszTitle + titlesize - 1); HLPFILE_Uncompress2(title, end, page->lpszTitle, page->lpszTitle + titlesize);
} }
else else
{ {
if (GET_UINT(buf, 0x4) > GET_UINT(buf, 0) - GET_UINT(buf, 0x10)) if (GET_UINT(buf, 0x4) > GET_UINT(buf, 0) - GET_UINT(buf, 0x10))
{ {
/* need to decompress */ /* need to decompress */
HLPFILE_Uncompress3(page->lpszTitle, page->lpszTitle + titlesize - 1, HLPFILE_Uncompress3(page->lpszTitle, page->lpszTitle + titlesize,
title, end); title, end);
} }
else 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) if (hlpfile->first_page)
{ {
@ -385,14 +397,36 @@ static BOOL HLPFILE_AddPage(HLPFILE *hlpfile, BYTE *buf, BYTE *end, unsigned off
page->file = hlpfile; page->file = hlpfile;
page->next = NULL; page->next = NULL;
page->first_paragraph = NULL; page->first_paragraph = NULL;
page->first_macro = NULL;
page->wNumber = GET_UINT(buf, 0x21); page->wNumber = GET_UINT(buf, 0x21);
page->offset = offset; page->offset = offset;
WINE_TRACE("Added page[%d]: title='%s' offset=%08x\n", page->browse_bwd = GET_UINT(buf, 0x19);
page->wNumber, page->lpszTitle, page->offset); 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)); 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; return TRUE;
} }
@ -1762,23 +1796,6 @@ static void HLPFILE_DeleteParagraph(HLPFILE_PARAGRAPH* paragraph)
} }
} }
/***********************************************************************
*
* DeletePage
*/
static void HLPFILE_DeletePage(HLPFILE_PAGE* page)
{
HLPFILE_PAGE* next;
while (page)
{
next = page->next;
HLPFILE_DeleteParagraph(page->first_paragraph);
HeapFree(GetProcessHeap(), 0, page);
page = next;
}
}
/*********************************************************************** /***********************************************************************
* *
* DeleteMacro * DeleteMacro
@ -1795,6 +1812,24 @@ static void HLPFILE_DeleteMacro(HLPFILE_MACRO* macro)
} }
} }
/***********************************************************************
*
* DeletePage
*/
static void HLPFILE_DeletePage(HLPFILE_PAGE* page)
{
HLPFILE_PAGE* next;
while (page)
{
next = page->next;
HLPFILE_DeleteParagraph(page->first_paragraph);
HLPFILE_DeleteMacro(page->first_macro);
HeapFree(GetProcessHeap(), 0, page);
page = next;
}
}
/*********************************************************************** /***********************************************************************
* *
* HLPFILE_FreeHlpFile * HLPFILE_FreeHlpFile
@ -1836,13 +1871,3 @@ void HLPFILE_FreeHlpFile(HLPFILE* hlpfile)
if (hlpfile->lpszCopyright) HeapFree(GetProcessHeap(), 0, hlpfile->lpszCopyright); if (hlpfile->lpszCopyright) HeapFree(GetProcessHeap(), 0, hlpfile->lpszCopyright);
HeapFree(GetProcessHeap(), 0, hlpfile); HeapFree(GetProcessHeap(), 0, hlpfile);
} }
/***********************************************************************
*
* FreeHlpFilePage
*/
void HLPFILE_FreeHlpFilePage(HLPFILE_PAGE* page)
{
if (!page) return;
HLPFILE_FreeHlpFile(page->file);
}

View file

@ -71,15 +71,26 @@ typedef struct tagHlpFileParagraph
struct tagHlpFileParagraph* next; struct tagHlpFileParagraph* next;
} HLPFILE_PARAGRAPH; } HLPFILE_PARAGRAPH;
typedef struct tagHlpFileMacro
{
LPCSTR lpszMacro;
struct tagHlpFileMacro* next;
} HLPFILE_MACRO;
typedef struct tagHlpFilePage typedef struct tagHlpFilePage
{ {
LPSTR lpszTitle; LPSTR lpszTitle;
HLPFILE_PARAGRAPH* first_paragraph; HLPFILE_PARAGRAPH* first_paragraph;
HLPFILE_MACRO* first_macro;
unsigned wNumber; unsigned wNumber;
unsigned offset; unsigned offset;
struct tagHlpFilePage* next; struct tagHlpFilePage* next;
struct tagHlpFilePage* prev; struct tagHlpFilePage* prev;
DWORD browse_bwd;
DWORD browse_fwd;
struct tagHlpFileFile* file; struct tagHlpFileFile* file;
} HLPFILE_PAGE; } HLPFILE_PAGE;
@ -89,12 +100,6 @@ typedef struct
unsigned long offset; unsigned long offset;
} HLPFILE_CONTEXT; } HLPFILE_CONTEXT;
typedef struct tagHlpFileMacro
{
LPCSTR lpszMacro;
struct tagHlpFileMacro* next;
} HLPFILE_MACRO;
typedef struct typedef struct
{ {
LOGFONT LogFont; LOGFONT LogFont;
@ -132,9 +137,9 @@ typedef struct tagHlpFileFile
HLPFILE_WINDOWINFO* windows; HLPFILE_WINDOWINFO* windows;
} HLPFILE; } HLPFILE;
HLPFILE *HLPFILE_ReadHlpFile(LPCSTR lpszPath); HLPFILE* HLPFILE_ReadHlpFile(LPCSTR lpszPath);
HLPFILE_PAGE *HLPFILE_Contents(HLPFILE* hlpfile); HLPFILE_PAGE* HLPFILE_Contents(HLPFILE* hlpfile);
HLPFILE_PAGE *HLPFILE_PageByHash(HLPFILE* hlpfile, LONG wNum); HLPFILE_PAGE* HLPFILE_PageByHash(HLPFILE* hlpfile, LONG lHash);
HLPFILE_PAGE* HLPFILE_PageByOffset(HLPFILE* hlpfile, LONG offset);
LONG HLPFILE_Hash(LPCSTR lpszContext); LONG HLPFILE_Hash(LPCSTR lpszContext);
VOID HLPFILE_FreeHlpFilePage(HLPFILE_PAGE*); void HLPFILE_FreeHlpFile(HLPFILE*);
VOID HLPFILE_FreeHlpFile(HLPFILE*);

View file

@ -222,12 +222,32 @@ void MACRO_AppendItem(LPCSTR str1, LPCSTR str2, LPCSTR str3, LPCSTR str4)
void MACRO_Back(void) 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) 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) void MACRO_BookmarkDefine(void)
@ -599,7 +619,14 @@ void MACRO_HelpOnTop(void)
void MACRO_History(void) 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) void MACRO_IfThen(BOOL b, LPCSTR t)
@ -717,7 +744,9 @@ void MACRO_Next(void)
HLPFILE_PAGE* page; HLPFILE_PAGE* page;
WINE_TRACE("()\n"); 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++; page->file->wRefCount++;
WINHELP_CreateHelpWindow(page, Globals.active_win->info, SW_NORMAL); WINHELP_CreateHelpWindow(page, Globals.active_win->info, SW_NORMAL);
@ -754,7 +783,9 @@ void MACRO_Prev(void)
HLPFILE_PAGE* page; HLPFILE_PAGE* page;
WINE_TRACE("()\n"); 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++; page->file->wRefCount++;
WINHELP_CreateHelpWindow(page, Globals.active_win->info, SW_NORMAL); WINHELP_CreateHelpWindow(page, Globals.active_win->info, SW_NORMAL);

View file

@ -24,6 +24,7 @@ char MAIN_WIN_CLASS_NAME[] = "MS_WINHELP";
char BUTTON_BOX_WIN_CLASS_NAME[] = "WHButtonBox"; char BUTTON_BOX_WIN_CLASS_NAME[] = "WHButtonBox";
char TEXT_WIN_CLASS_NAME[] = "WHText"; char TEXT_WIN_CLASS_NAME[] = "WHText";
char SHADOW_WIN_CLASS_NAME[] = "WHShadow"; char SHADOW_WIN_CLASS_NAME[] = "WHShadow";
char HISTORY_WIN_CLASS_NAME[] = "WHHistory";
char STRING_BUTTON[] = "BUTTON"; char STRING_BUTTON[] = "BUTTON";
/* Resource names */ /* Resource names */

View file

@ -38,6 +38,7 @@ static BOOL WINHELP_RegisterWinClasses(void);
static LRESULT CALLBACK WINHELP_MainWndProc(HWND, UINT, WPARAM, LPARAM); static LRESULT CALLBACK WINHELP_MainWndProc(HWND, UINT, WPARAM, LPARAM);
static LRESULT CALLBACK WINHELP_TextWndProc(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_ButtonBoxWndProc(HWND, UINT, WPARAM, LPARAM);
static LRESULT CALLBACK WINHELP_HistoryWndProc(HWND, UINT, WPARAM, LPARAM);
static void WINHELP_CheckPopup(UINT); static void WINHELP_CheckPopup(UINT);
static BOOL WINHELP_SplitLines(HWND hWnd, LPSIZE); static BOOL WINHELP_SplitLines(HWND hWnd, LPSIZE);
static void WINHELP_InitFonts(HWND hWnd); static void WINHELP_InitFonts(HWND hWnd);
@ -104,9 +105,9 @@ HLPFILE_WINDOWINFO* WINHELP_GetWindowInfo(HLPFILE* hlpfile, LPCSTR name)
{ {
strcpy(mwi.type, "primary"); strcpy(mwi.type, "primary");
strcpy(mwi.name, "main"); strcpy(mwi.name, "main");
LoadString(Globals.hInstance, STID_WINE_HELP, if (!LoadString(Globals.hInstance, STID_WINE_HELP,
mwi.caption, sizeof(mwi.caption)); mwi.caption, sizeof(mwi.caption)))
/*strcpy(mwi.caption, hlpfile->lpszTitle); */ strcpy(mwi.caption, hlpfile->lpszTitle);
mwi.origin.x = mwi.origin.y = mwi.size.cx = mwi.size.cy = CW_USEDEFAULT; mwi.origin.x = mwi.origin.y = mwi.size.cx = mwi.size.cy = CW_USEDEFAULT;
mwi.style = SW_SHOW; mwi.style = SW_SHOW;
mwi.sr_color = mwi.sr_color = 0xFFFFFF; mwi.sr_color = mwi.sr_color = 0xFFFFFF;
@ -214,7 +215,7 @@ int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE prev, LPSTR cmdline, int show)
*/ */
static BOOL WINHELP_RegisterWinClasses(void) 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.style = CS_HREDRAW | CS_VREDRAW;
class_main.lpfnWndProc = WINHELP_MainWndProc; class_main.lpfnWndProc = WINHELP_MainWndProc;
@ -241,10 +242,15 @@ static BOOL WINHELP_RegisterWinClasses(void)
class_shadow.hbrBackground = GetStockObject(GRAY_BRUSH); class_shadow.hbrBackground = GetStockObject(GRAY_BRUSH);
class_shadow.lpszClassName = SHADOW_WIN_CLASS_NAME; 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) && return (RegisterClass(&class_main) &&
RegisterClass(&class_button_box) && RegisterClass(&class_button_box) &&
RegisterClass(&class_text) && RegisterClass(&class_text) &&
RegisterClass(&class_shadow)); RegisterClass(&class_shadow) &&
RegisterClass(&class_history));
} }
typedef struct typedef struct
@ -310,6 +316,96 @@ static LRESULT WINHELP_HandleCommand(HWND hSrcWnd, LPARAM lParam)
return 0L; 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 * WINHELP_CreateHelpWindow
@ -320,8 +416,10 @@ BOOL WINHELP_CreateHelpWindow(HLPFILE_PAGE* page, HLPFILE_WINDOWINFO* wi,
WINHELP_WINDOW *win, *oldwin; WINHELP_WINDOW *win, *oldwin;
HWND hWnd; HWND hWnd;
BOOL bPrimary; BOOL bPrimary;
BOOL bPopup;
bPrimary = !lstrcmpi(wi->name, "main"); bPrimary = !lstrcmpi(wi->name, "main");
bPopup = wi->win_style & WS_POPUP;
/* Initialize WINHELP_WINDOW struct */ /* Initialize WINHELP_WINDOW struct */
win = HeapAlloc(GetProcessHeap(), 0, win = HeapAlloc(GetProcessHeap(), 0,
@ -341,6 +439,7 @@ BOOL WINHELP_CreateHelpWindow(HLPFILE_PAGE* page, HLPFILE_WINDOWINFO* wi,
win->hButtonBoxWnd = 0; win->hButtonBoxWnd = 0;
win->hTextWnd = 0; win->hTextWnd = 0;
win->hShadowWnd = 0; win->hShadowWnd = 0;
win->hHistoryWnd = 0;
win->hArrowCur = LoadCursorA(0, IDC_ARROWA); win->hArrowCur = LoadCursorA(0, IDC_ARROWA);
win->hHandCur = LoadCursorA(0, IDC_HANDA); win->hHandCur = LoadCursorA(0, IDC_HANDA);
@ -372,49 +471,30 @@ BOOL WINHELP_CreateHelpWindow(HLPFILE_PAGE* page, HLPFILE_WINDOWINFO* wi,
HLPFILE_MACRO *macro; HLPFILE_MACRO *macro;
for (macro = page->file->first_macro; macro; macro = macro->next) for (macro = page->file->first_macro; macro; macro = macro->next)
MACRO_ExecuteMacro(macro->lpszMacro); MACRO_ExecuteMacro(macro->lpszMacro);
for (macro = page->first_macro; macro; macro = macro->next)
MACRO_ExecuteMacro(macro->lpszMacro);
} }
/* Reuse existing window */ /* Reuse existing window */
if (!(wi->win_style & WS_POPUP)) if (!bPopup)
{ {
for (oldwin = win->next; oldwin; oldwin = oldwin->next) for (oldwin = win->next; oldwin; oldwin = oldwin->next)
{ {
if (!lstrcmpi(oldwin->lpszName, wi->name)) if (!lstrcmpi(oldwin->lpszName, wi->name))
{ {
WINHELP_BUTTON *button; return WINHELP_ReuseWindow(win, oldwin, page, nCmdShow);
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;
} }
} }
}
hWnd = CreateWindow((wi->win_style & WS_POPUP) ? TEXT_WIN_CLASS_NAME : MAIN_WIN_CLASS_NAME, win->histIndex = win->backIndex = 1;
win->history[0] = win->back[0] = page;
page->file->wRefCount += 2;
}
else
win->histIndex = win->backIndex = 0;
hWnd = CreateWindow(bPopup ? TEXT_WIN_CLASS_NAME : MAIN_WIN_CLASS_NAME,
wi->caption, wi->win_style, wi->caption, wi->win_style,
wi->origin.x, wi->origin.y, wi->size.cx, wi->size.cy, wi->origin.x, wi->origin.y, wi->size.cx, wi->size.cy,
0, bPrimary ? LoadMenu(Globals.hInstance, MAKEINTRESOURCE(MAIN_MENU)) : 0, 0, bPrimary ? LoadMenu(Globals.hInstance, MAKEINTRESOURCE(MAIN_MENU)) : 0,
@ -854,7 +934,6 @@ static LRESULT CALLBACK WINHELP_TextWndProc(HWND hWnd, UINT msg, WPARAM wParam,
win = (WINHELP_WINDOW*) GetWindowLong(hWnd, 0); win = (WINHELP_WINDOW*) GetWindowLong(hWnd, 0);
if (hWnd == Globals.hPopupWnd) Globals.hPopupWnd = 0; if (hWnd == Globals.hPopupWnd) Globals.hPopupWnd = 0;
if (win->hShadowWnd) DestroyWindow(win->hShadowWnd);
bExit = (Globals.wVersion >= 4 && !lstrcmpi(win->lpszName, "main")); bExit = (Globals.wVersion >= 4 && !lstrcmpi(win->lpszName, "main"));
@ -870,6 +949,72 @@ static LRESULT CALLBACK WINHELP_TextWndProc(HWND hWnd, UINT msg, WPARAM wParam,
return DefWindowProc(hWnd, msg, wParam, lParam); 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 * SetupText
@ -1315,19 +1460,41 @@ static void WINHELP_DeleteLines(WINHELP_WINDOW *win)
* *
* WINHELP_DeleteWindow * 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) for (w = &Globals.win_list; *w; w = &(*w)->next)
{
if (*w == win) if (*w == win)
{ {
*w = win->next; *w = win->next;
break; 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); 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); WINHELP_DeleteLines(win);
HeapFree(GetProcessHeap(), 0, win); HeapFree(GetProcessHeap(), 0, win);
} }
@ -1359,7 +1526,7 @@ static void WINHELP_InitFonts(HWND hWnd)
{ {
INT i; INT i;
for(i = 0; i < FONTS_LEN; i++) for (i = 0; i < FONTS_LEN; i++)
{ {
fonts[i] = CreateFontIndirect(&logfontlist[i]); fonts[i] = CreateFontIndirect(&logfontlist[i]);
} }

View file

@ -95,6 +95,7 @@ typedef struct tagWinHelp
HWND hButtonBoxWnd; HWND hButtonBoxWnd;
HWND hTextWnd; HWND hTextWnd;
HWND hShadowWnd; HWND hShadowWnd;
HWND hHistoryWnd;
HFONT* fonts; HFONT* fonts;
UINT fonts_len; UINT fonts_len;
@ -104,6 +105,12 @@ typedef struct tagWinHelp
HLPFILE_WINDOWINFO* info; 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; struct tagWinHelp* next;
} WINHELP_WINDOW; } WINHELP_WINDOW;
@ -131,6 +138,7 @@ extern char MAIN_WIN_CLASS_NAME[];
extern char BUTTON_BOX_WIN_CLASS_NAME[]; extern char BUTTON_BOX_WIN_CLASS_NAME[];
extern char TEXT_WIN_CLASS_NAME[]; extern char TEXT_WIN_CLASS_NAME[];
extern char SHADOW_WIN_CLASS_NAME[]; extern char SHADOW_WIN_CLASS_NAME[];
extern char HISTORY_WIN_CLASS_NAME[];
extern char STRING_BUTTON[]; extern char STRING_BUTTON[];
extern char STRING_MENU_Xx[]; extern char STRING_MENU_Xx[];
extern char STRING_DIALOG_TEST[]; extern char STRING_DIALOG_TEST[];