From 757928781e5b73a3bd7dfc4c40a20ab45dd12eb9 Mon Sep 17 00:00:00 2001 From: Eric Pouech Date: Tue, 16 Jul 2002 01:46:29 +0000 Subject: [PATCH] Bring winhelp back to life, with mainly support for Win95 help files. --- programs/winhelp/hlp2sgml.c | 440 ++++---- programs/winhelp/hlpfile.c | 1896 ++++++++++++++++++++++----------- programs/winhelp/hlpfile.h | 104 +- programs/winhelp/macro.c | 516 +++++---- programs/winhelp/macro.lex.l | 229 ++-- programs/winhelp/macro.yacc.y | 58 +- programs/winhelp/winhelp.c | 1672 ++++++++++++++++------------- programs/winhelp/winhelp.h | 129 +-- 8 files changed, 2993 insertions(+), 2051 deletions(-) diff --git a/programs/winhelp/hlp2sgml.c b/programs/winhelp/hlp2sgml.c index 452c5e56ea4..365deec5b3d 100644 --- a/programs/winhelp/hlp2sgml.c +++ b/programs/winhelp/hlp2sgml.c @@ -22,157 +22,158 @@ #include #include #include +#include #include "windows.h" #include "hlpfile.h" typedef struct { - const char *header1; - const char *header2; - const char *section; - const char *first_paragraph; - const char *newline; - const char *next_paragraph; - const char *special_char; - const char *begin_italic; - const char *end_italic; - const char *begin_boldface; - const char *end_boldface; - const char *begin_typewriter; - const char *end_typewriter; - const char *tail; + const char *header1; + const char *header2; + const char *section; + const char *first_paragraph; + const char *newline; + const char *next_paragraph; + const char *special_char; + const char *begin_italic; + const char *end_italic; + const char *begin_boldface; + const char *end_boldface; + const char *begin_typewriter; + const char *end_typewriter; + const char *tail; } FORMAT; typedef struct { - const char ch; - const char *subst; + const char ch; + const char *subst; } CHARMAP[]; FORMAT format = { - "\n" - "
\n" - "\n", + "<!doctype linuxdoc system>\n" + "<article>\n" + "<title>\n", - "\n<author>\n%s\n" - "<date>\n%s\n", + "\n<author>\n%s\n" + "<date>\n%s\n", - "\n<sect>\n", - "\n<p>\n", - "\n<newline>\n", - "\n\n", + "\n<sect>\n", + "\n<p>\n", + "\n<newline>\n", + "\n\n", - "&%s;", + "&%s;", - "<em>", - "</em>", - "<bf>", - "</bf>", - "<tt>", - "</tt>", + "<em>", + "</em>", + "<bf>", + "</bf>", + "<tt>", + "</tt>", - "\n</article>\n" + "\n</article>\n" }; CHARMAP charmap = - {{'Æ', "AElig"}, - {'Á', "Aacute"}, - {'Â', "Acirc"}, - {'À', "Agrave"}, - {'Ã', "Atilde"}, - {'Ç', "Ccedil"}, - {'É', "Eacute"}, - {'È', "Egrave"}, - {'Ë', "Euml"}, - {'Í', "Iacute"}, - {'Î', "Icirc"}, - {'Ì', "Igrave"}, - {'Ï', "Iuml"}, - {'Ñ', "Ntilde"}, - {'Ó', "Oacute"}, - {'Ô', "Ocirc"}, - {'Ò', "Ograve"}, - {'Ø', "Oslash"}, - {'Ú', "Uacute"}, - {'Ù', "Ugrave"}, - {'Ý', "Yacute"}, - {'á', "aacute"}, - {'â', "acirc"}, - {'æ', "aelig"}, - {'à', "agrave"}, - {'å', "aring"}, - {'ã', "atilde"}, - {'ç', "ccedil"}, - {'é', "eacute"}, - {'ê', "ecirc"}, - {'è', "egrave"}, - {'ë', "euml"}, - {'í', "iacute"}, - {'î', "icirc"}, - {'ì', "igrave"}, - {'ï', "iuml"}, - {'ñ', "ntilde"}, - {'ó', "oacute"}, - {'ÿ', "yuml"}, - {'ô', "ocirc"}, - {'ò', "ograve"}, - {'ø', "oslash"}, - {'õ', "otilde"}, - {'ú', "uacute"}, - {'û', "ucirc"}, - {'ù', "ugrave"}, - {'ý', "yacute"}, - {'<', "lt"}, - {'&', "amp"}, - {'"', "dquot"}, - {'#', "num"}, - {'%', "percnt"}, - {'\'', "quot"}, +{{'Æ', "AElig"}, + {'Á', "Aacute"}, + {'Â', "Acirc"}, + {'À', "Agrave"}, + {'Ã', "Atilde"}, + {'Ç', "Ccedil"}, + {'É', "Eacute"}, + {'È', "Egrave"}, + {'Ë', "Euml"}, + {'Í', "Iacute"}, + {'Î', "Icirc"}, + {'Ì', "Igrave"}, + {'Ï', "Iuml"}, + {'Ñ', "Ntilde"}, + {'Ó', "Oacute"}, + {'Ô', "Ocirc"}, + {'Ò', "Ograve"}, + {'Ø', "Oslash"}, + {'Ú', "Uacute"}, + {'Ù', "Ugrave"}, + {'Ý', "Yacute"}, + {'á', "aacute"}, + {'â', "acirc"}, + {'æ', "aelig"}, + {'à', "agrave"}, + {'å', "aring"}, + {'ã', "atilde"}, + {'ç', "ccedil"}, + {'é', "eacute"}, + {'ê', "ecirc"}, + {'è', "egrave"}, + {'ë', "euml"}, + {'í', "iacute"}, + {'î', "icirc"}, + {'ì', "igrave"}, + {'ï', "iuml"}, + {'ñ', "ntilde"}, + {'ó', "oacute"}, + {'ÿ', "yuml"}, + {'ô', "ocirc"}, + {'ò', "ograve"}, + {'ø', "oslash"}, + {'õ', "otilde"}, + {'ú', "uacute"}, + {'û', "ucirc"}, + {'ù', "ugrave"}, + {'ý', "yacute"}, + {'<', "lt"}, + {'&', "amp"}, + {'"', "dquot"}, + {'#', "num"}, + {'%', "percnt"}, + {'\'', "quot"}, #if 0 - {'(', "lpar"}, - {')', "rpar"}, - {'*', "ast"}, - {'+', "plus"}, - {',', "comma"}, - {'-', "hyphen"}, - {':', "colon"}, - {';', "semi"}, - {'=', "equals"}, - {'@', "commat"}, - {'[', "lsqb"}, - {']', "rsqb"}, - {'^', "circ"}, - {'_', "lowbar"}, - {'{', "lcub"}, - {'|', "verbar"}, - {'}', "rcub"}, - {'~', "tilde"}, + {'(', "lpar"}, + {')', "rpar"}, + {'*', "ast"}, + {'+', "plus"}, + {',', "comma"}, + {'-', "hyphen"}, + {':', "colon"}, + {';', "semi"}, + {'=', "equals"}, + {'@', "commat"}, + {'[', "lsqb"}, + {']', "rsqb"}, + {'^', "circ"}, + {'_', "lowbar"}, + {'{', "lcub"}, + {'|', "verbar"}, + {'}', "rcub"}, + {'~', "tilde"}, #endif - {'\\', "bsol"}, - {'$', "dollar"}, - {'Ä', "Auml"}, - {'ä', "auml"}, - {'Ö', "Ouml"}, - {'ö', "ouml"}, - {'Ü', "Uuml"}, - {'ü', "uuml"}, - {'ß', "szlig"}, - {'>', "gt"}, - {'§', "sect"}, - {'¶', "para"}, - {'©', "copy"}, - {'¡', "iexcl"}, - {'¿', "iquest"}, - {'¢', "cent"}, - {'£', "pound"}, - {'×', "times"}, - {'±', "plusmn"}, - {'÷', "divide"}, - {'¬', "not"}, - {'µ', "mu"}, - {0,0}}; + {'\\', "bsol"}, + {'$', "dollar"}, + {'Ä', "Auml"}, + {'ä', "auml"}, + {'Ö', "Ouml"}, + {'ö', "ouml"}, + {'Ü', "Uuml"}, + {'ü', "uuml"}, + {'ß', "szlig"}, + {'>', "gt"}, + {'§', "sect"}, + {'¶', "para"}, + {'©', "copy"}, + {'¡', "iexcl"}, + {'¿', "iquest"}, + {'¢', "cent"}, + {'£', "pound"}, + {'×', "times"}, + {'±', "plusmn"}, + {'÷', "divide"}, + {'¬', "not"}, + {'µ', "mu"}, + {0,0}}; /*********************************************************************** * @@ -181,18 +182,18 @@ CHARMAP charmap = static void print_text(const char *p) { - int i; + int i; - for (; *p; p++) + for (; *p; p++) { - for (i = 0; charmap[i].ch; i++) - if (*p == charmap[i].ch) - { - printf(format.special_char, charmap[i].subst); - break; - } - if (!charmap[i].ch) - printf("%c", *p); + for (i = 0; charmap[i].ch; i++) + if (*p == charmap[i].ch) + { + printf(format.special_char, charmap[i].subst); + break; + } + if (!charmap[i].ch) + printf("%c", *p); } } @@ -203,60 +204,68 @@ static void print_text(const char *p) int main(int argc, char **argv) { - HLPFILE *hlpfile; - HLPFILE_PAGE *page; - HLPFILE_PARAGRAPH *paragraph; - time_t t; - char date[50]; - char *filename; + HLPFILE *hlpfile; + HLPFILE_PAGE *page; + HLPFILE_PARAGRAPH *paragraph; + time_t t; + char date[50]; + char *filename; - hlpfile = HLPFILE_ReadHlpFile(argc > 1 ? argv[1] : ""); + hlpfile = HLPFILE_ReadHlpFile(argc > 1 ? argv[1] : ""); - if (!hlpfile) return(2); + if (!hlpfile) return 2; - time(&t); - strftime(date, sizeof(date), "%x", localtime(&t)); - filename = strrchr(hlpfile->lpszPath, '/'); - if (filename) filename++; - else filename = hlpfile->lpszPath; + time(&t); + strftime(date, sizeof(date), "%x", localtime(&t)); + filename = strrchr(hlpfile->lpszPath, '/'); + if (filename) filename++; + else filename = hlpfile->lpszPath; - /* Header */ - printf(format.header1); - print_text(hlpfile->lpszTitle); - printf(format.header2, filename, date); + /* Header */ + printf(format.header1); + print_text(hlpfile->lpszTitle); + printf(format.header2, filename, date); - for (page = hlpfile->first_page; page; page = page->next) + for (page = hlpfile->first_page; page; page = page->next) { - paragraph = page->first_paragraph; - if (!paragraph) continue; + paragraph = page->first_paragraph; + if (!paragraph) continue; - /* Section */ - printf(format.section); - for (; paragraph && !paragraph->wVSpace; paragraph = paragraph->next) - print_text(paragraph->lpszText); - printf(format.first_paragraph); + /* Section */ + printf(format.section); + for (; paragraph && !paragraph->u.text.wVSpace; paragraph = paragraph->next) + print_text(paragraph->u.text.lpszText); + printf(format.first_paragraph); - for (; paragraph; paragraph = paragraph->next) + for (; paragraph; paragraph = paragraph->next) { - /* New line; new paragraph */ - if (paragraph->wVSpace == 1) - printf(format.newline); - else if (paragraph->wVSpace > 1) - printf(format.next_paragraph); + switch (paragraph->cookie) + { + case para_normal_text: + case para_debug_text: + /* New line; new paragraph */ + if (paragraph->u.text.wVSpace == 1) + printf(format.newline); + else if (paragraph->u.text.wVSpace > 1) + printf(format.next_paragraph); - if (paragraph->wFont) - printf(format.begin_boldface); + if (paragraph->u.text.wFont) + printf(format.begin_boldface); - print_text(paragraph->lpszText); + print_text(paragraph->u.text.lpszText); - if (paragraph->wFont) - printf(format.end_boldface); + if (paragraph->u.text.wFont) + printf(format.end_boldface); + break; + case para_image: + break; + } } } - printf(format.tail); + printf(format.tail); - return(0); + return 0; } /*********************************************************************** @@ -268,64 +277,92 @@ static FILE *file = 0; HFILE WINAPI OpenFile( LPCSTR path, OFSTRUCT *ofs, UINT mode ) { - file = *path ? fopen(path, "r") : stdin; - return file ? (HFILE)1 : HFILE_ERROR; + file = *path ? fopen(path, "r") : stdin; + return file ? (HFILE)1 : HFILE_ERROR; } HFILE WINAPI _lclose( HFILE hFile ) { - fclose(file); - return 0; + fclose(file); + return 0; } LONG WINAPI _hread( HFILE hFile, LPVOID buffer, LONG count ) { - return fread(buffer, 1, count, file); + return fread(buffer, 1, count, file); } -HGLOBAL WINAPI GlobalAlloc( UINT flags, DWORD size ) +void* WINAPI HeapAlloc( HANDLE heap, DWORD flags, DWORD size ) { - return (HGLOBAL) malloc(size); + assert(flags == 0); + return malloc(size); } -LPVOID WINAPI GlobalLock( HGLOBAL handle ) +void* WINAPI HeapReAlloc( HANDLE heap, DWORD flags, void* ptr, DWORD size) { - return (LPVOID) handle; + assert(flags == 0); + return realloc(ptr, size); } -HGLOBAL WINAPI GlobalFree( HGLOBAL handle ) +BOOL WINAPI HeapFree( HGLOBAL handle, DWORD flags, void* ptr ) { - free((VOID*) handle); - return(0); + free(ptr); + return TRUE; } +char __wine_dbch_winhelp[] = "\003winhelp"; + +static char * const debug_channels[1] = +{ + __wine_dbch_winhelp +}; + +int wine_dbg_log( int cls, const char *channel, const char *func, const char *format, ... ) +{ + return 1; +} + +HBITMAP WINAPI CreateDIBitmap(HDC hdc, CONST BITMAPINFOHEADER* bih, DWORD a, CONST void* ptr, CONST BITMAPINFO* bi, UINT c) +{ + return 0; +} + +HDC WINAPI GetDC(HWND h) +{ + return 0; +} + +BOOL WINAPI DeleteObject(HGDIOBJ h) +{ + return TRUE; +} /* * String functions * * Copyright 1993 Yngvi Sigurjonsson (yngvi@hafro.is) */ -INT WINAPI lstrcmp(LPCSTR str1,LPCSTR str2) +INT WINAPI lstrcmp( LPCSTR str1, LPCSTR str2 ) { - return strcmp( str1, str2 ); + return strcmp( str1, str2 ); } INT WINAPI lstrcmpi( LPCSTR str1, LPCSTR str2 ) { - INT res; + INT res; - while (*str1) + while (*str1) { - if ((res = toupper(*str1) - toupper(*str2)) != 0) return res; - str1++; - str2++; + if ((res = toupper(*str1) - toupper(*str2)) != 0) return res; + str1++; + str2++; } - return toupper(*str1) - toupper(*str2); + return toupper(*str1) - toupper(*str2); } -INT WINAPI lstrlen(LPCSTR str) +INT WINAPI lstrlen( LPCSTR str ) { - return strlen(str); + return strlen(str); } LPSTR WINAPI lstrcpyA( LPSTR dst, LPCSTR src ) @@ -334,12 +371,3 @@ LPSTR WINAPI lstrcpyA( LPSTR dst, LPCSTR src ) strcpy( dst, src ); return dst; } - -void WINAPI hmemcpy16(LPVOID hpvDest, LPCVOID hpvSource, LONG cbCopy) -{ - memcpy(hpvDest, hpvSource, cbCopy); -} - -/* Local Variables: */ -/* c-file-style: "GNU" */ -/* End: */ diff --git a/programs/winhelp/hlpfile.c b/programs/winhelp/hlpfile.c index 76e0aa02588..064237faba6 100644 --- a/programs/winhelp/hlpfile.c +++ b/programs/winhelp/hlpfile.c @@ -1,7 +1,8 @@ /* * Help Viewer * - * Copyright 1996 Ulrich Schmid + * Copyright 1996 Ulrich Schmid + * 2002 Eric Pouech * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,16 +21,13 @@ #include <stdio.h> #include <string.h> -#include "windows.h" -#include "windowsx.h" +#include "winbase.h" +#include "wingdi.h" #include "winhelp.h" -static void Report(LPCSTR str) -{ -#if 0 - fprintf(stderr, "%s\n", str); -#endif -} +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(winhelp); #define GET_USHORT(buffer, i)\ (((BYTE)((buffer)[(i)]) + 0x100 * (BYTE)((buffer)[(i)+1]))) @@ -38,814 +36,1367 @@ static void Report(LPCSTR str) #define GET_UINT(buffer, i)\ GET_USHORT(buffer, i) + 0x10000 * GET_USHORT(buffer, i+2) -static BOOL HLPFILE_DoReadHlpFile(HLPFILE*, LPCSTR); -static BOOL HLPFILE_ReadFileToBuffer(HFILE); -static BOOL HLPFILE_FindSubFile(LPCSTR name, BYTE**, BYTE**); -static VOID HLPFILE_SystemCommands(HLPFILE*); -static BOOL HLPFILE_Uncompress1_Phrases(); -static BOOL HLPFILE_Uncompress1_Topic(); -static BOOL HLPFILE_GetContext(HLPFILE*); -static BOOL HLPFILE_AddPage(HLPFILE*, BYTE*, BYTE*); -static BOOL HLPFILE_AddParagraph(HLPFILE*, BYTE *, BYTE*); -static UINT HLPFILE_Uncompressed2_Size(BYTE*, BYTE*); -static VOID HLPFILE_Uncompress2(BYTE**, BYTE*, BYTE*); - static HLPFILE *first_hlpfile = 0; -static HGLOBAL hFileBuffer; static BYTE *file_buffer; static struct { - UINT num; - BYTE *buf; - HGLOBAL hBuffer; + UINT num; + unsigned* offsets; + char* buffer; } phrases; static struct { - BYTE **map; - BYTE *end; - UINT wMapLen; - HGLOBAL hMap; - HGLOBAL hBuffer; + BYTE** map; + BYTE* end; + UINT wMapLen; } topic; static struct { - UINT bDebug; - UINT wFont; - UINT wIndent; - UINT wHSpace; - UINT wVSpace; - UINT wVBackSpace; - HLPFILE_LINK link; + UINT bDebug; + UINT wFont; + UINT wIndent; + UINT wHSpace; + UINT wVSpace; + UINT wVBackSpace; + HLPFILE_LINK link; + HBITMAP hBitmap; + UINT bmpPos; } attributes; +static BOOL HLPFILE_DoReadHlpFile(HLPFILE*, LPCSTR); +static BOOL HLPFILE_ReadFileToBuffer(HFILE); +static BOOL HLPFILE_FindSubFile(LPCSTR name, BYTE**, BYTE**); +static BOOL HLPFILE_SystemCommands(HLPFILE*); +static INT HLPFILE_UncompressedLZ77_Size(BYTE *ptr, BYTE *end); +static BYTE* HLPFILE_UncompressLZ77(BYTE *ptr, BYTE *end, BYTE *newptr); +static BOOL HLPFILE_UncompressLZ77_Phrases(HLPFILE*); +static BOOL HLPFILE_Uncompress_Phrases40(HLPFILE*); +static BOOL HLPFILE_UncompressLZ77_Topic(HLPFILE*); +static BOOL HLPFILE_GetContext(HLPFILE*); +static BOOL HLPFILE_AddPage(HLPFILE*, BYTE*, BYTE*, unsigned); +static BOOL HLPFILE_AddParagraph(HLPFILE*, BYTE *, BYTE*, unsigned*); +static UINT HLPFILE_Uncompressed2_Size(BYTE*, BYTE*); +static void HLPFILE_Uncompress2(BYTE**, BYTE*, BYTE*); +static BOOL HLPFILE_Uncompress3(char*, const char*, const BYTE*, const BYTE*); +static void HLPFILE_UncompressRLE(const BYTE* src, unsigned sz, BYTE** dst); +static BOOL HLPFILE_ReadFont(HLPFILE* hlpfile); + /*********************************************************************** * * HLPFILE_Contents */ - HLPFILE_PAGE *HLPFILE_Contents(LPCSTR lpszPath) { - HLPFILE *hlpfile = HLPFILE_ReadHlpFile(lpszPath); + HLPFILE *hlpfile = HLPFILE_ReadHlpFile(lpszPath); - if (!hlpfile) return(0); + if (!hlpfile) return 0; - return(hlpfile->first_page); + return hlpfile->first_page; } /*********************************************************************** * * HLPFILE_PageByNumber */ - HLPFILE_PAGE *HLPFILE_PageByNumber(LPCSTR lpszPath, UINT wNum) { - HLPFILE_PAGE *page; - HLPFILE *hlpfile = HLPFILE_ReadHlpFile(lpszPath); + HLPFILE_PAGE *page; + HLPFILE *hlpfile = HLPFILE_ReadHlpFile(lpszPath); - if (!hlpfile) return(0); + if (!hlpfile) return 0; - for (page = hlpfile->first_page; page && wNum; page = page->next) wNum--; + WINE_TRACE("[%s/%u]\n", lpszPath, wNum); - return page; + for (page = hlpfile->first_page; page && wNum; page = page->next) wNum--; + + return page; } /*********************************************************************** * * HLPFILE_HlpFilePageByHash */ - HLPFILE_PAGE *HLPFILE_PageByHash(LPCSTR lpszPath, LONG lHash) { - INT i; - UINT wNum; - HLPFILE_PAGE *page; - HLPFILE *hlpfile = HLPFILE_ReadHlpFile(lpszPath); + HLPFILE_PAGE* page; + HLPFILE_PAGE* found; + HLPFILE* hlpfile = HLPFILE_ReadHlpFile(lpszPath); + int i; - if (!hlpfile) return(0); + WINE_TRACE("path<%s>[%lx]\n", lpszPath, lHash); - for (i = 0; i < hlpfile->wContextLen; i++) - if (hlpfile->Context[i].lHash == lHash) break; + if (!hlpfile) return 0; - if (i >= hlpfile->wContextLen) + page = NULL; + for (i = 0; i < hlpfile->wContextLen; i++) { - HLPFILE_FreeHlpFile(hlpfile); - return(0); + if (hlpfile->Context[i].lHash != lHash) continue; + + /* 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, lpszPath); + return NULL; } - - wNum = hlpfile->Context[i].wPage; - for (page = hlpfile->first_page; page && wNum; page = page->next) wNum--; - - return page; + WINE_ERR("Page of hash %lx not found in file %s\n", lHash, lpszPath); + return NULL; } /*********************************************************************** * * HLPFILE_Hash */ - LONG HLPFILE_Hash(LPCSTR lpszContext) { - LONG lHash = 0; - CHAR c; - while((c = *lpszContext++)) - { - CHAR x = 0; - if (c >= 'A' && c <= 'Z') x = c - 'A' + 17; - if (c >= 'a' && c <= 'z') x = c - 'a' + 17; - if (c >= '1' && c <= '9') x = c - '0'; - if (c == '0') x = 10; - if (c == '.') x = 12; - if (c == '_') x = 13; - if (x) lHash = lHash * 43 + x; - } - return lHash; -} + LONG lHash = 0; + CHAR c; + while ((c = *lpszContext++)) + { + CHAR x = 0; + if (c >= 'A' && c <= 'Z') x = c - 'A' + 17; + if (c >= 'a' && c <= 'z') x = c - 'a' + 17; + if (c >= '1' && c <= '9') x = c - '0'; + if (c == '0') x = 10; + if (c == '.') x = 12; + if (c == '_') x = 13; + if (x) lHash = lHash * 43 + x; + } + return lHash; +} /*********************************************************************** * * HLPFILE_ReadHlpFile */ - HLPFILE *HLPFILE_ReadHlpFile(LPCSTR lpszPath) { - HGLOBAL hHlpFile; - HLPFILE *hlpfile; + HLPFILE* hlpfile; - for (hlpfile = first_hlpfile; hlpfile; hlpfile = hlpfile->next) - if (!lstrcmp(hlpfile->lpszPath, lpszPath)) - { - hlpfile->wRefCount++; - return(hlpfile); - } - - hHlpFile = GlobalAlloc(GMEM_FIXED, sizeof(HLPFILE) + lstrlen(lpszPath) + 1); - if (!hHlpFile) return(0); - - hlpfile = GlobalLock(hHlpFile); - hlpfile->hSelf = hHlpFile; - hlpfile->wRefCount = 1; - hlpfile->hTitle = 0; - hlpfile->hContext = 0; - hlpfile->wContextLen = 0; - hlpfile->first_page = 0; - hlpfile->first_macro = 0; - hlpfile->prev = 0; - hlpfile->next = first_hlpfile; - first_hlpfile = hlpfile; - if (hlpfile->next) hlpfile->next->prev = hlpfile; - - hlpfile->lpszPath = GlobalLock(hHlpFile); - hlpfile->lpszPath += sizeof(HLPFILE); - strcpy(hlpfile->lpszPath, lpszPath); - - phrases.hBuffer = topic.hBuffer = hFileBuffer = 0; - - if (!HLPFILE_DoReadHlpFile(hlpfile, lpszPath)) + for (hlpfile = first_hlpfile; hlpfile; hlpfile = hlpfile->next) { - HLPFILE_FreeHlpFile(hlpfile); - hlpfile = 0; + if (!lstrcmp(hlpfile->lpszPath, lpszPath)) + { + hlpfile->wRefCount++; + return hlpfile; + } } - if (phrases.hBuffer) GlobalFree(phrases.hBuffer); - if (topic.hBuffer) GlobalFree(topic.hBuffer); - if (topic.hMap) GlobalFree(topic.hMap); - if (hFileBuffer) GlobalFree(hFileBuffer); + hlpfile = HeapAlloc(GetProcessHeap(), 0, sizeof(HLPFILE) + lstrlen(lpszPath) + 1); + if (!hlpfile) return 0; - return(hlpfile); + hlpfile->wRefCount = 1; + hlpfile->Context = NULL; + hlpfile->wContextLen = 0; + hlpfile->first_page = NULL; + hlpfile->first_macro = NULL; + hlpfile->prev = NULL; + hlpfile->next = first_hlpfile; + hlpfile->lpszPath = (char*)hlpfile + sizeof(HLPFILE); + hlpfile->lpszTitle = NULL; + + hlpfile->numFonts = 0; + hlpfile->fonts = NULL; + + strcpy(hlpfile->lpszPath, lpszPath); + + first_hlpfile = hlpfile; + if (hlpfile->next) hlpfile->next->prev = hlpfile; + + phrases.offsets = NULL; + phrases.buffer = NULL; + topic.map = NULL; + topic.end = NULL; + file_buffer = NULL; + + if (!HLPFILE_DoReadHlpFile(hlpfile, lpszPath)) + { + HLPFILE_FreeHlpFile(hlpfile); + hlpfile = 0; + } + + if (phrases.offsets) HeapFree(GetProcessHeap(), 0, phrases.offsets); + if (phrases.buffer) HeapFree(GetProcessHeap(), 0, phrases.buffer); + if (topic.map) HeapFree(GetProcessHeap(), 0, topic.map); + if (file_buffer) HeapFree(GetProcessHeap(), 0, file_buffer); + + return hlpfile; } /*********************************************************************** * * HLPFILE_DoReadHlpFile */ - static BOOL HLPFILE_DoReadHlpFile(HLPFILE *hlpfile, LPCSTR lpszPath) { - BOOL ret; - HFILE hFile; - OFSTRUCT ofs; - BYTE *buf; + BOOL ret; + HFILE hFile; + OFSTRUCT ofs; + BYTE* buf; + DWORD ref = 0x0C; + unsigned index, old_index, offset, len, offs; - hFile=OpenFile(lpszPath, &ofs, OF_READ | OF_SEARCH); - if (hFile == HFILE_ERROR) return FALSE; + hFile = OpenFile(lpszPath, &ofs, OF_READ | OF_SEARCH); + if (hFile == HFILE_ERROR) return FALSE; - ret = HLPFILE_ReadFileToBuffer(hFile); - _lclose(hFile); - if (!ret) return FALSE; + ret = HLPFILE_ReadFileToBuffer(hFile); + _lclose(hFile); + if (!ret) return FALSE; - HLPFILE_SystemCommands(hlpfile); - if (!HLPFILE_Uncompress1_Phrases()) return FALSE; - if (!HLPFILE_Uncompress1_Topic()) return FALSE; + if (!HLPFILE_SystemCommands(hlpfile)) return FALSE; + if (!HLPFILE_UncompressLZ77_Phrases(hlpfile) && + !HLPFILE_Uncompress_Phrases40(hlpfile)) + return FALSE; + if (!HLPFILE_UncompressLZ77_Topic(hlpfile)) return FALSE; + if (!HLPFILE_ReadFont(hlpfile)) return FALSE; - buf = topic.map[0] + 0xc; - while(buf + 0xc < topic.end) + buf = topic.map[0]; + old_index = -1; + offs = 0; + do { - BYTE *end = min(buf + GET_UINT(buf, 0), topic.end); - UINT next, index, offset; + BYTE* end; - switch (buf[0x14]) + /* FIXME this depends on the blocksize, can be 2k in some cases */ + index = (ref - 0x0C) >> 14; + offset = (ref - 0x0C) & 0x3fff; + + WINE_TRACE("ref=%08lx => [%u/%u]\n", ref, index, offset); + + if (index >= topic.wMapLen) {WINE_WARN("maplen\n"); break;} + buf = topic.map[index] + offset; + if (buf + 0x15 >= topic.end) {WINE_WARN("extra\n"); break;} + end = min(buf + GET_UINT(buf, 0), topic.end); + if (index != old_index) {offs = 0; old_index = index;} + + switch (buf[0x14]) { case 0x02: - if (!HLPFILE_AddPage(hlpfile, buf, end)) return(FALSE); - break; + if (!HLPFILE_AddPage(hlpfile, buf, end, index * 0x8000L + offs)) return FALSE; + break; case 0x20: - if (!HLPFILE_AddParagraph(hlpfile, buf, end)) return(FALSE); - break; + if (!HLPFILE_AddParagraph(hlpfile, buf, end, &len)) return FALSE; + offs += len; + break; case 0x23: - if (!HLPFILE_AddParagraph(hlpfile, buf, end)) return(FALSE); - break; + if (!HLPFILE_AddParagraph(hlpfile, buf, end, &len)) return FALSE; + offs += len; + break; default: - fprintf(stderr, "buf[0x14] = %x\n", buf[0x14]); + WINE_ERR("buf[0x14] = %x\n", buf[0x14]); } - next = GET_UINT(buf, 0xc); - if (next == 0xffffffff) break; + ref = GET_UINT(buf, 0xc); + } while (ref != 0xffffffff); - index = next >> 14; - offset = next & 0x3fff; - if (index > topic.wMapLen) {Report("maplen"); break;} - buf = topic.map[index] + offset; - } - - return(HLPFILE_GetContext(hlpfile)); + return HLPFILE_GetContext(hlpfile); } /*********************************************************************** * * HLPFILE_AddPage */ - -static BOOL HLPFILE_AddPage(HLPFILE *hlpfile, BYTE *buf, BYTE *end) +static BOOL HLPFILE_AddPage(HLPFILE *hlpfile, BYTE *buf, BYTE *end, unsigned offset) { - HGLOBAL hPage; - HLPFILE_PAGE *page, **pageptr; - BYTE *title; - UINT titlesize; + HLPFILE_PAGE* page; + BYTE* title; + UINT titlesize; - for (pageptr = &hlpfile->first_page; *pageptr; pageptr = &(*pageptr)->next) - /* Nothing */; + 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;}; - if (buf + 0x31 > end) {Report("page1"); return(FALSE);}; - title = buf + GET_UINT(buf, 0x10); - if (title > end) {Report("page2"); return(FALSE);}; + if (GET_UINT(buf, 0x4) > GET_UINT(buf, 0) - GET_UINT(buf, 0x10)) + { + if (hlpfile->hasPhrases) + { + titlesize = HLPFILE_Uncompressed2_Size(title, end); + page = HeapAlloc(GetProcessHeap(), 0, sizeof(HLPFILE_PAGE) + titlesize); + if (!page) return FALSE; - titlesize = HLPFILE_Uncompressed2_Size(title, end); - hPage = GlobalAlloc(GMEM_FIXED, sizeof(HLPFILE_PAGE) + titlesize); - if (!hPage) return FALSE; - page = *pageptr = GlobalLock(hPage); - pageptr = &page->next; - page->hSelf = hPage; - page->file = hlpfile; - page->next = 0; - page->first_paragraph = 0; + page->lpszTitle = (char*)page + sizeof(HLPFILE_PAGE); + HLPFILE_Uncompress2(&title, end, page->lpszTitle); + } + else + { + titlesize = GET_UINT(buf, 4) + 1; + page = HeapAlloc(GetProcessHeap(), 0, sizeof(HLPFILE_PAGE) + titlesize); + if (!page) return FALSE; + page->lpszTitle = (char*)page + sizeof(HLPFILE_PAGE); - page->lpszTitle = GlobalLock(hPage); - page->lpszTitle += sizeof(HLPFILE_PAGE); - HLPFILE_Uncompress2(&title, end, page->lpszTitle); + HLPFILE_Uncompress3(page->lpszTitle, page->lpszTitle + titlesize, title, end); + } + } + else + { + titlesize = GET_UINT(buf, 0x4); + page = HeapAlloc(GetProcessHeap(), 0, sizeof(HLPFILE_PAGE) + titlesize); + if (!page) return FALSE; - page->wNumber = GET_UINT(buf, 0x21); + page->lpszTitle = (char*)page + sizeof(HLPFILE_PAGE); + memcpy(page->lpszTitle, title, titlesize); + } - attributes.bDebug = 0; - attributes.wFont = 0; - attributes.wVSpace = 0; - attributes.wVBackSpace = 0; - attributes.wHSpace = 0; - attributes.wIndent = 0; - attributes.link.lpszPath = 0; + if (hlpfile->first_page) + { + HLPFILE_PAGE *p; - return TRUE; + for (p = hlpfile->first_page; p->next; p = p->next); + page->prev = p; + p->next = page; + } + else + { + hlpfile->first_page = page; + page->prev = NULL; + } + + page->file = hlpfile; + page->next = NULL; + page->first_paragraph = 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); + + memset(&attributes, 0, sizeof(attributes)); + + return TRUE; +} + +static long fetch_long(BYTE** ptr) +{ + long ret; + + if (*(*ptr) & 1) + { + ret = (*(unsigned long*)(*ptr) - 0x80000000L) / 2; + (*ptr) += 4; + } + else + { + ret = (*(unsigned short*)(*ptr) - 0x8000) / 2; + (*ptr) += 2; + } + + return ret; +} + +static unsigned long fetch_ulong(BYTE** ptr) +{ + unsigned long ret; + + if (*(*ptr) & 1) + { + ret = *(unsigned long*)(*ptr) / 2; + (*ptr) += 4; + } + else + { + ret = *(unsigned short*)(*ptr) / 2; + (*ptr) += 2; + } + return ret; +} + +static short fetch_short(BYTE** ptr) +{ + short ret; + + if (*(*ptr) & 1) + { + ret = (*(unsigned short*)(*ptr) - 0x8000) / 2; + (*ptr) += 2; + } + else + { + ret = (*(unsigned char*)(*ptr) - 0x80) / 2; + (*ptr)++; + } + return ret; +} + +static unsigned short fetch_ushort(BYTE** ptr) +{ + unsigned short ret; + + if (*(*ptr) & 1) + { + ret = *(unsigned short*)(*ptr) / 2; + (*ptr) += 2; + } + else + { + ret = *(unsigned char*)(*ptr) / 2; + (*ptr)++; + } + return ret; +} + +/****************************************************************** + * HLPFILE_LoadPictureByAddr + * + * + */ +static BOOL HLPFILE_LoadPictureByAddr(HLPFILE *hlpfile, char* ref, + unsigned long size, unsigned pos) +{ + unsigned i, numpict; + + numpict = *(unsigned short*)(ref + 2); + + for (i = 0; i < numpict; i++) + { + BYTE *beg, *ptr; + BYTE *pict_beg; + BYTE type, pack; + BITMAPINFO* bi; + unsigned long off, sz; + unsigned shift; + + ptr = beg = ref + *((unsigned long*)ref + 1 + i); + + type = *ptr++; + pack = *ptr++; + + bi = HeapAlloc(GetProcessHeap(), 0, sizeof(*bi)); + if (!bi) return FALSE; + + bi->bmiHeader.biSize = sizeof(bi->bmiHeader); + bi->bmiHeader.biXPelsPerMeter = fetch_ulong(&ptr); + bi->bmiHeader.biYPelsPerMeter = fetch_ulong(&ptr); + bi->bmiHeader.biPlanes = fetch_ushort(&ptr); + bi->bmiHeader.biBitCount = fetch_ushort(&ptr); + bi->bmiHeader.biWidth = fetch_ulong(&ptr); + bi->bmiHeader.biHeight = fetch_ulong(&ptr); + bi->bmiHeader.biClrUsed = fetch_ulong(&ptr); + bi->bmiHeader.biClrImportant = fetch_ulong(&ptr); + bi->bmiHeader.biCompression = BI_RGB; + if (bi->bmiHeader.biBitCount > 32) WINE_FIXME("Unknown bit count %u\n", bi->bmiHeader.biBitCount); + if (bi->bmiHeader.biPlanes != 1) WINE_FIXME("Unsupported planes %u\n", bi->bmiHeader.biPlanes); + shift = 32 / bi->bmiHeader.biBitCount; + bi->bmiHeader.biSizeImage = ((bi->bmiHeader.biWidth + shift - 1) / shift) * 4 * bi->bmiHeader.biHeight; + + sz = fetch_ulong(&ptr); + fetch_ulong(&ptr); /* hotspot size */ + + off = *(unsigned long*)ptr; ptr += 4; + /* *(unsigned long*)ptr; hotspot offset */ ptr += 4; + + /* now read palette info */ + if (type == 0x06) + { + unsigned nc = bi->bmiHeader.biClrUsed; + unsigned i; + + if (!nc) nc = 1 << bi->bmiHeader.biBitCount; + bi = HeapReAlloc(GetProcessHeap(), 0, bi, sizeof(*bi) + nc * sizeof(RGBQUAD)); + if (!bi) return FALSE; + for (i = 0; i < nc; i++) + { + bi->bmiColors[i].rgbBlue = ptr[0]; + bi->bmiColors[i].rgbGreen = ptr[1]; + bi->bmiColors[i].rgbRed = ptr[2]; + bi->bmiColors[i].rgbReserved = 0; + ptr += 4; + } + } + + switch (pack) + { + case 0: /* uncompressed */ + pict_beg = beg + off; + if (sz != bi->bmiHeader.biSizeImage) + WINE_WARN("Bogus image sizes: %lu / %lu [sz=(%lu,%lu) bc=%u pl=%u]\n", + sz, bi->bmiHeader.biSizeImage, + bi->bmiHeader.biWidth, bi->bmiHeader.biHeight, + bi->bmiHeader.biBitCount, bi->bmiHeader.biPlanes); + break; + case 1: /* RunLen */ + { + BYTE* dst; + + dst = pict_beg = HeapAlloc(GetProcessHeap(), 0, bi->bmiHeader.biSizeImage); + if (!pict_beg) return FALSE; + HLPFILE_UncompressRLE(beg + off, sz, &dst); + if (dst - pict_beg != bi->bmiHeader.biSizeImage) + WINE_FIXME("buffer XXX-flow\n"); + } + break; + case 2: /* LZ77 */ + { + unsigned long esz; + esz = HLPFILE_UncompressedLZ77_Size(beg + off, beg + off + sz); + pict_beg = HeapAlloc(GetProcessHeap(), 0, esz); + if (!pict_beg) return FALSE; + HLPFILE_UncompressLZ77(beg + off, beg + off + sz, pict_beg); + if (esz != bi->bmiHeader.biSizeImage) + WINE_WARN("Bogus image sizes: %lu / %lu [sz=(%lu,%lu) bc=%u pl=%u]\n", + esz, bi->bmiHeader.biSizeImage, + bi->bmiHeader.biWidth, bi->bmiHeader.biHeight, + bi->bmiHeader.biBitCount, bi->bmiHeader.biPlanes); + } + break; + case 3: /* LZ77 then RLE */ + { + BYTE* tmp; + unsigned long sz77; + BYTE* dst; + + sz77 = HLPFILE_UncompressedLZ77_Size(beg + off, beg + off + sz); + tmp = HeapAlloc(GetProcessHeap(), 0, bi->bmiHeader.biSizeImage); + if (!tmp) return FALSE; + HLPFILE_UncompressLZ77(beg + off, beg + off + sz, tmp); + pict_beg = dst = HeapAlloc(GetProcessHeap(), 0, bi->bmiHeader.biSizeImage); + if (!pict_beg) return FALSE; + HLPFILE_UncompressRLE(tmp, sz77, &dst); + if (dst - pict_beg != bi->bmiHeader.biSizeImage) + WINE_WARN("Bogus image sizes: %u / %lu [sz=(%lu,%lu) bc=%u pl=%u]\n", + dst - pict_beg, bi->bmiHeader.biSizeImage, + bi->bmiHeader.biWidth, bi->bmiHeader.biHeight, + bi->bmiHeader.biBitCount, bi->bmiHeader.biPlanes); + HeapFree(GetProcessHeap(), 0, tmp); + } + break; + default: + WINE_FIXME("Unsupported packing %u\n", pack); + return FALSE; + } + + attributes.hBitmap = CreateDIBitmap(GetDC(0), &bi->bmiHeader, CBM_INIT, + pict_beg, bi, DIB_RGB_COLORS); + if (!attributes.hBitmap) + WINE_ERR("Couldn't create bitmap\n"); + attributes.bmpPos = pos; + + HeapFree(GetProcessHeap(), 0, bi); + if (pict_beg != beg + off) HeapFree(GetProcessHeap(), 0, pict_beg); + + /* FIXME: implement support for multiple picture format */ + if (numpict != 1) WINE_FIXME("Supporting only one bitmap format per logical bitmap (for now). Using first format\n"); + break; + } + return TRUE; +} + +/****************************************************************** + * HLPFILE_LoadPictureByIndex + * + * + */ +static BOOL HLPFILE_LoadPictureByIndex(HLPFILE *hlpfile, unsigned index, unsigned pos) +{ + char tmp[16]; + BYTE *ref, *end; + + WINE_TRACE("Loading picture #%d\n", index); + sprintf(tmp, "bm%u", index); + + if (!HLPFILE_FindSubFile(tmp, &ref, &end)) {WINE_WARN("no sub file\n"); return FALSE;} + + ref += 9; + + return HLPFILE_LoadPictureByAddr(hlpfile, ref, end - ref, pos); } /*********************************************************************** * * HLPFILE_AddParagraph */ - -static BOOL HLPFILE_AddParagraph(HLPFILE *hlpfile, BYTE *buf, BYTE *end) +static BOOL HLPFILE_AddParagraph(HLPFILE *hlpfile, BYTE *buf, BYTE *end, unsigned* len) { - HGLOBAL hParagraph; - HLPFILE_PAGE *page; - HLPFILE_PARAGRAPH *paragraph, **paragraphptr; - UINT textsize; - BYTE *format, *text; - BOOL format_header = TRUE; - BOOL format_end = FALSE; - UINT mask, i; + HLPFILE_PAGE *page; + HLPFILE_PARAGRAPH *paragraph, **paragraphptr; + UINT textsize; + BYTE *format, *format_end, *text, *text_end; + long size; + unsigned short bits; + unsigned nc, ncol = 1; - if (!hlpfile->first_page) {Report("paragraph1"); return(FALSE);}; + if (!hlpfile->first_page) {WINE_WARN("no page\n"); return FALSE;}; - for (page = hlpfile->first_page; page->next; page = page->next) /* Nothing */; - for (paragraphptr = &page->first_paragraph; *paragraphptr; - paragraphptr = &(*paragraphptr)->next) /* Nothing */; + for (page = hlpfile->first_page; page->next; page = page->next) /* Nothing */; + for (paragraphptr = &page->first_paragraph; *paragraphptr; + paragraphptr = &(*paragraphptr)->next) /* Nothing */; - if (buf + 0x19 > end) {Report("paragraph2"); return(FALSE);}; + if (buf + 0x19 > end) {WINE_WARN("header too small\n"); return FALSE;}; - if (buf[0x14] == 0x02) return TRUE; + size = GET_UINT(buf, 0x4); - text = buf + GET_UINT(buf, 0x10); - - switch (buf[0x14]) + if (GET_UINT(buf, 0x4) > GET_UINT(buf, 0) - GET_UINT(buf, 0x10)) { - case 0x20: - format = buf + 0x18; - while (*format) format++; - format += 4; - break; + if (hlpfile->hasPhrases) + { + BYTE* lptr = buf + GET_UINT(buf, 0x10); + unsigned size2; - case 0x23: - format = buf + 0x2b; - if (buf[0x17] & 1) format++; - break; + size2 = HLPFILE_Uncompressed2_Size(lptr, end); + if (size2 != size + 1) + WINE_FIXME("Mismatch in sizes: decomp2=%u header=%lu\n", size2, size); + text = HeapAlloc(GetProcessHeap(), 0, size + 1); + if (!text) return FALSE; + HLPFILE_Uncompress2(&lptr, end, text); + } + else + { + /* block is compressed */ + text = HeapAlloc(GetProcessHeap(), 0, size); + if (!text) return FALSE; + HLPFILE_Uncompress3(text, text + size, buf + GET_UINT(buf, 0x10), end); + } + } + else + { + text = buf + GET_UINT(buf, 0x10); + } + text_end = text + size; - default: - Report("paragraph3"); - return FALSE; + format = buf + 0x15; + format_end = buf + GET_UINT(buf, 0x10); + + fetch_long(&format); + *len = fetch_ushort(&format); + if (buf[0x14] == 0x23) + { + char type; + + ncol = *format++; + + WINE_TRACE("#cols %u\n", ncol); + type = *format++; + if (type == 0 || type == 2) + format += 2; + format += ncol * 4; } - while (text < end) + for (nc = 0; nc < ncol; nc++) { - if (format_header) - { - format_header = FALSE; + WINE_TRACE("looking for format at offset %u for column %d\n", format - (buf + 0x15), nc); + if (buf[0x14] == 0x23) + format += 5; + format += 4; + bits = *(unsigned short*)format; format += 2; + if (bits & 0x0001) fetch_long(&format); + if (bits & 0x0002) fetch_short(&format); + if (bits & 0x0004) fetch_short(&format); + if (bits & 0x0008) fetch_short(&format); + if (bits & 0x0010) fetch_short(&format); + if (bits & 0x0020) fetch_short(&format); + if (bits & 0x0040) fetch_short(&format); + if (bits & 0x0100) format += 3; + if (bits & 0x0200) + { + int ntab = fetch_short(&format); + unsigned short ts; - mask = GET_USHORT(format, 0); - mask &= 0x3ff; - format += 2; + while (ntab-- > 0) + { + ts = fetch_ushort(&format); + if (ts & 0x4000) fetch_ushort(&format); + } + } - for (i = 0; i < 10; i++, mask = mask >> 1) - { - if (mask & 1) - { - BOOL twoargs = FALSE; - CHAR prefix0 = ' '; - CHAR prefix1 = '*'; + while (text < text_end && format < format_end) + { + WINE_TRACE("Got text: '%s' (%p/%p - %p/%p)\n", text, text, text_end, format, format_end); + textsize = strlen(text) + 1; + if (textsize > 1 || attributes.hBitmap) + { + paragraph = HeapAlloc(GetProcessHeap(), 0, + sizeof(HLPFILE_PARAGRAPH) + textsize); + if (!paragraph) return FALSE; + *paragraphptr = paragraph; + paragraphptr = ¶graph->next; - if (i == 9 && !twoargs) - { - switch (*format++) - { - default: - prefix0 = prefix1 = '?'; - break; + paragraph->next = NULL; + paragraph->link = NULL; - case 0x82: - prefix0 = prefix1 = 'x'; - break; + if (attributes.hBitmap) + { + paragraph->cookie = para_image; + paragraph->u.image.hBitmap = attributes.hBitmap; + paragraph->u.image.pos = attributes.bmpPos; + if (attributes.wVSpace) paragraph->u.image.pos |= 0x8000; + } + else + { + paragraph->cookie = (attributes.bDebug) ? para_debug_text : para_normal_text; + paragraph->u.text.wFont = attributes.wFont; + paragraph->u.text.wVSpace = attributes.wVSpace; + paragraph->u.text.wHSpace = attributes.wHSpace; + paragraph->u.text.wIndent = attributes.wIndent; + paragraph->u.text.lpszText = (char*)paragraph + sizeof(HLPFILE_PARAGRAPH); + strcpy(paragraph->u.text.lpszText, text); + } - case 0x84: - prefix0 = prefix1 = 'X'; - twoargs = TRUE; - } - } + if (attributes.link.lpszPath) + { + /* FIXME: should build a string table for the attributes.link.lpszPath + * they are reallocated for each link + */ + paragraph->link = HeapAlloc(GetProcessHeap(), 0, + sizeof(HLPFILE_LINK) + strlen(attributes.link.lpszPath) + 1); + if (!paragraph->link) return FALSE; - if (*format & 1) - switch(*format) - { - default: - format += 2; - break; - } - else - switch(*format) - { + paragraph->link->lpszPath = (char*)paragraph->link + sizeof(HLPFILE_LINK); + strcpy((char*)paragraph->link->lpszPath, attributes.link.lpszPath); + paragraph->link->lHash = attributes.link.lHash; - default: - format++; - break; + paragraph->link->bPopup = attributes.link.bPopup; + WINE_TRACE("Link to %s/%08lx\n", + paragraph->link->lpszPath, paragraph->link->lHash); + } +#if 0 + memset(&attributes, 0, sizeof(attributes)); +#else + attributes.hBitmap = 0; + attributes.link.lpszPath = NULL; + attributes.wVSpace = 0; + attributes.wHSpace = 0; + attributes.wIndent = 0; +#endif + } + /* else: null text, keep on storing attributes */ + text += textsize; - case 0x08: - format += 3; - break; - } + if (*format == 0xff) + { + format++; + break; + } - if (twoargs) format += (*format & 1) ? 2 : 1; - } - } - } + WINE_TRACE("format=%02x\n", *format); + switch (*format) + { + case 0x20: + WINE_FIXME("NIY\n"); + format += 5; + break; + + case 0x21: + WINE_FIXME("NIY\n"); + format += 3; + break; - for (; !format_header && text < end && format < end && !*text; text++) - { - switch(*format) - { case 0x80: - attributes.wFont = GET_USHORT(format, 1); - format += 3; - break; + attributes.wFont = GET_USHORT(format, 1); + WINE_TRACE("Changing font to %d\n", attributes.wFont); + format += 3; + break; case 0x81: - attributes.wVSpace++; - format += 1; - break; + attributes.wVSpace++; + format += 1; + break; case 0x82: - attributes.wVSpace += 2 - attributes.wVBackSpace; - attributes.wVBackSpace = 0; - attributes.wIndent = 0; - format += 1; - break; + attributes.wVSpace += 2 - attributes.wVBackSpace; + attributes.wVBackSpace = 0; + attributes.wIndent = 0; + format += 1; + break; case 0x83: - attributes.wIndent++; - format += 1; - break; + attributes.wIndent++; + format += 1; + break; +#if 0 case 0x84: - format += 3; - break; + format += 3; + break; +#endif case 0x86: case 0x87: case 0x88: - format += 9; - break; + { + BYTE pos = (*format - 0x86); + BYTE type = format[1]; + long size; + + format += 2; + size = fetch_long(&format); + switch (type) + { + case 0x22: + fetch_ushort(&format); /* hot spot */ + /* fall thru */ + case 0x03: + if (*(short*)format == 0) + HLPFILE_LoadPictureByIndex(hlpfile, + *(short*)(format + 2), + pos); + else + { + WINE_FIXME("does it work ???\n"); + HLPFILE_LoadPictureByAddr(hlpfile, format + 2, + size - 4, pos); + } + break; + case 0x05: + WINE_FIXME("Got an embedded element %s\n", format + 6); + break; + default: + WINE_FIXME("Got a type %d picture\n", type); + break; + } + format += size; + } + break; case 0x89: - attributes.wVBackSpace++; - format += 1; - break; + attributes.wVBackSpace++; + format += 1; + break; + case 0x8B: + case 0x8C: + WINE_FIXME("NIY\n"); + format += 1; + break; + +#if 0 case 0xa9: - format += 2; - break; + format += 2; + break; +#endif + + case 0xc8: + case 0xcc: + WINE_FIXME("macro NIY %s\n", format + 3); + format += GET_USHORT(format, 1) + 3; + break; + + case 0xe0: + case 0xe1: + WINE_WARN("jump topic 1 => %u\n", GET_UINT(format, 1)); + format += 5; + break; case 0xe2: case 0xe3: - attributes.link.lpszPath = hlpfile->lpszPath; - attributes.link.lHash = GET_UINT(format, 1); - attributes.link.bPopup = !(*format & 1); - format += 5; - break; + attributes.link.lpszPath = hlpfile->lpszPath; + attributes.link.lHash = GET_UINT(format, 1); + attributes.link.bPopup = !(*format & 1); + format += 5; + break; + + case 0xe6: + case 0xe7: + WINE_WARN("jump topic 2 => %u\n", GET_UINT(format, 1)); + format += 5; + break; case 0xea: - attributes.link.lpszPath = format + 8; - attributes.link.lHash = GET_UINT(format, 4); - attributes.link.bPopup = !(*format & 1); - format += 3 + GET_USHORT(format, 1); - break; + attributes.link.lpszPath = format + 8; + attributes.link.lHash = GET_UINT(format, 4); + attributes.link.bPopup = !(*format & 1); + format += 3 + GET_USHORT(format, 1); + break; - case 0xff: - if (buf[0x14] != 0x23 || GET_USHORT(format, 1) == 0xffff) - { - if (format_end) Report("format_end"); - format_end = TRUE; - break; - } - else - { - format_header = TRUE; - format += 10; - break; - } + case 0xee: + case 0xef: + case 0xeb: + WINE_WARN("jump to external file\n"); + format += 3 + GET_USHORT(format, 1); + break; default: - Report("format"); - format++; + WINE_WARN("format %02x\n", *format); + format++; } } + } + if (text_end != buf + GET_UINT(buf, 0x10) + size) + HeapFree(GetProcessHeap(), 0, text_end - size); + return TRUE; +} - if (text > end || format > end) {Report("paragraph_end"); return(FALSE);}; - if (text == end && !format_end) Report("text_end"); +/****************************************************************** + * HLPFILE_ReadFont + * + * + */ +static BOOL HLPFILE_ReadFont(HLPFILE* hlpfile) +{ + BYTE *ref, *end; + unsigned i, len, idx; + unsigned face_num, dscr_num, face_offset, dscr_offset; + BYTE flag, family; - if (text == end) break; - - textsize = HLPFILE_Uncompressed2_Size(text, end); - hParagraph = GlobalAlloc(GMEM_FIXED, sizeof(HLPFILE_PARAGRAPH) + textsize); - if (!hParagraph) return FALSE; - paragraph = *paragraphptr = GlobalLock(hParagraph); - paragraphptr = ¶graph->next; - paragraph->hSelf = hParagraph; - paragraph->next = 0; - paragraph->link = 0; - - paragraph->lpszText = GlobalLock(hParagraph); - paragraph->lpszText += sizeof(HLPFILE_PARAGRAPH); - HLPFILE_Uncompress2(&text, end, paragraph->lpszText); - - paragraph->bDebug = attributes.bDebug; - paragraph->wFont = attributes.wFont; - paragraph->wVSpace = attributes.wVSpace; - paragraph->wHSpace = attributes.wHSpace; - paragraph->wIndent = attributes.wIndent; - if (attributes.link.lpszPath) - { - LPSTR ptr; - HGLOBAL handle = GlobalAlloc(GMEM_FIXED, sizeof(HLPFILE_LINK) + - strlen(attributes.link.lpszPath) + 1); - if (!handle) return FALSE; - paragraph->link = GlobalLock(handle); - paragraph->link->hSelf = handle; - - ptr = GlobalLock(handle); - ptr += sizeof(HLPFILE_LINK); - lstrcpy(ptr, (LPSTR) attributes.link.lpszPath); - - paragraph->link->lpszPath = ptr; - paragraph->link->lHash = attributes.link.lHash; - paragraph->link->bPopup = attributes.link.bPopup; - } - - attributes.bDebug = 0; - attributes.wVSpace = 0; - attributes.wHSpace = 0; - attributes.link.lpszPath = 0; + if (!HLPFILE_FindSubFile("FONT", &ref, &end)) + { + WINE_WARN("no subfile FONT\n"); + hlpfile->numFonts = 0; + hlpfile->fonts = NULL; + return FALSE; } - return TRUE; + ref += 9; + + face_num = GET_USHORT(ref, 0); + dscr_num = GET_USHORT(ref, 2); + face_offset = GET_USHORT(ref, 4); + dscr_offset = GET_USHORT(ref, 6); + + WINE_TRACE("Got NumFacenames=%u@%u NumDesc=%u@%u\n", + face_num, face_offset, dscr_num, dscr_offset); + + hlpfile->numFonts = dscr_num; + hlpfile->fonts = HeapAlloc(GetProcessHeap(), 0, sizeof(HLPFILE_FONT) * dscr_num); + + len = (dscr_offset - face_offset) / face_num; +/* EPP for (i = face_offset; i < dscr_offset; i += len) */ +/* EPP WINE_FIXME("[%d]: %*s\n", i / len, len, ref + i); */ + for (i = 0; i < dscr_num; i++) + { + flag = ref[dscr_offset + i * 11 + 0]; + family = ref[dscr_offset + i * 11 + 2]; + + hlpfile->fonts[i].LogFont.lfHeight = -ref[dscr_offset + i * 11 + 1] / 2; + hlpfile->fonts[i].LogFont.lfWidth = 0; + hlpfile->fonts[i].LogFont.lfEscapement = 0; + hlpfile->fonts[i].LogFont.lfOrientation = 0; + hlpfile->fonts[i].LogFont.lfWeight = (flag & 1) ? 700 : 400; + hlpfile->fonts[i].LogFont.lfItalic = (flag & 2) ? TRUE : FALSE; + hlpfile->fonts[i].LogFont.lfUnderline = (flag & 4) ? TRUE : FALSE; + hlpfile->fonts[i].LogFont.lfStrikeOut = (flag & 8) ? TRUE : FALSE; + hlpfile->fonts[i].LogFont.lfCharSet = ANSI_CHARSET; + hlpfile->fonts[i].LogFont.lfOutPrecision = OUT_DEFAULT_PRECIS; + hlpfile->fonts[i].LogFont.lfClipPrecision = CLIP_DEFAULT_PRECIS; + hlpfile->fonts[i].LogFont.lfQuality = DEFAULT_QUALITY; + hlpfile->fonts[i].LogFont.lfPitchAndFamily = DEFAULT_PITCH; + + switch (family) + { + case 0x01: hlpfile->fonts[i].LogFont.lfPitchAndFamily |= FF_MODERN; break; + case 0x02: hlpfile->fonts[i].LogFont.lfPitchAndFamily |= FF_ROMAN; break; + case 0x03: hlpfile->fonts[i].LogFont.lfPitchAndFamily |= FF_SWISS; break; + case 0x04: hlpfile->fonts[i].LogFont.lfPitchAndFamily |= FF_SCRIPT; break; + case 0x05: hlpfile->fonts[i].LogFont.lfPitchAndFamily |= FF_DECORATIVE; break; + default: WINE_FIXME("Unknown family %u\n", family); + } + idx = *(unsigned short*)(ref + dscr_offset + i * 11 + 3); + + if (idx < face_num) + { + strncpy(hlpfile->fonts[i].LogFont.lfFaceName, ref + face_offset + idx * len, min(len, LF_FACESIZE - 1)); + hlpfile->fonts[i].LogFont.lfFaceName[min(len, LF_FACESIZE - 1) + 1] = '\0'; + } + else + { + WINE_FIXME("Too high face ref (%u/%u)\n", idx, face_num); + strcpy(hlpfile->fonts[i].LogFont.lfFaceName, "Helv"); + } + hlpfile->fonts[i].hFont = (HANDLE)0; + hlpfile->fonts[i].color = RGB(ref[dscr_offset + i * 11 + 5], + ref[dscr_offset + i * 11 + 6], + ref[dscr_offset + i * 11 + 7]); +#define X(b,s) ((flag & (1 << b)) ? "-"s: "") + WINE_TRACE("Font[%d]: flags=%02x%s%s%s%s%s%s pSize=%u family=%u face=%s[%u] color=%08lx\n", + i, flag, + X(0, "bold"), + X(1, "italic"), + X(2, "underline"), + X(3, "strikeOut"), + X(4, "dblUnderline"), + X(5, "smallCaps"), + ref[dscr_offset + i * 11 + 1], + family, + hlpfile->fonts[i].LogFont.lfFaceName, idx, + *(unsigned long*)(ref + dscr_offset + i * 11 + 5) & 0x00FFFFFF); + } +/* +--- only if FacenamesOffset >= 12 +unsigned short NumStyles number of style descriptors +unsigned short StyleOffset start of array of style descriptors + relative to &NumFacenames +--- only if FacenamesOffset >= 16 +unsigned short NumCharMapTables number of character mapping tables +unsigned short CharMapTableOffset start of array of character mapping +table names relative to &NumFacenames +*/ + return TRUE; } /*********************************************************************** * * HLPFILE_ReadFileToBuffer */ - static BOOL HLPFILE_ReadFileToBuffer(HFILE hFile) { - BYTE header[16], dummy[1]; - UINT size; + BYTE header[16], dummy[1]; + UINT size; - if (_hread(hFile, header, 16) != 16) {Report("header"); return(FALSE);}; + if (_hread(hFile, header, 16) != 16) {WINE_WARN("header\n"); return FALSE;}; - size = GET_UINT(header, 12); - hFileBuffer = GlobalAlloc(GMEM_FIXED, size + 1); - if (!hFileBuffer) return FALSE; - file_buffer = GlobalLock(hFileBuffer); + size = GET_UINT(header, 12); + file_buffer = HeapAlloc(GetProcessHeap(), 0, size + 1); + if (!file_buffer) return FALSE; - memcpy(file_buffer, header, 16); - if (_hread(hFile, file_buffer + 16, size - 16) != size - 16) - {Report("filesize1"); return(FALSE);}; + memcpy(file_buffer, header, 16); + if (_hread(hFile, file_buffer + 16, size - 16) != size - 16) + {WINE_WARN("filesize1\n"); return FALSE;}; - if (_hread(hFile, dummy, 1) != 0) Report("filesize2"); + if (_hread(hFile, dummy, 1) != 0) WINE_WARN("filesize2\n"); - file_buffer[size] = '0'; + file_buffer[size] = '\0'; /* FIXME: was '0', sounds ackward to me */ - return TRUE; + return TRUE; } /*********************************************************************** * * HLPFILE_FindSubFile */ - static BOOL HLPFILE_FindSubFile(LPCSTR name, BYTE **subbuf, BYTE **subend) { - BYTE *root = file_buffer + GET_UINT(file_buffer, 4); - BYTE *end = file_buffer + GET_UINT(file_buffer, 12); - BYTE *ptr = root + 0x37; + BYTE *root = file_buffer + GET_UINT(file_buffer, 4); + BYTE *end = file_buffer + GET_UINT(file_buffer, 12); + BYTE *ptr = root + 0x37; - while (ptr < end && ptr[0] == 0x7c) + while (ptr < end && ptr[0] == 0x7c) { - BYTE *fname = ptr + 1; - ptr += strlen(ptr) + 1; - if (!lstrcmpi(fname, name)) + BYTE *fname = ptr + 1; + ptr += strlen(ptr) + 1; + if (!lstrcmpi(fname, name)) { - *subbuf = file_buffer + GET_UINT(ptr, 0); - *subend = *subbuf + GET_UINT(*subbuf, 0); - if (file_buffer > *subbuf || *subbuf > *subend || *subend >= end) + *subbuf = file_buffer + GET_UINT(ptr, 0); + *subend = *subbuf + GET_UINT(*subbuf, 0); + if (file_buffer > *subbuf || *subbuf > *subend || *subend > end) { - Report("subfile"); - return FALSE; + WINE_WARN("size mismatch\n"); + return FALSE; } - return TRUE; + return TRUE; } - else ptr += 4; + else ptr += 4; } - return FALSE; + return FALSE; } /*********************************************************************** * * HLPFILE_SystemCommands */ -static VOID HLPFILE_SystemCommands(HLPFILE* hlpfile) +static BOOL HLPFILE_SystemCommands(HLPFILE* hlpfile) { - BYTE *buf, *ptr, *end; - HGLOBAL handle; - HLPFILE_MACRO *macro, **m; - LPSTR p; + BYTE *buf, *ptr, *end; + HLPFILE_MACRO *macro, **m; + LPSTR p; + unsigned short magic, minor, major, flags; - hlpfile->lpszTitle = ""; + hlpfile->lpszTitle = NULL; - if (!HLPFILE_FindSubFile("SYSTEM", &buf, &end)) return; + if (!HLPFILE_FindSubFile("SYSTEM", &buf, &end)) return FALSE; - for (ptr = buf + 0x15; ptr + 4 <= end; ptr += GET_USHORT(ptr, 2) + 4) + magic = GET_USHORT(buf + 9, 0); + minor = GET_USHORT(buf + 9, 2); + major = GET_USHORT(buf + 9, 4); + /* gen date on 4 bytes */ + flags = GET_USHORT(buf + 9, 10); + WINE_TRACE("Got system header: magic=%04x version=%d.%d flags=%04x\n", + magic, major, minor, flags); + if (magic != 0x036C || major != 1) + {WINE_WARN("Wrong system header\n"); return FALSE;} + if (minor <= 16) {WINE_WARN("too old file format (NIY)\n"); return FALSE;} + + hlpfile->version = minor; + hlpfile->flags = flags; + + for (ptr = buf + 0x15; ptr + 4 <= end; ptr += GET_USHORT(ptr, 2) + 4) { - switch (GET_USHORT(ptr, 0)) + switch (GET_USHORT(ptr, 0)) { case 1: - if (hlpfile->hTitle) {Report("title"); break;} - hlpfile->hTitle = GlobalAlloc(GMEM_FIXED, strlen(ptr + 4) + 1); - if (!hlpfile->hTitle) return; - hlpfile->lpszTitle = GlobalLock(hlpfile->hTitle); - lstrcpy(hlpfile->lpszTitle, ptr + 4); - break; + if (hlpfile->lpszTitle) {WINE_WARN("title\n"); break;} + hlpfile->lpszTitle = HeapAlloc(GetProcessHeap(), 0, strlen(ptr + 4) + 1); + if (!hlpfile->lpszTitle) return FALSE; + lstrcpy(hlpfile->lpszTitle, ptr + 4); + WINE_TRACE("Title: %s\n", hlpfile->lpszTitle); + break; case 2: - if (GET_USHORT(ptr, 2) != 1 || ptr[4] != 0) Report("system2"); - break; + if (GET_USHORT(ptr, 2) != 1 || ptr[4] != 0) WINE_WARN("system2\n"); + break; case 3: - if (GET_USHORT(ptr, 2) != 4 || GET_UINT(ptr, 4) != 0) Report("system3"); - break; + if (GET_USHORT(ptr, 2) != 4 || GET_UINT(ptr, 4) != 0) + WINE_WARN("system3\n"); + break; case 4: - handle = GlobalAlloc(GMEM_FIXED, sizeof(HLPFILE_MACRO) + lstrlen(ptr + 4) + 1); - if (!handle) break; - macro = GlobalLock(handle); - macro->hSelf = handle; - p = GlobalLock(handle); - p += sizeof(HLPFILE_MACRO); - lstrcpy(p, (LPSTR) ptr + 4); - macro->lpszMacro = p; - macro->next = 0; - m = &hlpfile->first_macro; - while (*m) m = &(*m)->next; - *m = macro; - break; + macro = HeapAlloc(GetProcessHeap(), 0, sizeof(HLPFILE_MACRO) + lstrlen(ptr + 4) + 1); + if (!macro) break; + p = (char*)macro + sizeof(HLPFILE_MACRO); + lstrcpy(p, (LPSTR)ptr + 4); + macro->lpszMacro = p; + macro->next = 0; + for (m = &hlpfile->first_macro; *m; m = &(*m)->next); + *m = macro; + break; default: - Report("system"); + WINE_WARN("Unsupport SystemRecord[%d]\n", GET_USHORT(ptr, 0)); } } + return TRUE; } /*********************************************************************** * - * HLPFILE_Uncompressed1_Size + * HLPFILE_UncompressedLZ77_Size */ - -static INT HLPFILE_Uncompressed1_Size(BYTE *ptr, BYTE *end) +static INT HLPFILE_UncompressedLZ77_Size(BYTE *ptr, BYTE *end) { - INT i, newsize = 0; + int i, newsize = 0; - while (ptr < end) + while (ptr < end) { - INT mask=*ptr++; - for (i = 0; i < 8 && ptr < end; i++, mask = mask >> 1) + int mask = *ptr++; + for (i = 0; i < 8 && ptr < end; i++, mask >>= 1) { - if (mask & 1) + if (mask & 1) { - INT code = GET_USHORT(ptr, 0); - INT len = 3 + (code >> 12); - newsize += len; - ptr += 2; + int code = GET_USHORT(ptr, 0); + int len = 3 + (code >> 12); + newsize += len; + ptr += 2; } - else newsize++, ptr++; + else newsize++, ptr++; } } - return(newsize); + return newsize; } /*********************************************************************** * - * HLPFILE_Uncompress1 + * HLPFILE_UncompressLZ77 */ - -static BYTE *HLPFILE_Uncompress1(BYTE *ptr, BYTE *end, BYTE *newptr) +static BYTE *HLPFILE_UncompressLZ77(BYTE *ptr, BYTE *end, BYTE *newptr) { - INT i; + int i; - while (ptr < end) + while (ptr < end) { - INT mask=*ptr++; - for (i = 0; i < 8 && ptr < end; i++, mask = mask >> 1) + int mask = *ptr++; + for (i = 0; i < 8 && ptr < end; i++, mask >>= 1) { - if (mask & 1) + if (mask & 1) { - INT code = GET_USHORT(ptr, 0); - INT len = 3 + (code >> 12); - INT offset = code & 0xfff; - memcpy(newptr, newptr - offset - 1, len); - newptr += len; - ptr += 2; + int code = GET_USHORT(ptr, 0); + int len = 3 + (code >> 12); + int offset = code & 0xfff; + memcpy(newptr, newptr - offset - 1, len); + newptr += len; + ptr += 2; } - else *newptr++ = *ptr++; + else *newptr++ = *ptr++; } } - return(newptr); + return newptr; } /*********************************************************************** * - * HLPFILE_Uncompress1_Phrases + * HLPFILE_UncompressLZ77_Phrases */ - -static BOOL HLPFILE_Uncompress1_Phrases() +static BOOL HLPFILE_UncompressLZ77_Phrases(HLPFILE* hlpfile) { - UINT i, num, newsize; - BYTE *buf, *end, *newbuf; + UINT i, num, dec_size; + BYTE *buf, *end; - if (!HLPFILE_FindSubFile("Phrases", &buf, &end)) {Report("phrases0"); return FALSE;} + if (!HLPFILE_FindSubFile("Phrases", &buf, &end)) return FALSE; - num = phrases.num = GET_USHORT(buf, 9); - if (buf + 2 * num + 0x13 >= end) {Report("uncompress1a"); return(FALSE);}; + num = phrases.num = GET_USHORT(buf, 9); + if (buf + 2 * num + 0x13 >= end) {WINE_WARN("1a\n"); return FALSE;}; - newsize = 2 * num + 2; - newsize += HLPFILE_Uncompressed1_Size(buf + 0x13 + 2 * num, end); - phrases.hBuffer = GlobalAlloc(GMEM_FIXED, newsize); - if (!phrases.hBuffer) return FALSE; - newbuf = phrases.buf = GlobalLock(phrases.hBuffer); + dec_size = HLPFILE_UncompressedLZ77_Size(buf + 0x13 + 2 * num, end); - memcpy(newbuf, buf + 0x11, 2 * num + 2); - HLPFILE_Uncompress1(buf + 0x13 + 2 * num, end, newbuf + 2 * num + 2); + phrases.offsets = HeapAlloc(GetProcessHeap(), 0, sizeof(unsigned) * (num + 1)); + phrases.buffer = HeapAlloc(GetProcessHeap(), 0, dec_size); + if (!phrases.offsets || !phrases.buffer) return FALSE; - for (i = 0; i < num; i++) - { - INT i0 = GET_USHORT(newbuf, 2 * i); - INT i1 = GET_USHORT(newbuf, 2 * i + 2); - if (i1 < i0 || i1 > newsize) {Report("uncompress1b"); return(FALSE);}; - } - return TRUE; + for (i = 0; i <= num; i++) + phrases.offsets[i] = GET_USHORT(buf, 0x11 + 2 * i) - 2 * num - 2; + + HLPFILE_UncompressLZ77(buf + 0x13 + 2 * num, end, phrases.buffer); + + hlpfile->hasPhrases = TRUE; + return TRUE; } /*********************************************************************** * - * HLPFILE_Uncompress1_Topic + * HLPFILE_Uncompress_Phrases40 */ - -static BOOL HLPFILE_Uncompress1_Topic() +static BOOL HLPFILE_Uncompress_Phrases40(HLPFILE* hlpfile) { - BYTE *buf, *ptr, *end, *newptr; - INT i, newsize = 0; + UINT num, dec_size; + BYTE *buf_idx, *end_idx; + BYTE *buf_phs, *end_phs; + short i, n; + long* ptr, mask = 0; + unsigned short bc; - if (!HLPFILE_FindSubFile("TOPIC", &buf, &end)) {Report("topic0"); return FALSE;} + if (!HLPFILE_FindSubFile("PhrIndex", &buf_idx, &end_idx) || + !HLPFILE_FindSubFile("PhrImage", &buf_phs, &end_phs)) return FALSE; - buf += 9; - topic.wMapLen = (end - buf - 1) / 0x1000 + 1; + ptr = (long*)(buf_idx + 9 + 28); + bc = GET_USHORT(buf_idx, 9 + 24) & 0x0F; + num = phrases.num = GET_USHORT(buf_idx, 9 + 4); - for (i = 0; i < topic.wMapLen; i++) + WINE_TRACE("Index: Magic=%08x #entries=%u CpsdSize=%u PhrImgSize=%u\n" + "\tPhrImgCprsdSize=%u 0=%u bc=%x ukn=%x\n", + GET_UINT(buf_idx, 9 + 0), + GET_UINT(buf_idx, 9 + 4), + GET_UINT(buf_idx, 9 + 8), + GET_UINT(buf_idx, 9 + 12), + GET_UINT(buf_idx, 9 + 16), + GET_UINT(buf_idx, 9 + 20), + GET_USHORT(buf_idx, 9 + 24), + GET_USHORT(buf_idx, 9 + 26)); + + dec_size = GET_UINT(buf_idx, 9 + 12); + if (dec_size != HLPFILE_UncompressedLZ77_Size(buf_phs + 9, end_phs)) { - ptr = buf + i * 0x1000; - - /* I don't know why, it's necessary for printman.hlp */ - if (ptr + 0x44 > end) ptr = end - 0x44; - - newsize += HLPFILE_Uncompressed1_Size(ptr + 0xc, min(end, ptr + 0x1000)); + WINE_WARN("size mismatch %u %u\n", + dec_size, HLPFILE_UncompressedLZ77_Size(buf_phs, end_phs)); + dec_size = max(dec_size, HLPFILE_UncompressedLZ77_Size(buf_phs, end_phs)); } - topic.hMap = GlobalAlloc(GMEM_FIXED, topic.wMapLen * sizeof(topic.map[0])); - topic.hBuffer = GlobalAlloc(GMEM_FIXED, newsize); - if (!topic.hMap || !topic.hBuffer) return FALSE; - topic.map = GlobalLock(topic.hMap); - newptr = GlobalLock(topic.hBuffer); - topic.end = newptr + newsize; + phrases.offsets = HeapAlloc(GetProcessHeap(), 0, sizeof(unsigned) * (num + 1)); + phrases.buffer = HeapAlloc(GetProcessHeap(), 0, dec_size); + if (!phrases.offsets || !phrases.buffer) return FALSE; - for (i = 0; i < topic.wMapLen; i++) +#define getbit() (ptr += (mask < 0), mask = mask*2 + (mask<=0), (*ptr & mask) != 0) + + phrases.offsets[0] = 0; + for (i = 0; i < num; i++) { - ptr = buf + i * 0x1000; - if (ptr + 0x44 > end) ptr = end - 0x44; + for (n = 1; getbit(); n += 1 << bc); + if (getbit()) n++; + if (bc > 1 && getbit()) n += 2; + if (bc > 2 && getbit()) n += 4; + if (bc > 3 && getbit()) n += 8; + if (bc > 4 && getbit()) n += 16; + phrases.offsets[i + 1] = phrases.offsets[i] + n; + } +#undef getbit - topic.map[i] = newptr - 0xc; - newptr = HLPFILE_Uncompress1(ptr + 0xc, min(end, ptr + 0x1000), newptr); + HLPFILE_UncompressLZ77(buf_phs + 9, end_phs, phrases.buffer); + + hlpfile->hasPhrases = FALSE; + return TRUE; +} + +/*********************************************************************** + * + * HLPFILE_UncompressLZ77_Topic + */ +static BOOL HLPFILE_UncompressLZ77_Topic(HLPFILE* hlpfile) +{ + BYTE *buf, *ptr, *end, *newptr; + int i, newsize = 0; + + if (!HLPFILE_FindSubFile("TOPIC", &buf, &end)) + {WINE_WARN("topic0\n"); return FALSE;} + + if (!(hlpfile->flags & 4)) WINE_FIXME("Unsupported format\n"); + + buf += 9; + topic.wMapLen = (end - buf - 1) / 0x1000 + 1; + + for (i = 0; i < topic.wMapLen; i++) + { + ptr = buf + i * 0x1000; + + /* I don't know why, it's necessary for printman.hlp */ + if (ptr + 0x44 > end) ptr = end - 0x44; + + newsize += HLPFILE_UncompressedLZ77_Size(ptr + 0xc, min(end, ptr + 0x1000)); } - return TRUE; + topic.map = HeapAlloc(GetProcessHeap(), 0, + topic.wMapLen * sizeof(topic.map[0]) + newsize); + if (!topic.map) return FALSE; + newptr = (char*)topic.map + topic.wMapLen * sizeof(topic.map[0]); + topic.end = newptr + newsize; + + for (i = 0; i < topic.wMapLen; i++) + { + ptr = buf + i * 0x1000; + if (ptr + 0x44 > end) ptr = end - 0x44; + + topic.map[i] = newptr; + newptr = HLPFILE_UncompressLZ77(ptr + 0xc, min(end, ptr + 0x1000), newptr); + } + + return TRUE; } /*********************************************************************** * * HLPFILE_Uncompressed2_Size */ - static UINT HLPFILE_Uncompressed2_Size(BYTE *ptr, BYTE *end) { - UINT wSize = 0; + UINT wSize = 0; - while (ptr < end && *ptr) + while (ptr < end) { - if (*ptr >= 0x20) - wSize++, ptr++; - else + if (!*ptr || *ptr >= 0x10) + wSize++, ptr++; + else { - BYTE *phptr, *phend; - UINT code = 0x100 * ptr[0] + ptr[1]; - UINT index = (code - 0x100) / 2; - BOOL space = code & 1; + BYTE *phptr, *phend; + UINT code = 0x100 * ptr[0] + ptr[1]; + UINT index = (code - 0x100) / 2; - if (index < phrases.num) + if (index < phrases.num) { - phptr = phrases.buf + GET_USHORT(phrases.buf, 2 * index); - phend = phrases.buf + GET_USHORT(phrases.buf, 2 * index + 2); + phptr = phrases.buffer + phrases.offsets[index]; + phend = phrases.buffer + phrases.offsets[index + 1]; - if (phend < phptr) Report("uncompress2a"); + if (phend < phptr) WINE_WARN("uncompress2a\n"); - wSize += phend - phptr; - if (space) wSize++; + wSize += phend - phptr; + if (code & 1) wSize++; } - else Report("uncompress2b"); + else WINE_WARN("uncompress2b %d|%d\n", index, phrases.num); - ptr += 2; + ptr += 2; } } - return(wSize + 1); + return wSize + 1; } /*********************************************************************** @@ -853,154 +1404,275 @@ static UINT HLPFILE_Uncompressed2_Size(BYTE *ptr, BYTE *end) * HLPFILE_Uncompress2 */ -static VOID HLPFILE_Uncompress2(BYTE **pptr, BYTE *end, BYTE *newptr) +static void HLPFILE_Uncompress2(BYTE **pptr, BYTE *end, BYTE *newptr) { - BYTE *ptr = *pptr; + BYTE *ptr = *pptr; - while (ptr < end && *ptr) + while (ptr < end) { - if (*ptr >= 0x20) - *newptr++ = *ptr++; - else + if (!*ptr || *ptr >= 0x10) + *newptr++ = *ptr++; + else { - BYTE *phptr, *phend; - UINT code = 0x100 * ptr[0] + ptr[1]; - UINT index = (code - 0x100) / 2; - BOOL space = code & 1; + BYTE *phptr, *phend; + UINT code = 0x100 * ptr[0] + ptr[1]; + UINT index = (code - 0x100) / 2; - phptr = phrases.buf + GET_USHORT(phrases.buf, 2 * index); - phend = phrases.buf + GET_USHORT(phrases.buf, 2 * index + 2); + phptr = phrases.buffer + phrases.offsets[index]; + phend = phrases.buffer + phrases.offsets[index + 1]; - memcpy(newptr, phptr, phend - phptr); - newptr += phend - phptr; - if (space) *newptr++ = ' '; + memcpy(newptr, phptr, phend - phptr); + newptr += phend - phptr; + if (code & 1) *newptr++ = ' '; - ptr += 2; + ptr += 2; } } - *newptr = '\0'; - *pptr = ptr; + *newptr = '\0'; + *pptr = ptr; +} + +/****************************************************************** + * HLPFILE_Uncompress3 + * + * + */ +static BOOL HLPFILE_Uncompress3(char* dst, const char* dst_end, + const BYTE* src, const BYTE* src_end) +{ + int idx, len; + + for (; src < src_end; src++) + { + if ((*src & 1) == 0) + { + idx = *src / 2; + if (idx > phrases.num) WINE_ERR("index in phrases\n"); + len = phrases.offsets[idx + 1] - phrases.offsets[idx]; + memcpy(dst, &phrases.buffer[phrases.offsets[idx]], len); + } + else if ((*src & 0x03) == 0x01) + { + idx = (*src + 1) * 64 + *++src; + if (idx > phrases.num) WINE_ERR("index in phrases\n"); + len = phrases.offsets[idx + 1] - phrases.offsets[idx]; + memcpy(dst, &phrases.buffer[phrases.offsets[idx]], len); + } + else if ((*src & 0x07) == 0x03) + { + len = (*src / 8) + 1; + memcpy(dst, src + 1, len); + src += len; + } + else + { + len = (*src / 16) + 1; + memset(dst, ((*src & 0x0F) == 0x07) ? ' ' : 0, len); + } + dst += len; + } + + if (dst > dst_end) WINE_ERR("buffer overflow (%p > %p)\n", dst, dst_end); + return TRUE; +} + +/****************************************************************** + * HLPFILE_UncompressRLE + * + * + */ +static void HLPFILE_UncompressRLE(const BYTE* src, unsigned sz, BYTE** dst) +{ + unsigned i; + BYTE ch; + + for (i = 0; i < sz; i++) + { + ch = src[i]; + if (ch & 0x80) + { + ch &= 0x7F; + memcpy(*dst, src + i + 1, ch); + i += ch; + } + else + { + memset(*dst, (char)src[i + 1], ch); + i++; + } + *dst += ch; + } +} + +/****************************************************************** + * HLPFILE_EnumBTreeLeaves + * + * + */ +static void HLPFILE_EnumBTreeLeaves(const BYTE* buf, const BYTE* end, unsigned (*fn)(const BYTE*, void*), void* user) +{ + unsigned psize, pnext; + unsigned num, nlvl; + const BYTE* ptr; + + num = GET_UINT(buf, 9 + 34); + psize = GET_USHORT(buf, 9 + 4); + nlvl = GET_USHORT(buf, 9 + 32); + pnext = GET_USHORT(buf, 26); + + WINE_TRACE("BTree: #entries=%u pagSize=%u #levels=%u #pages=%u root=%u struct%16s\n", + num, psize, nlvl, GET_USHORT(buf, 9 + 30), pnext, buf + 9 + 6); + if (!num) return; + + while (--nlvl > 0) + { + ptr = (buf + 9 + 38) + pnext * psize; + WINE_TRACE("BTree: (index[%u]) unused=%u #entries=%u <%u\n", + pnext, GET_USHORT(ptr, 0), GET_USHORT(ptr, 2), GET_USHORT(ptr, 4)); + pnext = GET_USHORT(ptr, 6); + } + while (pnext != 0xFFFF) + { + const BYTE* node_page; + unsigned short limit; + + node_page = ptr = (buf + 9 + 38) + pnext * psize; + limit = GET_USHORT(ptr, 2); + WINE_TRACE("BTree: (leaf [%u]) unused=%u #entries=%u <%u >%u\n", + pnext, GET_USHORT(ptr, 0), limit, GET_USHORT(ptr, 4), GET_USHORT(ptr, 6)); + ptr += 8; + while (limit--) + ptr += (fn)(ptr, user); + pnext = GET_USHORT(node_page, 6); + } +} + +struct myfncb { + HLPFILE* hlpfile; + int i; +}; + +static unsigned myfn(const BYTE* ptr, void* user) +{ + struct myfncb* m = user; + + m->hlpfile->Context[m->i].lHash = GET_UINT(ptr, 0); + m->hlpfile->Context[m->i].offset = GET_UINT(ptr, 4); + m->i++; + return 8; } /*********************************************************************** * * HLPFILE_GetContext */ - static BOOL HLPFILE_GetContext(HLPFILE *hlpfile) { - UINT i, j, clen, tlen; - BYTE *cbuf, *cptr, *cend, *tbuf, *tptr, *tend; + BYTE *cbuf, *cend; + struct myfncb m; + unsigned clen; - if (!HLPFILE_FindSubFile("CONTEXT", &cbuf, &cend)) {Report("context0"); return FALSE;} - if (cbuf + 0x37 > cend) {Report("context1"); return(FALSE);}; - clen = GET_UINT(cbuf, 0x2b); - if (cbuf + 0x37 + 8 * hlpfile->wContextLen > cend) {Report("context2"); return(FALSE);}; + if (!HLPFILE_FindSubFile("CONTEXT", &cbuf, &cend)) {WINE_WARN("context0\n"); return FALSE;} - if (!HLPFILE_FindSubFile("TTLBTREE", &tbuf, &tend)) {Report("ttlb0"); return FALSE;} - if (tbuf + 0x37 > tend) {Report("ttlb1"); return(FALSE);}; - tlen = GET_UINT(tbuf, 0x2b); + clen = GET_UINT(cbuf, 0x2b); + hlpfile->Context = HeapAlloc(GetProcessHeap(), 0, clen * sizeof(HLPFILE_CONTEXT)); + if (!hlpfile->Context) return FALSE; + hlpfile->wContextLen = clen; - hlpfile->hContext = GlobalAlloc(GMEM_FIXED, clen * sizeof(HLPFILE_CONTEXT)); - if (!hlpfile->hContext) return FALSE; - hlpfile->Context = GlobalLock(hlpfile->hContext); - hlpfile->wContextLen = clen; + m.hlpfile = hlpfile; + m.i = 0; + HLPFILE_EnumBTreeLeaves(cbuf, cend, myfn, &m); - cptr = cbuf + 0x37; - for (i = 0; i < clen; i++, cptr += 8) - { - tptr = tbuf + 0x37; - for (j = 0; j < tlen; j++, tptr += 5 + strlen(tptr + 4)) - { - if (tptr + 4 >= tend) {Report("ttlb2"); return(FALSE);}; - if (GET_UINT(tptr, 0) == GET_UINT(cptr, 4)) break; - } - if (j >= tlen) - { - Report("ttlb3"); - j = 0; - } - hlpfile->Context[i].lHash = GET_UINT(cptr, 0); - hlpfile->Context[i].wPage = j; - } - - return TRUE; + return TRUE; } /*********************************************************************** * * HLPFILE_DeleteParagraph */ - -static VOID HLPFILE_DeleteParagraph(HLPFILE_PARAGRAPH* paragraph) +static void HLPFILE_DeleteParagraph(HLPFILE_PARAGRAPH* paragraph) { - if (!paragraph) return; + HLPFILE_PARAGRAPH* next; - if (paragraph->link) GlobalFree(paragraph->link->hSelf); + while (paragraph) + { + next = paragraph->next; + if (paragraph->link) HeapFree(GetProcessHeap(), 0, paragraph->link); - HLPFILE_DeleteParagraph(paragraph->next); - GlobalFree(paragraph->hSelf); + HeapFree(GetProcessHeap(), 0, paragraph); + paragraph = next; + } } /*********************************************************************** * * DeletePage */ - -static VOID HLPFILE_DeletePage(HLPFILE_PAGE* page) +static void HLPFILE_DeletePage(HLPFILE_PAGE* page) { - if (!page) return; + HLPFILE_PAGE* next; - HLPFILE_DeletePage(page->next); - HLPFILE_DeleteParagraph(page->first_paragraph); - GlobalFree(page->hSelf); + while (page) + { + next = page->next; + HLPFILE_DeleteParagraph(page->first_paragraph); + HeapFree(GetProcessHeap(), 0, page); + page = next; + } } /*********************************************************************** * * DeleteMacro */ - -static VOID HLPFILE_DeleteMacro(HLPFILE_MACRO* macro) +static void HLPFILE_DeleteMacro(HLPFILE_MACRO* macro) { - if (!macro) return; + HLPFILE_MACRO* next; - HLPFILE_DeleteMacro(macro->next); - GlobalFree(macro->hSelf); + while (macro) + { + next = macro->next; + HeapFree(GetProcessHeap(), 0, macro); + macro = next; + } } /*********************************************************************** * * HLPFILE_FreeHlpFile */ - -VOID HLPFILE_FreeHlpFile(HLPFILE* hlpfile) +void HLPFILE_FreeHlpFile(HLPFILE* hlpfile) { - if (!hlpfile) return; - if (--hlpfile->wRefCount) return; + if (!hlpfile || --hlpfile->wRefCount > 0) return; - if (hlpfile->next) hlpfile->next->prev = hlpfile->prev; - if (hlpfile->prev) hlpfile->prev->next = hlpfile->next; - else first_hlpfile = 0; + if (hlpfile->next) hlpfile->next->prev = hlpfile->prev; + if (hlpfile->prev) hlpfile->prev->next = hlpfile->next; + else first_hlpfile = hlpfile->next; - HLPFILE_DeletePage(hlpfile->first_page); - HLPFILE_DeleteMacro(hlpfile->first_macro); - if (hlpfile->hContext) GlobalFree(hlpfile->hContext); - if (hlpfile->hTitle) GlobalFree(hlpfile->hTitle); - GlobalFree(hlpfile->hSelf); + if (hlpfile->numFonts) + { + unsigned i; + for (i = 0; i < hlpfile->numFonts; i++) + { + DeleteObject(hlpfile->fonts[i].hFont); + } + HeapFree(GetProcessHeap(), 0, hlpfile->fonts); + } + + HLPFILE_DeletePage(hlpfile->first_page); + HLPFILE_DeleteMacro(hlpfile->first_macro); + + if (hlpfile->Context) HeapFree(GetProcessHeap(), 0, hlpfile->Context); + if (hlpfile->lpszTitle) HeapFree(GetProcessHeap(), 0, hlpfile->lpszTitle); + HeapFree(GetProcessHeap(), 0, hlpfile); } /*********************************************************************** * * FreeHlpFilePage */ - -VOID HLPFILE_FreeHlpFilePage(HLPFILE_PAGE* page) +void HLPFILE_FreeHlpFilePage(HLPFILE_PAGE* page) { - if (!page) return; - HLPFILE_FreeHlpFile(page->file); + if (!page) return; + HLPFILE_FreeHlpFile(page->file); } - -/* Local Variables: */ -/* c-file-style: "GNU" */ -/* End: */ diff --git a/programs/winhelp/hlpfile.h b/programs/winhelp/hlpfile.h index 86ff922c30c..16e5ccbb7e7 100644 --- a/programs/winhelp/hlpfile.h +++ b/programs/winhelp/hlpfile.h @@ -1,7 +1,8 @@ /* * Help Viewer * - * Copyright 1996 Ulrich Schmid + * Copyright 1996 Ulrich Schmid + * 2002 Eric Pouech * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -22,74 +23,89 @@ struct tagHelpFile; typedef struct { - LPCSTR lpszPath; - LONG lHash; - BOOL bPopup; - - HGLOBAL hSelf; + LPCSTR lpszPath; + LONG lHash; + BOOL bPopup; } HLPFILE_LINK; +enum para_type {para_normal_text, para_debug_text, para_image}; + typedef struct tagHlpFileParagraph { - LPSTR lpszText; + enum para_type cookie; - UINT bDebug; - UINT wFont; - UINT wIndent; - UINT wHSpace; - UINT wVSpace; + union + { + struct + { + LPSTR lpszText; + unsigned wFont; + unsigned wIndent; + unsigned wHSpace; + unsigned wVSpace; + } text; + struct + { + HBITMAP hBitmap; + unsigned pos; /* 0: center, 1: left, 2: right */ + } image; + } u; - HLPFILE_LINK *link; + HLPFILE_LINK* link; - struct tagHlpFileParagraph *next; - - HGLOBAL hSelf; + struct tagHlpFileParagraph* next; } HLPFILE_PARAGRAPH; typedef struct tagHlpFilePage { - LPSTR lpszTitle; - HLPFILE_PARAGRAPH *first_paragraph; + LPSTR lpszTitle; + HLPFILE_PARAGRAPH* first_paragraph; - UINT wNumber; - - struct tagHlpFilePage *next; - struct tagHlpFileFile *file; - - HGLOBAL hSelf; + unsigned wNumber; + unsigned offset; + struct tagHlpFilePage* next; + struct tagHlpFilePage* prev; + struct tagHlpFileFile* file; } HLPFILE_PAGE; typedef struct { - LONG lHash; - UINT wPage; + LONG lHash; + unsigned long offset; } HLPFILE_CONTEXT; typedef struct tagHlpFileMacro { - LPCSTR lpszMacro; - - HGLOBAL hSelf; - struct tagHlpFileMacro *next; + LPCSTR lpszMacro; + struct tagHlpFileMacro* next; } HLPFILE_MACRO; +typedef struct +{ + LOGFONT LogFont; + HFONT hFont; + COLORREF color; +} HLPFILE_FONT; + typedef struct tagHlpFileFile { - LPSTR lpszPath; - LPSTR lpszTitle; - HLPFILE_PAGE *first_page; - HLPFILE_MACRO *first_macro; - UINT wContextLen; - HLPFILE_CONTEXT *Context; + LPSTR lpszPath; + LPSTR lpszTitle; + HLPFILE_PAGE* first_page; + HLPFILE_MACRO* first_macro; + unsigned wContextLen; + HLPFILE_CONTEXT* Context; + struct tagHlpFileFile* prev; + struct tagHlpFileFile* next; - struct tagHlpFileFile *prev; - struct tagHlpFileFile *next; + unsigned wRefCount; - UINT wRefCount; + unsigned short version; + unsigned short flags; + unsigned hasPhrases; /* Phrases or PhrIndex/PhrImage */ - HGLOBAL hTitle; - HGLOBAL hContext; - HGLOBAL hSelf; + unsigned numFonts; + HLPFILE_FONT* fonts; } HLPFILE; HLPFILE *HLPFILE_ReadHlpFile(LPCSTR lpszPath); @@ -98,7 +114,3 @@ HLPFILE_PAGE *HLPFILE_PageByHash(LPCSTR lpszPath, LONG wNum); LONG HLPFILE_Hash(LPCSTR lpszContext); VOID HLPFILE_FreeHlpFilePage(HLPFILE_PAGE*); VOID HLPFILE_FreeHlpFile(HLPFILE*); - -/* Local Variables: */ -/* c-file-style: "GNU" */ -/* End: */ diff --git a/programs/winhelp/macro.c b/programs/winhelp/macro.c index 9912aa90836..f2c42a4a780 100644 --- a/programs/winhelp/macro.c +++ b/programs/winhelp/macro.c @@ -18,460 +18,462 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include <stdio.h> #include "windows.h" #include "commdlg.h" #include "winhelp.h" #include "macro.h" -VOID MACRO_About(VOID) +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(winhelp); + +void MACRO_About(void) { - fprintf(stderr, "About()\n"); + WINE_FIXME("About()\n"); } -VOID MACRO_AddAccelerator(LONG u1, LONG u2, LPCSTR str) +void MACRO_AddAccelerator(LONG u1, LONG u2, LPCSTR str) { - fprintf(stderr, "AddAccelerator(%lu, %lu, \"%s\")\n", u1, u2, str); + WINE_FIXME("AddAccelerator(%lu, %lu, \"%s\")\n", u1, u2, str); } -VOID MACRO_ALink(LPCSTR str1, LONG u, LPCSTR str2) +void MACRO_ALink(LPCSTR str1, LONG u, LPCSTR str2) { - fprintf(stderr, "ALink(\"%s\", %lu, \"%s\")\n", str1, u, str2); + WINE_FIXME("ALink(\"%s\", %lu, \"%s\")\n", str1, u, str2); } -VOID MACRO_Annotate(VOID) +void MACRO_Annotate(void) { - fprintf(stderr, "Annotate()\n"); + WINE_FIXME("Annotate()\n"); } -VOID MACRO_AppendItem(LPCSTR str1, LPCSTR str2, LPCSTR str3, LPCSTR str4) +void MACRO_AppendItem(LPCSTR str1, LPCSTR str2, LPCSTR str3, LPCSTR str4) { - fprintf(stderr, "AppendItem(\"%s\", \"%s\", \"%s\", \"%s\")\n", str1, str2, str3, str4); + WINE_FIXME("AppendItem(\"%s\", \"%s\", \"%s\", \"%s\")\n", str1, str2, str3, str4); } -VOID MACRO_Back(VOID) +void MACRO_Back(void) { - fprintf(stderr, "Back()\n"); + WINE_FIXME("Back()\n"); } -VOID MACRO_BackFlush(VOID) +void MACRO_BackFlush(void) { - fprintf(stderr, "BackFlush()\n"); + WINE_FIXME("BackFlush()\n"); } -VOID MACRO_BookmarkDefine(VOID) +void MACRO_BookmarkDefine(void) { - fprintf(stderr, "BookmarkDefine()\n"); + WINE_FIXME("BookmarkDefine()\n"); } -VOID MACRO_BookmarkMore(VOID) +void MACRO_BookmarkMore(void) { - fprintf(stderr, "BookmarkMore()\n"); + WINE_FIXME("BookmarkMore()\n"); } -VOID MACRO_BrowseButtons(VOID) +void MACRO_BrowseButtons(void) { - MACRO_CreateButton("BTN_PREV", "&<<", "Prev()"); - MACRO_CreateButton("BTN_NEXT", "&>>", "Next()"); + MACRO_CreateButton("BTN_PREV", "&<<", "Prev()"); + MACRO_CreateButton("BTN_NEXT", "&>>", "Next()"); } -VOID MACRO_ChangeButtonBinding(LPCSTR str1, LPCSTR str2) +void MACRO_ChangeButtonBinding(LPCSTR str1, LPCSTR str2) { - fprintf(stderr, "ChangeButtonBinding(\"%s\", \"%s\")\n", str1, str2); + WINE_FIXME("ChangeButtonBinding(\"%s\", \"%s\")\n", str1, str2); } -VOID MACRO_ChangeEnable(LPCSTR str1, LPCSTR str2) +void MACRO_ChangeEnable(LPCSTR str1, LPCSTR str2) { - fprintf(stderr, "ChangeEnable(\"%s\", \"%s\")\n", str1, str2); + WINE_FIXME("ChangeEnable(\"%s\", \"%s\")\n", str1, str2); } -VOID MACRO_ChangeItemBinding(LPCSTR str1, LPCSTR str2) +void MACRO_ChangeItemBinding(LPCSTR str1, LPCSTR str2) { - fprintf(stderr, "ChangeItemBinding(\"%s\", \"%s\")\n", str1, str2); + WINE_FIXME("ChangeItemBinding(\"%s\", \"%s\")\n", str1, str2); } -VOID MACRO_CheckItem(LPCSTR str) +void MACRO_CheckItem(LPCSTR str) { - fprintf(stderr, "CheckItem(\"%s\")\n", str); + WINE_FIXME("CheckItem(\"%s\")\n", str); } -VOID MACRO_CloseSecondarys(VOID) +void MACRO_CloseSecondarys(void) { - WINHELP_WINDOW *win; - for (win = Globals.win_list; win; win = win->next) - if (win->lpszName && lstrcmpi(win->lpszName, "main")) - DestroyWindow(win->hMainWnd); + WINHELP_WINDOW *win; + for (win = Globals.win_list; win; win = win->next) + if (win->lpszName && lstrcmpi(win->lpszName, "main")) + DestroyWindow(win->hMainWnd); } -VOID MACRO_CloseWindow(LPCSTR lpszWindow) +void MACRO_CloseWindow(LPCSTR lpszWindow) { - WINHELP_WINDOW *win; - if (!lpszWindow || !lpszWindow[0]) lpszWindow = "main"; + WINHELP_WINDOW *win; + if (!lpszWindow || !lpszWindow[0]) lpszWindow = "main"; - for (win = Globals.win_list; win; win = win->next) - if (win->lpszName && !lstrcmpi(win->lpszName, lpszWindow)) - DestroyWindow(win->hMainWnd); + for (win = Globals.win_list; win; win = win->next) + if (win->lpszName && !lstrcmpi(win->lpszName, lpszWindow)) + DestroyWindow(win->hMainWnd); } -VOID MACRO_Compare(LPCSTR str) +void MACRO_Compare(LPCSTR str) { - fprintf(stderr, "Compare(\"%s\")\n", str); + WINE_FIXME("Compare(\"%s\")\n", str); } -VOID MACRO_Contents(VOID) +void MACRO_Contents(void) { - if (Globals.active_win->page) - MACRO_JumpContents(Globals.active_win->page->file->lpszPath, NULL); + if (Globals.active_win->page) + MACRO_JumpContents(Globals.active_win->page->file->lpszPath, NULL); } -VOID MACRO_ControlPanel(LPCSTR str1, LPCSTR str2, LONG u) +void MACRO_ControlPanel(LPCSTR str1, LPCSTR str2, LONG u) { - fprintf(stderr, "ControlPanel(\"%s\", \"%s\", %lu)\n", str1, str2, u); + WINE_FIXME("ControlPanel(\"%s\", \"%s\", %lu)\n", str1, str2, u); } -VOID MACRO_CopyDialog(VOID) +void MACRO_CopyDialog(void) { - fprintf(stderr, "CopyDialog()\n"); + WINE_FIXME("CopyDialog()\n"); } -VOID MACRO_CopyTopic(VOID) +void MACRO_CopyTopic(void) { - fprintf(stderr, "CopyTopic()\n"); + WINE_FIXME("CopyTopic()\n"); } -VOID MACRO_CreateButton(LPCSTR id, LPCSTR name, LPCSTR macro) +void MACRO_CreateButton(LPCSTR id, LPCSTR name, LPCSTR macro) { - WINHELP_WINDOW *win = Globals.active_win; - WINHELP_BUTTON *button, **b; - LONG size; - HGLOBAL handle; - LPSTR ptr; + WINHELP_WINDOW *win = Globals.active_win; + WINHELP_BUTTON *button, **b; + LONG size; + LPSTR ptr; - size = sizeof(WINHELP_BUTTON) + lstrlen(id) + lstrlen(name) + lstrlen(macro) + 3; - handle = GlobalAlloc(GMEM_FIXED, size); - if (!handle) return; + size = sizeof(WINHELP_BUTTON) + lstrlen(id) + lstrlen(name) + lstrlen(macro) + 3; - button = GlobalLock(handle); - button->hSelf = handle; - button->next = 0; - button->hWnd = 0; + button = HeapAlloc(GetProcessHeap(), 0, size); + if (!button) return; - ptr = GlobalLock(handle); - ptr += sizeof(WINHELP_BUTTON); + button->next = 0; + button->hWnd = 0; - lstrcpy(ptr, (LPSTR) id); - button->lpszID = ptr; - ptr += lstrlen(id) + 1; + ptr = (char*)button + sizeof(WINHELP_BUTTON); - lstrcpy(ptr, (LPSTR) name); - button->lpszName = ptr; - ptr += lstrlen(name) + 1; + lstrcpy(ptr, (LPSTR) id); + button->lpszID = ptr; + ptr += lstrlen(id) + 1; - lstrcpy(ptr, (LPSTR) macro); - button->lpszMacro = ptr; + lstrcpy(ptr, (LPSTR) name); + button->lpszName = ptr; + ptr += lstrlen(name) + 1; - button->wParam = WH_FIRST_BUTTON; - for (b = &win->first_button; *b; b = &(*b)->next) - button->wParam = max(button->wParam, (*b)->wParam + 1); - *b = button; + lstrcpy(ptr, (LPSTR) macro); + button->lpszMacro = ptr; - SendMessage(win->hMainWnd, WM_USER, 0, 0); + button->wParam = WH_FIRST_BUTTON; + for (b = &win->first_button; *b; b = &(*b)->next) + button->wParam = max(button->wParam, (*b)->wParam + 1); + *b = button; + + SendMessage(win->hMainWnd, WM_USER, 0, 0); } -VOID MACRO_DeleteItem(LPCSTR str) +void MACRO_DeleteItem(LPCSTR str) { - fprintf(stderr, "DeleteItem(\"%s\")\n", str); + WINE_FIXME("DeleteItem(\"%s\")\n", str); } -VOID MACRO_DeleteMark(LPCSTR str) +void MACRO_DeleteMark(LPCSTR str) { - fprintf(stderr, "DeleteMark(\"%s\")\n", str); + WINE_FIXME("DeleteMark(\"%s\")\n", str); } -VOID MACRO_DestroyButton(LPCSTR str) +void MACRO_DestroyButton(LPCSTR str) { - fprintf(stderr, "DestroyButton(\"%s\")\n", str); + WINE_FIXME("DestroyButton(\"%s\")\n", str); } -VOID MACRO_DisableButton(LPCSTR str) +void MACRO_DisableButton(LPCSTR str) { - fprintf(stderr, "DisableButton(\"%s\")\n", str); + WINE_FIXME("DisableButton(\"%s\")\n", str); } -VOID MACRO_DisableItem(LPCSTR str) +void MACRO_DisableItem(LPCSTR str) { - fprintf(stderr, "DisableItem(\"%s\")\n", str); + WINE_FIXME("DisableItem(\"%s\")\n", str); } -VOID MACRO_EnableButton(LPCSTR str) +void MACRO_EnableButton(LPCSTR str) { - fprintf(stderr, "EnableButton(\"%s\")\n", str); + WINE_FIXME("EnableButton(\"%s\")\n", str); } -VOID MACRO_EnableItem(LPCSTR str) +void MACRO_EnableItem(LPCSTR str) { - fprintf(stderr, "EnableItem(\"%s\")\n", str); + WINE_FIXME("EnableItem(\"%s\")\n", str); } -VOID MACRO_EndMPrint(VOID) +void MACRO_EndMPrint(void) { - fprintf(stderr, "EndMPrint()\n"); + WINE_FIXME("EndMPrint()\n"); } -VOID MACRO_ExecFile(LPCSTR str1, LPCSTR str2, LONG u, LPCSTR str3) +void MACRO_ExecFile(LPCSTR str1, LPCSTR str2, LONG u, LPCSTR str3) { - fprintf(stderr, "ExecFile(\"%s\", \"%s\", %lu, \"%s\")\n", str1, str2, u, str3); + WINE_FIXME("ExecFile(\"%s\", \"%s\", %lu, \"%s\")\n", str1, str2, u, str3); } -VOID MACRO_ExecProgram(LPCSTR str, LONG u) +void MACRO_ExecProgram(LPCSTR str, LONG u) { - fprintf(stderr, "ExecProgram(\"%s\", %lu)\n", str, u); + WINE_FIXME("ExecProgram(\"%s\", %lu)\n", str, u); } -VOID MACRO_Exit(VOID) +void MACRO_Exit(void) { - while(Globals.win_list) - DestroyWindow(Globals.win_list->hMainWnd); + while (Globals.win_list) + DestroyWindow(Globals.win_list->hMainWnd); } -VOID MACRO_ExtAbleItem(LPCSTR str, LONG u) +void MACRO_ExtAbleItem(LPCSTR str, LONG u) { - fprintf(stderr, "ExtAbleItem(\"%s\", %lu)\n", str, u); + WINE_FIXME("ExtAbleItem(\"%s\", %lu)\n", str, u); } -VOID MACRO_ExtInsertItem(LPCSTR str1, LPCSTR str2, LPCSTR str3, LPCSTR str4, LONG u1, LONG u2) +void MACRO_ExtInsertItem(LPCSTR str1, LPCSTR str2, LPCSTR str3, LPCSTR str4, LONG u1, LONG u2) { - fprintf(stderr, "ExtInsertItem(\"%s\", \"%s\", \"%s\", \"%s\", %lu, %lu)\n", str1, str2, str3, str4, u1, u2); + WINE_FIXME("ExtInsertItem(\"%s\", \"%s\", \"%s\", \"%s\", %lu, %lu)\n", str1, str2, str3, str4, u1, u2); } -VOID MACRO_ExtInsertMenu(LPCSTR str1, LPCSTR str2, LPCSTR str3, LONG u1, LONG u2) +void MACRO_ExtInsertMenu(LPCSTR str1, LPCSTR str2, LPCSTR str3, LONG u1, LONG u2) { - fprintf(stderr, "ExtInsertMenu(\"%s\", \"%s\", \"%s\", %lu, %lu)\n", str1, str2, str3, u1, u2); + WINE_FIXME("ExtInsertMenu(\"%s\", \"%s\", \"%s\", %lu, %lu)\n", str1, str2, str3, u1, u2); } BOOL MACRO_FileExist(LPCSTR str) { - fprintf(stderr, "FileExist(\"%s\")\n", str); - return TRUE; + WINE_FIXME("FileExist(\"%s\")\n", str); + return TRUE; } -VOID MACRO_FileOpen(VOID) +void MACRO_FileOpen(void) { - OPENFILENAME openfilename; - CHAR szPath[MAX_PATHNAME_LEN]; - CHAR szDir[MAX_PATHNAME_LEN]; - CHAR szzFilter[2 * MAX_STRING_LEN + 100]; - LPSTR p = szzFilter; + OPENFILENAME openfilename; + CHAR szPath[MAX_PATHNAME_LEN]; + CHAR szDir[MAX_PATHNAME_LEN]; + CHAR szzFilter[2 * MAX_STRING_LEN + 100]; + LPSTR p = szzFilter; - LoadString(Globals.hInstance, 0X12B, p, MAX_STRING_LEN); - p += strlen(p) + 1; - lstrcpy(p, "*.hlp"); - p += strlen(p) + 1; - LoadString(Globals.hInstance, 0x12A, p, MAX_STRING_LEN); - p += strlen(p) + 1; - lstrcpy(p, "*.*"); - p += strlen(p) + 1; - *p = '\0'; + LoadString(Globals.hInstance, 0X12B, p, MAX_STRING_LEN); + p += strlen(p) + 1; + lstrcpy(p, "*.hlp"); + p += strlen(p) + 1; + LoadString(Globals.hInstance, 0x12A, p, MAX_STRING_LEN); + p += strlen(p) + 1; + lstrcpy(p, "*.*"); + p += strlen(p) + 1; + *p = '\0'; - GetCurrentDirectory(sizeof(szDir), szDir); + GetCurrentDirectory(sizeof(szDir), szDir); - szPath[0]='\0'; + szPath[0]='\0'; - openfilename.lStructSize = 0; - openfilename.hwndOwner = Globals.active_win->hMainWnd; - openfilename.hInstance = Globals.hInstance; - openfilename.lpstrFilter = szzFilter; - openfilename.lpstrCustomFilter = 0; - openfilename.nMaxCustFilter = 0; - openfilename.nFilterIndex = 1; - openfilename.lpstrFile = szPath; - openfilename.nMaxFile = sizeof(szPath); - openfilename.lpstrFileTitle = 0; - openfilename.nMaxFileTitle = 0; - openfilename.lpstrInitialDir = szDir; - openfilename.lpstrTitle = 0; - openfilename.Flags = 0; - openfilename.nFileOffset = 0; - openfilename.nFileExtension = 0; - openfilename.lpstrDefExt = 0; - openfilename.lCustData = 0; - openfilename.lpfnHook = 0; - openfilename.lpTemplateName = 0; + openfilename.lStructSize = 0; + openfilename.hwndOwner = Globals.active_win->hMainWnd; + openfilename.hInstance = Globals.hInstance; + openfilename.lpstrFilter = szzFilter; + openfilename.lpstrCustomFilter = 0; + openfilename.nMaxCustFilter = 0; + openfilename.nFilterIndex = 1; + openfilename.lpstrFile = szPath; + openfilename.nMaxFile = sizeof(szPath); + openfilename.lpstrFileTitle = 0; + openfilename.nMaxFileTitle = 0; + openfilename.lpstrInitialDir = szDir; + openfilename.lpstrTitle = 0; + openfilename.Flags = 0; + openfilename.nFileOffset = 0; + openfilename.nFileExtension = 0; + openfilename.lpstrDefExt = 0; + openfilename.lCustData = 0; + openfilename.lpfnHook = 0; + openfilename.lpTemplateName = 0; - if (GetOpenFileName(&openfilename)) - WINHELP_CreateHelpWindow(szPath, 0, "main", FALSE, 0, NULL, SW_SHOWNORMAL); + if (GetOpenFileName(&openfilename)) + WINHELP_CreateHelpWindowByHash(szPath, 0, "main", FALSE, 0, NULL, SW_SHOWNORMAL); } -VOID MACRO_Find(VOID) +void MACRO_Find(void) { - fprintf(stderr, "Find()\n"); + WINE_FIXME("Find()\n"); } -VOID MACRO_Finder(VOID) +void MACRO_Finder(void) { - fprintf(stderr, "Finder()\n"); + WINE_FIXME("Finder()\n"); } -VOID MACRO_FloatingMenu(VOID) +void MACRO_FloatingMenu(void) { - fprintf(stderr, "FloatingMenu()\n"); + WINE_FIXME("FloatingMenu()\n"); } -VOID MACRO_Flush(VOID) +void MACRO_Flush(void) { - fprintf(stderr, "Flush()\n"); + WINE_FIXME("Flush()\n"); } -VOID MACRO_FocusWindow(LPCSTR str) +void MACRO_FocusWindow(LPCSTR str) { - fprintf(stderr, "FocusWindow(\"%s\")\n", str); + WINE_FIXME("FocusWindow(\"%s\")\n", str); } -VOID MACRO_Generate(LPCSTR str, WPARAM w, LPARAM l) +void MACRO_Generate(LPCSTR str, WPARAM w, LPARAM l) { - fprintf(stderr, "Generate(\"%s\", %x, %lx)\n", str, w, l); + WINE_FIXME("Generate(\"%s\", %x, %lx)\n", str, w, l); } -VOID MACRO_GotoMark(LPCSTR str) +void MACRO_GotoMark(LPCSTR str) { - fprintf(stderr, "GotoMark(\"%s\")\n", str); + WINE_FIXME("GotoMark(\"%s\")\n", str); } -VOID MACRO_HelpOn(VOID) +void MACRO_HelpOn(void) { - MACRO_JumpContents((Globals.wVersion > 4) ? "winhelp32.hlp" : "winhelp.hlp", NULL); + MACRO_JumpContents((Globals.wVersion > 4) ? "winhelp32.hlp" : "winhelp.hlp", NULL); } -VOID MACRO_HelpOnTop(VOID) +void MACRO_HelpOnTop(void) { - fprintf(stderr, "HelpOnTop()\n"); + WINE_FIXME("HelpOnTop()\n"); } -VOID MACRO_History(VOID) +void MACRO_History(void) { - fprintf(stderr, "History()\n"); + WINE_FIXME("History()\n"); } -BOOL MACRO_InitMPrint(VOID) +BOOL MACRO_InitMPrint(void) { - fprintf(stderr, "InitMPrint()\n"); - return FALSE; + WINE_FIXME("InitMPrint()\n"); + return FALSE; } -VOID MACRO_InsertItem(LPCSTR str1, LPCSTR str2, LPCSTR str3, LPCSTR str4, LONG u) +void MACRO_InsertItem(LPCSTR str1, LPCSTR str2, LPCSTR str3, LPCSTR str4, LONG u) { - fprintf(stderr, "InsertItem(\"%s\", \"%s\", \"%s\", \"%s\", %lu)\n", str1, str2, str3, str4, u); + WINE_FIXME("InsertItem(\"%s\", \"%s\", \"%s\", \"%s\", %lu)\n", str1, str2, str3, str4, u); } -VOID MACRO_InsertMenu(LPCSTR str1, LPCSTR str2, LONG u) +void MACRO_InsertMenu(LPCSTR str1, LPCSTR str2, LONG u) { - fprintf(stderr, "InsertMenu(\"%s\", \"%s\", %lu)\n", str1, str2, u); + WINE_FIXME("InsertMenu(\"%s\", \"%s\", %lu)\n", str1, str2, u); } -BOOL MACRO_IsBook(VOID) +BOOL MACRO_IsBook(void) { - fprintf(stderr, "IsBook()\n"); - return TRUE; + WINE_FIXME("IsBook()\n"); + return TRUE; } BOOL MACRO_IsMark(LPCSTR str) { - fprintf(stderr, "IsMark(\"%s\")\n", str); - return FALSE; + WINE_FIXME("IsMark(\"%s\")\n", str); + return FALSE; } BOOL MACRO_IsNotMark(LPCSTR str) { - fprintf(stderr, "IsNotMark(\"%s\")\n", str); - return TRUE; + WINE_FIXME("IsNotMark(\"%s\")\n", str); + return TRUE; } -VOID MACRO_JumpContents(LPCSTR lpszPath, LPCSTR lpszWindow) +void MACRO_JumpContents(LPCSTR lpszPath, LPCSTR lpszWindow) { - WINHELP_CreateHelpWindow(lpszPath, 0, lpszWindow, FALSE, 0, NULL, SW_NORMAL); + WINHELP_CreateHelpWindowByHash(lpszPath, 0, lpszWindow, FALSE, 0, NULL, SW_NORMAL); } -VOID MACRO_JumpContext(LPCSTR lpszPath, LPCSTR lpszWindow, LONG context) +void MACRO_JumpContext(LPCSTR lpszPath, LPCSTR lpszWindow, LONG context) { - fprintf(stderr, "JumpContext(\"%s\", \"%s\", %lu)\n", lpszPath, lpszWindow, context); + WINE_FIXME("JumpContext(\"%s\", \"%s\", %lu)\n", lpszPath, lpszWindow, context); } -VOID MACRO_JumpHash(LPCSTR lpszPath, LPCSTR lpszWindow, LONG lHash) +void MACRO_JumpHash(LPCSTR lpszPath, LPCSTR lpszWindow, LONG lHash) { - WINHELP_CreateHelpWindow(lpszPath, lHash, lpszWindow, FALSE, 0, NULL, SW_NORMAL); + WINHELP_CreateHelpWindowByHash(lpszPath, lHash, lpszWindow, FALSE, 0, NULL, SW_NORMAL); } -VOID MACRO_JumpHelpOn(VOID) +void MACRO_JumpHelpOn(void) { - fprintf(stderr, "JumpHelpOn()\n"); + WINE_FIXME("JumpHelpOn()\n"); } -VOID MACRO_JumpID(LPCSTR lpszPath, LPCSTR lpszWindow, LPCSTR topic_id) +void MACRO_JumpID(LPCSTR lpszPath, LPCSTR lpszWindow, LPCSTR topic_id) { - MACRO_JumpHash(lpszPath, lpszWindow, HLPFILE_Hash(topic_id)); + MACRO_JumpHash(lpszPath, lpszWindow, HLPFILE_Hash(topic_id)); } -VOID MACRO_JumpKeyword(LPCSTR lpszPath, LPCSTR lpszWindow, LPCSTR keyword) +void MACRO_JumpKeyword(LPCSTR lpszPath, LPCSTR lpszWindow, LPCSTR keyword) { - fprintf(stderr, "JumpKeyword(\"%s\", \"%s\", \"%s\")\n", lpszPath, lpszWindow, keyword); + WINE_FIXME("JumpKeyword(\"%s\", \"%s\", \"%s\")\n", lpszPath, lpszWindow, keyword); } -VOID MACRO_KLink(LPCSTR str1, LONG u, LPCSTR str2, LPCSTR str3) +void MACRO_KLink(LPCSTR str1, LONG u, LPCSTR str2, LPCSTR str3) { - fprintf(stderr, "KLink(\"%s\", %lu, \"%s\", \"%s\")\n", str1, u, str2, str3); + WINE_FIXME("KLink(\"%s\", %lu, \"%s\", \"%s\")\n", str1, u, str2, str3); } -VOID MACRO_Menu(VOID) +void MACRO_Menu(void) { - fprintf(stderr, "Menu()\n"); + WINE_FIXME("Menu()\n"); } -VOID MACRO_MPrintHash(LONG u) +void MACRO_MPrintHash(LONG u) { - fprintf(stderr, "MPrintHash(%lu)\n", u); + WINE_FIXME("MPrintHash(%lu)\n", u); } -VOID MACRO_MPrintID(LPCSTR str) +void MACRO_MPrintID(LPCSTR str) { - fprintf(stderr, "MPrintID(\"%s\")\n", str); + WINE_FIXME("MPrintID(\"%s\")\n", str); } -VOID MACRO_Next(VOID) +void MACRO_Next(void) { - fprintf(stderr, "Next()\n"); + if (Globals.active_win->page->next) + WINHELP_CreateHelpWindowByPage(Globals.active_win->page->next, "main", FALSE, 0, NULL, SW_NORMAL); } -VOID MACRO_NoShow(VOID) +void MACRO_NoShow(void) { - fprintf(stderr, "NoShow()\n"); + WINE_FIXME("NoShow()\n"); } -VOID MACRO_PopupContext(LPCSTR str, LONG u) +void MACRO_PopupContext(LPCSTR str, LONG u) { - fprintf(stderr, "PopupContext(\"%s\", %lu)\n", str, u); + WINE_FIXME("PopupContext(\"%s\", %lu)\n", str, u); } -VOID MACRO_PopupHash(LPCSTR str, LONG u) +void MACRO_PopupHash(LPCSTR str, LONG u) { - fprintf(stderr, "PopupHash(\"%s\", %lu)\n", str, u); + WINE_FIXME("PopupHash(\"%s\", %lu)\n", str, u); } -VOID MACRO_PopupId(LPCSTR str1, LPCSTR str2) +void MACRO_PopupId(LPCSTR str1, LPCSTR str2) { - fprintf(stderr, "PopupId(\"%s\", \"%s\")\n", str1, str2); + WINE_FIXME("PopupId(\"%s\", \"%s\")\n", str1, str2); } -VOID MACRO_PositionWindow(LONG i1, LONG i2, LONG u1, LONG u2, LONG u3, LPCSTR str) +void MACRO_PositionWindow(LONG i1, LONG i2, LONG u1, LONG u2, LONG u3, LPCSTR str) { - fprintf(stderr, "PositionWindow(%li, %li, %lu, %lu, %lu, \"%s\")\n", i1, i2, u1, u2, u3, str); + WINE_FIXME("PositionWindow(%li, %li, %lu, %lu, %lu, \"%s\")\n", i1, i2, u1, u2, u3, str); } -VOID MACRO_Prev(VOID) +void MACRO_Prev(void) { - fprintf(stderr, "Prev()\n"); + if (Globals.active_win->page->prev) + WINHELP_CreateHelpWindowByPage(Globals.active_win->page->prev, "main", FALSE, 0, NULL, SW_NORMAL); } -VOID MACRO_Print(VOID) +void MACRO_Print(void) { PRINTDLG printer; @@ -496,97 +498,93 @@ VOID MACRO_Print(VOID) printer.hSetupTemplate = 0; if (PrintDlgA(&printer)) { - fprintf(stderr, "Print()\n"); - }; + WINE_FIXME("Print()\n"); + } } -VOID MACRO_PrinterSetup(VOID) +void MACRO_PrinterSetup(void) { - fprintf(stderr, "PrinterSetup()\n"); + WINE_FIXME("PrinterSetup()\n"); } -VOID MACRO_RegisterRoutine(LPCSTR str1, LPCSTR str2, LPCSTR str3) +void MACRO_RegisterRoutine(LPCSTR str1, LPCSTR str2, LPCSTR str3) { - fprintf(stderr, "RegisterRoutine(\"%s\", \"%s\", \"%s\")\n", str1, str2, str3); + WINE_FIXME("RegisterRoutine(\"%s\", \"%s\", \"%s\")\n", str1, str2, str3); } -VOID MACRO_RemoveAccelerator(LONG u1, LONG u2) +void MACRO_RemoveAccelerator(LONG u1, LONG u2) { - fprintf(stderr, "RemoveAccelerator(%lu, %lu)\n", u1, u2); + WINE_FIXME("RemoveAccelerator(%lu, %lu)\n", u1, u2); } -VOID MACRO_ResetMenu(VOID) +void MACRO_ResetMenu(void) { - fprintf(stderr, "ResetMenu()\n"); + WINE_FIXME("ResetMenu()\n"); } -VOID MACRO_SaveMark(LPCSTR str) +void MACRO_SaveMark(LPCSTR str) { - fprintf(stderr, "SaveMark(\"%s\")\n", str); + WINE_FIXME("SaveMark(\"%s\")\n", str); } -VOID MACRO_Search(VOID) +void MACRO_Search(void) { - fprintf(stderr, "Search()\n"); + WINE_FIXME("Search()\n"); } -VOID MACRO_SetContents(LPCSTR str, LONG u) +void MACRO_SetContents(LPCSTR str, LONG u) { - fprintf(stderr, "SetContents(\"%s\", %lu)\n", str, u); + WINE_FIXME("SetContents(\"%s\", %lu)\n", str, u); } -VOID MACRO_SetHelpOnFile(LPCSTR str) +void MACRO_SetHelpOnFile(LPCSTR str) { - fprintf(stderr, "SetHelpOnFile(\"%s\")\n", str); + WINE_FIXME("SetHelpOnFile(\"%s\")\n", str); } -VOID MACRO_SetPopupColor(LONG u1, LONG u2, LONG u3) +void MACRO_SetPopupColor(LONG u1, LONG u2, LONG u3) { - fprintf(stderr, "SetPopupColor(%lu, %lu, %lu)\n", u1, u2, u3); + WINE_FIXME("SetPopupColor(%lu, %lu, %lu)\n", u1, u2, u3); } -VOID MACRO_ShellExecute(LPCSTR str1, LPCSTR str2, LONG u1, LONG u2, LPCSTR str3, LPCSTR str4) +void MACRO_ShellExecute(LPCSTR str1, LPCSTR str2, LONG u1, LONG u2, LPCSTR str3, LPCSTR str4) { - fprintf(stderr, "ShellExecute(\"%s\", \"%s\", %lu, %lu, \"%s\", \"%s\")\n", str1, str2, u1, u2, str3, str4); + WINE_FIXME("ShellExecute(\"%s\", \"%s\", %lu, %lu, \"%s\", \"%s\")\n", str1, str2, u1, u2, str3, str4); } -VOID MACRO_ShortCut(LPCSTR str1, LPCSTR str2, WPARAM w, LPARAM l, LPCSTR str) +void MACRO_ShortCut(LPCSTR str1, LPCSTR str2, WPARAM w, LPARAM l, LPCSTR str) { - fprintf(stderr, "ShortCut(\"%s\", \"%s\", %x, %lx, \"%s\")\n", str1, str2, w, l, str); + WINE_FIXME("ShortCut(\"%s\", \"%s\", %x, %lx, \"%s\")\n", str1, str2, w, l, str); } -VOID MACRO_TCard(LONG u) +void MACRO_TCard(LONG u) { - fprintf(stderr, "TCard(%lu)\n", u); + WINE_FIXME("TCard(%lu)\n", u); } -VOID MACRO_Test(LONG u) +void MACRO_Test(LONG u) { - fprintf(stderr, "Test(%lu)\n", u); + WINE_FIXME("Test(%lu)\n", u); } BOOL MACRO_TestALink(LPCSTR str) { - fprintf(stderr, "TestALink(\"%s\")\n", str); - return FALSE; + WINE_FIXME("TestALink(\"%s\")\n", str); + return FALSE; } BOOL MACRO_TestKLink(LPCSTR str) { - fprintf(stderr, "TestKLink(\"%s\")\n", str); - return FALSE; + WINE_FIXME("TestKLink(\"%s\")\n", str); + return FALSE; } -VOID MACRO_UncheckItem(LPCSTR str) +void MACRO_UncheckItem(LPCSTR str) { - fprintf(stderr, "UncheckItem(\"%s\")\n", str); + WINE_FIXME("UncheckItem(\"%s\")\n", str); } -VOID MACRO_UpdateWindow(LPCSTR str1, LPCSTR str2) +void MACRO_UpdateWindow(LPCSTR str1, LPCSTR str2) { - fprintf(stderr, "UpdateWindow(\"%s\", \"%s\")\n", str1, str2); + WINE_FIXME("UpdateWindow(\"%s\", \"%s\")\n", str1, str2); } - -/* Local Variables: */ -/* c-file-style: "GNU" */ -/* End: */ diff --git a/programs/winhelp/macro.lex.l b/programs/winhelp/macro.lex.l index 05e1dac38ba..cb201dc5395 100644 --- a/programs/winhelp/macro.lex.l +++ b/programs/winhelp/macro.lex.l @@ -19,15 +19,20 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ %} -%x quote dquote +%x quote %{ +#include <assert.h> #include "macro.h" #include "y.tab.h" +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(winhelp); + static LPCSTR macroptr; static LPSTR strptr; -static HGLOBAL hStringBuffer = 0; -static INT nested_quotes = 0; +static int quote_stack[32]; +static int quote_stk_idx = 0; #define YY_INPUT(buf,result,max_size)\ if ((result = *macroptr ? 1 : 0)) buf[0] = *macroptr++; @@ -35,181 +40,193 @@ static INT nested_quotes = 0; #define YY_NO_UNPUT %} %% -About yylval.void_function_void = MACRO_About; return VOID_FUNCTION_VOID; +About yylval.void_function_void = MACRO_About; return VOID_FUNCTION_VOID; AddAccelerator|AA yylval.void_function_2uint_string = MACRO_AddAccelerator; return VOID_FUNCTION_2UINT_STRING; -ALink|AL yylval.void_function_string_uint_string = MACRO_ALink; return VOID_FUNCTION_STRING_UINT_STRING; +ALink|AL yylval.void_function_string_uint_string = MACRO_ALink; return VOID_FUNCTION_STRING_UINT_STRING; Annotate yylval.void_function_void = MACRO_Annotate; return VOID_FUNCTION_VOID; -AppendItem yylval.void_function_4string = MACRO_AppendItem; return VOID_FUNCTION_4STRING; +AppendItem yylval.void_function_4string = MACRO_AppendItem; return VOID_FUNCTION_4STRING; Back yylval.void_function_void = MACRO_Back; return VOID_FUNCTION_VOID; BackFlush|BF yylval.void_function_void = MACRO_BackFlush; return VOID_FUNCTION_VOID; -BookmarkDefine yylval.void_function_void = MACRO_BookmarkDefine; return VOID_FUNCTION_VOID; +BookmarkDefine yylval.void_function_void = MACRO_BookmarkDefine; return VOID_FUNCTION_VOID; BookmarkMore yylval.void_function_void = MACRO_BookmarkMore; return VOID_FUNCTION_VOID; -BrowseButtons yylval.void_function_void = MACRO_BrowseButtons; return VOID_FUNCTION_VOID; +BrowseButtons yylval.void_function_void = MACRO_BrowseButtons; return VOID_FUNCTION_VOID; ChangeButtonBinding|CBB yylval.void_function_2string = MACRO_ChangeButtonBinding; return VOID_FUNCTION_2STRING; -ChangeEnable|CE yylval.void_function_2string = MACRO_ChangeEnable; return VOID_FUNCTION_2STRING; +ChangeEnable|CE yylval.void_function_2string = MACRO_ChangeEnable; return VOID_FUNCTION_2STRING; ChangeItemBinding|CIB yylval.void_function_2string = MACRO_ChangeItemBinding; return VOID_FUNCTION_2STRING; CheckItem|CI yylval.void_function_string = MACRO_CheckItem; return VOID_FUNCTION_STRING; -CloseSecondarys|CS yylval.void_function_void = MACRO_CloseSecondarys; return VOID_FUNCTION_VOID; -CloseWindow|CW yylval.void_function_string = MACRO_CloseWindow; return VOID_FUNCTION_STRING; -Compare yylval.void_function_string = MACRO_Compare; return VOID_FUNCTION_STRING; +CloseSecondarys|CS yylval.void_function_void = MACRO_CloseSecondarys; return VOID_FUNCTION_VOID; +CloseWindow|CW yylval.void_function_string = MACRO_CloseWindow; return VOID_FUNCTION_STRING; +Compare yylval.void_function_string = MACRO_Compare; return VOID_FUNCTION_STRING; Contents yylval.void_function_void = MACRO_Contents; return VOID_FUNCTION_VOID; -ControlPanel yylval.void_function_2string_uint = MACRO_ControlPanel; return VOID_FUNCTION_2STRING_UINT; +ControlPanel yylval.void_function_2string_uint = MACRO_ControlPanel; return VOID_FUNCTION_2STRING_UINT; CopyDialog yylval.void_function_void = MACRO_CopyDialog; return VOID_FUNCTION_VOID; CopyTopic|CT yylval.void_function_void = MACRO_CopyTopic; return VOID_FUNCTION_VOID; -CreateButton|CB yylval.void_function_3string = MACRO_CreateButton; return VOID_FUNCTION_3STRING; +CreateButton|CB yylval.void_function_3string = MACRO_CreateButton; return VOID_FUNCTION_3STRING; DeleteItem yylval.void_function_string = MACRO_DeleteItem; return VOID_FUNCTION_STRING; DeleteMark yylval.void_function_string = MACRO_DeleteMark; return VOID_FUNCTION_STRING; -DestroyButton yylval.void_function_string = MACRO_DestroyButton; return VOID_FUNCTION_STRING; -DisableButton|DB yylval.void_function_string = MACRO_DisableButton; return VOID_FUNCTION_STRING; -DisableItem|DI yylval.void_function_string = MACRO_DisableItem; return VOID_FUNCTION_STRING; -EnableButton|EB yylval.void_function_string = MACRO_EnableButton; return VOID_FUNCTION_STRING; +DestroyButton yylval.void_function_string = MACRO_DestroyButton; return VOID_FUNCTION_STRING; +DisableButton|DB yylval.void_function_string = MACRO_DisableButton; return VOID_FUNCTION_STRING; +DisableItem|DI yylval.void_function_string = MACRO_DisableItem; return VOID_FUNCTION_STRING; +EnableButton|EB yylval.void_function_string = MACRO_EnableButton; return VOID_FUNCTION_STRING; EnableItem|EI yylval.void_function_string = MACRO_EnableItem; return VOID_FUNCTION_STRING; EndMPrint yylval.void_function_void = MACRO_EndMPrint; return VOID_FUNCTION_VOID; ExecFile|EF yylval.void_function_2string_uint_string = MACRO_ExecFile; return VOID_FUNCTION_2STRING_UINT_STRING; -ExecProgram|EP yylval.void_function_string_uint = MACRO_ExecProgram; return VOID_FUNCTION_STRING_UINT; +ExecProgram|EP yylval.void_function_string_uint = MACRO_ExecProgram; return VOID_FUNCTION_STRING_UINT; Exit yylval.void_function_void = MACRO_Exit; return VOID_FUNCTION_VOID; -ExtAbleItem yylval.void_function_string_uint = MACRO_ExtAbleItem; return VOID_FUNCTION_STRING_UINT; +ExtAbleItem yylval.void_function_string_uint = MACRO_ExtAbleItem; return VOID_FUNCTION_STRING_UINT; ExtInsertItem yylval.void_function_4string_2uint = MACRO_ExtInsertItem; return VOID_FUNCTION_4STRING_2UINT; ExtInsertMenu yylval.void_function_3string_2uint = MACRO_ExtInsertMenu; return VOID_FUNCTION_3STRING_2UINT; FileExist|FE yylval.bool_function_string = MACRO_FileExist; return BOOL_FUNCTION_STRING; FileOpen|FO yylval.void_function_void = MACRO_FileOpen; return VOID_FUNCTION_VOID; Find yylval.void_function_void = MACRO_Find; return VOID_FUNCTION_VOID; -Finder|FD yylval.void_function_void = MACRO_Finder; return VOID_FUNCTION_VOID; +Finder|FD yylval.void_function_void = MACRO_Finder; return VOID_FUNCTION_VOID; FloatingMenu yylval.void_function_void = MACRO_FloatingMenu; return VOID_FUNCTION_VOID; -Flush|FH yylval.void_function_void = MACRO_Flush; return VOID_FUNCTION_VOID; -FocusWindow yylval.void_function_string = MACRO_FocusWindow; return VOID_FUNCTION_STRING; +Flush|FH yylval.void_function_void = MACRO_Flush; return VOID_FUNCTION_VOID; +FocusWindow yylval.void_function_string = MACRO_FocusWindow; return VOID_FUNCTION_STRING; Generate yylval.void_function_string_wparam_lparam = MACRO_Generate; return VOID_FUNCTION_STRING_WPARAM_LPARAM; GotoMark yylval.void_function_string = MACRO_GotoMark; return VOID_FUNCTION_STRING; -HelpOn yylval.void_function_void = MACRO_HelpOn; return VOID_FUNCTION_VOID; +HelpOn yylval.void_function_void = MACRO_HelpOn; return VOID_FUNCTION_VOID; HelpOnTop yylval.void_function_void = MACRO_HelpOnTop; return VOID_FUNCTION_VOID; -History yylval.void_function_void = MACRO_History; return VOID_FUNCTION_VOID; +History yylval.void_function_void = MACRO_History; return VOID_FUNCTION_VOID; IfThen|IF return IF_THEN; IfThenElse|IE return IF_THEN_ELSE; InitMPrint yylval.bool_function_void = MACRO_InitMPrint; return BOOL_FUNCTION_VOID; -InsertItem yylval.void_function_4string_uint = MACRO_InsertItem; return VOID_FUNCTION_4STRING_UINT; -InsertMenu yylval.void_function_2string_uint = MACRO_InsertMenu; return VOID_FUNCTION_2STRING_UINT; -IsBook yylval.bool_function_void = MACRO_IsBook; return BOOL_FUNCTION_VOID; -IsMark yylval.bool_function_string = MACRO_IsMark; return BOOL_FUNCTION_STRING; +InsertItem yylval.void_function_4string_uint = MACRO_InsertItem; return VOID_FUNCTION_4STRING_UINT; +InsertMenu yylval.void_function_2string_uint = MACRO_InsertMenu; return VOID_FUNCTION_2STRING_UINT; +IsBook yylval.bool_function_void = MACRO_IsBook; return BOOL_FUNCTION_VOID; +IsMark yylval.bool_function_string = MACRO_IsMark; return BOOL_FUNCTION_STRING; IsNotMark|NM yylval.bool_function_string = MACRO_IsNotMark; return BOOL_FUNCTION_STRING; -JumpContents yylval.void_function_2string = MACRO_JumpContents; return VOID_FUNCTION_FILE_WIN; -JumpContext|JC yylval.void_function_2string_uint = MACRO_JumpContext; return VOID_FUNCTION_FILE_WIN_UINT; -JumpHash|JH yylval.void_function_2string_uint = MACRO_JumpHash; return VOID_FUNCTION_FILE_WIN_UINT; +JumpContents yylval.void_function_2string = MACRO_JumpContents; return VOID_FUNCTION_FILE_WIN; +JumpContext|JC yylval.void_function_2string_uint = MACRO_JumpContext; return VOID_FUNCTION_FILE_WIN_UINT; +JumpHash|JH yylval.void_function_2string_uint = MACRO_JumpHash; return VOID_FUNCTION_FILE_WIN_UINT; JumpHelpOn yylval.void_function_void = MACRO_JumpHelpOn; return VOID_FUNCTION_VOID; -JumpID|JI yylval.void_function_3string = MACRO_JumpID; return VOID_FUNCTION_FILE_WIN_STRING; -JumpKeyword|JK yylval.void_function_3string = MACRO_JumpKeyword; return VOID_FUNCTION_FILE_WIN_STRING; -KLink|KL yylval.void_function_string_uint_2string = MACRO_KLink; return VOID_FUNCTION_STRING_UINT_2STRING; +JumpID|JI yylval.void_function_3string = MACRO_JumpID; return VOID_FUNCTION_FILE_WIN_STRING; +JumpKeyword|JK yylval.void_function_3string = MACRO_JumpKeyword; return VOID_FUNCTION_FILE_WIN_STRING; +KLink|KL yylval.void_function_string_uint_2string = MACRO_KLink; return VOID_FUNCTION_STRING_UINT_2STRING; Menu|MU yylval.void_function_void = MACRO_Menu; return VOID_FUNCTION_VOID; MPrintHash yylval.void_function_uint = MACRO_MPrintHash; return VOID_FUNCTION_UINT; MPrintID yylval.void_function_string = MACRO_MPrintID; return VOID_FUNCTION_STRING; Next yylval.void_function_void = MACRO_Next; return VOID_FUNCTION_VOID; -NoShow yylval.void_function_void = MACRO_NoShow; return VOID_FUNCTION_VOID; +NoShow yylval.void_function_void = MACRO_NoShow; return VOID_FUNCTION_VOID; Not return NOT; -PopupContext|PC yylval.void_function_string_uint = MACRO_PopupContext; return VOID_FUNCTION_STRING_UINT; -PopupHash yylval.void_function_string_uint = MACRO_PopupHash; return VOID_FUNCTION_STRING_UINT; -PopupId|PI yylval.void_function_2string = MACRO_PopupId; return VOID_FUNCTION_2STRING; +PopupContext|PC yylval.void_function_string_uint = MACRO_PopupContext; return VOID_FUNCTION_STRING_UINT; +PopupHash yylval.void_function_string_uint = MACRO_PopupHash; return VOID_FUNCTION_STRING_UINT; +PopupId|PI yylval.void_function_2string = MACRO_PopupId; return VOID_FUNCTION_2STRING; PositionWindow|PW yylval.void_function_2int_3uint_string = MACRO_PositionWindow; return VOID_FUNCTION_2INT_3UINT_STRING; Prev yylval.void_function_void = MACRO_Prev; return VOID_FUNCTION_VOID; -Print yylval.void_function_void = MACRO_Print; return VOID_FUNCTION_VOID; +Print yylval.void_function_void = MACRO_Print; return VOID_FUNCTION_VOID; PrinterSetup yylval.void_function_void = MACRO_PrinterSetup; return VOID_FUNCTION_VOID; -RegisterRoutine|RR yylval.void_function_3string = MACRO_RegisterRoutine; return VOID_FUNCTION_3STRING; +RegisterRoutine|RR yylval.void_function_3string = MACRO_RegisterRoutine; return VOID_FUNCTION_3STRING; RemoveAccelerator|RA yylval.void_function_2uint = MACRO_RemoveAccelerator; return VOID_FUNCTION_2UINT; ResetMenu yylval.void_function_void = MACRO_ResetMenu; return VOID_FUNCTION_VOID; SaveMark yylval.void_function_string = MACRO_SaveMark; return VOID_FUNCTION_STRING; -Search yylval.void_function_void = MACRO_Search; return VOID_FUNCTION_VOID; -SetContents yylval.void_function_string_uint = MACRO_SetContents; return VOID_FUNCTION_STRING_UINT; -SetHelpOnFile yylval.void_function_string = MACRO_SetHelpOnFile; return VOID_FUNCTION_STRING; -SetPopupColor|SPC yylval.void_function_3uint = MACRO_SetPopupColor; return VOID_FUNCTION_3UINT; -ShellExecute|SE yylval.void_function_2string_2uint_2string = MACRO_ShellExecute; return VOID_FUNCTION_2STRING_2UINT_2STRING; -ShortCut|SH yylval.void_function_2string_wparam_lparam_string = MACRO_ShortCut; return VOID_FUNCTION_2STRING_WPARAM_LPARAM_STRING; -TCard yylval.void_function_uint = MACRO_TCard; return VOID_FUNCTION_UINT; +Search yylval.void_function_void = MACRO_Search; return VOID_FUNCTION_VOID; +SetContents yylval.void_function_string_uint = MACRO_SetContents; return VOID_FUNCTION_STRING_UINT; +SetHelpOnFile yylval.void_function_string = MACRO_SetHelpOnFile; return VOID_FUNCTION_STRING; +SetPopupColor|SPC yylval.void_function_3uint = MACRO_SetPopupColor; return VOID_FUNCTION_3UINT; +ShellExecute|SE yylval.void_function_2string_2uint_2string = MACRO_ShellExecute; return VOID_FUNCTION_2STRING_2UINT_2STRING; +ShortCut|SH yylval.void_function_2string_wparam_lparam_string = MACRO_ShortCut; return VOID_FUNCTION_2STRING_WPARAM_LPARAM_STRING; +TCard yylval.void_function_uint = MACRO_TCard; return VOID_FUNCTION_UINT; Test yylval.void_function_uint = MACRO_Test; return VOID_FUNCTION_UINT; TestALink yylval.bool_function_string = MACRO_TestALink; return BOOL_FUNCTION_STRING; TestKLink yylval.bool_function_string = MACRO_TestKLink; return BOOL_FUNCTION_STRING; -UncheckItem|UI yylval.void_function_string = MACRO_UncheckItem; return VOID_FUNCTION_STRING; -UpdateWindow|UW yylval.void_function_2string = MACRO_UpdateWindow; return VOID_FUNCTION_2STRING; +UncheckItem|UI yylval.void_function_string = MACRO_UncheckItem; return VOID_FUNCTION_STRING; +UpdateWindow|UW yylval.void_function_2string = MACRO_UpdateWindow; return VOID_FUNCTION_2STRING; [-+]?[0-9]+ yylval.integer = strtol(yytext, NULL, 10); return INTEGER; [-+]?0[xX][0-9a-f]+ yylval.integer = strtol(yytext, NULL, 16); return INTEGER; -\` | -\" { - if (!hStringBuffer) - { - hStringBuffer = GlobalAlloc(GMEM_FIXED, strlen(macroptr)); - strptr = GlobalLock(hStringBuffer); - } - yylval.string = strptr; - BEGIN (yytext[0] == '`' ? quote : dquote); - } -<quote>\` { - *strptr++ = yytext[0]; - nested_quotes++; - } - -<quote>\' | -<dquote>\" { - if (nested_quotes) - { - nested_quotes--; - *strptr++ = yytext[0]; - } - else - { - BEGIN INITIAL; - *strptr++ = '\0'; - return tSTRING; - } - } - -<quote,dquote>. *strptr++ = yytext[0]; -<quote,dquote>\\. *strptr++ = yytext[1]; - -<quote,dquote><<EOF>> return 0; +\` | +\" | +\' | +<quote>\` | +<quote>\" | +<quote>\' { + if (quote_stk_idx == 0 || + (yytext[0] == '\"' && quote_stack[quote_stk_idx - 1] != '\"') || + (yytext[0] == '`')) + { + /* opening a new one */ + if (quote_stk_idx == 0) + { + strptr = HeapAlloc(GetProcessHeap(), 0, strlen(macroptr) + 1); + yylval.string = strptr; + BEGIN(quote); + } + else *strptr++ = yytext[0]; + quote_stack[quote_stk_idx++] = yytext[0]; + assert(quote_stk_idx < sizeof(quote_stack) / sizeof(quote_stack[0])); + } + else + { + if (yytext[0] == '`') assert(0); + /* close the current quote */ + if (--quote_stk_idx == 0) + { + BEGIN INITIAL; + *strptr++ = '\0'; + return tSTRING; + } + else *strptr++ = yytext[0]; + } + } +<quote>. *strptr++ = yytext[0]; +<quote>\\. *strptr++ = yytext[1]; +<quote><<EOF>> return 0; " " - -. return yytext[0]; +. return yytext[0]; %% #include "winhelp.h" static CHAR szTestMacro[256]; static LRESULT CALLBACK MACRO_TestDialogProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) { - if (msg == WM_COMMAND && wParam == IDOK) + if (msg == WM_COMMAND && wParam == IDOK) { - GetDlgItemText(hDlg, 99, szTestMacro, sizeof(szTestMacro)); - EndDialog(hDlg, IDOK); - return TRUE; + GetDlgItemText(hDlg, 99, szTestMacro, sizeof(szTestMacro)); + EndDialog(hDlg, IDOK); + return TRUE; } - return FALSE; + return FALSE; } -VOID MACRO_ExecuteMacro(LPCSTR macro) +void MACRO_ExecuteMacro(LPCSTR macro) { - if (!lstrcmpi(macro, "MacroTest")) + WINE_TRACE("%s\n", wine_dbgstr_a(macro)); + if (!lstrcmpi(macro, "MacroTest")) { - WNDPROC lpfnDlg = MakeProcInstance(MACRO_TestDialogProc, Globals.hInstance); - DialogBox(Globals.hInstance, STRING_DIALOG_TEST, Globals.active_win->hMainWnd, (DLGPROC)lpfnDlg); - FreeProcInstance(lpfnDlg); - macro = szTestMacro; + WNDPROC lpfnDlg = MakeProcInstance(MACRO_TestDialogProc, Globals.hInstance); + DialogBox(Globals.hInstance, STRING_DIALOG_TEST, Globals.active_win->hMainWnd, (DLGPROC)lpfnDlg); + FreeProcInstance(lpfnDlg); + macro = szTestMacro; } - macroptr = macro; + macroptr = macro; - yyparse(); + yyparse(); - if (hStringBuffer) GlobalFree(hStringBuffer); - hStringBuffer = 0; + if (strptr) + { + HeapFree(GetProcessHeap(), 0, strptr); + strptr = NULL; + } + quote_stk_idx = 0; } -void yyerror (const char *s) +void yyerror(const char *s) { - fprintf(stderr, "%s\n", s); - nested_quotes = 0; - BEGIN INITIAL; - yyrestart(yyin); + WINE_WARN("Error while parsing: %s\n", s); + BEGIN INITIAL; + yyrestart(yyin); + if (strptr) + { + HeapFree(GetProcessHeap(), 0, strptr); + strptr = NULL; + } + quote_stk_idx = 0; } #ifndef yywrap diff --git a/programs/winhelp/macro.yacc.y b/programs/winhelp/macro.yacc.y index 84f022afde3..f819e0e53b7 100644 --- a/programs/winhelp/macro.yacc.y +++ b/programs/winhelp/macro.yacc.y @@ -97,83 +97,83 @@ macrosep: ';' | ':' ; macro: /* Empty */ | - IF_THEN '(' bool_macro ',' {if (! $3) skip++;} - macrostring ')' {if (! $3) skip--;} | - IF_THEN_ELSE '(' bool_macro ',' {if (! $3) skip++;} - macrostring ',' {if (! $3) skip--; else skip++;} - macrostring ')' {if ( $3) skip--;} | + IF_THEN '(' bool_macro ',' {if (!$3) skip++;} + macrostring ')' {if (!$3) skip--;} | + IF_THEN_ELSE '(' bool_macro ',' {if (!$3) skip++;} + macrostring ',' {if (!$3) skip--; else skip++;} + macrostring ')' {if ( $3) skip--;} | VOID_FUNCTION_VOID '(' ')' - {if (! skip) (*$1)();} | + {if (!skip) (*$1)();} | VOID_FUNCTION_STRING '(' tSTRING ')' - {if (! skip) (*$1)($3);} | + {if (!skip) (*$1)($3);} | VOID_FUNCTION_2STRING '(' tSTRING ',' tSTRING ')' - {if (! skip) (*$1)($3, $5);} | + {if (!skip) (*$1)($3, $5);} | VOID_FUNCTION_2STRING_UINT '(' tSTRING ',' tSTRING ',' INTEGER ')' - {if (! skip) (*$1)($3, $5, $7);} | + {if (!skip) (*$1)($3, $5, $7);} | VOID_FUNCTION_2STRING_UINT_STRING '(' tSTRING ',' tSTRING ',' INTEGER ',' tSTRING ')' - {if (! skip) (*$1)($3, $5, $7, $9);} | + {if (!skip) (*$1)($3, $5, $7, $9);} | VOID_FUNCTION_2STRING_2UINT_2STRING '(' tSTRING ',' tSTRING ',' INTEGER ',' INTEGER ',' tSTRING ',' tSTRING ')' - {if (! skip) (*$1)($3, $5, $7, $9, $11, $13);} | + {if (!skip) (*$1)($3, $5, $7, $9, $11, $13);} | VOID_FUNCTION_2STRING_WPARAM_LPARAM_STRING '(' tSTRING ',' tSTRING ',' INTEGER ',' INTEGER ',' tSTRING ')' - {if (! skip) (*$1)($3, $5, $7, $9, $11);} | + {if (!skip) (*$1)($3, $5, $7, $9, $11);} | VOID_FUNCTION_3STRING '(' tSTRING ',' tSTRING ',' tSTRING ')' - {if (! skip) (*$1)($3, $5, $7);} | + {if (!skip) (*$1)($3, $5, $7);} | VOID_FUNCTION_3STRING_2UINT '(' tSTRING ',' tSTRING ',' tSTRING ',' INTEGER ',' INTEGER ')' - {if (! skip) (*$1)($3, $5, $7, $9, $11);} | + {if (!skip) (*$1)($3, $5, $7, $9, $11);} | VOID_FUNCTION_4STRING '(' tSTRING ',' tSTRING ',' tSTRING ',' tSTRING ')' - {if (! skip) (*$1)($3, $5, $7, $9);} | + {if (!skip) (*$1)($3, $5, $7, $9);} | VOID_FUNCTION_4STRING_UINT '(' tSTRING ',' tSTRING ',' tSTRING ',' tSTRING ',' INTEGER')' - {if (! skip) (*$1)($3, $5, $7, $9, $11);} | + {if (!skip) (*$1)($3, $5, $7, $9, $11);} | VOID_FUNCTION_4STRING_2UINT '(' tSTRING ',' tSTRING ',' tSTRING ',' tSTRING ',' INTEGER ',' INTEGER')' - {if (! skip) (*$1)($3, $5, $7, $9, $11, $13);} | + {if (!skip) (*$1)($3, $5, $7, $9, $11, $13);} | VOID_FUNCTION_STRING_UINT '(' tSTRING ',' INTEGER ')' - {if (! skip) (*$1)($3, $5);} | + {if (!skip) (*$1)($3, $5);} | VOID_FUNCTION_STRING_UINT_STRING '(' tSTRING ',' INTEGER ',' tSTRING ')' - {if (! skip) (*$1)($3, $5, $7);} | + {if (!skip) (*$1)($3, $5, $7);} | VOID_FUNCTION_STRING_UINT_2STRING '(' tSTRING ',' INTEGER ',' tSTRING ',' tSTRING ')' - {if (! skip) (*$1)($3, $5, $7, $9);} | + {if (!skip) (*$1)($3, $5, $7, $9);} | VOID_FUNCTION_STRING_WPARAM_LPARAM '(' tSTRING ',' INTEGER ',' INTEGER ')' - {if (! skip) (*$1)($3, $5, $7);} | + {if (!skip) (*$1)($3, $5, $7);} | VOID_FUNCTION_UINT '(' INTEGER ')' - {if (! skip) (*$1)($3);} | + {if (!skip) (*$1)($3);} | VOID_FUNCTION_2UINT '(' INTEGER ',' INTEGER ')' - {if (! skip) (*$1)($3, $5);} | + {if (!skip) (*$1)($3, $5);} | VOID_FUNCTION_2UINT_STRING '(' INTEGER ',' INTEGER ',' tSTRING ')' - {if (! skip) (*$1)($3, $5, $7);} | + {if (!skip) (*$1)($3, $5, $7);} | VOID_FUNCTION_3UINT '(' INTEGER ',' INTEGER ',' INTEGER ')' - {if (! skip) (*$1)($3, $5, $7);} | + {if (!skip) (*$1)($3, $5, $7);} | VOID_FUNCTION_2INT_3UINT_STRING '(' INTEGER ',' INTEGER ',' INTEGER ',' INTEGER ',' INTEGER ',' tSTRING ')' - {if (! skip) (*$1)($3, $5, $7, $9, $11, $13);} | + {if (!skip) (*$1)($3, $5, $7, $9, $11, $13);} | VOID_FUNCTION_FILE_WIN '(' file_win ')' - {if (! skip) (*$1)(filename, windowname);} | + {if (!skip) (*$1)(filename, windowname);} | VOID_FUNCTION_FILE_WIN_STRING '(' file_win ',' tSTRING ')' - {if (! skip) (*$1)(filename, windowname, $5);} | + {if (!skip) (*$1)(filename, windowname, $5);} | VOID_FUNCTION_FILE_WIN_UINT '(' file_win ',' INTEGER ')' - {if (! skip) (*$1)(filename, windowname, $5);} ; + {if (!skip) (*$1)(filename, windowname, $5);} ; file_win: tSTRING { diff --git a/programs/winhelp/winhelp.c b/programs/winhelp/winhelp.c index df5ff3050ec..9a2e1a7c8b7 100644 --- a/programs/winhelp/winhelp.c +++ b/programs/winhelp/winhelp.c @@ -1,8 +1,9 @@ /* * Help Viewer * - * Copyright 1996 Ulrich Schmid <uschmid@mail.hh.provi.de> - * Copyright 2002 Sylvain Petreolle <spetreolle@yahoo.fr> + * Copyright 1996 Ulrich Schmid <uschmid@mail.hh.provi.de> + * 2002 Sylvain Petreolle <spetreolle@yahoo.fr> + * 2002 Eric Pouech <eric.pouech@wanadoo.fr> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -22,23 +23,25 @@ #include <stdio.h> #include <string.h> #include "winbase.h" +#include "wingdi.h" #include "windowsx.h" #include "winhelp.h" #include "winhelp_res.h" -static BOOL WINHELP_RegisterWinClasses(); +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(winhelp); + +static BOOL WINHELP_RegisterWinClasses(void); 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 VOID WINHELP_CheckPopup(UINT); +static void WINHELP_CheckPopup(UINT); static BOOL WINHELP_SplitLines(HWND hWnd, LPSIZE); -static VOID WINHELP_InitFonts(HWND hWnd); -static VOID WINHELP_DeleteLines(WINHELP_WINDOW*); -static VOID WINHELP_DeleteWindow(WINHELP_WINDOW*); -static VOID WINHELP_SetupText(HWND hWnd); -static BOOL WINHELP_AppendText(WINHELP_LINE***, WINHELP_LINE_PART***, - LPSIZE, LPSIZE, INT*, INT, LPCSTR, UINT, - HFONT, COLORREF, HLPFILE_LINK*); +static void WINHELP_InitFonts(HWND hWnd); +static void WINHELP_DeleteLines(WINHELP_WINDOW*); +static void WINHELP_DeleteWindow(WINHELP_WINDOW*); +static void WINHELP_SetupText(HWND hWnd); static WINHELP_LINE_PART* WINHELP_IsOverLink(HWND hWnd, WPARAM wParam, LPARAM lParam); WINHELP_GLOBALS Globals = {3, 0, 0, 0, 0, 0}; @@ -49,96 +52,94 @@ static BOOL MacroTest = FALSE; * * WinMain */ - -int PASCAL WinMain (HINSTANCE hInstance, HINSTANCE prev, LPSTR cmdline, int show) +int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE prev, LPSTR cmdline, int show) { - MSG msg; - LONG lHash = 0; + MSG msg; + LONG lHash = 0; - Globals.hInstance = hInstance; + Globals.hInstance = hInstance; - /* Get options */ - while (*cmdline && (*cmdline == ' ' || *cmdline == '-')) + /* Get options */ + while (*cmdline && (*cmdline == ' ' || *cmdline == '-')) { - CHAR option; - LPCSTR topic_id; - if (*cmdline++ == ' ') continue; + CHAR option; + LPCSTR topic_id; + if (*cmdline++ == ' ') continue; - option = *cmdline; - if (option) cmdline++; - while (*cmdline && *cmdline == ' ') cmdline++; - switch(option) + option = *cmdline; + if (option) cmdline++; + while (*cmdline && *cmdline == ' ') cmdline++; + switch (option) { case 'i': case 'I': - topic_id = cmdline; - while (*cmdline && *cmdline != ' ') cmdline++; - if (*cmdline) *cmdline++ = '\0'; - lHash = HLPFILE_Hash(topic_id); - break; + topic_id = cmdline; + while (*cmdline && *cmdline != ' ') cmdline++; + if (*cmdline) *cmdline++ = '\0'; + lHash = HLPFILE_Hash(topic_id); + break; case '3': case '4': - Globals.wVersion = option - '0'; - break; + Globals.wVersion = option - '0'; + break; case 't': - MacroTest = TRUE; - break; + MacroTest = TRUE; + break; } } - /* Create primary window */ - WINHELP_RegisterWinClasses(); - WINHELP_CreateHelpWindow(cmdline, lHash, "main", FALSE, NULL, NULL, show); + /* Create primary window */ + WINHELP_RegisterWinClasses(); + WINHELP_CreateHelpWindowByHash(cmdline, lHash, "main", FALSE, NULL, NULL, show); - /* Message loop */ - while (GetMessage (&msg, 0, 0, 0)) + /* Message loop */ + while (GetMessage(&msg, 0, 0, 0)) { - TranslateMessage (&msg); - DispatchMessage (&msg); + TranslateMessage(&msg); + DispatchMessage(&msg); } - return 0; + return 0; } /*********************************************************************** * * RegisterWinClasses */ - -static BOOL WINHELP_RegisterWinClasses() +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_main.style = CS_HREDRAW | CS_VREDRAW; - class_main.lpfnWndProc = WINHELP_MainWndProc; - class_main.cbClsExtra = 0; - class_main.cbWndExtra = sizeof(LONG); - class_main.hInstance = Globals.hInstance; - class_main.hIcon = LoadIcon (0, IDI_APPLICATION); - class_main.hCursor = LoadCursor (0, IDC_ARROW); - class_main.hbrBackground = GetStockObject (WHITE_BRUSH); - class_main.lpszMenuName = 0; - class_main.lpszClassName = MAIN_WIN_CLASS_NAME; + class_main.style = CS_HREDRAW | CS_VREDRAW; + class_main.lpfnWndProc = WINHELP_MainWndProc; + class_main.cbClsExtra = 0; + class_main.cbWndExtra = sizeof(LONG); + class_main.hInstance = Globals.hInstance; + class_main.hIcon = LoadIcon(0, IDI_APPLICATION); + class_main.hCursor = LoadCursor(0, IDC_ARROW); + class_main.hbrBackground = GetStockObject(WHITE_BRUSH); + class_main.lpszMenuName = 0; + class_main.lpszClassName = MAIN_WIN_CLASS_NAME; - class_button_box = class_main; - class_button_box.lpfnWndProc = WINHELP_ButtonBoxWndProc; - class_button_box.hbrBackground = GetStockObject(GRAY_BRUSH); - class_button_box.lpszClassName = BUTTON_BOX_WIN_CLASS_NAME; + class_button_box = class_main; + class_button_box.lpfnWndProc = WINHELP_ButtonBoxWndProc; + class_button_box.hbrBackground = GetStockObject(GRAY_BRUSH); + class_button_box.lpszClassName = BUTTON_BOX_WIN_CLASS_NAME; - class_text = class_main; - class_text.lpfnWndProc = WINHELP_TextWndProc; - class_text.lpszClassName = TEXT_WIN_CLASS_NAME; + class_text = class_main; + class_text.lpfnWndProc = WINHELP_TextWndProc; + class_text.lpszClassName = TEXT_WIN_CLASS_NAME; - class_shadow = class_main; - class_shadow.lpfnWndProc = DefWindowProc; - class_shadow.hbrBackground = GetStockObject(GRAY_BRUSH); - class_shadow.lpszClassName = SHADOW_WIN_CLASS_NAME; + class_shadow = class_main; + class_shadow.lpfnWndProc = DefWindowProc; + class_shadow.hbrBackground = GetStockObject(GRAY_BRUSH); + class_shadow.lpszClassName = SHADOW_WIN_CLASS_NAME; - return (RegisterClass(&class_main) && - RegisterClass(&class_button_box) && - RegisterClass(&class_text) && - RegisterClass(&class_shadow)); + return (RegisterClass(&class_main) && + RegisterClass(&class_button_box) && + RegisterClass(&class_text) && + RegisterClass(&class_shadow)); } /*********************************************************************** @@ -146,421 +147,445 @@ static BOOL WINHELP_RegisterWinClasses() * WINHELP_CreateHelpWindow */ -VOID WINHELP_CreateHelpWindow(LPCSTR lpszFile, LONG lHash, LPCSTR lpszWindow, - BOOL bPopup, HWND hParentWnd, LPPOINT mouse, INT nCmdShow) +static BOOL WINHELP_CreateHelpWindow(HLPFILE_PAGE* page, LPCSTR lpszWindow, + BOOL bPopup, HWND hParentWnd, LPPOINT mouse, INT nCmdShow) { - CHAR szCaption[MAX_STRING_LEN]; - CHAR szContents[MAX_STRING_LEN]; - CHAR szSearch[MAX_STRING_LEN]; - CHAR szBack[MAX_STRING_LEN]; - CHAR szHistory[MAX_STRING_LEN]; - SIZE size = {CW_USEDEFAULT, CW_USEDEFAULT}; - POINT origin = {240, 0}; - LPSTR ptr; - HGLOBAL handle; - WINHELP_WINDOW *win, *oldwin; - HLPFILE_PAGE *page; - HLPFILE_MACRO *macro; - HWND hWnd; - BOOL bPrimary; + CHAR szCaption[MAX_STRING_LEN]; + CHAR szContents[MAX_STRING_LEN]; + CHAR szSearch[MAX_STRING_LEN]; + CHAR szBack[MAX_STRING_LEN]; + CHAR szHistory[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"); + if (bPopup) + lpszWindow = NULL; + else if (!lpszWindow || !lpszWindow[0]) + lpszWindow = Globals.active_win->lpszName; + bPrimary = lpszWindow && !lstrcmpi(lpszWindow, "main"); - /* Read help file */ - if (lpszFile[0]) + /* Calculate horizontal size and position of a popup window */ + if (bPopup) { - page = lHash ? HLPFILE_PageByHash(lpszFile, lHash) : HLPFILE_Contents(lpszFile); + 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 */ - /* Add Suffix `.hlp' */ - if (!page && lstrcmpi(lpszFile + strlen(lpszFile) - 4, ".hlp")) + 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); + } + + /* Initialize WINHELP_WINDOW struct */ + win = HeapAlloc(GetProcessHeap(), 0, + sizeof(WINHELP_WINDOW) + (lpszWindow ? strlen(lpszWindow) + 1 : 0)); + 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->page = page; + win->first_button = 0; + win->first_line = 0; + win->hMainWnd = 0; + win->hButtonBoxWnd = 0; + win->hTextWnd = 0; + win->hShadowWnd = 0; + + win->hArrowCur = LoadCursorA(0, IDC_ARROWA); + win->hHandCur = LoadCursorA(0, IDC_HANDA); + + Globals.active_win = win; + + /* Initialize default pushbuttons */ + if (MacroTest && !bPopup) + MACRO_CreateButton("BTN_TEST", "&Test", "MacroTest"); + if (bPrimary && page) + { + LoadString(Globals.hInstance, 0x126, szContents, sizeof(szContents)); + LoadString(Globals.hInstance, 0x127, szSearch, sizeof(szSearch)); + LoadString(Globals.hInstance, 0x128, szBack, sizeof(szBack)); + LoadString(Globals.hInstance, 0x129, szHistory, sizeof(szHistory)); + MACRO_CreateButton("BTN_CONTENTS", szContents, "Contents()"); + MACRO_CreateButton("BTN_SEARCH", szSearch, "Search()"); + MACRO_CreateButton("BTN_BACK", szBack, "Back()"); + MACRO_CreateButton("BTN_HISTORY", szHistory, "History()"); + } + + /* Initialize file specific pushbuttons */ + if (!bPopup && page) + for (macro = page->file->first_macro; macro; macro = macro->next) + MACRO_ExecuteMacro(macro->lpszMacro); + + /* Reuse existing window */ + if (lpszWindow) + for (oldwin = win->next; oldwin; oldwin = oldwin->next) + if (oldwin->lpszName && !lstrcmpi(oldwin->lpszName, lpszWindow)) + { + 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); + UpdateWindow(win->hTextWnd); + + + for (button = oldwin->first_button; button; button = button->next) + DestroyWindow(button->hWnd); + + WINHELP_DeleteWindow(oldwin); + return TRUE; + } + + /* Create main Window */ + if (!page) LoadString(Globals.hInstance, 0x120, 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, + 0, bPrimary ? LoadMenu(Globals.hInstance, MAKEINTRESOURCE(MAIN_MENU)) : 0, + Globals.hInstance, win); + + ShowWindow(hWnd, nCmdShow); + UpdateWindow(hWnd); + + 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) +{ + HLPFILE_PAGE* page; + + /* Read help file */ + if (lpszFile[0]) + { + page = lHash ? HLPFILE_PageByHash(lpszFile, lHash) : HLPFILE_Contents(lpszFile); + + /* Add Suffix `.hlp' */ + if (!page && lstrcmpi(lpszFile + strlen(lpszFile) - 4, ".hlp")) { - CHAR szFile_hlp[MAX_PATHNAME_LEN]; + 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"); + lstrcpyn(szFile_hlp, lpszFile, sizeof(szFile_hlp) - 4); + szFile_hlp[sizeof(szFile_hlp) - 5] = '\0'; + lstrcat(szFile_hlp, ".hlp"); - page = lHash ? HLPFILE_PageByHash(szFile_hlp, lHash) : HLPFILE_Contents(szFile_hlp); - if (!page) + page = lHash ? HLPFILE_PageByHash(szFile_hlp, lHash) : HLPFILE_Contents(szFile_hlp); + if (!page) { - WINHELP_MessageBoxIDS_s(HLPFILE_ERROR_s, lpszFile, WHERROR, MB_OK); - if (Globals.win_list) return; + WINHELP_MessageBoxIDS_s(HLPFILE_ERROR_s, lpszFile, WHERROR, MB_OK); + if (Globals.win_list) return FALSE; } } } - else page = 0; - - /* 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; - - 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); - } - - /* Initialize WINHELP_WINDOW struct */ - handle = GlobalAlloc(GMEM_FIXED, sizeof(WINHELP_WINDOW) + - (lpszWindow ? strlen(lpszWindow) + 1 : 0)); - if (!handle) return; - win = GlobalLock(handle); - win->hSelf = handle; - win->next = Globals.win_list; - Globals.win_list = win; - if (lpszWindow) - { - ptr = GlobalLock(handle); - ptr += sizeof(WINHELP_WINDOW); - lstrcpy(ptr, (LPSTR) lpszWindow); - win->lpszName = ptr; - } - else win->lpszName = NULL; - - win->page = page; - win->first_button = 0; - win->first_line = 0; - win->hMainWnd = 0; - win->hButtonBoxWnd = 0; - win->hTextWnd = 0; - win->hShadowWnd = 0; - - win->hArrowCur = LoadCursorA(0, IDC_ARROWA); - win->hHandCur = LoadCursorA(0, IDC_HANDA); - - Globals.active_win = win; - - /* Initialize default pushbuttons */ - if (MacroTest && !bPopup) - MACRO_CreateButton("BTN_TEST", "&Test", "MacroTest"); - if (bPrimary && page) - { - LoadString(Globals.hInstance, 0x126, szContents, sizeof(szContents)); - LoadString(Globals.hInstance, 0x127, szSearch, sizeof(szSearch)); - LoadString(Globals.hInstance, 0x128, szBack, sizeof(szBack)); - LoadString(Globals.hInstance, 0x129, szHistory, sizeof(szHistory)); - MACRO_CreateButton("BTN_CONTENTS", szContents, "Contents()"); - MACRO_CreateButton("BTN_SEARCH", szSearch, "Search()"); - MACRO_CreateButton("BTN_BACK", szBack, "Back()"); - MACRO_CreateButton("BTN_HISTORY", szHistory, "History()"); - } - - /* Initialize file specific pushbuttons */ - if (!bPopup && page) - for (macro = page->file->first_macro; macro; macro = macro->next) - MACRO_ExecuteMacro(macro->lpszMacro); - - /* Reuse existing window */ - if (lpszWindow) - for (oldwin = win->next; oldwin; oldwin = oldwin->next) - if (oldwin->lpszName && !lstrcmpi(oldwin->lpszName, lpszWindow)) - { - 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); - UpdateWindow(win->hTextWnd); - - - for (button = oldwin->first_button; button; button = button->next) - DestroyWindow(button->hWnd); - - WINHELP_DeleteWindow(oldwin); - return; - } - - /* Create main Window */ - if (!page) LoadString(Globals.hInstance, 0x120, 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, - 0, bPrimary ? LoadMenu(Globals.hInstance, MAKEINTRESOURCE(MAIN_MENU)) : 0, - Globals.hInstance, win); - - ShowWindow (hWnd, nCmdShow); - UpdateWindow (hWnd); + else page = NULL; + return WINHELP_CreateHelpWindowByPage(page, lpszWindow, bPopup, hParentWnd, mouse, nCmdShow); } /*********************************************************************** * * WINHELP_MainWndProc */ - -static LRESULT CALLBACK WINHELP_MainWndProc (HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) +static LRESULT CALLBACK WINHELP_MainWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { - WINHELP_WINDOW *win; - WINHELP_BUTTON *button; - RECT rect, button_box_rect; - INT text_top; + WINHELP_WINDOW *win; + WINHELP_BUTTON *button; + RECT rect, button_box_rect; + INT text_top; - WINHELP_CheckPopup(msg); + WINHELP_CheckPopup(msg); - switch (msg) + switch (msg) { case WM_NCCREATE: - win = (WINHELP_WINDOW*) ((LPCREATESTRUCT) lParam)->lpCreateParams; - SetWindowLong(hWnd, 0, (LONG) win); - win->hMainWnd = hWnd; - break; + win = (WINHELP_WINDOW*) ((LPCREATESTRUCT) lParam)->lpCreateParams; + SetWindowLong(hWnd, 0, (LONG) win); + win->hMainWnd = hWnd; + break; case WM_CREATE: - win = (WINHELP_WINDOW*) GetWindowLong(hWnd, 0); + win = (WINHELP_WINDOW*) GetWindowLong(hWnd, 0); - /* Create button box and text Window */ - CreateWindow(BUTTON_BOX_WIN_CLASS_NAME, "", WS_CHILD | WS_VISIBLE, - 0, 0, 0, 0, hWnd, 0, Globals.hInstance, win); + /* Create button box and text Window */ + CreateWindow(BUTTON_BOX_WIN_CLASS_NAME, "", WS_CHILD | WS_VISIBLE, + 0, 0, 0, 0, hWnd, 0, Globals.hInstance, win); - CreateWindow(TEXT_WIN_CLASS_NAME, "", WS_CHILD | WS_VISIBLE, - 0, 0, 0, 0, hWnd, 0, Globals.hInstance, win); + CreateWindow(TEXT_WIN_CLASS_NAME, "", WS_CHILD | WS_VISIBLE, + 0, 0, 0, 0, hWnd, 0, Globals.hInstance, win); - /* Fall through */ + /* Fall through */ case WM_USER: case WM_WINDOWPOSCHANGED: - win = (WINHELP_WINDOW*) GetWindowLong(hWnd, 0); - GetClientRect(hWnd, &rect); + win = (WINHELP_WINDOW*) GetWindowLong(hWnd, 0); + GetClientRect(hWnd, &rect); - /* Update button box and text Window */ - SetWindowPos(win->hButtonBoxWnd, HWND_TOP, - rect.left, rect.top, - rect.right - rect.left, - rect.bottom - rect.top, 0); + /* Update button box and text Window */ + SetWindowPos(win->hButtonBoxWnd, HWND_TOP, + rect.left, rect.top, + rect.right - rect.left, + rect.bottom - rect.top, 0); - GetWindowRect(win->hButtonBoxWnd, &button_box_rect); - text_top = rect.top + button_box_rect.bottom - button_box_rect.top; + GetWindowRect(win->hButtonBoxWnd, &button_box_rect); + text_top = rect.top + button_box_rect.bottom - button_box_rect.top; - SetWindowPos(win->hTextWnd, HWND_TOP, - rect.left, text_top, - rect.right - rect.left, - rect.bottom - text_top, 0); + SetWindowPos(win->hTextWnd, HWND_TOP, + rect.left, text_top, + rect.right - rect.left, + rect.bottom - text_top, 0); - break; + break; case WM_COMMAND: - Globals.active_win = win = (WINHELP_WINDOW*) GetWindowLong(hWnd, 0); - switch (wParam) + Globals.active_win = win = (WINHELP_WINDOW*) GetWindowLong(hWnd, 0); + switch (wParam) { - /* Menu FILE */ + /* Menu FILE */ case 0x101: MACRO_FileOpen(); break; case 0x104: MACRO_Print(); break; case 0x106: MACRO_PrinterSetup(); break; case 0x108: MACRO_Exit(); break; - /* Menu EDIT */ - case 0x10A: MACRO_CopyDialog(); break; - case 0x10C: MACRO_Annotate(); break; + /* Menu EDIT */ + case 0x10A: MACRO_CopyDialog(); break; + case 0x10C: MACRO_Annotate(); break; - /* Menu Bookmark */ + /* Menu Bookmark */ case 0x10E: MACRO_BookmarkDefine(); break; - /* Menu Help */ + /* Menu Help */ case 0x110: MACRO_HelpOn(); break; case 0x111: MACRO_HelpOnTop(); break; - /* Menu Info */ + /* Menu Info */ case 0x113: MACRO_About(); break; case 0x114: - ShellAbout(hWnd, "WINE", "Help", 0); - break; + ShellAbout(hWnd, "WINE", "Help", 0); + break; default: - /* Buttons */ - for (button = win->first_button; button; button = button->next) - if (wParam == button->wParam) break; - if (button) - MACRO_ExecuteMacro(button->lpszMacro); - else - WINHELP_MessageBoxIDS(0x124, 0x121, MB_OK); - break; + /* Buttons */ + for (button = win->first_button; button; button = button->next) + if (wParam == button->wParam) break; + if (button) + MACRO_ExecuteMacro(button->lpszMacro); + else + WINHELP_MessageBoxIDS(0x124, 0x121, MB_OK); + break; } - break; + break; + case WM_DESTROY: + if (Globals.hPopupWnd) DestroyWindow(Globals.hPopupWnd); + break; } - return DefWindowProc (hWnd, msg, wParam, lParam); + return DefWindowProc(hWnd, msg, wParam, lParam); } /*********************************************************************** * * WINHELP_ButtonBoxWndProc */ - -static LRESULT CALLBACK WINHELP_ButtonBoxWndProc (HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) +static LRESULT CALLBACK WINHELP_ButtonBoxWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { - WINDOWPOS *winpos; - WINHELP_WINDOW *win; - WINHELP_BUTTON *button; - SIZE button_size; - INT x, y; + WINDOWPOS *winpos; + WINHELP_WINDOW *win; + WINHELP_BUTTON *button; + SIZE button_size; + INT x, y; - WINHELP_CheckPopup(msg); + WINHELP_CheckPopup(msg); - switch(msg) + switch (msg) { case WM_NCCREATE: - win = (WINHELP_WINDOW*) ((LPCREATESTRUCT) lParam)->lpCreateParams; - SetWindowLong(hWnd, 0, (LONG) win); - win->hButtonBoxWnd = hWnd; - break; + win = (WINHELP_WINDOW*) ((LPCREATESTRUCT) lParam)->lpCreateParams; + SetWindowLong(hWnd, 0, (LONG) win); + win->hButtonBoxWnd = hWnd; + break; case WM_WINDOWPOSCHANGING: - winpos = (WINDOWPOS*) lParam; - win = (WINHELP_WINDOW*) GetWindowLong(hWnd, 0); + winpos = (WINDOWPOS*) lParam; + win = (WINHELP_WINDOW*) GetWindowLong(hWnd, 0); - /* Update buttons */ - button_size.cx = 0; - button_size.cy = 0; - for (button = win->first_button; button; button = button->next) + /* Update buttons */ + button_size.cx = 0; + button_size.cy = 0; + for (button = win->first_button; button; button = button->next) { - HDC hDc; - SIZE textsize; - if (!button->hWnd) - button->hWnd = CreateWindow(STRING_BUTTON, (LPSTR) button->lpszName, - WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, - 0, 0, 0, 0, - hWnd, (HMENU) button->wParam, - Globals.hInstance, 0); - hDc = GetDC(button->hWnd); - GetTextExtentPoint(hDc, button->lpszName, - lstrlen(button->lpszName), &textsize); - ReleaseDC(button->hWnd, hDc); + HDC hDc; + SIZE textsize; + if (!button->hWnd) + button->hWnd = CreateWindow(STRING_BUTTON, (LPSTR) button->lpszName, + WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, + 0, 0, 0, 0, + hWnd, (HMENU) button->wParam, + Globals.hInstance, 0); + hDc = GetDC(button->hWnd); + GetTextExtentPoint(hDc, button->lpszName, + lstrlen(button->lpszName), &textsize); + ReleaseDC(button->hWnd, hDc); - button_size.cx = max(button_size.cx, textsize.cx + BUTTON_CX); - button_size.cy = max(button_size.cy, textsize.cy + BUTTON_CY); + button_size.cx = max(button_size.cx, textsize.cx + BUTTON_CX); + button_size.cy = max(button_size.cy, textsize.cy + BUTTON_CY); } - x = 0; - y = 0; - for (button = win->first_button; button; button = button->next) + x = 0; + y = 0; + for (button = win->first_button; button; button = button->next) { - SetWindowPos(button->hWnd, HWND_TOP, x, y, button_size.cx, button_size.cy, 0); + SetWindowPos(button->hWnd, HWND_TOP, x, y, button_size.cx, button_size.cy, 0); - if (x + 2 * button_size.cx <= winpos->cx) - x += button_size.cx; - else - x = 0, y += button_size.cy; + if (x + 2 * button_size.cx <= winpos->cx) + x += button_size.cx; + else + x = 0, y += button_size.cy; } - winpos->cy = y + (x ? button_size.cy : 0); - break; + winpos->cy = y + (x ? button_size.cy : 0); + break; case WM_COMMAND: - SendMessage(GetParent(hWnd), msg, wParam, lParam); - break; + SendMessage(GetParent(hWnd), msg, wParam, lParam); + break; } - return(DefWindowProc(hWnd, msg, wParam, lParam)); + return DefWindowProc(hWnd, msg, wParam, lParam); } /*********************************************************************** * * WINHELP_TextWndProc */ - -static LRESULT CALLBACK WINHELP_TextWndProc (HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) +static LRESULT CALLBACK WINHELP_TextWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { - WINHELP_WINDOW *win; - WINHELP_LINE *line; - WINHELP_LINE_PART *part; - WINDOWPOS *winpos; - PAINTSTRUCT ps; - HDC hDc; - POINT mouse; - INT scroll_pos; - HWND hPopupWnd; - BOOL bExit; + WINHELP_WINDOW *win; + WINHELP_LINE *line; + WINHELP_LINE_PART *part; + WINDOWPOS *winpos; + PAINTSTRUCT ps; + HDC hDc; + POINT mouse; + INT scroll_pos; + HWND hPopupWnd; + BOOL bExit; - if (msg != WM_LBUTTONDOWN) - WINHELP_CheckPopup(msg); + if (msg != WM_LBUTTONDOWN) + WINHELP_CheckPopup(msg); - switch (msg) + switch (msg) { case WM_NCCREATE: - win = (WINHELP_WINDOW*) ((LPCREATESTRUCT) lParam)->lpCreateParams; - SetWindowLong(hWnd, 0, (LONG) win); - win->hTextWnd = hWnd; - if (!win->lpszName) Globals.hPopupWnd = win->hMainWnd = hWnd; - WINHELP_InitFonts(hWnd); - break; + win = (WINHELP_WINDOW*) ((LPCREATESTRUCT) lParam)->lpCreateParams; + SetWindowLong(hWnd, 0, (LONG) win); + win->hTextWnd = hWnd; + if (!win->lpszName) Globals.hPopupWnd = win->hMainWnd = hWnd; + WINHELP_InitFonts(hWnd); + break; case WM_CREATE: - win = (WINHELP_WINDOW*) GetWindowLong(hWnd, 0); + win = (WINHELP_WINDOW*) GetWindowLong(hWnd, 0); - /* Calculate vertical size and position of a popup window */ - if (!win->lpszName) + /* Calculate vertical size and position of a popup window */ + if (!win->lpszName) { - POINT origin; - RECT old_window_rect; - RECT old_client_rect; - SIZE old_window_size; - SIZE old_client_size; - SIZE new_client_size; - SIZE new_window_size; + POINT origin; + RECT old_window_rect; + RECT old_client_rect; + SIZE old_window_size; + SIZE old_client_size; + SIZE new_client_size; + SIZE new_window_size; - GetWindowRect(hWnd, &old_window_rect); - origin.x = old_window_rect.left; - origin.y = old_window_rect.top; - old_window_size.cx = old_window_rect.right - old_window_rect.left; - old_window_size.cy = old_window_rect.bottom - old_window_rect.top; + GetWindowRect(hWnd, &old_window_rect); + origin.x = old_window_rect.left; + origin.y = old_window_rect.top; + old_window_size.cx = old_window_rect.right - old_window_rect.left; + old_window_size.cy = old_window_rect.bottom - old_window_rect.top; - GetClientRect(hWnd, &old_client_rect); - old_client_size.cx = old_client_rect.right - old_client_rect.left; - old_client_size.cy = old_client_rect.bottom - old_client_rect.top; + GetClientRect(hWnd, &old_client_rect); + old_client_size.cx = old_client_rect.right - old_client_rect.left; + old_client_size.cy = old_client_rect.bottom - old_client_rect.top; - new_client_size = old_client_size; - WINHELP_SplitLines(hWnd, &new_client_size); + new_client_size = old_client_size; + WINHELP_SplitLines(hWnd, &new_client_size); - if (origin.y + POPUP_YDISTANCE + new_client_size.cy <= GetSystemMetrics(SM_CYSCREEN)) - origin.y += POPUP_YDISTANCE; - else - origin.y -= POPUP_YDISTANCE + new_client_size.cy; + if (origin.y + POPUP_YDISTANCE + new_client_size.cy <= GetSystemMetrics(SM_CYSCREEN)) + origin.y += POPUP_YDISTANCE; + else + origin.y -= POPUP_YDISTANCE + new_client_size.cy; - new_window_size.cx = old_window_size.cx - old_client_size.cx + new_client_size.cx; - new_window_size.cy = old_window_size.cy - old_client_size.cy + new_client_size.cy; + new_window_size.cx = old_window_size.cx - old_client_size.cx + new_client_size.cx; + new_window_size.cy = old_window_size.cy - old_client_size.cy + new_client_size.cy; - win->hShadowWnd = - CreateWindow(SHADOW_WIN_CLASS_NAME, "", WS_POPUP | WS_VISIBLE, - origin.x + SHADOW_DX, origin.y + SHADOW_DY, - new_window_size.cx, new_window_size.cy, - 0, 0, Globals.hInstance, 0); + win->hShadowWnd = + CreateWindow(SHADOW_WIN_CLASS_NAME, "", WS_POPUP, + origin.x + SHADOW_DX, origin.y + SHADOW_DY, + new_window_size.cx, new_window_size.cy, + 0, 0, Globals.hInstance, 0); - SetWindowPos(hWnd, HWND_TOP, origin.x, origin.y, - new_window_size.cx, new_window_size.cy, - SWP_NOZORDER | SWP_NOACTIVATE); - ShowWindow(win->hShadowWnd, SW_NORMAL); + SetWindowPos(hWnd, HWND_TOP, origin.x, origin.y, + new_window_size.cx, new_window_size.cy, + 0); + SetWindowPos(win->hShadowWnd, hWnd, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE); + ShowWindow(win->hShadowWnd, SW_NORMAL); + SetActiveWindow(hWnd); } - break; + break; case WM_WINDOWPOSCHANGED: - winpos = (WINDOWPOS*) lParam; - if (!(winpos->flags & SWP_NOSIZE)) WINHELP_SetupText(hWnd); - break; + winpos = (WINDOWPOS*) lParam; + + if (!(winpos->flags & SWP_NOSIZE)) WINHELP_SetupText(hWnd); + break; case WM_VSCROLL: - { + { BOOL update = TRUE; RECT rect; INT Min, Max; @@ -569,353 +594,544 @@ static LRESULT CALLBACK WINHELP_TextWndProc (HWND hWnd, UINT msg, WPARAM wParam, GetClientRect(hWnd, &rect); switch (wParam & 0xffff) - { - case SB_THUMBTRACK: - case SB_THUMBPOSITION: CurPos = wParam >> 16; break; - case SB_TOP: CurPos = Min; break; - case SB_BOTTOM: CurPos = Max; break; - case SB_PAGEUP: CurPos -= (rect.bottom - rect.top) / 2; break; - case SB_PAGEDOWN: CurPos += (rect.bottom - rect.top) / 2; break; - case SB_LINEUP: CurPos -= GetSystemMetrics(SM_CXVSCROLL); break; - case SB_LINEDOWN: CurPos += GetSystemMetrics(SM_CXVSCROLL); break; - default: update = FALSE; - } + { + case SB_THUMBTRACK: + case SB_THUMBPOSITION: CurPos = wParam >> 16; break; + case SB_TOP: CurPos = Min; break; + case SB_BOTTOM: CurPos = Max; break; + case SB_PAGEUP: CurPos -= (rect.bottom - rect.top) / 2; break; + case SB_PAGEDOWN: CurPos += (rect.bottom - rect.top) / 2; break; + case SB_LINEUP: CurPos -= GetSystemMetrics(SM_CXVSCROLL); break; + case SB_LINEDOWN: CurPos += GetSystemMetrics(SM_CXVSCROLL); break; + default: update = FALSE; + } if (update) - { + { INT dy = GetScrollPos(hWnd, SB_VERT) - CurPos; SetScrollPos(hWnd, SB_VERT, CurPos, TRUE); ScrollWindow(hWnd, 0, dy, NULL, NULL); UpdateWindow(hWnd); - } - } - break; + } + } + break; case WM_PAINT: - hDc = BeginPaint (hWnd, &ps); - win = (WINHELP_WINDOW*) GetWindowLong(hWnd, 0); - scroll_pos = GetScrollPos(hWnd, SB_VERT); + hDc = BeginPaint(hWnd, &ps); + win = (WINHELP_WINDOW*) GetWindowLong(hWnd, 0); + scroll_pos = GetScrollPos(hWnd, SB_VERT); - for (line = win->first_line; line; line = line->next) - for (part = &line->first_part; part; part = part->next) - { - SelectObject(hDc, part->hFont); - SetTextColor(hDc, part->color); - TextOut(hDc, part->rect.left, part->rect.top - scroll_pos, - (LPSTR) part->lpsText, part->wTextLen); - } + for (line = win->first_line; line; line = line->next) + { + for (part = &line->first_part; part; part = part->next) + { + switch (part->cookie) + { + case hlp_line_part_text: + SelectObject(hDc, part->u.text.hFont); + SetTextColor(hDc, part->u.text.color); + TextOut(hDc, part->rect.left, part->rect.top - scroll_pos, + part->u.text.lpsText, part->u.text.wTextLen); + if (part->u.text.wUnderline) + { + HPEN hPen; - EndPaint (hWnd, &ps); - break; + switch (part->u.text.wUnderline) + { + case 1: /* simple */ + case 2: /* double */ + hPen = CreatePen(PS_SOLID, 1, part->u.text.color); + break; + case 3: /* dotted */ + hPen = CreatePen(PS_DOT, 1, part->u.text.color); + break; + default: + WINE_FIXME("Unknow underline type\n"); + continue; + } + + SelectObject(hDc, hPen); + MoveToEx(hDc, part->rect.left, part->rect.bottom - scroll_pos - 1, NULL); + LineTo(hDc, part->rect.right, part->rect.bottom - scroll_pos - 1); + if (part->u.text.wUnderline == 2) + { + MoveToEx(hDc, part->rect.left, part->rect.bottom - scroll_pos + 1, NULL); + LineTo(hDc, part->rect.right, part->rect.bottom - scroll_pos + 1); + } + DeleteObject(hPen); + } + break; + case hlp_line_part_image: + { + HDC hMemDC; + + hMemDC = CreateCompatibleDC(hDc); + SelectObject(hMemDC, part->u.image.hBitmap); + BitBlt(hDc, part->rect.left, part->rect.top - scroll_pos, + part->rect.right - part->rect.left, part->rect.bottom - part->rect.top, + hMemDC, 0, 0, SRCCOPY); + DeleteDC(hMemDC); + } + break; + } + } + } + + EndPaint(hWnd, &ps); + break; case WM_MOUSEMOVE: - win = (WINHELP_WINDOW*) GetWindowLong(hWnd, 0); + win = (WINHELP_WINDOW*) GetWindowLong(hWnd, 0); - if(WINHELP_IsOverLink(hWnd, wParam, lParam)) - SetCursor(win->hHandCur); /* set to hand pointer cursor to indicate a link */ - else - SetCursor(win->hArrowCur); /* set to hand pointer cursor to indicate a link */ + if (WINHELP_IsOverLink(hWnd, wParam, lParam)) + SetCursor(win->hHandCur); /* set to hand pointer cursor to indicate a link */ + else + SetCursor(win->hArrowCur); /* set to hand pointer cursor to indicate a link */ - break; + break; case WM_LBUTTONDOWN: - win = (WINHELP_WINDOW*) GetWindowLong(hWnd, 0); + win = (WINHELP_WINDOW*) GetWindowLong(hWnd, 0); - hPopupWnd = Globals.hPopupWnd; - Globals.hPopupWnd = 0; + hPopupWnd = Globals.hPopupWnd; + Globals.hPopupWnd = 0; - part = WINHELP_IsOverLink(hWnd, wParam, lParam); - if(part) - { - mouse.x = LOWORD(lParam); - mouse.y = HIWORD(lParam); + part = WINHELP_IsOverLink(hWnd, wParam, lParam); + if (part) + { + mouse.x = LOWORD(lParam); + mouse.y = HIWORD(lParam); - WINHELP_CreateHelpWindow(part->link.lpszPath, part->link.lHash, NULL, - part->link.bPopup, hWnd, &mouse, SW_NORMAL); - } + WINHELP_CreateHelpWindowByHash(part->link.lpszPath, part->link.lHash, NULL, + part->link.bPopup, hWnd, &mouse, SW_NORMAL); + } - if (hPopupWnd) - DestroyWindow(hPopupWnd); - break; + if (hPopupWnd) + DestroyWindow(hPopupWnd); + break; case WM_NCDESTROY: - 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")); - WINHELP_DeleteWindow(win); + WINHELP_DeleteWindow(win); - if (bExit) MACRO_Exit(); + if (bExit) MACRO_Exit(); - if (!Globals.win_list) - PostQuitMessage (0); - break; + if (!Globals.win_list) + PostQuitMessage(0); + break; } - return DefWindowProc (hWnd, msg, wParam, lParam); + return DefWindowProc(hWnd, msg, wParam, lParam); } /*********************************************************************** * * SetupText */ - -static VOID WINHELP_SetupText(HWND hWnd) +static void WINHELP_SetupText(HWND hWnd) { - HDC hDc = GetDC(hWnd); - RECT rect; - SIZE newsize; + HDC hDc = GetDC(hWnd); + RECT rect; + SIZE newsize; - ShowScrollBar(hWnd, SB_VERT, FALSE); - if (!WINHELP_SplitLines(hWnd, NULL)) + ShowScrollBar(hWnd, SB_VERT, FALSE); + if (!WINHELP_SplitLines(hWnd, NULL)) { - ShowScrollBar(hWnd, SB_VERT, TRUE); - GetClientRect(hWnd, &rect); + ShowScrollBar(hWnd, SB_VERT, TRUE); + GetClientRect(hWnd, &rect); - WINHELP_SplitLines(hWnd, &newsize); - SetScrollRange(hWnd, SB_VERT, 0, rect.top + newsize.cy - rect.bottom, TRUE); + WINHELP_SplitLines(hWnd, &newsize); + SetScrollRange(hWnd, SB_VERT, 0, rect.top + newsize.cy - rect.bottom, TRUE); } - else SetScrollPos(hWnd, SB_VERT, 0, FALSE); + else SetScrollPos(hWnd, SB_VERT, 0, FALSE); - ReleaseDC(hWnd, hDc); -} - -/*********************************************************************** - * - * WINHELP_SplitLines - */ - -static BOOL WINHELP_SplitLines(HWND hWnd, LPSIZE newsize) -{ - WINHELP_WINDOW *win = (WINHELP_WINDOW*) GetWindowLong(hWnd, 0); - HLPFILE_PARAGRAPH *p; - WINHELP_LINE **line = &win->first_line; - WINHELP_LINE_PART **part = 0; - INT line_ascent = 0; - SIZE space; - RECT rect; - HDC hDc; - - if (newsize) newsize->cx = newsize->cy = 0; - - if (!win->page) return TRUE; - - WINHELP_DeleteLines(win); - - GetClientRect(hWnd, &rect); - - rect.top += INTERNAL_BORDER_WIDTH; - rect.left += INTERNAL_BORDER_WIDTH; - rect.right -= INTERNAL_BORDER_WIDTH; - rect.bottom -= INTERNAL_BORDER_WIDTH; - - - space.cy = rect.top; - space.cx = rect.left; - - hDc = GetDC(hWnd); - - for (p = win->page->first_paragraph; p; p = p->next) - { - TEXTMETRIC tm; - SIZE textsize = {0, 0}; - LPCSTR text = p->lpszText; - UINT len = strlen(text); - UINT indent = 0; - - UINT wFont = (p->wFont < win->fonts_len) ? p->wFont : 0; - BOOL bUnderline = p->link && !p->link->bPopup; - HFONT hFont = win->fonts[wFont][bUnderline ? 1 : 0]; - - COLORREF color = RGB(0, 0, 0); - if (p->link) color = RGB(0, 0x80, 0); - if (p->bDebug) color = RGB(0xff, 0, 0); - - SelectObject(hDc, hFont); - - GetTextMetrics (hDc, &tm); - - if (p->wIndent) - { - indent = p->wIndent * 5 * tm.tmAveCharWidth; - if (!part) - space.cx = rect.left + indent - 2 * tm.tmAveCharWidth; - } - - if (p->wVSpace) - { - part = 0; - space.cx = rect.left + indent; - space.cy += (p->wVSpace - 1) * tm.tmHeight; - } - - if (p->wHSpace) - { - space.cx += p->wHSpace * 2 * tm.tmAveCharWidth; - } - - while (len) - { - INT free_width = rect.right - (part ? (*line)->rect.right : rect.left) - space.cx; - UINT low = 0, curr = len, high = len, textlen = 0; - - if (free_width > 0) - { - while (1) - { - GetTextExtentPoint(hDc, text, curr, &textsize); - - if (textsize.cx <= free_width) low = curr; - else high = curr; - - if (high <= low + 1) break; - - if (textsize.cx) curr = (curr * free_width) / textsize.cx; - if (curr <= low) curr = low + 1; - else if (curr >= high) curr = high - 1; - } - textlen = low; - while (textlen && text[textlen] && text[textlen] != ' ') textlen--; - } - if (!part && !textlen) textlen = max(low, 1); - - if (free_width <= 0 || !textlen) - { - part = 0; - space.cx = rect.left + indent; - space.cx = min(space.cx, rect.right - rect.left - 1); - continue; - } - - if (!WINHELP_AppendText(&line, &part, &space, &textsize, - &line_ascent, tm.tmAscent, - text, textlen, hFont, color, p->link) || - (!newsize && (*line)->rect.bottom > rect.bottom)) - { - ReleaseDC(hWnd, hDc); - return FALSE; - } - - if (newsize) - newsize->cx = max(newsize->cx, (*line)->rect.right + INTERNAL_BORDER_WIDTH); - - len -= textlen; - text += textlen; - if (text[0] == ' ') text++, len--; - } - } - - if (newsize) - newsize->cy = (*line)->rect.bottom + INTERNAL_BORDER_WIDTH; - - ReleaseDC(hWnd, hDc); - return TRUE; + ReleaseDC(hWnd, hDc); } /*********************************************************************** * * WINHELP_AppendText */ - static BOOL WINHELP_AppendText(WINHELP_LINE ***linep, WINHELP_LINE_PART ***partp, LPSIZE space, LPSIZE textsize, INT *line_ascent, INT ascent, LPCSTR text, UINT textlen, - HFONT font, COLORREF color, HLPFILE_LINK *link) + HFONT font, COLORREF color, HLPFILE_LINK *link, + unsigned underline) { - HGLOBAL handle; - WINHELP_LINE *line; - WINHELP_LINE_PART *part; - LPSTR ptr; + WINHELP_LINE *line; + WINHELP_LINE_PART *part; + LPSTR ptr; - if (!*partp) /* New line */ + if (!*partp) /* New line */ { - *line_ascent = ascent; + *line_ascent = ascent; - handle = GlobalAlloc(GMEM_FIXED, sizeof(WINHELP_LINE) + textlen + - (link ? lstrlen(link->lpszPath) + 1 : 0)); - if (!handle) return FALSE; - line = GlobalLock(handle); - line->next = 0; - part = &line->first_part; - ptr = GlobalLock(handle); - ptr += sizeof(WINHELP_LINE); + line = HeapAlloc(GetProcessHeap(), 0, + sizeof(WINHELP_LINE) + textlen + (link ? lstrlen(link->lpszPath) + 1 : 0)); + if (!line) return FALSE; - line->rect.top = (**linep ? (**linep)->rect.bottom : 0) + space->cy; - line->rect.bottom = line->rect.top; - line->rect.left = space->cx; - line->rect.right = space->cx; + line->next = 0; + part = &line->first_part; + ptr = (char*)line + sizeof(WINHELP_LINE); - if (**linep) *linep = &(**linep)->next; - **linep = line; - space->cy = 0; + line->rect.top = (**linep ? (**linep)->rect.bottom : 0) + space->cy; + line->rect.bottom = line->rect.top; + line->rect.left = space->cx; + line->rect.right = space->cx; + + if (**linep) *linep = &(**linep)->next; + **linep = line; + space->cy = 0; } - else /* Same line */ + else /* Same line */ { - line = **linep; + line = **linep; - if (*line_ascent < ascent) + if (*line_ascent < ascent) { - WINHELP_LINE_PART *p; - for (p = &line->first_part; p; p = p->next) + WINHELP_LINE_PART *p; + for (p = &line->first_part; p; p = p->next) { - p->rect.top += ascent - *line_ascent; - p->rect.bottom += ascent - *line_ascent; + p->rect.top += ascent - *line_ascent; + p->rect.bottom += ascent - *line_ascent; } - line->rect.bottom += ascent - *line_ascent; - *line_ascent = ascent; + line->rect.bottom += ascent - *line_ascent; + *line_ascent = ascent; } - handle = GlobalAlloc(GMEM_FIXED, sizeof(WINHELP_LINE_PART) + textlen + - (link ? lstrlen(link->lpszPath) + 1 : 0)); - if (!handle) return FALSE; - part = GlobalLock(handle); - **partp = part; - ptr = GlobalLock(handle); - ptr += sizeof(WINHELP_LINE_PART); + part = HeapAlloc(GetProcessHeap(), 0, + sizeof(WINHELP_LINE_PART) + textlen + + (link ? lstrlen(link->lpszPath) + 1 : 0)); + if (!part) return FALSE; + **partp = part; + ptr = (char*)part + sizeof(WINHELP_LINE_PART); } - memcpy(ptr, text, textlen); - part->rect.left = line->rect.right + (*partp ? space->cx : 0); - part->rect.right = part->rect.left + textsize->cx; - line->rect.right = part->rect.right; - part->rect.top = - ((*partp) ? line->rect.top : line->rect.bottom) + *line_ascent - ascent; - part->rect.bottom = part->rect.top + textsize->cy; - line->rect.bottom = max(line->rect.bottom, part->rect.bottom); - part->hSelf = handle; - part->lpsText = ptr; - part->wTextLen = textlen; - part->hFont = font; - part->color = color; - if (link) + memcpy(ptr, text, textlen); + part->cookie = hlp_line_part_text; + part->rect.left = line->rect.right + (*partp ? space->cx : 0); + part->rect.right = part->rect.left + textsize->cx; + line->rect.right = part->rect.right; + part->rect.top = + ((*partp) ? line->rect.top : line->rect.bottom) + *line_ascent - ascent; + part->rect.bottom = part->rect.top + textsize->cy; + line->rect.bottom = max(line->rect.bottom, part->rect.bottom); + part->u.text.lpsText = ptr; + part->u.text.wTextLen = textlen; + part->u.text.hFont = font; + part->u.text.color = color; + part->u.text.wUnderline = underline; + + WINE_TRACE("Appended text '%*.*s'[%d] @ (%d,%d-%d,%d)\n", + part->u.text.wTextLen, + part->u.text.wTextLen, + part->u.text.lpsText, + part->u.text.wTextLen, + part->rect.left, part->rect.top, part->rect.right, part->rect.bottom); + if (link) { - strcpy(ptr + textlen, link->lpszPath); - part->link.lpszPath = ptr + textlen; - part->link.lHash = link->lHash; - part->link.bPopup = link->bPopup; + strcpy(ptr + textlen, link->lpszPath); + part->link.lpszPath = ptr + textlen; + part->link.lHash = link->lHash; + part->link.bPopup = link->bPopup; } - else part->link.lpszPath = 0; + else part->link.lpszPath = 0; - part->next = 0; - *partp = &part->next; + part->next = 0; + *partp = &part->next; - space->cx = 0; + space->cx = 0; - return TRUE; + return TRUE; +} + +/*********************************************************************** + * + * WINHELP_AppendBitmap + */ +static BOOL WINHELP_AppendBitmap(WINHELP_LINE ***linep, WINHELP_LINE_PART ***partp, + LPSIZE space, + HBITMAP hBmp, LPSIZE bmpSize, + HLPFILE_LINK *link, unsigned pos) +{ + WINHELP_LINE *line; + WINHELP_LINE_PART *part; + LPSTR ptr; + + if (!*partp || pos == 1) /* New line */ + { + line = HeapAlloc(GetProcessHeap(), 0, + sizeof(WINHELP_LINE) + (link ? lstrlen(link->lpszPath) + 1 : 0)); + if (!line) return FALSE; + + line->next = NULL; + part = &line->first_part; + + line->rect.top = (**linep ? (**linep)->rect.bottom : 0) + space->cy; + line->rect.bottom = line->rect.top; + line->rect.left = space->cx; + line->rect.right = space->cx; + + if (**linep) *linep = &(**linep)->next; + **linep = line; + space->cy = 0; + ptr = (char*)line + sizeof(WINHELP_LINE); + } + else /* Same line */ + { + if (pos == 2) WINE_FIXME("Left alignment not handled\n"); + line = **linep; + + part = HeapAlloc(GetProcessHeap(), 0, + sizeof(WINHELP_LINE_PART) + + (link ? lstrlen(link->lpszPath) + 1 : 0)); + if (!part) return FALSE; + **partp = part; + ptr = (char*)part + sizeof(WINHELP_LINE_PART); + } + + part->cookie = hlp_line_part_image; + part->rect.left = line->rect.right + (*partp ? space->cx : 0); + part->rect.right = part->rect.left + bmpSize->cx; + line->rect.right = part->rect.right; + part->rect.top = + ((*partp) ? line->rect.top : line->rect.bottom); + part->rect.bottom = part->rect.top + bmpSize->cy; + line->rect.bottom = max(line->rect.bottom, part->rect.bottom); + part->u.image.hBitmap = hBmp; + + WINE_TRACE("Appended bitmap '%d' @ (%d,%d-%d,%d)\n", + (unsigned)part->u.image.hBitmap, + part->rect.left, part->rect.top, part->rect.right, part->rect.bottom); + + if (link) + { + strcpy(ptr, link->lpszPath); + part->link.lpszPath = ptr; + part->link.lHash = link->lHash; + part->link.bPopup = link->bPopup; + } + else part->link.lpszPath = 0; + + part->next = NULL; + *partp = &part->next; + + space->cx = 0; + + return TRUE; +} + + +/*********************************************************************** + * + * WINHELP_SplitLines + */ +static BOOL WINHELP_SplitLines(HWND hWnd, LPSIZE newsize) +{ + WINHELP_WINDOW *win = (WINHELP_WINDOW*) GetWindowLong(hWnd, 0); + HLPFILE_PARAGRAPH *p; + WINHELP_LINE **line = &win->first_line; + WINHELP_LINE_PART **part = 0; + INT line_ascent = 0; + SIZE space; + RECT rect; + HDC hDc; + + if (newsize) newsize->cx = newsize->cy = 0; + + if (!win->page) return TRUE; + + WINHELP_DeleteLines(win); + + GetClientRect(hWnd, &rect); + + rect.top += INTERNAL_BORDER_WIDTH; + rect.left += INTERNAL_BORDER_WIDTH; + rect.right -= INTERNAL_BORDER_WIDTH; + rect.bottom -= INTERNAL_BORDER_WIDTH; + + space.cy = rect.top; + space.cx = rect.left; + + hDc = GetDC(hWnd); + + for (p = win->page->first_paragraph; p; p = p->next) + { + switch (p->cookie) + { + case para_normal_text: + case para_debug_text: + { + TEXTMETRIC tm; + SIZE textsize = {0, 0}; + LPCSTR text = p->u.text.lpszText; + UINT indent = 0; + UINT len = strlen(text); + unsigned underline = 0; + + HFONT hFont = 0; + COLORREF color = RGB(0, 0, 0); + + if (p->u.text.wFont < win->page->file->numFonts) + { + HLPFILE* hlpfile = win->page->file; + + if (!hlpfile->fonts[p->u.text.wFont].hFont) + hlpfile->fonts[p->u.text.wFont].hFont = CreateFontIndirect(&hlpfile->fonts[p->u.text.wFont].LogFont); + hFont = hlpfile->fonts[p->u.text.wFont].hFont; + color = hlpfile->fonts[p->u.text.wFont].color; + } + else + { + UINT wFont = (p->u.text.wFont < win->fonts_len) ? p->u.text.wFont : 0; + + hFont = win->fonts[wFont]; + } + + if (p->link) + { + underline = (p->link->bPopup) ? 3 : 1; + color = RGB(0, 0x80, 0); + } + if (p->cookie == para_debug_text) color = RGB(0xff, 0, 0); + + SelectObject(hDc, hFont); + + GetTextMetrics(hDc, &tm); + + if (p->u.text.wIndent) + { + indent = p->u.text.wIndent * 5 * tm.tmAveCharWidth; + if (!part) + space.cx = rect.left + indent - 2 * tm.tmAveCharWidth; + } + + if (p->u.text.wVSpace) + { + part = 0; + space.cx = rect.left + indent; + space.cy += (p->u.text.wVSpace - 1) * tm.tmHeight; + } + + if (p->u.text.wHSpace) + { + space.cx += p->u.text.wHSpace * 2 * tm.tmAveCharWidth; + } + + WINE_TRACE("splitting text %s\n", text); + + while (len) + { + INT free_width = rect.right - (part ? (*line)->rect.right : rect.left) - space.cx; + UINT low = 0, curr = len, high = len, textlen = 0; + + if (free_width > 0) + { + while (1) + { + GetTextExtentPoint(hDc, text, curr, &textsize); + + if (textsize.cx <= free_width) low = curr; + else high = curr; + + if (high <= low + 1) break; + + if (textsize.cx) curr = (curr * free_width) / textsize.cx; + if (curr <= low) curr = low + 1; + else if (curr >= high) curr = high - 1; + } + textlen = low; + while (textlen && text[textlen] && text[textlen] != ' ') textlen--; + } + if (!part && !textlen) textlen = max(low, 1); + + if (free_width <= 0 || !textlen) + { + part = 0; + space.cx = rect.left + indent; + space.cx = min(space.cx, rect.right - rect.left - 1); + continue; + } + + WINE_TRACE("\t => %d %*s\n", textlen, textlen, text); + + if (!WINHELP_AppendText(&line, &part, &space, &textsize, + &line_ascent, tm.tmAscent, + text, textlen, hFont, color, p->link, underline) || + (!newsize && (*line)->rect.bottom > rect.bottom)) + { + ReleaseDC(hWnd, hDc); + return FALSE; + } + + if (newsize) + newsize->cx = max(newsize->cx, (*line)->rect.right + INTERNAL_BORDER_WIDTH); + + len -= textlen; + text += textlen; + if (text[0] == ' ') text++, len--; + } + } + break; + case para_image: + { + DIBSECTION dibs; + SIZE bmpSize; + INT free_width; + + if (p->u.image.pos & 0x8000) + { + space.cx = rect.left; + space.cy += (*line)->rect.bottom - (*line)->rect.top; + part = 0; + } + + GetObject(p->u.image.hBitmap, sizeof(dibs), &dibs); + bmpSize.cx = dibs.dsBm.bmWidth; + bmpSize.cy = dibs.dsBm.bmHeight; + + free_width = rect.right - (part ? (*line)->rect.right : rect.left) - space.cx; + if (free_width <= 0) + { + part = NULL; + space.cx = rect.left; + space.cx = min(space.cx, rect.right - rect.left - 1); + } + if (!WINHELP_AppendBitmap(&line, &part, &space, + p->u.image.hBitmap, &bmpSize, + p->link, p->u.image.pos) || + (!newsize && (*line)->rect.bottom > rect.bottom)) + { + return FALSE; + } + } + break; + } + + } + + if (newsize) + newsize->cy = (*line)->rect.bottom + INTERNAL_BORDER_WIDTH; + + ReleaseDC(hWnd, hDc); + return TRUE; } /*********************************************************************** * * WINHELP_CheckPopup */ - -static VOID WINHELP_CheckPopup(UINT msg) +static void WINHELP_CheckPopup(UINT msg) { - if (!Globals.hPopupWnd) return; + if (!Globals.hPopupWnd) return; - switch (msg) + switch (msg) { case WM_COMMAND: case WM_LBUTTONDOWN: @@ -924,8 +1140,8 @@ static VOID WINHELP_CheckPopup(UINT msg) case WM_NCLBUTTONDOWN: case WM_NCMBUTTONDOWN: case WM_NCRBUTTONDOWN: - DestroyWindow(Globals.hPopupWnd); - Globals.hPopupWnd = 0; + DestroyWindow(Globals.hPopupWnd); + Globals.hPopupWnd = 0; } } @@ -933,83 +1149,76 @@ static VOID WINHELP_CheckPopup(UINT msg) * * WINHELP_DeleteLines */ - -static VOID WINHELP_DeleteLines(WINHELP_WINDOW *win) +static void WINHELP_DeleteLines(WINHELP_WINDOW *win) { - WINHELP_LINE *line, *next_line; - WINHELP_LINE_PART *part, *next_part; - for(line = win->first_line; line; line = next_line) + WINHELP_LINE *line, *next_line; + WINHELP_LINE_PART *part, *next_part; + for(line = win->first_line; line; line = next_line) { - next_line = line->next; - for(part = &line->first_part; part; part = next_part) + next_line = line->next; + for (part = &line->first_part; part; part = next_part) { - next_part = part->next; - GlobalFree(part->hSelf); + next_part = part->next; + HeapFree(GetProcessHeap(), 0, part); } } - win->first_line = 0; + win->first_line = 0; } /*********************************************************************** * * WINHELP_DeleteWindow */ - -static VOID WINHELP_DeleteWindow(WINHELP_WINDOW *win) +static void WINHELP_DeleteWindow(WINHELP_WINDOW *win) { - WINHELP_WINDOW **w; + WINHELP_WINDOW **w; - for (w = &Globals.win_list; *w; w = &(*w)->next) - if (*w == win) - { - *w = win->next; - break; - } + for (w = &Globals.win_list; *w; w = &(*w)->next) + if (*w == win) + { + *w = win->next; + break; + } - if (win->hShadowWnd) DestroyWindow(win->hShadowWnd); - HLPFILE_FreeHlpFilePage(win->page); - WINHELP_DeleteLines(win); - GlobalFree(win->hSelf); + if (win->hShadowWnd) DestroyWindow(win->hShadowWnd); + HLPFILE_FreeHlpFilePage(win->page); + WINHELP_DeleteLines(win); + HeapFree(GetProcessHeap(), 0, win); } /*********************************************************************** * * WINHELP_InitFonts */ - -static VOID WINHELP_InitFonts(HWND hWnd) +static void WINHELP_InitFonts(HWND hWnd) { - WINHELP_WINDOW *win = (WINHELP_WINDOW*) GetWindowLong(hWnd, 0); - LOGFONT logfontlist[] = { - {-10, 0, 0, 0, 400, 0, 0, 0, 0, 0, 0, 0, 32, "Helv"}, - {-12, 0, 0, 0, 700, 0, 0, 0, 0, 0, 0, 0, 32, "Helv"}, - {-12, 0, 0, 0, 700, 0, 0, 0, 0, 0, 0, 0, 32, "Helv"}, - {-12, 0, 0, 0, 400, 0, 0, 0, 0, 0, 0, 0, 32, "Helv"}, - {-12, 0, 0, 0, 700, 0, 0, 0, 0, 0, 0, 0, 32, "Helv"}, - {-10, 0, 0, 0, 700, 0, 0, 0, 0, 0, 0, 0, 32, "Helv"}, - { -8, 0, 0, 0, 400, 0, 0, 0, 0, 0, 0, 0, 32, "Helv"}}; + WINHELP_WINDOW *win = (WINHELP_WINDOW*) GetWindowLong(hWnd, 0); + LOGFONT logfontlist[] = { + {-10, 0, 0, 0, 400, 0, 0, 0, 0, 0, 0, 0, 32, "Helv"}, + {-12, 0, 0, 0, 700, 0, 0, 0, 0, 0, 0, 0, 32, "Helv"}, + {-12, 0, 0, 0, 700, 0, 0, 0, 0, 0, 0, 0, 32, "Helv"}, + {-12, 0, 0, 0, 400, 0, 0, 0, 0, 0, 0, 0, 32, "Helv"}, + {-12, 0, 0, 0, 700, 0, 0, 0, 0, 0, 0, 0, 32, "Helv"}, + {-10, 0, 0, 0, 700, 0, 0, 0, 0, 0, 0, 0, 32, "Helv"}, + { -8, 0, 0, 0, 400, 0, 0, 0, 0, 0, 0, 0, 32, "Helv"}}; #define FONTS_LEN (sizeof(logfontlist)/sizeof(*logfontlist)) - static HFONT fonts[FONTS_LEN][2]; - static BOOL init = 0; + static HFONT fonts[FONTS_LEN]; + static BOOL init = 0; - win->fonts_len = FONTS_LEN; - win->fonts = fonts; + win->fonts_len = FONTS_LEN; + win->fonts = fonts; - if (!init) + if (!init) { - INT i; + INT i; - for(i = 0; i < FONTS_LEN; i++) + for(i = 0; i < FONTS_LEN; i++) { - LOGFONT logfont = logfontlist[i]; - - fonts[i][0] = CreateFontIndirect(&logfont); - logfont.lfUnderline = 1; - fonts[i][1] = CreateFontIndirect(&logfont); + fonts[i] = CreateFontIndirect(&logfontlist[i]); } - init = 1; + init = 1; } } @@ -1017,64 +1226,63 @@ static VOID WINHELP_InitFonts(HWND hWnd) * * WINHELP_MessageBoxIDS */ - INT WINHELP_MessageBoxIDS(UINT ids_text, UINT ids_title, WORD type) { - CHAR text[MAX_STRING_LEN]; - CHAR title[MAX_STRING_LEN]; + CHAR text[MAX_STRING_LEN]; + CHAR title[MAX_STRING_LEN]; - LoadString(Globals.hInstance, ids_text, text, sizeof(text)); - LoadString(Globals.hInstance, ids_title, title, sizeof(title)); + LoadString(Globals.hInstance, ids_text, text, sizeof(text)); + LoadString(Globals.hInstance, ids_title, title, sizeof(title)); - return(MessageBox(0, text, title, type)); + return MessageBox(0, text, title, type); } /*********************************************************************** * * MAIN_MessageBoxIDS_s */ - INT WINHELP_MessageBoxIDS_s(UINT ids_text, LPCSTR str, UINT ids_title, WORD type) { - CHAR text[MAX_STRING_LEN]; - CHAR title[MAX_STRING_LEN]; - CHAR newtext[MAX_STRING_LEN + MAX_PATHNAME_LEN]; + CHAR text[MAX_STRING_LEN]; + CHAR title[MAX_STRING_LEN]; + CHAR newtext[MAX_STRING_LEN + MAX_PATHNAME_LEN]; - LoadString(Globals.hInstance, ids_text, text, sizeof(text)); - LoadString(Globals.hInstance, ids_title, title, sizeof(title)); - wsprintf(newtext, text, str); + LoadString(Globals.hInstance, ids_text, text, sizeof(text)); + LoadString(Globals.hInstance, ids_title, title, sizeof(title)); + wsprintf(newtext, text, str); - return(MessageBox(0, newtext, title, type)); + return MessageBox(0, newtext, title, type); } +/****************************************************************** + * WINHELP_IsOverLink + * + * + */ WINHELP_LINE_PART* WINHELP_IsOverLink(HWND hWnd, WPARAM wParam, LPARAM lParam) { - WINHELP_WINDOW* win = (WINHELP_WINDOW*) GetWindowLong(hWnd, 0); - POINT mouse; - WINHELP_LINE *line; - WINHELP_LINE_PART *part; - int scroll_pos = GetScrollPos(hWnd, SB_VERT); + WINHELP_WINDOW* win = (WINHELP_WINDOW*) GetWindowLong(hWnd, 0); + POINT mouse; + WINHELP_LINE *line; + WINHELP_LINE_PART *part; + int scroll_pos = GetScrollPos(hWnd, SB_VERT); - mouse.x = LOWORD(lParam); - mouse.y = HIWORD(lParam); - for (line = win->first_line; line; line = line->next) - { - for (part = &line->first_part; part; part = part->next) + mouse.x = LOWORD(lParam); + mouse.y = HIWORD(lParam); + for (line = win->first_line; line; line = line->next) { - if (part->link.lpszPath && - part->rect.left <= mouse.x && - part->rect.right >= mouse.x && - part->rect.top <= mouse.y + scroll_pos && - part->rect.bottom >= mouse.y + scroll_pos) - { - return part; - } + for (part = &line->first_part; part; part = part->next) + { + if (part->link.lpszPath && + part->rect.left <= mouse.x && + part->rect.right >= mouse.x && + part->rect.top <= mouse.y + scroll_pos && + part->rect.bottom >= mouse.y + scroll_pos) + { + return part; + } + } } - } - return NULL; + return NULL; } - -/* Local Variables: */ -/* c-file-style: "GNU" */ -/* End: */ diff --git a/programs/winhelp/winhelp.h b/programs/winhelp/winhelp.h index 0c6b2ab0229..e6cd58df63c 100644 --- a/programs/winhelp/winhelp.h +++ b/programs/winhelp/winhelp.h @@ -1,9 +1,10 @@ /* * Help Viewer * - * Copyright 1996 Ulrich Schmid - * Copyright 2002 Sylvain Petreolle <spetreolle@yahoo.fr> - + * Copyright 1996 Ulrich Schmid + * Copyright 2002 Sylvain Petreolle <spetreolle@yahoo.fr> + * 2002 Eric Pouech + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either @@ -19,16 +20,16 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#define MAX_LANGUAGE_NUMBER 255 -#define MAX_PATHNAME_LEN 1024 -#define MAX_STRING_LEN 255 +#define MAX_LANGUAGE_NUMBER 255 +#define MAX_PATHNAME_LEN 1024 +#define MAX_STRING_LEN 255 -#define INTERNAL_BORDER_WIDTH 5 -#define POPUP_YDISTANCE 20 -#define SHADOW_DX 20 -#define SHADOW_DY 20 -#define BUTTON_CX 6 -#define BUTTON_CY 6 +#define INTERNAL_BORDER_WIDTH 5 +#define POPUP_YDISTANCE 20 +#define SHADOW_DX 10 +#define SHADOW_DY 10 +#define BUTTON_CX 6 +#define BUTTON_CY 6 #ifndef RC_INVOKED @@ -38,82 +39,92 @@ typedef struct tagHelpLinePart { - RECT rect; - LPCSTR lpsText; - UINT wTextLen; - HFONT hFont; - COLORREF color; + RECT rect; + enum {hlp_line_part_text, hlp_line_part_image} cookie; + union + { + struct + { + LPCSTR lpsText; + HFONT hFont; + COLORREF color; + WORD wTextLen; + WORD wUnderline; /* 0 None, 1 simple, 2 double, 3 dotted */ + } text; + struct + { + HBITMAP hBitmap; + } image; + } u; - struct - { - LPCSTR lpszPath; - LONG lHash; - BOOL bPopup; - } link; + struct + { + LPCSTR lpszPath; + LONG lHash; + BOOL bPopup; + } link; - HGLOBAL hSelf; - struct tagHelpLinePart *next; + struct tagHelpLinePart *next; } WINHELP_LINE_PART; typedef struct tagHelpLine { - RECT rect; - WINHELP_LINE_PART first_part; - struct tagHelpLine *next; + RECT rect; + WINHELP_LINE_PART first_part; + struct tagHelpLine* next; } WINHELP_LINE; typedef struct tagHelpButton { - HWND hWnd; + HWND hWnd; - LPCSTR lpszID; - LPCSTR lpszName; - LPCSTR lpszMacro; + LPCSTR lpszID; + LPCSTR lpszName; + LPCSTR lpszMacro; - WPARAM wParam; + WPARAM wParam; - RECT rect; + RECT rect; - HGLOBAL hSelf; - struct tagHelpButton *next; + struct tagHelpButton*next; } WINHELP_BUTTON; typedef struct tagWinHelp { - LPCSTR lpszName; + LPCSTR lpszName; - WINHELP_BUTTON *first_button; - HLPFILE_PAGE *page; - WINHELP_LINE *first_line; + WINHELP_BUTTON* first_button; + HLPFILE_PAGE* page; + WINHELP_LINE* first_line; - HWND hMainWnd; - HWND hButtonBoxWnd; - HWND hTextWnd; - HWND hShadowWnd; + HWND hMainWnd; + HWND hButtonBoxWnd; + HWND hTextWnd; + HWND hShadowWnd; - HFONT (*fonts)[2]; - UINT fonts_len; + HFONT* fonts; + UINT fonts_len; - HCURSOR hArrowCur; - HCURSOR hHandCur; + HCURSOR hArrowCur; + HCURSOR hHandCur; - HGLOBAL hSelf; - struct tagWinHelp *next; + struct tagWinHelp* next; } WINHELP_WINDOW; typedef struct { - UINT wVersion; - HANDLE hInstance; - HWND hPopupWnd; - UINT wStringTableOffset; - WINHELP_WINDOW *active_win; - WINHELP_WINDOW *win_list; + UINT wVersion; + HANDLE hInstance; + HWND hPopupWnd; + UINT wStringTableOffset; + WINHELP_WINDOW* active_win; + WINHELP_WINDOW* win_list; } WINHELP_GLOBALS; extern WINHELP_GLOBALS Globals; -VOID WINHELP_CreateHelpWindow(LPCSTR, LONG, LPCSTR, BOOL, HWND, LPPOINT, INT); +BOOL WINHELP_CreateHelpWindowByHash(LPCSTR, LONG, LPCSTR, BOOL, HWND, LPPOINT, INT); +BOOL WINHELP_CreateHelpWindowByPage(HLPFILE_PAGE*, LPCSTR, BOOL, HWND, LPPOINT, INT); INT WINHELP_MessageBoxIDS(UINT, UINT, WORD); INT WINHELP_MessageBoxIDS_s(UINT, LPCSTR, UINT, WORD); @@ -128,7 +139,3 @@ extern CHAR STRING_DIALOG_TEST[]; /* Buttons */ #define WH_FIRST_BUTTON 500 - -/* Local Variables: */ -/* c-file-style: "GNU" */ -/* End: */