- Add winhelp based on Wine.
authorGed Murphy <gedmurphy@reactos.org>
Sat, 12 May 2007 10:14:45 +0000 (10:14 +0000)
committerGed Murphy <gedmurphy@reactos.org>
Sat, 12 May 2007 10:14:45 +0000 (10:14 +0000)
- Not fully complete and has some bugs.
- go to help -> help on help for a preview

svn path=/trunk/; revision=26719

38 files changed:
reactos/base/applications/applications.rbuild
reactos/base/applications/winhelp/Bg.rc [new file with mode: 0644]
reactos/base/applications/winhelp/Cs.rc [new file with mode: 0644]
reactos/base/applications/winhelp/Da.rc [new file with mode: 0644]
reactos/base/applications/winhelp/De.rc [new file with mode: 0644]
reactos/base/applications/winhelp/En.rc [new file with mode: 0644]
reactos/base/applications/winhelp/Eo.rc [new file with mode: 0644]
reactos/base/applications/winhelp/Es.rc [new file with mode: 0644]
reactos/base/applications/winhelp/Fi.rc [new file with mode: 0644]
reactos/base/applications/winhelp/Fr.rc [new file with mode: 0644]
reactos/base/applications/winhelp/Hu.rc [new file with mode: 0644]
reactos/base/applications/winhelp/It.rc [new file with mode: 0644]
reactos/base/applications/winhelp/Ko.rc [new file with mode: 0644]
reactos/base/applications/winhelp/Nl.rc [new file with mode: 0644]
reactos/base/applications/winhelp/No.rc [new file with mode: 0644]
reactos/base/applications/winhelp/Pl.rc [new file with mode: 0644]
reactos/base/applications/winhelp/Pt.rc [new file with mode: 0644]
reactos/base/applications/winhelp/Ru.rc [new file with mode: 0644]
reactos/base/applications/winhelp/Si.rc [new file with mode: 0644]
reactos/base/applications/winhelp/Sk.rc [new file with mode: 0644]
reactos/base/applications/winhelp/Sw.rc [new file with mode: 0644]
reactos/base/applications/winhelp/Tr.rc [new file with mode: 0644]
reactos/base/applications/winhelp/Va.rc [new file with mode: 0644]
reactos/base/applications/winhelp/Wa.rc [new file with mode: 0644]
reactos/base/applications/winhelp/Zh.rc [new file with mode: 0644]
reactos/base/applications/winhelp/callback.c [new file with mode: 0644]
reactos/base/applications/winhelp/hlpfile.c [new file with mode: 0644]
reactos/base/applications/winhelp/hlpfile.h [new file with mode: 0644]
reactos/base/applications/winhelp/lex.yy.c [new file with mode: 0644]
reactos/base/applications/winhelp/macro.c [new file with mode: 0644]
reactos/base/applications/winhelp/macro.h [new file with mode: 0644]
reactos/base/applications/winhelp/macro.lex.l [new file with mode: 0644]
reactos/base/applications/winhelp/rsrc.rc [new file with mode: 0644]
reactos/base/applications/winhelp/string.c [new file with mode: 0644]
reactos/base/applications/winhelp/winhelp.c [new file with mode: 0644]
reactos/base/applications/winhelp/winhelp.h [new file with mode: 0644]
reactos/base/applications/winhelp/winhelp.rbuild [new file with mode: 0644]
reactos/base/applications/winhelp/winhelp_res.h [new file with mode: 0644]

index 339db4b..ca1fe85 100644 (file)
@@ -55,6 +55,9 @@
 <directory name="taskmgr">
        <xi:include href="taskmgr/taskmgr.rbuild" />
 </directory>
+<directory name="winhelp">
+       <xi:include href="winhelp/winhelp.rbuild" />
+</directory>
 <directory name="wordpad">
        <xi:include href="wordpad/wordpad.rbuild" />
 </directory>
diff --git a/reactos/base/applications/winhelp/Bg.rc b/reactos/base/applications/winhelp/Bg.rc
new file mode 100644 (file)
index 0000000..d04a9d0
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * Help Viewer Bulgarian resource
+ *
+ * Copyright 2005 Milko Krachounov
+ *
+ * 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
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/* Menu */
+
+MAIN_MENU MENU LANGUAGE LANG_BULGARIAN, SUBLANG_DEFAULT
+{
+ POPUP "&Ôàéë" {
+  MENUITEM "&Îòâîðè", MNID_FILE_OPEN
+  MENUITEM SEPARATOR
+  MENUITEM "&Ïå÷àò", MNID_FILE_PRINT
+  MENUITEM "&Íàñòðîéêà íà ïðèíòåðà...", MNID_FILE_SETUP
+   MENUITEM SEPARATOR
+  MENUITEM "&Èçõîä", MNID_FILE_EXIT
+ }
+ POPUP "&Ðåäàêòèðàíå" {
+   MENUITEM "&Êîïèðàé...", MNID_EDIT_COPYDLG
+   MENUITEM SEPARATOR
+   MENUITEM "&Àíîòèðàé...", MNID_EDIT_ANNOTATE
+ }
+ POPUP "&Îòìåòêè" {
+   MENUITEM "&Çàäàé...", MNID_BKMK_DEFINE
+ }
+ POPUP "&Ïîìîù" {
+   MENUITEM "Ïîìîù &çà ïîìîùòà", MNID_HELP_HELPON
+   MENUITEM "Âèíàãè îò&ãîðå", MNID_HELP_HELPTOP
+   MENUITEM SEPARATOR
+   MENUITEM "&Èíôîðìàöèÿ...", MNID_HELP_ABOUT
+#ifdef WINELIB
+   MENUITEM "&Îòíîñíî WINE", MNID_HELP_WINE
+#endif
+ }
+}
+
+/* Strings */
+STRINGTABLE DISCARDABLE LANGUAGE LANG_BULGARIAN, SUBLANG_DEFAULT
+{
+STID_WINE_HELP,        "WINE Ïîìîù"
+STID_WHERROR,          "ÃÐÅØÊÀ"
+STID_WARNING,                  "ÏÐÅÄÓÏÐÅÆÄÅÍÈÅ"
+STID_INFO,             "Èíôîðìàöèÿ"
+STID_NOT_IMPLEMENTED,  "Íå å ðåàëèçèðàíî"
+STID_HLPFILE_ERROR_s,  "Ãðåøêà ïðè ÷åòåíå íà ïîìîùíèÿ ôàéë `%s'"
+STID_CONTENTS,                 "&Ñúäúðæàíèå"
+STID_SEARCH,           "&Òúðñè"
+STID_BACK,             "&Íàçàä"
+STID_HISTORY,          "&Èñòîðèÿ"
+STID_TOPICS,           "&Òåìè"
+STID_ALL_FILES,        "Âñè÷êè ôàéëîâå (*.*)"
+STID_HELP_FILES_HLP,   "Ïîìîùíè ôàéëîâå (*.hlp)"
+STID_FILE_NOT_FOUND_s  "Cannot find '%s'. Do you want to find this file yourself?"
+}
diff --git a/reactos/base/applications/winhelp/Cs.rc b/reactos/base/applications/winhelp/Cs.rc
new file mode 100644 (file)
index 0000000..06c2e17
--- /dev/null
@@ -0,0 +1,74 @@
+/* Hey, Emacs, open this file with -*- coding: cp1250 -*-
+ *
+ * Help Viewer Czech resources
+ *
+ * Copyright 1996 Ulrich Schmid
+ * Copyright 2002 Sylvain Petreolle
+ * Copyright 2004 David Kredba
+ *
+ * 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
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/* Czech strings in CP1250 */
+
+/* Menu */
+
+MAIN_MENU MENU LANGUAGE LANG_CZECH, SUBLANG_DEFAULT
+{
+ POPUP "&Soubor" {
+  MENUITEM "&Otevøít", MNID_FILE_OPEN
+  MENUITEM SEPARATOR
+  MENUITEM "&Tisk", MNID_FILE_PRINT
+  MENUITEM "Na&stavení tisku...", MNID_FILE_SETUP
+   MENUITEM SEPARATOR
+  MENUITEM "&Konec", MNID_FILE_EXIT
+ }
+ POPUP "Úprav&y" {
+   MENUITEM "&Kopírovat...", MNID_EDIT_COPYDLG
+   MENUITEM SEPARATOR
+   MENUITEM "P&oznamenat si...", MNID_EDIT_ANNOTATE
+ }
+ POPUP "&Zálo\9eka" {
+   MENUITEM "Pøi&dat...", MNID_BKMK_DEFINE
+ }
+ POPUP "&Nápovìda" {
+   MENUITEM "Náp&ovìda k nápovìdì", MNID_HELP_HELPON
+   MENUITEM "V\9edy na &vrchu", MNID_HELP_HELPTOP
+   MENUITEM SEPARATOR
+   MENUITEM "&Informace...", MNID_HELP_ABOUT
+#ifdef WINELIB
+   MENUITEM "O &WINE", MNID_HELP_WINE
+#endif
+ }
+}
+
+/* Strings */
+STRINGTABLE DISCARDABLE LANGUAGE LANG_CZECH, SUBLANG_DEFAULT
+{
+STID_WINE_HELP,        "Nápovìda WINE"
+STID_WHERROR,          "CHYBA"
+STID_WARNING,                  "VAROVÁNÍ"
+STID_INFO,             "Informace"
+STID_NOT_IMPLEMENTED,  "Není implementováno"
+STID_HLPFILE_ERROR_s,  "Nelze pøeèíst soubor nápovìdy `%s'"
+STID_CONTENTS,                 "&Obsah"
+STID_SEARCH,           "&Hledat"
+STID_BACK,             "&Zpìt"
+STID_HISTORY,          "&Historie"
+STID_TOPICS,           "&Témata"
+STID_ALL_FILES,        "V\9aechny soubory (*.*)"
+STID_HELP_FILES_HLP,   "Soubory nápovìdy (*.hlp)"
+STID_FILE_NOT_FOUND_s  "Cannot find '%s'. Do you want to find this file yourself?"
+}
diff --git a/reactos/base/applications/winhelp/Da.rc b/reactos/base/applications/winhelp/Da.rc
new file mode 100644 (file)
index 0000000..522cdae
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * Help Viewer
+ *
+ * Copyright 1997 Henrik Olsen
+ * Copyright 2002 Sylvain Petreolle <spetreolle@yahoo.fr>
+ *
+ * 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
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/* Menu */
+
+MAIN_MENU MENU LANGUAGE LANG_DANISH, SUBLANG_DEFAULT
+{
+ POPUP "&Filer" {
+  MENUITEM "Å&bn...", MNID_FILE_OPEN
+  MENUITEM SEPARATOR
+  MENUITEM "&Udskriv emne", MNID_FILE_PRINT
+  MENUITEM "&Indstil printer", MNID_FILE_SETUP
+   MENUITEM SEPARATOR
+  MENUITEM "&Afslut", MNID_FILE_EXIT
+ }
+ POPUP "&Rediger" {
+   MENUITEM "K&opier...", MNID_EDIT_COPYDLG
+   MENUITEM SEPARATOR
+   MENUITEM "&Anmærk...", MNID_EDIT_ANNOTATE
+ }
+ POPUP "Bog&mærke" {
+   MENUITEM "&Definer...", MNID_BKMK_DEFINE
+ }
+ POPUP "&Hjælp" {
+   MENUITEM "&Brug af Hjælp", MNID_HELP_HELPON
+   MENUITEM "Altid &øverst", MNID_HELP_HELPTOP
+   MENUITEM SEPARATOR
+   MENUITEM "&Info...", MNID_HELP_ABOUT
+#ifdef WINELIB
+   MENUITEM "Om &WINE", MNID_HELP_WINE
+#endif
+ }
+}
+
+
+/* Strings */
+
+STRINGTABLE DISCARDABLE LANGUAGE LANG_DANISH, SUBLANG_DEFAULT
+{
+STID_WINE_HELP,        "WINE Hjælp"
+STID_WHERROR,          "FEJL"
+STID_WARNING,                  "ADVARSEL"
+STID_INFO,             "Information"
+STID_NOT_IMPLEMENTED,  "Ikke implementeret"
+STID_HLPFILE_ERROR_s,  "Fejl ved indlæsning af filen `%s'"
+STID_CONTENTS,                 "&Indhold"
+STID_SEARCH,           "&Søg"
+STID_BACK,             "&Tilbage"
+STID_HISTORY,          "&Oversigt"
+STID_TOPICS,           "To&pics"
+STID_ALL_FILES,        "Alle filer (*.*)"
+STID_HELP_FILES_HLP,   "Hjælpe filer (*.hlp)"
+STID_FILE_NOT_FOUND_s  "Cannot find '%s'. Do you want to find this file yourself?"
+}
diff --git a/reactos/base/applications/winhelp/De.rc b/reactos/base/applications/winhelp/De.rc
new file mode 100644 (file)
index 0000000..8ec84cd
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * Help Viewer
+ *
+ * Copyright 1996 Ulrich Schmid
+ * Copyright 2002 Sylvain Petreolle <spetreolle@yahoo.fr>
+ *
+ * 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
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/* Menu */
+
+MAIN_MENU MENU LANGUAGE LANG_GERMAN, SUBLANG_NEUTRAL
+{
+ POPUP "&Datei" {
+  MENUITEM "Ö&ffnen...", MNID_FILE_OPEN
+  MENUITEM SEPARATOR
+  MENUITEM "Thema &drucken", MNID_FILE_PRINT
+  MENUITEM "Drucker&einrichtung...", MNID_FILE_SETUP
+   MENUITEM SEPARATOR
+  MENUITEM "&Beenden", MNID_FILE_EXIT
+ }
+ POPUP "&Bearbeiten" {
+   MENUITEM "&Kopieren...", MNID_EDIT_COPYDLG
+   MENUITEM SEPARATOR
+   MENUITEM "&Anmerken...", MNID_EDIT_ANNOTATE
+ }
+ POPUP "&Lesezeichen" {
+   MENUITEM "&Definieren...", MNID_BKMK_DEFINE
+ }
+ POPUP "&Hilfe" {
+   MENUITEM "&Hilfe benutzen", MNID_HELP_HELPON
+   MENUITEM "Immer im &Vordergrund", MNID_HELP_HELPTOP
+   MENUITEM SEPARATOR
+   MENUITEM "&Info...", MNID_HELP_ABOUT
+#ifdef WINELIB
+   MENUITEM "&Über WINE", MNID_HELP_WINE
+#endif
+ }
+}
+
+/* Strings */
+
+STRINGTABLE DISCARDABLE LANGUAGE LANG_GERMAN, SUBLANG_NEUTRAL
+{
+STID_WINE_HELP,        "WINE Hilfe"
+STID_WHERROR,          "FEHLER"
+STID_WARNING,                  "ACHTUNG"
+STID_INFO,             "Information"
+STID_NOT_IMPLEMENTED,  "Nicht implementiert"
+STID_HLPFILE_ERROR_s,  "Fehler beim Lesen der Hilfe-Datei `%s'"
+STID_CONTENTS,                 "&Inhalt"
+STID_SEARCH,           "&Suchen"
+STID_BACK,             "&Zurück"
+STID_HISTORY,          "&Bisher"
+STID_TOPICS,           "&Topics"
+STID_ALL_FILES,        "Alle Dateien (*.*)"
+STID_HELP_FILES_HLP,   "Hilfe-Dateien (*.hlp)"
+STID_FILE_NOT_FOUND_s  "Cannot find '%s'. Do you want to find this file yourself?"
+}
diff --git a/reactos/base/applications/winhelp/En.rc b/reactos/base/applications/winhelp/En.rc
new file mode 100644 (file)
index 0000000..8c4bac2
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * Help Viewer
+ *
+ * Copyright 1996 Ulrich Schmid
+ * Copyright 2002 Sylvain Petreolle <spetreolle@yahoo.fr>
+ *
+ * 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
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/* Menu */
+
+MAIN_MENU MENU LANGUAGE LANG_ENGLISH, SUBLANG_DEFAULT
+{
+ POPUP "&File" {
+  MENUITEM "&Open", MNID_FILE_OPEN
+  MENUITEM SEPARATOR
+  MENUITEM "&Print", MNID_FILE_PRINT
+  MENUITEM "Printer &setup...", MNID_FILE_SETUP
+   MENUITEM SEPARATOR
+  MENUITEM "E&xit", MNID_FILE_EXIT
+ }
+ POPUP "&Edit" {
+   MENUITEM "&Copy...", MNID_EDIT_COPYDLG
+   MENUITEM SEPARATOR
+   MENUITEM "&Annotate...", MNID_EDIT_ANNOTATE
+ }
+ POPUP "&Bookmark" {
+   MENUITEM "&Define...", MNID_BKMK_DEFINE
+ }
+ POPUP "&Help" {
+   MENUITEM "Help &on help", MNID_HELP_HELPON
+   MENUITEM "Always on &top", MNID_HELP_HELPTOP
+   MENUITEM SEPARATOR
+   MENUITEM "&Info...", MNID_HELP_ABOUT
+#ifdef WINELIB
+   MENUITEM "&About WINE", MNID_HELP_WINE
+#endif
+ }
+}
+
+/* Strings */
+STRINGTABLE DISCARDABLE LANGUAGE LANG_ENGLISH, SUBLANG_DEFAULT
+{
+STID_WINE_HELP,        "WINE Help"
+STID_WHERROR,          "ERROR"
+STID_WARNING,                  "WARNING"
+STID_INFO,             "Information"
+STID_NOT_IMPLEMENTED,  "Not implemented"
+STID_HLPFILE_ERROR_s,  "Error while reading the help file `%s'"
+STID_CONTENTS,                 "&Contents"
+STID_SEARCH,           "&Search"
+STID_BACK,             "&Back"
+STID_HISTORY,          "&History"
+STID_TOPICS,           "&Topics"
+STID_ALL_FILES,        "All files (*.*)"
+STID_HELP_FILES_HLP,   "Help files (*.hlp)"
+STID_FILE_NOT_FOUND_s  "Cannot find '%s'. Do you want to find this file yourself?"
+}
diff --git a/reactos/base/applications/winhelp/Eo.rc b/reactos/base/applications/winhelp/Eo.rc
new file mode 100644 (file)
index 0000000..cc8ef66
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * Help Viewer
+ * Esperanto Language Support
+ *
+ * Copyright 2006 Antonio Codazzi
+ *
+ * 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
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/* Cxapelitaj literoj estas en Latin-3 iso8859-3 */
+
+/* Menu */
+
+MAIN_MENU MENU LANGUAGE LANG_ESPERANTO, SUBLANG_DEFAULT
+{
+ POPUP "&Dosiero" {
+  MENUITEM "&Malfermu", MNID_FILE_OPEN
+  MENUITEM SEPARATOR
+  MENUITEM "&Presu", MNID_FILE_PRINT
+  MENUITEM "&Impozu Printilon...", MNID_FILE_SETUP
+   MENUITEM SEPARATOR
+  MENUITEM "&Finu", MNID_FILE_EXIT
+ }
+ POPUP "&Redakto" {
+   MENUITEM "&Kopiu...", MNID_EDIT_COPYDLG
+   MENUITEM SEPARATOR
+   MENUITEM "&Notu...", MNID_EDIT_ANNOTATE
+ }
+ POPUP "&Legosigno" {
+   MENUITEM "&Difinu...", MNID_BKMK_DEFINE
+ }
+ POPUP "&Helpo" {
+   MENUITEM "&Helpu pri helpo", MNID_HELP_HELPON
+   MENUITEM "Æiam &supre", MNID_HELP_HELPTOP
+   MENUITEM SEPARATOR
+   MENUITEM "&Pri...", MNID_HELP_ABOUT
+#ifdef WINELIB
+   MENUITEM "&Pri WINE", MNID_HELP_WINE
+#endif
+ }
+}
+
+/* Strings */
+STRINGTABLE DISCARDABLE LANGUAGE LANG_ESPERANTO, SUBLANG_DEFAULT
+{
+STID_WINE_HELP,        "WINE Helpanto"
+STID_WHERROR,          "ERARO"
+STID_WARNING,          "ATENTU"
+STID_INFO,             "Informo pri"
+STID_NOT_IMPLEMENTED,  "Ne-implementata"
+STID_HLPFILE_ERROR_s,  "Eraro dum la legado de helpdosiero `%s'"
+STID_CONTENTS,         "&Enhavo"
+STID_SEARCH,           "&Seræu"
+STID_BACK,             "&Retro"
+STID_HISTORY,          "Krono&logio"
+STID_TOPICS,           "&Temoj"
+STID_ALL_FILES,        "Tutaj dosieroj (*.*)"
+STID_HELP_FILES_HLP,   "Helpaj dosieroj (*.hlp)"
+STID_FILE_NOT_FOUND_s  "Cannot find '%s'. Do you want to find this file yourself?"
+}
diff --git a/reactos/base/applications/winhelp/Es.rc b/reactos/base/applications/winhelp/Es.rc
new file mode 100644 (file)
index 0000000..93d9223
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * Help Viewer
+ *
+ * Copyright 1996 Ulrich Schmid
+ * Copyright 2002 Sylvain Petreolle <spetreolle@yahoo.fr>
+ * Copyright 2003, 2004 José Manuel Ferrer Ortiz
+ *
+ * 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
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/* Menu */
+
+MAIN_MENU MENU LANGUAGE LANG_SPANISH, SUBLANG_NEUTRAL
+{
+ POPUP "&Archivo" {
+  MENUITEM "A&brir...", MNID_FILE_OPEN
+  MENUITEM SEPARATOR
+  MENUITEM "&Imprimir", MNID_FILE_PRINT
+  MENUITEM "&Configuración impresora...", MNID_FILE_SETUP
+   MENUITEM SEPARATOR
+  MENUITEM "&Salir", MNID_FILE_EXIT
+ }
+ POPUP "&Editar" {
+   MENUITEM "&Copiar...", MNID_EDIT_COPYDLG
+   MENUITEM SEPARATOR
+   MENUITEM "&Anotar...", MNID_EDIT_ANNOTATE
+ }
+ POPUP "&Marcador" {
+   MENUITEM "&Definir...", MNID_BKMK_DEFINE
+ }
+ POPUP "A&yuda" {
+   MENUITEM "&Ayuda sobre la ayuda", MNID_HELP_HELPON
+   MENUITEM "&Siempre visible", MNID_HELP_HELPTOP
+   MENUITEM SEPARATOR
+   MENUITEM "&Info...", MNID_HELP_ABOUT
+#ifdef WINELIB
+   MENUITEM "&Acerca de WINE", MNID_HELP_WINE
+#endif
+ }
+}
+
+/* Strings */
+STRINGTABLE DISCARDABLE LANGUAGE LANG_SPANISH, SUBLANG_NEUTRAL
+{
+STID_WINE_HELP,        "Ayuda de WINE"
+STID_WHERROR,          "ERROR"
+STID_WARNING,                  "ADVERTENCIA"
+STID_INFO,             "Información"
+STID_NOT_IMPLEMENTED,  "Aún no implementado"
+STID_HLPFILE_ERROR_s,  "Error al leer el archivo de ayuda `%s'"
+STID_CONTENTS,                 "&Índice"
+STID_SEARCH,           "&Buscar"
+STID_BACK,             "&Anterior"
+STID_HISTORY,          "&Historial"
+STID_TOPICS,           "&Temas"
+STID_ALL_FILES,        "Todos los archivos (*.*)"
+STID_HELP_FILES_HLP,   "Archivos de ayuda (*.hlp)"
+STID_FILE_NOT_FOUND_s  "Cannot find '%s'. Do you want to find this file yourself?"
+}
diff --git a/reactos/base/applications/winhelp/Fi.rc b/reactos/base/applications/winhelp/Fi.rc
new file mode 100644 (file)
index 0000000..90de636
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * Help Viewer
+ *
+ * Copyright 1996 Ulrich Schmid
+ * Finnish language by Jussi Tirkkonen <jt@modeemi.cs.tut.fi>
+ * Copyright 2002 Sylvain Petreolle <spetreolle@yahoo.fr>
+ *
+ * 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
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/* Menu */
+
+MAIN_MENU MENU LANGUAGE LANG_FINNISH, SUBLANG_DEFAULT
+{
+ POPUP "&Tiedosto" {
+  MENUITEM "&Avaa...", MNID_FILE_OPEN
+  MENUITEM SEPARATOR
+  MENUITEM "&Tulosta", MNID_FILE_PRINT
+  MENUITEM "&Kirjoittimen asetukset...", MNID_FILE_SETUP
+   MENUITEM SEPARATOR
+  MENUITEM "&Lopeta", MNID_FILE_EXIT
+ }
+ POPUP "&Muokkaa" {
+   MENUITEM "&Kopioi...", MNID_EDIT_COPYDLG
+   MENUITEM SEPARATOR
+   MENUITEM "&Huomautus...", MNID_EDIT_ANNOTATE
+ }
+ POPUP "&Kirjanmerkki" {
+   MENUITEM "&Aseta...", MNID_BKMK_DEFINE
+ }
+ POPUP "&Ohje" {
+   MENUITEM "&Ohjeen käyttö", MNID_HELP_HELPON
+   MENUITEM "&Aina päällimmäisenä", MNID_HELP_HELPTOP
+   MENUITEM SEPARATOR
+   MENUITEM "T&ietoja...", MNID_HELP_ABOUT
+#ifdef WINELIB
+   MENUITEM "&Tietoja WINEstä", MNID_HELP_WINE
+#endif
+ }
+}
+
+/* Strings */
+
+STRINGTABLE DISCARDABLE LANGUAGE LANG_FINNISH, SUBLANG_DEFAULT
+{
+STID_WINE_HELP,        "WINE Ohje"
+STID_WHERROR,          "VIRHE"
+STID_WARNING,                  "VAROITUS"
+STID_INFO,             "Tietoja"
+STID_NOT_IMPLEMENTED,  "Ei käytettävissä"
+STID_HLPFILE_ERROR_s,  "Virhe luettaessa ohjetiedostoa `%s'"
+STID_CONTENTS,                 "&Sisällys"
+STID_SEARCH,           "&Etsi"
+STID_BACK,             "&Takaisin"
+STID_HISTORY,          "&Luetut"
+STID_TOPICS,           "T&opics"
+STID_ALL_FILES,        "Kaikki tiedostot (*.*)"
+STID_HELP_FILES_HLP,   "Ohjetiedostot (*.hlp)"
+STID_FILE_NOT_FOUND_s  "Cannot find '%s'. Do you want to find this file yourself?"
+}
diff --git a/reactos/base/applications/winhelp/Fr.rc b/reactos/base/applications/winhelp/Fr.rc
new file mode 100644 (file)
index 0000000..7318507
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * Help Viewer
+ *
+ * Copyright 1996 Ulrich Schmid
+ * Copyright 2002 Sylvain Petreolle <spetreolle@yahoo.fr>
+ *
+ * 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
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/* Menu */
+
+LANGUAGE LANG_FRENCH, SUBLANG_NEUTRAL
+
+MAIN_MENU MENU
+{
+ POPUP "&Fichier" {
+  MENUITEM "&Ouvrir", MNID_FILE_OPEN
+  MENUITEM SEPARATOR
+  MENUITEM "Im&primer", MNID_FILE_PRINT
+  MENUITEM "&Configuration de l'imprimante...", MNID_FILE_SETUP
+   MENUITEM SEPARATOR
+  MENUITEM "&Quitter", MNID_FILE_EXIT
+ }
+ POPUP "É&dition" {
+   MENUITEM "&Copier...", MNID_EDIT_COPYDLG
+   MENUITEM SEPARATOR
+   MENUITEM "&Annotation...", MNID_EDIT_ANNOTATE
+ }
+ POPUP "&Signet" {
+   MENUITEM "&Définir...", MNID_BKMK_DEFINE
+ }
+ POPUP "Aid&e" {
+   MENUITEM "&Utiliser l'aide", MNID_HELP_HELPON
+   MENUITEM "&Toujours visible", MNID_HELP_HELPTOP
+   MENUITEM SEPARATOR
+   MENUITEM "&Info...", MNID_HELP_ABOUT
+#ifdef WINELIB
+   MENUITEM "À &propos de WINE", MNID_HELP_WINE
+#endif
+ }
+}
+
+/* Strings */
+STRINGTABLE DISCARDABLE
+{
+STID_WINE_HELP,        "Aide de WINE"
+STID_WHERROR,          "ERREUR"
+STID_WARNING,                  "ATTENTION"
+STID_INFO,             "Information"
+STID_NOT_IMPLEMENTED,  "Non implémenté"
+STID_HLPFILE_ERROR_s,  "Une erreur est survenue en lisant le fichier d'aide « %s »"
+STID_CONTENTS,                 "&Index"
+STID_SEARCH,           "&Rechercher"
+STID_BACK,             "&Précédent"
+STID_HISTORY,          "&Historique"
+STID_TOPICS,           "&Sujets"
+STID_ALL_FILES,        "Tous fichiers (*.*)"
+STID_HELP_FILES_HLP,   "Fichiers d'aide (*.hlp)"
+STID_FILE_NOT_FOUND_s  "Cannot find '%s'. Do you want to find this file yourself?"
+}
diff --git a/reactos/base/applications/winhelp/Hu.rc b/reactos/base/applications/winhelp/Hu.rc
new file mode 100644 (file)
index 0000000..8f4ef53
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * Help Viewer
+ *
+ * Copyright 1996 Ulrich Schmid
+ * Copyright 2002 Sylvain Petreolle
+ * Copyright 2002 Zoly Nagy
+ *
+ * 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
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/* Menu */
+
+MAIN_MENU MENU LANGUAGE LANG_HUNGARIAN, SUBLANG_DEFAULT
+{
+ POPUP "&Fájl" {
+  MENUITEM "&Megnyitás...", MNID_FILE_OPEN
+  MENUITEM SEPARATOR
+  MENUITEM "&Nyomtatás", MNID_FILE_PRINT
+  MENUITEM "Nyomtató &beállítás...", MNID_FILE_SETUP
+   MENUITEM SEPARATOR
+  MENUITEM "&Kilépés", MNID_FILE_EXIT
+ }
+ POPUP "&Szerkesztés" {
+   MENUITEM "&Másolás...", MNID_EDIT_COPYDLG
+   MENUITEM SEPARATOR
+   MENUITEM "&Jegyzet...", MNID_EDIT_ANNOTATE
+ }
+ POPUP "&Könyvjelzõ" {
+   MENUITEM "&Definiálás...", MNID_BKMK_DEFINE
+ }
+ POPUP "&Súgó" {
+   MENUITEM "&Használat", MNID_HELP_HELPON
+   MENUITEM "Mindig &legfelül", MNID_HELP_HELPTOP
+   MENUITEM SEPARATOR
+   MENUITEM "&Információ...", MNID_HELP_ABOUT
+#ifdef WINELIB
+   MENUITEM "&&A WINE-ról", MNID_HELP_WINE
+#endif
+ }
+}
+
+/* Strings */
+
+STRINGTABLE DISCARDABLE LANGUAGE LANG_HUNGARIAN, SUBLANG_DEFAULT
+{
+STID_WINE_HELP,        "WINE súgó"
+STID_WHERROR,          "HIBA"
+STID_WARNING,                  "FIGYELMEZTETÉS"
+STID_INFO,             "Információ"
+STID_NOT_IMPLEMENTED,  "Nincs implementálva"
+STID_HLPFILE_ERROR_s,  "Hiba a `%s' file olvasásakor"
+STID_CONTENTS,                 "&Tartalom"
+STID_SEARCH,           "&Keresés"
+STID_BACK,             "&Vissza"
+STID_HISTORY,          "&Elõzmény"
+STID_TOPICS,           "&Témakörök"
+STID_ALL_FILES,        "Minden fájl (*.*)"
+STID_HELP_FILES_HLP,   "Súgó fájlok (*.hlp)"
+STID_FILE_NOT_FOUND_s  "Cannot find '%s'. Do you want to find this file yourself?"
+}
diff --git a/reactos/base/applications/winhelp/It.rc b/reactos/base/applications/winhelp/It.rc
new file mode 100644 (file)
index 0000000..bce3f14
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * Help Viewer
+ *
+ * Copyright 1996 Ulrich Schmid
+ * Copyright 2002 Sylvain Petreolle <spetreolle@yahoo.fr>
+ *
+ * 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
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/* Menu */
+
+MAIN_MENU MENU LANGUAGE LANG_ITALIAN, SUBLANG_NEUTRAL
+{
+ POPUP "&File" {
+  MENUITEM "&Apri...", MNID_FILE_OPEN
+  MENUITEM SEPARATOR
+  MENUITEM "S&tampa", MNID_FILE_PRINT
+  MENUITEM "&Setup stampante...", MNID_FILE_SETUP
+   MENUITEM SEPARATOR
+  MENUITEM "&Esci", MNID_FILE_EXIT
+ }
+ POPUP "&Modifica" {
+   MENUITEM "&Copia...", MNID_EDIT_COPYDLG
+   MENUITEM SEPARATOR
+   MENUITEM "&Annota...", MNID_EDIT_ANNOTATE
+ }
+ POPUP "&Segnalibro" {
+   MENUITEM "&Definisci...", MNID_BKMK_DEFINE
+ }
+ POPUP "&?" {
+   MENUITEM "&Aiuto sulla guida", MNID_HELP_HELPON
+   MENUITEM "Sempre in primo &piano", MNID_HELP_HELPTOP
+   MENUITEM SEPARATOR
+   MENUITEM "&Informazioni su...", MNID_HELP_ABOUT
+#ifdef WINELIB
+   MENUITEM "&Informazion su WINE", MNID_HELP_WINE
+#endif
+ }
+}
+
+/* Strings */
+
+STRINGTABLE DISCARDABLE LANGUAGE LANG_ITALIAN, SUBLANG_NEUTRAL
+{
+STID_WINE_HELP,        "Guida di WINE"
+STID_WHERROR,          "ERRORE"
+STID_WARNING,                  "ATTENZIONE"
+STID_INFO,             "Informazione"
+STID_NOT_IMPLEMENTED,  "Non ancora implementato"
+STID_HLPFILE_ERROR_s,  "Errore di lettura del file della Guida `%s'"
+STID_CONTENTS,                 "&Sommario"
+STID_SEARCH,           "&Trova"
+STID_BACK,             "&Precedente"
+STID_HISTORY,          "&Cronologia"
+STID_TOPICS,           "&Argomenti"
+STID_ALL_FILES,        "Tutti i file (*.*)"
+STID_HELP_FILES_HLP,   "File della Guida (*.hlp)"
+STID_FILE_NOT_FOUND_s  "Cannot find '%s'. Do you want to find this file yourself?"
+}
diff --git a/reactos/base/applications/winhelp/Ko.rc b/reactos/base/applications/winhelp/Ko.rc
new file mode 100644 (file)
index 0000000..4db5070
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * Help Viewer
+ *
+ * Copyright 1996 Ulrich Schmid
+ * Copyright 2002 Sylvain Petreolle <spetreolle@yahoo.fr>
+ *
+ * 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
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/* Menu */
+
+MAIN_MENU MENU LANGUAGE LANG_KOREAN, SUBLANG_NEUTRAL
+{
+ POPUP "ÆÄÀÏ(&F)" {
+  MENUITEM "¿­±â(&O)...", MNID_FILE_OPEN
+  MENUITEM SEPARATOR
+  MENUITEM "Àμâ(&P)", MNID_FILE_PRINT
+  MENUITEM "ÇÁ¸°ÅÍ ¼³Á¤(&S)...", MNID_FILE_SETUP
+   MENUITEM SEPARATOR
+  MENUITEM "Á¾·á(&E)", MNID_FILE_EXIT
+ }
+ POPUP "ÆíÁý(&E)" {
+   MENUITEM "º¹»ç(&C)...", MNID_EDIT_COPYDLG
+   MENUITEM SEPARATOR
+   MENUITEM "ÁÖ¼®(&A)...", MNID_EDIT_ANNOTATE
+ }
+ POPUP "Ã¥°¥ÇÇ(&B)" {
+   MENUITEM "Á¤ÀÇ(&D)...", MNID_BKMK_DEFINE
+ }
+ POPUP "µµ¿ò¸»(&H)" {
+   MENUITEM "µµ¿ò¸» »ç¿ë¹ý(&O)", MNID_HELP_HELPON
+   MENUITEM "Ç×»ó À§(&T)", MNID_HELP_HELPTOP
+   MENUITEM SEPARATOR
+   MENUITEM "Á¤º¸(&I)...", MNID_HELP_ABOUT
+#ifdef WINELIB
+   MENUITEM "Wine¿¡ °üÇÏ¿©(&A)", MNID_HELP_WINE
+#endif
+ }
+}
+
+/* Strings */
+
+STRINGTABLE DISCARDABLE LANGUAGE LANG_KOREAN, SUBLANG_NEUTRAL
+{
+STID_WINE_HELP,        "Wine µµ¿ò¸»"
+STID_WHERROR,          "¿À·ù"
+STID_WARNING,                  "°æ°í"
+STID_INFO,             "Á¤º¸"
+STID_NOT_IMPLEMENTED,  "±¸ÇöµÇÁö ¾Ê¾ÒÀ½"
+STID_HLPFILE_ERROR_s,  "µµ¿ò¸» ÆÄÀÏ `%s'¸¦ Àд µµÁß ¿À·ù ¹ß»ý"
+STID_CONTENTS,                 "¸ñÂ÷(&C)"
+STID_SEARCH,           "ã±â(&S)"
+STID_BACK,             "µÚ·Î(&B)"
+STID_HISTORY,          "È÷½ºÅ丮(&H)"
+STID_TOPICS,           "¸ñÂ÷(&T)"
+STID_ALL_FILES,        "¸ðµç ÆÄÀÏ (*.*)"
+STID_HELP_FILES_HLP,   "µµ¿ò¸» ÆÄÀÏ (*.hlp)"
+STID_FILE_NOT_FOUND_s  "%sÀ» Ã£À» ¼ö ¾ø½À´Ï´Ù'. ÀÌ ÆÄÀÏÀ» ½º½º·Î Ã£°Ú½À´Ï±î?"
+}
diff --git a/reactos/base/applications/winhelp/Nl.rc b/reactos/base/applications/winhelp/Nl.rc
new file mode 100644 (file)
index 0000000..44ecd90
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * Help Viewer (Dutch resources)
+ *
+ * Copyright 2003 Hans Leidekker
+ *
+ * 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
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/* Menu */
+
+MAIN_MENU MENU LANGUAGE LANG_DUTCH, SUBLANG_NEUTRAL
+{
+ POPUP "&Bestand" {
+  MENUITEM "&Openen", MNID_FILE_OPEN
+  MENUITEM SEPARATOR
+  MENUITEM "Af&drukken", MNID_FILE_PRINT
+  MENUITEM "&Printerinstellingen...", MNID_FILE_SETUP
+  MENUITEM SEPARATOR
+  MENUITEM "&Afsluiten", MNID_FILE_EXIT
+ }
+ POPUP "&Bewerken" {
+   MENUITEM "&Kopiëren...", MNID_EDIT_COPYDLG
+   MENUITEM SEPARATOR
+   MENUITEM "&Annoteren...", MNID_EDIT_ANNOTATE
+ }
+ POPUP "&Favorieten" {
+   MENUITEM "&Aanmaken...", MNID_BKMK_DEFINE
+ }
+ POPUP "&Help" {
+   MENUITEM "Hulp &bij help", MNID_HELP_HELPON
+   MENUITEM "Altijd &zichtbaar", MNID_HELP_HELPTOP
+   MENUITEM SEPARATOR
+   MENUITEM "&Info...", MNID_HELP_ABOUT
+#ifdef WINELIB
+   MENUITEM "&Over WINE", MNID_HELP_WINE
+#endif
+ }
+}
+
+/* Strings */
+STRINGTABLE DISCARDABLE LANGUAGE LANG_DUTCH, SUBLANG_NEUTRAL
+{
+STID_WINE_HELP,        "WINE Help"
+STID_WHERROR,          "FOUT"
+STID_WARNING,                  "WAARSCHUWING"
+STID_INFO,             "Informatie"
+STID_NOT_IMPLEMENTED,  "Niet geïmplementeerd"
+STID_HLPFILE_ERROR_s,  "Fout bij het lezen van het helpbestand `%s'"
+STID_CONTENTS,                 "&Inhoud"
+STID_SEARCH,           "&Zoeken"
+STID_BACK,             "&Terug"
+STID_HISTORY,          "&Geschiedenis"
+STID_TOPICS,           "&Onderwerpen"
+STID_ALL_FILES,        "Alle bestanden (*.*)"
+STID_HELP_FILES_HLP,   "Helpbestanden (*.hlp)"
+STID_FILE_NOT_FOUND_s  "Cannot find '%s'. Do you want to find this file yourself?"
+}
diff --git a/reactos/base/applications/winhelp/No.rc b/reactos/base/applications/winhelp/No.rc
new file mode 100644 (file)
index 0000000..f016efb
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * Help Viewer
+ *
+ * Copyright 2005 Alexander N. Sørnes <alex@thehandofagony.com>
+ *
+ * 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
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/* Menu */
+
+MAIN_MENU MENU LANGUAGE LANG_NORWEGIAN, SUBLANG_NORWEGIAN_BOKMAL
+{
+ POPUP "&Fil" {
+  MENUITEM "&Åpne", MNID_FILE_OPEN
+  MENUITEM SEPARATOR
+  MENUITEM "Skriv &ut", MNID_FILE_PRINT
+  MENUITEM "Opp&sett av skriveren . . .", MNID_FILE_SETUP
+   MENUITEM SEPARATOR
+  MENUITEM "&Avslutt", MNID_FILE_EXIT
+ }
+ POPUP "R&ediger" {
+   MENUITEM "&Kopier . . .", MNID_EDIT_COPYDLG
+   MENUITEM SEPARATOR
+   MENUITEM "K&ommenter . . .", MNID_EDIT_ANNOTATE
+ }
+ POPUP "&Bokmerke" {
+   MENUITEM "&Definer . . .", MNID_BKMK_DEFINE
+ }
+ POPUP "&Hjelp" {
+   MENUITEM "&Hjelp til Hjelp", MNID_HELP_HELPON
+   MENUITEM "All&tid øverst", MNID_HELP_HELPTOP
+   MENUITEM SEPARATOR
+   MENUITEM "&Informasjon . . .", MNID_HELP_ABOUT
+#ifdef WINELIB
+   MENUITEM "&om WINE", MNID_HELP_WINE
+#endif
+ }
+}
+
+/* Strings */
+STRINGTABLE DISCARDABLE LANGUAGE LANG_NORWEGIAN, SUBLANG_NORWEGIAN_BOKMAL
+{
+STID_WINE_HELP,        "Hjelp"
+STID_WHERROR,          "FEIL"
+STID_WARNING,                  "ADVARSEL"
+STID_INFO,             "Informasjon"
+STID_NOT_IMPLEMENTED,  "Ikke implementert"
+STID_HLPFILE_ERROR_s,  "Feil ved lesing av hjelpefilen '%s'"
+STID_CONTENTS,                 "&Innhold"
+STID_SEARCH,           "&Søk"
+STID_BACK,             "Til&bake"
+STID_HISTORY,          "&Historikk"
+STID_TOPICS,           "&Emner"
+STID_ALL_FILES,        "Alle filer (*.*)"
+STID_HELP_FILES_HLP,   "Hjelp-filer (*.hlp)"
+STID_FILE_NOT_FOUND_s  "Cannot find '%s'. Do you want to find this file yourself?"
+}
diff --git a/reactos/base/applications/winhelp/Pl.rc b/reactos/base/applications/winhelp/Pl.rc
new file mode 100644 (file)
index 0000000..1c90a0c
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * Help Viewer
+ *
+ * Copyright 1996 Ulrich Schmid
+ * Copyright 2002 Sylvain Petreolle <spetreolle@yahoo.fr>
+ * Copyright 2004 Piotr Caban
+ *
+ * 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
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/* Menu */
+
+MAIN_MENU MENU LANGUAGE LANG_POLISH, SUBLANG_DEFAULT
+{
+ POPUP "&Plik" {
+  MENUITEM "&Otwórz", MNID_FILE_OPEN
+  MENUITEM SEPARATOR
+  MENUITEM "&Drukuj", MNID_FILE_PRINT
+  MENUITEM "&Ustawienia drukarki...", MNID_FILE_SETUP
+   MENUITEM SEPARATOR
+  MENUITEM "&Wyj\9ccie", MNID_FILE_EXIT
+ }
+ POPUP "&Edycja" {
+   MENUITEM "&Kopiuj...", MNID_EDIT_COPYDLG
+   MENUITEM SEPARATOR
+   MENUITEM "&Skomentuj...", MNID_EDIT_ANNOTATE
+ }
+ POPUP "&Zak³adka" {
+   MENUITEM "&Zdefiniuj...", MNID_BKMK_DEFINE
+ }
+ POPUP "Pomo&c" {
+   MENUITEM "&Pomoc", MNID_HELP_HELPON
+   MENUITEM "&Zawsze na wierzchu", MNID_HELP_HELPTOP
+   MENUITEM SEPARATOR
+   MENUITEM "&O programie...", MNID_HELP_ABOUT
+#ifdef WINELIB
+   MENUITEM "&O programie WINE", MNID_HELP_WINE
+#endif
+ }
+}
+
+/* Strings */
+STRINGTABLE DISCARDABLE LANGUAGE LANG_POLISH, SUBLANG_DEFAULT
+{
+STID_WINE_HELP,        "WINE - Pomoc"
+STID_WHERROR,          "B£¥D"
+STID_WARNING,                  "OSTRZE¯ENIE"
+STID_INFO,             "Informacja"
+STID_NOT_IMPLEMENTED,  "Nie zaimplementowane"
+STID_HLPFILE_ERROR_s,  "B³¹d w trakcie odczytu pliku pomocy `%s'"
+STID_CONTENTS,                 "&Zawarto\9cæ"
+STID_SEARCH,           "&Szukaj"
+STID_BACK,             "&Wstecz"
+STID_HISTORY,          "&Historia"
+STID_TOPICS,           "&Tematy"
+STID_ALL_FILES,        "Wszystkie pliki (*.*)"
+STID_HELP_FILES_HLP,   "Pliki pomocy (*.hlp)"
+STID_FILE_NOT_FOUND_s  "Cannot find '%s'. Do you want to find this file yourself?"
+}
diff --git a/reactos/base/applications/winhelp/Pt.rc b/reactos/base/applications/winhelp/Pt.rc
new file mode 100644 (file)
index 0000000..d080c19
--- /dev/null
@@ -0,0 +1,130 @@
+/*
+ * Help Viewer
+ * Portuguese Language Support
+ *
+ * Copyright 1996 Ulrich Schmid
+ * Portuguese translation by Gustavo Junior Alves <alves@correionet.com.br>
+ * Copyright 2002 Sylvain Petreolle <spetreolle@yahoo.fr>
+ * Copyright 2003 Marcelo Duarte
+ * Copyright 2004 Américo José Melo
+ *
+ * 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
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/* Menu */
+
+LANGUAGE LANG_PORTUGUESE, SUBLANG_PORTUGUESE_BRAZILIAN
+
+MAIN_MENU MENU
+{
+ POPUP "&Arquivo" {
+  MENUITEM "&Abrir...", MNID_FILE_OPEN
+  MENUITEM SEPARATOR
+  MENUITEM "&Imprimir", MNID_FILE_PRINT
+  MENUITEM "&Configurar Impressora...", MNID_FILE_SETUP
+   MENUITEM SEPARATOR
+  MENUITEM "Sai&r", MNID_FILE_EXIT
+ }
+ POPUP "&Editar" {
+   MENUITEM "&Copiar...", MNID_EDIT_COPYDLG
+   MENUITEM SEPARATOR
+   MENUITEM "&Anotar...", MNID_EDIT_ANNOTATE
+ }
+ POPUP "In&dicador" {
+   MENUITEM "&Definir...", MNID_BKMK_DEFINE
+ }
+ POPUP "Aj&uda" {
+   MENUITEM "Ajuda &na ajuda", MNID_HELP_HELPON
+   MENUITEM "Sempre &visível", MNID_HELP_HELPTOP
+   MENUITEM SEPARATOR
+   MENUITEM "&Informações...", MNID_HELP_ABOUT
+#ifdef WINELIB
+   MENUITEM "&Sobre WINE", MNID_HELP_WINE
+#endif
+ }
+}
+
+LANGUAGE LANG_PORTUGUESE, SUBLANG_PORTUGUESE
+
+MAIN_MENU MENU
+{
+ POPUP "&Ficheiro" {
+  MENUITEM "&Abrir...", MNID_FILE_OPEN
+  MENUITEM SEPARATOR
+  MENUITEM "&Imprimir", MNID_FILE_PRINT
+  MENUITEM "&Configurar Impressora...", MNID_FILE_SETUP
+   MENUITEM SEPARATOR
+  MENUITEM "Sai&r", MNID_FILE_EXIT
+ }
+ POPUP "&Editar" {
+   MENUITEM "&Copiar...", MNID_EDIT_COPYDLG
+   MENUITEM SEPARATOR
+   MENUITEM "&Anotar...", MNID_EDIT_ANNOTATE
+ }
+ POPUP "In&dicador" {
+   MENUITEM "&Definir...", MNID_BKMK_DEFINE
+ }
+ POPUP "Aj&uda" {
+   MENUITEM "Ajuda &na ajuda", MNID_HELP_HELPON
+   MENUITEM "Sempre &visível", MNID_HELP_HELPTOP
+   MENUITEM SEPARATOR
+   MENUITEM "&Informações...", MNID_HELP_ABOUT
+#ifdef WINELIB
+   MENUITEM "&Acerca do WINE", MNID_HELP_WINE
+#endif
+ }
+}
+
+/* Strings */
+
+LANGUAGE LANG_PORTUGUESE, SUBLANG_PORTUGUESE_BRAZILIAN
+
+STRINGTABLE DISCARDABLE
+{
+STID_WINE_HELP,        "Ajuda WINE"
+STID_WHERROR,          "ERRO"
+STID_WARNING,                  "AVISO"
+STID_INFO,             "Informação"
+STID_NOT_IMPLEMENTED,  "Não implementado"
+STID_HLPFILE_ERROR_s,  "Erro encontrado na leitura do arquivo de ajuda '%s'"
+STID_CONTENTS,                 "&Conteúdo"
+STID_SEARCH,           "&Procurar"
+STID_BACK,             "&Voltar"
+STID_HISTORY,          "&Histórico"
+STID_TOPICS,           "&Tópicos"
+STID_ALL_FILES,        "Todos os arquivos (*.*)"
+STID_HELP_FILES_HLP,   "Arquivos de ajuda (*.hlp)"
+STID_FILE_NOT_FOUND_s   "Cannot find '%s'. Do you want to find this file yourself?"
+}
+
+LANGUAGE LANG_PORTUGUESE, SUBLANG_PORTUGUESE
+
+STRINGTABLE DISCARDABLE
+{
+STID_WINE_HELP,        "Ajuda WINE"
+STID_WHERROR,          "ERRO"
+STID_WARNING,                  "AVISO"
+STID_INFO,             "Informação"
+STID_NOT_IMPLEMENTED,  "Não implementado"
+STID_HLPFILE_ERROR_s,  "Erro encontrado na leitura do ficheiro de ajuda '%s'"
+STID_CONTENTS,                 "&Conteúdo"
+STID_SEARCH,           "&Procurar"
+STID_BACK,             "&Voltar"
+STID_HISTORY,          "&Histórico"
+STID_TOPICS,           "&Tópicos"
+STID_ALL_FILES,        "Todos os ficheiros (*.*)"
+STID_HELP_FILES_HLP,   "Ficheiros de ajuda (*.hlp)"
+STID_FILE_NOT_FOUND_s  "Cannot find '%s'. Do you want to find this file yourself?"
+}
diff --git a/reactos/base/applications/winhelp/Ru.rc b/reactos/base/applications/winhelp/Ru.rc
new file mode 100644 (file)
index 0000000..c07a743
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * Help Viewer (Russian resources)
+ *
+ * Copyright 2003 Igor Stepin
+ *
+ * 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
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/* Menu */
+
+MAIN_MENU MENU LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT
+{
+ POPUP "&Ôàéë" {
+  MENUITEM "&Îòêðûòü", MNID_FILE_OPEN
+  MENUITEM SEPARATOR
+  MENUITEM "&Ïå÷àòàòü", MNID_FILE_PRINT
+  MENUITEM "Íàñòðîéêà &ïðèíòåðà...", MNID_FILE_SETUP
+   MENUITEM SEPARATOR
+  MENUITEM "&Âûõîä", MNID_FILE_EXIT
+ }
+ POPUP "&Ïðàâêà" {
+   MENUITEM "&Êîïèðîâàòü...", MNID_EDIT_COPYDLG
+   MENUITEM SEPARATOR
+   MENUITEM "&Çàìåòêè...", MNID_EDIT_ANNOTATE
+ }
+ POPUP "&Çàêëàäêà" {
+   MENUITEM "&Îïðåäåëèòü...", MNID_BKMK_DEFINE
+ }
+ POPUP "&Ñïðàâêà" {
+   MENUITEM "Ïîìîùü &ïî ïîìîùè", MNID_HELP_HELPON
+   MENUITEM "Âñåãäà &ñâåðõó", MNID_HELP_HELPTOP
+   MENUITEM SEPARATOR
+   MENUITEM "&Èíôîðìàöèÿ...", MNID_HELP_ABOUT
+#ifdef WINELIB
+   MENUITEM "&ΠWine", MNID_HELP_WINE
+#endif
+ }
+}
+
+/* Strings */
+STRINGTABLE DISCARDABLE LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT
+{
+STID_WINE_HELP,        "Ñïðàâêà WINE"
+STID_WHERROR,          "ÎØÈÁÊÀ"
+STID_WARNING,                  "ÂÍÈÌÀÍÈÅ"
+STID_INFO,             "Èíôîðìàöèÿ"
+STID_NOT_IMPLEMENTED,  "Íå ðåàëèçîâàííî"
+STID_HLPFILE_ERROR_s,  "Îøèáêà ïðè ÷òåíèè ôàéëà ïîìîùè `%s'"
+STID_CONTENTS,                 "&Ñîäåðæàíèå"
+STID_SEARCH,           "&Íàéòè"
+STID_BACK,             "&Íàçàä"
+STID_HISTORY,          "&Èñòîðèÿ"
+STID_TOPICS,           "&Óêàçàòåëü"
+STID_ALL_FILES,        "Âñå ôàéëû (*.*)"
+STID_HELP_FILES_HLP,   "Ôàéëû ñïðàâêè (*.hlp)"
+STID_FILE_NOT_FOUND_s  "Íå ìîãó íàéòè '%s'. Âû õîòèòå íàéòè ýòîò ôàéë ñàìîñòîÿòåëüíî?"
+}
diff --git a/reactos/base/applications/winhelp/Si.rc b/reactos/base/applications/winhelp/Si.rc
new file mode 100644 (file)
index 0000000..d587908
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * Help Viewer (Slovenian Resources)
+ *
+ * Copyright 2002-2003 Rok Mandeljc <rok.mandeljc@gimb.org>
+ *
+ * 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
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/* Menu */
+
+MAIN_MENU MENU LANGUAGE LANG_SLOVENIAN, SUBLANG_DEFAULT
+{
+ POPUP "&Datoteka" {
+  MENUITEM "&Odpri ...", MNID_FILE_OPEN
+  MENUITEM SEPARATOR
+  MENUITEM "Na&tisni temo ...", MNID_FILE_PRINT
+  MENUITEM "&Priprava tiskalnika", MNID_FILE_SETUP
+  MENUITEM SEPARATOR
+  MENUITEM "Iz&hod", MNID_FILE_EXIT
+ }
+ POPUP "&Urejanje" {
+   MENUITEM "&Kopiraj", MNID_EDIT_COPYDLG
+   MENUITEM SEPARATOR
+   MENUITEM "&Pripombe ...", MNID_EDIT_ANNOTATE
+ }
+ POPUP "&Zaznamek" {
+   MENUITEM "&Doloèi ...", MNID_BKMK_DEFINE
+ }
+ POPUP "&Pomoè" {
+   MENUITEM "&O pomoèi", MNID_HELP_HELPON
+   MENUITEM "Vedno na &vrhu", MNID_HELP_HELPTOP
+   MENUITEM SEPARATOR
+   MENUITEM "&Informacije ...", MNID_HELP_ABOUT
+#ifdef WINELIB
+   MENUITEM "&O WINE", MNID_HELP_WINE
+#endif
+ }
+}
+
+/* Strings */
+STRINGTABLE DISCARDABLE LANGUAGE LANG_SLOVENIAN, SUBLANG_DEFAULT
+{
+STID_WINE_HELP,                "WINE Pomoè"
+STID_WHERROR,          "NAPAKA"
+STID_WARNING,                  "OPOZORILO"
+STID_INFO,                     "Informacija"
+STID_NOT_IMPLEMENTED,  "Ni (\9ae) na voljo"
+STID_HLPFILE_ERROR_s,  "Napaka pri branju datoteke `%s'"
+STID_CONTENTS,                 "&Teme pomoèi"
+STID_SEARCH,           "&Iskanje"
+STID_BACK,                     "&Nazaj"
+STID_HISTORY,          "&Zgodovina"
+STID_TOPICS,           "&Vsebina"
+STID_ALL_FILES,                "Vse datiteke (*.*)"
+STID_HELP_FILES_HLP,   "Datoteke s pomoèjo (*.hlp)"
+STID_FILE_NOT_FOUND_s  "Cannot find '%s'. Do you want to find this file yourself?"
+}
diff --git a/reactos/base/applications/winhelp/Sk.rc b/reactos/base/applications/winhelp/Sk.rc
new file mode 100644 (file)
index 0000000..c8e713f
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * Help Viewer
+ *
+ * Copyright 1996 Ulrich Schmid
+ *
+ * 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
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+MAIN_MENU MENU LANGUAGE LANG_SLOVAK, SUBLANG_DEFAULT
+{
+ POPUP "&Súbor" {
+   MENUITEM "&Otvori\9d...", MNID_FILE_OPEN
+   MENUITEM SEPARATOR
+   MENUITEM "&Tlaèi\9d", MNID_FILE_PRINT
+   MENUITEM "&Nastavenie tlaèe...", MNID_FILE_SETUP
+   MENUITEM "U&konèi\9d", MNID_FILE_EXIT
+ }
+ POPUP "&Upravi\9d" {
+   MENUITEM "Kopí&rova\9d...", MNID_EDIT_COPYDLG
+   MENUITEM SEPARATOR
+   MENUITEM "&Skomentova\9d...", MNID_EDIT_ANNOTATE
+ }
+ POPUP "&Zálo\9eka" {
+   MENUITEM "&Definova\9d...", MNID_BKMK_DEFINE
+ }
+ POPUP "&Pomoc" {
+   MENUITEM "Pomoc &na pomoci", MNID_HELP_HELPON
+   MENUITEM "V\9edy na &vrchu", MNID_HELP_HELPTOP
+   MENUITEM SEPARATOR
+   MENUITEM "&Info...", MNID_HELP_ABOUT
+#ifdef WINELIB
+   MENUITEM "O& WINE", MNID_HELP_WINE
+#endif
+ }
+}
+
+/* Strings */
+STRINGTABLE DISCARDABLE LANGUAGE LANG_SLOVAK, SUBLANG_DEFAULT
+{
+STID_WINE_HELP,             "WINE Pomoc"
+STID_WHERROR,               "CHYBA"
+STID_WARNING,               "VAROVANIE"
+STID_INFO,                  "Informácie"
+STID_NOT_IMPLEMENTED,       "Neimplementované"
+STID_HLPFILE_ERROR_s,       "Chyba poèas èítania súboru `%s'"
+STID_CONTENTS,              "&Obsah"
+STID_SEARCH,                "&H¾ada\9d"
+STID_BACK,                  "&Spä\9d"
+STID_HISTORY,               "&História"
+STID_TOPICS,               "&Topics"
+STID_ALL_FILES,             "V\9aetky súbory (*.*)"
+STID_HELP_FILES_HLP,        "Súbory pomoci (*.hlp)"
+STID_FILE_NOT_FOUND_s       "Cannot find '%s'. Do you want to find this file yourself?"
+}
diff --git a/reactos/base/applications/winhelp/Sw.rc b/reactos/base/applications/winhelp/Sw.rc
new file mode 100644 (file)
index 0000000..84da4f9
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * Help Viewer
+ *
+ * Copyright 1996 Ulrich Schmid
+ * Swedish language by Karl Backström <karl_b@geocities.com>
+ * Copyright 2002 Sylvain Petreolle <spetreolle@yahoo.fr>
+ *
+ * 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
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/* Menu */
+
+MAIN_MENU MENU LANGUAGE LANG_SWEDISH, SUBLANG_DEFAULT
+{
+ POPUP "&Arkiv" {
+  MENUITEM "&Öppna...", MNID_FILE_OPEN
+  MENUITEM SEPARATOR
+  MENUITEM "&Skriv ut", MNID_FILE_PRINT
+  MENUITEM "Skrivar &inställningar...", MNID_FILE_SETUP
+   MENUITEM SEPARATOR
+  MENUITEM "&Avsluta", MNID_FILE_EXIT
+ }
+ POPUP "&Redigera" {
+   MENUITEM "&Kopiera...", MNID_EDIT_COPYDLG
+   MENUITEM SEPARATOR
+   MENUITEM "&Markera...", MNID_EDIT_ANNOTATE
+ }
+ POPUP "&Bokmärke" {
+   MENUITEM "&Defingera...", MNID_BKMK_DEFINE
+ }
+ POPUP "&Hjälp" {
+   MENUITEM "Användningen &av hjälp", MNID_HELP_HELPON
+   MENUITEM "Alltid &överst", MNID_HELP_HELPTOP
+   MENUITEM SEPARATOR
+   MENUITEM "&Information...", MNID_HELP_ABOUT
+#ifdef WINELIB
+   MENUITEM "&Om WINE", MNID_HELP_WINE
+#endif
+ }
+}
+
+/* Strings */
+
+STRINGTABLE DISCARDABLE LANGUAGE LANG_SWEDISH, SUBLANG_DEFAULT
+{
+STID_WINE_HELP,        "WINE Hjälp"
+STID_WHERROR,          "FEL"
+STID_WARNING,                  "VARNING"
+STID_INFO,             "Information"
+STID_NOT_IMPLEMENTED,  "Ej implementererat"
+STID_HLPFILE_ERROR_s,  "FEL vid läsning av hjälp filen `%s'"
+STID_CONTENTS,                 "&Innehåll"
+STID_SEARCH,           "&Sök"
+STID_BACK,             "&Tillbaka"
+STID_HISTORY,          "&Översikt"
+STID_TOPICS,           "T&opics"
+STID_ALL_FILES,        "Alla filer (*.*))"
+STID_HELP_FILES_HLP,   "Hjälp filer (*.hlp)"
+STID_FILE_NOT_FOUND_s  "Cannot find '%s'. Do you want to find this file yourself?"
+}
diff --git a/reactos/base/applications/winhelp/Tr.rc b/reactos/base/applications/winhelp/Tr.rc
new file mode 100644 (file)
index 0000000..9578e8b
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * Turkish Resources for Help Viewer
+ *
+ * Copyright 2006 Fatih Aþýcý <fasici@linux-sevenler.org>
+ *
+ * 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
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/* Menu */
+
+MAIN_MENU MENU LANGUAGE LANG_TURKISH, SUBLANG_DEFAULT
+{
+ POPUP "&Dosya" {
+  MENUITEM "&Aç", MNID_FILE_OPEN
+  MENUITEM SEPARATOR
+  MENUITEM "Ya&zdýr", MNID_FILE_PRINT
+  MENUITEM "&Yazýcý ayarlarý...", MNID_FILE_SETUP
+   MENUITEM SEPARATOR
+  MENUITEM "&Çýkýþ", MNID_FILE_EXIT
+ }
+ POPUP "Dü&zen" {
+   MENUITEM "K&opyala...", MNID_EDIT_COPYDLG
+   MENUITEM SEPARATOR
+   MENUITEM "&Annotate...", MNID_EDIT_ANNOTATE
+ }
+ POPUP "Yer Ý&mleri" {
+   MENUITEM "&Tanýmla...", MNID_BKMK_DEFINE
+ }
+ POPUP "&Yardým" {
+   MENUITEM "&Yardým Kullanýmý", MNID_HELP_HELPON
+   MENUITEM "&Her Zaman Üstte", MNID_HELP_HELPTOP
+   MENUITEM SEPARATOR
+   MENUITEM "&Bilgi...", MNID_HELP_ABOUT
+#ifdef WINELIB
+   MENUITEM "WINE &Hakkýnda", MNID_HELP_WINE
+#endif
+ }
+}
+
+/* Strings */
+STRINGTABLE DISCARDABLE LANGUAGE LANG_TURKISH, SUBLANG_DEFAULT
+{
+STID_WINE_HELP,        "WINE Yardým"
+STID_WHERROR,          "HATA"
+STID_WARNING,                  "UYARI"
+STID_INFO,             "Bilgi"
+STID_NOT_IMPLEMENTED,  "Henüz tamamlanmadý"
+STID_HLPFILE_ERROR_s,  "'%s' yardým dosyasý açýlýrken hata"
+STID_CONTENTS,                 "&Ýçindekiler"
+STID_SEARCH,           "&Ara"
+STID_BACK,             "&Geri"
+STID_HISTORY,          "Ge&çmiþ"
+STID_TOPICS,           "&Konular"
+STID_ALL_FILES,        "Tüm dosyalar (*.*)"
+STID_HELP_FILES_HLP,   "Yardým dosyalarý (*.hlp)"
+STID_FILE_NOT_FOUND_s  "Cannot find '%s'. Do you want to find this file yourself?"
+}
diff --git a/reactos/base/applications/winhelp/Va.rc b/reactos/base/applications/winhelp/Va.rc
new file mode 100644 (file)
index 0000000..647c9df
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * Help Viewer
+ *
+ * Copyright 1996 Ulrich Schmid
+ * Rumantsch Ladin (Vallader) by mbaur@g26.ethz.ch
+ * Copyright 2002 Sylvain Petreolle <spetreolle@yahoo.fr>
+ *
+ * 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
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/* Menu */
+
+/*
+*  language : switzerland romanch
+*  not supported today
+*/
+MAIN_MENU MENU LANGUAGE LANG_, SUBLANG_DEFAULT
+{
+ POPUP "&Datoteca" {
+  MENUITEM "&Rivir", MNID_FILE_OPEN
+  MENUITEM SEPARATOR
+  MENUITEM "&Stampar tema", MNID_FILE_PRINT
+  MENUITEM "&Installaziun dal stampader...", MNID_FILE_SETUP
+   MENUITEM SEPARATOR
+  MENUITEM "&Finir", MNID_FILE_EXIT
+ }
+ POPUP "&Lavurar" {
+   MENUITEM "Capchar", MNID_EDIT_COPYDLG
+   MENUITEM SEPARATOR
+   MENUITEM "&Annotaziun...", MNID_EDIT_ANNOTATE
+ }
+ POPUP "&Marca" {
+   MENUITEM "&Definir...", MNID_BKMK_DEFINE
+ }
+ POPUP "&Agüd" {
+   MENUITEM "&Douvrar l'agüd", MNID_HELP_HELPON
+   MENUITEM "Adüna da&vant", MNID_HELP_HELPTOP
+   MENUITEM SEPARATOR
+   MENUITEM "I&nfuormaziuns", MNID_HELP_ABOUT
+#ifdef WINELIB
+   MENUITEM "Davart &WINE", MNID_HELP_WINE
+#endif
+ }
+}
+
+/* Strings */
+
+STRINGTABLE DISCARDABLE LANGUAGE LANG_FRENCH, SUBLANG_DEFAULT
+{
+WINE_HELP,             "WINE agüd"
+WHERROR,               "SBAGL"
+WARNING,               "ATTENZIUN"
+INFO,                          "INFUORMAZIUN"
+NOT_IMPLEMENTED,       "Na implementa"
+HLPFILE_ERROR_s,       "Sbagl cun leger la datoteca d'agüd `%s'"
+CONTENTS,              "&Cuntgnü"
+SEARCH,                "&Tscherchar"
+BACK,                  "&Inavo"
+HISTORY,               "&Fin qua"
+TOPICS,                        "T&opics"
+ALL_FILES,             "Tuot las datotecas (*.*)"
+HELP_FILES_HLP,        "Datotecas d'agüd (*.hlp)"
+STID_FILE_NOT_FOUND_s   "Cannot find '%s'. Do you want to find this file yourself?"
+}
diff --git a/reactos/base/applications/winhelp/Wa.rc b/reactos/base/applications/winhelp/Wa.rc
new file mode 100644 (file)
index 0000000..c536d2a
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * Help Viewer
+ *
+ * Copyright 1996 Ulrich Schmid
+ * Copyright 1999 Pablo Saratxaga
+ * Copyright 2002 Sylvain Petreolle <spetreolle@yahoo.fr>
+ *
+ * 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
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifdef LANG_WALON
+
+/* Menu */
+
+MAIN_MENU MENU LANGUAGE LANG_WALON, SUBLANG_DEFAULT
+{
+ POPUP "&Fitchî" {
+  MENUITEM "&Drovî...", MNID_FILE_OPEN
+  MENUITEM SEPARATOR
+  MENUITEM "&Rexhe", MNID_FILE_PRINT
+  MENUITEM "&Apontiaedje del scrirece...", MNID_FILE_SETUP
+   MENUITEM SEPARATOR
+  MENUITEM "Moussî &Foû", MNID_FILE_EXIT
+ }
+ POPUP "&Candjî" {
+   MENUITEM "&Copyî...", MNID_EDIT_COPYDLG
+   MENUITEM SEPARATOR
+   MENUITEM "&Sicrîre...", MNID_EDIT_ANNOTATE
+ }
+ POPUP "&Rimårkes" {
+   MENUITEM "&Defini...", MNID_BKMK_DEFINE
+ }
+ POPUP "&Aide" {
+   MENUITEM "&Aide so l' Aide", MNID_HELP_HELPON
+   MENUITEM "Todi &Visibe", MNID_HELP_HELPTOP
+   MENUITEM SEPARATOR
+   MENUITEM "&Informåcion...", MNID_HELP_ABOUT
+#ifdef WINELIB
+   MENUITEM "Å &dfait di WINEE", MNID_HELP_WINE
+#endif
+ }
+}
+
+/* Strings */
+
+STRINGTABLE DISCARDABLE LANGUAGE LANG_WALON, SUBLANG_DEFAULT
+{
+STID_WINE_HELP,        "Aidance di WINE"
+STID_WHERROR,          "AROKE"
+STID_WARNING,                  "ADVERTIXHMINT"
+STID_INFO,             "Informåcion"
+STID_NOT_IMPLEMENTED,  "Nén co possibe"
+STID_HLPFILE_ERROR_s,  "Yåk n' a nén stî å moumint di lere li fitchî d' aide `%s'"
+STID_CONTENTS,                 "Å&dvins"
+STID_SEARCH,           "C&werî"
+STID_BACK,             "Èn &Erî"
+STID_HISTORY,          "&Istwere"
+STID_TOPICS,           "&Topics"
+STID_ALL_FILES,        "Tos les fitchîs (*.*)"
+STID_HELP_FILES_HLP,   "Fitchîs d' aide (*.hlp)"
+STID_FILE_NOT_FOUND_s  "Cannot find '%s'. Do you want to find this file yourself?"
+}
+
+#endif  /* LANG_WALON */
diff --git a/reactos/base/applications/winhelp/Zh.rc b/reactos/base/applications/winhelp/Zh.rc
new file mode 100644 (file)
index 0000000..8c0689b
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * Help Viewer
+ * Simplified Chinese Language Support
+ *
+ * Copyright 2002 liuspider <liuspider@yahoo.com>
+ *
+ * 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
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/* Menu */
+
+MAIN_MENU MENU LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED
+{
+ POPUP "Îļþ£¨&F£©" {
+  MENUITEM "´ò¿ª£¨&O£©", MNID_FILE_OPEN
+  MENUITEM SEPARATOR
+  MENUITEM "´òÓ¡£¨&P£©", MNID_FILE_PRINT
+  MENUITEM "´òÓ¡»úÉèÖã¨&S£©...", MNID_FILE_SETUP
+   MENUITEM SEPARATOR
+  MENUITEM "Í˳ö£¨&E£©", MNID_FILE_EXIT
+ }
+ POPUP "±à¼­£¨&E£©" {
+   MENUITEM "¸´ÖÆ£¨&C£©...", MNID_EDIT_COPYDLG
+   MENUITEM SEPARATOR
+   MENUITEM "×¢ÊÍ£¨&A£©...", MNID_EDIT_ANNOTATE
+ }
+ POPUP "ÊéÇ©£¨&B£©" {
+   MENUITEM "¶¨Ò壨&D£©...", MNID_BKMK_DEFINE
+ }
+ POPUP "°ïÖú£¨&H£©" {
+   MENUITEM "ÈçºÎʹÓðïÖú£¨&O£©", MNID_HELP_HELPON
+   MENUITEM "×ÜÊÇÔÚ×îÇ°Ã棨&T£©", MNID_HELP_HELPTOP
+   MENUITEM SEPARATOR
+   MENUITEM "×ÊÁÏÐÅÏ¢£¨&I£©...", MNID_HELP_ABOUT
+#ifdef WINELIB
+   MENUITEM "¹ØÓÚ WINE£¨&A£©", MNID_HELP_WINE
+#endif
+ }
+}
+
+/* Strings */
+STRINGTABLE DISCARDABLE LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED
+{
+STID_WINE_HELP,        "WINE °ïÖú"
+STID_WHERROR,          "´íÎó"
+STID_WARNING,                  "¾¯¸æ"
+STID_INFO,             "ÐÅÏ¢"
+STID_NOT_IMPLEMENTED,  "δʵÏÖ"
+STID_HLPFILE_ERROR_s,  "¶ÁÈë°ïÖúÎļþ ¡®%s¡¯ Ê±·¢Éú´íÎó"
+STID_CONTENTS,                 "ÄÚÈÝ£¨&C£©"
+STID_SEARCH,           "ËÑË÷£¨&S£©"
+STID_BACK,             "·µ»Ø£¨&B£©"
+STID_HISTORY,          "ÀúÊ·£¨&H£©"
+STID_TOPICS,           "Ö÷Ì⣨&T£©"
+STID_ALL_FILES,        "ËùÓÐÎļþ (*.*)"
+STID_HELP_FILES_HLP,   "°ïÖúÎļþ (*.hlp)"
+STID_FILE_NOT_FOUND_s  "Cannot find '%s'. Do you want to find this file yourself?"
+}
diff --git a/reactos/base/applications/winhelp/callback.c b/reactos/base/applications/winhelp/callback.c
new file mode 100644 (file)
index 0000000..b966039
--- /dev/null
@@ -0,0 +1,180 @@
+/*
+ * Help Viewer - DLL callback into WineHelp
+ *
+ * Copyright 2004 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
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#define WIN32_LEAN_AND_MEAN
+
+#include <stdio.h>
+
+#include "windows.h"
+#include "winhelp.h"
+
+#include "wine/debug.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(winhelp);
+
+static WORD CALLBACK WHD_GetFSError(void)
+{
+    WINE_FIXME("()\n");
+    return 0;
+}
+
+static HANDLE CALLBACK WHD_Open(LPSTR name, BYTE flags)
+{
+    unsigned    mode = 0;
+
+    //WINE_FIXME("(%s %x)\n", wine_dbgstr_a(name), flags);
+    switch (flags)
+    {
+    case 0: mode = GENERIC_READ | GENERIC_WRITE; break;
+    case 2: mode = GENERIC_READ; break;
+    default: WINE_FIXME("Undocumented flags %x\n", flags);
+    }
+    return CreateFile(name, mode, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
+                      OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+}
+
+static WORD CALLBACK WHD_Close(HANDLE fs)
+{
+    WINE_FIXME("(%p)\n", fs);
+    CloseHandle(fs);
+    return 0;
+}
+
+static HANDLE CALLBACK WHD_OpenBag(HANDLE fs, LPSTR name, BYTE flags)
+{
+    WINE_FIXME("(%p %s %x)\n", fs, name, flags);
+    return NULL;
+}
+
+static HANDLE CALLBACK WHD_CloseBag(HANDLE bag)
+{
+    WINE_FIXME("()\n");
+    return NULL;
+}
+
+static LONG CALLBACK WHD_ReadBag(HANDLE bag, BYTE* ptr, LONG len)
+{
+    WINE_FIXME("()\n");
+    return 0;
+}
+
+static LONG CALLBACK WHD_TellBag(HANDLE bag)
+{
+    WINE_FIXME("()\n");
+    return 0;
+}
+
+static LONG CALLBACK WHD_SeekBag(HANDLE bag, LONG offset, WORD whence)
+{
+    WINE_FIXME("()\n");
+    return 0;
+}
+
+static BOOL CALLBACK WHD_IsEofBag(HANDLE bag)
+{
+    WINE_FIXME("()\n");
+    return FALSE;
+}
+
+static LONG CALLBACK WHD_SizeBag(HANDLE bag)
+{
+    WINE_FIXME("()\n");
+    return 0;
+}
+
+static BOOL CALLBACK WHD_Access(HANDLE fs, LPSTR name, BYTE flags)
+{
+    WINE_FIXME("()\n");
+    return FALSE;
+}
+
+static WORD CALLBACK WHD_LLInfoFromBag(HANDLE bag, WORD opt, LPWORD p1, LPLONG p2, LPLONG p3)
+{
+    WINE_FIXME("()\n");
+    return 0;
+}
+
+static WORD CALLBACK WHD_LLInfoFromFile(HANDLE fs, LPSTR name, WORD opt, LPWORD p1, LPLONG p2, LPLONG p3)
+{
+    WINE_FIXME("()\n");
+    return 0;
+}
+
+static void CALLBACK WHD_Error(int err)
+{
+    WINE_FIXME("()\n");
+}
+
+static void CALLBACK WHD_ErrorString(LPSTR err)
+{
+    WINE_FIXME("()\n");
+}
+
+static LONG CALLBACK WHD_GetInfo(WORD what, HWND hnd)
+{
+    LONG        ret = 0;
+
+    WINE_TRACE("(%x %p)\n", what, hnd);
+    switch (what)
+    {
+    case 0: break;
+    case 1: /* instance */ ret = (LONG)Globals.hInstance; break;
+    case 3: /* current window */ ret = (LONG)Globals.active_win->hMainWnd; break;
+    case 2: /* main window */
+    case 4: /* handle to opened file */
+    case 5: /* foreground color */
+    case 6: /* background color */
+    case 7: /* topic number */
+    case 8: /* current opened file name */
+        WINE_FIXME("NIY %u\n", what);
+        break;
+    default:
+        WINE_FIXME("Undocumented %u\n", what);
+        break;
+    }
+    return ret;
+}
+
+static LONG CALLBACK WHD_API(LPSTR x, WORD xx, DWORD xxx)
+{
+    WINE_FIXME("()\n");
+    return 0;
+}
+
+FARPROC Callbacks[] =
+{
+    (FARPROC)WHD_GetFSError, 
+    (FARPROC)WHD_Open, 
+    (FARPROC)WHD_Close, 
+    (FARPROC)WHD_OpenBag, 
+    (FARPROC)WHD_CloseBag,
+    (FARPROC)WHD_ReadBag,
+    (FARPROC)WHD_TellBag,
+    (FARPROC)WHD_SeekBag,
+    (FARPROC)WHD_IsEofBag, 
+    (FARPROC)WHD_SizeBag,
+    (FARPROC)WHD_Access,
+    (FARPROC)WHD_LLInfoFromBag, 
+    (FARPROC)WHD_LLInfoFromFile, 
+    (FARPROC)WHD_Error,
+    (FARPROC)WHD_ErrorString,
+    (FARPROC)WHD_GetInfo,
+    (FARPROC)WHD_API
+};
diff --git a/reactos/base/applications/winhelp/hlpfile.c b/reactos/base/applications/winhelp/hlpfile.c
new file mode 100644 (file)
index 0000000..c6ff1b5
--- /dev/null
@@ -0,0 +1,2065 @@
+/*
+ * Help Viewer
+ *
+ * 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
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "windef.h"
+#include "winbase.h"
+#include "wingdi.h"
+#include "winuser.h"
+#include "winhelp.h"
+
+#include "wine/debug.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(winhelp);
+
+static inline unsigned short GET_USHORT(const BYTE* buffer, unsigned i)
+{
+    return (BYTE)buffer[i] + 0x100 * (BYTE)buffer[i + 1];
+}
+
+static inline short GET_SHORT(const BYTE* buffer, unsigned i)
+{
+    return (BYTE)buffer[i] + 0x100 * (signed char)buffer[i+1];
+}
+
+static inline unsigned GET_UINT(const BYTE* buffer, unsigned i)
+{
+    return GET_USHORT(buffer, i) + 0x10000 * GET_USHORT(buffer, i + 2);
+}
+
+static HLPFILE *first_hlpfile = 0;
+static BYTE    *file_buffer;
+
+static struct
+{
+    UINT        num;
+    unsigned*   offsets;
+    char*       buffer;
+} phrases;
+
+static struct
+{
+    BYTE**      map;
+    BYTE*       end;
+    UINT        wMapLen;
+} topic;
+
+static struct
+{
+    UINT                wFont;
+    UINT                wIndent;
+    UINT                wHSpace;
+    UINT                wVSpace;
+    HLPFILE_LINK*       link;
+} 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_Uncompress_Topic(HLPFILE*);
+static BOOL  HLPFILE_GetContext(HLPFILE*);
+static BOOL  HLPFILE_GetMap(HLPFILE*);
+static BOOL  HLPFILE_AddPage(HLPFILE*, BYTE*, BYTE*, unsigned);
+static BOOL  HLPFILE_AddParagraph(HLPFILE*, BYTE *, BYTE*, unsigned*);
+static void  HLPFILE_Uncompress2(const BYTE*, const BYTE*, BYTE*, const BYTE*);
+static BOOL  HLPFILE_Uncompress3(char*, const char*, const BYTE*, const BYTE*);
+static void  HLPFILE_UncompressRLE(const BYTE* src, const BYTE* end, BYTE** dst, unsigned dstsz);
+static BOOL  HLPFILE_ReadFont(HLPFILE* hlpfile);
+
+#if 0
+/***********************************************************************
+ *
+ *           HLPFILE_PageByNumber
+ */
+static HLPFILE_PAGE *HLPFILE_PageByNumber(LPCSTR lpszPath, UINT wNum)
+{
+    HLPFILE_PAGE *page;
+    HLPFILE *hlpfile = HLPFILE_ReadHlpFile(lpszPath);
+
+    if (!hlpfile) return 0;
+
+    WINE_TRACE("[%s/%u]\n", lpszPath, wNum);
+
+    for (page = hlpfile->first_page; page && wNum; page = page->next) wNum--;
+
+    /* HLPFILE_FreeHlpFile(lpszPath); */
+
+    return page;
+}
+#endif
+
+/* FIXME:
+ * this finds the page containing the offset. The offset can either
+ * refer to the top of the page (offset == page->offset), or
+ * to some paragraph inside the page...
+ * As of today, we only return the page... we should also return
+ * a paragraph, and then, while opening a new page, compute the
+ * y-offset of the paragraph to be shown and scroll the window
+ * accordinly
+ */
+/******************************************************************
+ *             HLPFILE_PageByOffset
+ *
+ *
+ */
+HLPFILE_PAGE *HLPFILE_PageByOffset(HLPFILE* hlpfile, LONG offset)
+{
+    HLPFILE_PAGE*       page;
+    HLPFILE_PAGE*       found;
+
+    if (!hlpfile) return 0;
+
+    WINE_TRACE("<%s>[%x]\n", hlpfile->lpszPath, offset);
+
+    if (offset == 0xFFFFFFFF) return NULL;
+    page = NULL;
+
+    for (found = NULL, page = hlpfile->first_page; page; page = page->next)
+    {
+        if (page->offset <= offset && (!found || found->offset < page->offset))
+            found = page;
+    }
+    if (!found)
+        WINE_ERR("Page of offset %u not found in file %s\n",
+                 offset, hlpfile->lpszPath);
+    return found;
+}
+
+/***********************************************************************
+ *
+ *           HLPFILE_HlpFilePageByHash
+ */
+HLPFILE_PAGE *HLPFILE_PageByHash(HLPFILE* hlpfile, LONG lHash)
+{
+    int                 i;
+
+    if (!hlpfile) return 0;
+
+    WINE_TRACE("<%s>[%x]\n", hlpfile->lpszPath, lHash);
+
+    for (i = 0; i < hlpfile->wContextLen; i++)
+    {
+        if (hlpfile->Context[i].lHash == lHash)
+            return HLPFILE_PageByOffset(hlpfile, hlpfile->Context[i].offset);
+    }
+
+    WINE_ERR("Page of hash %x not found in file %s\n", lHash, hlpfile->lpszPath);
+    return NULL;
+}
+
+/***********************************************************************
+ *
+ *           HLPFILE_PageByMap
+ */
+HLPFILE_PAGE *HLPFILE_PageByMap(HLPFILE* hlpfile, LONG lMap)
+{
+    int                 i;
+
+    if (!hlpfile) return 0;
+
+    WINE_TRACE("<%s>[%x]\n", hlpfile->lpszPath, lMap);
+
+    for (i = 0; i < hlpfile->wMapLen; i++)
+    {
+        if (hlpfile->Map[i].lMap == lMap)
+            return HLPFILE_PageByOffset(hlpfile, hlpfile->Map[i].offset);
+    }
+
+    WINE_ERR("Page of Map %x not found in file %s\n", lMap, hlpfile->lpszPath);
+    return NULL;
+}
+
+/***********************************************************************
+ *
+ *           HLPFILE_Contents
+ */
+HLPFILE_PAGE* HLPFILE_Contents(HLPFILE *hlpfile)
+{
+    HLPFILE_PAGE*       page = NULL;
+
+    if (!hlpfile) return NULL;
+
+    page = HLPFILE_PageByOffset(hlpfile, hlpfile->contents_start);
+    if (!page) page = hlpfile->first_page;
+    return page;
+}
+
+/***********************************************************************
+ *
+ *           HLPFILE_Hash
+ */
+LONG HLPFILE_Hash(LPCSTR lpszContext)
+{
+    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)
+{
+    HLPFILE*      hlpfile;
+
+    for (hlpfile = first_hlpfile; hlpfile; hlpfile = hlpfile->next)
+    {
+        if (!strcmp(lpszPath, hlpfile->lpszPath))
+        {
+            hlpfile->wRefCount++;
+            return hlpfile;
+        }
+    }
+
+    hlpfile = HeapAlloc(GetProcessHeap(), 0, sizeof(HLPFILE) + lstrlen(lpszPath) + 1);
+    if (!hlpfile) return 0;
+
+    hlpfile->lpszPath           = (char*)hlpfile + sizeof(HLPFILE);
+    hlpfile->lpszTitle          = NULL;
+    hlpfile->lpszCopyright      = NULL;
+    hlpfile->first_page         = NULL;
+    hlpfile->first_macro        = NULL;
+    hlpfile->wContextLen        = 0;
+    hlpfile->Context            = NULL;
+    hlpfile->wMapLen            = 0;
+    hlpfile->Map                = NULL;
+    hlpfile->contents_start     = 0xFFFFFFFF;
+    hlpfile->prev               = NULL;
+    hlpfile->next               = first_hlpfile;
+    hlpfile->wRefCount          = 1;
+
+    hlpfile->numBmps            = 0;
+    hlpfile->bmps               = NULL;
+
+    hlpfile->numFonts           = 0;
+    hlpfile->fonts              = NULL;
+
+    hlpfile->numWindows         = 0;
+    hlpfile->windows            = 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;
+    }
+
+    HeapFree(GetProcessHeap(), 0, phrases.offsets);
+    HeapFree(GetProcessHeap(), 0, phrases.buffer);
+    HeapFree(GetProcessHeap(), 0, topic.map);
+    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;
+    DWORD       ref = 0x0C;
+    unsigned    index, old_index, offset, len, offs;
+
+    hFile = OpenFile(lpszPath, &ofs, OF_READ);
+    if (hFile == HFILE_ERROR) return FALSE;
+
+    ret = HLPFILE_ReadFileToBuffer(hFile);
+    _lclose(hFile);
+    if (!ret) return FALSE;
+
+    if (!HLPFILE_SystemCommands(hlpfile)) return FALSE;
+
+    /* load phrases support */
+    if (!HLPFILE_UncompressLZ77_Phrases(hlpfile))
+        HLPFILE_Uncompress_Phrases40(hlpfile);
+
+    if (!HLPFILE_Uncompress_Topic(hlpfile)) return FALSE;
+    if (!HLPFILE_ReadFont(hlpfile)) return FALSE;
+
+    buf = topic.map[0];
+    old_index = -1;
+    offs = 0;
+    do
+    {
+        BYTE*   end;
+
+        /* FIXME this depends on the blocksize, can be 2k in some cases */
+        index  = (ref - 0x0C) >> 14;
+        offset = (ref - 0x0C) & 0x3fff;
+
+        WINE_TRACE("ref=%08x => [%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, index * 0x8000L + offs)) return FALSE;
+            break;
+
+       case 0x20:
+            if (!HLPFILE_AddParagraph(hlpfile, buf, end, &len)) return FALSE;
+            offs += len;
+            break;
+
+       case 0x23:
+            if (!HLPFILE_AddParagraph(hlpfile, buf, end, &len)) return FALSE;
+            offs += len;
+            break;
+
+       default:
+            WINE_ERR("buf[0x14] = %x\n", buf[0x14]);
+       }
+
+        ref = GET_UINT(buf, 0xc);
+    } while (ref != 0xffffffff);
+
+    HLPFILE_GetMap(hlpfile);
+    return HLPFILE_GetContext(hlpfile);
+}
+
+/***********************************************************************
+ *
+ *           HLPFILE_AddPage
+ */
+static BOOL HLPFILE_AddPage(HLPFILE *hlpfile, BYTE *buf, BYTE *end, unsigned offset)
+{
+    HLPFILE_PAGE* page;
+    BYTE*         title;
+    UINT          titlesize;
+    char*         ptr;
+    HLPFILE_MACRO*macro;
+
+    if (buf + 0x31 > end) {WINE_WARN("page1\n"); return FALSE;};
+    title = buf + GET_UINT(buf, 0x10);
+    if (title > end) {WINE_WARN("page2\n"); return FALSE;};
+
+    titlesize = GET_UINT(buf, 4);
+    page = HeapAlloc(GetProcessHeap(), 0, sizeof(HLPFILE_PAGE) + titlesize + 1);
+    if (!page) return FALSE;
+    page->lpszTitle = (char*)page + sizeof(HLPFILE_PAGE);
+
+    if (hlpfile->hasPhrases)
+    {
+        HLPFILE_Uncompress2(title, end, (BYTE*)page->lpszTitle, (BYTE*)page->lpszTitle + titlesize);
+    }
+    else
+    {
+        if (GET_UINT(buf, 0x4) > GET_UINT(buf, 0) - GET_UINT(buf, 0x10))
+        {
+            /* need to decompress */
+            HLPFILE_Uncompress3(page->lpszTitle, page->lpszTitle + titlesize, 
+                                title, end);
+        }
+        else
+        {
+            memcpy(page->lpszTitle, title, titlesize);
+        }
+    }
+
+    page->lpszTitle[titlesize] = '\0';
+
+    if (hlpfile->first_page)
+    {
+        HLPFILE_PAGE  *p;
+
+        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->first_macro     = NULL;
+    page->wNumber         = GET_UINT(buf, 0x21);
+    page->offset          = offset;
+
+    page->browse_bwd = GET_UINT(buf, 0x19);
+    page->browse_fwd = GET_UINT(buf, 0x1D);
+
+    WINE_TRACE("Added page[%d]: title='%s' %08x << %08x >> %08x\n",
+               page->wNumber, page->lpszTitle, 
+               page->browse_bwd, page->offset, page->browse_fwd);
+
+    memset(&attributes, 0, sizeof(attributes));
+
+    /* now load macros */
+    ptr = page->lpszTitle + strlen(page->lpszTitle) + 1;
+    while (ptr < page->lpszTitle + titlesize)
+    {
+        unsigned len = strlen(ptr);
+        char*    macro_str;
+
+        WINE_TRACE("macro: %s\n", ptr);
+        macro = HeapAlloc(GetProcessHeap(), 0, sizeof(HLPFILE_MACRO) + len + 1);
+        macro->lpszMacro = macro_str = (char*)(macro + 1);
+        memcpy(macro_str, ptr, len + 1);
+        /* FIXME: shall we really link macro in reverse order ??
+         * may produce strange results when played at page opening
+         */
+        macro->next = page->first_macro;
+        page->first_macro = macro;
+        ptr += len + 1;
+    }
+
+    return TRUE;
+}
+
+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_DecompressGfx
+ *
+ * Decompress the data part of a bitmap or a metafile
+ */
+static BYTE*    HLPFILE_DecompressGfx(BYTE* src, unsigned csz, unsigned sz, BYTE packing)
+{
+    BYTE*       dst;
+    BYTE*       tmp;
+    BYTE*       tmp2;
+    unsigned    sz77;
+
+    WINE_TRACE("Unpacking (%d) from %u bytes to %u bytes\n", packing, csz, sz);
+
+    switch (packing)
+    {
+    case 0: /* uncompressed */
+        if (sz != csz)
+            WINE_WARN("Bogus gfx sizes (uncompressed): %u / %u\n", sz, csz);
+        dst = src;
+        break;
+    case 1: /* RunLen */
+        tmp = dst = HeapAlloc(GetProcessHeap(), 0, sz);
+        if (!dst) return NULL;
+        HLPFILE_UncompressRLE(src, src + csz, &tmp, sz);
+        if (tmp - dst != sz)
+            WINE_WARN("Bogus gfx sizes (RunLen): %u/%u\n", tmp - dst, sz);
+        break;
+    case 2: /* LZ77 */
+        sz77 = HLPFILE_UncompressedLZ77_Size(src, src + csz);
+        dst = HeapAlloc(GetProcessHeap(), 0, sz77);
+        if (!dst) return NULL;
+        HLPFILE_UncompressLZ77(src, src + csz, dst);
+        if (sz77 != sz)
+            WINE_WARN("Bogus gfx sizes (LZ77): %u / %u\n", sz77, sz);
+        break;
+    case 3: /* LZ77 then RLE */
+        sz77 = HLPFILE_UncompressedLZ77_Size(src, src + csz);
+        tmp = HeapAlloc(GetProcessHeap(), 0, sz77);
+        if (!tmp) return FALSE;
+        HLPFILE_UncompressLZ77(src, src + csz, tmp);
+        dst = tmp2 = HeapAlloc(GetProcessHeap(), 0, sz);
+        if (!dst) return FALSE;
+        HLPFILE_UncompressRLE(tmp, tmp + sz77, &tmp2, sz);
+        if (tmp2 - dst != sz)
+            WINE_WARN("Bogus gfx sizes (LZ77+RunLen): %u / %u\n", tmp2 - dst, sz);
+        HeapFree(GetProcessHeap(), 0, tmp);
+        break;
+    default:
+        WINE_FIXME("Unsupported packing %u\n", packing);
+        return NULL;
+    }
+    return dst;
+}
+
+/******************************************************************
+ *             HLPFILE_LoadBitmap
+ *
+ *
+ */
+static BOOL HLPFILE_LoadBitmap(BYTE* beg, BYTE type, BYTE pack, 
+                               HLPFILE_PARAGRAPH* paragraph)
+{
+    BYTE*               ptr;
+    BYTE*               pict_beg;
+    BITMAPINFO*         bi;
+    unsigned long       off, csz;
+    HDC                 hdc;
+
+    bi = HeapAlloc(GetProcessHeap(), 0, sizeof(*bi));
+    if (!bi) return FALSE;
+
+    ptr = beg + 2; /* for type and pack */
+
+    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);
+    bi->bmiHeader.biSizeImage = (((bi->bmiHeader.biWidth * bi->bmiHeader.biBitCount + 31) & ~31) / 8) * bi->bmiHeader.biHeight;
+    WINE_TRACE("planes=%d bc=%d size=(%d,%d)\n",
+               bi->bmiHeader.biPlanes, bi->bmiHeader.biBitCount, 
+               bi->bmiHeader.biWidth, bi->bmiHeader.biHeight);
+
+    csz = fetch_ulong(&ptr);
+    fetch_ulong(&ptr); /* hotspot size */
+
+    off = GET_UINT(ptr, 0);     ptr += 4;
+    /* GET_UINT(ptr, 0); hotspot offset */ ptr += 4;
+    
+    /* now read palette info */
+    if (type == 0x06)
+    {
+        unsigned nc = bi->bmiHeader.biClrUsed;
+        unsigned i;
+        
+        /* not quite right, especially for bitfields type of compression */
+        if (!nc && bi->bmiHeader.biBitCount <= 8)
+            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;
+        }
+    }
+    pict_beg = HLPFILE_DecompressGfx(beg + off, csz, bi->bmiHeader.biSizeImage, pack);
+    
+    paragraph->u.gfx.u.bmp.hBitmap = CreateDIBitmap(hdc = GetDC(0), &bi->bmiHeader, 
+                                                    CBM_INIT, pict_beg, 
+                                                    bi, DIB_RGB_COLORS);
+    ReleaseDC(0, hdc);      
+    if (!paragraph->u.gfx.u.bmp.hBitmap)
+        WINE_ERR("Couldn't create bitmap\n");
+    
+    HeapFree(GetProcessHeap(), 0, bi);
+    if (pict_beg != beg + off) HeapFree(GetProcessHeap(), 0, pict_beg);
+
+    return TRUE;
+}
+
+/******************************************************************
+ *             HLPFILE_LoadMetaFile
+ *
+ *
+ */
+static BOOL     HLPFILE_LoadMetaFile(BYTE* beg, BYTE pack, HLPFILE_PARAGRAPH* paragraph)
+{
+    BYTE*               ptr;
+    unsigned long       size, csize;
+    unsigned long       off, hsoff;
+    BYTE*               bits;
+    LPMETAFILEPICT      lpmfp;
+
+    WINE_TRACE("Loading metafile\n");
+
+    ptr = beg + 2; /* for type and pack */
+
+    lpmfp = &paragraph->u.gfx.u.mfp;
+    lpmfp->mm = fetch_ushort(&ptr); /* mapping mode */
+
+    lpmfp->xExt = GET_USHORT(ptr, 0);
+    lpmfp->yExt = GET_USHORT(ptr, 2);
+    ptr += 4;
+
+    size = fetch_ulong(&ptr); /* decompressed size */
+    csize = fetch_ulong(&ptr); /* compressed size */
+    fetch_ulong(&ptr); /* hotspot size */
+    off = GET_UINT(ptr, 0);
+    hsoff = GET_UINT(ptr, 4);
+    ptr += 8;
+
+    WINE_TRACE("sz=%lu csz=%lu (%d,%d) offs=%lu/%u,%lu\n",
+               size, csize, lpmfp->xExt, lpmfp->yExt, off, ptr - beg, hsoff);
+
+    bits = HLPFILE_DecompressGfx(beg + off, csize, size, pack);
+    if (!bits) return FALSE;
+
+    paragraph->cookie = para_metafile;
+
+    lpmfp->hMF = SetMetaFileBitsEx(size, bits);
+
+    if (!lpmfp->hMF)
+        WINE_FIXME("Couldn't load metafile\n");
+
+    if (bits != beg + off) HeapFree(GetProcessHeap(), 0, bits);
+
+    return TRUE;
+}
+
+/******************************************************************
+ *             HLPFILE_LoadGfxByAddr
+ *
+ *
+ */
+static  BOOL    HLPFILE_LoadGfxByAddr(HLPFILE *hlpfile, BYTE* ref,
+                                      unsigned long size, 
+                                      HLPFILE_PARAGRAPH* paragraph)
+{
+    unsigned    i, numpict;
+
+    numpict = GET_USHORT(ref, 2);
+    WINE_TRACE("Got picture magic=%04x #=%d\n", 
+               GET_USHORT(ref, 0), numpict);
+
+    for (i = 0; i < numpict; i++)
+    {
+        BYTE*   beg;
+        BYTE*   ptr;
+        BYTE    type, pack;
+
+        WINE_TRACE("Offset[%d] = %x\n", i, GET_UINT(ref, (1 + i) * 4));
+        beg = ptr = ref + GET_UINT(ref, (1 + i) * 4);
+
+        type = *ptr++;
+        pack = *ptr++;
+        
+        switch (type)
+        {
+        case 5: /* device dependent bmp */
+        case 6: /* device independent bmp */
+            HLPFILE_LoadBitmap(beg, type, pack, paragraph);
+            break;
+        case 8: 
+            HLPFILE_LoadMetaFile(beg, pack, paragraph);
+            break;
+        default: WINE_FIXME("Unknown type %u\n", type); return FALSE;
+        }
+
+        /* FIXME: hotspots */
+
+        /* 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_LoadGfxByIndex
+ *
+ *
+ */
+static  BOOL    HLPFILE_LoadGfxByIndex(HLPFILE *hlpfile, unsigned index, 
+                                       HLPFILE_PARAGRAPH* paragraph)
+{
+    char        tmp[16];
+    BYTE        *ref, *end;
+    BOOL        ret;
+
+    WINE_TRACE("Loading picture #%d\n", index);
+
+    if (index < hlpfile->numBmps && hlpfile->bmps[index] != NULL)
+    {
+        paragraph->u.gfx.u.bmp.hBitmap = hlpfile->bmps[index];
+        return TRUE;
+    }
+
+    sprintf(tmp, "|bm%u", index);
+
+    if (!HLPFILE_FindSubFile(tmp, &ref, &end)) {WINE_WARN("no sub file\n"); return FALSE;}
+
+    ref += 9;
+
+    ret = HLPFILE_LoadGfxByAddr(hlpfile, ref, end - ref, paragraph);
+
+    /* cache bitmap */
+    if (ret && paragraph->cookie == para_bitmap)
+    {
+        if (index >= hlpfile->numBmps)
+        {
+            hlpfile->numBmps = index + 1;
+           if (hlpfile->bmps)
+               hlpfile->bmps = HeapReAlloc(GetProcessHeap(), 0, hlpfile->bmps, 
+                                        hlpfile->numBmps * sizeof(hlpfile->bmps[0]));
+           else
+               hlpfile->bmps = HeapAlloc(GetProcessHeap(), 0, 
+                                        hlpfile->numBmps * sizeof(hlpfile->bmps[0]));
+
+        }
+        hlpfile->bmps[index] = paragraph->u.gfx.u.bmp.hBitmap;
+    }
+    return ret;
+}
+
+/******************************************************************
+ *             HLPFILE_AllocLink
+ *
+ *
+ */
+static HLPFILE_LINK*       HLPFILE_AllocLink(int cookie, const char* str, LONG hash,
+                                             BOOL clrChange, unsigned wnd)
+{
+    HLPFILE_LINK*  link;
+    char*          link_str;
+
+    /* FIXME: should build a string table for the attributes.link.lpszPath
+     * they are reallocated for each link
+     */
+    link = HeapAlloc(GetProcessHeap(), 0, sizeof(HLPFILE_LINK) + strlen(str) + 1);
+    if (!link) return NULL;
+
+    link->cookie     = cookie;
+    link->lpszString = link_str = (char*)link + sizeof(HLPFILE_LINK);
+    strcpy(link_str, str);
+    link->lHash      = hash;
+    link->bClrChange = clrChange ? 1 : 0;
+    link->window     = wnd;
+    link->wRefCount   = 1;
+
+    WINE_TRACE("Link[%d] to %s@%08x:%d\n",
+               link->cookie, link->lpszString, 
+               link->lHash, link->window);
+    return link;
+}
+
+/***********************************************************************
+ *
+ *           HLPFILE_AddParagraph
+ */
+static BOOL HLPFILE_AddParagraph(HLPFILE *hlpfile, BYTE *buf, BYTE *end, unsigned* len)
+{
+    HLPFILE_PAGE      *page;
+    HLPFILE_PARAGRAPH *paragraph, **paragraphptr;
+    UINT               textsize;
+    BYTE              *format, *format_end;
+    char              *text, *text_end;
+    long               size;
+    unsigned short     bits;
+    unsigned           nc, ncol = 1;
+
+    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 */;
+
+    if (buf + 0x19 > end) {WINE_WARN("header too small\n"); return FALSE;};
+
+    size = GET_UINT(buf, 0x4);
+    text = HeapAlloc(GetProcessHeap(), 0, size);
+    if (!text) return FALSE;
+    if (hlpfile->hasPhrases)
+    {
+        HLPFILE_Uncompress2(buf + GET_UINT(buf, 0x10), end, (BYTE*)text, (BYTE*)text + size);
+    }
+    else
+    {
+        if (GET_UINT(buf, 0x4) > GET_UINT(buf, 0) - GET_UINT(buf, 0x10))
+        {
+            /* block is compressed */
+            HLPFILE_Uncompress3(text, text + size, buf + GET_UINT(buf, 0x10), end);
+        }
+        else
+        {
+            text = (char*)buf + GET_UINT(buf, 0x10);
+        }
+    }
+    text_end = text + size;
+
+    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;
+    }
+
+    for (nc = 0; nc < ncol; nc++)
+    {
+        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 = GET_USHORT(format, 0); 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;
+
+            while (ntab-- > 0)
+            {
+                ts = fetch_ushort(&format);
+                if (ts & 0x4000) fetch_ushort(&format);
+            }
+        }
+        /* 0x0400, 0x0800 and 0x1000 don't need space */
+        if ((bits & 0xE080) != 0) 
+            WINE_FIXME("Unsupported bits %04x, potential trouble ahead\n", bits);
+
+        while (text < text_end && format < format_end)
+        {
+            //WINE_TRACE("Got text: %s (%p/%p - %p/%p)\n", wine_dbgstr_a(text), text, text_end, format, format_end);
+            textsize = strlen(text) + 1;
+            if (textsize > 1)
+            {
+                paragraph = HeapAlloc(GetProcessHeap(), 0,
+                                      sizeof(HLPFILE_PARAGRAPH) + textsize);
+                if (!paragraph) return FALSE;
+                *paragraphptr = paragraph;
+                paragraphptr = &paragraph->next;
+
+                paragraph->next            = NULL;
+                paragraph->link            = attributes.link;
+                if (paragraph->link) paragraph->link->wRefCount++;
+                paragraph->cookie          = 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);
+
+                attributes.wVSpace = 0;
+                attributes.wHSpace = 0;
+            }
+            /* else: null text, keep on storing attributes */
+            text += textsize;
+
+           if (*format == 0xff)
+            {
+                format++;
+                break;
+            }
+
+            WINE_TRACE("format=%02x\n", *format);
+            switch (*format)
+            {
+            case 0x20:
+                WINE_FIXME("NIY20\n");
+                format += 5;
+                break;
+
+            case 0x21:
+                WINE_FIXME("NIY21\n");
+                format += 3;
+                break;
+
+           case 0x80:
+                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;
+
+           case 0x82:
+                attributes.wVSpace++;
+                attributes.wIndent = 0;
+                format += 1;
+                break;
+
+           case 0x83:
+                attributes.wIndent++;
+                format += 1;
+                break;
+
+#if 0
+           case 0x84:
+                format += 3;
+                break;
+#endif
+
+           case 0x86:
+           case 0x87:
+           case 0x88:
+                {
+                    BYTE    pos = (*format - 0x86);
+                    BYTE    type = format[1];
+                    long    size;
+
+                    format += 2;
+                    size = fetch_long(&format);
+
+                    paragraph = HeapAlloc(GetProcessHeap(), 0,
+                                          sizeof(HLPFILE_PARAGRAPH) + textsize);
+                    if (!paragraph) return FALSE;
+                    *paragraphptr = paragraph;
+                    paragraphptr = &paragraph->next;
+
+                    paragraph->next        = NULL;
+                    paragraph->link        = attributes.link;
+                    if (paragraph->link) paragraph->link->wRefCount++;
+                    paragraph->cookie      = para_bitmap;
+                    paragraph->u.gfx.pos   = pos;
+                    switch (type)
+                    {
+                    case 0x22:
+                        fetch_ushort(&format); /* hot spot */
+                        /* fall thru */
+                    case 0x03:
+                        switch (GET_SHORT(format, 0))
+                        {
+                        case 0:
+                            HLPFILE_LoadGfxByIndex(hlpfile, GET_SHORT(format, 2), 
+                                                   paragraph);
+                            break;
+                        case 1:
+                            WINE_FIXME("does it work ??? %x<%lu>#%u\n", 
+                                       GET_SHORT(format, 0), 
+                                       size, GET_SHORT(format, 2));
+                            HLPFILE_LoadGfxByAddr(hlpfile, format + 2, size - 4, 
+                                                  paragraph);
+                            break;
+                        default:
+                            WINE_FIXME("??? %u\n", GET_SHORT(format, 0));
+                            break;
+                        }
+                        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;
+                    }
+                    if (attributes.wVSpace) paragraph->u.gfx.pos |= 0x8000;
+
+                    format += size;
+                }
+                break;
+
+           case 0x89:
+                HLPFILE_FreeLink(attributes.link);
+                attributes.link = NULL;
+                format += 1;
+                break;
+
+            case 0x8B:
+            case 0x8C:
+                WINE_FIXME("NIY non-break space/hyphen\n");
+                format += 1;
+                break;
+
+#if 0
+           case 0xA9:
+                format += 2;
+                break;
+#endif
+
+            case 0xC8:
+            case 0xCC:
+                WINE_TRACE("macro => %s\n", format + 3);
+                HLPFILE_FreeLink(attributes.link);
+                attributes.link = HLPFILE_AllocLink(hlp_link_macro, (const char*)format + 3, 
+                                                    0, !(*format & 4), -1);
+                format += 3 + GET_USHORT(format, 1);
+                break;
+
+            case 0xE0:
+            case 0xE1:
+                WINE_WARN("jump topic 1 => %u\n", GET_UINT(format, 1));
+                format += 5;
+                break;
+
+           case 0xE2:
+           case 0xE3:
+            case 0xE6:
+            case 0xE7:
+                HLPFILE_FreeLink(attributes.link);
+                attributes.link = HLPFILE_AllocLink((*format & 1) ? hlp_link_link : hlp_link_popup,
+                                                    hlpfile->lpszPath, 
+                                                    GET_UINT(format, 1), 
+                                                    !(*format & 4), -1);
+                format += 5;
+                break;
+
+           case 0xEA:
+            case 0xEB:
+            case 0xEE:
+            case 0xEF:
+                {
+                    char*       ptr = (char*) format + 8;
+                    BYTE        type = format[3];
+                    int         wnd = -1;
+                    char*       str;
+
+                    if (type == 1) wnd = *ptr++;
+                    if (type == 4 || type == 6)
+                    {
+                        str = ptr;
+                        ptr += strlen(ptr) + 1;
+                    }
+                    else
+                        str = hlpfile->lpszPath;
+                    if (type == 6)
+                    {
+                        for (wnd = hlpfile->numWindows - 1; wnd >= 0; wnd--)
+                        {
+                            if (!strcmp(ptr, hlpfile->windows[wnd].name)) break;
+                        }
+                        if (wnd == -1)
+                            WINE_WARN("Couldn't find window info for %s\n", ptr);
+                    }
+                    HLPFILE_FreeLink(attributes.link);
+                    attributes.link = HLPFILE_AllocLink((*format & 4) ? hlp_link_link : hlp_link_popup,
+                                                        str, GET_UINT(format, 4),
+                                                        !(*format & 1), wnd);
+                }
+                format += 3 + GET_USHORT(format, 1);
+                break;
+
+           default:
+                WINE_WARN("format %02x\n", *format);
+                format++;
+           }
+       }
+    }
+    if (text_end != (char*)buf + GET_UINT(buf, 0x10) + size)
+        HeapFree(GetProcessHeap(), 0, text_end - size);
+    return TRUE;
+}
+
+/******************************************************************
+ *             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 (!HLPFILE_FindSubFile("|FONT", &ref, &end))
+    {
+        WINE_WARN("no subfile FONT\n");
+        hlpfile->numFonts = 0;
+        hlpfile->fonts = NULL;
+        return FALSE;
+    }
+
+    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 = GET_USHORT(ref, dscr_offset + i * 11 + 3);
+
+        if (idx < face_num)
+        {
+            memcpy(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)] = '\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 = 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=%08x\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,
+                   GET_UINT(ref, dscr_offset + i * 11 + 5) & 0x00FFFFFF);
+    }
+    return TRUE;
+}
+
+/***********************************************************************
+ *
+ *           HLPFILE_ReadFileToBuffer
+ */
+static BOOL HLPFILE_ReadFileToBuffer(HFILE hFile)
+{
+    BYTE  header[16], dummy[1];
+    UINT  size;
+
+    if (_hread(hFile, header, 16) != 16) {WINE_WARN("header\n"); return FALSE;};
+
+    /* sanity checks */
+    if (GET_UINT(header, 0) != 0x00035F3F)
+    {WINE_WARN("wrong header\n"); return FALSE;};
+
+    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)
+    {WINE_WARN("filesize1\n"); return FALSE;};
+
+    if (_hread(hFile, dummy, 1) != 0) WINE_WARN("filesize2\n");
+
+    file_buffer[size] = '\0'; /* FIXME: was '0', sounds ackward to me */
+
+    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;
+    BYTE *bth;
+
+    unsigned    pgsize;
+    unsigned    pglast;
+    unsigned    nentries;
+    unsigned    i, n;
+
+    bth = root + 9;
+
+    /* FIXME: this should be using the EnumBTree functions from this file */
+    pgsize = GET_USHORT(bth, 4);
+    WINE_TRACE("%s => pgsize=%u #pg=%u rootpg=%u #lvl=%u\n", 
+               name, pgsize, GET_USHORT(bth, 30), GET_USHORT(bth, 26), GET_USHORT(bth, 32));
+
+    ptr = bth + 38 + GET_USHORT(bth, 26) * pgsize;
+
+    for (n = 1; n < GET_USHORT(bth, 32); n++)
+    {
+        nentries = GET_USHORT(ptr, 2);
+        pglast = GET_USHORT(ptr, 4);
+        WINE_TRACE("[%u]: #entries=%u next=%u\n", n, nentries, pglast);
+
+        ptr += 6;
+        for (i = 0; i < nentries; i++)
+        {
+            char *str = (char*) ptr;
+            WINE_TRACE("<= %s\n", str);
+            if (strcmp(name, str) < 0) break;
+            ptr += strlen(str) + 1;
+            pglast = GET_USHORT(ptr, 0);
+            ptr += 2;
+        }
+        ptr = bth + 38 + pglast * pgsize;
+    }
+
+    nentries = GET_USHORT(ptr, 2);
+    ptr += 8;
+    for (i = 0; i < nentries; i++)
+    {
+        char*   fname = (char*)ptr;
+        ptr += strlen(fname) + 1;
+        WINE_TRACE("\\- %s\n", fname);
+        if (strcmp(fname, name) == 0)
+        {
+            *subbuf = file_buffer + GET_UINT(ptr, 0);
+            *subend = *subbuf + GET_UINT(*subbuf, 0);
+            if (file_buffer > *subbuf || *subbuf > *subend || *subend > end)
+           {
+                WINE_WARN("size mismatch\n");
+                return FALSE;
+           }
+            return TRUE;
+        }
+        ptr += 4;
+    }
+
+    return FALSE;
+}
+
+/***********************************************************************
+ *
+ *           HLPFILE_SystemCommands
+ */
+static BOOL HLPFILE_SystemCommands(HLPFILE* hlpfile)
+{
+    BYTE *buf, *ptr, *end;
+    HLPFILE_MACRO *macro, **m;
+    LPSTR p;
+    unsigned short magic, minor, major, flags;
+
+    hlpfile->lpszTitle = NULL;
+
+    if (!HLPFILE_FindSubFile("|SYSTEM", &buf, &end)) return FALSE;
+
+    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;}
+    if (flags & 8) {WINE_WARN("Unsupported yet page size\n"); return FALSE;}
+
+    hlpfile->version = minor;
+    hlpfile->flags = flags;
+
+    for (ptr = buf + 0x15; ptr + 4 <= end; ptr += GET_USHORT(ptr, 2) + 4)
+    {
+        char *str = (char*) ptr + 4;
+        switch (GET_USHORT(ptr, 0))
+       {
+       case 1:
+            if (hlpfile->lpszTitle) {WINE_WARN("title\n"); break;}
+            hlpfile->lpszTitle = HeapAlloc(GetProcessHeap(), 0, strlen(str) + 1);
+            if (!hlpfile->lpszTitle) return FALSE;
+            lstrcpy(hlpfile->lpszTitle, str);
+            WINE_TRACE("Title: %s\n", hlpfile->lpszTitle);
+            break;
+
+       case 2:
+            if (hlpfile->lpszCopyright) {WINE_WARN("copyright\n"); break;}
+            hlpfile->lpszCopyright = HeapAlloc(GetProcessHeap(), 0, strlen(str) + 1);
+            if (!hlpfile->lpszCopyright) return FALSE;
+            lstrcpy(hlpfile->lpszCopyright, str);
+            WINE_TRACE("Copyright: %s\n", hlpfile->lpszCopyright);
+            break;
+
+       case 3:
+            if (GET_USHORT(ptr, 2) != 4) {WINE_WARN("system3\n");break;}
+            hlpfile->contents_start = GET_UINT(ptr, 4);
+            WINE_TRACE("Setting contents start at %08lx\n", hlpfile->contents_start);
+            break;
+
+       case 4:
+            macro = HeapAlloc(GetProcessHeap(), 0, sizeof(HLPFILE_MACRO) + lstrlen(str) + 1);
+            if (!macro) break;
+            p = (char*)macro + sizeof(HLPFILE_MACRO);
+            lstrcpy(p, str);
+            macro->lpszMacro = p;
+            macro->next = 0;
+            for (m = &hlpfile->first_macro; *m; m = &(*m)->next);
+            *m = macro;
+            break;
+
+        case 6:
+            if (GET_USHORT(ptr, 2) != 90) {WINE_WARN("system6\n");break;}
+
+           if (hlpfile->windows) 
+               hlpfile->windows = HeapReAlloc(GetProcessHeap(), 0, hlpfile->windows, 
+                                           sizeof(HLPFILE_WINDOWINFO) * ++hlpfile->numWindows);
+           else 
+               hlpfile->windows = HeapAlloc(GetProcessHeap(), 0, 
+                                           sizeof(HLPFILE_WINDOWINFO) * ++hlpfile->numWindows);
+           
+            if (hlpfile->windows)
+            {
+                unsigned flags = GET_USHORT(ptr, 4);
+                HLPFILE_WINDOWINFO* wi = &hlpfile->windows[hlpfile->numWindows - 1];
+
+                if (flags & 0x0001) strcpy(wi->type, &str[2]);
+                else wi->type[0] = '\0';
+                if (flags & 0x0002) strcpy(wi->name, &str[12]);
+                else wi->name[0] = '\0';
+                if (flags & 0x0004) strcpy(wi->caption, &str[23]);
+                else lstrcpynA(wi->caption, hlpfile->lpszTitle, sizeof(wi->caption));
+                wi->origin.x = (flags & 0x0008) ? GET_USHORT(ptr, 76) : CW_USEDEFAULT;
+                wi->origin.y = (flags & 0x0010) ? GET_USHORT(ptr, 78) : CW_USEDEFAULT;
+                wi->size.cx = (flags & 0x0020) ? GET_USHORT(ptr, 80) : CW_USEDEFAULT;
+                wi->size.cy = (flags & 0x0040) ? GET_USHORT(ptr, 82) : CW_USEDEFAULT;
+                wi->style = (flags & 0x0080) ? GET_USHORT(ptr, 84) : SW_SHOW;
+                wi->win_style = WS_OVERLAPPEDWINDOW;
+                wi->sr_color = (flags & 0x0100) ? GET_UINT(ptr, 86) : 0xFFFFFF;
+                wi->nsr_color = (flags & 0x0200) ? GET_UINT(ptr, 90) : 0xFFFFFF;
+                WINE_TRACE("System-Window: flags=%c%c%c%c%c%c%c%c type=%s name=%s caption=%s (%d,%d)x(%d,%d)\n",
+                           flags & 0x0001 ? 'T' : 't',
+                           flags & 0x0002 ? 'N' : 'n',
+                           flags & 0x0004 ? 'C' : 'c',
+                           flags & 0x0008 ? 'X' : 'x',
+                           flags & 0x0010 ? 'Y' : 'y',
+                           flags & 0x0020 ? 'W' : 'w',
+                           flags & 0x0040 ? 'H' : 'h',
+                           flags & 0x0080 ? 'S' : 's',
+                           wi->type, wi->name, wi->caption, wi->origin.x, wi->origin.y,
+                           wi->size.cx, wi->size.cy);
+            }
+            break;
+       default:
+            WINE_WARN("Unsupported SystemRecord[%d]\n", GET_USHORT(ptr, 0));
+       }
+    }
+    if (!hlpfile->lpszTitle)
+        hlpfile->lpszTitle = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 1);
+    return TRUE;
+}
+
+/***********************************************************************
+ *
+ *           HLPFILE_UncompressedLZ77_Size
+ */
+static INT HLPFILE_UncompressedLZ77_Size(BYTE *ptr, BYTE *end)
+{
+    int  i, newsize = 0;
+
+    while (ptr < end)
+    {
+        int mask = *ptr++;
+        for (i = 0; i < 8 && ptr < end; i++, mask >>= 1)
+       {
+            if (mask & 1)
+           {
+                int code = GET_USHORT(ptr, 0);
+                int len  = 3 + (code >> 12);
+                newsize += len;
+                ptr     += 2;
+           }
+            else newsize++, ptr++;
+       }
+    }
+
+    return newsize;
+}
+
+/***********************************************************************
+ *
+ *           HLPFILE_UncompressLZ77
+ */
+static BYTE *HLPFILE_UncompressLZ77(BYTE *ptr, BYTE *end, BYTE *newptr)
+{
+    int i;
+
+    while (ptr < end)
+    {
+        int mask = *ptr++;
+        for (i = 0; i < 8 && ptr < end; i++, mask >>= 1)
+       {
+            if (mask & 1)
+           {
+                int code   = GET_USHORT(ptr, 0);
+                int len    = 3 + (code >> 12);
+                int offset = code & 0xfff;
+                /*
+                 * We must copy byte-by-byte here. We cannot use memcpy nor
+                 * memmove here. Just example:
+                 * a[]={1,2,3,4,5,6,7,8,9,10}
+                 * newptr=a+2;
+                 * offset=1;
+                 * We expect:
+                 * {1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 11, 12}
+                 */
+                for (; len>0; len--, newptr++) *newptr = *(newptr-offset-1);
+                ptr    += 2;
+           }
+            else *newptr++ = *ptr++;
+       }
+    }
+
+    return newptr;
+}
+
+/***********************************************************************
+ *
+ *           HLPFILE_UncompressLZ77_Phrases
+ */
+static BOOL HLPFILE_UncompressLZ77_Phrases(HLPFILE* hlpfile)
+{
+    UINT i, num, dec_size;
+    BYTE *buf, *end;
+
+    if (!HLPFILE_FindSubFile("|Phrases", &buf, &end)) return FALSE;
+
+    num = phrases.num = GET_USHORT(buf, 9);
+    if (buf + 2 * num + 0x13 >= end) {WINE_WARN("1a\n"); return FALSE;};
+
+    dec_size = HLPFILE_UncompressedLZ77_Size(buf + 0x13 + 2 * num, end);
+
+    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++)
+        phrases.offsets[i] = GET_USHORT(buf, 0x11 + 2 * i) - 2 * num - 2;
+
+    HLPFILE_UncompressLZ77(buf + 0x13 + 2 * num, end, (BYTE*)phrases.buffer);
+
+    hlpfile->hasPhrases = TRUE;
+    return TRUE;
+}
+
+/***********************************************************************
+ *
+ *           HLPFILE_Uncompress_Phrases40
+ */
+static BOOL HLPFILE_Uncompress_Phrases40(HLPFILE* hlpfile)
+{
+    UINT num, dec_size, cpr_size;
+    BYTE *buf_idx, *end_idx;
+    BYTE *buf_phs, *end_phs;
+    short i, n;
+    long* ptr, mask = 0;
+    unsigned short bc;
+
+    if (!HLPFILE_FindSubFile("|PhrIndex", &buf_idx, &end_idx) ||
+        !HLPFILE_FindSubFile("|PhrImage", &buf_phs, &end_phs)) return FALSE;
+
+    ptr = (long*)(buf_idx + 9 + 28);
+    bc = GET_USHORT(buf_idx, 9 + 24) & 0x0F;
+    num = phrases.num = GET_USHORT(buf_idx, 9 + 4);
+
+    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);
+    cpr_size = GET_UINT(buf_idx, 9 + 16);
+
+    if (dec_size != cpr_size &&
+        dec_size != HLPFILE_UncompressedLZ77_Size(buf_phs + 9, end_phs))
+    {
+        WINE_WARN("size mismatch %u %u\n",
+                  dec_size, HLPFILE_UncompressedLZ77_Size(buf_phs + 9, end_phs));
+        dec_size = max(dec_size, HLPFILE_UncompressedLZ77_Size(buf_phs + 9, end_phs));
+    }
+
+    phrases.offsets = HeapAlloc(GetProcessHeap(), 0, sizeof(unsigned) * (num + 1));
+    phrases.buffer  = HeapAlloc(GetProcessHeap(), 0, dec_size);
+    if (!phrases.offsets || !phrases.buffer) return FALSE;
+
+#define getbit() (ptr += (mask < 0), mask = mask*2 + (mask<=0), (*ptr & mask) != 0)
+
+    phrases.offsets[0] = 0;
+    for (i = 0; i < num; i++)
+    {
+        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
+
+    if (dec_size == cpr_size)
+        memcpy(phrases.buffer, buf_phs + 9, dec_size);
+    else
+        HLPFILE_UncompressLZ77(buf_phs + 9, end_phs, (BYTE*)phrases.buffer);
+
+    hlpfile->hasPhrases = FALSE;
+    return TRUE;
+}
+
+/***********************************************************************
+ *
+ *           HLPFILE_Uncompress_Topic
+ */
+static BOOL HLPFILE_Uncompress_Topic(HLPFILE* hlpfile)
+{
+    BYTE *buf, *ptr, *end, *newptr;
+    int  i, newsize = 0;
+
+    if (!HLPFILE_FindSubFile("|TOPIC", &buf, &end))
+    {WINE_WARN("topic0\n"); return FALSE;}
+
+    switch (hlpfile->flags & (8|4))
+    {
+    case 8:
+        WINE_FIXME("Unsupported format\n");
+        return FALSE;
+    case 4:
+        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));
+        }
+        
+        topic.map = HeapAlloc(GetProcessHeap(), 0,
+                              topic.wMapLen * sizeof(topic.map[0]) + newsize);
+        if (!topic.map) return FALSE;
+        newptr = (BYTE*)(topic.map + topic.wMapLen);
+        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);
+        }
+        break;
+    case 0:
+        /* basically, we need to copy the 0x1000 byte pages (removing the first 0x0C) in
+         * one single are in memory
+         */
+#define DST_LEN (0x1000 - 0x0C)
+        buf += 9;
+        newsize = end - buf;
+        /* number of destination pages */
+        topic.wMapLen = (newsize - 1) / DST_LEN + 1;
+        topic.map = HeapAlloc(GetProcessHeap(), 0,
+                              topic.wMapLen * (sizeof(topic.map[0]) + DST_LEN));
+        if (!topic.map) return FALSE;
+        newptr = (BYTE*)(topic.map + topic.wMapLen);
+        topic.end = newptr + newsize;
+
+        for (i = 0; i < topic.wMapLen; i++)
+        {
+            topic.map[i] = newptr + i * DST_LEN;
+            memcpy(topic.map[i], buf + i * 0x1000 + 0x0C, DST_LEN);
+        }
+#undef DST_LEN
+        break;
+    }
+    return TRUE;
+}
+
+/***********************************************************************
+ *
+ *           HLPFILE_Uncompress2
+ */
+
+static void HLPFILE_Uncompress2(const BYTE *ptr, const BYTE *end, BYTE *newptr, const BYTE *newend)
+{
+    BYTE *phptr, *phend;
+    UINT code;
+    UINT index;
+
+    while (ptr < end && newptr < newend)
+    {
+        if (!*ptr || *ptr >= 0x10)
+            *newptr++ = *ptr++;
+        else
+       {
+            code  = 0x100 * ptr[0] + ptr[1];
+            index = (code - 0x100) / 2;
+
+            phptr = (BYTE*)phrases.buffer + phrases.offsets[index];
+            phend = (BYTE*)phrases.buffer + phrases.offsets[index + 1];
+
+            if (newptr + (phend - phptr) > newend)
+            {
+                WINE_FIXME("buffer overflow %p > %p for %d bytes\n", 
+                           newptr, newend, phend - phptr);
+                return;
+            }
+            memcpy(newptr, phptr, phend - phptr);
+            newptr += phend - phptr;
+            if (code & 1) *newptr++ = ' ';
+
+            ptr += 2;
+       }
+    }
+    if (newptr > newend) WINE_FIXME("buffer overflow %p > %p\n", newptr, newend);
+}
+
+/******************************************************************
+ *             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 %d/%d\n", idx, phrases.num);
+                len = 0;
+            }
+            else 
+            {
+                len = phrases.offsets[idx + 1] - phrases.offsets[idx];
+                if (dst + len <= dst_end)
+                    memcpy(dst, &phrases.buffer[phrases.offsets[idx]], len);
+            }
+        }
+        else if ((*src & 0x03) == 0x01)
+        {
+            idx = (*src + 1) * 64;
+            idx += *++src;
+            if (idx > phrases.num) 
+            {
+                WINE_ERR("index in phrases %d/%d\n", idx, phrases.num);
+                len = 0;
+            }
+            else
+            {
+                len = phrases.offsets[idx + 1] - phrases.offsets[idx];
+                if (dst + len <= dst_end)
+                    memcpy(dst, &phrases.buffer[phrases.offsets[idx]], len);
+            }
+        }
+        else if ((*src & 0x07) == 0x03)
+        {
+            len = (*src / 8) + 1;
+            if (dst + len <= dst_end)
+                memcpy(dst, src + 1, len);
+            src += len;
+        }
+        else
+        {
+            len = (*src / 16) + 1;
+            if (dst + len <= dst_end)
+                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, const BYTE* end, BYTE** dst, unsigned dstsz)
+{
+    BYTE        ch;
+    BYTE*       sdst = *dst + dstsz;
+
+    while (src < end)
+    {
+        ch = *src++;
+        if (ch & 0x80)
+        {
+            ch &= 0x7F;
+            if ((*dst) + ch <= sdst)
+                memcpy(*dst, src, ch);
+            src += ch;
+        }
+        else
+        {
+            if ((*dst) + ch <= sdst)
+                memset(*dst, (char)*src, ch);
+            src++;
+        }
+        *dst += ch;
+    }
+    if (*dst != sdst)
+        WINE_WARN("Buffer X-flow: d(%u) instead of d(%u)\n",
+                  *dst - (sdst - dstsz), dstsz);
+}
+
+/******************************************************************
+ *             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, 9 + 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, 4);
+    }
+    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)
+{
+    BYTE                *cbuf, *cend;
+    struct myfncb       m;
+    unsigned            clen;
+
+    if (!HLPFILE_FindSubFile("|CONTEXT",  &cbuf, &cend)) {WINE_WARN("context0\n"); return FALSE;}
+
+    clen = GET_UINT(cbuf, 0x2b);
+    hlpfile->Context = HeapAlloc(GetProcessHeap(), 0, clen * sizeof(HLPFILE_CONTEXT));
+    if (!hlpfile->Context) return FALSE;
+    hlpfile->wContextLen = clen;
+
+    m.hlpfile = hlpfile;
+    m.i = 0;
+    HLPFILE_EnumBTreeLeaves(cbuf, cend, myfn, &m);
+
+    return TRUE;
+}
+
+/***********************************************************************
+ *
+ *           HLPFILE_GetMap
+ */
+static BOOL HLPFILE_GetMap(HLPFILE *hlpfile)
+{
+    BYTE                *cbuf, *cend;
+    unsigned            entries, i;
+
+    if (!HLPFILE_FindSubFile("|CTXOMAP",  &cbuf, &cend)) {WINE_WARN("no map section\n"); return FALSE;}
+
+    entries = GET_USHORT(cbuf, 9);
+    hlpfile->Map = HeapAlloc(GetProcessHeap(), 0, entries * sizeof(HLPFILE_MAP));
+    if (!hlpfile->Map) return FALSE;
+    hlpfile->wMapLen = entries;
+    for (i = 0; i < entries; i++)
+    {
+        hlpfile->Map[i].lMap = GET_UINT(cbuf+11,i*8);
+        hlpfile->Map[i].offset = GET_UINT(cbuf+11,i*8+4);
+    }
+    return TRUE;
+}
+
+/******************************************************************
+ *             HLPFILE_DeleteLink
+ *
+ *
+ */
+void HLPFILE_FreeLink(HLPFILE_LINK* link)
+{
+    if (link && !--link->wRefCount)
+        HeapFree(GetProcessHeap(), 0, link);
+}
+
+/***********************************************************************
+ *
+ *           HLPFILE_DeleteParagraph
+ */
+static void HLPFILE_DeleteParagraph(HLPFILE_PARAGRAPH* paragraph)
+{
+    HLPFILE_PARAGRAPH* next;
+
+    while (paragraph)
+    {
+        next = paragraph->next;
+
+        if (paragraph->cookie == para_metafile)
+            DeleteMetaFile(paragraph->u.gfx.u.mfp.hMF);
+
+        HLPFILE_FreeLink(paragraph->link);
+
+        HeapFree(GetProcessHeap(), 0, paragraph);
+        paragraph = next;
+    }
+}
+
+/***********************************************************************
+ *
+ *           DeleteMacro
+ */
+static void HLPFILE_DeleteMacro(HLPFILE_MACRO* macro)
+{
+    HLPFILE_MACRO*      next;
+
+    while (macro)
+    {
+        next = macro->next;
+        HeapFree(GetProcessHeap(), 0, macro);
+        macro = next;
+    }
+}
+
+/***********************************************************************
+ *
+ *           DeletePage
+ */
+static void HLPFILE_DeletePage(HLPFILE_PAGE* page)
+{
+    HLPFILE_PAGE* next;
+
+    while (page)
+    {
+        next = page->next;
+        HLPFILE_DeleteParagraph(page->first_paragraph);
+        HLPFILE_DeleteMacro(page->first_macro);
+        HeapFree(GetProcessHeap(), 0, page);
+        page = next;
+    }
+}
+
+/***********************************************************************
+ *
+ *           HLPFILE_FreeHlpFile
+ */
+void HLPFILE_FreeHlpFile(HLPFILE* hlpfile)
+{
+    unsigned i;
+
+    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 = hlpfile->next;
+
+    if (hlpfile->numFonts)
+    {
+        for (i = 0; i < hlpfile->numFonts; i++)
+        {
+            DeleteObject(hlpfile->fonts[i].hFont);
+        }
+        HeapFree(GetProcessHeap(), 0, hlpfile->fonts);
+    }
+
+    if (hlpfile->numBmps)
+    {
+        for (i = 0; i < hlpfile->numBmps; i++)
+        {
+            DeleteObject(hlpfile->bmps[i]);
+        }
+        HeapFree(GetProcessHeap(), 0, hlpfile->bmps);
+    }
+
+    HLPFILE_DeletePage(hlpfile->first_page);
+    HLPFILE_DeleteMacro(hlpfile->first_macro);
+
+    if (hlpfile->numWindows)    HeapFree(GetProcessHeap(), 0, hlpfile->windows);
+    HeapFree(GetProcessHeap(), 0, hlpfile->Context);
+    HeapFree(GetProcessHeap(), 0, hlpfile->Map);
+    HeapFree(GetProcessHeap(), 0, hlpfile->lpszTitle);
+    HeapFree(GetProcessHeap(), 0, hlpfile->lpszCopyright);
+    HeapFree(GetProcessHeap(), 0, hlpfile);
+}
diff --git a/reactos/base/applications/winhelp/hlpfile.h b/reactos/base/applications/winhelp/hlpfile.h
new file mode 100644 (file)
index 0000000..4d62cdd
--- /dev/null
@@ -0,0 +1,163 @@
+/*
+ * Help Viewer
+ *
+ * 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
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+struct tagHelpFile;
+
+typedef struct 
+{
+    char        type[10];
+    char        name[9];
+    char        caption[51];
+    POINT       origin;
+    SIZE        size;
+    int         style;
+    DWORD       win_style;
+    COLORREF    sr_color;       /* color for scrollable region */
+    COLORREF    nsr_color;      /* color for non scrollable region */
+} HLPFILE_WINDOWINFO;
+
+typedef struct
+{
+    enum {hlp_link_link, hlp_link_popup, hlp_link_macro} cookie;
+    LPCSTR      lpszString;     /* name of the file to for the link (NULL if same file) */
+    LONG        lHash;          /* topic index */
+    unsigned    bClrChange : 1, /* true if the link is green & underlined */
+                wRefCount;      /* number of internal references to this object */
+    unsigned    window;         /* window number for displaying the link (-1 is current) */
+} HLPFILE_LINK;
+
+enum para_type {para_normal_text, para_debug_text, para_bitmap, para_metafile};
+
+typedef struct tagHlpFileParagraph
+{
+    enum para_type              cookie;
+
+    union
+    {
+        struct
+        {
+            LPSTR                       lpszText;
+            unsigned                    wFont;
+            unsigned                    wIndent;
+            unsigned                    wHSpace;
+            unsigned                    wVSpace;
+        } text;
+        struct
+        {
+            unsigned                    pos;    /* 0: center, 1: left, 2: right */
+            union 
+            {
+                struct 
+                {
+                    HBITMAP             hBitmap;
+                } bmp;
+                METAFILEPICT            mfp;
+            } u;
+        } gfx; /* for bitmaps and metafiles */
+    } u;
+
+    HLPFILE_LINK*               link;
+
+    struct tagHlpFileParagraph* next;
+} HLPFILE_PARAGRAPH;
+
+typedef struct tagHlpFileMacro
+{
+    LPCSTR                      lpszMacro;
+    struct tagHlpFileMacro*     next;
+} HLPFILE_MACRO;
+
+typedef struct tagHlpFilePage
+{
+    LPSTR                       lpszTitle;
+    HLPFILE_PARAGRAPH*          first_paragraph;
+    HLPFILE_MACRO*              first_macro;
+
+    unsigned                    wNumber;
+    unsigned                    offset;
+    struct tagHlpFilePage*      next;
+    struct tagHlpFilePage*      prev;
+
+    DWORD                       browse_bwd;
+    DWORD                       browse_fwd;
+
+    struct tagHlpFileFile*      file;
+} HLPFILE_PAGE;
+
+typedef struct
+{
+    LONG                        lHash;
+    unsigned long               offset;
+} HLPFILE_CONTEXT;
+
+typedef struct
+{
+    LONG                        lMap;
+    unsigned long               offset;
+} HLPFILE_MAP;
+
+typedef struct
+{
+    LOGFONT                     LogFont;
+    HFONT                       hFont;
+    COLORREF                    color;
+} HLPFILE_FONT;
+
+typedef struct tagHlpFileFile
+{
+    LPSTR                       lpszPath;
+    LPSTR                       lpszTitle;
+    LPSTR                       lpszCopyright;
+    HLPFILE_PAGE*               first_page;
+    HLPFILE_MACRO*              first_macro;
+    unsigned                    wContextLen;
+    HLPFILE_CONTEXT*            Context;
+    unsigned                    wMapLen;
+    HLPFILE_MAP*                Map;
+    unsigned long               contents_start;
+
+    struct tagHlpFileFile*      prev;
+    struct tagHlpFileFile*      next;
+
+    unsigned                    wRefCount;
+
+    unsigned short              version;
+    unsigned short              flags;
+    unsigned                    hasPhrases; /* Phrases or PhrIndex/PhrImage */
+
+    unsigned                    numBmps;
+    HBITMAP*                    bmps;
+
+    unsigned                    numFonts;
+    HLPFILE_FONT*               fonts;
+
+    unsigned                    numWindows;
+    HLPFILE_WINDOWINFO*         windows;
+} HLPFILE;
+
+HLPFILE*      HLPFILE_ReadHlpFile(LPCSTR lpszPath);
+HLPFILE_PAGE* HLPFILE_Contents(HLPFILE* hlpfile);
+HLPFILE_PAGE* HLPFILE_PageByHash(HLPFILE* hlpfile, LONG lHash);
+HLPFILE_PAGE* HLPFILE_PageByMap(HLPFILE* hlpfile, LONG lMap);
+HLPFILE_PAGE* HLPFILE_PageByOffset(HLPFILE* hlpfile, LONG offset);
+LONG          HLPFILE_Hash(LPCSTR lpszContext);
+void          HLPFILE_FreeLink(HLPFILE_LINK* link);
+void          HLPFILE_FreeHlpFile(HLPFILE*);
diff --git a/reactos/base/applications/winhelp/lex.yy.c b/reactos/base/applications/winhelp/lex.yy.c
new file mode 100644 (file)
index 0000000..9b34d38
--- /dev/null
@@ -0,0 +1,1841 @@
+/* A lexical scanner generated by flex */\r
+\r
+/* Scanner skeleton version:\r
+ * $Header: /home/daffy/u0/vern/flex/RCS/flex.skl,v 2.91 96/09/10 16:58:48 vern Exp $\r
+ */\r
+\r
+#define FLEX_SCANNER\r
+#define YY_FLEX_MAJOR_VERSION 2\r
+#define YY_FLEX_MINOR_VERSION 5\r
+\r
+#include <stdio.h>\r
+\r
+\r
+/* cfront 1.2 defines "c_plusplus" instead of "__cplusplus" */\r
+#ifdef c_plusplus\r
+#ifndef __cplusplus\r
+#define __cplusplus\r
+#endif\r
+#endif\r
+\r
+\r
+#ifdef __cplusplus\r
+\r
+#include <stdlib.h>\r
+#include <unistd.h>\r
+\r
+/* Use prototypes in function declarations. */\r
+#define YY_USE_PROTOS\r
+\r
+/* The "const" storage-class-modifier is valid. */\r
+#define YY_USE_CONST\r
+\r
+#else  /* ! __cplusplus */\r
+\r
+#if __STDC__\r
+\r
+#define YY_USE_PROTOS\r
+#define YY_USE_CONST\r
+\r
+#endif /* __STDC__ */\r
+#endif /* ! __cplusplus */\r
+\r
+#ifdef __TURBOC__\r
+ #pragma warn -rch\r
+ #pragma warn -use\r
+#include <io.h>\r
+#include <stdlib.h>\r
+#define YY_USE_CONST\r
+#define YY_USE_PROTOS\r
+#endif\r
+\r
+#ifdef YY_USE_CONST\r
+#define yyconst const\r
+#else\r
+#define yyconst\r
+#endif\r
+\r
+\r
+#ifdef YY_USE_PROTOS\r
+#define YY_PROTO(proto) proto\r
+#else\r
+#define YY_PROTO(proto) ()\r
+#endif\r
+\r
+/* Returned upon end-of-file. */\r
+#define YY_NULL 0\r
+\r
+/* Promotes a possibly negative, possibly signed char to an unsigned\r
+ * integer for use as an array index.  If the signed char is negative,\r
+ * we want to instead treat it as an 8-bit unsigned char, hence the\r
+ * double cast.\r
+ */\r
+#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)\r
+\r
+/* Enter a start condition.  This macro really ought to take a parameter,\r
+ * but we do it the disgusting crufty way forced on us by the ()-less\r
+ * definition of BEGIN.\r
+ */\r
+#define BEGIN yy_start = 1 + 2 *\r
+\r
+/* Translate the current start state into a value that can be later handed\r
+ * to BEGIN to return to the state.  The YYSTATE alias is for lex\r
+ * compatibility.\r
+ */\r
+#define YY_START ((yy_start - 1) / 2)\r
+#define YYSTATE YY_START\r
+\r
+/* Action number for EOF rule of a given start state. */\r
+#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)\r
+\r
+/* Special action meaning "start processing a new file". */\r
+#define YY_NEW_FILE yyrestart( yyin )\r
+\r
+#define YY_END_OF_BUFFER_CHAR 0\r
+\r
+/* Size of default input buffer. */\r
+#define YY_BUF_SIZE 16384\r
+\r
+typedef struct yy_buffer_state *YY_BUFFER_STATE;\r
+\r
+extern int yyleng;\r
+extern FILE *yyin, *yyout;\r
+\r
+#define EOB_ACT_CONTINUE_SCAN 0\r
+#define EOB_ACT_END_OF_FILE 1\r
+#define EOB_ACT_LAST_MATCH 2\r
+\r
+/* The funky do-while in the following #define is used to turn the definition\r
+ * int a single C statement (which needs a semi-colon terminator).  This\r
+ * avoids problems with code like:\r
+ *\r
+ *     if ( condition_holds )\r
+ *             yyless( 5 );\r
+ *     else\r
+ *             do_something_else();\r
+ *\r
+ * Prior to using the do-while the compiler would get upset at the\r
+ * "else" because it interpreted the "if" statement as being all\r
+ * done when it reached the ';' after the yyless() call.\r
+ */\r
+\r
+/* Return all but the first 'n' matched characters back to the input stream. */\r
+\r
+#define yyless(n) \\r
+       do \\r
+               { \\r
+               /* Undo effects of setting up yytext. */ \\r
+               *yy_cp = yy_hold_char; \\r
+               YY_RESTORE_YY_MORE_OFFSET \\r
+               yy_c_buf_p = yy_cp = yy_bp + n - YY_MORE_ADJ; \\r
+               YY_DO_BEFORE_ACTION; /* set up yytext again */ \\r
+               } \\r
+       while ( 0 )\r
+\r
+#define unput(c) yyunput( c, yytext_ptr )\r
+\r
+/* The following is because we cannot portably get our hands on size_t\r
+ * (without autoconf's help, which isn't available because we want\r
+ * flex-generated scanners to compile on their own).\r
+ */\r
+typedef unsigned int yy_size_t;\r
+\r
+\r
+struct yy_buffer_state\r
+       {\r
+       FILE *yy_input_file;\r
+\r
+       char *yy_ch_buf;                /* input buffer */\r
+       char *yy_buf_pos;               /* current position in input buffer */\r
+\r
+       /* Size of input buffer in bytes, not including room for EOB\r
+        * characters.\r
+        */\r
+       yy_size_t yy_buf_size;\r
+\r
+       /* Number of characters read into yy_ch_buf, not including EOB\r
+        * characters.\r
+        */\r
+       int yy_n_chars;\r
+\r
+       /* Whether we "own" the buffer - i.e., we know we created it,\r
+        * and can realloc() it to grow it, and should free() it to\r
+        * delete it.\r
+        */\r
+       int yy_is_our_buffer;\r
+\r
+       /* Whether this is an "interactive" input source; if so, and\r
+        * if we're using stdio for input, then we want to use getc()\r
+        * instead of fread(), to make sure we stop fetching input after\r
+        * each newline.\r
+        */\r
+       int yy_is_interactive;\r
+\r
+       /* Whether we're considered to be at the beginning of a line.\r
+        * If so, '^' rules will be active on the next match, otherwise\r
+        * not.\r
+        */\r
+       int yy_at_bol;\r
+\r
+       /* Whether to try to fill the input buffer when we reach the\r
+        * end of it.\r
+        */\r
+       int yy_fill_buffer;\r
+\r
+       int yy_buffer_status;\r
+#define YY_BUFFER_NEW 0\r
+#define YY_BUFFER_NORMAL 1\r
+       /* When an EOF's been seen but there's still some text to process\r
+        * then we mark the buffer as YY_EOF_PENDING, to indicate that we\r
+        * shouldn't try reading from the input source any more.  We might\r
+        * still have a bunch of tokens to match, though, because of\r
+        * possible backing-up.\r
+        *\r
+        * When we actually see the EOF, we change the status to "new"\r
+        * (via yyrestart()), so that the user can continue scanning by\r
+        * just pointing yyin at a new input file.\r
+        */\r
+#define YY_BUFFER_EOF_PENDING 2\r
+       };\r
+\r
+static YY_BUFFER_STATE yy_current_buffer = 0;\r
+\r
+/* We provide macros for accessing buffer states in case in the\r
+ * future we want to put the buffer states in a more general\r
+ * "scanner state".\r
+ */\r
+#define YY_CURRENT_BUFFER yy_current_buffer\r
+\r
+\r
+/* yy_hold_char holds the character lost when yytext is formed. */\r
+static char yy_hold_char;\r
+\r
+static int yy_n_chars;         /* number of characters read into yy_ch_buf */\r
+\r
+\r
+int yyleng;\r
+\r
+/* Points to current character in buffer. */\r
+static char *yy_c_buf_p = (char *) 0;\r
+static int yy_init = 1;                /* whether we need to initialize */\r
+static int yy_start = 0;       /* start state number */\r
+\r
+/* Flag which is used to allow yywrap()'s to do buffer switches\r
+ * instead of setting up a fresh yyin.  A bit of a hack ...\r
+ */\r
+static int yy_did_buffer_switch_on_eof;\r
+\r
+void yyrestart YY_PROTO(( FILE *input_file ));\r
+\r
+void yy_switch_to_buffer YY_PROTO(( YY_BUFFER_STATE new_buffer ));\r
+void yy_load_buffer_state YY_PROTO(( void ));\r
+YY_BUFFER_STATE yy_create_buffer YY_PROTO(( FILE *file, int size ));\r
+void yy_delete_buffer YY_PROTO(( YY_BUFFER_STATE b ));\r
+void yy_init_buffer YY_PROTO(( YY_BUFFER_STATE b, FILE *file ));\r
+void yy_flush_buffer YY_PROTO(( YY_BUFFER_STATE b ));\r
+#define YY_FLUSH_BUFFER yy_flush_buffer( yy_current_buffer )\r
+\r
+YY_BUFFER_STATE yy_scan_buffer YY_PROTO(( char *base, yy_size_t size ));\r
+YY_BUFFER_STATE yy_scan_string YY_PROTO(( yyconst char *yy_str ));\r
+YY_BUFFER_STATE yy_scan_bytes YY_PROTO(( yyconst char *bytes, int len ));\r
+\r
+static void *yy_flex_alloc YY_PROTO(( yy_size_t ));\r
+static void *yy_flex_realloc YY_PROTO(( void *, yy_size_t ));\r
+static void yy_flex_free YY_PROTO(( void * ));\r
+\r
+#define yy_new_buffer yy_create_buffer\r
+\r
+#define yy_set_interactive(is_interactive) \\r
+       { \\r
+       if ( ! yy_current_buffer ) \\r
+               yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \\r
+       yy_current_buffer->yy_is_interactive = is_interactive; \\r
+       }\r
+\r
+#define yy_set_bol(at_bol) \\r
+       { \\r
+       if ( ! yy_current_buffer ) \\r
+               yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \\r
+       yy_current_buffer->yy_at_bol = at_bol; \\r
+       }\r
+\r
+#define YY_AT_BOL() (yy_current_buffer->yy_at_bol)\r
+\r
+typedef unsigned char YY_CHAR;\r
+FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0;\r
+typedef int yy_state_type;\r
+extern char *yytext;\r
+#define yytext_ptr yytext\r
+\r
+static yy_state_type yy_get_previous_state YY_PROTO(( void ));\r
+static yy_state_type yy_try_NUL_trans YY_PROTO(( yy_state_type current_state ));\r
+static int yy_get_next_buffer YY_PROTO(( void ));\r
+static void yy_fatal_error YY_PROTO(( yyconst char msg[] ));\r
+\r
+/* Done after the current pattern has been matched and before the\r
+ * corresponding action - sets up yytext.\r
+ */\r
+#define YY_DO_BEFORE_ACTION \\r
+       yytext_ptr = yy_bp; \\r
+       yyleng = (int) (yy_cp - yy_bp); \\r
+       yy_hold_char = *yy_cp; \\r
+       *yy_cp = '\0'; \\r
+       yy_c_buf_p = yy_cp;\r
+\r
+#define YY_NUM_RULES 14\r
+#define YY_END_OF_BUFFER 15\r
+static yyconst short int yy_accept[28] =\r
+    {   0,\r
+        0,    0,    0,    0,   15,   13,   14,   12,    5,    6,\r
+       13,    1,    1,    3,    4,   10,    8,    9,   10,    7,\r
+        1,    1,    0,    3,   11,    2,    0\r
+    } ;\r
+\r
+static yyconst int yy_ec[256] =\r
+    {   0,\r
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    2,\r
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,\r
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,\r
+        1,    3,    1,    4,    1,    1,    1,    1,    5,    1,\r
+        1,    1,    6,    1,    6,    1,    1,    7,    8,    8,\r
+        8,    8,    8,    8,    8,    8,    8,    1,    1,    1,\r
+        1,    1,    1,    1,    9,    9,    9,    9,    9,    9,\r
+        9,    9,    9,    9,    9,    9,    9,    9,    9,    9,\r
+        9,    9,    9,    9,    9,    9,    9,   10,    9,    9,\r
+        1,   11,    1,    1,   12,   13,   14,   14,   14,   14,\r
+\r
+       14,   14,    9,    9,    9,    9,    9,    9,    9,    9,\r
+        9,    9,    9,    9,    9,    9,    9,    9,    9,   10,\r
+        9,    9,    1,    1,    1,    1,    1,    1,    1,    1,\r
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,\r
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,\r
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,\r
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,\r
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,\r
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,\r
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,\r
+\r
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,\r
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,\r
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,\r
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,\r
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,\r
+        1,    1,    1,    1,    1\r
+    } ;\r
+\r
+static yyconst int yy_meta[15] =\r
+    {   0,\r
+        1,    2,    1,    1,    1,    1,    3,    3,    4,    5,\r
+        1,    4,    1,    6\r
+    } ;\r
+\r
+static yyconst short int yy_base[33] =\r
+    {   0,\r
+        0,    0,   13,   25,   25,   62,   62,   62,   62,   62,\r
+       12,   13,   14,    0,   62,   62,   62,   62,    0,   62,\r
+        6,   24,    0,    0,   62,    0,   62,   38,   42,   45,\r
+       51,   55\r
+    } ;\r
+\r
+static yyconst short int yy_def[33] =\r
+    {   0,\r
+       27,    1,   28,   28,   27,   27,   27,   27,   27,   27,\r
+       27,   29,   27,   30,   27,   27,   27,   27,   31,   27,\r
+       29,   27,   32,   30,   27,   32,    0,   27,   27,   27,\r
+       27,   27\r
+    } ;\r
+\r
+static yyconst short int yy_nxt[77] =\r
+    {   0,\r
+        6,    7,    8,    9,   10,   11,   12,   13,   14,   14,\r
+        6,    6,   15,   14,    7,   23,   17,   18,   21,   22,\r
+       22,   22,   23,   19,   27,   20,    7,   27,   17,   18,\r
+       22,   22,   27,   27,   27,   19,   27,   20,   16,   16,\r
+       16,   16,   16,   16,   22,   27,   22,   24,   24,   24,\r
+       24,   25,   27,   25,   25,   25,   25,   26,   27,   27,\r
+       26,    5,   27,   27,   27,   27,   27,   27,   27,   27,\r
+       27,   27,   27,   27,   27,   27\r
+    } ;\r
+\r
+static yyconst short int yy_chk[77] =\r
+    {   0,\r
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,\r
+        1,    1,    1,    1,    3,   21,    3,    3,   11,   11,\r
+       13,   13,   12,    3,    5,    3,    4,    0,    4,    4,\r
+       22,   22,    0,    0,    0,    4,    0,    4,   28,   28,\r
+       28,   28,   28,   28,   29,    0,   29,   30,   30,   30,\r
+       30,   31,    0,   31,   31,   31,   31,   32,    0,    0,\r
+       32,   27,   27,   27,   27,   27,   27,   27,   27,   27,\r
+       27,   27,   27,   27,   27,   27\r
+    } ;\r
+\r
+static yy_state_type yy_last_accepting_state;\r
+static char *yy_last_accepting_cpos;\r
+\r
+/* The intent behind this definition is that it'll catch\r
+ * any uses of REJECT which flex missed.\r
+ */\r
+#define REJECT reject_used_but_not_detected\r
+#define yymore() yymore_used_but_not_detected\r
+#define YY_MORE_ADJ 0\r
+#define YY_RESTORE_YY_MORE_OFFSET\r
+char *yytext;\r
+#line 1 "D:\\ReactOS\\trunk\\reactos\\base\\applications\\winhelp\\macro.lex.l"\r
+#define INITIAL 0\r
+#line 2 "D:\\ReactOS\\trunk\\reactos\\base\\applications\\winhelp\\macro.lex.l"\r
+/*\r
+ * Help Viewer\r
+ *\r
+ * Copyright 1996 Ulrich Schmid\r
+ * Copyright 2002 Eric Pouech\r
+ *\r
+ * This library is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU Lesser General Public\r
+ * License as published by the Free Software Foundation; either\r
+ * version 2.1 of the License, or (at your option) any later version.\r
+ *\r
+ * This library is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
+ * Lesser General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU Lesser General Public\r
+ * License along with this library; if not, write to the Free Software\r
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA\r
+ */\r
+#define YY_NO_UNPUT 1\r
+#define quote 1\r
+\r
+#line 26 "D:\\ReactOS\\trunk\\reactos\\base\\applications\\winhelp\\macro.lex.l"\r
+#include <assert.h>\r
+#include "macro.h"\r
+\r
+#include "wine/debug.h"\r
+\r
+WINE_DEFAULT_DEBUG_CHANNEL(winhelp);\r
+\r
+static LPCSTR  macroptr;\r
+static LPSTR   strptr;\r
+static int     quote_stack[32];\r
+static int     quote_stk_idx = 0;\r
+struct lexret  yylval;\r
+\r
+#define YY_INPUT(buf,result,max_size)\\r
+  if ((result = *macroptr ? 1 : 0)) buf[0] = *macroptr++;\r
+\r
+#line 427 "lex.yy.c"\r
+\r
+/* Macros after this point can all be overridden by user definitions in\r
+ * section 1.\r
+ */\r
+\r
+#ifndef YY_SKIP_YYWRAP\r
+#ifdef __cplusplus\r
+extern "C" int yywrap YY_PROTO(( void ));\r
+#else\r
+extern int yywrap YY_PROTO(( void ));\r
+#endif\r
+#endif\r
+\r
+#ifndef YY_NO_UNPUT\r
+static void yyunput YY_PROTO(( int c, char *buf_ptr ));\r
+#endif\r
+\r
+#ifndef yytext_ptr\r
+static void yy_flex_strncpy YY_PROTO(( char *, yyconst char *, int ));\r
+#endif\r
+\r
+#ifdef YY_NEED_STRLEN\r
+static int yy_flex_strlen YY_PROTO(( yyconst char * ));\r
+#endif\r
+\r
+#ifndef YY_NO_INPUT\r
+#ifdef __cplusplus\r
+static int yyinput YY_PROTO(( void ));\r
+#else\r
+static int input YY_PROTO(( void ));\r
+#endif\r
+#endif\r
+\r
+#if YY_STACK_USED\r
+static int yy_start_stack_ptr = 0;\r
+static int yy_start_stack_depth = 0;\r
+static int *yy_start_stack = 0;\r
+#ifndef YY_NO_PUSH_STATE\r
+static void yy_push_state YY_PROTO(( int new_state ));\r
+#endif\r
+#ifndef YY_NO_POP_STATE\r
+static void yy_pop_state YY_PROTO(( void ));\r
+#endif\r
+#ifndef YY_NO_TOP_STATE\r
+static int yy_top_state YY_PROTO(( void ));\r
+#endif\r
+\r
+#else\r
+#define YY_NO_PUSH_STATE 1\r
+#define YY_NO_POP_STATE 1\r
+#define YY_NO_TOP_STATE 1\r
+#endif\r
+\r
+#ifdef YY_MALLOC_DECL\r
+YY_MALLOC_DECL\r
+#else\r
+#if __STDC__\r
+#ifndef __cplusplus\r
+#include <stdlib.h>\r
+#endif\r
+#else\r
+/* Just try to get by without declaring the routines.  This will fail\r
+ * miserably on non-ANSI systems for which sizeof(size_t) != sizeof(int)\r
+ * or sizeof(void*) != sizeof(int).\r
+ */\r
+#endif\r
+#endif\r
+\r
+/* Amount of stuff to slurp up with each read. */\r
+#ifndef YY_READ_BUF_SIZE\r
+#define YY_READ_BUF_SIZE 8192\r
+#endif\r
+\r
+/* Copy whatever the last rule matched to the standard output. */\r
+\r
+#ifndef ECHO\r
+/* This used to be an fputs(), but since the string might contain NUL's,\r
+ * we now use fwrite().\r
+ */\r
+#define ECHO (void) fwrite( yytext, yyleng, 1, yyout )\r
+#endif\r
+\r
+/* Gets input and stuffs it into "buf".  number of characters read, or YY_NULL,\r
+ * is returned in "result".\r
+ */\r
+#ifndef YY_INPUT\r
+#define YY_INPUT(buf,result,max_size) \\r
+       if ( yy_current_buffer->yy_is_interactive ) \\r
+               { \\r
+               int c = '*', n; \\r
+               for ( n = 0; n < max_size && \\r
+                            (c = getc( yyin )) != EOF && c != '\n'; ++n ) \\r
+                       buf[n] = (char) c; \\r
+               if ( c == '\n' ) \\r
+                       buf[n++] = (char) c; \\r
+               if ( c == EOF && ferror( yyin ) ) \\r
+                       YY_FATAL_ERROR( "input in flex scanner failed" ); \\r
+               result = n; \\r
+               } \\r
+       else if ( ((result = fread( buf, 1, max_size, yyin )) == 0) \\r
+                 && ferror( yyin ) ) \\r
+               YY_FATAL_ERROR( "input in flex scanner failed" );\r
+#endif\r
+\r
+/* No semi-colon after return; correct usage is to write "yyterminate();" -\r
+ * we don't want an extra ';' after the "return" because that will cause\r
+ * some compilers to complain about unreachable statements.\r
+ */\r
+#ifndef yyterminate\r
+#define yyterminate() return YY_NULL\r
+#endif\r
+\r
+/* Number of entries by which start-condition stack grows. */\r
+#ifndef YY_START_STACK_INCR\r
+#define YY_START_STACK_INCR 25\r
+#endif\r
+\r
+/* Report a fatal error. */\r
+#ifndef YY_FATAL_ERROR\r
+#define YY_FATAL_ERROR(msg) yy_fatal_error( msg )\r
+#endif\r
+\r
+/* Default declaration of generated scanner - a define so the user can\r
+ * easily add parameters.\r
+ */\r
+#ifndef YY_DECL\r
+#define YY_DECL int yylex YY_PROTO(( void ))\r
+#endif\r
+\r
+/* Code executed at the beginning of each rule, after yytext and yyleng\r
+ * have been set up.\r
+ */\r
+#ifndef YY_USER_ACTION\r
+#define YY_USER_ACTION\r
+#endif\r
+\r
+/* Code executed at the end of each rule. */\r
+#ifndef YY_BREAK\r
+#define YY_BREAK break;\r
+#endif\r
+\r
+#define YY_RULE_SETUP \\r
+       YY_USER_ACTION\r
+\r
+YY_DECL\r
+       {\r
+       register yy_state_type yy_current_state;\r
+       register char *yy_cp, *yy_bp;\r
+       register int yy_act;\r
+\r
+#line 43 "D:\\ReactOS\\trunk\\reactos\\base\\applications\\winhelp\\macro.lex.l"\r
+\r
+\r
+#line 581 "lex.yy.c"\r
+\r
+       if ( yy_init )\r
+               {\r
+               yy_init = 0;\r
+\r
+#ifdef YY_USER_INIT\r
+               YY_USER_INIT;\r
+#endif\r
+\r
+               if ( ! yy_start )\r
+                       yy_start = 1;   /* first start state */\r
+\r
+               if ( ! yyin )\r
+                       yyin = stdin;\r
+\r
+               if ( ! yyout )\r
+                       yyout = stdout;\r
+\r
+               if ( ! yy_current_buffer )\r
+                       yy_current_buffer =\r
+                               yy_create_buffer( yyin, YY_BUF_SIZE );\r
+\r
+               yy_load_buffer_state();\r
+               }\r
+\r
+       while ( 1 )             /* loops until end-of-file is reached */\r
+               {\r
+               yy_cp = yy_c_buf_p;\r
+\r
+               /* Support of yytext. */\r
+               *yy_cp = yy_hold_char;\r
+\r
+               /* yy_bp points to the position in yy_ch_buf of the start of\r
+                * the current run.\r
+                */\r
+               yy_bp = yy_cp;\r
+\r
+               yy_current_state = yy_start;\r
+yy_match:\r
+               do\r
+                       {\r
+                       register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)];\r
+                       if ( yy_accept[yy_current_state] )\r
+                               {\r
+                               yy_last_accepting_state = yy_current_state;\r
+                               yy_last_accepting_cpos = yy_cp;\r
+                               }\r
+                       while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )\r
+                               {\r
+                               yy_current_state = (int) yy_def[yy_current_state];\r
+                               if ( yy_current_state >= 28 )\r
+                                       yy_c = yy_meta[(unsigned int) yy_c];\r
+                               }\r
+                       yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];\r
+                       ++yy_cp;\r
+                       }\r
+               while ( yy_base[yy_current_state] != 62 );\r
+\r
+yy_find_action:\r
+               yy_act = yy_accept[yy_current_state];\r
+               if ( yy_act == 0 )\r
+                       { /* have to back up */\r
+                       yy_cp = yy_last_accepting_cpos;\r
+                       yy_current_state = yy_last_accepting_state;\r
+                       yy_act = yy_accept[yy_current_state];\r
+                       }\r
+\r
+               YY_DO_BEFORE_ACTION;\r
+\r
+\r
+do_action:     /* This label is used only to access EOF actions. */\r
+\r
+\r
+               switch ( yy_act )\r
+       { /* beginning of action switch */\r
+                       case 0: /* must back up */\r
+                       /* undo the effects of YY_DO_BEFORE_ACTION */\r
+                       *yy_cp = yy_hold_char;\r
+                       yy_cp = yy_last_accepting_cpos;\r
+                       yy_current_state = yy_last_accepting_state;\r
+                       goto yy_find_action;\r
+\r
+case 1:\r
+YY_RULE_SETUP\r
+#line 45 "D:\\ReactOS\\trunk\\reactos\\base\\applications\\winhelp\\macro.lex.l"\r
+yylval.integer = strtol(yytext, NULL, 10);     return INTEGER;\r
+       YY_BREAK\r
+case 2:\r
+YY_RULE_SETUP\r
+#line 46 "D:\\ReactOS\\trunk\\reactos\\base\\applications\\winhelp\\macro.lex.l"\r
+yylval.integer = strtol(yytext, NULL, 16);     return INTEGER;\r
+       YY_BREAK\r
+case 3:\r
+YY_RULE_SETUP\r
+#line 48 "D:\\ReactOS\\trunk\\reactos\\base\\applications\\winhelp\\macro.lex.l"\r
+return MACRO_Lookup(yytext, &yylval);\r
+       YY_BREAK\r
+case 4:\r
+#line 51 "D:\\ReactOS\\trunk\\reactos\\base\\applications\\winhelp\\macro.lex.l"\r
+case 5:\r
+#line 52 "D:\\ReactOS\\trunk\\reactos\\base\\applications\\winhelp\\macro.lex.l"\r
+case 6:\r
+#line 53 "D:\\ReactOS\\trunk\\reactos\\base\\applications\\winhelp\\macro.lex.l"\r
+case 7:\r
+#line 54 "D:\\ReactOS\\trunk\\reactos\\base\\applications\\winhelp\\macro.lex.l"\r
+case 8:\r
+#line 55 "D:\\ReactOS\\trunk\\reactos\\base\\applications\\winhelp\\macro.lex.l"\r
+case 9:\r
+YY_RULE_SETUP\r
+#line 55 "D:\\ReactOS\\trunk\\reactos\\base\\applications\\winhelp\\macro.lex.l"\r
+{\r
+    if (quote_stk_idx == 0 ||\r
+        (yytext[0] == '\"' && quote_stack[quote_stk_idx - 1] != '\"') ||\r
+        (yytext[0] == '`'))\r
+    {\r
+        /* opening a new one */\r
+        if (quote_stk_idx == 0)\r
+        {\r
+            strptr = HeapAlloc(GetProcessHeap(), 0, strlen(macroptr) + 1);\r
+            yylval.string = strptr;\r
+            BEGIN(quote);\r
+        }\r
+        else *strptr++ = yytext[0];\r
+        quote_stack[quote_stk_idx++] = yytext[0];\r
+        assert(quote_stk_idx < sizeof(quote_stack) / sizeof(quote_stack[0]));\r
+    }\r
+    else\r
+    {\r
+        if (yytext[0] == '`') assert(0);\r
+        /* close the current quote */\r
+        if (--quote_stk_idx == 0)\r
+        {\r
+            BEGIN INITIAL;\r
+            *strptr++ = '\0';\r
+            return STRING;\r
+        }\r
+        else *strptr++ = yytext[0];\r
+    }\r
+}\r
+       YY_BREAK\r
+case 10:\r
+YY_RULE_SETUP\r
+#line 85 "D:\\ReactOS\\trunk\\reactos\\base\\applications\\winhelp\\macro.lex.l"\r
+*strptr++ = yytext[0];\r
+       YY_BREAK\r
+case 11:\r
+YY_RULE_SETUP\r
+#line 86 "D:\\ReactOS\\trunk\\reactos\\base\\applications\\winhelp\\macro.lex.l"\r
+*strptr++ = yytext[1];\r
+       YY_BREAK\r
+case YY_STATE_EOF(quote):\r
+#line 87 "D:\\ReactOS\\trunk\\reactos\\base\\applications\\winhelp\\macro.lex.l"\r
+return 0;\r
+       YY_BREAK\r
+case 12:\r
+YY_RULE_SETUP\r
+#line 89 "D:\\ReactOS\\trunk\\reactos\\base\\applications\\winhelp\\macro.lex.l"\r
+\r
+       YY_BREAK\r
+case 13:\r
+YY_RULE_SETUP\r
+#line 90 "D:\\ReactOS\\trunk\\reactos\\base\\applications\\winhelp\\macro.lex.l"\r
+return yytext[0];\r
+       YY_BREAK\r
+case 14:\r
+YY_RULE_SETUP\r
+#line 91 "D:\\ReactOS\\trunk\\reactos\\base\\applications\\winhelp\\macro.lex.l"\r
+ECHO;\r
+       YY_BREAK\r
+#line 751 "lex.yy.c"\r
+case YY_STATE_EOF(INITIAL):\r
+       yyterminate();\r
+\r
+       case YY_END_OF_BUFFER:\r
+               {\r
+               /* Amount of text matched not including the EOB char. */\r
+               int yy_amount_of_matched_text = (int) (yy_cp - yytext_ptr) - 1;\r
+\r
+               /* Undo the effects of YY_DO_BEFORE_ACTION. */\r
+               *yy_cp = yy_hold_char;\r
+               YY_RESTORE_YY_MORE_OFFSET\r
+\r
+               if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_NEW )\r
+                       {\r
+                       /* We're scanning a new file or input source.  It's\r
+                        * possible that this happened because the user\r
+                        * just pointed yyin at a new source and called\r
+                        * yylex().  If so, then we have to assure\r
+                        * consistency between yy_current_buffer and our\r
+                        * globals.  Here is the right place to do so, because\r
+                        * this is the first action (other than possibly a\r
+                        * back-up) that will match for the new input source.\r
+                        */\r
+                       yy_n_chars = yy_current_buffer->yy_n_chars;\r
+                       yy_current_buffer->yy_input_file = yyin;\r
+                       yy_current_buffer->yy_buffer_status = YY_BUFFER_NORMAL;\r
+                       }\r
+\r
+               /* Note that here we test for yy_c_buf_p "<=" to the position\r
+                * of the first EOB in the buffer, since yy_c_buf_p will\r
+                * already have been incremented past the NUL character\r
+                * (since all states make transitions on EOB to the\r
+                * end-of-buffer state).  Contrast this with the test\r
+                * in input().\r
+                */\r
+               if ( yy_c_buf_p <= &yy_current_buffer->yy_ch_buf[yy_n_chars] )\r
+                       { /* This was really a NUL. */\r
+                       yy_state_type yy_next_state;\r
+\r
+                       yy_c_buf_p = yytext_ptr + yy_amount_of_matched_text;\r
+\r
+                       yy_current_state = yy_get_previous_state();\r
+\r
+                       /* Okay, we're now positioned to make the NUL\r
+                        * transition.  We couldn't have\r
+                        * yy_get_previous_state() go ahead and do it\r
+                        * for us because it doesn't know how to deal\r
+                        * with the possibility of jamming (and we don't\r
+                        * want to build jamming into it because then it\r
+                        * will run more slowly).\r
+                        */\r
+\r
+                       yy_next_state = yy_try_NUL_trans( yy_current_state );\r
+\r
+                       yy_bp = yytext_ptr + YY_MORE_ADJ;\r
+\r
+                       if ( yy_next_state )\r
+                               {\r
+                               /* Consume the NUL. */\r
+                               yy_cp = ++yy_c_buf_p;\r
+                               yy_current_state = yy_next_state;\r
+                               goto yy_match;\r
+                               }\r
+\r
+                       else\r
+                               {\r
+                               yy_cp = yy_c_buf_p;\r
+                               goto yy_find_action;\r
+                               }\r
+                       }\r
+\r
+               else switch ( yy_get_next_buffer() )\r
+                       {\r
+                       case EOB_ACT_END_OF_FILE:\r
+                               {\r
+                               yy_did_buffer_switch_on_eof = 0;\r
+\r
+                               if ( yywrap() )\r
+                                       {\r
+                                       /* Note: because we've taken care in\r
+                                        * yy_get_next_buffer() to have set up\r
+                                        * yytext, we can now set up\r
+                                        * yy_c_buf_p so that if some total\r
+                                        * hoser (like flex itself) wants to\r
+                                        * call the scanner after we return the\r
+                                        * YY_NULL, it'll still work - another\r
+                                        * YY_NULL will get returned.\r
+                                        */\r
+                                       yy_c_buf_p = yytext_ptr + YY_MORE_ADJ;\r
+\r
+                                       yy_act = YY_STATE_EOF(YY_START);\r
+                                       goto do_action;\r
+                                       }\r
+\r
+                               else\r
+                                       {\r
+                                       if ( ! yy_did_buffer_switch_on_eof )\r
+                                               YY_NEW_FILE;\r
+                                       }\r
+                               break;\r
+                               }\r
+\r
+                       case EOB_ACT_CONTINUE_SCAN:\r
+                               yy_c_buf_p =\r
+                                       yytext_ptr + yy_amount_of_matched_text;\r
+\r
+                               yy_current_state = yy_get_previous_state();\r
+\r
+                               yy_cp = yy_c_buf_p;\r
+                               yy_bp = yytext_ptr + YY_MORE_ADJ;\r
+                               goto yy_match;\r
+\r
+                       case EOB_ACT_LAST_MATCH:\r
+                               yy_c_buf_p =\r
+                               &yy_current_buffer->yy_ch_buf[yy_n_chars];\r
+\r
+                               yy_current_state = yy_get_previous_state();\r
+\r
+                               yy_cp = yy_c_buf_p;\r
+                               yy_bp = yytext_ptr + YY_MORE_ADJ;\r
+                               goto yy_find_action;\r
+                       }\r
+               break;\r
+               }\r
+\r
+       default:\r
+               YY_FATAL_ERROR(\r
+                       "fatal flex scanner internal error--no action found" );\r
+       } /* end of action switch */\r
+               } /* end of scanning one token */\r
+       } /* end of yylex */\r
+\r
+\r
+/* yy_get_next_buffer - try to read in a new buffer\r
+ *\r
+ * Returns a code representing an action:\r
+ *     EOB_ACT_LAST_MATCH -\r
+ *     EOB_ACT_CONTINUE_SCAN - continue scanning from current position\r
+ *     EOB_ACT_END_OF_FILE - end of file\r
+ */\r
+\r
+static int yy_get_next_buffer()\r
+       {\r
+       register char *dest = yy_current_buffer->yy_ch_buf;\r
+       register char *source = yytext_ptr;\r
+       register int number_to_move, i;\r
+       int ret_val;\r
+\r
+       if ( yy_c_buf_p > &yy_current_buffer->yy_ch_buf[yy_n_chars + 1] )\r
+               YY_FATAL_ERROR(\r
+               "fatal flex scanner internal error--end of buffer missed" );\r
+\r
+       if ( yy_current_buffer->yy_fill_buffer == 0 )\r
+               { /* Don't try to fill the buffer, so this is an EOF. */\r
+               if ( yy_c_buf_p - yytext_ptr - YY_MORE_ADJ == 1 )\r
+                       {\r
+                       /* We matched a single character, the EOB, so\r
+                        * treat this as a final EOF.\r
+                        */\r
+                       return EOB_ACT_END_OF_FILE;\r
+                       }\r
+\r
+               else\r
+                       {\r
+                       /* We matched some text prior to the EOB, first\r
+                        * process it.\r
+                        */\r
+                       return EOB_ACT_LAST_MATCH;\r
+                       }\r
+               }\r
+\r
+       /* Try to read more data. */\r
+\r
+       /* First move last chars to start of buffer. */\r
+       number_to_move = (int) (yy_c_buf_p - yytext_ptr) - 1;\r
+\r
+       for ( i = 0; i < number_to_move; ++i )\r
+               *(dest++) = *(source++);\r
+\r
+       if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_EOF_PENDING )\r
+               /* don't do the read, it's not guaranteed to return an EOF,\r
+                * just force an EOF\r
+                */\r
+               yy_current_buffer->yy_n_chars = yy_n_chars = 0;\r
+\r
+       else\r
+               {\r
+               int num_to_read =\r
+                       yy_current_buffer->yy_buf_size - number_to_move - 1;\r
+\r
+               while ( num_to_read <= 0 )\r
+                       { /* Not enough room in the buffer - grow it. */\r
+#ifdef YY_USES_REJECT\r
+                       YY_FATAL_ERROR(\r
+"input buffer overflow, can't enlarge buffer because scanner uses REJECT" );\r
+#else\r
+\r
+                       /* just a shorter name for the current buffer */\r
+                       YY_BUFFER_STATE b = yy_current_buffer;\r
+\r
+                       int yy_c_buf_p_offset =\r
+                               (int) (yy_c_buf_p - b->yy_ch_buf);\r
+\r
+                       if ( b->yy_is_our_buffer )\r
+                               {\r
+                               int new_size = b->yy_buf_size * 2;\r
+\r
+                               if ( new_size <= 0 )\r
+                                       b->yy_buf_size += b->yy_buf_size / 8;\r
+                               else\r
+                                       b->yy_buf_size *= 2;\r
+\r
+                               b->yy_ch_buf = (char *)\r
+                                       /* Include room in for 2 EOB chars. */\r
+                                       yy_flex_realloc( (void *) b->yy_ch_buf,\r
+                                                        b->yy_buf_size + 2 );\r
+                               }\r
+                       else\r
+                               /* Can't grow it, we don't own it. */\r
+                               b->yy_ch_buf = 0;\r
+\r
+                       if ( ! b->yy_ch_buf )\r
+                               YY_FATAL_ERROR(\r
+                               "fatal error - scanner input buffer overflow" );\r
+\r
+                       yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset];\r
+\r
+                       num_to_read = yy_current_buffer->yy_buf_size -\r
+                                               number_to_move - 1;\r
+#endif\r
+                       }\r
+\r
+               if ( num_to_read > YY_READ_BUF_SIZE )\r
+                       num_to_read = YY_READ_BUF_SIZE;\r
+\r
+               /* Read in more data. */\r
+               YY_INPUT( (&yy_current_buffer->yy_ch_buf[number_to_move]),\r
+                       yy_n_chars, num_to_read );\r
+\r
+               yy_current_buffer->yy_n_chars = yy_n_chars;\r
+               }\r
+\r
+       if ( yy_n_chars == 0 )\r
+               {\r
+               if ( number_to_move == YY_MORE_ADJ )\r
+                       {\r
+                       ret_val = EOB_ACT_END_OF_FILE;\r
+                       yyrestart( yyin );\r
+                       }\r
+\r
+               else\r
+                       {\r
+                       ret_val = EOB_ACT_LAST_MATCH;\r
+                       yy_current_buffer->yy_buffer_status =\r
+                               YY_BUFFER_EOF_PENDING;\r
+                       }\r
+               }\r
+\r
+       else\r
+               ret_val = EOB_ACT_CONTINUE_SCAN;\r
+\r
+       yy_n_chars += number_to_move;\r
+       yy_current_buffer->yy_ch_buf[yy_n_chars] = YY_END_OF_BUFFER_CHAR;\r
+       yy_current_buffer->yy_ch_buf[yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR;\r
+\r
+       yytext_ptr = &yy_current_buffer->yy_ch_buf[0];\r
+\r
+       return ret_val;\r
+       }\r
+\r
+\r
+/* yy_get_previous_state - get the state just before the EOB char was reached */\r
+\r
+static yy_state_type yy_get_previous_state()\r
+       {\r
+       register yy_state_type yy_current_state;\r
+       register char *yy_cp;\r
+\r
+       yy_current_state = yy_start;\r
+\r
+       for ( yy_cp = yytext_ptr + YY_MORE_ADJ; yy_cp < yy_c_buf_p; ++yy_cp )\r
+               {\r
+               register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);\r
+               if ( yy_accept[yy_current_state] )\r
+                       {\r
+                       yy_last_accepting_state = yy_current_state;\r
+                       yy_last_accepting_cpos = yy_cp;\r
+                       }\r
+               while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )\r
+                       {\r
+                       yy_current_state = (int) yy_def[yy_current_state];\r
+                       if ( yy_current_state >= 28 )\r
+                               yy_c = yy_meta[(unsigned int) yy_c];\r
+                       }\r
+               yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];\r
+               }\r
+\r
+       return yy_current_state;\r
+       }\r
+\r
+\r
+/* yy_try_NUL_trans - try to make a transition on the NUL character\r
+ *\r
+ * synopsis\r
+ *     next_state = yy_try_NUL_trans( current_state );\r
+ */\r
+\r
+#ifdef YY_USE_PROTOS\r
+static yy_state_type yy_try_NUL_trans( yy_state_type yy_current_state )\r
+#else\r
+static yy_state_type yy_try_NUL_trans( yy_current_state )\r
+yy_state_type yy_current_state;\r
+#endif\r
+       {\r
+       register int yy_is_jam;\r
+       register char *yy_cp = yy_c_buf_p;\r
+\r
+       register YY_CHAR yy_c = 1;\r
+       if ( yy_accept[yy_current_state] )\r
+               {\r
+               yy_last_accepting_state = yy_current_state;\r
+               yy_last_accepting_cpos = yy_cp;\r
+               }\r
+       while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )\r
+               {\r
+               yy_current_state = (int) yy_def[yy_current_state];\r
+               if ( yy_current_state >= 28 )\r
+                       yy_c = yy_meta[(unsigned int) yy_c];\r
+               }\r
+       yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];\r
+       yy_is_jam = (yy_current_state == 27);\r
+\r
+       return yy_is_jam ? 0 : yy_current_state;\r
+       }\r
+\r
+\r
+#ifndef YY_NO_UNPUT\r
+#ifdef YY_USE_PROTOS\r
+static void yyunput( int c, register char *yy_bp )\r
+#else\r
+static void yyunput( c, yy_bp )\r
+int c;\r
+register char *yy_bp;\r
+#endif\r
+       {\r
+       register char *yy_cp = yy_c_buf_p;\r
+\r
+       /* undo effects of setting up yytext */\r
+       *yy_cp = yy_hold_char;\r
+\r
+       if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 )\r
+               { /* need to shift things up to make room */\r
+               /* +2 for EOB chars. */\r
+               register int number_to_move = yy_n_chars + 2;\r
+               register char *dest = &yy_current_buffer->yy_ch_buf[\r
+                                       yy_current_buffer->yy_buf_size + 2];\r
+               register char *source =\r
+                               &yy_current_buffer->yy_ch_buf[number_to_move];\r
+\r
+               while ( source > yy_current_buffer->yy_ch_buf )\r
+                       *--dest = *--source;\r
+\r
+               yy_cp += (int) (dest - source);\r
+               yy_bp += (int) (dest - source);\r
+               yy_current_buffer->yy_n_chars =\r
+                       yy_n_chars = yy_current_buffer->yy_buf_size;\r
+\r
+               if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 )\r
+                       YY_FATAL_ERROR( "flex scanner push-back overflow" );\r
+               }\r
+\r
+       *--yy_cp = (char) c;\r
+\r
+\r
+       yytext_ptr = yy_bp;\r
+       yy_hold_char = *yy_cp;\r
+       yy_c_buf_p = yy_cp;\r
+       }\r
+#endif /* ifndef YY_NO_UNPUT */\r
+\r
+\r
+#ifdef __cplusplus\r
+static int yyinput()\r
+#else\r
+static int input()\r
+#endif\r
+       {\r
+       int c;\r
+\r
+       *yy_c_buf_p = yy_hold_char;\r
+\r
+       if ( *yy_c_buf_p == YY_END_OF_BUFFER_CHAR )\r
+               {\r
+               /* yy_c_buf_p now points to the character we want to return.\r
+                * If this occurs *before* the EOB characters, then it's a\r
+                * valid NUL; if not, then we've hit the end of the buffer.\r
+                */\r
+               if ( yy_c_buf_p < &yy_current_buffer->yy_ch_buf[yy_n_chars] )\r
+                       /* This was really a NUL. */\r
+                       *yy_c_buf_p = '\0';\r
+\r
+               else\r
+                       { /* need more input */\r
+                       int offset = yy_c_buf_p - yytext_ptr;\r
+                       ++yy_c_buf_p;\r
+\r
+                       switch ( yy_get_next_buffer() )\r
+                               {\r
+                               case EOB_ACT_LAST_MATCH:\r
+                                       /* This happens because yy_g_n_b()\r
+                                        * sees that we've accumulated a\r
+                                        * token and flags that we need to\r
+                                        * try matching the token before\r
+                                        * proceeding.  But for input(),\r
+                                        * there's no matching to consider.\r
+                                        * So convert the EOB_ACT_LAST_MATCH\r
+                                        * to EOB_ACT_END_OF_FILE.\r
+                                        */\r
+\r
+                                       /* Reset buffer status. */\r
+                                       yyrestart( yyin );\r
+\r
+                                       /* fall through */\r
+\r
+                               case EOB_ACT_END_OF_FILE:\r
+                                       {\r
+                                       if ( yywrap() )\r
+                                               return EOF;\r
+\r
+                                       if ( ! yy_did_buffer_switch_on_eof )\r
+                                               YY_NEW_FILE;\r
+#ifdef __cplusplus\r
+                                       return yyinput();\r
+#else\r
+                                       return input();\r
+#endif\r
+                                       }\r
+\r
+                               case EOB_ACT_CONTINUE_SCAN:\r
+                                       yy_c_buf_p = yytext_ptr + offset;\r
+                                       break;\r
+                               }\r
+                       }\r
+               }\r
+\r
+       c = *(unsigned char *) yy_c_buf_p;      /* cast for 8-bit char's */\r
+       *yy_c_buf_p = '\0';     /* preserve yytext */\r
+       yy_hold_char = *++yy_c_buf_p;\r
+\r
+\r
+       return c;\r
+       }\r
+\r
+\r
+#ifdef YY_USE_PROTOS\r
+void yyrestart( FILE *input_file )\r
+#else\r
+void yyrestart( input_file )\r
+FILE *input_file;\r
+#endif\r
+       {\r
+       if ( ! yy_current_buffer )\r
+               yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE );\r
+\r
+       yy_init_buffer( yy_current_buffer, input_file );\r
+       yy_load_buffer_state();\r
+       }\r
+\r
+\r
+#ifdef YY_USE_PROTOS\r
+void yy_switch_to_buffer( YY_BUFFER_STATE new_buffer )\r
+#else\r
+void yy_switch_to_buffer( new_buffer )\r
+YY_BUFFER_STATE new_buffer;\r
+#endif\r
+       {\r
+       if ( yy_current_buffer == new_buffer )\r
+               return;\r
+\r
+       if ( yy_current_buffer )\r
+               {\r
+               /* Flush out information for old buffer. */\r
+               *yy_c_buf_p = yy_hold_char;\r
+               yy_current_buffer->yy_buf_pos = yy_c_buf_p;\r
+               yy_current_buffer->yy_n_chars = yy_n_chars;\r
+               }\r
+\r
+       yy_current_buffer = new_buffer;\r
+       yy_load_buffer_state();\r
+\r
+       /* We don't actually know whether we did this switch during\r
+        * EOF (yywrap()) processing, but the only time this flag\r
+        * is looked at is after yywrap() is called, so it's safe\r
+        * to go ahead and always set it.\r
+        */\r
+       yy_did_buffer_switch_on_eof = 1;\r
+       }\r
+\r
+\r
+#ifdef YY_USE_PROTOS\r
+void yy_load_buffer_state( void )\r
+#else\r
+void yy_load_buffer_state()\r
+#endif\r
+       {\r
+       yy_n_chars = yy_current_buffer->yy_n_chars;\r
+       yytext_ptr = yy_c_buf_p = yy_current_buffer->yy_buf_pos;\r
+       yyin = yy_current_buffer->yy_input_file;\r
+       yy_hold_char = *yy_c_buf_p;\r
+       }\r
+\r
+\r
+#ifdef YY_USE_PROTOS\r
+YY_BUFFER_STATE yy_create_buffer( FILE *file, int size )\r
+#else\r
+YY_BUFFER_STATE yy_create_buffer( file, size )\r
+FILE *file;\r
+int size;\r
+#endif\r
+       {\r
+       YY_BUFFER_STATE b;\r
+\r
+       b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) );\r
+       if ( ! b )\r
+               YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );\r
+\r
+       b->yy_buf_size = size;\r
+\r
+       /* yy_ch_buf has to be 2 characters longer than the size given because\r
+        * we need to put in 2 end-of-buffer characters.\r
+        */\r
+       b->yy_ch_buf = (char *) yy_flex_alloc( b->yy_buf_size + 2 );\r
+       if ( ! b->yy_ch_buf )\r
+               YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );\r
+\r
+       b->yy_is_our_buffer = 1;\r
+\r
+       yy_init_buffer( b, file );\r
+\r
+       return b;\r
+       }\r
+\r
+\r
+#ifdef YY_USE_PROTOS\r
+void yy_delete_buffer( YY_BUFFER_STATE b )\r
+#else\r
+void yy_delete_buffer( b )\r
+YY_BUFFER_STATE b;\r
+#endif\r
+       {\r
+       if ( ! b )\r
+               return;\r
+\r
+       if ( b == yy_current_buffer )\r
+               yy_current_buffer = (YY_BUFFER_STATE) 0;\r
+\r
+       if ( b->yy_is_our_buffer )\r
+               yy_flex_free( (void *) b->yy_ch_buf );\r
+\r
+       yy_flex_free( (void *) b );\r
+       }\r
+\r
+\r
+#ifndef YY_ALWAYS_INTERACTIVE\r
+#ifndef YY_NEVER_INTERACTIVE\r
+extern int isatty YY_PROTO(( int ));\r
+#endif\r
+#endif\r
+\r
+#ifdef YY_USE_PROTOS\r
+void yy_init_buffer( YY_BUFFER_STATE b, FILE *file )\r
+#else\r
+void yy_init_buffer( b, file )\r
+YY_BUFFER_STATE b;\r
+FILE *file;\r
+#endif\r
+\r
+\r
+       {\r
+       yy_flush_buffer( b );\r
+\r
+       b->yy_input_file = file;\r
+       b->yy_fill_buffer = 1;\r
+\r
+#if YY_ALWAYS_INTERACTIVE\r
+       b->yy_is_interactive = 1;\r
+#else\r
+#if YY_NEVER_INTERACTIVE\r
+       b->yy_is_interactive = 0;\r
+#else\r
+       b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0;\r
+#endif\r
+#endif\r
+       }\r
+\r
+\r
+#ifdef YY_USE_PROTOS\r
+void yy_flush_buffer( YY_BUFFER_STATE b )\r
+#else\r
+void yy_flush_buffer( b )\r
+YY_BUFFER_STATE b;\r
+#endif\r
+\r
+       {\r
+       if ( ! b )\r
+               return;\r
+\r
+       b->yy_n_chars = 0;\r
+\r
+       /* We always need two end-of-buffer characters.  The first causes\r
+        * a transition to the end-of-buffer state.  The second causes\r
+        * a jam in that state.\r
+        */\r
+       b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;\r
+       b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;\r
+\r
+       b->yy_buf_pos = &b->yy_ch_buf[0];\r
+\r
+       b->yy_at_bol = 1;\r
+       b->yy_buffer_status = YY_BUFFER_NEW;\r
+\r
+       if ( b == yy_current_buffer )\r
+               yy_load_buffer_state();\r
+       }\r
+\r
+\r
+#ifndef YY_NO_SCAN_BUFFER\r
+#ifdef YY_USE_PROTOS\r
+YY_BUFFER_STATE yy_scan_buffer( char *base, yy_size_t size )\r
+#else\r
+YY_BUFFER_STATE yy_scan_buffer( base, size )\r
+char *base;\r
+yy_size_t size;\r
+#endif\r
+       {\r
+       YY_BUFFER_STATE b;\r
+\r
+       if ( size < 2 ||\r
+            base[size-2] != YY_END_OF_BUFFER_CHAR ||\r
+            base[size-1] != YY_END_OF_BUFFER_CHAR )\r
+               /* They forgot to leave room for the EOB's. */\r
+               return 0;\r
+\r
+       b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) );\r
+       if ( ! b )\r
+               YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" );\r
+\r
+       b->yy_buf_size = size - 2;      /* "- 2" to take care of EOB's */\r
+       b->yy_buf_pos = b->yy_ch_buf = base;\r
+       b->yy_is_our_buffer = 0;\r
+       b->yy_input_file = 0;\r
+       b->yy_n_chars = b->yy_buf_size;\r
+       b->yy_is_interactive = 0;\r
+       b->yy_at_bol = 1;\r
+       b->yy_fill_buffer = 0;\r
+       b->yy_buffer_status = YY_BUFFER_NEW;\r
+\r
+       yy_switch_to_buffer( b );\r
+\r
+       return b;\r
+       }\r
+#endif\r
+\r
+\r
+#ifndef YY_NO_SCAN_STRING\r
+#ifdef YY_USE_PROTOS\r
+YY_BUFFER_STATE yy_scan_string( yyconst char *yy_str )\r
+#else\r
+YY_BUFFER_STATE yy_scan_string( yy_str )\r
+yyconst char *yy_str;\r
+#endif\r
+       {\r
+       int len;\r
+       for ( len = 0; yy_str[len]; ++len )\r
+               ;\r
+\r
+       return yy_scan_bytes( yy_str, len );\r
+       }\r
+#endif\r
+\r
+\r
+#ifndef YY_NO_SCAN_BYTES\r
+#ifdef YY_USE_PROTOS\r
+YY_BUFFER_STATE yy_scan_bytes( yyconst char *bytes, int len )\r
+#else\r
+YY_BUFFER_STATE yy_scan_bytes( bytes, len )\r
+yyconst char *bytes;\r
+int len;\r
+#endif\r
+       {\r
+       YY_BUFFER_STATE b;\r
+       char *buf;\r
+       yy_size_t n;\r
+       int i;\r
+\r
+       /* Get memory for full buffer, including space for trailing EOB's. */\r
+       n = len + 2;\r
+       buf = (char *) yy_flex_alloc( n );\r
+       if ( ! buf )\r
+               YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" );\r
+\r
+       for ( i = 0; i < len; ++i )\r
+               buf[i] = bytes[i];\r
+\r
+       buf[len] = buf[len+1] = YY_END_OF_BUFFER_CHAR;\r
+\r
+       b = yy_scan_buffer( buf, n );\r
+       if ( ! b )\r
+               YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" );\r
+\r
+       /* It's okay to grow etc. this buffer, and we should throw it\r
+        * away when we're done.\r
+        */\r
+       b->yy_is_our_buffer = 1;\r
+\r
+       return b;\r
+       }\r
+#endif\r
+\r
+\r
+#ifndef YY_NO_PUSH_STATE\r
+#ifdef YY_USE_PROTOS\r
+static void yy_push_state( int new_state )\r
+#else\r
+static void yy_push_state( new_state )\r
+int new_state;\r
+#endif\r
+       {\r
+       if ( yy_start_stack_ptr >= yy_start_stack_depth )\r
+               {\r
+               yy_size_t new_size;\r
+\r
+               yy_start_stack_depth += YY_START_STACK_INCR;\r
+               new_size = yy_start_stack_depth * sizeof( int );\r
+\r
+               if ( ! yy_start_stack )\r
+                       yy_start_stack = (int *) yy_flex_alloc( new_size );\r
+\r
+               else\r
+                       yy_start_stack = (int *) yy_flex_realloc(\r
+                                       (void *) yy_start_stack, new_size );\r
+\r
+               if ( ! yy_start_stack )\r
+                       YY_FATAL_ERROR(\r
+                       "out of memory expanding start-condition stack" );\r
+               }\r
+\r
+       yy_start_stack[yy_start_stack_ptr++] = YY_START;\r
+\r
+       BEGIN(new_state);\r
+       }\r
+#endif\r
+\r
+\r
+#ifndef YY_NO_POP_STATE\r
+static void yy_pop_state()\r
+       {\r
+       if ( --yy_start_stack_ptr < 0 )\r
+               YY_FATAL_ERROR( "start-condition stack underflow" );\r
+\r
+       BEGIN(yy_start_stack[yy_start_stack_ptr]);\r
+       }\r
+#endif\r
+\r
+\r
+#ifndef YY_NO_TOP_STATE\r
+static int yy_top_state()\r
+       {\r
+       return yy_start_stack[yy_start_stack_ptr - 1];\r
+       }\r
+#endif\r
+\r
+#ifndef YY_EXIT_FAILURE\r
+#define YY_EXIT_FAILURE 2\r
+#endif\r
+\r
+#ifdef YY_USE_PROTOS\r
+static void yy_fatal_error( yyconst char msg[] )\r
+#else\r
+static void yy_fatal_error( msg )\r
+char msg[];\r
+#endif\r
+       {\r
+       (void) fprintf( stderr, "%s\n", msg );\r
+       exit( YY_EXIT_FAILURE );\r
+       }\r
+\r
+\r
+\r
+/* Redefine yyless() so it works in section 3 code. */\r
+\r
+#undef yyless\r
+#define yyless(n) \\r
+       do \\r
+               { \\r
+               /* Undo effects of setting up yytext. */ \\r
+               yytext[yyleng] = yy_hold_char; \\r
+               yy_c_buf_p = yytext + n; \\r
+               yy_hold_char = *yy_c_buf_p; \\r
+               *yy_c_buf_p = '\0'; \\r
+               yyleng = n; \\r
+               } \\r
+       while ( 0 )\r
+\r
+\r
+/* Internal utility routines. */\r
+\r
+#ifndef yytext_ptr\r
+#ifdef YY_USE_PROTOS\r
+static void yy_flex_strncpy( char *s1, yyconst char *s2, int n )\r
+#else\r
+static void yy_flex_strncpy( s1, s2, n )\r
+char *s1;\r
+yyconst char *s2;\r
+int n;\r
+#endif\r
+       {\r
+       register int i;\r
+       for ( i = 0; i < n; ++i )\r
+               s1[i] = s2[i];\r
+       }\r
+#endif\r
+\r
+#ifdef YY_NEED_STRLEN\r
+#ifdef YY_USE_PROTOS\r
+static int yy_flex_strlen( yyconst char *s )\r
+#else\r
+static int yy_flex_strlen( s )\r
+yyconst char *s;\r
+#endif\r
+       {\r
+       register int n;\r
+       for ( n = 0; s[n]; ++n )\r
+               ;\r
+\r
+       return n;\r
+       }\r
+#endif\r
+\r
+\r
+#ifdef YY_USE_PROTOS\r
+static void *yy_flex_alloc( yy_size_t size )\r
+#else\r
+static void *yy_flex_alloc( size )\r
+yy_size_t size;\r
+#endif\r
+       {\r
+       return (void *) malloc( size );\r
+       }\r
+\r
+#ifdef YY_USE_PROTOS\r
+static void *yy_flex_realloc( void *ptr, yy_size_t size )\r
+#else\r
+static void *yy_flex_realloc( ptr, size )\r
+void *ptr;\r
+yy_size_t size;\r
+#endif\r
+       {\r
+       /* The cast to (char *) in the following accommodates both\r
+        * implementations that use char* generic pointers, and those\r
+        * that use void* generic pointers.  It works with the latter\r
+        * because both ANSI C and C++ allow castless assignment from\r
+        * any pointer type to void*, and deal with argument conversions\r
+        * as though doing an assignment.\r
+        */\r
+       return (void *) realloc( (char *) ptr, size );\r
+       }\r
+\r
+#ifdef YY_USE_PROTOS\r
+static void yy_flex_free( void *ptr )\r
+#else\r
+static void yy_flex_free( ptr )\r
+void *ptr;\r
+#endif\r
+       {\r
+       free( ptr );\r
+       }\r
+\r
+#if YY_MAIN\r
+int main()\r
+       {\r
+       yylex();\r
+       return 0;\r
+       }\r
+#endif\r
+#line 91 "D:\\ReactOS\\trunk\\reactos\\base\\applications\\winhelp\\macro.lex.l"\r
+\r
+\r
+#if 0\r
+/* all code for testing macros */\r
+#include "winhelp.h"\r
+static CHAR szTestMacro[256];\r
+\r
+static LRESULT CALLBACK MACRO_TestDialogProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)\r
+{\r
+    if (msg == WM_COMMAND && wParam == IDOK)\r
+    {\r
+        GetDlgItemText(hDlg, 99, szTestMacro, sizeof(szTestMacro));\r
+        EndDialog(hDlg, IDOK);\r
+        return TRUE;\r
+    }\r
+    return FALSE;\r
+}\r
+\r
+void macro_test(void)\r
+{\r
+    WNDPROC lpfnDlg = MakeProcInstance(MACRO_TestDialogProc, Globals.hInstance);\r
+    DialogBox(Globals.hInstance, STRING_DIALOG_TEST, Globals.active_win->hMainWnd, (DLGPROC)lpfnDlg);\r
+    FreeProcInstance(lpfnDlg);\r
+    macro = szTestMacro;\r
+}\r
+#endif\r
+\r
+/* small helper function for debug messages */\r
+static const char* ts(int t)\r
+{\r
+    static char c[2] = {0,0};\r
+\r
+    switch (t)\r
+    {\r
+    case EMPTY: return "EMPTY";\r
+    case VOID_FUNCTION: return "VOID_FUNCTION";\r
+    case BOOL_FUNCTION: return "BOOL_FUNCTION";\r
+    case INTEGER: return "INTEGER";\r
+    case STRING: return "STRING";\r
+    case IDENTIFIER: return "IDENTIFIER";\r
+    default: c[0] = (char)t; return c;\r
+    }\r
+}\r
+\r
+static int MACRO_CallBoolFunc(FARPROC fn, const char* args, void** ret);\r
+\r
+/******************************************************************\r
+ *             MACRO_CheckArgs\r
+ *\r
+ * checks number of arguments against prototype, and stores arguments on\r
+ * stack pa for later call\r
+ * returns -1 on error, otherwise the number of pushed parameters\r
+ */\r
+static int MACRO_CheckArgs(void* pa[], unsigned max, const char* args)\r
+{\r
+    int         t;\r
+    int         len = 0, idx = 0;\r
+\r
+    WINE_TRACE("Checking %s\n", args);\r
+\r
+    if (yylex() != '(') {WINE_WARN("missing (\n");return -1;}\r
+\r
+    if (*args)\r
+    {\r
+        len = strlen(args);\r
+        for (;;)\r
+        {\r
+            t = yylex();\r
+            WINE_TRACE("Got %s <=> %c\n", ts(t), *args);\r
+\r
+            switch (*args)\r
+            {\r
+            case 'S': \r
+                if (t != STRING)\r
+                {WINE_WARN("missing S\n");return -1;}\r
+                pa[idx] = (void*)yylval.string;  \r
+                break;\r
+            case 'U':\r
+            case 'I':\r
+                if (t != INTEGER)\r
+                {WINE_WARN("missing U\n");return -1;}   \r
+                pa[idx] = (void*)yylval.integer; \r
+                break;\r
+            case 'B':\r
+                if (t != BOOL_FUNCTION) \r
+                {WINE_WARN("missing B\n");return -1;}   \r
+                if (MACRO_CallBoolFunc(yylval.function, yylval.proto, &pa[idx]) == 0)\r
+                    return -1;\r
+                break;\r
+            default: \r
+                WINE_WARN("unexpected %s while args is %c\n", ts(t), *args);\r
+                return -1;\r
+            }\r
+            idx++;\r
+            if (*++args == '\0') break;\r
+            t = yylex();\r
+            if (t == ')') goto CheckArgs_end;\r
+            if (t != ',') {WINE_WARN("missing ,\n");return -1;}\r
+            if (idx >= max) {WINE_FIXME("stack overflow (%d)\n", max);return -1;}\r
+        }\r
+    }\r
+    if (yylex() != ')') {WINE_WARN("missing )\n");return -1;}\r
+\r
+CheckArgs_end:\r
+    while (len > idx) pa[--len] = NULL;\r
+    return idx;\r
+}\r
+\r
+/******************************************************************\r
+ *             MACRO_CallBoolFunc\r
+ *\r
+ * Invokes boolean function fn, which arguments are defined by args\r
+ * stores bool result into ret\r
+ */\r
+static int MACRO_CallBoolFunc(FARPROC fn, const char* args, void** ret)\r
+{\r
+    void*       pa[2];\r
+    int         idx = MACRO_CheckArgs(pa, sizeof(pa)/sizeof(pa[0]), args);\r
+\r
+    if (idx < 0) return 0;\r
+    if (!fn)     return 1;\r
+\r
+    WINE_TRACE("calling with %u pmts\n", idx);\r
+\r
+    switch (strlen(args))\r
+    {\r
+    case 0: *ret = (void*)(fn)();          break;\r
+    case 1: *ret = (void*)(fn)(pa[0]);     break;\r
+    default: WINE_FIXME("NIY\n");\r
+    }\r
+\r
+    return 1;\r
+}\r
+\r
+/******************************************************************\r
+ *             MACRO_CallVoidFunc\r
+ *\r
+ *\r
+ */\r
+static int MACRO_CallVoidFunc(FARPROC fn, const char* args)\r
+{\r
+    void*       pa[6];\r
+    int         idx = MACRO_CheckArgs(pa, sizeof(pa)/sizeof(pa[0]), args);\r
+\r
+    if (idx < 0) return 0;\r
+    if (!fn)     return 1;\r
+\r
+    WINE_TRACE("calling %p with %u pmts\n", fn, idx);\r
+\r
+    switch (strlen(args))\r
+    {\r
+    case 0: (fn)();                                     break;\r
+    case 1: (fn)(pa[0]);                                break;\r
+    case 2: (fn)(pa[0],pa[1]);                          break;\r
+    case 3: (fn)(pa[0],pa[1],pa[2]);                    break;\r
+    case 4: (fn)(pa[0],pa[1],pa[2],pa[3]);              break;\r
+    case 5: (fn)(pa[0],pa[1],pa[2],pa[3],pa[4]);        break;\r
+    case 6: (fn)(pa[0],pa[1],pa[2],pa[3],pa[4],pa[5]);  break;\r
+    default: WINE_FIXME("NIY\n");\r
+    }\r
+\r
+    return 1;\r
+}\r
+\r
+BOOL MACRO_ExecuteMacro(LPCSTR macro)\r
+{\r
+    int t;\r
+\r
+    //WINE_TRACE("%s\n", wine_dbgstr_a(macro));\r
+\r
+    macroptr = macro;\r
+\r
+    while ((t = yylex()) != EMPTY)\r
+    {\r
+        switch (t)\r
+        {\r
+        case VOID_FUNCTION:\r
+            WINE_TRACE("got type void func(%s)\n", yylval.proto);\r
+            MACRO_CallVoidFunc(yylval.function, yylval.proto);\r
+            break;\r
+        case BOOL_FUNCTION:\r
+            WINE_WARN("got type bool func(%s)\n", yylval.proto);\r
+            break;\r
+        default:\r
+            WINE_WARN("got unexpected type %s\n", ts(t));\r
+            return 0;\r
+        }\r
+        switch (t = yylex())\r
+        {\r
+        case EMPTY:     return 1;\r
+        case ';':       break;\r
+        default:        return 0;\r
+        }\r
+    }\r
+\r
+    HeapFree(GetProcessHeap(), 0, strptr);\r
+    strptr = NULL;\r
+    quote_stk_idx = 0;\r
+\r
+    return 1;\r
+}\r
+\r
+#ifndef yywrap\r
+int yywrap(void) { return 1; }\r
+#endif\r
diff --git a/reactos/base/applications/winhelp/macro.c b/reactos/base/applications/winhelp/macro.c
new file mode 100644 (file)
index 0000000..803b5bb
--- /dev/null
@@ -0,0 +1,928 @@
+/*
+ * Help Viewer
+ *
+ * Copyright 1996 Ulrich Schmid
+ * Copyright 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
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#define WIN32_LEAN_AND_MEAN
+
+#include <stdio.h>
+
+#include "windows.h"
+#include "commdlg.h"
+#include "winhelp.h"
+
+#include "wine/debug.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(winhelp);
+
+/**************************************************/
+/*               Macro table                      */
+/**************************************************/
+struct MacroDesc {
+    const char* name;
+    const char* alias;
+    BOOL        isBool;
+    const char* arguments;
+    FARPROC     fn;
+};
+
+/* types:
+ *      U:      32 bit unsigned int
+ *      I:      32 bit signed int
+ *      S:      string
+ *      v:      unknown (32 bit entity)
+ */
+
+static struct MacroDesc MACRO_Builtins[] = {
+    {"About",               NULL, 0, "",       (FARPROC)MACRO_About},
+    {"AddAccelerator",      "AA", 0, "UUS",    (FARPROC)MACRO_AddAccelerator},
+    {"ALink",               "AL", 0, "SUS",    (FARPROC)MACRO_ALink},
+    {"Annotate",            NULL, 0, "",       (FARPROC)MACRO_Annotate},
+    {"AppendItem",          NULL, 0, "SSSS",   (FARPROC)MACRO_AppendItem},
+    {"Back",                NULL, 0, "",       (FARPROC)MACRO_Back},
+    {"BackFlush",           "BF", 0, "",       (FARPROC)MACRO_BackFlush},
+    {"BookmarkDefine",      NULL, 0, "",       (FARPROC)MACRO_BookmarkDefine},
+    {"BookmarkMore",        NULL, 0, "",       (FARPROC)MACRO_BookmarkMore},
+    {"BrowseButtons",       NULL, 0, "",       (FARPROC)MACRO_BrowseButtons},
+    {"ChangeButtonBinding", "CBB",0, "SS",     (FARPROC)MACRO_ChangeButtonBinding},
+    {"ChangeEnable",        "CE", 0, "SS",     (FARPROC)MACRO_ChangeEnable},
+    {"ChangeItemBinding",   "CIB",0, "SS",     (FARPROC)MACRO_ChangeItemBinding},
+    {"CheckItem",           "CI", 0, "S",      (FARPROC)MACRO_CheckItem},
+    {"CloseSecondarys",     "CS", 0, "",       (FARPROC)MACRO_CloseSecondarys},
+    {"CloseWindow",         "CW", 0, "S",      (FARPROC)MACRO_CloseWindow},
+    {"Compare",             NULL, 0, "S",      (FARPROC)MACRO_Compare},
+    {"Contents",            NULL, 0, "",       (FARPROC)MACRO_Contents},
+    {"ControlPanel",        NULL, 0, "SSU",    (FARPROC)MACRO_ControlPanel},
+    {"CopyDialog",          NULL, 0, "",       (FARPROC)MACRO_CopyDialog},
+    {"CopyTopic",           "CT", 0, "",       (FARPROC)MACRO_CopyTopic},
+    {"CreateButton",        "CB", 0, "SSS",    (FARPROC)MACRO_CreateButton},
+    {"DeleteItem",          NULL, 0, "S",      (FARPROC)MACRO_DeleteItem},
+    {"DeleteMark",          NULL, 0, "S",      (FARPROC)MACRO_DeleteMark},
+    {"DestroyButton",       NULL, 0, "S",      (FARPROC)MACRO_DestroyButton},
+    {"DisableButton",       "DB", 0, "S",      (FARPROC)MACRO_DisableButton},
+    {"DisableItem",         "DI", 0, "S",      (FARPROC)MACRO_DisableItem},
+    {"EnableButton",        "EB", 0, "S",      (FARPROC)MACRO_EnableButton},
+    {"EnableItem",          "EI", 0, "S",      (FARPROC)MACRO_EnableItem},
+    {"EndMPrint",           NULL, 0, "",       (FARPROC)MACRO_EndMPrint},
+    {"ExecFile",            "EF", 0, "SSUS",   (FARPROC)MACRO_ExecFile},
+    {"ExecProgram",         "EP", 0, "SU",     (FARPROC)MACRO_ExecProgram},
+    {"Exit",                NULL, 0, "",       (FARPROC)MACRO_Exit},
+    {"ExtAbleItem",         NULL, 0, "SU",     (FARPROC)MACRO_ExtAbleItem},
+    {"ExtInsertItem",       NULL, 0, "SSSSUU", (FARPROC)MACRO_ExtInsertItem},
+    {"ExtInsertMenu",       NULL, 0, "SSSUU",  (FARPROC)MACRO_ExtInsertMenu},
+    {"FileExist",           "FE", 1, "S",      (FARPROC)MACRO_FileExist},
+    {"FileOpen",            "FO", 0, "",       (FARPROC)MACRO_FileOpen},
+    {"Find",                NULL, 0, "",       (FARPROC)MACRO_Find},
+    {"Finder",              "FD", 0, "",       (FARPROC)MACRO_Finder},
+    {"FloatingMenu",        NULL, 0, "",       (FARPROC)MACRO_FloatingMenu},
+    {"Flush",               "FH", 0, "",       (FARPROC)MACRO_Flush},
+    {"FocusWindow",         NULL, 0, "S",      (FARPROC)MACRO_FocusWindow},
+    {"Generate",            NULL, 0, "SUU",    (FARPROC)MACRO_Generate},
+    {"GotoMark",            NULL, 0, "S",      (FARPROC)MACRO_GotoMark},
+    {"HelpOn",              NULL, 0, "",       (FARPROC)MACRO_HelpOn},
+    {"HelpOnTop",           NULL, 0, "",       (FARPROC)MACRO_HelpOnTop},
+    {"History",             NULL, 0, "",       (FARPROC)MACRO_History},
+    {"InitMPrint",          NULL, 1, "",       (FARPROC)MACRO_InitMPrint},
+    {"InsertItem",          NULL, 0, "SSSSU",  (FARPROC)MACRO_InsertItem},
+    {"InsertMenu",          NULL, 0, "SSU",    (FARPROC)MACRO_InsertMenu},
+    {"IfThen",              "IF", 0, "BS",     (FARPROC)MACRO_IfThen},
+    {"IfThenElse",          "IE", 0, "BSS",    (FARPROC)MACRO_IfThenElse},
+    {"IsBook",              NULL, 1, "",       (FARPROC)MACRO_IsBook},
+    {"IsMark",              NULL, 1, "S",      (FARPROC)MACRO_IsMark},
+    {"IsNotMark",           "NM", 1, "S",      (FARPROC)MACRO_IsNotMark},
+    {"JumpContents",        NULL, 0, "SS",     (FARPROC)MACRO_JumpContents},
+    {"JumpContext",         "JC", 0, "SSU",    (FARPROC)MACRO_JumpContext},
+    {"JumpHash",            "JH", 0, "SSU",    (FARPROC)MACRO_JumpHash},
+    {"JumpHelpOn",          NULL, 0, "",       (FARPROC)MACRO_JumpHelpOn},
+    {"JumpID",              "JI", 0, "SSS",    (FARPROC)MACRO_JumpID},
+    {"JumpKeyword",         "JK", 0, "SSS",    (FARPROC)MACRO_JumpKeyword},
+    {"KLink",               "KL", 0, "SUSS",   (FARPROC)MACRO_KLink},
+    {"Menu",                "MU", 0, "",       (FARPROC)MACRO_Menu},
+    {"MPrintHash",          NULL, 0, "U",      (FARPROC)MACRO_MPrintHash},
+    {"MPrintID",            NULL, 0, "S",      (FARPROC)MACRO_MPrintID},
+    {"Next",                NULL, 0, "",       (FARPROC)MACRO_Next},
+    {"NoShow",              NULL, 0, "",       (FARPROC)MACRO_NoShow},
+    {"PopupContext",        "PC", 0, "SU",     (FARPROC)MACRO_PopupContext},
+    {"PopupHash",           NULL, 0, "SU",     (FARPROC)MACRO_PopupHash},
+    {"PopupId",             "PI", 0, "SS",     (FARPROC)MACRO_PopupId},
+    {"PositionWindow",      "PW", 0, "IIUUUS", (FARPROC)MACRO_PositionWindow},
+    {"Prev",                NULL, 0, "",       (FARPROC)MACRO_Prev},
+    {"Print",               NULL, 0, "",       (FARPROC)MACRO_Print},
+    {"PrinterSetup",        NULL, 0, "",       (FARPROC)MACRO_PrinterSetup},
+    {"RegisterRoutine",     "RR", 0, "SSS",    (FARPROC)MACRO_RegisterRoutine},
+    {"RemoveAccelerator",   "RA", 0, "UU",     (FARPROC)MACRO_RemoveAccelerator},
+    {"ResetMenu",           NULL, 0, "",       (FARPROC)MACRO_ResetMenu},
+    {"SaveMark",            NULL, 0, "S",      (FARPROC)MACRO_SaveMark},
+    {"Search",              NULL, 0, "",       (FARPROC)MACRO_Search},
+    {"SetContents",         NULL, 0, "SU",     (FARPROC)MACRO_SetContents},
+    {"SetHelpOnFile",       NULL, 0, "S",      (FARPROC)MACRO_SetHelpOnFile},
+    {"SetPopupColor",       "SPC",0, "UUU",    (FARPROC)MACRO_SetPopupColor},
+    {"ShellExecute",        "SE", 0, "SSUUSS", (FARPROC)MACRO_ShellExecute},
+    {"ShortCut",            "SH", 0, "SSUUS",  (FARPROC)MACRO_ShortCut},
+    {"TCard",               NULL, 0, "U",      (FARPROC)MACRO_TCard},
+    {"Test",                NULL, 0, "U",      (FARPROC)MACRO_Test},
+    {"TestALink",           NULL, 1, "S",      (FARPROC)MACRO_TestALink},
+    {"TestKLink",           NULL, 1, "S",      (FARPROC)MACRO_TestKLink},
+    {"UncheckItem",         "UI", 0, "S",      (FARPROC)MACRO_UncheckItem},
+    {"UpdateWindow",        "UW", 0, "SS",     (FARPROC)MACRO_UpdateWindow},
+    {NULL,                  NULL, 0, NULL,     NULL}
+};
+
+static struct MacroDesc*MACRO_Loaded /* = NULL */;
+static unsigned         MACRO_NumLoaded /* = 0 */;
+
+static int MACRO_DoLookUp(struct MacroDesc* start, const char* name, struct lexret* lr, unsigned len)
+{
+    struct MacroDesc*   md;
+
+    for (md = start; md->name && len != 0; md++, len--)
+    {
+        if (strcasecmp(md->name, name) == 0 || (md->alias != NULL && strcasecmp(md->alias, name) == 0))
+        {
+            lr->proto = md->arguments;
+            lr->function = md->fn;
+            return md->isBool ? BOOL_FUNCTION : VOID_FUNCTION;
+        }
+    }
+    return EMPTY;
+}
+
+int MACRO_Lookup(const char* name, struct lexret* lr)
+{
+    int ret;
+
+    if ((ret = MACRO_DoLookUp(MACRO_Builtins, name, lr, -1)) != EMPTY)
+        return ret;
+    if (MACRO_Loaded && (ret = MACRO_DoLookUp(MACRO_Loaded, name, lr, MACRO_NumLoaded)) != EMPTY)
+        return ret;
+
+    lr->string = name;
+    return IDENTIFIER;
+}
+
+/*******      helper functions     *******/
+
+static WINHELP_BUTTON**        MACRO_LookupButton(WINHELP_WINDOW* win, LPCSTR name)
+{
+    WINHELP_BUTTON**    b;
+
+    for (b = &win->first_button; *b; b = &(*b)->next)
+        if (!lstrcmpi(name, (*b)->lpszID)) break;
+    return b;
+}
+
+/******* real macro implementation *******/
+
+void CALLBACK MACRO_About(void)
+{
+    WINE_FIXME("()\n");
+}
+
+void CALLBACK MACRO_AddAccelerator(LONG u1, LONG u2, LPCSTR str)
+{
+    WINE_FIXME("(%u, %u, \"%s\")\n", u1, u2, str);
+}
+
+void CALLBACK MACRO_ALink(LPCSTR str1, LONG u, LPCSTR str2)
+{
+    WINE_FIXME("(\"%s\", %u, \"%s\")\n", str1, u, str2);
+}
+
+void CALLBACK MACRO_Annotate(void)
+{
+    WINE_FIXME("()\n");
+}
+
+void CALLBACK MACRO_AppendItem(LPCSTR str1, LPCSTR str2, LPCSTR str3, LPCSTR str4)
+{
+    WINE_FIXME("(\"%s\", \"%s\", \"%s\", \"%s\")\n", str1, str2, str3, str4);
+}
+
+void CALLBACK MACRO_Back(void)
+{
+    WINHELP_WINDOW* win = Globals.active_win;
+
+    WINE_TRACE("()\n");
+
+    if (win && win->backIndex >= 2)
+        WINHELP_CreateHelpWindow(win->back[--win->backIndex - 1],
+                                 win->info, SW_SHOW);
+}
+
+void CALLBACK MACRO_BackFlush(void)
+{
+    WINHELP_WINDOW* win = Globals.active_win;
+
+    WINE_TRACE("()\n");
+
+    if (win)
+    {
+        int     i;
+
+        for (i = 0; i < win->backIndex; i++)
+        {
+            HLPFILE_FreeHlpFile(win->back[i]->file);
+            win->back[i] = NULL;
+        }
+        win->backIndex = 0;
+    }
+}
+
+void CALLBACK MACRO_BookmarkDefine(void)
+{
+    WINE_FIXME("()\n");
+}
+
+void CALLBACK MACRO_BookmarkMore(void)
+{
+    WINE_FIXME("()\n");
+}
+
+void CALLBACK MACRO_BrowseButtons(void)
+{
+    WINE_TRACE("()\n");
+
+    MACRO_CreateButton("BTN_PREV", "&<<", "Prev()");
+    MACRO_CreateButton("BTN_NEXT", "&>>", "Next()");
+}
+
+void CALLBACK MACRO_ChangeButtonBinding(LPCSTR id, LPCSTR macro)
+{
+    WINHELP_WINDOW*     win = Globals.active_win;
+    WINHELP_BUTTON*     button;
+    WINHELP_BUTTON**    b;
+    LONG                size;
+    LPSTR               ptr;
+
+    WINE_TRACE("(\"%s\", \"%s\")\n", id, macro);
+
+    b = MACRO_LookupButton(win, id);
+    if (!*b) {WINE_FIXME("Couldn't find button '%s'\n", id); return;}
+
+    size = sizeof(WINHELP_BUTTON) + lstrlen(id) +
+        lstrlen((*b)->lpszName) + lstrlen(macro) + 3;
+
+    button = HeapAlloc(GetProcessHeap(), 0, size);
+    if (!button) return;
+
+    button->next  = (*b)->next;
+    button->hWnd  = (*b)->hWnd;
+    button->wParam = (*b)->wParam;
+
+    ptr = (char*)button + sizeof(WINHELP_BUTTON);
+
+    lstrcpy(ptr, id);
+    button->lpszID = ptr;
+    ptr += lstrlen(id) + 1;
+
+    lstrcpy(ptr, (*b)->lpszName);
+    button->lpszName = ptr;
+    ptr += lstrlen((*b)->lpszName) + 1;
+
+    lstrcpy(ptr, macro);
+    button->lpszMacro = ptr;
+
+    *b = button;
+
+    SendMessage(win->hMainWnd, WM_USER, 0, 0);
+}
+
+void CALLBACK MACRO_ChangeEnable(LPCSTR id, LPCSTR macro)
+{
+    WINE_TRACE("(\"%s\", \"%s\")\n", id, macro);
+
+    MACRO_ChangeButtonBinding(id, macro);
+    MACRO_EnableButton(id);
+}
+
+void CALLBACK MACRO_ChangeItemBinding(LPCSTR str1, LPCSTR str2)
+{
+    WINE_FIXME("(\"%s\", \"%s\")\n", str1, str2);
+}
+
+void CALLBACK MACRO_CheckItem(LPCSTR str)
+{
+    WINE_FIXME("(\"%s\")\n", str);
+}
+
+void CALLBACK MACRO_CloseSecondarys(void)
+{
+    WINHELP_WINDOW *win;
+
+    WINE_TRACE("()\n");
+    for (win = Globals.win_list; win; win = win->next)
+        if (win->lpszName && lstrcmpi(win->lpszName, "main"))
+            DestroyWindow(win->hMainWnd);
+}
+
+void CALLBACK MACRO_CloseWindow(LPCSTR lpszWindow)
+{
+    WINHELP_WINDOW *win;
+
+    WINE_TRACE("(\"%s\")\n", lpszWindow);
+
+    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);
+}
+
+void CALLBACK MACRO_Compare(LPCSTR str)
+{
+    WINE_FIXME("(\"%s\")\n", str);
+}
+
+void CALLBACK MACRO_Contents(void)
+{
+    WINE_TRACE("()\n");
+
+    if (Globals.active_win->page)
+        MACRO_JumpContents(Globals.active_win->page->file->lpszPath, NULL);
+}
+
+void CALLBACK MACRO_ControlPanel(LPCSTR str1, LPCSTR str2, LONG u)
+{
+    WINE_FIXME("(\"%s\", \"%s\", %u)\n", str1, str2, u);
+}
+
+void CALLBACK MACRO_CopyDialog(void)
+{
+    WINE_FIXME("()\n");
+}
+
+void CALLBACK MACRO_CopyTopic(void)
+{
+    WINE_FIXME("()\n");
+}
+
+void CALLBACK MACRO_CreateButton(LPCSTR id, LPCSTR name, LPCSTR macro)
+{
+    WINHELP_WINDOW *win = Globals.active_win;
+    WINHELP_BUTTON *button, **b;
+    LONG            size;
+    LPSTR           ptr;
+
+    WINE_TRACE("(\"%s\", \"%s\", %s)\n", id, name, macro);
+
+    size = sizeof(WINHELP_BUTTON) + lstrlen(id) + lstrlen(name) + lstrlen(macro) + 3;
+
+    button = HeapAlloc(GetProcessHeap(), 0, size);
+    if (!button) return;
+
+    button->next  = 0;
+    button->hWnd  = 0;
+
+    ptr = (char*)button + sizeof(WINHELP_BUTTON);
+
+    lstrcpy(ptr, id);
+    button->lpszID = ptr;
+    ptr += lstrlen(id) + 1;
+
+    lstrcpy(ptr, name);
+    button->lpszName = ptr;
+    ptr += lstrlen(name) + 1;
+
+    lstrcpy(ptr, macro);
+    button->lpszMacro = ptr;
+
+    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 CALLBACK MACRO_DeleteItem(LPCSTR str)
+{
+    WINE_FIXME("(\"%s\")\n", str);
+}
+
+void CALLBACK MACRO_DeleteMark(LPCSTR str)
+{
+    WINE_FIXME("(\"%s\")\n", str);
+}
+
+void CALLBACK MACRO_DestroyButton(LPCSTR str)
+{
+    WINE_FIXME("(\"%s\")\n", str);
+}
+
+void CALLBACK MACRO_DisableButton(LPCSTR id)
+{
+    WINHELP_BUTTON**    b;
+
+    WINE_FIXME("(\"%s\")\n", id);
+
+    b = MACRO_LookupButton(Globals.active_win, id);
+    if (!*b) {WINE_FIXME("Couldn't find button '%s'\n", id); return;}
+
+    EnableWindow((*b)->hWnd, FALSE);
+}
+
+void CALLBACK MACRO_DisableItem(LPCSTR str)
+{
+    WINE_FIXME("(\"%s\")\n", str);
+}
+
+void CALLBACK MACRO_EnableButton(LPCSTR id)
+{
+    WINHELP_BUTTON**    b;
+
+    WINE_TRACE("(\"%s\")\n", id);
+
+    b = MACRO_LookupButton(Globals.active_win, id);
+    if (!*b) {WINE_FIXME("Couldn't find button '%s'\n", id); return;}
+
+    EnableWindow((*b)->hWnd, TRUE);
+}
+
+void CALLBACK MACRO_EnableItem(LPCSTR str)
+{
+    WINE_FIXME("(\"%s\")\n", str);
+}
+
+void CALLBACK MACRO_EndMPrint(void)
+{
+    WINE_FIXME("()\n");
+}
+
+void CALLBACK MACRO_ExecFile(LPCSTR str1, LPCSTR str2, LONG u, LPCSTR str3)
+{
+    WINE_FIXME("(\"%s\", \"%s\", %u, \"%s\")\n", str1, str2, u, str3);
+}
+
+void CALLBACK MACRO_ExecProgram(LPCSTR str, LONG u)
+{
+    WINE_FIXME("(\"%s\", %u)\n", str, u);
+}
+
+void CALLBACK MACRO_Exit(void)
+{
+    WINE_TRACE("()\n");
+
+    while (Globals.win_list)
+        DestroyWindow(Globals.win_list->hMainWnd);
+}
+
+void CALLBACK MACRO_ExtAbleItem(LPCSTR str, LONG u)
+{
+    WINE_FIXME("(\"%s\", %u)\n", str, u);
+}
+
+void CALLBACK MACRO_ExtInsertItem(LPCSTR str1, LPCSTR str2, LPCSTR str3, LPCSTR str4, LONG u1, LONG u2)
+{
+    WINE_FIXME("(\"%s\", \"%s\", \"%s\", \"%s\", %u, %u)\n", str1, str2, str3, str4, u1, u2);
+}
+
+void CALLBACK MACRO_ExtInsertMenu(LPCSTR str1, LPCSTR str2, LPCSTR str3, LONG u1, LONG u2)
+{
+    WINE_FIXME("(\"%s\", \"%s\", \"%s\", %u, %u)\n", str1, str2, str3, u1, u2);
+}
+
+BOOL CALLBACK MACRO_FileExist(LPCSTR str)
+{
+    WINE_TRACE("(\"%s\")\n", str);
+    return GetFileAttributes(str) != INVALID_FILE_ATTRIBUTES;
+}
+
+void CALLBACK MACRO_FileOpen(void)
+{
+    char szFile[MAX_PATH];
+
+    if (WINHELP_GetOpenFileName(szFile, MAX_PATH))
+    {
+        HLPFILE*        hlpfile = WINHELP_LookupHelpFile(szFile);
+
+        WINHELP_CreateHelpWindowByHash(hlpfile, 0,
+                                       WINHELP_GetWindowInfo(hlpfile, "main"), SW_SHOWNORMAL);
+    }
+}
+
+void CALLBACK MACRO_Find(void)
+{
+    WINE_FIXME("()\n");
+}
+
+void CALLBACK MACRO_Finder(void)
+{
+    WINE_FIXME("()\n");
+}
+
+void CALLBACK MACRO_FloatingMenu(void)
+{
+    WINE_FIXME("()\n");
+}
+
+void CALLBACK MACRO_Flush(void)
+{
+    WINE_FIXME("()\n");
+}
+
+void CALLBACK MACRO_FocusWindow(LPCSTR lpszWindow)
+{
+    WINHELP_WINDOW *win;
+
+    WINE_TRACE("(\"%s\")\n", lpszWindow);
+
+    if (!lpszWindow || !lpszWindow[0]) lpszWindow = "main";
+
+    for (win = Globals.win_list; win; win = win->next)
+        if (win->lpszName && !lstrcmpi(win->lpszName, lpszWindow))
+            SetFocus(win->hMainWnd);
+}
+
+void CALLBACK MACRO_Generate(LPCSTR str, LONG w, LONG l)
+{
+    WINE_FIXME("(\"%s\", %x, %x)\n", str, w, l);
+}
+
+void CALLBACK MACRO_GotoMark(LPCSTR str)
+{
+    WINE_FIXME("(\"%s\")\n", str);
+}
+
+void CALLBACK MACRO_HelpOn(void)
+{
+    WINE_TRACE("()\n");
+    MACRO_JumpContents((Globals.wVersion > 4) ? "winhelp32.hlp" : "winhelp.hlp", NULL);
+}
+
+void CALLBACK MACRO_HelpOnTop(void)
+{
+    WINE_FIXME("()\n");
+}
+
+void CALLBACK MACRO_History(void)
+{
+    WINE_TRACE("()\n");
+
+    if (Globals.active_win && !Globals.active_win->hHistoryWnd)
+    {
+        HWND hWnd = CreateWindow(HISTORY_WIN_CLASS_NAME, "History", WS_OVERLAPPEDWINDOW,
+                                 0, 0, 0, 0, 0, 0, Globals.hInstance, Globals.active_win);
+        ShowWindow(hWnd, SW_NORMAL);
+    }
+}
+
+void CALLBACK MACRO_IfThen(BOOL b, LPCSTR t)
+{
+    if (b) MACRO_ExecuteMacro(t);
+}
+
+void CALLBACK MACRO_IfThenElse(BOOL b, LPCSTR t, LPCSTR f)
+{
+    if (b) MACRO_ExecuteMacro(t); else MACRO_ExecuteMacro(f);
+}
+
+BOOL CALLBACK MACRO_InitMPrint(void)
+{
+    WINE_FIXME("()\n");
+    return FALSE;
+}
+
+void CALLBACK MACRO_InsertItem(LPCSTR str1, LPCSTR str2, LPCSTR str3, LPCSTR str4, LONG u)
+{
+    WINE_FIXME("(\"%s\", \"%s\", \"%s\", \"%s\", %u)\n", str1, str2, str3, str4, u);
+}
+
+void CALLBACK MACRO_InsertMenu(LPCSTR str1, LPCSTR str2, LONG u)
+{
+    WINE_FIXME("(\"%s\", \"%s\", %u)\n", str1, str2, u);
+}
+
+BOOL CALLBACK MACRO_IsBook(void)
+{
+    WINE_TRACE("()\n");
+    return Globals.isBook;
+}
+
+BOOL CALLBACK MACRO_IsMark(LPCSTR str)
+{
+    WINE_FIXME("(\"%s\")\n", str);
+    return FALSE;
+}
+
+BOOL CALLBACK MACRO_IsNotMark(LPCSTR str)
+{
+    WINE_FIXME("(\"%s\")\n", str);
+    return TRUE;
+}
+
+void CALLBACK MACRO_JumpContents(LPCSTR lpszPath, LPCSTR lpszWindow)
+{
+    HLPFILE*    hlpfile;
+
+    WINE_TRACE("(\"%s\", \"%s\")\n", lpszPath, lpszWindow);
+    hlpfile = WINHELP_LookupHelpFile(lpszPath);
+    WINHELP_CreateHelpWindowByHash(hlpfile, 0,
+                                   WINHELP_GetWindowInfo(hlpfile, lpszWindow),
+                                   SW_NORMAL);
+}
+
+void CALLBACK MACRO_JumpContext(LPCSTR lpszPath, LPCSTR lpszWindow, LONG context)
+{
+    HLPFILE*    hlpfile;
+
+    WINE_TRACE("(\"%s\", \"%s\", %d)\n", lpszPath, lpszWindow, context);
+    hlpfile = WINHELP_LookupHelpFile(lpszPath);
+    /* Some madness: what user calls 'context', hlpfile calls 'map' */
+    WINHELP_CreateHelpWindowByMap(hlpfile, context,
+                                  WINHELP_GetWindowInfo(hlpfile, lpszWindow),
+                                  SW_NORMAL);
+}
+
+void CALLBACK MACRO_JumpHash(LPCSTR lpszPath, LPCSTR lpszWindow, LONG lHash)
+{
+    HLPFILE*    hlpfile;
+
+    WINE_TRACE("(\"%s\", \"%s\", %u)\n", lpszPath, lpszWindow, lHash);
+    hlpfile = WINHELP_LookupHelpFile(lpszPath);
+    WINHELP_CreateHelpWindowByHash(hlpfile, lHash,
+                                   WINHELP_GetWindowInfo(hlpfile, lpszWindow),
+                                   SW_NORMAL);
+}
+
+void CALLBACK MACRO_JumpHelpOn(void)
+{
+    WINE_FIXME("()\n");
+}
+
+/* FIXME: those two macros are wrong
+ * they should only contain 2 strings, path & window are coded as path>window
+ */
+void CALLBACK MACRO_JumpID(LPCSTR lpszPath, LPCSTR lpszWindow, LPCSTR topic_id)
+{
+    WINE_TRACE("(\"%s\", \"%s\", \"%s\")\n", lpszPath, lpszWindow, topic_id);
+    MACRO_JumpHash(lpszPath, lpszWindow, HLPFILE_Hash(topic_id));
+}
+
+void CALLBACK MACRO_JumpKeyword(LPCSTR lpszPath, LPCSTR lpszWindow, LPCSTR keyword)
+{
+    WINE_FIXME("(\"%s\", \"%s\", \"%s\")\n", lpszPath, lpszWindow, keyword);
+}
+
+void CALLBACK MACRO_KLink(LPCSTR str1, LONG u, LPCSTR str2, LPCSTR str3)
+{
+    WINE_FIXME("(\"%s\", %u, \"%s\", \"%s\")\n", str1, u, str2, str3);
+}
+
+void CALLBACK MACRO_Menu(void)
+{
+    WINE_FIXME("()\n");
+}
+
+void CALLBACK MACRO_MPrintHash(LONG u)
+{
+    WINE_FIXME("(%u)\n", u);
+}
+
+void CALLBACK MACRO_MPrintID(LPCSTR str)
+{
+    WINE_FIXME("(\"%s\")\n", str);
+}
+
+void CALLBACK MACRO_Next(void)
+{
+    HLPFILE_PAGE*   page;
+
+    WINE_TRACE("()\n");
+    page = Globals.active_win->page;
+    page = HLPFILE_PageByOffset(page->file, page->browse_fwd);
+    if (page)
+    {
+        page->file->wRefCount++;
+        WINHELP_CreateHelpWindow(page, Globals.active_win->info, SW_NORMAL);
+    }
+}
+
+void CALLBACK MACRO_NoShow(void)
+{
+    WINE_FIXME("()\n");
+}
+
+void CALLBACK MACRO_PopupContext(LPCSTR str, LONG u)
+{
+    WINE_FIXME("(\"%s\", %u)\n", str, u);
+}
+
+void CALLBACK MACRO_PopupHash(LPCSTR str, LONG u)
+{
+    WINE_FIXME("(\"%s\", %u)\n", str, u);
+}
+
+void CALLBACK MACRO_PopupId(LPCSTR str1, LPCSTR str2)
+{
+    WINE_FIXME("(\"%s\", \"%s\")\n", str1, str2);
+}
+
+void CALLBACK MACRO_PositionWindow(LONG i1, LONG i2, LONG u1, LONG u2, LONG u3, LPCSTR str)
+{
+    WINE_FIXME("(%i, %i, %u, %u, %u, \"%s\")\n", i1, i2, u1, u2, u3, str);
+}
+
+void CALLBACK MACRO_Prev(void)
+{
+    HLPFILE_PAGE*   page;
+
+    WINE_TRACE("()\n");
+    page = Globals.active_win->page;
+    page = HLPFILE_PageByOffset(page->file, page->browse_bwd);
+    if (page)
+    {
+        page->file->wRefCount++;
+        WINHELP_CreateHelpWindow(page, Globals.active_win->info, SW_NORMAL);
+    }
+}
+
+void CALLBACK MACRO_Print(void)
+{
+    PRINTDLG printer;
+
+    WINE_TRACE("()\n");
+
+    printer.lStructSize         = sizeof(printer);
+    printer.hwndOwner           = Globals.active_win->hMainWnd;
+    printer.hInstance           = Globals.hInstance;
+    printer.hDevMode            = 0;
+    printer.hDevNames           = 0;
+    printer.hDC                 = 0;
+    printer.Flags               = 0;
+    printer.nFromPage           = 0;
+    printer.nToPage             = 0;
+    printer.nMinPage            = 0;
+    printer.nMaxPage            = 0;
+    printer.nCopies             = 0;
+    printer.lCustData           = 0;
+    printer.lpfnPrintHook       = 0;
+    printer.lpfnSetupHook       = 0;
+    printer.lpPrintTemplateName = 0;
+    printer.lpSetupTemplateName = 0;
+    printer.hPrintTemplate      = 0;
+    printer.hSetupTemplate      = 0;
+
+    if (PrintDlgA(&printer)) {
+        WINE_FIXME("Print()\n");
+    }
+}
+
+void CALLBACK MACRO_PrinterSetup(void)
+{
+    WINE_FIXME("()\n");
+}
+
+void CALLBACK MACRO_RegisterRoutine(LPCSTR dll_name, LPCSTR proc, LPCSTR args)
+{
+    FARPROC             fn = NULL;
+    int                 size;
+    WINHELP_DLL*        dll;
+
+    WINE_TRACE("(\"%s\", \"%s\", \"%s\")\n", dll_name, proc, args);
+
+    /* FIXME: are the registered DLLs global or linked to the current file ???
+     * We assume globals (as we did for macros, but is this really the case ???)
+     */
+    for (dll = Globals.dlls; dll; dll = dll->next)
+    {
+        if (!strcmp(dll->name, dll_name)) break;
+    }
+    if (!dll)
+    {
+        HANDLE hLib = LoadLibrary(dll_name);
+
+        /* FIXME: the library will not be unloaded until exit of program 
+         * We don't send the DW_TERM message
+         */
+        WINE_TRACE("Loading %s\n", dll_name);
+        /* FIXME: should look in the directory where current hlpfile
+         * is loaded from
+         */
+        if (hLib == NULL)
+        {
+            /* FIXME: internationalisation for error messages */
+            WINE_FIXME("Cannot find dll %s\n", dll_name);
+        }
+        else if ((dll = HeapAlloc(GetProcessHeap(), 0, sizeof(*dll))))
+        {
+            dll->hLib = hLib;
+            dll->name = strdup(dll_name); /* FIXME */
+            dll->next = Globals.dlls;
+            Globals.dlls = dll;
+            dll->handler = (WINHELP_LDLLHandler)GetProcAddress(dll->hLib, "LDLLHandler");
+            dll->class = dll->handler ? (dll->handler)(DW_WHATMSG, 0, 0) : DC_NOMSG;
+            WINE_TRACE("Got class %x for DLL %s\n", dll->class, dll_name);
+            if (dll->class & DC_INITTERM) dll->handler(DW_INIT, 0, 0);
+            if (dll->class & DC_CALLBACKS) dll->handler(DW_CALLBACKS, (DWORD)Callbacks, 0);
+        }
+        else WINE_WARN("OOM\n");
+    }
+    if (dll && !(fn = GetProcAddress(dll->hLib, proc)))
+    {
+        /* FIXME: internationalisation for error messages */
+        WINE_FIXME("Cannot find proc %s in dll %s\n", dll_name, proc);
+    }
+
+    size = ++MACRO_NumLoaded * sizeof(struct MacroDesc);
+    if (!MACRO_Loaded) MACRO_Loaded = HeapAlloc(GetProcessHeap(), 0, size);
+    else MACRO_Loaded = HeapReAlloc(GetProcessHeap(), 0, MACRO_Loaded, size);
+    MACRO_Loaded[MACRO_NumLoaded - 1].name      = strdup(proc); /* FIXME */
+    MACRO_Loaded[MACRO_NumLoaded - 1].alias     = NULL;
+    MACRO_Loaded[MACRO_NumLoaded - 1].isBool    = 0;
+    MACRO_Loaded[MACRO_NumLoaded - 1].arguments = strdup(args); /* FIXME */
+    MACRO_Loaded[MACRO_NumLoaded - 1].fn        = fn;
+    WINE_TRACE("Added %s(%s) at %p\n", proc, args, fn);
+}
+
+void CALLBACK MACRO_RemoveAccelerator(LONG u1, LONG u2)
+{
+    WINE_FIXME("(%u, %u)\n", u1, u2);
+}
+
+void CALLBACK MACRO_ResetMenu(void)
+{
+    WINE_FIXME("()\n");
+}
+
+void CALLBACK MACRO_SaveMark(LPCSTR str)
+{
+    WINE_FIXME("(\"%s\")\n", str);
+}
+
+void CALLBACK MACRO_Search(void)
+{
+    WINE_FIXME("()\n");
+}
+
+void CALLBACK MACRO_SetContents(LPCSTR str, LONG u)
+{
+    WINE_FIXME("(\"%s\", %u)\n", str, u);
+}
+
+void CALLBACK MACRO_SetHelpOnFile(LPCSTR str)
+{
+    WINE_FIXME("(\"%s\")\n", str);
+}
+
+void CALLBACK MACRO_SetPopupColor(LONG u1, LONG u2, LONG u3)
+{
+    WINE_FIXME("(%u, %u, %u)\n", u1, u2, u3);
+}
+
+void CALLBACK MACRO_ShellExecute(LPCSTR str1, LPCSTR str2, LONG u1, LONG u2, LPCSTR str3, LPCSTR str4)
+{
+    WINE_FIXME("(\"%s\", \"%s\", %u, %u, \"%s\", \"%s\")\n", str1, str2, u1, u2, str3, str4);
+}
+
+void CALLBACK MACRO_ShortCut(LPCSTR str1, LPCSTR str2, LONG w, LONG l, LPCSTR str)
+{
+    WINE_FIXME("(\"%s\", \"%s\", %x, %x, \"%s\")\n", str1, str2, w, l, str);
+}
+
+void CALLBACK MACRO_TCard(LONG u)
+{
+    WINE_FIXME("(%u)\n", u);
+}
+
+void CALLBACK MACRO_Test(LONG u)
+{
+    WINE_FIXME("(%u)\n", u);
+}
+
+BOOL CALLBACK MACRO_TestALink(LPCSTR str)
+{
+    WINE_FIXME("(\"%s\")\n", str);
+    return FALSE;
+}
+
+BOOL CALLBACK MACRO_TestKLink(LPCSTR str)
+{
+    WINE_FIXME("(\"%s\")\n", str);
+    return FALSE;
+}
+
+void CALLBACK MACRO_UncheckItem(LPCSTR str)
+{
+    WINE_FIXME("(\"%s\")\n", str);
+}
+
+void CALLBACK MACRO_UpdateWindow(LPCSTR str1, LPCSTR str2)
+{
+    WINE_FIXME("(\"%s\", \"%s\")\n", str1, str2);
+}
diff --git a/reactos/base/applications/winhelp/macro.h b/reactos/base/applications/winhelp/macro.h
new file mode 100644 (file)
index 0000000..68be1c6
--- /dev/null
@@ -0,0 +1,140 @@
+/*
+ * Help Viewer
+ *
+ * Copyright 1996 Ulrich Schmid
+ * Copyright 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
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef __MACRO_H__
+#define __MACRO_H__
+
+#include <stdarg.h>
+
+#include "windef.h"
+#include "winbase.h"
+
+struct lexret {
+  LPCSTR        proto;
+  BOOL          bool;
+  LONG          integer;
+  LPCSTR        string;
+  FARPROC       function;
+};
+
+extern struct lexret yylval;
+
+BOOL MACRO_ExecuteMacro(LPCSTR);
+int  MACRO_Lookup(const char* name, struct lexret* lr);
+
+enum token_types {EMPTY, VOID_FUNCTION, BOOL_FUNCTION, INTEGER, STRING, IDENTIFIER};
+void CALLBACK MACRO_About(void);
+void CALLBACK MACRO_AddAccelerator(LONG, LONG, LPCSTR);
+void CALLBACK MACRO_ALink(LPCSTR, LONG, LPCSTR);
+void CALLBACK MACRO_Annotate(void);
+void CALLBACK MACRO_AppendItem(LPCSTR, LPCSTR, LPCSTR, LPCSTR);
+void CALLBACK MACRO_Back(void);
+void CALLBACK MACRO_BackFlush(void);
+void CALLBACK MACRO_BookmarkDefine(void);
+void CALLBACK MACRO_BookmarkMore(void);
+void CALLBACK MACRO_BrowseButtons(void);
+void CALLBACK MACRO_ChangeButtonBinding(LPCSTR, LPCSTR);
+void CALLBACK MACRO_ChangeEnable(LPCSTR, LPCSTR);
+void CALLBACK MACRO_ChangeItemBinding(LPCSTR, LPCSTR);
+void CALLBACK MACRO_CheckItem(LPCSTR);
+void CALLBACK MACRO_CloseSecondarys(void);
+void CALLBACK MACRO_CloseWindow(LPCSTR);
+void CALLBACK MACRO_Compare(LPCSTR);
+void CALLBACK MACRO_Contents(void);
+void CALLBACK MACRO_ControlPanel(LPCSTR, LPCSTR, LONG);
+void CALLBACK MACRO_CopyDialog(void);
+void CALLBACK MACRO_CopyTopic(void);
+void CALLBACK MACRO_CreateButton(LPCSTR, LPCSTR, LPCSTR);
+void CALLBACK MACRO_DeleteItem(LPCSTR);
+void CALLBACK MACRO_DeleteMark(LPCSTR);
+void CALLBACK MACRO_DestroyButton(LPCSTR);
+void CALLBACK MACRO_DisableButton(LPCSTR);
+void CALLBACK MACRO_DisableItem(LPCSTR);
+void CALLBACK MACRO_EnableButton(LPCSTR);
+void CALLBACK MACRO_EnableItem(LPCSTR);
+void CALLBACK MACRO_EndMPrint(void);
+void CALLBACK MACRO_ExecFile(LPCSTR, LPCSTR, LONG, LPCSTR);
+void CALLBACK MACRO_ExecProgram(LPCSTR, LONG);
+void CALLBACK MACRO_Exit(void);
+void CALLBACK MACRO_ExtAbleItem(LPCSTR, LONG);
+void CALLBACK MACRO_ExtInsertItem(LPCSTR, LPCSTR, LPCSTR, LPCSTR, LONG, LONG);
+void CALLBACK MACRO_ExtInsertMenu(LPCSTR, LPCSTR, LPCSTR, LONG, LONG);
+BOOL CALLBACK MACRO_FileExist(LPCSTR);
+void CALLBACK MACRO_FileOpen(void);
+void CALLBACK MACRO_Find(void);
+void CALLBACK MACRO_Finder(void);
+void CALLBACK MACRO_FloatingMenu(void);
+void CALLBACK MACRO_Flush(void);
+void CALLBACK MACRO_FocusWindow(LPCSTR);
+void CALLBACK MACRO_Generate(LPCSTR, LONG, LONG);
+void CALLBACK MACRO_GotoMark(LPCSTR);
+void CALLBACK MACRO_HelpOn(void);
+void CALLBACK MACRO_HelpOnTop(void);
+void CALLBACK MACRO_History(void);
+void CALLBACK MACRO_IfThen(BOOL, LPCSTR);
+void CALLBACK MACRO_IfThenElse(BOOL, LPCSTR, LPCSTR);
+BOOL CALLBACK MACRO_InitMPrint(void);
+void CALLBACK MACRO_InsertItem(LPCSTR, LPCSTR, LPCSTR, LPCSTR, LONG);
+void CALLBACK MACRO_InsertMenu(LPCSTR, LPCSTR, LONG);
+BOOL CALLBACK MACRO_IsBook(void);
+BOOL CALLBACK MACRO_IsMark(LPCSTR);
+BOOL CALLBACK MACRO_IsNotMark(LPCSTR);
+void CALLBACK MACRO_JumpContents(LPCSTR, LPCSTR);
+void CALLBACK MACRO_JumpContext(LPCSTR, LPCSTR, LONG);
+void CALLBACK MACRO_JumpHash(LPCSTR, LPCSTR, LONG);
+void CALLBACK MACRO_JumpHelpOn(void);
+void CALLBACK MACRO_JumpID(LPCSTR, LPCSTR, LPCSTR);
+void CALLBACK MACRO_JumpKeyword(LPCSTR, LPCSTR, LPCSTR);
+void CALLBACK MACRO_KLink(LPCSTR, LONG, LPCSTR, LPCSTR);
+void CALLBACK MACRO_Menu(void);
+void CALLBACK MACRO_MPrintHash(LONG);
+void CALLBACK MACRO_MPrintID(LPCSTR);
+void CALLBACK MACRO_Next(void);
+void CALLBACK MACRO_NoShow(void);
+void CALLBACK MACRO_PopupContext(LPCSTR, LONG);
+void CALLBACK MACRO_PopupHash(LPCSTR, LONG);
+void CALLBACK MACRO_PopupId(LPCSTR, LPCSTR);
+void CALLBACK MACRO_PositionWindow(LONG, LONG, LONG, LONG, LONG, LPCSTR);
+void CALLBACK MACRO_Prev(void);
+void CALLBACK MACRO_Print(void);
+void CALLBACK MACRO_PrinterSetup(void);
+void CALLBACK MACRO_RegisterRoutine(LPCSTR, LPCSTR, LPCSTR);
+void CALLBACK MACRO_RemoveAccelerator(LONG, LONG);
+void CALLBACK MACRO_ResetMenu(void);
+void CALLBACK MACRO_SaveMark(LPCSTR);
+void CALLBACK MACRO_Search(void);
+void CALLBACK MACRO_SetContents(LPCSTR, LONG);
+void CALLBACK MACRO_SetHelpOnFile(LPCSTR);
+void CALLBACK MACRO_SetPopupColor(LONG, LONG, LONG);
+void CALLBACK MACRO_ShellExecute(LPCSTR, LPCSTR, LONG, LONG, LPCSTR, LPCSTR);
+void CALLBACK MACRO_ShortCut(LPCSTR, LPCSTR, LONG, LONG, LPCSTR);
+void CALLBACK MACRO_TCard(LONG);
+void CALLBACK MACRO_Test(LONG);
+BOOL CALLBACK MACRO_TestALink(LPCSTR);
+BOOL CALLBACK MACRO_TestKLink(LPCSTR);
+void CALLBACK MACRO_UncheckItem(LPCSTR);
+void CALLBACK MACRO_UpdateWindow(LPCSTR, LPCSTR);
+
+/* Local Variables:    */
+/* c-file-style: "GNU" */
+/* End:                */
+
+#endif /* __MACRO_H__ */
diff --git a/reactos/base/applications/winhelp/macro.lex.l b/reactos/base/applications/winhelp/macro.lex.l
new file mode 100644 (file)
index 0000000..f6aa0d9
--- /dev/null
@@ -0,0 +1,295 @@
+%{\r
+/*\r
+ * Help Viewer\r
+ *\r
+ * Copyright 1996 Ulrich Schmid\r
+ * Copyright 2002 Eric Pouech\r
+ *\r
+ * This library is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU Lesser General Public\r
+ * License as published by the Free Software Foundation; either\r
+ * version 2.1 of the License, or (at your option) any later version.\r
+ *\r
+ * This library is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
+ * Lesser General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU Lesser General Public\r
+ * License along with this library; if not, write to the Free Software\r
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA\r
+ */\r
+%}\r
+%option nounput interactive 8bit\r
+%x quote\r
+%{\r
+#include <assert.h>\r
+#include "macro.h"\r
+\r
+#include "wine/debug.h"\r
+\r
+WINE_DEFAULT_DEBUG_CHANNEL(winhelp);\r
+\r
+static LPCSTR  macroptr;\r
+static LPSTR   strptr;\r
+static int     quote_stack[32];\r
+static int     quote_stk_idx = 0;\r
+struct lexret  yylval;\r
+\r
+#define YY_INPUT(buf,result,max_size)\\r
+  if ((result = *macroptr ? 1 : 0)) buf[0] = *macroptr++;\r
+\r
+%}\r
+%%\r
+\r
+[-+]?[0-9]+             yylval.integer = strtol(yytext, NULL, 10);     return INTEGER;\r
+[-+]?0[xX][0-9a-f]+    yylval.integer = strtol(yytext, NULL, 16);      return INTEGER;\r
+\r
+[a-zA-Z][_0-9a-zA-Z]*   return MACRO_Lookup(yytext, &yylval);\r
+\r
+\`         |\r
+\"         |\r
+\'          |\r
+<quote>\`   |\r
+<quote>\"   |\r
+<quote>\'   {\r
+    if (quote_stk_idx == 0 ||\r
+        (yytext[0] == '\"' && quote_stack[quote_stk_idx - 1] != '\"') ||\r
+        (yytext[0] == '`'))\r
+    {\r
+        /* opening a new one */\r
+        if (quote_stk_idx == 0)\r
+        {\r
+            strptr = HeapAlloc(GetProcessHeap(), 0, strlen(macroptr) + 1);\r
+            yylval.string = strptr;\r
+            BEGIN(quote);\r
+        }\r
+        else *strptr++ = yytext[0];\r
+        quote_stack[quote_stk_idx++] = yytext[0];\r
+        assert(quote_stk_idx < sizeof(quote_stack) / sizeof(quote_stack[0]));\r
+    }\r
+    else\r
+    {\r
+        if (yytext[0] == '`') assert(0);\r
+        /* close the current quote */\r
+        if (--quote_stk_idx == 0)\r
+        {\r
+            BEGIN INITIAL;\r
+            *strptr++ = '\0';\r
+            return STRING;\r
+        }\r
+        else *strptr++ = yytext[0];\r
+    }\r
+}\r
+\r
+<quote>.                *strptr++ = yytext[0];\r
+<quote>\\.             *strptr++ = yytext[1];\r
+<quote><<EOF>>         return 0;\r
+\r
+" "\r
+.                      return yytext[0];\r
+%%\r
+\r
+#if 0\r
+/* all code for testing macros */\r
+#include "winhelp.h"\r
+static CHAR szTestMacro[256];\r
+\r
+static LRESULT CALLBACK MACRO_TestDialogProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)\r
+{\r
+    if (msg == WM_COMMAND && wParam == IDOK)\r
+    {\r
+        GetDlgItemText(hDlg, 99, szTestMacro, sizeof(szTestMacro));\r
+        EndDialog(hDlg, IDOK);\r
+        return TRUE;\r
+    }\r
+    return FALSE;\r
+}\r
+\r
+void macro_test(void)\r
+{\r
+    WNDPROC lpfnDlg = MakeProcInstance(MACRO_TestDialogProc, Globals.hInstance);\r
+    DialogBox(Globals.hInstance, STRING_DIALOG_TEST, Globals.active_win->hMainWnd, (DLGPROC)lpfnDlg);\r
+    FreeProcInstance(lpfnDlg);\r
+    macro = szTestMacro;\r
+}\r
+#endif\r
+\r
+/* small helper function for debug messages */\r
+static const char* ts(int t)\r
+{\r
+    static char c[2] = {0,0};\r
+\r
+    switch (t)\r
+    {\r
+    case EMPTY: return "EMPTY";\r
+    case VOID_FUNCTION: return "VOID_FUNCTION";\r
+    case BOOL_FUNCTION: return "BOOL_FUNCTION";\r
+    case INTEGER: return "INTEGER";\r
+    case STRING: return "STRING";\r
+    case IDENTIFIER: return "IDENTIFIER";\r
+    default: c[0] = (char)t; return c;\r
+    }\r
+}\r
+\r
+static int MACRO_CallBoolFunc(FARPROC fn, const char* args, void** ret);\r
+\r
+/******************************************************************\r
+ *             MACRO_CheckArgs\r
+ *\r
+ * checks number of arguments against prototype, and stores arguments on\r
+ * stack pa for later call\r
+ * returns -1 on error, otherwise the number of pushed parameters\r
+ */\r
+static int MACRO_CheckArgs(void* pa[], unsigned max, const char* args)\r
+{\r
+    int         t;\r
+    int         len = 0, idx = 0;\r
+\r
+    WINE_TRACE("Checking %s\n", args);\r
+\r
+    if (yylex() != '(') {WINE_WARN("missing (\n");return -1;}\r
+\r
+    if (*args)\r
+    {\r
+        len = strlen(args);\r
+        for (;;)\r
+        {\r
+            t = yylex();\r
+            WINE_TRACE("Got %s <=> %c\n", ts(t), *args);\r
+\r
+            switch (*args)\r
+            {\r
+            case 'S': \r
+                if (t != STRING)\r
+                {WINE_WARN("missing S\n");return -1;}\r
+                pa[idx] = (void*)yylval.string;  \r
+                break;\r
+            case 'U':\r
+            case 'I':\r
+                if (t != INTEGER)\r
+                {WINE_WARN("missing U\n");return -1;}   \r
+                pa[idx] = (void*)yylval.integer; \r
+                break;\r
+            case 'B':\r
+                if (t != BOOL_FUNCTION) \r
+                {WINE_WARN("missing B\n");return -1;}   \r
+                if (MACRO_CallBoolFunc(yylval.function, yylval.proto, &pa[idx]) == 0)\r
+                    return -1;\r
+                break;\r
+            default: \r
+                WINE_WARN("unexpected %s while args is %c\n", ts(t), *args);\r
+                return -1;\r
+            }\r
+            idx++;\r
+            if (*++args == '\0') break;\r
+            t = yylex();\r
+            if (t == ')') goto CheckArgs_end;\r
+            if (t != ',') {WINE_WARN("missing ,\n");return -1;}\r
+            if (idx >= max) {WINE_FIXME("stack overflow (%d)\n", max);return -1;}\r
+        }\r
+    }\r
+    if (yylex() != ')') {WINE_WARN("missing )\n");return -1;}\r
+\r
+CheckArgs_end:\r
+    while (len > idx) pa[--len] = NULL;\r
+    return idx;\r
+}\r
+\r
+/******************************************************************\r
+ *             MACRO_CallBoolFunc\r
+ *\r
+ * Invokes boolean function fn, which arguments are defined by args\r
+ * stores bool result into ret\r
+ */\r
+static int MACRO_CallBoolFunc(FARPROC fn, const char* args, void** ret)\r
+{\r
+    void*       pa[2];\r
+    int         idx = MACRO_CheckArgs(pa, sizeof(pa)/sizeof(pa[0]), args);\r
+\r
+    if (idx < 0) return 0;\r
+    if (!fn)     return 1;\r
+\r
+    WINE_TRACE("calling with %u pmts\n", idx);\r
+\r
+    switch (strlen(args))\r
+    {\r
+    case 0: *ret = (void*)(fn)();          break;\r
+    case 1: *ret = (void*)(fn)(pa[0]);     break;\r
+    default: WINE_FIXME("NIY\n");\r
+    }\r
+\r
+    return 1;\r
+}\r
+\r
+/******************************************************************\r
+ *             MACRO_CallVoidFunc\r
+ *\r
+ *\r
+ */\r
+static int MACRO_CallVoidFunc(FARPROC fn, const char* args)\r
+{\r
+    void*       pa[6];\r
+    int         idx = MACRO_CheckArgs(pa, sizeof(pa)/sizeof(pa[0]), args);\r
+\r
+    if (idx < 0) return 0;\r
+    if (!fn)     return 1;\r
+\r
+    WINE_TRACE("calling %p with %u pmts\n", fn, idx);\r
+\r
+    switch (strlen(args))\r
+    {\r
+    case 0: (fn)();                                     break;\r
+    case 1: (fn)(pa[0]);                                break;\r
+    case 2: (fn)(pa[0],pa[1]);                          break;\r
+    case 3: (fn)(pa[0],pa[1],pa[2]);                    break;\r
+    case 4: (fn)(pa[0],pa[1],pa[2],pa[3]);              break;\r
+    case 5: (fn)(pa[0],pa[1],pa[2],pa[3],pa[4]);        break;\r
+    case 6: (fn)(pa[0],pa[1],pa[2],pa[3],pa[4],pa[5]);  break;\r
+    default: WINE_FIXME("NIY\n");\r
+    }\r
+\r
+    return 1;\r
+}\r
+\r
+BOOL MACRO_ExecuteMacro(LPCSTR macro)\r
+{\r
+    int t;\r
+\r
+    //WINE_TRACE("%s\n", wine_dbgstr_a(macro));\r
+\r
+    macroptr = macro;\r
+\r
+    while ((t = yylex()) != EMPTY)\r
+    {\r
+        switch (t)\r
+        {\r
+        case VOID_FUNCTION:\r
+            WINE_TRACE("got type void func(%s)\n", yylval.proto);\r
+            MACRO_CallVoidFunc(yylval.function, yylval.proto);\r
+            break;\r
+        case BOOL_FUNCTION:\r
+            WINE_WARN("got type bool func(%s)\n", yylval.proto);\r
+            break;\r
+        default:\r
+            WINE_WARN("got unexpected type %s\n", ts(t));\r
+            return 0;\r
+        }\r
+        switch (t = yylex())\r
+        {\r
+        case EMPTY:     return 1;\r
+        case ';':       break;\r
+        default:        return 0;\r
+        }\r
+    }\r
+\r
+    HeapFree(GetProcessHeap(), 0, strptr);\r
+    strptr = NULL;\r
+    quote_stk_idx = 0;\r
+\r
+    return 1;\r
+}\r
+\r
+#ifndef yywrap\r
+int yywrap(void) { return 1; }\r
+#endif\r
diff --git a/reactos/base/applications/winhelp/rsrc.rc b/reactos/base/applications/winhelp/rsrc.rc
new file mode 100644 (file)
index 0000000..0698c51
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Help Viewer
+ *
+ * Copyright 1996 Ulrich Schmid
+ * Copyright 2002 Sylvain Petreolle <spetreolle@yahoo.fr>
+ *
+ * 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
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <windows.h>
+#include "winhelp.h"
+#include "winhelp_res.h"
+
+#include "Bg.rc"
+#include "Cs.rc"
+#include "Da.rc"
+#include "De.rc"
+#include "En.rc"
+//#include "Eo.rc"
+#include "Es.rc"
+#include "Fi.rc"
+#include "Fr.rc"
+#include "Hu.rc"
+#include "It.rc"
+#include "Ko.rc"
+#include "Nl.rc"
+#include "No.rc"
+#include "Pl.rc"
+#include "Pt.rc"
+#include "Ru.rc"
+#include "Si.rc"
+#include "Sk.rc"
+#include "Sw.rc"
+#include "Tr.rc"
+#include "Wa.rc"
+#include "Zh.rc"
diff --git a/reactos/base/applications/winhelp/string.c b/reactos/base/applications/winhelp/string.c
new file mode 100644 (file)
index 0000000..df85cf4
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Help Viewer
+ *
+ * Copyright 1996 Ulrich Schmid
+ *
+ * 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
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/* Class names */
+
+const char MAIN_WIN_CLASS_NAME[]       = "MS_WINHELP";
+const char BUTTON_BOX_WIN_CLASS_NAME[] = "WHButtonBox";
+const char TEXT_WIN_CLASS_NAME[]       = "WHText";
+const char SHADOW_WIN_CLASS_NAME[]     = "WHShadow";
+const char HISTORY_WIN_CLASS_NAME[]    = "WHHistory";
+const char STRING_BUTTON[]             = "BUTTON";
+
+/* Resource names */
+const char STRING_DIALOG_TEST[]        = "DIALOG_TEST";
+
+/* Local Variables:    */
+/* c-file-style: "GNU" */
+/* End:                */
diff --git a/reactos/base/applications/winhelp/winhelp.c b/reactos/base/applications/winhelp/winhelp.c
new file mode 100644 (file)
index 0000000..8905d6e
--- /dev/null
@@ -0,0 +1,1930 @@
+/*
+ * Help Viewer
+ *
+ * Copyright    1996 Ulrich Schmid <uschmid@mail.hh.provi.de>
+ *              2002 Sylvain Petreolle <spetreolle@yahoo.fr>
+ *              2002 Eric Pouech <eric.pouech@wanadoo.fr>
+ *              2004 Ken Belleau <jamez@ivic.qc.ca>
+ *
+ * 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
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <assert.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+#include <stdlib.h>
+
+#include "windef.h"
+#include "winbase.h"
+#include "wingdi.h"
+#include "winuser.h"
+#include "commdlg.h"
+#include "winhelp.h"
+#include "winhelp_res.h"
+#include "shellapi.h"
+
+#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 LRESULT CALLBACK WINHELP_ButtonWndProc(HWND, UINT, WPARAM, LPARAM);
+static LRESULT CALLBACK WINHELP_HistoryWndProc(HWND, UINT, WPARAM, LPARAM);
+static LRESULT CALLBACK WINHELP_ShadowWndProc(HWND, UINT, WPARAM, LPARAM);
+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 WINHELP_LINE_PART* WINHELP_IsOverLink(WINHELP_WINDOW*, WPARAM, LPARAM);
+
+WINHELP_GLOBALS Globals = {3, NULL, NULL, 0, TRUE, NULL, NULL, NULL, NULL};
+
+
+/***********************************************************************
+ *
+ *           WINHELP_GetOpenFileName
+ */
+BOOL WINHELP_GetOpenFileName(LPSTR lpszFile, int len)
+{
+    OPENFILENAME openfilename;
+    CHAR szDir[MAX_PATH];
+    CHAR szzFilter[2 * MAX_STRING_LEN + 100];
+    LPSTR p = szzFilter;
+
+    WINE_TRACE("()\n");
+
+    LoadString(Globals.hInstance, STID_HELP_FILES_HLP, p, MAX_STRING_LEN);
+    p += strlen(p) + 1;
+    lstrcpy(p, "*.hlp");
+    p += strlen(p) + 1;
+    LoadString(Globals.hInstance, STID_ALL_FILES, p, MAX_STRING_LEN);
+    p += strlen(p) + 1;
+    lstrcpy(p, "*.*");
+    p += strlen(p) + 1;
+    *p = '\0';
+
+    GetCurrentDirectory(sizeof(szDir), szDir);
+
+    lpszFile[0]='\0';
+
+    openfilename.lStructSize       = sizeof(OPENFILENAME);
+    openfilename.hwndOwner         = NULL;
+    openfilename.hInstance         = Globals.hInstance;
+    openfilename.lpstrFilter       = szzFilter;
+    openfilename.lpstrCustomFilter = 0;
+    openfilename.nMaxCustFilter    = 0;
+    openfilename.nFilterIndex      = 1;
+    openfilename.lpstrFile         = lpszFile;
+    openfilename.nMaxFile          = len;
+    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;
+
+    return GetOpenFileName(&openfilename);
+}
+
+/***********************************************************************
+ *
+ *           WINHELP_LookupHelpFile
+ */
+HLPFILE* WINHELP_LookupHelpFile(LPCSTR lpszFile)
+{
+    HLPFILE*        hlpfile;
+    char szFullName[MAX_PATH];
+    char szAddPath[MAX_PATH];
+    char *p;
+
+    /*
+     * NOTE: This is needed by popup windows only.
+     * In other cases it's not needed but does not hurt though.
+     */
+    if (Globals.active_win && Globals.active_win->page && Globals.active_win->page->file)
+    {
+        strcpy(szAddPath, Globals.active_win->page->file->lpszPath);
+        p = strrchr(szAddPath, '\\');
+        if (p) *p = 0;
+    }
+
+    /*
+     * FIXME: Should we swap conditions?
+     */
+    if (!SearchPath(NULL, lpszFile, ".hlp", MAX_PATH, szFullName, NULL) &&
+        !SearchPath(szAddPath, lpszFile, ".hlp", MAX_PATH, szFullName, NULL))
+    {
+        if (WINHELP_MessageBoxIDS_s(STID_FILE_NOT_FOUND_s, lpszFile, STID_WHERROR,
+                                    MB_YESNO|MB_ICONQUESTION) != IDYES)
+            return NULL;
+        if (!WINHELP_GetOpenFileName(szFullName, MAX_PATH))
+            return NULL;
+    }
+    hlpfile = HLPFILE_ReadHlpFile(szFullName);
+    if (!hlpfile)
+        WINHELP_MessageBoxIDS_s(STID_HLPFILE_ERROR_s, lpszFile,
+                                STID_WHERROR, MB_OK|MB_ICONSTOP);
+    return hlpfile;
+}
+
+/******************************************************************
+ *             WINHELP_GetWindowInfo
+ *
+ *
+ */
+HLPFILE_WINDOWINFO*     WINHELP_GetWindowInfo(HLPFILE* hlpfile, LPCSTR name)
+{
+    static      HLPFILE_WINDOWINFO      mwi;
+    unsigned int     i;
+
+    if (!name || !name[0])
+        name = Globals.active_win->lpszName;
+
+    if (hlpfile)
+        for (i = 0; i < hlpfile->numWindows; i++)
+            if (!strcmp(hlpfile->windows[i].name, name))
+                return &hlpfile->windows[i];
+
+    if (strcmp(name, "main") != 0)
+    {
+        WINE_FIXME("Couldn't find window info for %s\n", name);
+        assert(0);
+        return NULL;
+    }
+    if (!mwi.name[0])
+    {
+        strcpy(mwi.type, "primary");
+        strcpy(mwi.name, "main");
+        if (!LoadString(Globals.hInstance, STID_WINE_HELP, 
+                        mwi.caption, sizeof(mwi.caption)))
+            strcpy(mwi.caption, hlpfile->lpszTitle);
+        mwi.origin.x = mwi.origin.y = mwi.size.cx = mwi.size.cy = CW_USEDEFAULT;
+        mwi.style = SW_SHOW;
+        mwi.win_style = WS_OVERLAPPEDWINDOW;
+        mwi.sr_color = mwi.sr_color = 0xFFFFFF;
+    }
+    return &mwi;
+}
+
+/******************************************************************
+ *             HLPFILE_GetPopupWindowInfo
+ *
+ *
+ */
+static HLPFILE_WINDOWINFO*     WINHELP_GetPopupWindowInfo(HLPFILE* hlpfile, HWND hParentWnd, POINT* mouse)
+{
+    static      HLPFILE_WINDOWINFO      wi;
+
+    RECT parent_rect;
+    
+    wi.type[0] = wi.name[0] = wi.caption[0] = '\0';
+
+    /* Calculate horizontal size and position of a popup window */
+    GetWindowRect(hParentWnd, &parent_rect);
+    wi.size.cx = (parent_rect.right  - parent_rect.left) / 2;
+    wi.size.cy = 10; /* need a non null value, so that border are taken into account while computing */
+
+    wi.origin = *mouse;
+    ClientToScreen(hParentWnd, &wi.origin);
+    wi.origin.x -= wi.size.cx / 2;
+    wi.origin.x  = min(wi.origin.x, GetSystemMetrics(SM_CXSCREEN) - wi.size.cx);
+    wi.origin.x  = max(wi.origin.x, 0);
+
+    wi.style = SW_SHOW;
+    wi.win_style = WS_POPUPWINDOW;
+    wi.sr_color = wi.sr_color = 0xFFFFFF;
+
+    return &wi;
+}
+
+/***********************************************************************
+ *
+ *           WinMain
+ */
+int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE prev, LPSTR cmdline, int show)
+{
+    MSG                 msg;
+    LONG                lHash = 0;
+    HLPFILE*            hlpfile;
+    static CHAR         default_wndname[] = "main";
+    LPSTR               wndname = default_wndname;
+    WINHELP_DLL*        dll;
+
+    Globals.hInstance = hInstance;
+
+    /* Get options */
+    while (*cmdline && (*cmdline == ' ' || *cmdline == '-'))
+    {
+        CHAR   option;
+        LPCSTR topic_id;
+        if (*cmdline++ == ' ') continue;
+
+        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;
+
+       case '3':
+       case '4':
+            Globals.wVersion = option - '0';
+            break;
+
+        case 'x':
+            show = SW_HIDE; 
+            Globals.isBook = FALSE;
+            break;
+
+        default:
+            WINE_FIXME("Unsupported cmd line: %s\n", cmdline);
+            break;
+       }
+    }
+
+    /* Create primary window */
+    if (!WINHELP_RegisterWinClasses())
+    {
+        WINE_FIXME("Couldn't register classes\n");
+        return 0;
+    }
+
+    if (*cmdline)
+    {
+        char*   ptr;
+        if ((*cmdline == '"') && (ptr = strchr(cmdline+1, '"')))
+        {
+            cmdline++;
+            *ptr = '\0';
+        }
+        if ((ptr = strchr(cmdline, '>')))
+        {
+            *ptr = '\0';
+            wndname = ptr + 1;
+        }
+        hlpfile = WINHELP_LookupHelpFile(cmdline);
+        if (!hlpfile) return 0;
+    }
+    else hlpfile = NULL;
+    WINHELP_CreateHelpWindowByHash(hlpfile, lHash, 
+                                   WINHELP_GetWindowInfo(hlpfile, wndname), show);
+
+    /* Message loop */
+    while (GetMessage(&msg, 0, 0, 0))
+    {
+        TranslateMessage(&msg);
+        DispatchMessage(&msg);
+    }
+    for (dll = Globals.dlls; dll; dll = dll->next)
+    {
+        if (dll->class & DC_INITTERM) dll->handler(DW_TERM, 0, 0);
+    }
+    return 0;
+}
+
+/***********************************************************************
+ *
+ *           RegisterWinClasses
+ */
+static BOOL WINHELP_RegisterWinClasses(void)
+{
+    WNDCLASS class_main, class_button_box, class_text, class_shadow, class_history;
+
+    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_text = class_main;
+    class_text.lpfnWndProc         = WINHELP_TextWndProc;
+    class_text.hbrBackground       = 0;
+    class_text.lpszClassName       = TEXT_WIN_CLASS_NAME;
+
+    class_shadow = class_main;
+    class_shadow.lpfnWndProc       = WINHELP_ShadowWndProc;
+    class_shadow.hbrBackground     = GetStockObject(GRAY_BRUSH);
+    class_shadow.lpszClassName     = SHADOW_WIN_CLASS_NAME;
+
+    class_history = class_main;
+    class_history.lpfnWndProc      = WINHELP_HistoryWndProc;
+    class_history.lpszClassName    = HISTORY_WIN_CLASS_NAME;
+
+    return (RegisterClass(&class_main) &&
+            RegisterClass(&class_button_box) &&
+            RegisterClass(&class_text) &&
+            RegisterClass(&class_shadow) &&
+            RegisterClass(&class_history));
+}
+
+typedef struct
+{
+    WORD size;
+    WORD command;
+    LONG data;
+    LONG reserved;
+    WORD ofsFilename;
+    WORD ofsData;
+} WINHELP,*LPWINHELP;
+
+/******************************************************************
+ *             WINHELP_HandleCommand
+ *
+ *
+ */
+static LRESULT  WINHELP_HandleCommand(HWND hSrcWnd, LPARAM lParam)
+{
+    COPYDATASTRUCT*     cds = (COPYDATASTRUCT*)lParam;
+    WINHELP*            wh;
+
+    if (cds->dwData != 0xA1DE505)
+    {
+        WINE_FIXME("Wrong magic number (%08lx)\n", cds->dwData);
+        return 0;
+    }
+
+    wh = (WINHELP*)cds->lpData;
+
+    if (wh)
+    {
+        char*   ptr = (wh->ofsFilename) ? (LPSTR)wh + wh->ofsFilename : NULL;
+
+        WINE_TRACE("Got[%u]: cmd=%u data=%08x fn=%s\n",
+                   wh->size, wh->command, wh->data, ptr);
+        switch (wh->command)
+        {
+        case HELP_CONTEXT:
+            if (ptr)
+            {
+                MACRO_JumpContext(ptr, "main", wh->data);
+            }
+            break;
+        case HELP_QUIT:
+            MACRO_Exit();
+            break;
+        case HELP_CONTENTS:
+            if (ptr)
+            {
+                MACRO_JumpContents(ptr, "main");
+            }
+            break;
+        case HELP_HELPONHELP:
+            MACRO_HelpOn();
+            break;
+        /* case HELP_SETINDEX: */
+        case HELP_SETCONTENTS:
+            if (ptr)
+            {
+                MACRO_SetContents(ptr, wh->data);
+            }
+            break;
+        case HELP_CONTEXTPOPUP:
+            if (ptr)
+            {
+                MACRO_PopupContext(ptr, wh->data);
+            }
+            break;
+        /* case HELP_FORCEFILE:*/
+        /* case HELP_CONTEXTMENU: */
+        case HELP_FINDER:
+            /* in fact, should be the topic dialog box */
+            WINE_FIXME("HELP_FINDER: stub\n");
+            if (ptr)
+            {
+                MACRO_JumpHash(ptr, "main", 0);
+            }
+            break;
+        /* case HELP_WM_HELP: */
+        /* case HELP_SETPOPUP_POS: */
+        /* case HELP_KEY: */
+        /* case HELP_COMMAND: */
+        /* case HELP_PARTIALKEY: */
+        /* case HELP_MULTIKEY: */
+        /* case HELP_SETWINPOS: */
+            WINE_FIXME("Unknown command (%x) for remote winhelp control\n", wh->command);
+            break;
+        }
+    }
+    return 0L;
+}
+
+/******************************************************************
+ *             WINHELP_ReuseWindow
+ *
+ *
+ */
+static BOOL     WINHELP_ReuseWindow(WINHELP_WINDOW* win, WINHELP_WINDOW* oldwin, 
+                                    HLPFILE_PAGE* page, int nCmdShow)
+{
+    unsigned int i;
+
+    win->hMainWnd      = oldwin->hMainWnd;
+    win->hButtonBoxWnd = oldwin->hButtonBoxWnd;
+    win->hTextWnd      = oldwin->hTextWnd;
+    win->hHistoryWnd   = oldwin->hHistoryWnd;
+    oldwin->hMainWnd = oldwin->hButtonBoxWnd = oldwin->hTextWnd = oldwin->hHistoryWnd = 0;
+    win->hBrush = oldwin->hBrush;
+
+    SetWindowLong(win->hMainWnd,      0, (LONG)win);
+    SetWindowLong(win->hButtonBoxWnd, 0, (LONG)win);
+    SetWindowLong(win->hTextWnd,      0, (LONG)win);
+    SetWindowLong(win->hHistoryWnd,   0, (LONG)win);
+
+    WINHELP_InitFonts(win->hMainWnd);
+
+    if (page)
+        SetWindowText(win->hMainWnd, page->file->lpszTitle);
+
+    WINHELP_SetupText(win->hTextWnd);
+    InvalidateRect(win->hTextWnd, NULL, TRUE);
+    SendMessage(win->hMainWnd, WM_USER, 0, 0);
+    ShowWindow(win->hMainWnd, nCmdShow);
+    UpdateWindow(win->hTextWnd);
+
+    if (!(win->info->win_style & WS_POPUP))
+    {
+        unsigned        num;
+
+        memcpy(win->history, oldwin->history, sizeof(win->history));
+        win->histIndex = oldwin->histIndex;
+
+        /* FIXME: when using back, we shouldn't update the history... */
+
+        if (page)
+        {
+            for (i = 0; i < win->histIndex; i++)
+                if (win->history[i] == page) break;
+
+            /* if the new page is already in the history, do nothing */
+            if (i == win->histIndex)
+            {
+                num = sizeof(win->history) / sizeof(win->history[0]);
+                if (win->histIndex == num)
+                {
+                    /* we're full, remove latest entry */
+                    HLPFILE_FreeHlpFile(win->history[0]->file);
+                    memmove(&win->history[0], &win->history[1], 
+                            (num - 1) * sizeof(win->history[0]));
+                    win->histIndex--;
+                }
+                win->history[win->histIndex++] = page;
+                page->file->wRefCount++;
+                if (win->hHistoryWnd) InvalidateRect(win->hHistoryWnd, NULL, TRUE);
+            }
+        }
+
+        memcpy(win->back, oldwin->back, sizeof(win->back));
+        win->backIndex = oldwin->backIndex;
+
+        if (page)
+        {
+            num = sizeof(win->back) / sizeof(win->back[0]);
+            if (win->backIndex == num)
+            {
+                /* we're full, remove latest entry */
+                HLPFILE_FreeHlpFile(win->back[0]->file);
+                memmove(&win->back[0], &win->back[1], 
+                        (num - 1) * sizeof(win->back[0]));
+                win->backIndex--;
+            }
+            win->back[win->backIndex++] = page;
+            page->file->wRefCount++;
+        }
+    }
+    else
+        win->backIndex = win->histIndex = 0;
+
+    oldwin->histIndex = oldwin->backIndex = 0;
+    WINHELP_DeleteWindow(oldwin);
+    return TRUE;
+}
+
+/***********************************************************************
+ *
+ *           WINHELP_CreateHelpWindow
+ */
+BOOL WINHELP_CreateHelpWindow(HLPFILE_PAGE* page, HLPFILE_WINDOWINFO* wi,
+                              int nCmdShow)
+{
+    WINHELP_WINDOW *win, *oldwin;
+    HWND hWnd;
+    BOOL bPrimary;
+    BOOL bPopup;
+    LPSTR name;
+
+    bPrimary = !lstrcmpi(wi->name, "main");
+    bPopup = wi->win_style & WS_POPUP;
+
+    /* Initialize WINHELP_WINDOW struct */
+    win = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
+                    sizeof(WINHELP_WINDOW) + strlen(wi->name) + 1);
+    if (!win) return FALSE;
+
+    win->next = Globals.win_list;
+    Globals.win_list = win;
+
+    name = (char*)win + sizeof(WINHELP_WINDOW);
+    lstrcpy(name, wi->name);
+    win->lpszName = name;
+
+    win->page = page;
+
+    win->hArrowCur = LoadCursorA(0, (LPSTR)IDC_ARROW);
+    win->hHandCur = LoadCursorA(0, (LPSTR)IDC_HAND);
+
+    win->info = wi;
+
+    Globals.active_win = win;
+
+    /* Initialize default pushbuttons */
+    if (bPrimary && page)
+    {
+        CHAR    buffer[MAX_STRING_LEN];
+
+        LoadString(Globals.hInstance, STID_CONTENTS, buffer, sizeof(buffer));
+        MACRO_CreateButton("BTN_CONTENTS", buffer, "Contents()");
+        LoadString(Globals.hInstance, STID_SEARCH,buffer, sizeof(buffer));
+        MACRO_CreateButton("BTN_SEARCH", buffer, "Search()");
+        LoadString(Globals.hInstance, STID_BACK, buffer, sizeof(buffer));
+        MACRO_CreateButton("BTN_BACK", buffer, "Back()");
+        LoadString(Globals.hInstance, STID_HISTORY, buffer, sizeof(buffer));
+        MACRO_CreateButton("BTN_HISTORY", buffer, "History()");
+        LoadString(Globals.hInstance, STID_TOPICS, buffer, sizeof(buffer));
+        MACRO_CreateButton("BTN_TOPICS", buffer, "Finder()");
+    }
+
+    /* Initialize file specific pushbuttons */
+    if (!(wi->win_style & WS_POPUP) && page)
+    {
+        HLPFILE_MACRO  *macro;
+        for (macro = page->file->first_macro; macro; macro = macro->next)
+            MACRO_ExecuteMacro(macro->lpszMacro);
+
+        for (macro = page->first_macro; macro; macro = macro->next)
+            MACRO_ExecuteMacro(macro->lpszMacro);
+    }
+
+    /* Reuse existing window */
+    if (!bPopup)
+    {
+        for (oldwin = win->next; oldwin; oldwin = oldwin->next)
+        {
+            if (!lstrcmpi(oldwin->lpszName, wi->name))
+            {
+                return WINHELP_ReuseWindow(win, oldwin, page, nCmdShow);
+            }
+        }
+        if (page)
+        {
+            win->histIndex = win->backIndex = 1;
+            win->history[0] = win->back[0] = page;
+            page->file->wRefCount += 2;
+            strcpy(wi->caption, page->file->lpszTitle);
+        }
+    }
+
+    hWnd = CreateWindow(bPopup ? TEXT_WIN_CLASS_NAME : MAIN_WIN_CLASS_NAME,
+                        wi->caption, 
+                        bPrimary ? WS_OVERLAPPEDWINDOW : wi->win_style,
+                        wi->origin.x, wi->origin.y, wi->size.cx, wi->size.cy,
+                        NULL, bPrimary ? LoadMenu(Globals.hInstance, MAKEINTRESOURCE(MAIN_MENU)) : 0,
+                        Globals.hInstance, win);
+
+    ShowWindow(hWnd, nCmdShow);
+    UpdateWindow(hWnd);
+
+    return TRUE;
+}
+
+/***********************************************************************
+ *
+ *           WINHELP_CreateHelpWindowByHash
+ */
+BOOL WINHELP_CreateHelpWindowByHash(HLPFILE* hlpfile, LONG lHash, 
+                                    HLPFILE_WINDOWINFO* wi, int nCmdShow)
+{
+    HLPFILE_PAGE*       page = NULL;
+
+    if (hlpfile)
+        page = lHash ? HLPFILE_PageByHash(hlpfile, lHash) : 
+            HLPFILE_Contents(hlpfile);
+    if (page) page->file->wRefCount++;
+    return WINHELP_CreateHelpWindow(page, wi, nCmdShow);
+}
+
+/***********************************************************************
+ *
+ *           WINHELP_CreateHelpWindowByMap
+ */
+BOOL WINHELP_CreateHelpWindowByMap(HLPFILE* hlpfile, LONG lMap,
+                                   HLPFILE_WINDOWINFO* wi, int nCmdShow)
+{
+    HLPFILE_PAGE*       page = NULL;
+
+    page = HLPFILE_PageByMap(hlpfile, lMap);
+    if (page) page->file->wRefCount++;
+    return WINHELP_CreateHelpWindow(page, wi, nCmdShow);
+}
+
+/***********************************************************************
+ *
+ *           WINHELP_MainWndProc
+ */
+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, curPos, min, max, dy, keyDelta;
+
+    WINHELP_CheckPopup(msg);
+
+    switch (msg)
+    {
+    case WM_NCCREATE:
+        win = (WINHELP_WINDOW*) ((LPCREATESTRUCT) lParam)->lpCreateParams;
+        SetWindowLong(hWnd, 0, (LONG) win);
+        win->hMainWnd = hWnd;
+        break;
+
+    case WM_CREATE:
+        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);
+
+        CreateWindow(TEXT_WIN_CLASS_NAME, "", WS_CHILD | WS_VISIBLE,
+                     0, 0, 0, 0, hWnd, 0, Globals.hInstance, win);
+
+        /* Fall through */
+    case WM_USER:
+    case WM_WINDOWPOSCHANGED:
+        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);
+
+        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);
+
+        break;
+
+    case WM_COMMAND:
+        Globals.active_win = win = (WINHELP_WINDOW*) GetWindowLong(hWnd, 0);
+        switch (wParam)
+       {
+            /* Menu FILE */
+       case MNID_FILE_OPEN:    MACRO_FileOpen();       break;
+       case MNID_FILE_PRINT:   MACRO_Print();          break;
+       case MNID_FILE_SETUP:   MACRO_PrinterSetup();   break;
+       case MNID_FILE_EXIT:    MACRO_Exit();           break;
+
+            /* Menu EDIT */
+       case MNID_EDIT_COPYDLG: MACRO_CopyDialog();     break;
+       case MNID_EDIT_ANNOTATE:MACRO_Annotate();       break;
+
+            /* Menu Bookmark */
+       case MNID_BKMK_DEFINE:  MACRO_BookmarkDefine(); break;
+
+            /* Menu Help */
+       case MNID_HELP_HELPON:  MACRO_HelpOn();         break;
+       case MNID_HELP_HELPTOP: MACRO_HelpOnTop();      break;
+       case MNID_HELP_ABOUT:   MACRO_About();          break;
+       case MNID_HELP_WINE:    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(STID_NOT_IMPLEMENTED, 0x121, MB_OK);
+            break;
+       }
+        break;
+    case WM_DESTROY:
+        if (Globals.hPopupWnd) DestroyWindow(Globals.hPopupWnd);
+        break;
+    case WM_COPYDATA:
+        return WINHELP_HandleCommand((HWND)wParam, lParam);
+
+    case WM_KEYDOWN:
+        keyDelta = 0;
+
+        switch (wParam)
+        {
+        case VK_UP:
+        case VK_DOWN:
+            keyDelta = GetSystemMetrics(SM_CXVSCROLL);
+            if (wParam == VK_UP)
+                keyDelta = -keyDelta;
+
+        case VK_PRIOR:
+        case VK_NEXT:
+            win = (WINHELP_WINDOW*) GetWindowLong(hWnd, 0);
+            curPos = GetScrollPos(win->hTextWnd, SB_VERT);
+            GetScrollRange(win->hTextWnd, SB_VERT, &min, &max);
+
+            if (keyDelta == 0)
+            {            
+                GetClientRect(win->hTextWnd, &rect);
+                keyDelta = (rect.bottom - rect.top) / 2;
+                if (wParam == VK_PRIOR)
+                    keyDelta = -keyDelta;
+            }
+
+            curPos += keyDelta;
+            if (curPos > max)
+                 curPos = max;
+            else if (curPos < min)
+                 curPos = min;
+
+            dy = GetScrollPos(win->hTextWnd, SB_VERT) - curPos;
+            SetScrollPos(win->hTextWnd, SB_VERT, curPos, TRUE);
+            ScrollWindow(win->hTextWnd, 0, dy, NULL, NULL);
+            UpdateWindow(win->hTextWnd);
+            return 0;
+
+        case VK_ESCAPE:
+            MACRO_Exit();
+            return 0;
+        }
+        break;
+    }
+    return DefWindowProc(hWnd, msg, wParam, lParam);
+}
+
+/***********************************************************************
+ *
+ *           WINHELP_ButtonBoxWndProc
+ */
+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;
+
+    WINHELP_CheckPopup(msg);
+
+    switch (msg)
+    {
+    case WM_NCCREATE:
+        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);
+
+        /* 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, button->lpszName,
+                                            WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
+                                            0, 0, 0, 0,
+                                            hWnd, (HMENU) button->wParam,
+                                            Globals.hInstance, 0);
+                if (button->hWnd) {
+                    if (Globals.button_proc == NULL)
+                        Globals.button_proc = (WNDPROC) GetWindowLongPtr(button->hWnd, GWLP_WNDPROC);
+                    SetWindowLongPtr(button->hWnd, GWLP_WNDPROC, (LONG_PTR) WINHELP_ButtonWndProc);
+                }
+            }
+            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);
+       }
+
+        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);
+
+            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;
+
+    case WM_COMMAND:
+        SendMessage(GetParent(hWnd), msg, wParam, lParam);
+        break;
+
+    case WM_KEYDOWN:
+        switch (wParam)
+        {
+        case VK_UP:
+        case VK_DOWN:
+        case VK_PRIOR:
+        case VK_NEXT:
+        case VK_ESCAPE:
+            return SendMessage(GetParent(hWnd), msg, wParam, lParam);
+        }
+        break;
+    }
+
+    return DefWindowProc(hWnd, msg, wParam, lParam);
+}
+
+/***********************************************************************
+ *
+ *           WINHELP_ButtonWndProc
+ */
+static LRESULT CALLBACK WINHELP_ButtonWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+    if (msg == WM_KEYDOWN)
+    {
+        switch (wParam)
+        {
+        case VK_UP:
+        case VK_DOWN:
+        case VK_PRIOR:
+        case VK_NEXT:
+        case VK_ESCAPE:
+            return SendMessage(GetParent(hWnd), msg, wParam, lParam);
+        }
+    }
+
+    return CallWindowProc(Globals.button_proc, hWnd, msg, wParam, lParam);
+}
+
+/***********************************************************************
+ *
+ *           WINHELP_TextWndProc
+ */
+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;
+
+    if (msg != WM_LBUTTONDOWN)
+        WINHELP_CheckPopup(msg);
+
+    switch (msg)
+    {
+    case WM_NCCREATE:
+        win = (WINHELP_WINDOW*) ((LPCREATESTRUCT) lParam)->lpCreateParams;
+        SetWindowLong(hWnd, 0, (LONG) win);
+        win->hTextWnd = hWnd;
+        win->hBrush = CreateSolidBrush(win->info->sr_color);
+        if (win->info->win_style & WS_POPUP) Globals.hPopupWnd = win->hMainWnd = hWnd;
+        WINHELP_InitFonts(hWnd);
+        break;
+
+    case WM_CREATE:
+        win = (WINHELP_WINDOW*) GetWindowLong(hWnd, 0);
+
+        /* Calculate vertical size and position of a popup window */
+        if (win->info->win_style & WS_POPUP)
+       {
+            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;
+
+            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);
+
+            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;
+
+            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,
+                         0);
+            SetWindowPos(win->hShadowWnd, hWnd, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
+            ShowWindow(win->hShadowWnd, SW_NORMAL);
+            SetActiveWindow(hWnd);
+       }
+        break;
+
+    case WM_WINDOWPOSCHANGED:
+        winpos = (WINDOWPOS*) lParam;
+
+        if (!(winpos->flags & SWP_NOSIZE)) WINHELP_SetupText(hWnd);
+        break;
+
+    case WM_MOUSEWHEEL:
+    {
+       int wheelDelta = 0;
+       UINT scrollLines = 3;
+       int curPos = GetScrollPos(hWnd, SB_VERT);
+       int min, max;
+
+       GetScrollRange(hWnd, SB_VERT, &min, &max);
+
+       SystemParametersInfo(SPI_GETWHEELSCROLLLINES,0, &scrollLines, 0);
+       if (wParam & (MK_SHIFT | MK_CONTROL))
+           return DefWindowProc(hWnd, msg, wParam, lParam);
+       wheelDelta -= GET_WHEEL_DELTA_WPARAM(wParam);
+       if (abs(wheelDelta) >= WHEEL_DELTA && scrollLines) {
+           int dy;
+
+           curPos += wheelDelta;
+           if (curPos > max)
+                curPos = max;
+           else if (curPos < min)
+                curPos = min;
+
+           dy = GetScrollPos(hWnd, SB_VERT) - curPos;
+           SetScrollPos(hWnd, SB_VERT, curPos, TRUE);
+           ScrollWindow(hWnd, 0, dy, NULL, NULL);
+           UpdateWindow(hWnd);
+       }
+    }
+    break;
+
+    case WM_VSCROLL:
+    {
+       BOOL  update = TRUE;
+       RECT  rect;
+       INT   Min, Max;
+       INT   CurPos = GetScrollPos(hWnd, SB_VERT);
+       INT   dy;
+       
+       GetScrollRange(hWnd, SB_VERT, &Min, &Max);
+       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;
+        }
+       if (update)
+        {
+           if (CurPos > Max)
+                CurPos = Max;
+           else if (CurPos < Min)
+                CurPos = Min;
+           dy = GetScrollPos(hWnd, SB_VERT) - CurPos;
+           SetScrollPos(hWnd, SB_VERT, CurPos, TRUE);
+           ScrollWindow(hWnd, 0, dy, NULL, NULL);
+           UpdateWindow(hWnd);
+        }
+    }
+    break;
+
+    case WM_PAINT:
+        hDc = BeginPaint(hWnd, &ps);
+        win = (WINHELP_WINDOW*) GetWindowLong(hWnd, 0);
+        scroll_pos = GetScrollPos(hWnd, SB_VERT);
+
+        /* No DPtoLP needed - MM_TEXT map mode */
+        if (ps.fErase) FillRect(hDc, &ps.rcPaint, win->hBrush);
+        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);
+                    SetBkColor(hDc, win->info->sr_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;
+
+                        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_bitmap:
+                    {
+                        HDC hMemDC;
+
+                        hMemDC = CreateCompatibleDC(hDc);
+                        SelectObject(hMemDC, part->u.bitmap.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;
+                case hlp_line_part_metafile:
+                    {
+                        HDC hMemDC;
+                        HBITMAP hBitmap;
+                        SIZE sz;
+                        RECT rc;
+
+                        sz.cx = part->rect.right - part->rect.left;
+                        sz.cy = part->rect.bottom - part->rect.top;
+                        hMemDC = CreateCompatibleDC(hDc);
+                        hBitmap = CreateCompatibleBitmap(hDc, sz.cx, sz.cy);
+                        SelectObject(hMemDC, hBitmap);
+                        SelectObject(hMemDC, win->hBrush);
+                        rc.left = 0;
+                        rc.top = 0;
+                        rc.right = sz.cx;
+                        rc.bottom = sz.cy;
+                        FillRect(hMemDC, &rc, win->hBrush);
+                        SetMapMode(hMemDC, part->u.metafile.mm);
+                        SetWindowExtEx(hMemDC, sz.cx, sz.cy, 0);
+                        SetViewportExtEx(hMemDC, sz.cx, sz.cy, 0);
+                        SetWindowOrgEx(hMemDC, 0, 0, 0);
+                        SetViewportOrgEx(hMemDC, 0, 0, 0);
+                        PlayMetaFile(hMemDC, part->u.metafile.hMetaFile);
+                        SetMapMode(hMemDC, MM_TEXT);
+                        SetWindowOrgEx(hMemDC, 0, 0, 0);
+                        SetViewportOrgEx(hMemDC, 0, 0, 0);
+                        BitBlt(hDc, part->rect.left, part->rect.top - scroll_pos,
+                               sz.cx, sz.cy, hMemDC, 0, 0, SRCCOPY);
+                        DeleteDC(hMemDC);
+                        DeleteObject(hBitmap);
+                    }
+                    break;
+                }
+            }
+        }
+
+        EndPaint(hWnd, &ps);
+        break;
+
+    case WM_MOUSEMOVE:
+        win = (WINHELP_WINDOW*) GetWindowLong(hWnd, 0);
+
+        if (WINHELP_IsOverLink(win, 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;
+
+    case WM_LBUTTONDOWN:
+        win = (WINHELP_WINDOW*) GetWindowLong(hWnd, 0);
+
+        hPopupWnd = Globals.hPopupWnd;
+        Globals.hPopupWnd = 0;
+
+        part = WINHELP_IsOverLink(win, wParam, lParam);
+        if (part)
+        {
+            HLPFILE*            hlpfile;
+            HLPFILE_WINDOWINFO* wi;
+
+            mouse.x = (short)LOWORD(lParam);
+            mouse.y = (short)HIWORD(lParam);
+
+            if (part->link) switch (part->link->cookie)
+            {
+            case hlp_link_link:
+                hlpfile = WINHELP_LookupHelpFile(part->link->lpszString);
+                if (part->link->window == -1)
+                    wi = win->info;
+                else if ((part->link->window >= 0) && (part->link->window < hlpfile->numWindows))
+                    wi = &hlpfile->windows[part->link->window];
+                else
+                {
+                    WINE_WARN("link to window %d/%d\n", part->link->window, hlpfile->numWindows);
+                    break;
+                }
+                WINHELP_CreateHelpWindowByHash(hlpfile, part->link->lHash, wi,
+                                               SW_NORMAL);
+                break;
+            case hlp_link_popup:
+                hlpfile = WINHELP_LookupHelpFile(part->link->lpszString);
+                if (hlpfile) WINHELP_CreateHelpWindowByHash(hlpfile, part->link->lHash, 
+                                               WINHELP_GetPopupWindowInfo(hlpfile, hWnd, &mouse),
+                                               SW_NORMAL);
+                break;
+            case hlp_link_macro:
+                MACRO_ExecuteMacro(part->link->lpszString);
+                break;
+            default:
+                WINE_FIXME("Unknown link cookie %d\n", part->link->cookie);
+            }
+        }
+
+        if (hPopupWnd)
+            DestroyWindow(hPopupWnd);
+        break;
+
+    case WM_NCDESTROY:
+        win = (WINHELP_WINDOW*) GetWindowLong(hWnd, 0);
+
+        if (hWnd == Globals.hPopupWnd) Globals.hPopupWnd = 0;
+
+        bExit = (Globals.wVersion >= 4 && !lstrcmpi(win->lpszName, "main"));
+        DeleteObject(win->hBrush);
+
+        WINHELP_DeleteWindow(win);
+
+        if (bExit) MACRO_Exit();
+
+        if (!Globals.win_list)
+            PostQuitMessage(0);
+        break;
+    }
+
+    return DefWindowProc(hWnd, msg, wParam, lParam);
+}
+
+/******************************************************************
+ *             WINHELP_HistoryWndProc
+ *
+ *
+ */
+static LRESULT CALLBACK WINHELP_HistoryWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+    WINHELP_WINDOW*     win;
+    PAINTSTRUCT         ps;
+    HDC                 hDc;
+    TEXTMETRIC          tm;
+    unsigned int        i;
+    RECT                r;
+
+    switch (msg)
+    {
+    case WM_NCCREATE:
+        win = (WINHELP_WINDOW*)((LPCREATESTRUCT)lParam)->lpCreateParams;
+        SetWindowLong(hWnd, 0, (LONG)win);
+        win->hHistoryWnd = hWnd;
+        break;
+    case WM_CREATE:
+        win = (WINHELP_WINDOW*) GetWindowLong(hWnd, 0);
+        hDc = GetDC(hWnd);
+        GetTextMetrics(hDc, &tm);
+        GetWindowRect(hWnd, &r);
+
+        r.right = r.left + 30 * tm.tmAveCharWidth;
+        r.bottom = r.top + (sizeof(win->history) / sizeof(win->history[0])) * tm.tmHeight;
+        AdjustWindowRect(&r, GetWindowLong(hWnd, GWL_STYLE), FALSE);
+        if (r.left < 0) {r.right -= r.left; r.left = 0;}
+        if (r.top < 0) {r.bottom -= r.top; r.top = 0;}
+
+        MoveWindow(hWnd, r.left, r.top, r.right, r.bottom, TRUE);
+        ReleaseDC(hWnd, hDc);
+        break;
+    case WM_LBUTTONDOWN:
+        win = (WINHELP_WINDOW*) GetWindowLong(hWnd, 0);
+        hDc = GetDC(hWnd);
+        GetTextMetrics(hDc, &tm);
+        i = HIWORD(lParam) / tm.tmHeight;
+        if (i < win->histIndex)
+            WINHELP_CreateHelpWindow(win->history[i], win->info, SW_SHOW);
+        ReleaseDC(hWnd, hDc);
+        break;
+    case WM_PAINT:
+        hDc = BeginPaint(hWnd, &ps);
+        win = (WINHELP_WINDOW*) GetWindowLong(hWnd, 0);
+        GetTextMetrics(hDc, &tm);
+
+        for (i = 0; i < win->histIndex; i++)
+        {
+            TextOut(hDc, 0, i * tm.tmHeight, win->history[i]->lpszTitle, 
+                    strlen(win->history[i]->lpszTitle));
+        }
+        EndPaint(hWnd, &ps);
+        break;
+    case WM_DESTROY:
+        win = (WINHELP_WINDOW*) GetWindowLong(hWnd, 0);
+        if (hWnd == win->hHistoryWnd)
+            win->hHistoryWnd = 0;
+        break;
+    }
+    return DefWindowProc(hWnd, msg, wParam, lParam);
+}
+
+/***********************************************************************
+ *
+ *           WINHELP_ShadowWndProc
+ */
+static LRESULT CALLBACK WINHELP_ShadowWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+    WINHELP_CheckPopup(msg);
+    return DefWindowProc(hWnd, msg, wParam, lParam);
+}
+
+/***********************************************************************
+ *
+ *           SetupText
+ */
+static void WINHELP_SetupText(HWND hWnd)
+{
+    HDC  hDc = GetDC(hWnd);
+    RECT rect;
+    SIZE newsize;
+
+    ShowScrollBar(hWnd, SB_VERT, FALSE);
+    if (!WINHELP_SplitLines(hWnd, NULL))
+    {
+        ShowScrollBar(hWnd, SB_VERT, TRUE);
+        GetClientRect(hWnd, &rect);
+
+        WINHELP_SplitLines(hWnd, &newsize);
+        SetScrollRange(hWnd, SB_VERT, 0, rect.top + newsize.cy - rect.bottom, TRUE);
+    }
+    else
+    {
+        SetScrollPos(hWnd, SB_VERT, 0, FALSE);
+        SetScrollRange(hWnd, SB_VERT, 0, 0, FALSE);
+    }
+
+    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,
+                               unsigned underline)
+{
+    WINHELP_LINE      *line;
+    WINHELP_LINE_PART *part;
+    LPSTR ptr;
+
+    if (!*partp) /* New line */
+    {
+        *line_ascent  = ascent;
+
+        line = HeapAlloc(GetProcessHeap(), 0,
+                         sizeof(WINHELP_LINE) + textlen);
+        if (!line) return FALSE;
+
+        line->next    = 0;
+        part          = &line->first_part;
+        ptr           = (char*)line + sizeof(WINHELP_LINE);
+
+        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 */
+    {
+        line = **linep;
+
+        if (*line_ascent < ascent)
+       {
+            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;
+           }
+            line->rect.bottom += ascent - *line_ascent;
+            *line_ascent = ascent;
+       }
+
+        part = HeapAlloc(GetProcessHeap(), 0,
+                         sizeof(WINHELP_LINE_PART) + textlen);
+        if (!part) return FALSE;
+        **partp = part;
+        ptr     = (char*)part + sizeof(WINHELP_LINE_PART);
+    }
+
+    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);
+
+    part->link = link;
+    if (link) link->wRefCount++;
+
+    part->next          = 0;
+    *partp              = &part->next;
+
+    space->cx = 0;
+
+    return TRUE;
+}
+
+/***********************************************************************
+ *
+ *           WINHELP_AppendGfxObject
+ */
+static WINHELP_LINE_PART* WINHELP_AppendGfxObject(WINHELP_LINE ***linep, WINHELP_LINE_PART ***partp,
+                                                  LPSIZE space, LPSIZE gfxSize,
+                                                  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));
+        if (!line) return NULL;
+
+        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));
+        if (!part) return NULL;
+        **partp = part;
+        ptr = (char*)part + sizeof(WINHELP_LINE_PART);
+    }
+
+    /* part->cookie should be set by caller (image or metafile) */
+    part->rect.left       = line->rect.right + (*partp ? space->cx : 0);
+    part->rect.right      = part->rect.left + gfxSize->cx;
+    line->rect.right      = part->rect.right;
+    part->rect.top        = (*partp) ? line->rect.top : line->rect.bottom;
+    part->rect.bottom     = part->rect.top + gfxSize->cy;
+    line->rect.bottom     = max(line->rect.bottom, part->rect.bottom);
+
+    WINE_TRACE("Appended gfx @ (%d,%d-%d,%d)\n",
+               part->rect.left, part->rect.top, part->rect.right, part->rect.bottom);
+
+    part->link = link;
+    if (link) link->wRefCount++;
+
+    part->next            = NULL;
+    *partp                = &part->next;
+
+    space->cx = 0;
+
+    return part;
+}
+
+
+/***********************************************************************
+ *
+ *           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 && p->link->bClrChange)
+                {
+                    underline = (p->link->cookie == hlp_link_popup) ? 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_bitmap:
+        case para_metafile:
+            {
+                SIZE                    gfxSize;
+                INT                     free_width;
+                WINHELP_LINE_PART*      ref_part;
+
+                if (p->u.gfx.pos & 0x8000)
+                {
+                    space.cx = rect.left;
+                    if (*line)
+                        space.cy += (*line)->rect.bottom - (*line)->rect.top;
+                    part = 0;
+                }
+
+                if (p->cookie == para_bitmap)
+                {
+                    DIBSECTION              dibs;
+                    
+                    GetObject(p->u.gfx.u.bmp.hBitmap, sizeof(dibs), &dibs);
+                    gfxSize.cx = dibs.dsBm.bmWidth;
+                    gfxSize.cy = dibs.dsBm.bmHeight;
+                }
+                else
+                {
+                    LPMETAFILEPICT lpmfp = &p->u.gfx.u.mfp;
+                    if (lpmfp->mm == MM_ANISOTROPIC || lpmfp->mm == MM_ISOTROPIC)
+                    {
+                        gfxSize.cx = MulDiv(lpmfp->xExt, GetDeviceCaps(hDc, HORZRES),
+                                            100*GetDeviceCaps(hDc, HORZSIZE));
+                        gfxSize.cy = MulDiv(lpmfp->yExt, GetDeviceCaps(hDc, VERTRES),
+                                            100*GetDeviceCaps(hDc, VERTSIZE));
+                    }
+                    else
+                    {
+                        gfxSize.cx = lpmfp->xExt;
+                        gfxSize.cy = lpmfp->yExt;
+                    }
+                }
+
+                free_width = rect.right - ((part && *line) ? (*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);
+                }
+                ref_part = WINHELP_AppendGfxObject(&line, &part, &space, &gfxSize,
+                                                   p->link, p->u.gfx.pos);
+                if (!ref_part || (!newsize && (*line)->rect.bottom > rect.bottom))
+                {
+                    return FALSE;
+                }
+                if (p->cookie == para_bitmap)
+                {
+                    ref_part->cookie = hlp_line_part_bitmap;
+                    ref_part->u.bitmap.hBitmap = p->u.gfx.u.bmp.hBitmap;
+                }
+                else
+                {
+                    ref_part->cookie = hlp_line_part_metafile;
+                    ref_part->u.metafile.hMetaFile = p->u.gfx.u.mfp.hMF;
+                    ref_part->u.metafile.mm = p->u.gfx.u.mfp.mm;
+                }
+            }
+            break;
+        }
+    }
+
+    if (newsize)
+        newsize->cy = (*line)->rect.bottom + INTERNAL_BORDER_WIDTH;
+
+    ReleaseDC(hWnd, hDc);
+    return TRUE;
+}
+
+/***********************************************************************
+ *
+ *           WINHELP_CheckPopup
+ */
+static void WINHELP_CheckPopup(UINT msg)
+{
+    if (!Globals.hPopupWnd) return;
+
+    switch (msg)
+    {
+    case WM_COMMAND:
+    case WM_LBUTTONDOWN:
+    case WM_MBUTTONDOWN:
+    case WM_RBUTTONDOWN:
+    case WM_NCLBUTTONDOWN:
+    case WM_NCMBUTTONDOWN:
+    case WM_NCRBUTTONDOWN:
+        DestroyWindow(Globals.hPopupWnd);
+        Globals.hPopupWnd = 0;
+    }
+}
+
+/***********************************************************************
+ *
+ *           WINHELP_DeleteLines
+ */
+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)
+    {
+        next_line = line->next;
+        for (part = &line->first_part; part; part = next_part)
+       {
+            next_part = part->next;
+            HLPFILE_FreeLink(part->link);
+            HeapFree(GetProcessHeap(), 0, part);
+       }
+    }
+    win->first_line = 0;
+}
+
+/***********************************************************************
+ *
+ *           WINHELP_DeleteWindow
+ */
+static void WINHELP_DeleteWindow(WINHELP_WINDOW* win)
+{
+    WINHELP_WINDOW**    w;
+    unsigned int        i;
+    WINHELP_BUTTON*     b;
+    WINHELP_BUTTON*     bp;
+
+    for (w = &Globals.win_list; *w; w = &(*w)->next)
+    {
+        if (*w == win)
+        {
+            *w = win->next;
+            break;
+        }
+    }
+
+    if (Globals.active_win == win)
+    {
+        Globals.active_win = Globals.win_list;
+        if (Globals.win_list)
+            SetActiveWindow(Globals.win_list->hMainWnd);
+    }
+
+    for (b = win->first_button; b; b = bp)
+    {
+        DestroyWindow(b->hWnd);
+        bp = b->next;
+        HeapFree(GetProcessHeap(), 0, b);
+    }
+
+    if (win->hShadowWnd) DestroyWindow(win->hShadowWnd);
+    if (win->hHistoryWnd) DestroyWindow(win->hHistoryWnd);
+
+    for (i = 0; i < win->histIndex; i++)
+    {
+        HLPFILE_FreeHlpFile(win->history[i]->file);
+    }
+
+    for (i = 0; i < win->backIndex; i++)
+        HLPFILE_FreeHlpFile(win->back[i]->file);
+
+    if (win->page) HLPFILE_FreeHlpFile(win->page->file);
+    WINHELP_DeleteLines(win);
+    HeapFree(GetProcessHeap(), 0, win);
+}
+
+/***********************************************************************
+ *
+ *           WINHELP_InitFonts
+ */
+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"}};
+#define FONTS_LEN (sizeof(logfontlist)/sizeof(*logfontlist))
+
+    static HFONT fonts[FONTS_LEN];
+    static BOOL init = 0;
+
+    win->fonts_len = FONTS_LEN;
+    win->fonts = fonts;
+
+    if (!init)
+    {
+        UINT i;
+
+        for (i = 0; i < FONTS_LEN; i++)
+       {
+            fonts[i] = CreateFontIndirect(&logfontlist[i]);
+       }
+
+        init = 1;
+    }
+}
+
+/***********************************************************************
+ *
+ *           WINHELP_MessageBoxIDS
+ */
+INT WINHELP_MessageBoxIDS(UINT ids_text, UINT ids_title, WORD type)
+{
+    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));
+
+    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_PATH];
+
+    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);
+}
+
+/******************************************************************
+ *             WINHELP_IsOverLink
+ *
+ *
+ */
+WINHELP_LINE_PART* WINHELP_IsOverLink(WINHELP_WINDOW* win, WPARAM wParam, LPARAM lParam)
+{
+    POINT mouse;
+    WINHELP_LINE      *line;
+    WINHELP_LINE_PART *part;
+    int scroll_pos = GetScrollPos(win->hTextWnd, 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)
+        {
+            if (part->link && 
+                part->link->lpszString &&
+                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;
+}
diff --git a/reactos/base/applications/winhelp/winhelp.h b/reactos/base/applications/winhelp/winhelp.h
new file mode 100644 (file)
index 0000000..b49324c
--- /dev/null
@@ -0,0 +1,200 @@
+/*
+ * Help Viewer
+ *
+ * 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
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef __WINHELP_H__
+#define __WINHELP_H__
+
+#define MAX_LANGUAGE_NUMBER     255
+#define MAX_STRING_LEN          255
+
+#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
+
+#define WINE_WARN DPRINT
+
+#ifndef RC_INVOKED
+
+#include <stdarg.h>
+
+#include "hlpfile.h"
+#include "windef.h"
+#include "winbase.h"
+#include "macro.h"
+#include "winhelp_res.h"
+
+typedef struct tagHelpLinePart
+{
+    RECT      rect;
+    enum {hlp_line_part_text, hlp_line_part_bitmap, hlp_line_part_metafile} 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;
+        } bitmap;
+        struct
+        {
+            HMETAFILE   hMetaFile;
+            INT         mm;
+        } metafile;
+    } u;
+    HLPFILE_LINK*       link;
+
+    struct tagHelpLinePart *next;
+} WINHELP_LINE_PART;
+
+typedef struct tagHelpLine
+{
+    RECT                rect;
+    WINHELP_LINE_PART   first_part;
+    struct tagHelpLine* next;
+} WINHELP_LINE;
+
+typedef struct tagHelpButton
+{
+    HWND                hWnd;
+
+    LPCSTR              lpszID;
+    LPCSTR              lpszName;
+    LPCSTR              lpszMacro;
+
+    WPARAM              wParam;
+
+    RECT                rect;
+
+    struct tagHelpButton*next;
+} WINHELP_BUTTON;
+
+typedef struct tagWinHelp
+{
+    LPCSTR              lpszName;
+
+    WINHELP_BUTTON*     first_button;
+    HLPFILE_PAGE*       page;
+    WINHELP_LINE*       first_line;
+
+    HWND                hMainWnd;
+    HWND                hButtonBoxWnd;
+    HWND                hTextWnd;
+    HWND                hShadowWnd;
+    HWND                hHistoryWnd;
+
+    HFONT*              fonts;
+    UINT                fonts_len;
+
+    HCURSOR             hArrowCur;
+    HCURSOR             hHandCur;
+
+    HBRUSH              hBrush;
+
+    HLPFILE_WINDOWINFO* info;
+
+    /* FIXME: for now it's a fixed size */
+    HLPFILE_PAGE*       history[40];
+    unsigned            histIndex;
+    HLPFILE_PAGE*       back[40];
+    unsigned            backIndex;
+
+    struct tagWinHelp*  next;
+} WINHELP_WINDOW;
+
+#define DC_NOMSG     0x00000000
+#define DC_MINMAX    0x00000001
+#define DC_INITTERM  0x00000002
+#define DC_JUMP      0x00000004
+#define DC_ACTIVATE  0x00000008
+#define DC_CALLBACKS 0x00000010
+
+#define DW_NOTUSED    0
+#define DW_WHATMSG    1
+#define DW_MINMAX     2
+#define DW_SIZE       3
+#define DW_INIT       4
+#define DW_TERM       5
+#define DW_STARTJUMP  6
+#define DW_ENDJUMP    7
+#define DW_CHGFILE    8
+#define DW_ACTIVATE   9
+#define        DW_CALLBACKS 10
+
+typedef long (CALLBACK *WINHELP_LDLLHandler)(WORD, LONG, LONG);
+
+typedef struct tagDll
+{
+    HANDLE              hLib;
+    const char*         name;
+    WINHELP_LDLLHandler handler;
+    DWORD               class;
+    struct tagDll*      next;
+} WINHELP_DLL;
+
+typedef struct
+{
+    UINT                wVersion;
+    HANDLE              hInstance;
+    HWND                hPopupWnd;
+    UINT                wStringTableOffset;
+    BOOL                isBook;
+    WINHELP_WINDOW*     active_win;
+    WINHELP_WINDOW*     win_list;
+    WNDPROC             button_proc;
+    WINHELP_DLL*        dlls;
+} WINHELP_GLOBALS;
+
+extern WINHELP_GLOBALS Globals;
+extern FARPROC         Callbacks[];
+
+BOOL WINHELP_CreateHelpWindowByHash(HLPFILE*, LONG, HLPFILE_WINDOWINFO*, int);
+BOOL WINHELP_CreateHelpWindowByMap(HLPFILE*, LONG, HLPFILE_WINDOWINFO*, int);
+BOOL WINHELP_CreateHelpWindow(HLPFILE_PAGE*, HLPFILE_WINDOWINFO*, int);
+BOOL WINHELP_GetOpenFileName(LPSTR, int);
+INT  WINHELP_MessageBoxIDS(UINT, UINT, WORD);
+INT  WINHELP_MessageBoxIDS_s(UINT, LPCSTR, UINT, WORD);
+HLPFILE* WINHELP_LookupHelpFile(LPCSTR lpszFile);
+HLPFILE_WINDOWINFO* WINHELP_GetWindowInfo(HLPFILE* hlpfile, LPCSTR name);
+
+extern const char MAIN_WIN_CLASS_NAME[];
+extern const char BUTTON_BOX_WIN_CLASS_NAME[];
+extern const char TEXT_WIN_CLASS_NAME[];
+extern const char SHADOW_WIN_CLASS_NAME[];
+extern const char HISTORY_WIN_CLASS_NAME[];
+extern const char STRING_BUTTON[];
+extern const char STRING_MENU_Xx[];
+extern const char STRING_DIALOG_TEST[];
+#endif
+
+/* Buttons */
+#define WH_FIRST_BUTTON     500
+
+#endif /* __WINHELP_H__ */
diff --git a/reactos/base/applications/winhelp/winhelp.rbuild b/reactos/base/applications/winhelp/winhelp.rbuild
new file mode 100644 (file)
index 0000000..f9591c4
--- /dev/null
@@ -0,0 +1,26 @@
+<?xml version="1.0"?>\r
+<rbuild xmlns:xi="http://www.w3.org/2001/XInclude">\r
+       <module name="winhelp" type="win32gui" installbase="system32" installname="winhelp.exe" unicode="no">\r
+               <include base="winhelp">.</include>\r
+               <define name="__USE_W32API" />\r
+               <define name="_WIN32_IE">0x0600</define>\r
+               <define name="_WIN32_WINNT">0x0501</define>\r
+               <library>kernel32</library>\r
+               <library>user32</library>\r
+               <library>gdi32</library>\r
+               <library>ntdll</library>\r
+               <library>comdlg32</library>\r
+               <library>advapi32</library>\r
+               <library>shell32</library>\r
+               <library>comctl32</library>\r
+               <compilationunit name="unit.c">\r
+                       <file>callback.c</file>\r
+                       <file>hlpfile.c</file>\r
+                       <file>macro.c</file>\r
+                       <file>string.c</file>\r
+                       <file>winhelp.c</file>\r
+                       <file>lex.yy.c</file>\r
+               </compilationunit>\r
+               <file>rsrc.rc</file>\r
+       </module>\r
+</rbuild>\r
diff --git a/reactos/base/applications/winhelp/winhelp_res.h b/reactos/base/applications/winhelp/winhelp_res.h
new file mode 100644 (file)
index 0000000..a6e46f1
--- /dev/null
@@ -0,0 +1,32 @@
+#define MNID_FILE_OPEN          0x101
+#define MNID_FILE_PRINT         0x104
+#define MNID_FILE_SETUP         0x106
+#define MNID_FILE_EXIT          0x108
+
+#define MNID_EDIT_COPYDLG       0x111
+#define MNID_EDIT_ANNOTATE      0x112
+
+#define MNID_BKMK_DEFINE        0x121
+
+#define MNID_HELP_HELPON        0x131
+#define MNID_HELP_HELPTOP       0x132
+#define MNID_HELP_ABOUT         0x141
+#define MNID_HELP_WINE          0x142
+
+#define MAIN_MENU              0x10F
+
+#define STID_WINE_HELP         0x120
+#define STID_WHERROR           0x121
+#define STID_WARNING           0x122
+#define STID_INFO              0x123
+#define STID_NOT_IMPLEMENTED   0x124
+#define STID_HLPFILE_ERROR_s   0x125
+#define STID_CONTENTS          0x126
+#define STID_SEARCH            0x127
+#define STID_BACK              0x128
+#define STID_HISTORY           0x129
+#define STID_TOPICS            0x12A
+#define STID_ALL_FILES                 0x12B
+#define STID_HELP_FILES_HLP    0x12C
+#define STID_DIALOG_TEST       0x12D
+#define STID_FILE_NOT_FOUND_s  0x12E