diff --git a/reactos/baseaddress.rbuild b/reactos/baseaddress.rbuild
index 4d606c84f2c..e5279947ce7 100644
--- a/reactos/baseaddress.rbuild
+++ b/reactos/baseaddress.rbuild
@@ -136,6 +136,7 @@
+
diff --git a/reactos/dll/win32/hhctrl.ocx/Cs.rc b/reactos/dll/win32/hhctrl.ocx/Cs.rc
new file mode 100644
index 00000000000..ec564d830d1
--- /dev/null
+++ b/reactos/dll/win32/hhctrl.ocx/Cs.rc
@@ -0,0 +1,62 @@
+/* Hey, Emacs, open this file with -*- coding: cp1250 -*-
+ *
+ * HTML Help resources
+ * Czech Language Support
+ *
+ * Copyright 2005 James Hawkins
+ * Copyright 2005 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
+ */
+
+LANGUAGE LANG_CZECH, SUBLANG_DEFAULT
+
+/* Czech strings in CP1250 */
+
+STRINGTABLE
+BEGIN
+ IDS_CONTENTS "&Obsah"
+ IDS_INDEX "I&ndex"
+ IDS_SEARCH "&Hledat"
+ IDS_FAVORITES "Oblí&bené"
+END
+
+STRINGTABLE
+BEGIN
+ IDTB_EXPAND "Rozbalit"
+ IDTB_CONTRACT "Skrýt"
+ IDTB_STOP "Zastavit"
+ IDTB_REFRESH "Obnovit"
+ IDTB_BACK "Zpìt"
+ IDTB_HOME "Domù"
+ IDTB_SYNC "Synchronizovat"
+ IDTB_PRINT "Tisk"
+ IDTB_OPTIONS "Volby"
+ IDTB_FORWARD "Vpøed"
+ IDTB_NOTES "IDTB_NOTES"
+ IDTB_BROWSE_FWD "IDTB_BROWSE_FWD"
+ IDTB_BROWSE_BACK "IDT_BROWSE_BACK"
+ IDTB_CONTENTS "IDTB_CONTENTS"
+ IDTB_INDEX "IDTB_INDEX"
+ IDTB_SEARCH "IDTB_SEARCH"
+ IDTB_HISTORY "IDTB_HISTORY"
+ IDTB_FAVORITES "IDTB_FAVORITES"
+ IDTB_JUMP1 "Skok1"
+ IDTB_JUMP2 "Skok2"
+ IDTB_CUSTOMIZE "Pøizpùsobit"
+ IDTB_ZOOM "Lupa"
+ IDTB_TOC_NEXT "IDTB_TOC_NEXT"
+ IDTB_TOC_PREV "IDTB_TOC_PREV"
+END
diff --git a/reactos/dll/win32/hhctrl.ocx/De.rc b/reactos/dll/win32/hhctrl.ocx/De.rc
new file mode 100644
index 00000000000..ef6e6997bd5
--- /dev/null
+++ b/reactos/dll/win32/hhctrl.ocx/De.rc
@@ -0,0 +1,58 @@
+/*
+ * HTML Help resources
+ * German Language Support
+ *
+ * Copyright 2005 Henning Gerhardt
+ *
+ * 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
+ */
+
+LANGUAGE LANG_GERMAN, SUBLANG_NEUTRAL
+
+STRINGTABLE
+BEGIN
+ IDS_CONTENTS "&Inhalt"
+ IDS_INDEX "I&ndex"
+ IDS_SEARCH "&Suche"
+ IDS_FAVORITES "&Favoriten"
+END
+
+STRINGTABLE
+BEGIN
+ IDTB_EXPAND "Anzeigen"
+ IDTB_CONTRACT "Verstecken"
+ IDTB_STOP "Stop"
+ IDTB_REFRESH "Aktualisieren"
+ IDTB_BACK "Zurück"
+ IDTB_HOME "Startseite"
+ IDTB_SYNC "Synchronisieren"
+ IDTB_PRINT "Drucken"
+ IDTB_OPTIONS "Einstellungen"
+ IDTB_FORWARD "Vorwärts"
+ IDTB_NOTES "IDTB_NOTES"
+ IDTB_BROWSE_FWD "IDTB_BROWSE_FWD"
+ IDTB_BROWSE_BACK "IDT_BROWSE_BACK"
+ IDTB_CONTENTS "IDTB_CONTENTS"
+ IDTB_INDEX "IDTB_INDEX"
+ IDTB_SEARCH "IDTB_SEARCH"
+ IDTB_HISTORY "IDTB_HISTORY"
+ IDTB_FAVORITES "IDTB_FAVORITES"
+ IDTB_JUMP1 "Sprung1"
+ IDTB_JUMP2 "Sprung2"
+ IDTB_CUSTOMIZE "Anpassen"
+ IDTB_ZOOM "Vergrößern"
+ IDTB_TOC_NEXT "IDTB_TOC_NEXT"
+ IDTB_TOC_PREV "IDTB_TOC_PREV"
+END
diff --git a/reactos/dll/win32/hhctrl.ocx/En.rc b/reactos/dll/win32/hhctrl.ocx/En.rc
new file mode 100644
index 00000000000..e55162adfe0
--- /dev/null
+++ b/reactos/dll/win32/hhctrl.ocx/En.rc
@@ -0,0 +1,58 @@
+/*
+ * HTML Help resources
+ * English Language Support
+ *
+ * Copyright 2005 James Hawkins
+ *
+ * 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
+ */
+
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+
+STRINGTABLE
+BEGIN
+ IDS_CONTENTS "&Contents"
+ IDS_INDEX "I&ndex"
+ IDS_SEARCH "&Search"
+ IDS_FAVORITES "Favor&ites"
+END
+
+STRINGTABLE
+BEGIN
+ IDTB_EXPAND "Show"
+ IDTB_CONTRACT "Hide"
+ IDTB_STOP "Stop"
+ IDTB_REFRESH "Refresh"
+ IDTB_BACK "Back"
+ IDTB_HOME "Home"
+ IDTB_SYNC "Sync"
+ IDTB_PRINT "Print"
+ IDTB_OPTIONS "Options"
+ IDTB_FORWARD "Forward"
+ IDTB_NOTES "IDTB_NOTES"
+ IDTB_BROWSE_FWD "IDTB_BROWSE_FWD"
+ IDTB_BROWSE_BACK "IDT_BROWSE_BACK"
+ IDTB_CONTENTS "IDTB_CONTENTS"
+ IDTB_INDEX "IDTB_INDEX"
+ IDTB_SEARCH "IDTB_SEARCH"
+ IDTB_HISTORY "IDTB_HISTORY"
+ IDTB_FAVORITES "IDTB_FAVORITES"
+ IDTB_JUMP1 "Jump1"
+ IDTB_JUMP2 "Jump2"
+ IDTB_CUSTOMIZE "Customize"
+ IDTB_ZOOM "Zoom"
+ IDTB_TOC_NEXT "IDTB_TOC_NEXT"
+ IDTB_TOC_PREV "IDTB_TOC_PREV"
+END
diff --git a/reactos/dll/win32/hhctrl.ocx/Fi.rc b/reactos/dll/win32/hhctrl.ocx/Fi.rc
new file mode 100644
index 00000000000..975ce1f49aa
--- /dev/null
+++ b/reactos/dll/win32/hhctrl.ocx/Fi.rc
@@ -0,0 +1,58 @@
+/*
+ * HTML Help resources
+ * Finnish Language Support
+ *
+ * Copyright 2005 Kimmo Myllyvirta
+ *
+ * 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
+ */
+
+LANGUAGE LANG_FINNISH, SUBLANG_DEFAULT
+
+STRINGTABLE
+BEGIN
+ IDS_CONTENTS "&Sisällys"
+ IDS_INDEX "&Hakemisto"
+ IDS_SEARCH "&Etsi"
+ IDS_FAVORITES "S&uosikit"
+END
+
+STRINGTABLE
+BEGIN
+ IDTB_EXPAND "Näytä"
+ IDTB_CONTRACT "Piilota"
+ IDTB_STOP "Pysäytä"
+ IDTB_REFRESH "Päivitä"
+ IDTB_BACK "Takaisin"
+ IDTB_HOME "Alkuun"
+ IDTB_SYNC "Synkronoi"
+ IDTB_PRINT "Tulosta"
+ IDTB_OPTIONS "Valinnat"
+ IDTB_FORWARD "Seuraava"
+ IDTB_NOTES "IDTB_NOTES"
+ IDTB_BROWSE_FWD "IDTB_BROWSE_FWD"
+ IDTB_BROWSE_BACK "IDT_BROWSE_BACK"
+ IDTB_CONTENTS "IDTB_CONTENTS"
+ IDTB_INDEX "IDTB_INDEX"
+ IDTB_SEARCH "IDTB_SEARCH"
+ IDTB_HISTORY "IDTB_HISTORY"
+ IDTB_FAVORITES "IDTB_FAVORITES"
+ IDTB_JUMP1 "Hyppää1"
+ IDTB_JUMP2 "Hyppää2"
+ IDTB_CUSTOMIZE "Räätälöi"
+ IDTB_ZOOM "Suurenna"
+ IDTB_TOC_NEXT "IDTB_TOC_NEXT"
+ IDTB_TOC_PREV "IDTB_TOC_PREV"
+END
diff --git a/reactos/dll/win32/hhctrl.ocx/Fr.rc b/reactos/dll/win32/hhctrl.ocx/Fr.rc
new file mode 100644
index 00000000000..0e5dd4f9591
--- /dev/null
+++ b/reactos/dll/win32/hhctrl.ocx/Fr.rc
@@ -0,0 +1,58 @@
+/*
+ * HTML Help resources
+ * French Language Support
+ *
+ * Copyright 2006 Jonathan Ernst
+ *
+ * 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
+ */
+
+LANGUAGE LANG_FRENCH, SUBLANG_NEUTRAL
+
+STRINGTABLE
+BEGIN
+ IDS_CONTENTS "Somm&aire"
+ IDS_INDEX "I&ndex"
+ IDS_SEARCH "&Recherche"
+ IDS_FAVORITES "&Signets"
+END
+
+STRINGTABLE
+BEGIN
+ IDTB_EXPAND "Afficher"
+ IDTB_CONTRACT "Cacher"
+ IDTB_STOP "Arrêter"
+ IDTB_REFRESH "A&ctualiser"
+ IDTB_BACK "Précédent"
+ IDTB_HOME "Sommaire"
+ IDTB_SYNC "Synchroniser"
+ IDTB_PRINT "Imprimer"
+ IDTB_OPTIONS "Options"
+ IDTB_FORWARD "Suivant"
+ IDTB_NOTES "IDTB_NOTES"
+ IDTB_BROWSE_FWD "IDTB_BROWSE_FWD"
+ IDTB_BROWSE_BACK "IDT_BROWSE_BACK"
+ IDTB_CONTENTS "IDTB_CONTENTS"
+ IDTB_INDEX "IDTB_INDEX"
+ IDTB_SEARCH "IDTB_SEARCH"
+ IDTB_HISTORY "IDTB_HISTORY"
+ IDTB_FAVORITES "IDTB_FAVORITES"
+ IDTB_JUMP1 "Jump1"
+ IDTB_JUMP2 "Jump2"
+ IDTB_CUSTOMIZE "Personnaliser"
+ IDTB_ZOOM "Zoom"
+ IDTB_TOC_NEXT "IDTB_TOC_NEXT"
+ IDTB_TOC_PREV "IDTB_TOC_PREV"
+END
diff --git a/reactos/dll/win32/hhctrl.ocx/Hu.rc b/reactos/dll/win32/hhctrl.ocx/Hu.rc
new file mode 100644
index 00000000000..225c04a82d7
--- /dev/null
+++ b/reactos/dll/win32/hhctrl.ocx/Hu.rc
@@ -0,0 +1,58 @@
+/*
+ * HTML Help resources
+ * Hungarian Language Support
+ *
+ * Copyright 2006 Andras Kovacs
+ *
+ * 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
+ */
+
+LANGUAGE LANG_HUNGARIAN, SUBLANG_DEFAULT
+
+STRINGTABLE
+BEGIN
+ IDS_CONTENTS "&Tartalom"
+ IDS_INDEX "I&ndex"
+ IDS_SEARCH "&Keresés"
+ IDS_FAVORITES "Kedven&cek"
+END
+
+STRINGTABLE
+BEGIN
+ IDTB_EXPAND "Megjelenítés"
+ IDTB_CONTRACT "Elrejtés"
+ IDTB_STOP "Megállítás"
+ IDTB_REFRESH "Frissítés"
+ IDTB_BACK "Vissza"
+ IDTB_HOME "Kezdõlap"
+ IDTB_SYNC "Szink."
+ IDTB_PRINT "Nyomtatás"
+ IDTB_OPTIONS "Opciók"
+ IDTB_FORWARD "Elõre"
+ IDTB_NOTES "IDTB_NOTES"
+ IDTB_BROWSE_FWD "IDTB_BROWSE_FWD"
+ IDTB_BROWSE_BACK "IDT_BROWSE_BACK"
+ IDTB_CONTENTS "IDTB_CONTENTS"
+ IDTB_INDEX "IDTB_INDEX"
+ IDTB_SEARCH "IDTB_SEARCH"
+ IDTB_HISTORY "IDTB_HISTORY"
+ IDTB_FAVORITES "IDTB_FAVORITES"
+ IDTB_JUMP1 "Jump1"
+ IDTB_JUMP2 "Jump2"
+ IDTB_CUSTOMIZE "Testreszabás"
+ IDTB_ZOOM "Zoom"
+ IDTB_TOC_NEXT "IDTB_TOC_NEXT"
+ IDTB_TOC_PREV "IDTB_TOC_PREV"
+END
diff --git a/reactos/dll/win32/hhctrl.ocx/Ko.rc b/reactos/dll/win32/hhctrl.ocx/Ko.rc
new file mode 100644
index 00000000000..05f7aafe8ba
--- /dev/null
+++ b/reactos/dll/win32/hhctrl.ocx/Ko.rc
@@ -0,0 +1,59 @@
+/*
+ * HTML Help resources
+ * English Language Support
+ *
+ * Copyright 2005 James Hawkins
+ * Copyright 2005 YunSong Hwang
+
+ * 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
+ */
+
+LANGUAGE LANG_KOREAN, SUBLANG_NEUTRAL
+
+STRINGTABLE
+BEGIN
+ IDS_CONTENTS "¸ñ·Ï(&C)"
+ IDS_INDEX "À妽º(&N)"
+ IDS_SEARCH "ã±â(&S)"
+ IDS_FAVORITES "Áñ°Üã±â(&I)"
+END
+
+STRINGTABLE
+BEGIN
+ IDTB_EXPAND "º¸¿©ÁÖ±â"
+ IDTB_CONTRACT "¼û±â±â"
+ IDTB_STOP "Á¤Áö"
+ IDTB_REFRESH "»õ·Î °íħ"
+ IDTB_BACK "µÚ·Î"
+ IDTB_HOME "Ȩ"
+ IDTB_SYNC "µ¿±âÈ"
+ IDTB_PRINT "Àμâ"
+ IDTB_OPTIONS "¿É¼Ç"
+ IDTB_FORWARD "¾ÕÀ¸·Î"
+ IDTB_NOTES "IDTB_NOTES"
+ IDTB_BROWSE_FWD "IDTB_BROWSE_FWD"
+ IDTB_BROWSE_BACK "IDT_BROWSE_BACK"
+ IDTB_CONTENTS "IDTB_CONTENTS"
+ IDTB_INDEX "IDTB_INDEX"
+ IDTB_SEARCH "IDTB_SEARCH"
+ IDTB_HISTORY "IDTB_HISTORY"
+ IDTB_FAVORITES "IDTB_FAVORITES"
+ IDTB_JUMP1 "Jump1"
+ IDTB_JUMP2 "Jump2"
+ IDTB_CUSTOMIZE "»ç¿ëÀÚÁ¤ÀÇ"
+ IDTB_ZOOM "È®´ë"
+ IDTB_TOC_NEXT "IDTB_TOC_NEXT"
+ IDTB_TOC_PREV "IDTB_TOC_PREV"
+END
diff --git a/reactos/dll/win32/hhctrl.ocx/Nl.rc b/reactos/dll/win32/hhctrl.ocx/Nl.rc
new file mode 100644
index 00000000000..929ac39f6da
--- /dev/null
+++ b/reactos/dll/win32/hhctrl.ocx/Nl.rc
@@ -0,0 +1,58 @@
+/*
+ * HTML Help resources
+ * Dutch Language Support
+ *
+ * Copyright 2005 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
+ */
+
+LANGUAGE LANG_DUTCH, SUBLANG_NEUTRAL
+
+STRINGTABLE
+BEGIN
+ IDS_CONTENTS "&Inhoud"
+ IDS_INDEX "I&ndex"
+ IDS_SEARCH "&Zoeken"
+ IDS_FAVORITES "&Favorieten"
+END
+
+STRINGTABLE
+BEGIN
+ IDTB_EXPAND "Weergeven"
+ IDTB_CONTRACT "Verbergen"
+ IDTB_STOP "Stop"
+ IDTB_REFRESH "Actualiseren"
+ IDTB_BACK "Terug"
+ IDTB_HOME "Startpagina"
+ IDTB_SYNC "Synchroniseren"
+ IDTB_PRINT "Afdrukken"
+ IDTB_OPTIONS "Instellingen"
+ IDTB_FORWARD "Vooruit"
+ IDTB_NOTES "IDTB_NOTES"
+ IDTB_BROWSE_FWD "IDTB_BROWSE_FWD"
+ IDTB_BROWSE_BACK "IDT_BROWSE_BACK"
+ IDTB_CONTENTS "IDTB_CONTENTS"
+ IDTB_INDEX "IDTB_INDEX"
+ IDTB_SEARCH "IDTB_SEARCH"
+ IDTB_HISTORY "IDTB_HISTORY"
+ IDTB_FAVORITES "IDTB_FAVORITES"
+ IDTB_JUMP1 "Sprong1"
+ IDTB_JUMP2 "Sprong2"
+ IDTB_CUSTOMIZE "Aanpassen"
+ IDTB_ZOOM "Vergroten"
+ IDTB_TOC_NEXT "IDTB_TOC_NEXT"
+ IDTB_TOC_PREV "IDTB_TOC_PREV"
+END
diff --git a/reactos/dll/win32/hhctrl.ocx/No.rc b/reactos/dll/win32/hhctrl.ocx/No.rc
new file mode 100644
index 00000000000..5ff634d02df
--- /dev/null
+++ b/reactos/dll/win32/hhctrl.ocx/No.rc
@@ -0,0 +1,58 @@
+/*
+ * HTML Help resources
+ * Norwegian Bokmål Language Support
+ *
+ * Copyright 2005 Alexander N. Sørnes
+ *
+ * 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
+ */
+
+LANGUAGE LANG_NORWEGIAN, SUBLANG_NORWEGIAN_BOKMAL
+
+STRINGTABLE
+BEGIN
+ IDS_CONTENTS "&Innhold"
+ IDS_INDEX "I&ndeks"
+ IDS_SEARCH "&Søk"
+ IDS_FAVORITES "Favor&itter"
+END
+
+STRINGTABLE
+BEGIN
+ IDTB_EXPAND "Vis"
+ IDTB_CONTRACT "Skjul"
+ IDTB_STOP "Stopp"
+ IDTB_REFRESH "Oppdater"
+ IDTB_BACK "Tilbake"
+ IDTB_HOME "Hjem"
+ IDTB_SYNC "Synkroniser"
+ IDTB_PRINT "Skriv ut"
+ IDTB_OPTIONS "Innstillinger"
+ IDTB_FORWARD "Fram"
+ IDTB_NOTES "IDTB_NOTES"
+ IDTB_BROWSE_FWD "IDTB_BROWSE_FWD"
+ IDTB_BROWSE_BACK "IDT_BROWSE_BACK"
+ IDTB_CONTENTS "IDTB_CONTENTS"
+ IDTB_INDEX "IDTB_INDEX"
+ IDTB_SEARCH "IDTB_SEARCH"
+ IDTB_HISTORY "IDTB_HISTORY"
+ IDTB_FAVORITES "IDTB_FAVORITES"
+ IDTB_JUMP1 "Jump1"
+ IDTB_JUMP2 "Jump2"
+ IDTB_CUSTOMIZE "Tilpass"
+ IDTB_ZOOM "Forstørr"
+ IDTB_TOC_NEXT "IDTB_TOC_NEXT"
+ IDTB_TOC_PREV "IDTB_TOC_PREV"
+END
diff --git a/reactos/dll/win32/hhctrl.ocx/Pl.rc b/reactos/dll/win32/hhctrl.ocx/Pl.rc
new file mode 100644
index 00000000000..1323ec3e7e5
--- /dev/null
+++ b/reactos/dll/win32/hhctrl.ocx/Pl.rc
@@ -0,0 +1,59 @@
+/*
+ * HTML Help resources
+ * Polish Language Support
+ *
+ * Copyright 2005 James Hawkins
+ * Copyright 2006 Mikolaj Zalewski
+ *
+ * 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
+ */
+
+LANGUAGE LANG_POLISH, SUBLANG_DEFAULT
+
+STRINGTABLE
+BEGIN
+ IDS_CONTENTS "&Spis treœci"
+ IDS_INDEX "&Indeks"
+ IDS_SEARCH "&Wyszukaj"
+ IDS_FAVORITES "&Ulubione"
+END
+
+STRINGTABLE
+BEGIN
+ IDTB_EXPAND "Poka¿"
+ IDTB_CONTRACT "Ukryj"
+ IDTB_STOP "Zatrzymaj"
+ IDTB_REFRESH "Odœwie¿"
+ IDTB_BACK "Wstecz"
+ IDTB_HOME "Start"
+ IDTB_SYNC "Sync"
+ IDTB_PRINT "Drukuj"
+ IDTB_OPTIONS "Opcje"
+ IDTB_FORWARD "Dalej"
+ IDTB_NOTES "IDTB_NOTES"
+ IDTB_BROWSE_FWD "IDTB_BROWSE_FWD"
+ IDTB_BROWSE_BACK "IDT_BROWSE_BACK"
+ IDTB_CONTENTS "IDTB_CONTENTS"
+ IDTB_INDEX "IDTB_INDEX"
+ IDTB_SEARCH "IDTB_SEARCH"
+ IDTB_HISTORY "IDTB_HISTORY"
+ IDTB_FAVORITES "IDTB_FAVORITES"
+ IDTB_JUMP1 "Skok1"
+ IDTB_JUMP2 "Skok2"
+ IDTB_CUSTOMIZE "Dostosuj"
+ IDTB_ZOOM "Powiêksz"
+ IDTB_TOC_NEXT "IDTB_TOC_NEXT"
+ IDTB_TOC_PREV "IDTB_TOC_PREV"
+END
diff --git a/reactos/dll/win32/hhctrl.ocx/Tr.rc b/reactos/dll/win32/hhctrl.ocx/Tr.rc
new file mode 100644
index 00000000000..748899908f7
--- /dev/null
+++ b/reactos/dll/win32/hhctrl.ocx/Tr.rc
@@ -0,0 +1,58 @@
+/*
+ * HTML Help resources
+ * Turkish Language Support
+ *
+ * Copyright 2006 Fatih Aþýcý
+ *
+ * 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
+ */
+
+LANGUAGE LANG_TURKISH, SUBLANG_DEFAULT
+
+STRINGTABLE
+BEGIN
+ IDS_CONTENTS "&Ýçerik"
+ IDS_INDEX "Di&zin"
+ IDS_SEARCH "&Ara"
+ IDS_FAVORITES "&Sýk Kullanýlanlar"
+END
+
+STRINGTABLE
+BEGIN
+ IDTB_EXPAND "Göster"
+ IDTB_CONTRACT "Gizle"
+ IDTB_STOP "Dur"
+ IDTB_REFRESH "Yenile"
+ IDTB_BACK "Geri"
+ IDTB_HOME "Ev"
+ IDTB_SYNC "Eþitle"
+ IDTB_PRINT "Yazdýr"
+ IDTB_OPTIONS "Seçenekler"
+ IDTB_FORWARD "Ýleri"
+ IDTB_NOTES "IDTB_NOTES"
+ IDTB_BROWSE_FWD "IDTB_BROWSE_FWD"
+ IDTB_BROWSE_BACK "IDT_BROWSE_BACK"
+ IDTB_CONTENTS "IDTB_CONTENTS"
+ IDTB_INDEX "IDTB_INDEX"
+ IDTB_SEARCH "IDTB_SEARCH"
+ IDTB_HISTORY "IDTB_HISTORY"
+ IDTB_FAVORITES "IDTB_FAVORITES"
+ IDTB_JUMP1 "Jump1"
+ IDTB_JUMP2 "Jump2"
+ IDTB_CUSTOMIZE "Özelleþtir"
+ IDTB_ZOOM "Yaklaþtýr"
+ IDTB_TOC_NEXT "IDTB_TOC_NEXT"
+ IDTB_TOC_PREV "IDTB_TOC_PREV"
+END
diff --git a/reactos/dll/win32/hhctrl.ocx/chm.c b/reactos/dll/win32/hhctrl.ocx/chm.c
new file mode 100644
index 00000000000..d65d766a18c
--- /dev/null
+++ b/reactos/dll/win32/hhctrl.ocx/chm.c
@@ -0,0 +1,399 @@
+/*
+ * CHM Utility API
+ *
+ * Copyright 2005 James Hawkins
+ * Copyright 2007 Jacek 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
+ */
+
+#include "hhctrl.h"
+
+#include "winreg.h"
+#include "shlwapi.h"
+#include "wine/debug.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(htmlhelp);
+
+#define BLOCK_BITS 12
+#define BLOCK_SIZE (1 << BLOCK_BITS)
+#define BLOCK_MASK (BLOCK_SIZE-1)
+
+/* Reads a string from the #STRINGS section in the CHM file */
+static LPCSTR GetChmString(CHMInfo *chm, DWORD offset)
+{
+ if(!chm->strings_stream)
+ return NULL;
+
+ if(chm->strings_size <= (offset >> BLOCK_BITS)) {
+ if(chm->strings)
+ chm->strings = hhctrl_realloc_zero(chm->strings,
+ chm->strings_size = ((offset >> BLOCK_BITS)+1)*sizeof(char*));
+ else
+ chm->strings = hhctrl_alloc_zero(
+ chm->strings_size = ((offset >> BLOCK_BITS)+1)*sizeof(char*));
+
+ }
+
+ if(!chm->strings[offset >> BLOCK_BITS]) {
+ LARGE_INTEGER pos;
+ DWORD read;
+ HRESULT hres;
+
+ pos.QuadPart = offset & ~BLOCK_MASK;
+ hres = IStream_Seek(chm->strings_stream, pos, STREAM_SEEK_SET, NULL);
+ if(FAILED(hres)) {
+ WARN("Seek failed: %08x\n", hres);
+ return NULL;
+ }
+
+ chm->strings[offset >> BLOCK_BITS] = hhctrl_alloc(BLOCK_SIZE);
+
+ hres = IStream_Read(chm->strings_stream, chm->strings[offset >> BLOCK_BITS],
+ BLOCK_SIZE, &read);
+ if(FAILED(hres)) {
+ WARN("Read failed: %08x\n", hres);
+ hhctrl_free(chm->strings[offset >> BLOCK_BITS]);
+ chm->strings[offset >> BLOCK_BITS] = NULL;
+ return NULL;
+ }
+ }
+
+ return chm->strings[offset >> BLOCK_BITS] + (offset & BLOCK_MASK);
+}
+
+static BOOL ReadChmSystem(CHMInfo *chm)
+{
+ IStream *stream;
+ DWORD ver=0xdeadbeef, read, buf_size;
+ char *buf;
+ HRESULT hres;
+
+ struct {
+ WORD code;
+ WORD len;
+ } entry;
+
+ static const WCHAR wszSYSTEM[] = {'#','S','Y','S','T','E','M',0};
+
+ hres = IStorage_OpenStream(chm->pStorage, wszSYSTEM, NULL, STGM_READ, 0, &stream);
+ if(FAILED(hres)) {
+ WARN("Could not open #SYSTEM stream: %08x\n", hres);
+ return FALSE;
+ }
+
+ IStream_Read(stream, &ver, sizeof(ver), &read);
+ TRACE("version is %x\n", ver);
+
+ buf = hhctrl_alloc(8*sizeof(DWORD));
+ buf_size = 8*sizeof(DWORD);
+
+ while(1) {
+ hres = IStream_Read(stream, &entry, sizeof(entry), &read);
+ if(hres != S_OK)
+ break;
+
+ if(entry.len > buf_size)
+ buf = hhctrl_realloc(buf, buf_size=entry.len);
+
+ hres = IStream_Read(stream, buf, entry.len, &read);
+ if(hres != S_OK)
+ break;
+
+ switch(entry.code) {
+ case 0x2:
+ TRACE("Default topic is %s\n", debugstr_an(buf, entry.len));
+ break;
+ case 0x3:
+ TRACE("Title is %s\n", debugstr_an(buf, entry.len));
+ break;
+ case 0x5:
+ TRACE("Default window is %s\n", debugstr_an(buf, entry.len));
+ break;
+ case 0x6:
+ TRACE("Compiled file is %s\n", debugstr_an(buf, entry.len));
+ break;
+ case 0x9:
+ TRACE("Version is %s\n", debugstr_an(buf, entry.len));
+ break;
+ case 0xa:
+ TRACE("Time is %08x\n", *(DWORD*)buf);
+ break;
+ case 0xc:
+ TRACE("Number of info types: %d\n", *(DWORD*)buf);
+ break;
+ case 0xf:
+ TRACE("Check sum: %x\n", *(DWORD*)buf);
+ break;
+ default:
+ TRACE("unhandled code %x, size %x\n", entry.code, entry.len);
+ }
+ }
+
+ hhctrl_free(buf);
+ IStream_Release(stream);
+
+ return SUCCEEDED(hres);
+}
+
+LPWSTR FindContextAlias(CHMInfo *chm, DWORD index)
+{
+ IStream *ivb_stream;
+ DWORD size, read, i;
+ DWORD *buf;
+ LPCSTR ret = NULL;
+ HRESULT hres;
+
+ static const WCHAR wszIVB[] = {'#','I','V','B',0};
+
+ hres = IStorage_OpenStream(chm->pStorage, wszIVB, NULL, STGM_READ, 0, &ivb_stream);
+ if(FAILED(hres)) {
+ WARN("Could not open #IVB stream: %08x\n", hres);
+ return NULL;
+ }
+
+ hres = IStream_Read(ivb_stream, &size, sizeof(size), &read);
+ if(FAILED(hres)) {
+ WARN("Read failed: %08x\n", hres);
+ IStream_Release(ivb_stream);
+ return NULL;
+ }
+
+ buf = hhctrl_alloc(size);
+ hres = IStream_Read(ivb_stream, buf, size, &read);
+ IStream_Release(ivb_stream);
+ if(FAILED(hres)) {
+ WARN("Read failed: %08x\n", hres);
+ hhctrl_free(buf);
+ return NULL;
+ }
+
+ size /= 2*sizeof(DWORD);
+
+ for(i=0; ipStorage;
+ IStream *pStream;
+ HRESULT hr;
+ DWORD cbRead;
+
+ static const WCHAR windowsW[] = {'#','W','I','N','D','O','W','S',0};
+
+ hr = IStorage_OpenStream(pStorage, windowsW, NULL, STGM_READ, 0, &pStream);
+ if (FAILED(hr))
+ return FALSE;
+
+ /* jump past the #WINDOWS header */
+ liOffset.QuadPart = sizeof(DWORD) * 2;
+
+ hr = IStream_Seek(pStream, liOffset, STREAM_SEEK_SET, NULL);
+ if (FAILED(hr)) goto done;
+
+ /* read the HH_WINTYPE struct data */
+ hr = IStream_Read(pStream, pHHWinType, sizeof(*pHHWinType), &cbRead);
+ if (FAILED(hr)) goto done;
+
+ /* convert the #STRINGS offsets to actual strings */
+ pHHWinType->pszType = strdupAtoW(GetChmString(pChmInfo, (DWORD)pHHWinType->pszType));
+ pHHWinType->pszCaption = strdupAtoW(GetChmString(pChmInfo, (DWORD)pHHWinType->pszCaption));
+ pHHWinType->pszToc = strdupAtoW(GetChmString(pChmInfo, (DWORD)pHHWinType->pszToc));
+ pHHWinType->pszIndex = strdupAtoW(GetChmString(pChmInfo, (DWORD)pHHWinType->pszIndex));
+ pHHWinType->pszFile = strdupAtoW(GetChmString(pChmInfo, (DWORD)pHHWinType->pszFile));
+ pHHWinType->pszHome = strdupAtoW(GetChmString(pChmInfo, (DWORD)pHHWinType->pszHome));
+ pHHWinType->pszJump1 = strdupAtoW(GetChmString(pChmInfo, (DWORD)pHHWinType->pszJump1));
+ pHHWinType->pszJump2 = strdupAtoW(GetChmString(pChmInfo, (DWORD)pHHWinType->pszJump2));
+ pHHWinType->pszUrlJump1 = strdupAtoW(GetChmString(pChmInfo, (DWORD)pHHWinType->pszUrlJump1));
+ pHHWinType->pszUrlJump2 = strdupAtoW(GetChmString(pChmInfo, (DWORD)pHHWinType->pszUrlJump2));
+
+ /* FIXME: pszCustomTabs is a list of multiple zero-terminated strings so ReadString won't
+ * work in this case
+ */
+#if 0
+ pHHWinType->pszCustomTabs = CHM_ReadString(pChmInfo, (DWORD)pHHWinType->pszCustomTabs);
+#endif
+
+done:
+ IStream_Release(pStream);
+
+ return SUCCEEDED(hr);
+}
+
+static LPCWSTR skip_schema(LPCWSTR url)
+{
+ static const WCHAR its_schema[] = {'i','t','s',':'};
+ static const WCHAR msits_schema[] = {'m','s','-','i','t','s',':'};
+ static const WCHAR mk_schema[] = {'m','k',':','@','M','S','I','T','S','t','o','r','e',':'};
+
+ if(!strncmpiW(its_schema, url, sizeof(its_schema)/sizeof(WCHAR)))
+ return url+sizeof(its_schema)/sizeof(WCHAR);
+ if(!strncmpiW(msits_schema, url, sizeof(msits_schema)/sizeof(WCHAR)))
+ return url+sizeof(msits_schema)/sizeof(WCHAR);
+ if(!strncmpiW(mk_schema, url, sizeof(mk_schema)/sizeof(WCHAR)))
+ return url+sizeof(mk_schema)/sizeof(WCHAR);
+
+ return url;
+}
+
+void SetChmPath(ChmPath *file, LPCWSTR base_file, LPCWSTR path)
+{
+ LPCWSTR ptr;
+ static const WCHAR separatorW[] = {':',':',0};
+
+ path = skip_schema(path);
+
+ ptr = strstrW(path, separatorW);
+ if(ptr) {
+ WCHAR chm_file[MAX_PATH];
+ WCHAR rel_path[MAX_PATH];
+ WCHAR base_path[MAX_PATH];
+ LPWSTR p;
+
+ strcpyW(base_path, base_file);
+ p = strrchrW(base_path, '\\');
+ if(p)
+ *p = 0;
+
+ memcpy(rel_path, path, (ptr-path)*sizeof(WCHAR));
+ rel_path[ptr-path] = 0;
+
+ PathCombineW(chm_file, base_path, rel_path);
+
+ file->chm_file = strdupW(chm_file);
+ ptr += 2;
+ }else {
+ file->chm_file = strdupW(base_file);
+ ptr = path;
+ }
+
+ file->chm_index = strdupW(ptr);
+
+ TRACE("ChmFile = {%s %s}\n", debugstr_w(file->chm_file), debugstr_w(file->chm_index));
+}
+
+IStream *GetChmStream(CHMInfo *info, LPCWSTR parent_chm, ChmPath *chm_file)
+{
+ IStorage *storage;
+ IStream *stream;
+ HRESULT hres;
+
+ TRACE("%s (%s :: %s)\n", debugstr_w(parent_chm), debugstr_w(chm_file->chm_file),
+ debugstr_w(chm_file->chm_index));
+
+ if(parent_chm || chm_file->chm_file) {
+ hres = IITStorage_StgOpenStorage(info->pITStorage,
+ chm_file->chm_file ? chm_file->chm_file : parent_chm, NULL,
+ STGM_READ | STGM_SHARE_DENY_WRITE, NULL, 0, &storage);
+ if(FAILED(hres)) {
+ WARN("Could not open storage: %08x\n", hres);
+ return NULL;
+ }
+ }else {
+ storage = info->pStorage;
+ IStorage_AddRef(info->pStorage);
+ }
+
+ hres = IStorage_OpenStream(storage, chm_file->chm_index, NULL, STGM_READ, 0, &stream);
+ IStorage_Release(storage);
+ if(FAILED(hres))
+ WARN("Could not open stream: %08x\n", hres);
+
+ return stream;
+}
+
+/* Opens the CHM file for reading */
+CHMInfo *OpenCHM(LPCWSTR szFile)
+{
+ WCHAR file[MAX_PATH] = {0};
+ DWORD res;
+ HRESULT hres;
+
+ static const WCHAR wszSTRINGS[] = {'#','S','T','R','I','N','G','S',0};
+
+ CHMInfo *ret = hhctrl_alloc_zero(sizeof(CHMInfo));
+
+ res = GetFullPathNameW(szFile, sizeof(file), file, NULL);
+ ret->szFile = strdupW(file);
+
+ hres = CoCreateInstance(&CLSID_ITStorage, NULL, CLSCTX_INPROC_SERVER,
+ &IID_IITStorage, (void **) &ret->pITStorage) ;
+ if(FAILED(hres)) {
+ WARN("Could not create ITStorage: %08x\n", hres);
+ return CloseCHM(ret);
+ }
+
+ hres = IITStorage_StgOpenStorage(ret->pITStorage, szFile, NULL,
+ STGM_READ | STGM_SHARE_DENY_WRITE, NULL, 0, &ret->pStorage);
+ if(FAILED(hres)) {
+ WARN("Could not open storage: %08x\n", hres);
+ return CloseCHM(ret);
+ }
+
+ hres = IStorage_OpenStream(ret->pStorage, wszSTRINGS, NULL, STGM_READ, 0,
+ &ret->strings_stream);
+ if(FAILED(hres)) {
+ WARN("Could not open #STRINGS stream: %08x\n", hres);
+ return CloseCHM(ret);
+ }
+
+ if(!ReadChmSystem(ret)) {
+ WARN("Could not read #SYSTEM\n");
+ return CloseCHM(ret);
+ }
+
+ return ret;
+}
+
+CHMInfo *CloseCHM(CHMInfo *chm)
+{
+ if(chm->pITStorage)
+ IITStorage_Release(chm->pITStorage);
+
+ if(chm->pStorage)
+ IStorage_Release(chm->pStorage);
+
+ if(chm->strings_stream)
+ IStream_Release(chm->strings_stream);
+
+ if(chm->strings_size) {
+ int i;
+
+ for(i=0; istrings_size; i++)
+ hhctrl_free(chm->strings[i]);
+ }
+
+ hhctrl_free(chm->strings);
+ hhctrl_free(chm);
+
+ return NULL;
+}
diff --git a/reactos/dll/win32/hhctrl.ocx/content.c b/reactos/dll/win32/hhctrl.ocx/content.c
new file mode 100644
index 00000000000..c572bafb201
--- /dev/null
+++ b/reactos/dll/win32/hhctrl.ocx/content.c
@@ -0,0 +1,435 @@
+/*
+ * Copyright 2007 Jacek Caban for CodeWeavers
+ *
+ * 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 NONAMELESSUNION
+#define NONAMELESSSTRUCT
+
+#include "hhctrl.h"
+
+#include "wine/debug.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(htmlhelp);
+
+#define BLOCK_SIZE 0x1000
+
+typedef enum {
+ INSERT_NEXT,
+ INSERT_CHILD
+} insert_type_t;
+
+typedef struct {
+ char *buf;
+ int size;
+ int len;
+} strbuf_t;
+
+static void strbuf_init(strbuf_t *buf)
+{
+ buf->size = 8;
+ buf->len = 0;
+ buf->buf = hhctrl_alloc(buf->size);
+}
+
+static void strbuf_zero(strbuf_t *buf)
+{
+ buf->len = 0;
+}
+
+static void strbuf_free(strbuf_t *buf)
+{
+ hhctrl_free(buf->buf);
+}
+
+static void strbuf_append(strbuf_t *buf, const char *data, int len)
+{
+ if(buf->len+len > buf->size) {
+ buf->size = buf->len+len;
+ buf->buf = hhctrl_realloc(buf->buf, buf->size);
+ }
+
+ memcpy(buf->buf+buf->len, data, len);
+ buf->len += len;
+}
+
+typedef struct {
+ IStream *str;
+ char buf[BLOCK_SIZE];
+ ULONG size;
+ ULONG p;
+} stream_t;
+
+static void stream_init(stream_t *stream, IStream *str)
+{
+ memset(stream, 0, sizeof(stream_t));
+ stream->str = str;
+}
+
+static BOOL stream_chr(stream_t *stream, strbuf_t *buf, char c)
+{
+ BOOL b = TRUE;
+ ULONG i;
+
+ while(b) {
+ for(i=stream->p; isize; i++) {
+ if(stream->buf[i] == c) {
+ b = FALSE;
+ break;
+ }
+ }
+
+ if(buf && i > stream->p)
+ strbuf_append(buf, stream->buf+stream->p, i-stream->p);
+ stream->p = i;
+
+ if(stream->p == stream->size) {
+ stream->p = 0;
+ IStream_Read(stream->str, stream->buf, sizeof(stream->buf), &stream->size);
+ if(!stream->size)
+ break;
+ }
+ }
+
+ return stream->size != 0;
+}
+
+static void get_node_name(strbuf_t *node, strbuf_t *name)
+{
+ const char *ptr = node->buf+1;
+
+ strbuf_zero(name);
+
+ while(*ptr != '>' && !isspace(*ptr))
+ ptr++;
+
+ strbuf_append(name, node->buf+1, ptr-node->buf-1);
+ strbuf_append(name, "", 1);
+}
+
+static BOOL next_node(stream_t *stream, strbuf_t *buf)
+{
+ if(!stream_chr(stream, NULL, '<'))
+ return FALSE;
+
+ if(!stream_chr(stream, buf, '>'))
+ return FALSE;
+
+ strbuf_append(buf, ">", 2);
+
+ return TRUE;
+}
+
+static const char *get_attr(const char *node, const char *name, int *len)
+{
+ const char *ptr, *ptr2;
+ char name_buf[32];
+ int nlen;
+
+ nlen = strlen(name);
+ memcpy(name_buf, name, nlen);
+ name_buf[nlen++] = '=';
+ name_buf[nlen++] = '\"';
+ name_buf[nlen] = 0;
+
+ ptr = strstr(node, name_buf);
+ if(!ptr) {
+ WARN("name not found\n");
+ return NULL;
+ }
+
+ ptr += nlen;
+ ptr2 = strchr(ptr, '\"');
+ if(!ptr2)
+ return NULL;
+
+ *len = ptr2-ptr;
+ return ptr;
+}
+
+static void parse_obj_node_param(ContentItem *item, ContentItem *hhc_root, const char *text)
+{
+ const char *ptr;
+ LPWSTR *param, merge;
+ int len, wlen;
+
+ ptr = get_attr(text, "name", &len);
+ if(!ptr) {
+ WARN("name attr not found\n");
+ return;
+ }
+
+ if(!strncasecmp("name", ptr, len)) {
+ param = &item->name;
+ }else if(!strncasecmp("merge", ptr, len)) {
+ param = &merge;
+ }else if(!strncasecmp("local", ptr, len)) {
+ param = &item->local;
+ }else {
+ WARN("unhandled param %s\n", debugstr_an(ptr, len));
+ return;
+ }
+
+ ptr = get_attr(text, "value", &len);
+ if(!ptr) {
+ WARN("value attr not found\n");
+ return;
+ }
+
+ wlen = MultiByteToWideChar(CP_ACP, 0, ptr, len, NULL, 0);
+ *param = hhctrl_alloc((wlen+1)*sizeof(WCHAR));
+ MultiByteToWideChar(CP_ACP, 0, ptr, len, *param, wlen);
+ (*param)[wlen] = 0;
+
+ if(param == &merge) {
+ SetChmPath(&item->merge, hhc_root->merge.chm_file, merge);
+ hhctrl_free(merge);
+ }
+}
+
+static ContentItem *parse_hhc(HHInfo*,IStream*,ContentItem*,insert_type_t*);
+
+static ContentItem *insert_item(ContentItem *item, ContentItem *new_item, insert_type_t insert_type)
+{
+ if(!item)
+ return new_item;
+
+ switch(insert_type) {
+ case INSERT_NEXT:
+ item->next = new_item;
+ return new_item;
+ case INSERT_CHILD:
+ if(item->child) {
+ ContentItem *iter = item->child;
+ while(iter->next)
+ iter = iter->next;
+ iter->next = new_item;
+ }else {
+ item->child = new_item;
+ }
+ return item;
+ }
+
+ return NULL;
+}
+
+static ContentItem *parse_sitemap_object(HHInfo *info, stream_t *stream, ContentItem *hhc_root,
+ insert_type_t *insert_type)
+{
+ strbuf_t node, node_name;
+ ContentItem *item;
+
+ *insert_type = INSERT_NEXT;
+
+ strbuf_init(&node);
+ strbuf_init(&node_name);
+
+ item = hhctrl_alloc_zero(sizeof(ContentItem));
+
+ while(next_node(stream, &node)) {
+ get_node_name(&node, &node_name);
+
+ TRACE("%s\n", node.buf);
+
+ if(!strcasecmp(node_name.buf, "/object"))
+ break;
+ if(!strcasecmp(node_name.buf, "param"))
+ parse_obj_node_param(item, hhc_root, node.buf);
+
+ strbuf_zero(&node);
+ }
+
+ strbuf_free(&node);
+ strbuf_free(&node_name);
+
+ if(item->merge.chm_index) {
+ IStream *merge_stream;
+
+ merge_stream = GetChmStream(info->pCHMInfo, item->merge.chm_file, &item->merge);
+ if(merge_stream) {
+ item->child = parse_hhc(info, merge_stream, hhc_root, insert_type);
+ IStream_Release(merge_stream);
+ }else {
+ WARN("Could not get %s::%s stream\n", debugstr_w(item->merge.chm_file),
+ debugstr_w(item->merge.chm_file));
+ }
+
+ }
+
+ return item;
+}
+
+static ContentItem *parse_ul(HHInfo *info, stream_t *stream, ContentItem *hhc_root)
+{
+ strbuf_t node, node_name;
+ ContentItem *ret = NULL, *prev = NULL, *new_item = NULL;
+ insert_type_t it;
+
+ strbuf_init(&node);
+ strbuf_init(&node_name);
+
+ while(next_node(stream, &node)) {
+ get_node_name(&node, &node_name);
+
+ TRACE("%s\n", node.buf);
+
+ if(!strcasecmp(node_name.buf, "object")) {
+ const char *ptr;
+ int len;
+
+ static const char sz_text_sitemap[] = "text/sitemap";
+
+ ptr = get_attr(node.buf, "type", &len);
+
+ if(ptr && len == sizeof(sz_text_sitemap)-1
+ && !memcmp(ptr, sz_text_sitemap, len)) {
+ new_item = parse_sitemap_object(info, stream, hhc_root, &it);
+ prev = insert_item(prev, new_item, it);
+ if(!ret)
+ ret = prev;
+ }
+ }else if(!strcasecmp(node_name.buf, "ul")) {
+ new_item = parse_ul(info, stream, hhc_root);
+ insert_item(prev, new_item, INSERT_CHILD);
+ }else if(!strcasecmp(node_name.buf, "/ul")) {
+ break;
+ }
+
+ strbuf_zero(&node);
+ }
+
+ strbuf_free(&node);
+ strbuf_free(&node_name);
+
+ return ret;
+}
+
+static ContentItem *parse_hhc(HHInfo *info, IStream *str, ContentItem *hhc_root,
+ insert_type_t *insert_type)
+{
+ stream_t stream;
+ strbuf_t node, node_name;
+ ContentItem *ret = NULL, *prev = NULL;
+
+ *insert_type = INSERT_NEXT;
+
+ strbuf_init(&node);
+ strbuf_init(&node_name);
+
+ stream_init(&stream, str);
+
+ while(next_node(&stream, &node)) {
+ get_node_name(&node, &node_name);
+
+ TRACE("%s\n", node.buf);
+
+ if(!strcasecmp(node_name.buf, "ul")) {
+ ContentItem *item = parse_ul(info, &stream, hhc_root);
+ prev = insert_item(prev, item, INSERT_CHILD);
+ if(!ret)
+ ret = prev;
+ *insert_type = INSERT_CHILD;
+ }
+
+ strbuf_zero(&node);
+ }
+
+ strbuf_free(&node);
+ strbuf_free(&node_name);
+
+ return ret;
+}
+
+static void insert_content_item(HWND hwnd, ContentItem *parent, ContentItem *item)
+{
+ TVINSERTSTRUCTW tvis;
+
+ memset(&tvis, 0, sizeof(tvis));
+ tvis.u.item.mask = TVIF_TEXT|TVIF_PARAM;
+ tvis.u.item.cchTextMax = strlenW(item->name)+1;
+ tvis.u.item.pszText = item->name;
+ tvis.u.item.lParam = (LPARAM)item;
+ tvis.hParent = parent ? parent->id : 0;
+ tvis.hInsertAfter = TVI_LAST;
+
+ item->id = (HTREEITEM)SendMessageW(hwnd, TVM_INSERTITEMW, 0, (LPARAM)&tvis);
+}
+
+static void fill_content_tree(HWND hwnd, ContentItem *parent, ContentItem *item)
+{
+ while(item) {
+ if(item->name) {
+ insert_content_item(hwnd, parent, item);
+ fill_content_tree(hwnd, item, item->child);
+ }else {
+ fill_content_tree(hwnd, parent, item->child);
+ }
+ item = item->next;
+ }
+}
+
+static void set_item_parents(ContentItem *parent, ContentItem *item)
+{
+ while(item) {
+ item->parent = parent;
+ set_item_parents(item, item->child);
+ item = item->next;
+ }
+}
+
+void InitContent(HHInfo *info)
+{
+ IStream *stream;
+ insert_type_t insert_type;
+
+ info->content = hhctrl_alloc_zero(sizeof(ContentItem));
+ SetChmPath(&info->content->merge, info->pCHMInfo->szFile, info->WinType.pszToc);
+
+ stream = GetChmStream(info->pCHMInfo, info->pCHMInfo->szFile, &info->content->merge);
+ if(!stream) {
+ TRACE("Could not get content stream\n");
+ return;
+ }
+
+ info->content->child = parse_hhc(info, stream, info->content, &insert_type);
+ IStream_Release(stream);
+
+ set_item_parents(NULL, info->content);
+ fill_content_tree(info->tabs[TAB_CONTENTS].hwnd, NULL, info->content);
+}
+
+static void free_content_item(ContentItem *item)
+{
+ ContentItem *next;
+
+ while(item) {
+ next = item->next;
+
+ free_content_item(item->child);
+
+ hhctrl_free(item->name);
+ hhctrl_free(item->local);
+ hhctrl_free(item->merge.chm_file);
+ hhctrl_free(item->merge.chm_index);
+
+ item = next;
+ }
+}
+
+void ReleaseContent(HHInfo *info)
+{
+ free_content_item(info->content);
+}
diff --git a/reactos/dll/win32/hhctrl.ocx/help.c b/reactos/dll/win32/hhctrl.ocx/help.c
new file mode 100644
index 00000000000..3bc9e8e6b62
--- /dev/null
+++ b/reactos/dll/win32/hhctrl.ocx/help.c
@@ -0,0 +1,972 @@
+/*
+ * Help Viewer Implementation
+ *
+ * Copyright 2005 James Hawkins
+ * Copyright 2007 Jacek Caban for CodeWeavers
+ *
+ * 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 "hhctrl.h"
+
+#include "wingdi.h"
+#include "commctrl.h"
+#include "wininet.h"
+
+#include "wine/debug.h"
+
+#include "resource.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(htmlhelp);
+
+static LRESULT Help_OnSize(HWND hWnd);
+
+/* Window type defaults */
+
+#define WINTYPE_DEFAULT_X 280
+#define WINTYPE_DEFAULT_Y 100
+#define WINTYPE_DEFAULT_WIDTH 740
+#define WINTYPE_DEFAULT_HEIGHT 640
+#define WINTYPE_DEFAULT_NAVWIDTH 250
+
+#define TAB_TOP_PADDING 8
+#define TAB_RIGHT_PADDING 4
+#define TAB_MARGIN 8
+
+static const WCHAR szEmpty[] = {0};
+
+/* Loads a string from the resource file */
+static LPWSTR HH_LoadString(DWORD dwID)
+{
+ LPWSTR string = NULL;
+ int iSize;
+
+ iSize = LoadStringW(hhctrl_hinstance, dwID, NULL, 0);
+ iSize += 2; /* some strings (tab text) needs double-null termination */
+
+ string = hhctrl_alloc(iSize * sizeof(WCHAR));
+ LoadStringW(hhctrl_hinstance, dwID, string, iSize);
+
+ return string;
+}
+
+static HRESULT navigate_url(HHInfo *info, LPCWSTR surl)
+{
+ VARIANT url;
+ HRESULT hres;
+
+ TRACE("%s\n", debugstr_w(surl));
+
+ V_VT(&url) = VT_BSTR;
+ V_BSTR(&url) = SysAllocString(surl);
+
+ hres = IWebBrowser2_Navigate2(info->web_browser, &url, 0, 0, 0, 0);
+
+ VariantClear(&url);
+
+ if(FAILED(hres))
+ TRACE("Navigation failed: %08x\n", hres);
+
+ return hres;
+}
+
+BOOL NavigateToUrl(HHInfo *info, LPCWSTR surl)
+{
+ ChmPath chm_path;
+ BOOL ret;
+ HRESULT hres;
+
+ hres = navigate_url(info, surl);
+ if(SUCCEEDED(hres))
+ return TRUE;
+
+ SetChmPath(&chm_path, info->pCHMInfo->szFile, surl);
+ ret = NavigateToChm(info, chm_path.chm_file, chm_path.chm_index);
+
+ hhctrl_free(chm_path.chm_file);
+ hhctrl_free(chm_path.chm_index);
+
+ return ret;
+}
+
+BOOL NavigateToChm(HHInfo *info, LPCWSTR file, LPCWSTR index)
+{
+ WCHAR buf[INTERNET_MAX_URL_LENGTH];
+ WCHAR full_path[MAX_PATH];
+ LPWSTR ptr;
+
+ static const WCHAR url_format[] =
+ {'m','k',':','@','M','S','I','T','S','t','o','r','e',':','%','s',':',':','%','s',0};
+
+ TRACE("%p %s %s\n", info, debugstr_w(file), debugstr_w(index));
+
+ if (!info->web_browser)
+ return FALSE;
+
+ if(!GetFullPathNameW(file, sizeof(full_path), full_path, NULL)) {
+ WARN("GetFullPathName failed: %u\n", GetLastError());
+ return FALSE;
+ }
+
+ wsprintfW(buf, url_format, full_path, index);
+
+ /* FIXME: HACK */
+ if((ptr = strchrW(buf, '#')))
+ *ptr = 0;
+
+ return SUCCEEDED(navigate_url(info, buf));
+}
+
+/* Size Bar */
+
+#define SIZEBAR_WIDTH 4
+
+static const WCHAR szSizeBarClass[] = {
+ 'H','H',' ','S','i','z','e','B','a','r',0
+};
+
+/* Draw the SizeBar */
+static void SB_OnPaint(HWND hWnd)
+{
+ PAINTSTRUCT ps;
+ HDC hdc;
+ RECT rc;
+
+ hdc = BeginPaint(hWnd, &ps);
+
+ GetClientRect(hWnd, &rc);
+
+ /* dark frame */
+ rc.right += 1;
+ rc.bottom -= 1;
+ FrameRect(hdc, &rc, GetStockObject(GRAY_BRUSH));
+
+ /* white highlight */
+ SelectObject(hdc, GetStockObject(WHITE_PEN));
+ MoveToEx(hdc, rc.right, 1, NULL);
+ LineTo(hdc, 1, 1);
+ LineTo(hdc, 1, rc.bottom - 1);
+
+
+ MoveToEx(hdc, 0, rc.bottom, NULL);
+ LineTo(hdc, rc.right, rc.bottom);
+
+ EndPaint(hWnd, &ps);
+}
+
+static void SB_OnLButtonDown(HWND hWnd, WPARAM wParam, LPARAM lParam)
+{
+ SetCapture(hWnd);
+}
+
+static void SB_OnLButtonUp(HWND hWnd, WPARAM wParam, LPARAM lParam)
+{
+ HHInfo *pHHInfo = (HHInfo *)GetWindowLongPtrW(hWnd, GWLP_USERDATA);
+ POINT pt;
+
+ pt.x = (short)LOWORD(lParam);
+ pt.y = (short)HIWORD(lParam);
+
+ /* update the window sizes */
+ pHHInfo->WinType.iNavWidth += pt.x;
+ Help_OnSize(hWnd);
+
+ ReleaseCapture();
+}
+
+static void SB_OnMouseMove(HWND hWnd, WPARAM wParam, LPARAM lParam)
+{
+ /* ignore WM_MOUSEMOVE if not dragging the SizeBar */
+ if (!(wParam & MK_LBUTTON))
+ return;
+}
+
+static LRESULT CALLBACK SizeBar_WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ switch (message)
+ {
+ case WM_LBUTTONDOWN:
+ SB_OnLButtonDown(hWnd, wParam, lParam);
+ break;
+ case WM_LBUTTONUP:
+ SB_OnLButtonUp(hWnd, wParam, lParam);
+ break;
+ case WM_MOUSEMOVE:
+ SB_OnMouseMove(hWnd, wParam, lParam);
+ break;
+ case WM_PAINT:
+ SB_OnPaint(hWnd);
+ break;
+ default:
+ return DefWindowProcW(hWnd, message, wParam, lParam);
+ }
+
+ return 0;
+}
+
+static void HH_RegisterSizeBarClass(HHInfo *pHHInfo)
+{
+ WNDCLASSEXW wcex;
+
+ wcex.cbSize = sizeof(WNDCLASSEXW);
+ wcex.style = 0;
+ wcex.lpfnWndProc = SizeBar_WndProc;
+ wcex.cbClsExtra = 0;
+ wcex.cbWndExtra = 0;
+ wcex.hInstance = hhctrl_hinstance;
+ wcex.hIcon = LoadIconW(NULL, (LPCWSTR)IDI_APPLICATION);
+ wcex.hCursor = LoadCursorW(NULL, (LPCWSTR)IDC_SIZEWE);
+ wcex.hbrBackground = (HBRUSH)(COLOR_MENU + 1);
+ wcex.lpszMenuName = NULL;
+ wcex.lpszClassName = szSizeBarClass;
+ wcex.hIconSm = LoadIconW(NULL, (LPCWSTR)IDI_APPLICATION);
+
+ RegisterClassExW(&wcex);
+}
+
+static void SB_GetSizeBarRect(HHInfo *info, RECT *rc)
+{
+ RECT rectWND, rectTB, rectNP;
+
+ GetClientRect(info->WinType.hwndHelp, &rectWND);
+ GetClientRect(info->WinType.hwndToolBar, &rectTB);
+ GetClientRect(info->WinType.hwndNavigation, &rectNP);
+
+ rc->left = rectNP.right;
+ rc->top = rectTB.bottom;
+ rc->bottom = rectWND.bottom - rectTB.bottom;
+ rc->right = SIZEBAR_WIDTH;
+}
+
+static BOOL HH_AddSizeBar(HHInfo *pHHInfo)
+{
+ HWND hWnd;
+ HWND hwndParent = pHHInfo->WinType.hwndHelp;
+ DWORD dwStyles = WS_CHILDWINDOW | WS_VISIBLE | WS_OVERLAPPED;
+ DWORD dwExStyles = WS_EX_LEFT | WS_EX_LTRREADING | WS_EX_RIGHTSCROLLBAR;
+ RECT rc;
+
+ SB_GetSizeBarRect(pHHInfo, &rc);
+
+ hWnd = CreateWindowExW(dwExStyles, szSizeBarClass, szEmpty, dwStyles,
+ rc.left, rc.top, rc.right, rc.bottom,
+ hwndParent, NULL, hhctrl_hinstance, NULL);
+ if (!hWnd)
+ return FALSE;
+
+ /* store the pointer to the HH info struct */
+ SetWindowLongPtrW(hWnd, GWLP_USERDATA, (LONG_PTR)pHHInfo);
+
+ pHHInfo->hwndSizeBar = hWnd;
+ return TRUE;
+}
+
+/* Child Window */
+
+static const WCHAR szChildClass[] = {
+ 'H','H',' ','C','h','i','l','d',0
+};
+
+static LRESULT Child_OnPaint(HWND hWnd)
+{
+ PAINTSTRUCT ps;
+ HDC hdc;
+ RECT rc;
+
+ hdc = BeginPaint(hWnd, &ps);
+
+ /* Only paint the Navigation pane, identified by the fact
+ * that it has a child window
+ */
+ if (GetWindow(hWnd, GW_CHILD))
+ {
+ GetClientRect(hWnd, &rc);
+
+ /* set the border color */
+ SelectObject(hdc, GetStockObject(DC_PEN));
+ SetDCPenColor(hdc, GetSysColor(COLOR_BTNSHADOW));
+
+ /* Draw the top border */
+ LineTo(hdc, rc.right, 0);
+
+ SelectObject(hdc, GetStockObject(WHITE_PEN));
+ MoveToEx(hdc, 0, 1, NULL);
+ LineTo(hdc, rc.right, 1);
+ }
+
+ EndPaint(hWnd, &ps);
+
+ return 0;
+}
+
+static void ResizeTabChild(HHInfo *info, HWND hwnd)
+{
+ RECT rect, tabrc;
+ DWORD cnt;
+
+ GetClientRect(info->WinType.hwndNavigation, &rect);
+ SendMessageW(info->hwndTabCtrl, TCM_GETITEMRECT, 0, (LPARAM)&tabrc);
+ cnt = SendMessageW(info->hwndTabCtrl, TCM_GETROWCOUNT, 0, 0);
+
+ rect.left = TAB_MARGIN;
+ rect.top = TAB_TOP_PADDING + cnt*(tabrc.bottom-tabrc.top) + TAB_MARGIN;
+ rect.right -= TAB_RIGHT_PADDING + TAB_MARGIN;
+ rect.bottom -= TAB_MARGIN;
+
+ SetWindowPos(hwnd, NULL, rect.left, rect.top, rect.right-rect.left,
+ rect.bottom-rect.top, SWP_NOZORDER | SWP_NOACTIVATE);
+}
+
+static LRESULT Child_OnSize(HWND hwnd)
+{
+ HHInfo *info = (HHInfo*)GetWindowLongPtrW(hwnd, GWLP_USERDATA);
+ RECT rect;
+
+ if(!info || hwnd != info->WinType.hwndNavigation)
+ return 0;
+
+ GetClientRect(hwnd, &rect);
+ SetWindowPos(info->hwndTabCtrl, HWND_TOP, 0, 0,
+ rect.right - TAB_RIGHT_PADDING,
+ rect.bottom - TAB_TOP_PADDING, SWP_NOMOVE);
+
+ ResizeTabChild(info, info->tabs[TAB_CONTENTS].hwnd);
+ return 0;
+}
+
+static LRESULT OnTabChange(HWND hwnd)
+{
+ HHInfo *info = (HHInfo*)GetWindowLongPtrW(hwnd, GWLP_USERDATA);
+
+ TRACE("%p\n", hwnd);
+
+ if (!info)
+ return 0;
+
+ if(info->tabs[info->current_tab].hwnd)
+ ShowWindow(info->tabs[info->current_tab].hwnd, SW_HIDE);
+
+ info->current_tab = SendMessageW(info->hwndTabCtrl, TCM_GETCURSEL, 0, 0);
+
+ if(info->tabs[info->current_tab].hwnd)
+ ShowWindow(info->tabs[info->current_tab].hwnd, SW_SHOW);
+
+ return 0;
+}
+
+static LRESULT OnTopicChange(HWND hwnd, ContentItem *item)
+{
+ HHInfo *info = (HHInfo*)GetWindowLongPtrW(hwnd, GWLP_USERDATA);
+ LPCWSTR chmfile = NULL;
+ ContentItem *iter = item;
+
+ if(!item || !info)
+ return 0;
+
+ TRACE("name %s loal %s\n", debugstr_w(item->name), debugstr_w(item->local));
+
+ while(iter) {
+ if(iter->merge.chm_file) {
+ chmfile = iter->merge.chm_file;
+ break;
+ }
+ iter = iter->parent;
+ }
+
+ NavigateToChm(info, chmfile, item->local);
+ return 0;
+}
+
+static LRESULT CALLBACK Child_WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ switch (message)
+ {
+ case WM_PAINT:
+ return Child_OnPaint(hWnd);
+ case WM_SIZE:
+ return Child_OnSize(hWnd);
+ case WM_NOTIFY: {
+ NMHDR *nmhdr = (NMHDR*)lParam;
+ switch(nmhdr->code) {
+ case TCN_SELCHANGE:
+ return OnTabChange(hWnd);
+ case TVN_SELCHANGEDW:
+ return OnTopicChange(hWnd, (ContentItem*)((NMTREEVIEWW *)lParam)->itemNew.lParam);
+ }
+ break;
+ }
+ default:
+ return DefWindowProcW(hWnd, message, wParam, lParam);
+ }
+
+ return 0;
+}
+
+static void HH_RegisterChildWndClass(HHInfo *pHHInfo)
+{
+ WNDCLASSEXW wcex;
+
+ wcex.cbSize = sizeof(WNDCLASSEXW);
+ wcex.style = 0;
+ wcex.lpfnWndProc = Child_WndProc;
+ wcex.cbClsExtra = 0;
+ wcex.cbWndExtra = 0;
+ wcex.hInstance = hhctrl_hinstance;
+ wcex.hIcon = LoadIconW(NULL, (LPCWSTR)IDI_APPLICATION);
+ wcex.hCursor = LoadCursorW(NULL, (LPCWSTR)IDC_ARROW);
+ wcex.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
+ wcex.lpszMenuName = NULL;
+ wcex.lpszClassName = szChildClass;
+ wcex.hIconSm = LoadIconW(NULL, (LPCWSTR)IDI_APPLICATION);
+
+ RegisterClassExW(&wcex);
+}
+
+/* Toolbar */
+
+#define ICON_SIZE 20
+
+static void TB_OnClick(HWND hWnd, DWORD dwID)
+{
+ HHInfo *info = (HHInfo *)GetWindowLongPtrW(hWnd, GWLP_USERDATA);
+
+ switch (dwID)
+ {
+ case IDTB_STOP:
+ DoPageAction(info, WB_STOP);
+ break;
+ case IDTB_REFRESH:
+ DoPageAction(info, WB_REFRESH);
+ break;
+ case IDTB_BACK:
+ DoPageAction(info, WB_GOBACK);
+ break;
+ case IDTB_HOME:
+ NavigateToChm(info, info->pCHMInfo->szFile, info->WinType.pszHome);
+ break;
+ case IDTB_FORWARD:
+ DoPageAction(info, WB_GOFORWARD);
+ break;
+ case IDTB_EXPAND:
+ case IDTB_CONTRACT:
+ case IDTB_SYNC:
+ case IDTB_PRINT:
+ case IDTB_OPTIONS:
+ case IDTB_BROWSE_FWD:
+ case IDTB_BROWSE_BACK:
+ case IDTB_JUMP1:
+ case IDTB_JUMP2:
+ case IDTB_CUSTOMIZE:
+ case IDTB_ZOOM:
+ case IDTB_TOC_NEXT:
+ case IDTB_TOC_PREV:
+ break;
+ }
+}
+
+static void TB_AddButton(TBBUTTON *pButtons, DWORD dwIndex, DWORD dwID)
+{
+ /* FIXME: Load the correct button bitmaps */
+ pButtons[dwIndex].iBitmap = STD_PRINT;
+ pButtons[dwIndex].idCommand = dwID;
+ pButtons[dwIndex].fsState = TBSTATE_ENABLED;
+ pButtons[dwIndex].fsStyle = BTNS_BUTTON;
+ pButtons[dwIndex].dwData = 0;
+ pButtons[dwIndex].iString = 0;
+}
+
+static void TB_AddButtonsFromFlags(TBBUTTON *pButtons, DWORD dwButtonFlags, LPDWORD pdwNumButtons)
+{
+ *pdwNumButtons = 0;
+
+ if (dwButtonFlags & HHWIN_BUTTON_EXPAND)
+ TB_AddButton(pButtons, (*pdwNumButtons)++, IDTB_EXPAND);
+
+ if (dwButtonFlags & HHWIN_BUTTON_BACK)
+ TB_AddButton(pButtons, (*pdwNumButtons)++, IDTB_BACK);
+
+ if (dwButtonFlags & HHWIN_BUTTON_FORWARD)
+ TB_AddButton(pButtons, (*pdwNumButtons)++, IDTB_FORWARD);
+
+ if (dwButtonFlags & HHWIN_BUTTON_STOP)
+ TB_AddButton(pButtons, (*pdwNumButtons)++, IDTB_STOP);
+
+ if (dwButtonFlags & HHWIN_BUTTON_REFRESH)
+ TB_AddButton(pButtons, (*pdwNumButtons)++, IDTB_REFRESH);
+
+ if (dwButtonFlags & HHWIN_BUTTON_HOME)
+ TB_AddButton(pButtons, (*pdwNumButtons)++, IDTB_HOME);
+
+ if (dwButtonFlags & HHWIN_BUTTON_SYNC)
+ TB_AddButton(pButtons, (*pdwNumButtons)++, IDTB_SYNC);
+
+ if (dwButtonFlags & HHWIN_BUTTON_OPTIONS)
+ TB_AddButton(pButtons, (*pdwNumButtons)++, IDTB_OPTIONS);
+
+ if (dwButtonFlags & HHWIN_BUTTON_PRINT)
+ TB_AddButton(pButtons, (*pdwNumButtons)++, IDTB_PRINT);
+
+ if (dwButtonFlags & HHWIN_BUTTON_JUMP1)
+ TB_AddButton(pButtons, (*pdwNumButtons)++, IDTB_JUMP1);
+
+ if (dwButtonFlags & HHWIN_BUTTON_JUMP2)
+ TB_AddButton(pButtons,(*pdwNumButtons)++, IDTB_JUMP2);
+
+ if (dwButtonFlags & HHWIN_BUTTON_ZOOM)
+ TB_AddButton(pButtons, (*pdwNumButtons)++, IDTB_ZOOM);
+
+ if (dwButtonFlags & HHWIN_BUTTON_TOC_NEXT)
+ TB_AddButton(pButtons, (*pdwNumButtons)++, IDTB_TOC_NEXT);
+
+ if (dwButtonFlags & HHWIN_BUTTON_TOC_PREV)
+ TB_AddButton(pButtons, (*pdwNumButtons)++, IDTB_TOC_PREV);
+}
+
+static BOOL HH_AddToolbar(HHInfo *pHHInfo)
+{
+ HWND hToolbar;
+ HWND hwndParent = pHHInfo->WinType.hwndHelp;
+ DWORD toolbarFlags;
+ TBBUTTON buttons[IDTB_TOC_PREV - IDTB_EXPAND];
+ TBADDBITMAP tbAB;
+ DWORD dwStyles, dwExStyles;
+ DWORD dwNumButtons, dwIndex;
+
+ if (pHHInfo->WinType.fsWinProperties & HHWIN_PARAM_TB_FLAGS)
+ toolbarFlags = pHHInfo->WinType.fsToolBarFlags;
+ else
+ toolbarFlags = HHWIN_DEF_BUTTONS;
+
+ TB_AddButtonsFromFlags(buttons, toolbarFlags, &dwNumButtons);
+
+ dwStyles = WS_CHILDWINDOW | WS_VISIBLE | TBSTYLE_FLAT |
+ TBSTYLE_WRAPABLE | TBSTYLE_TOOLTIPS | CCS_NODIVIDER;
+ dwExStyles = WS_EX_LEFT | WS_EX_LTRREADING | WS_EX_RIGHTSCROLLBAR;
+
+ hToolbar = CreateWindowExW(dwExStyles, TOOLBARCLASSNAMEW, NULL, dwStyles,
+ 0, 0, 0, 0, hwndParent, NULL,
+ hhctrl_hinstance, NULL);
+ if (!hToolbar)
+ return FALSE;
+
+ SendMessageW(hToolbar, TB_SETBITMAPSIZE, 0, MAKELONG(ICON_SIZE, ICON_SIZE));
+ SendMessageW(hToolbar, TB_BUTTONSTRUCTSIZE, sizeof(TBBUTTON), 0);
+ SendMessageW(hToolbar, WM_SETFONT, (WPARAM)pHHInfo->hFont, TRUE);
+
+ /* FIXME: Load correct icons for all buttons */
+ tbAB.hInst = HINST_COMMCTRL;
+ tbAB.nID = IDB_STD_LARGE_COLOR;
+ SendMessageW(hToolbar, TB_ADDBITMAP, 0, (LPARAM)&tbAB);
+
+ for (dwIndex = 0; dwIndex < dwNumButtons; dwIndex++)
+ {
+ LPWSTR szBuf = HH_LoadString(buttons[dwIndex].idCommand);
+ DWORD dwLen = strlenW(szBuf);
+ szBuf[dwLen + 2] = 0; /* Double-null terminate */
+
+ buttons[dwIndex].iString = (DWORD)SendMessageW(hToolbar, TB_ADDSTRINGW, 0, (LPARAM)szBuf);
+ hhctrl_free(szBuf);
+ }
+
+ SendMessageW(hToolbar, TB_ADDBUTTONSW, dwNumButtons, (LPARAM)&buttons);
+ SendMessageW(hToolbar, TB_AUTOSIZE, 0, 0);
+ ShowWindow(hToolbar, SW_SHOW);
+
+ pHHInfo->WinType.hwndToolBar = hToolbar;
+ return TRUE;
+}
+
+/* Navigation Pane */
+
+static void NP_GetNavigationRect(HHInfo *pHHInfo, RECT *rc)
+{
+ HWND hwndParent = pHHInfo->WinType.hwndHelp;
+ HWND hwndToolbar = pHHInfo->WinType.hwndToolBar;
+ RECT rectWND, rectTB;
+
+ GetClientRect(hwndParent, &rectWND);
+ GetClientRect(hwndToolbar, &rectTB);
+
+ rc->left = 0;
+ rc->top = rectTB.bottom;
+ rc->bottom = rectWND.bottom - rectTB.bottom;
+
+ if (!(pHHInfo->WinType.fsValidMembers & HHWIN_PARAM_NAV_WIDTH) &&
+ pHHInfo->WinType.iNavWidth == 0)
+ {
+ pHHInfo->WinType.iNavWidth = WINTYPE_DEFAULT_NAVWIDTH;
+ }
+
+ rc->right = pHHInfo->WinType.iNavWidth;
+}
+
+static DWORD NP_CreateTab(HINSTANCE hInstance, HWND hwndTabCtrl, DWORD index)
+{
+ TCITEMW tie;
+ LPWSTR tabText = HH_LoadString(index);
+ DWORD ret;
+
+ tie.mask = TCIF_TEXT;
+ tie.pszText = tabText;
+
+ ret = SendMessageW( hwndTabCtrl, TCM_INSERTITEMW, index, (LPARAM)&tie );
+
+ hhctrl_free(tabText);
+ return ret;
+}
+
+static BOOL HH_AddNavigationPane(HHInfo *info)
+{
+ HWND hWnd, hwndTabCtrl;
+ HWND hwndParent = info->WinType.hwndHelp;
+ DWORD dwStyles = WS_CHILDWINDOW | WS_VISIBLE;
+ DWORD dwExStyles = WS_EX_LEFT | WS_EX_LTRREADING | WS_EX_RIGHTSCROLLBAR;
+ RECT rc;
+
+ NP_GetNavigationRect(info, &rc);
+
+ hWnd = CreateWindowExW(dwExStyles, szChildClass, szEmpty, dwStyles,
+ rc.left, rc.top, rc.right, rc.bottom,
+ hwndParent, NULL, hhctrl_hinstance, NULL);
+ if (!hWnd)
+ return FALSE;
+
+ SetWindowLongPtrW(hWnd, GWLP_USERDATA, (LONG_PTR)info);
+
+ hwndTabCtrl = CreateWindowExW(dwExStyles, WC_TABCONTROLW, szEmpty, dwStyles,
+ 0, TAB_TOP_PADDING,
+ rc.right - TAB_RIGHT_PADDING,
+ rc.bottom - TAB_TOP_PADDING,
+ hWnd, NULL, hhctrl_hinstance, NULL);
+ if (!hwndTabCtrl)
+ return FALSE;
+
+ if (*info->WinType.pszToc)
+ info->tabs[TAB_CONTENTS].id = NP_CreateTab(hhctrl_hinstance, hwndTabCtrl, IDS_CONTENTS);
+
+ if (*info->WinType.pszIndex)
+ info->tabs[TAB_INDEX].id = NP_CreateTab(hhctrl_hinstance, hwndTabCtrl, IDS_INDEX);
+
+ if (info->WinType.fsWinProperties & HHWIN_PROP_TAB_SEARCH)
+ info->tabs[TAB_SEARCH].id = NP_CreateTab(hhctrl_hinstance, hwndTabCtrl, IDS_SEARCH);
+
+ if (info->WinType.fsWinProperties & HHWIN_PROP_TAB_FAVORITES)
+ info->tabs[TAB_FAVORITES].id = NP_CreateTab(hhctrl_hinstance, hwndTabCtrl, IDS_FAVORITES);
+
+ SendMessageW(hwndTabCtrl, WM_SETFONT, (WPARAM)info->hFont, TRUE);
+
+ info->hwndTabCtrl = hwndTabCtrl;
+ info->WinType.hwndNavigation = hWnd;
+ return TRUE;
+}
+
+/* HTML Pane */
+
+static void HP_GetHTMLRect(HHInfo *info, RECT *rc)
+{
+ RECT rectTB, rectWND, rectNP, rectSB;
+
+ GetClientRect(info->WinType.hwndHelp, &rectWND);
+ GetClientRect(info->WinType.hwndToolBar, &rectTB);
+ GetClientRect(info->WinType.hwndNavigation, &rectNP);
+ GetClientRect(info->hwndSizeBar, &rectSB);
+
+ rc->left = rectNP.right + rectSB.right;
+ rc->top = rectTB.bottom;
+ rc->right = rectWND.right - rc->left;
+ rc->bottom = rectWND.bottom - rectTB.bottom;
+}
+
+static BOOL HH_AddHTMLPane(HHInfo *pHHInfo)
+{
+ HWND hWnd;
+ HWND hwndParent = pHHInfo->WinType.hwndHelp;
+ DWORD dwStyles = WS_CHILDWINDOW | WS_VISIBLE | WS_CLIPCHILDREN;
+ DWORD dwExStyles = WS_EX_LEFT | WS_EX_LTRREADING | WS_EX_RIGHTSCROLLBAR | WS_EX_CLIENTEDGE;
+ RECT rc;
+
+ HP_GetHTMLRect(pHHInfo, &rc);
+
+ hWnd = CreateWindowExW(dwExStyles, szChildClass, szEmpty, dwStyles,
+ rc.left, rc.top, rc.right, rc.bottom,
+ hwndParent, NULL, hhctrl_hinstance, NULL);
+ if (!hWnd)
+ return FALSE;
+
+ if (!InitWebBrowser(pHHInfo, hWnd))
+ return FALSE;
+
+ /* store the pointer to the HH info struct */
+ SetWindowLongPtrW(hWnd, GWLP_USERDATA, (LONG_PTR)pHHInfo);
+
+ ShowWindow(hWnd, SW_SHOW);
+ UpdateWindow(hWnd);
+
+ pHHInfo->WinType.hwndHTML = hWnd;
+ return TRUE;
+}
+
+static BOOL AddContentTab(HHInfo *info)
+{
+ info->tabs[TAB_CONTENTS].hwnd = CreateWindowExW(WS_EX_CLIENTEDGE, WC_TREEVIEWW,
+ szEmpty, WS_CHILD | WS_BORDER | 0x25, 50, 50, 100, 100,
+ info->WinType.hwndNavigation, NULL, hhctrl_hinstance, NULL);
+ if(!info->tabs[TAB_CONTENTS].hwnd) {
+ ERR("Could not create treeview control\n");
+ return FALSE;
+ }
+
+ ResizeTabChild(info, info->tabs[TAB_CONTENTS].hwnd);
+ ShowWindow(info->tabs[TAB_CONTENTS].hwnd, SW_SHOW);
+
+ return TRUE;
+}
+
+/* Viewer Window */
+
+static LRESULT Help_OnSize(HWND hWnd)
+{
+ HHInfo *pHHInfo = (HHInfo *)GetWindowLongPtrW(hWnd, GWLP_USERDATA);
+ DWORD dwSize;
+ RECT rc;
+
+ if (!pHHInfo)
+ return 0;
+
+ NP_GetNavigationRect(pHHInfo, &rc);
+ SetWindowPos(pHHInfo->WinType.hwndNavigation, HWND_TOP, 0, 0,
+ rc.right, rc.bottom, SWP_NOMOVE);
+
+ SB_GetSizeBarRect(pHHInfo, &rc);
+ SetWindowPos(pHHInfo->hwndSizeBar, HWND_TOP, rc.left, rc.top,
+ rc.right, rc.bottom, SWP_SHOWWINDOW);
+
+ HP_GetHTMLRect(pHHInfo, &rc);
+ SetWindowPos(pHHInfo->WinType.hwndHTML, HWND_TOP, rc.left, rc.top,
+ rc.right, rc.bottom, SWP_SHOWWINDOW);
+
+ /* Resize browser window taking the frame size into account */
+ dwSize = GetSystemMetrics(SM_CXFRAME);
+ ResizeWebBrowser(pHHInfo, rc.right - dwSize, rc.bottom - dwSize);
+
+ return 0;
+}
+
+static LRESULT CALLBACK Help_WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ switch (message)
+ {
+ case WM_COMMAND:
+ if (HIWORD(wParam) == BN_CLICKED)
+ TB_OnClick(hWnd, LOWORD(wParam));
+ break;
+ case WM_SIZE:
+ return Help_OnSize(hWnd);
+ case WM_CLOSE:
+ ReleaseHelpViewer((HHInfo *)GetWindowLongPtrW(hWnd, GWLP_USERDATA));
+ return 0;
+ case WM_DESTROY:
+ if(hh_process)
+ PostQuitMessage(0);
+ break;
+
+ default:
+ return DefWindowProcW(hWnd, message, wParam, lParam);
+ }
+
+ return 0;
+}
+
+static BOOL HH_CreateHelpWindow(HHInfo *info)
+{
+ HWND hWnd;
+ RECT winPos = info->WinType.rcWindowPos;
+ WNDCLASSEXW wcex;
+ DWORD dwStyles, dwExStyles;
+ DWORD x, y, width, height;
+
+ static const WCHAR windowClassW[] = {
+ 'H','H',' ', 'P','a','r','e','n','t',0
+ };
+
+ wcex.cbSize = sizeof(WNDCLASSEXW);
+ wcex.style = CS_HREDRAW | CS_VREDRAW;
+ wcex.lpfnWndProc = Help_WndProc;
+ wcex.cbClsExtra = 0;
+ wcex.cbWndExtra = 0;
+ wcex.hInstance = hhctrl_hinstance;
+ wcex.hIcon = LoadIconW(NULL, (LPCWSTR)IDI_APPLICATION);
+ wcex.hCursor = LoadCursorW(NULL, (LPCWSTR)IDC_ARROW);
+ wcex.hbrBackground = (HBRUSH)(COLOR_MENU + 1);
+ wcex.lpszMenuName = NULL;
+ wcex.lpszClassName = windowClassW;
+ wcex.hIconSm = LoadIconW(NULL, (LPCWSTR)IDI_APPLICATION);
+
+ RegisterClassExW(&wcex);
+
+ /* Read in window parameters if available */
+ if (info->WinType.fsValidMembers & HHWIN_PARAM_STYLES)
+ dwStyles = info->WinType.dwStyles;
+ else
+ dwStyles = WS_OVERLAPPEDWINDOW | WS_VISIBLE |
+ WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
+
+ if (info->WinType.fsValidMembers & HHWIN_PARAM_EXSTYLES)
+ dwExStyles = info->WinType.dwExStyles;
+ else
+ dwExStyles = WS_EX_LEFT | WS_EX_LTRREADING | WS_EX_APPWINDOW |
+ WS_EX_WINDOWEDGE | WS_EX_RIGHTSCROLLBAR;
+
+ if (info->WinType.fsValidMembers & HHWIN_PARAM_RECT)
+ {
+ x = winPos.left;
+ y = winPos.top;
+ width = winPos.right - x;
+ height = winPos.bottom - y;
+ }
+ else
+ {
+ x = WINTYPE_DEFAULT_X;
+ y = WINTYPE_DEFAULT_Y;
+ width = WINTYPE_DEFAULT_WIDTH;
+ height = WINTYPE_DEFAULT_HEIGHT;
+ }
+
+ hWnd = CreateWindowExW(dwExStyles, windowClassW, info->WinType.pszCaption,
+ dwStyles, x, y, width, height, NULL, NULL, hhctrl_hinstance, NULL);
+ if (!hWnd)
+ return FALSE;
+
+ ShowWindow(hWnd, SW_SHOW);
+ UpdateWindow(hWnd);
+
+ /* store the pointer to the HH info struct */
+ SetWindowLongPtrW(hWnd, GWLP_USERDATA, (LONG_PTR)info);
+
+ info->WinType.hwndHelp = hWnd;
+ return TRUE;
+}
+
+static void HH_CreateFont(HHInfo *pHHInfo)
+{
+ LOGFONTW lf;
+
+ GetObjectW(GetStockObject(ANSI_VAR_FONT), sizeof(LOGFONTW), &lf);
+ lf.lfWeight = FW_NORMAL;
+ lf.lfItalic = FALSE;
+ lf.lfUnderline = FALSE;
+
+ pHHInfo->hFont = CreateFontIndirectW(&lf);
+}
+
+static void HH_InitRequiredControls(DWORD dwControls)
+{
+ INITCOMMONCONTROLSEX icex;
+
+ icex.dwSize = sizeof(INITCOMMONCONTROLSEX);
+ icex.dwICC = dwControls;
+ InitCommonControlsEx(&icex);
+}
+
+/* Creates the whole package */
+static BOOL CreateViewer(HHInfo *pHHInfo)
+{
+ HH_CreateFont(pHHInfo);
+
+ if (!HH_CreateHelpWindow(pHHInfo))
+ return FALSE;
+
+ HH_InitRequiredControls(ICC_BAR_CLASSES);
+
+ if (!HH_AddToolbar(pHHInfo))
+ return FALSE;
+
+ HH_RegisterChildWndClass(pHHInfo);
+
+ if (!HH_AddNavigationPane(pHHInfo))
+ return FALSE;
+
+ HH_RegisterSizeBarClass(pHHInfo);
+
+ if (!HH_AddSizeBar(pHHInfo))
+ return FALSE;
+
+ if (!HH_AddHTMLPane(pHHInfo))
+ return FALSE;
+
+ if (!AddContentTab(pHHInfo))
+ return FALSE;
+
+ InitContent(pHHInfo);
+
+ return TRUE;
+}
+
+void ReleaseHelpViewer(HHInfo *info)
+{
+ TRACE("(%p)\n", info);
+
+ if (!info)
+ return;
+
+ /* Free allocated strings */
+ hhctrl_free((LPWSTR)info->WinType.pszType);
+ hhctrl_free((LPWSTR)info->WinType.pszCaption);
+ hhctrl_free((LPWSTR)info->WinType.pszToc);
+ hhctrl_free((LPWSTR)info->WinType.pszIndex);
+ hhctrl_free((LPWSTR)info->WinType.pszFile);
+ hhctrl_free((LPWSTR)info->WinType.pszHome);
+ hhctrl_free((LPWSTR)info->WinType.pszJump1);
+ hhctrl_free((LPWSTR)info->WinType.pszJump2);
+ hhctrl_free((LPWSTR)info->WinType.pszUrlJump1);
+ hhctrl_free((LPWSTR)info->WinType.pszUrlJump2);
+
+ if (info->pCHMInfo)
+ CloseCHM(info->pCHMInfo);
+
+ ReleaseWebBrowser(info);
+ ReleaseContent(info);
+
+ if(info->WinType.hwndHelp)
+ DestroyWindow(info->WinType.hwndHelp);
+
+ hhctrl_free(info);
+ OleUninitialize();
+}
+
+HHInfo *CreateHelpViewer(LPCWSTR filename)
+{
+ HHInfo *info = hhctrl_alloc_zero(sizeof(HHInfo));
+
+ OleInitialize(NULL);
+
+ info->pCHMInfo = OpenCHM(filename);
+ if(!info->pCHMInfo) {
+ ReleaseHelpViewer(info);
+ return NULL;
+ }
+
+ if (!LoadWinTypeFromCHM(info->pCHMInfo, &info->WinType)) {
+ ReleaseHelpViewer(info);
+ return NULL;
+ }
+
+ if(!CreateViewer(info)) {
+ ReleaseHelpViewer(info);
+ return NULL;
+ }
+
+ return info;
+}
diff --git a/reactos/dll/win32/hhctrl.ocx/hhctrl.c b/reactos/dll/win32/hhctrl.ocx/hhctrl.c
new file mode 100644
index 00000000000..de66a8a69dd
--- /dev/null
+++ b/reactos/dll/win32/hhctrl.ocx/hhctrl.c
@@ -0,0 +1,189 @@
+/*
+ * hhctrl implementation
+ *
+ * Copyright 2004 Krzysztof Foltman
+ * Copyright 2007 Jacek Caban for CodeWeavers
+ *
+ * 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 "wine/debug.h"
+
+#define INIT_GUID
+#include "hhctrl.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(htmlhelp);
+
+HINSTANCE hhctrl_hinstance;
+BOOL hh_process = FALSE;
+
+BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD fdwReason, LPVOID lpvReserved)
+{
+ TRACE("(%p,%d,%p)\n", hInstance, fdwReason, lpvReserved);
+
+ switch (fdwReason)
+ {
+ case DLL_PROCESS_ATTACH:
+ hhctrl_hinstance = hInstance;
+ DisableThreadLibraryCalls(hInstance);
+ break;
+ case DLL_PROCESS_DETACH:
+ break;
+ }
+ return TRUE;
+}
+
+static const char *command_to_string(UINT command)
+{
+#define X(x) case x: return #x
+ switch (command)
+ {
+ X( HH_DISPLAY_TOPIC );
+ X( HH_DISPLAY_TOC );
+ X( HH_DISPLAY_INDEX );
+ X( HH_DISPLAY_SEARCH );
+ X( HH_SET_WIN_TYPE );
+ X( HH_GET_WIN_TYPE );
+ X( HH_GET_WIN_HANDLE );
+ X( HH_ENUM_INFO_TYPE );
+ X( HH_SET_INFO_TYPE );
+ X( HH_SYNC );
+ X( HH_RESERVED1 );
+ X( HH_RESERVED2 );
+ X( HH_RESERVED3 );
+ X( HH_KEYWORD_LOOKUP );
+ X( HH_DISPLAY_TEXT_POPUP );
+ X( HH_HELP_CONTEXT );
+ X( HH_TP_HELP_CONTEXTMENU );
+ X( HH_TP_HELP_WM_HELP );
+ X( HH_CLOSE_ALL );
+ X( HH_ALINK_LOOKUP );
+ X( HH_GET_LAST_ERROR );
+ X( HH_ENUM_CATEGORY );
+ X( HH_ENUM_CATEGORY_IT );
+ X( HH_RESET_IT_FILTER );
+ X( HH_SET_INCLUSIVE_FILTER );
+ X( HH_SET_EXCLUSIVE_FILTER );
+ X( HH_INITIALIZE );
+ X( HH_UNINITIALIZE );
+ X( HH_PRETRANSLATEMESSAGE );
+ X( HH_SET_GLOBAL_PROPERTY );
+ default: return "???";
+ }
+#undef X
+}
+
+/******************************************************************
+ * HtmlHelpW (hhctrl.ocx.15)
+ */
+HWND WINAPI HtmlHelpW(HWND caller, LPCWSTR filename, UINT command, DWORD data)
+{
+ TRACE("(%p, %s, command=%s, data=%d)\n",
+ caller, debugstr_w( filename ),
+ command_to_string( command ), data);
+
+ switch (command)
+ {
+ case HH_DISPLAY_TOPIC:
+ case HH_DISPLAY_TOC:
+ case HH_DISPLAY_SEARCH:{
+ HHInfo *info;
+ BOOL res;
+
+ FIXME("Not all HH cases handled correctly\n");
+
+ info = CreateHelpViewer(filename);
+
+ res = NavigateToChm(info, info->pCHMInfo->szFile, info->WinType.pszFile);
+ if(!res)
+ ReleaseHelpViewer(info);
+
+ return NULL; /* FIXME */
+ }
+ case HH_HELP_CONTEXT: {
+ HHInfo *info;
+ LPWSTR url;
+
+ info = CreateHelpViewer(filename);
+ if(!info)
+ return NULL;
+
+ url = FindContextAlias(info->pCHMInfo, data);
+ if(!url)
+ return NULL;
+
+ NavigateToUrl(info, url);
+ hhctrl_free(url);
+
+ return NULL; /* FIXME */
+ }
+ default:
+ FIXME("HH case %s not handled.\n", command_to_string( command ));
+ }
+
+ return 0;
+}
+
+/******************************************************************
+ * HtmlHelpA (hhctrl.ocx.14)
+ */
+HWND WINAPI HtmlHelpA(HWND caller, LPCSTR filename, UINT command, DWORD data)
+{
+ WCHAR *wfile = NULL;
+ HWND result;
+
+ if (filename)
+ {
+ DWORD len = MultiByteToWideChar( CP_ACP, 0, filename, -1, NULL, 0 );
+
+ wfile = hhctrl_alloc(len*sizeof(WCHAR));
+ MultiByteToWideChar( CP_ACP, 0, filename, -1, wfile, len );
+ }
+
+ result = HtmlHelpW( caller, wfile, command, data );
+
+ hhctrl_free(wfile);
+ return result;
+}
+
+/******************************************************************
+ * doWinMain (hhctrl.ocx.13)
+ */
+int WINAPI doWinMain(HINSTANCE hInstance, LPSTR szCmdLine)
+{
+ MSG msg;
+
+ hh_process = TRUE;
+
+ /* FIXME: Check szCmdLine for bad arguments */
+ HtmlHelpA(GetDesktopWindow(), szCmdLine, HH_DISPLAY_TOPIC, 0);
+
+ while (GetMessageW(&msg, 0, 0, 0))
+ {
+ TranslateMessage(&msg);
+ DispatchMessageW(&msg);
+ }
+
+ return 0;
+}
+
+/******************************************************************
+ * DllGetClassObject (hhctrl.ocx.@)
+ */
+HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
+{
+ FIXME("(%s %s %p)\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
+ return CLASS_E_CLASSNOTAVAILABLE;
+}
diff --git a/reactos/dll/win32/hhctrl.ocx/hhctrl.h b/reactos/dll/win32/hhctrl.ocx/hhctrl.h
new file mode 100644
index 00000000000..c362e4e1de2
--- /dev/null
+++ b/reactos/dll/win32/hhctrl.ocx/hhctrl.h
@@ -0,0 +1,185 @@
+/*
+ * Copyright 2005 James Hawkins
+ * Copyright 2007 Jacek Caban for CodeWeavers
+ *
+ * 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 HHCTRL_H
+#define HHCTRL_H
+
+#include
+
+#define COBJMACROS
+
+#include "windef.h"
+#include "winbase.h"
+#include "winuser.h"
+#include "winnls.h"
+#include "htmlhelp.h"
+#include "ole2.h"
+#include "exdisp.h"
+#include "mshtmhst.h"
+#include "commctrl.h"
+
+#ifdef INIT_GUID
+#include "initguid.h"
+#endif
+
+#include "itss.h"
+#include "wine/unicode.h"
+
+#define WB_GOBACK 0
+#define WB_GOFORWARD 1
+#define WB_GOHOME 2
+#define WB_SEARCH 3
+#define WB_REFRESH 4
+#define WB_STOP 5
+
+typedef struct {
+ LPWSTR chm_file;
+ LPWSTR chm_index;
+} ChmPath;
+
+typedef struct ContentItem {
+ struct ContentItem *parent;
+ struct ContentItem *child;
+ struct ContentItem *next;
+
+ HTREEITEM id;
+
+ LPWSTR name;
+ LPWSTR local;
+ ChmPath merge;
+} ContentItem;
+
+typedef struct CHMInfo
+{
+ IITStorage *pITStorage;
+ IStorage *pStorage;
+ LPCWSTR szFile;
+
+ IStream *strings_stream;
+ char **strings;
+ DWORD strings_size;
+} CHMInfo;
+
+#define TAB_CONTENTS 0
+#define TAB_INDEX 1
+#define TAB_SEARCH 2
+#define TAB_FAVORITES 3
+
+typedef struct {
+ HWND hwnd;
+ DWORD id;
+} HHTab;
+
+typedef struct {
+ IOleClientSite *client_site;
+ IWebBrowser2 *web_browser;
+ IOleObject *wb_object;
+
+ HH_WINTYPEW WinType;
+ CHMInfo *pCHMInfo;
+ ContentItem *content;
+ HWND hwndTabCtrl;
+ HWND hwndSizeBar;
+ HFONT hFont;
+
+ HHTab tabs[TAB_FAVORITES+1];
+ DWORD current_tab;
+} HHInfo;
+
+BOOL InitWebBrowser(HHInfo*,HWND);
+void ReleaseWebBrowser(HHInfo*);
+void ResizeWebBrowser(HHInfo*,DWORD,DWORD);
+void DoPageAction(HHInfo*,DWORD);
+
+void InitContent(HHInfo*);
+void ReleaseContent(HHInfo*);
+
+CHMInfo *OpenCHM(LPCWSTR szFile);
+BOOL LoadWinTypeFromCHM(CHMInfo *pCHMInfo, HH_WINTYPEW *pHHWinType);
+CHMInfo *CloseCHM(CHMInfo *pCHMInfo);
+void SetChmPath(ChmPath*,LPCWSTR,LPCWSTR);
+IStream *GetChmStream(CHMInfo*,LPCWSTR,ChmPath*);
+LPWSTR FindContextAlias(CHMInfo*,DWORD);
+
+HHInfo *CreateHelpViewer(LPCWSTR);
+void ReleaseHelpViewer(HHInfo*);
+BOOL NavigateToUrl(HHInfo*,LPCWSTR);
+BOOL NavigateToChm(HHInfo*,LPCWSTR,LPCWSTR);
+
+/* memory allocation functions */
+
+static inline void *hhctrl_alloc(size_t len)
+{
+ return HeapAlloc(GetProcessHeap(), 0, len);
+}
+
+static inline void *hhctrl_alloc_zero(size_t len)
+{
+ return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len);
+}
+
+static inline void *hhctrl_realloc(void *mem, size_t len)
+{
+ return HeapReAlloc(GetProcessHeap(), 0, mem, len);
+}
+
+static inline void *hhctrl_realloc_zero(void *mem, size_t len)
+{
+ return HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, mem, len);
+}
+
+static inline BOOL hhctrl_free(void *mem)
+{
+ return HeapFree(GetProcessHeap(), 0, mem);
+}
+
+static inline LPWSTR strdupW(LPCWSTR str)
+{
+ LPWSTR ret;
+ int size;
+
+ if(!str)
+ return NULL;
+
+ size = (strlenW(str)+1)*sizeof(WCHAR);
+ ret = hhctrl_alloc(size);
+ memcpy(ret, str, size);
+
+ return ret;
+}
+
+static inline LPWSTR strdupAtoW(LPCSTR str)
+{
+ LPWSTR ret;
+ DWORD len;
+
+ if(!str)
+ return NULL;
+
+ len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
+ ret = hhctrl_alloc(len*sizeof(WCHAR));
+ MultiByteToWideChar(CP_ACP, 0, str, -1, ret, len);
+
+ return ret;
+}
+
+extern HINSTANCE hhctrl_hinstance;
+extern BOOL hh_process;
+
+#endif
diff --git a/reactos/dll/win32/hhctrl.ocx/hhctrl.ocx.rbuild b/reactos/dll/win32/hhctrl.ocx/hhctrl.ocx.rbuild
new file mode 100644
index 00000000000..ed5027b7a72
--- /dev/null
+++ b/reactos/dll/win32/hhctrl.ocx/hhctrl.ocx.rbuild
@@ -0,0 +1,32 @@
+
+
+ .
+ include/reactos/wine
+
+
+
+ 0x600
+ 0x501
+ 0x501
+ wine
+ kernel32
+ user32
+ gdi32
+ shell32
+ comctl32
+ advapi32
+ gdi32
+ ntdll
+ ole32
+ oleaut32
+ shlwapi
+ chm.c
+ content.c
+ help.c
+ hhctrl.c
+ regsvr.c
+ webbrowser.c
+ itss.idl
+ hhctrl.rc
+ hhctrl.ocx.spec
+
diff --git a/reactos/dll/win32/hhctrl.ocx/hhctrl.ocx.spec b/reactos/dll/win32/hhctrl.ocx/hhctrl.ocx.spec
new file mode 100644
index 00000000000..e9cd118d895
--- /dev/null
+++ b/reactos/dll/win32/hhctrl.ocx/hhctrl.ocx.spec
@@ -0,0 +1,6 @@
+13 stdcall doWinMain(long ptr)
+14 stdcall HtmlHelpA(ptr ptr long long)
+15 stdcall HtmlHelpW(ptr ptr long long)
+@ stdcall -private DllGetClassObject(ptr ptr ptr)
+@ stdcall -private DllRegisterServer()
+@ stdcall -private DllUnregisterServer()
diff --git a/reactos/dll/win32/hhctrl.ocx/hhctrl.rc b/reactos/dll/win32/hhctrl.ocx/hhctrl.rc
new file mode 100644
index 00000000000..1e90f81bf7d
--- /dev/null
+++ b/reactos/dll/win32/hhctrl.ocx/hhctrl.rc
@@ -0,0 +1,42 @@
+/*
+ * HTML Help resources
+ *
+ * Copyright 2005 James Hawkins
+ *
+ * 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 "windef.h"
+#include "winbase.h"
+#include "wingdi.h"
+#include "winnls.h"
+#include "htmlhelp.h"
+#include "resource.h"
+
+LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
+
+#include "version.rc"
+
+#include "Cs.rc"
+#include "De.rc"
+#include "En.rc"
+#include "Fr.rc"
+#include "Fi.rc"
+#include "Hu.rc"
+#include "Ko.rc"
+#include "Nl.rc"
+#include "No.rc"
+#include "Pl.rc"
+#include "Tr.rc"
diff --git a/reactos/dll/win32/hhctrl.ocx/itss.h b/reactos/dll/win32/hhctrl.ocx/itss.h
new file mode 100644
index 00000000000..d0803c7baa0
--- /dev/null
+++ b/reactos/dll/win32/hhctrl.ocx/itss.h
@@ -0,0 +1,307 @@
+/*** Autogenerated by WIDL 0.3.0 from dll\win32\hhctrl.ocx\itss.idl - Do not edit ***/
+#include
+#include
+
+#ifndef __WIDL_DLL_WIN32_HHCTRL_OCX_ITSS_H
+#define __WIDL_DLL_WIN32_HHCTRL_OCX_ITSS_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+#include
+typedef struct _ITS_Control_Data {
+ UINT cdwControlData;
+ UINT adwControlData[1];
+} ITS_Control_Data, *PITS_Control_Data;
+typedef enum ECompactionLev {
+ COMPACT_DATA = 0,
+ COMPACT_DATA_AND_PATH = 1
+} ECompactionLev;
+#ifndef __IITStorage_FWD_DEFINED__
+#define __IITStorage_FWD_DEFINED__
+typedef interface IITStorage IITStorage;
+#endif
+
+/*****************************************************************************
+ * IITStorage interface
+ */
+#ifndef __IITStorage_INTERFACE_DEFINED__
+#define __IITStorage_INTERFACE_DEFINED__
+
+DEFINE_GUID(IID_IITStorage, 0x88cc31de, 0x27ab, 0x11d0, 0x9d,0xf9, 0x00,0xa0,0xc9,0x22,0xe6,0xec);
+#if defined(__cplusplus) && !defined(CINTERFACE)
+interface IITStorage : public IUnknown
+{
+ virtual HRESULT STDMETHODCALLTYPE StgCreateDocfile(
+ const WCHAR* pwcsName,
+ DWORD grfMode,
+ DWORD reserved,
+ IStorage** ppstgOpen) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE StgCreateDocfileOnILockBytes(
+ ILockBytes* plkbyt,
+ DWORD grfMode,
+ DWORD reserved,
+ IStorage** ppstgOpen) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE StgIsStorageFile(
+ const WCHAR* pwcsName) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE StgIsStorageILockBytes(
+ ILockBytes* plkbyt) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE StgOpenStorage(
+ const WCHAR* pwcsName,
+ IStorage* pstgPriority,
+ DWORD grfMode,
+ SNB snbExclude,
+ DWORD reserved,
+ IStorage** ppstgOpen) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE StgOpenStorageOnILockBytes(
+ ILockBytes* plkbyt,
+ IStorage* pStgPriority,
+ DWORD grfMode,
+ SNB snbExclude,
+ DWORD reserved,
+ IStorage** ppstgOpen) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE StgSetTimes(
+ WCHAR* lpszName,
+ FILETIME* pctime,
+ FILETIME* patime,
+ FILETIME* pmtime) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE SetControlData(
+ PITS_Control_Data pControlData) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE DefaultControlData(
+ PITS_Control_Data* ppControlData) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE Compact(
+ const WCHAR* pwcsName,
+ ECompactionLev iLev) = 0;
+
+};
+#else
+typedef struct IITStorageVtbl {
+ BEGIN_INTERFACE
+
+ /*** IUnknown methods ***/
+ HRESULT (STDMETHODCALLTYPE *QueryInterface)(
+ IITStorage* This,
+ REFIID riid,
+ void** ppvObject);
+
+ ULONG (STDMETHODCALLTYPE *AddRef)(
+ IITStorage* This);
+
+ ULONG (STDMETHODCALLTYPE *Release)(
+ IITStorage* This);
+
+ /*** IITStorage methods ***/
+ HRESULT (STDMETHODCALLTYPE *StgCreateDocfile)(
+ IITStorage* This,
+ const WCHAR* pwcsName,
+ DWORD grfMode,
+ DWORD reserved,
+ IStorage** ppstgOpen);
+
+ HRESULT (STDMETHODCALLTYPE *StgCreateDocfileOnILockBytes)(
+ IITStorage* This,
+ ILockBytes* plkbyt,
+ DWORD grfMode,
+ DWORD reserved,
+ IStorage** ppstgOpen);
+
+ HRESULT (STDMETHODCALLTYPE *StgIsStorageFile)(
+ IITStorage* This,
+ const WCHAR* pwcsName);
+
+ HRESULT (STDMETHODCALLTYPE *StgIsStorageILockBytes)(
+ IITStorage* This,
+ ILockBytes* plkbyt);
+
+ HRESULT (STDMETHODCALLTYPE *StgOpenStorage)(
+ IITStorage* This,
+ const WCHAR* pwcsName,
+ IStorage* pstgPriority,
+ DWORD grfMode,
+ SNB snbExclude,
+ DWORD reserved,
+ IStorage** ppstgOpen);
+
+ HRESULT (STDMETHODCALLTYPE *StgOpenStorageOnILockBytes)(
+ IITStorage* This,
+ ILockBytes* plkbyt,
+ IStorage* pStgPriority,
+ DWORD grfMode,
+ SNB snbExclude,
+ DWORD reserved,
+ IStorage** ppstgOpen);
+
+ HRESULT (STDMETHODCALLTYPE *StgSetTimes)(
+ IITStorage* This,
+ WCHAR* lpszName,
+ FILETIME* pctime,
+ FILETIME* patime,
+ FILETIME* pmtime);
+
+ HRESULT (STDMETHODCALLTYPE *SetControlData)(
+ IITStorage* This,
+ PITS_Control_Data pControlData);
+
+ HRESULT (STDMETHODCALLTYPE *DefaultControlData)(
+ IITStorage* This,
+ PITS_Control_Data* ppControlData);
+
+ HRESULT (STDMETHODCALLTYPE *Compact)(
+ IITStorage* This,
+ const WCHAR* pwcsName,
+ ECompactionLev iLev);
+
+ END_INTERFACE
+} IITStorageVtbl;
+interface IITStorage {
+ const IITStorageVtbl* lpVtbl;
+};
+
+#ifdef COBJMACROS
+/*** IUnknown methods ***/
+#define IITStorage_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
+#define IITStorage_AddRef(p) (p)->lpVtbl->AddRef(p)
+#define IITStorage_Release(p) (p)->lpVtbl->Release(p)
+/*** IITStorage methods ***/
+#define IITStorage_StgCreateDocfile(p,a,b,c,d) (p)->lpVtbl->StgCreateDocfile(p,a,b,c,d)
+#define IITStorage_StgCreateDocfileOnILockBytes(p,a,b,c,d) (p)->lpVtbl->StgCreateDocfileOnILockBytes(p,a,b,c,d)
+#define IITStorage_StgIsStorageFile(p,a) (p)->lpVtbl->StgIsStorageFile(p,a)
+#define IITStorage_StgIsStorageILockBytes(p,a) (p)->lpVtbl->StgIsStorageILockBytes(p,a)
+#define IITStorage_StgOpenStorage(p,a,b,c,d,e,f) (p)->lpVtbl->StgOpenStorage(p,a,b,c,d,e,f)
+#define IITStorage_StgOpenStorageOnILockBytes(p,a,b,c,d,e,f) (p)->lpVtbl->StgOpenStorageOnILockBytes(p,a,b,c,d,e,f)
+#define IITStorage_StgSetTimes(p,a,b,c,d) (p)->lpVtbl->StgSetTimes(p,a,b,c,d)
+#define IITStorage_SetControlData(p,a) (p)->lpVtbl->SetControlData(p,a)
+#define IITStorage_DefaultControlData(p,a) (p)->lpVtbl->DefaultControlData(p,a)
+#define IITStorage_Compact(p,a,b) (p)->lpVtbl->Compact(p,a,b)
+#endif
+
+#endif
+
+HRESULT CALLBACK IITStorage_StgCreateDocfile_Proxy(
+ IITStorage* This,
+ const WCHAR* pwcsName,
+ DWORD grfMode,
+ DWORD reserved,
+ IStorage** ppstgOpen);
+void __RPC_STUB IITStorage_StgCreateDocfile_Stub(
+ IRpcStubBuffer* This,
+ IRpcChannelBuffer* pRpcChannelBuffer,
+ PRPC_MESSAGE pRpcMessage,
+ DWORD* pdwStubPhase);
+HRESULT CALLBACK IITStorage_StgCreateDocfileOnILockBytes_Proxy(
+ IITStorage* This,
+ ILockBytes* plkbyt,
+ DWORD grfMode,
+ DWORD reserved,
+ IStorage** ppstgOpen);
+void __RPC_STUB IITStorage_StgCreateDocfileOnILockBytes_Stub(
+ IRpcStubBuffer* This,
+ IRpcChannelBuffer* pRpcChannelBuffer,
+ PRPC_MESSAGE pRpcMessage,
+ DWORD* pdwStubPhase);
+HRESULT CALLBACK IITStorage_StgIsStorageFile_Proxy(
+ IITStorage* This,
+ const WCHAR* pwcsName);
+void __RPC_STUB IITStorage_StgIsStorageFile_Stub(
+ IRpcStubBuffer* This,
+ IRpcChannelBuffer* pRpcChannelBuffer,
+ PRPC_MESSAGE pRpcMessage,
+ DWORD* pdwStubPhase);
+HRESULT CALLBACK IITStorage_StgIsStorageILockBytes_Proxy(
+ IITStorage* This,
+ ILockBytes* plkbyt);
+void __RPC_STUB IITStorage_StgIsStorageILockBytes_Stub(
+ IRpcStubBuffer* This,
+ IRpcChannelBuffer* pRpcChannelBuffer,
+ PRPC_MESSAGE pRpcMessage,
+ DWORD* pdwStubPhase);
+HRESULT CALLBACK IITStorage_StgOpenStorage_Proxy(
+ IITStorage* This,
+ const WCHAR* pwcsName,
+ IStorage* pstgPriority,
+ DWORD grfMode,
+ SNB snbExclude,
+ DWORD reserved,
+ IStorage** ppstgOpen);
+void __RPC_STUB IITStorage_StgOpenStorage_Stub(
+ IRpcStubBuffer* This,
+ IRpcChannelBuffer* pRpcChannelBuffer,
+ PRPC_MESSAGE pRpcMessage,
+ DWORD* pdwStubPhase);
+HRESULT CALLBACK IITStorage_StgOpenStorageOnILockBytes_Proxy(
+ IITStorage* This,
+ ILockBytes* plkbyt,
+ IStorage* pStgPriority,
+ DWORD grfMode,
+ SNB snbExclude,
+ DWORD reserved,
+ IStorage** ppstgOpen);
+void __RPC_STUB IITStorage_StgOpenStorageOnILockBytes_Stub(
+ IRpcStubBuffer* This,
+ IRpcChannelBuffer* pRpcChannelBuffer,
+ PRPC_MESSAGE pRpcMessage,
+ DWORD* pdwStubPhase);
+HRESULT CALLBACK IITStorage_StgSetTimes_Proxy(
+ IITStorage* This,
+ WCHAR* lpszName,
+ FILETIME* pctime,
+ FILETIME* patime,
+ FILETIME* pmtime);
+void __RPC_STUB IITStorage_StgSetTimes_Stub(
+ IRpcStubBuffer* This,
+ IRpcChannelBuffer* pRpcChannelBuffer,
+ PRPC_MESSAGE pRpcMessage,
+ DWORD* pdwStubPhase);
+HRESULT CALLBACK IITStorage_SetControlData_Proxy(
+ IITStorage* This,
+ PITS_Control_Data pControlData);
+void __RPC_STUB IITStorage_SetControlData_Stub(
+ IRpcStubBuffer* This,
+ IRpcChannelBuffer* pRpcChannelBuffer,
+ PRPC_MESSAGE pRpcMessage,
+ DWORD* pdwStubPhase);
+HRESULT CALLBACK IITStorage_DefaultControlData_Proxy(
+ IITStorage* This,
+ PITS_Control_Data* ppControlData);
+void __RPC_STUB IITStorage_DefaultControlData_Stub(
+ IRpcStubBuffer* This,
+ IRpcChannelBuffer* pRpcChannelBuffer,
+ PRPC_MESSAGE pRpcMessage,
+ DWORD* pdwStubPhase);
+HRESULT CALLBACK IITStorage_Compact_Proxy(
+ IITStorage* This,
+ const WCHAR* pwcsName,
+ ECompactionLev iLev);
+void __RPC_STUB IITStorage_Compact_Stub(
+ IRpcStubBuffer* This,
+ IRpcChannelBuffer* pRpcChannelBuffer,
+ PRPC_MESSAGE pRpcMessage,
+ DWORD* pdwStubPhase);
+
+#endif /* __IITStorage_INTERFACE_DEFINED__ */
+
+DEFINE_GUID(CLSID_ITStorage,0x5d02926a,0x212e,0x11d0,0x9d,0xf9,0x00,0xa0,0xc9,0x22,0xe6,0xec);
+DEFINE_GUID(CLSID_MSFSStore,0xd54eee56,0xaaab,0x11d0,0x9e,0x1d,0x00,0xa0,0xc9,0x22,0xe6,0xec);
+DEFINE_GUID(CLSID_MSITStore,0x9d148290,0xb9c8,0x11d0,0xa4,0xcc,0x00,0x00,0xf8,0x01,0x49,0xf6);
+DEFINE_GUID(CLSID_ITSProtocol,0x9d148291,0xb9c8,0x11d0,0xa4,0xcc,0x00,0x00,0xf8,0x01,0x49,0xf6);
+/* Begin additional prototypes for all interfaces */
+
+unsigned long __RPC_USER SNB_UserSize (unsigned long *, unsigned long, SNB *);
+unsigned char * __RPC_USER SNB_UserMarshal (unsigned long *, unsigned char *, SNB *);
+unsigned char * __RPC_USER SNB_UserUnmarshal(unsigned long *, unsigned char *, SNB *);
+void __RPC_USER SNB_UserFree (unsigned long *, SNB *);
+
+/* End additional prototypes */
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* __WIDL_DLL_WIN32_HHCTRL_OCX_ITSS_H */
diff --git a/reactos/dll/win32/hhctrl.ocx/itss.idl b/reactos/dll/win32/hhctrl.ocx/itss.idl
new file mode 100644
index 00000000000..9d09cb65f1a
--- /dev/null
+++ b/reactos/dll/win32/hhctrl.ocx/itss.idl
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2004 Mike McCormack
+ *
+ * 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
+ */
+
+import "oaidl.idl";
+
+typedef struct _ITS_Control_Data
+{
+ UINT cdwControlData;
+ UINT adwControlData[1];
+
+} ITS_Control_Data, *PITS_Control_Data;
+
+typedef enum ECompactionLev {
+ COMPACT_DATA = 0,
+ COMPACT_DATA_AND_PATH
+} ECompactionLev;
+
+[
+ object,
+ uuid(88cc31de-27ab-11d0-9df9-00a0c922e6ec),
+ pointer_default(unique)
+]
+interface IITStorage : IUnknown
+{
+ HRESULT StgCreateDocfile(
+ [in] const WCHAR * pwcsName,
+ [in] DWORD grfMode,
+ [in] DWORD reserved,
+ [out] IStorage ** ppstgOpen);
+
+ HRESULT StgCreateDocfileOnILockBytes(
+ [in] ILockBytes * plkbyt,
+ [in] DWORD grfMode,
+ [in] DWORD reserved,
+ [out] IStorage ** ppstgOpen);
+
+
+ HRESULT StgIsStorageFile(
+ [in] const WCHAR * pwcsName);
+
+ HRESULT StgIsStorageILockBytes(
+ [in] ILockBytes * plkbyt);
+
+ HRESULT StgOpenStorage(
+ [in] const WCHAR * pwcsName,
+ [in] IStorage * pstgPriority,
+ [in] DWORD grfMode,
+ [in] SNB snbExclude,
+ [in] DWORD reserved,
+ [out] IStorage ** ppstgOpen);
+
+ HRESULT StgOpenStorageOnILockBytes(
+ [in] ILockBytes * plkbyt,
+ [in] IStorage * pStgPriority,
+ [in] DWORD grfMode,
+ [in] SNB snbExclude,
+ [in] DWORD reserved,
+ [out] IStorage ** ppstgOpen);
+
+ HRESULT StgSetTimes(
+ [in] WCHAR const * lpszName,
+ [in] FILETIME const * pctime,
+ [in] FILETIME const * patime,
+ [in] FILETIME const * pmtime);
+
+ HRESULT SetControlData(
+ [in] PITS_Control_Data pControlData);
+
+ HRESULT DefaultControlData(
+ [out] PITS_Control_Data * ppControlData);
+
+ HRESULT Compact(
+ [in] const WCHAR * pwcsName,
+ [in] ECompactionLev iLev);
+}
+
+cpp_quote("DEFINE_GUID(CLSID_ITStorage,0x5d02926a,0x212e,0x11d0,0x9d,0xf9,0x00,0xa0,0xc9,0x22,0xe6,0xec);")
+cpp_quote("DEFINE_GUID(CLSID_MSFSStore,0xd54eee56,0xaaab,0x11d0,0x9e,0x1d,0x00,0xa0,0xc9,0x22,0xe6,0xec);")
+cpp_quote("DEFINE_GUID(CLSID_MSITStore,0x9d148290,0xb9c8,0x11d0,0xa4,0xcc,0x00,0x00,0xf8,0x01,0x49,0xf6);")
+cpp_quote("DEFINE_GUID(CLSID_ITSProtocol,0x9d148291,0xb9c8,0x11d0,0xa4,0xcc,0x00,0x00,0xf8,0x01,0x49,0xf6);")
diff --git a/reactos/dll/win32/hhctrl.ocx/regsvr.c b/reactos/dll/win32/hhctrl.ocx/regsvr.c
new file mode 100644
index 00000000000..cfdc36288c7
--- /dev/null
+++ b/reactos/dll/win32/hhctrl.ocx/regsvr.c
@@ -0,0 +1,569 @@
+/*
+ * self-registerable dll functions for hhctrl.ocx
+ *
+ * Copyright (C) 2004 Stefan Leichter
+ *
+ * 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
+#include
+
+#include "windef.h"
+#include "winbase.h"
+#include "winuser.h"
+#include "wingdi.h"
+#include "winreg.h"
+#include "winerror.h"
+
+#include "ole2.h"
+
+#include "wine/debug.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(htmlhelp);
+
+/*
+ * Near the bottom of this file are the exported DllRegisterServer and
+ * DllUnregisterServer, which make all this worthwhile.
+ */
+
+/***********************************************************************
+ * interface for self-registering
+ */
+struct regsvr_interface
+{
+ IID const *iid; /* NULL for end of list */
+ LPCSTR name; /* can be NULL to omit */
+ IID const *base_iid; /* can be NULL to omit */
+ int num_methods; /* can be <0 to omit */
+ CLSID const *ps_clsid; /* can be NULL to omit */
+ CLSID const *ps_clsid32; /* can be NULL to omit */
+};
+
+static HRESULT register_interfaces(struct regsvr_interface const *list);
+static HRESULT unregister_interfaces(struct regsvr_interface const *list);
+
+struct regsvr_coclass
+{
+ CLSID const *clsid; /* NULL for end of list */
+ LPCSTR name; /* can be NULL to omit */
+ LPCSTR ips; /* can be NULL to omit */
+ LPCSTR ips32; /* can be NULL to omit */
+ LPCSTR ips32_tmodel; /* can be NULL to omit */
+ LPCSTR progid; /* can be NULL to omit */
+ LPCSTR viprogid; /* can be NULL to omit */
+ LPCSTR progid_extra; /* can be NULL to omit */
+};
+
+static HRESULT register_coclasses(struct regsvr_coclass const *list);
+static HRESULT unregister_coclasses(struct regsvr_coclass const *list);
+
+/***********************************************************************
+ * static string constants
+ */
+static WCHAR const interface_keyname[10] = {
+ 'I', 'n', 't', 'e', 'r', 'f', 'a', 'c', 'e', 0 };
+static WCHAR const base_ifa_keyname[14] = {
+ 'B', 'a', 's', 'e', 'I', 'n', 't', 'e', 'r', 'f', 'a', 'c',
+ 'e', 0 };
+static WCHAR const num_methods_keyname[11] = {
+ 'N', 'u', 'm', 'M', 'e', 't', 'h', 'o', 'd', 's', 0 };
+static WCHAR const ps_clsid_keyname[15] = {
+ 'P', 'r', 'o', 'x', 'y', 'S', 't', 'u', 'b', 'C', 'l', 's',
+ 'i', 'd', 0 };
+static WCHAR const ps_clsid32_keyname[17] = {
+ 'P', 'r', 'o', 'x', 'y', 'S', 't', 'u', 'b', 'C', 'l', 's',
+ 'i', 'd', '3', '2', 0 };
+static WCHAR const clsid_keyname[6] = {
+ 'C', 'L', 'S', 'I', 'D', 0 };
+static WCHAR const curver_keyname[7] = {
+ 'C', 'u', 'r', 'V', 'e', 'r', 0 };
+static WCHAR const ips_keyname[13] = {
+ 'I', 'n', 'P', 'r', 'o', 'c', 'S', 'e', 'r', 'v', 'e', 'r',
+ 0 };
+static WCHAR const ips32_keyname[15] = {
+ 'I', 'n', 'P', 'r', 'o', 'c', 'S', 'e', 'r', 'v', 'e', 'r',
+ '3', '2', 0 };
+static WCHAR const progid_keyname[7] = {
+ 'P', 'r', 'o', 'g', 'I', 'D', 0 };
+static WCHAR const viprogid_keyname[25] = {
+ 'V', 'e', 'r', 's', 'i', 'o', 'n', 'I', 'n', 'd', 'e', 'p',
+ 'e', 'n', 'd', 'e', 'n', 't', 'P', 'r', 'o', 'g', 'I', 'D',
+ 0 };
+static char const tmodel_valuename[] = "ThreadingModel";
+
+/***********************************************************************
+ * static helper functions
+ */
+static LONG register_key_guid(HKEY base, WCHAR const *name, GUID const *guid);
+static LONG register_key_defvalueW(HKEY base, WCHAR const *name,
+ WCHAR const *value);
+static LONG register_key_defvalueA(HKEY base, WCHAR const *name,
+ char const *value);
+static LONG register_progid(WCHAR const *clsid,
+ char const *progid, char const *curver_progid,
+ char const *name, char const *extra);
+static LONG recursive_delete_key(HKEY key);
+static LONG recursive_delete_keyA(HKEY base, char const *name);
+static LONG recursive_delete_keyW(HKEY base, WCHAR const *name);
+
+/***********************************************************************
+ * register_interfaces
+ */
+static HRESULT register_interfaces(struct regsvr_interface const *list)
+{
+ LONG res = ERROR_SUCCESS;
+ HKEY interface_key;
+
+ res = RegCreateKeyExW(HKEY_CLASSES_ROOT, interface_keyname, 0, NULL, 0,
+ KEY_READ | KEY_WRITE, NULL, &interface_key, NULL);
+ if (res != ERROR_SUCCESS) goto error_return;
+
+ for (; res == ERROR_SUCCESS && list->iid; ++list) {
+ WCHAR buf[39];
+ HKEY iid_key;
+
+ StringFromGUID2(list->iid, buf, 39);
+ res = RegCreateKeyExW(interface_key, buf, 0, NULL, 0,
+ KEY_READ | KEY_WRITE, NULL, &iid_key, NULL);
+ if (res != ERROR_SUCCESS) goto error_close_interface_key;
+
+ if (list->name) {
+ res = RegSetValueExA(iid_key, NULL, 0, REG_SZ,
+ (CONST BYTE*)(list->name),
+ strlen(list->name) + 1);
+ if (res != ERROR_SUCCESS) goto error_close_iid_key;
+ }
+
+ if (list->base_iid) {
+ res = register_key_guid(iid_key, base_ifa_keyname, list->base_iid);
+ if (res != ERROR_SUCCESS) goto error_close_iid_key;
+ }
+
+ if (0 <= list->num_methods) {
+ static WCHAR const fmt[3] = { '%', 'd', 0 };
+ HKEY key;
+
+ res = RegCreateKeyExW(iid_key, num_methods_keyname, 0, NULL, 0,
+ KEY_READ | KEY_WRITE, NULL, &key, NULL);
+ if (res != ERROR_SUCCESS) goto error_close_iid_key;
+
+ wsprintfW(buf, fmt, list->num_methods);
+ res = RegSetValueExW(key, NULL, 0, REG_SZ,
+ (CONST BYTE*)buf,
+ (lstrlenW(buf) + 1) * sizeof(WCHAR));
+ RegCloseKey(key);
+
+ if (res != ERROR_SUCCESS) goto error_close_iid_key;
+ }
+
+ if (list->ps_clsid) {
+ res = register_key_guid(iid_key, ps_clsid_keyname, list->ps_clsid);
+ if (res != ERROR_SUCCESS) goto error_close_iid_key;
+ }
+
+ if (list->ps_clsid32) {
+ res = register_key_guid(iid_key, ps_clsid32_keyname, list->ps_clsid32);
+ if (res != ERROR_SUCCESS) goto error_close_iid_key;
+ }
+
+ error_close_iid_key:
+ RegCloseKey(iid_key);
+ }
+
+error_close_interface_key:
+ RegCloseKey(interface_key);
+error_return:
+ return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
+}
+
+/***********************************************************************
+ * unregister_interfaces
+ */
+static HRESULT unregister_interfaces(struct regsvr_interface const *list)
+{
+ LONG res = ERROR_SUCCESS;
+ HKEY interface_key;
+
+ res = RegOpenKeyExW(HKEY_CLASSES_ROOT, interface_keyname, 0,
+ KEY_READ | KEY_WRITE, &interface_key);
+ if (res == ERROR_FILE_NOT_FOUND) return S_OK;
+ if (res != ERROR_SUCCESS) goto error_return;
+
+ for (; res == ERROR_SUCCESS && list->iid; ++list) {
+ WCHAR buf[39];
+
+ StringFromGUID2(list->iid, buf, 39);
+ res = recursive_delete_keyW(interface_key, buf);
+ }
+
+ RegCloseKey(interface_key);
+error_return:
+ return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
+}
+
+/***********************************************************************
+ * register_coclasses
+ */
+static HRESULT register_coclasses(struct regsvr_coclass const *list)
+{
+ LONG res = ERROR_SUCCESS;
+ HKEY coclass_key;
+
+ res = RegCreateKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, NULL, 0,
+ KEY_READ | KEY_WRITE, NULL, &coclass_key, NULL);
+ if (res != ERROR_SUCCESS) goto error_return;
+
+ for (; res == ERROR_SUCCESS && list->clsid; ++list) {
+ WCHAR buf[39];
+ HKEY clsid_key;
+
+ StringFromGUID2(list->clsid, buf, 39);
+ res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
+ KEY_READ | KEY_WRITE, NULL, &clsid_key, NULL);
+ if (res != ERROR_SUCCESS) goto error_close_coclass_key;
+
+ if (list->name) {
+ res = RegSetValueExA(clsid_key, NULL, 0, REG_SZ,
+ (CONST BYTE*)(list->name),
+ strlen(list->name) + 1);
+ if (res != ERROR_SUCCESS) goto error_close_clsid_key;
+ }
+
+ if (list->ips) {
+ res = register_key_defvalueA(clsid_key, ips_keyname, list->ips);
+ if (res != ERROR_SUCCESS) goto error_close_clsid_key;
+ }
+
+ if (list->ips32) {
+ HKEY ips32_key;
+
+ res = RegCreateKeyExW(clsid_key, ips32_keyname, 0, NULL, 0,
+ KEY_READ | KEY_WRITE, NULL,
+ &ips32_key, NULL);
+ if (res != ERROR_SUCCESS) goto error_close_clsid_key;
+
+ res = RegSetValueExA(ips32_key, NULL, 0, REG_SZ,
+ (CONST BYTE*)list->ips32,
+ lstrlenA(list->ips32) + 1);
+ if (res == ERROR_SUCCESS && list->ips32_tmodel)
+ res = RegSetValueExA(ips32_key, tmodel_valuename, 0, REG_SZ,
+ (CONST BYTE*)list->ips32_tmodel,
+ strlen(list->ips32_tmodel) + 1);
+ RegCloseKey(ips32_key);
+ if (res != ERROR_SUCCESS) goto error_close_clsid_key;
+ }
+
+ if (list->progid) {
+ res = register_key_defvalueA(clsid_key, progid_keyname,
+ list->progid);
+ if (res != ERROR_SUCCESS) goto error_close_clsid_key;
+
+ res = register_progid(buf, list->progid, NULL,
+ list->name, list->progid_extra);
+ if (res != ERROR_SUCCESS) goto error_close_clsid_key;
+ }
+
+ if (list->viprogid) {
+ res = register_key_defvalueA(clsid_key, viprogid_keyname,
+ list->viprogid);
+ if (res != ERROR_SUCCESS) goto error_close_clsid_key;
+
+ res = register_progid(buf, list->viprogid, list->progid,
+ list->name, list->progid_extra);
+ if (res != ERROR_SUCCESS) goto error_close_clsid_key;
+ }
+
+ error_close_clsid_key:
+ RegCloseKey(clsid_key);
+ }
+
+error_close_coclass_key:
+ RegCloseKey(coclass_key);
+error_return:
+ return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
+}
+
+/***********************************************************************
+ * unregister_coclasses
+ */
+static HRESULT unregister_coclasses(struct regsvr_coclass const *list)
+{
+ LONG res = ERROR_SUCCESS;
+ HKEY coclass_key;
+
+ res = RegOpenKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0,
+ KEY_READ | KEY_WRITE, &coclass_key);
+ if (res == ERROR_FILE_NOT_FOUND) return S_OK;
+ if (res != ERROR_SUCCESS) goto error_return;
+
+ for (; res == ERROR_SUCCESS && list->clsid; ++list) {
+ WCHAR buf[39];
+
+ StringFromGUID2(list->clsid, buf, 39);
+ res = recursive_delete_keyW(coclass_key, buf);
+ if (res != ERROR_SUCCESS) goto error_close_coclass_key;
+
+ if (list->progid) {
+ res = recursive_delete_keyA(HKEY_CLASSES_ROOT, list->progid);
+ if (res != ERROR_SUCCESS) goto error_close_coclass_key;
+ }
+
+ if (list->viprogid) {
+ res = recursive_delete_keyA(HKEY_CLASSES_ROOT, list->viprogid);
+ if (res != ERROR_SUCCESS) goto error_close_coclass_key;
+ }
+ }
+
+error_close_coclass_key:
+ RegCloseKey(coclass_key);
+error_return:
+ return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
+}
+
+/***********************************************************************
+ * regsvr_key_guid
+ */
+static LONG register_key_guid(HKEY base, WCHAR const *name, GUID const *guid)
+{
+ WCHAR buf[39];
+
+ StringFromGUID2(guid, buf, 39);
+ return register_key_defvalueW(base, name, buf);
+}
+
+/***********************************************************************
+ * regsvr_key_defvalueW
+ */
+static LONG register_key_defvalueW(
+ HKEY base,
+ WCHAR const *name,
+ WCHAR const *value)
+{
+ LONG res;
+ HKEY key;
+
+ res = RegCreateKeyExW(base, name, 0, NULL, 0,
+ KEY_READ | KEY_WRITE, NULL, &key, NULL);
+ if (res != ERROR_SUCCESS) return res;
+ res = RegSetValueExW(key, NULL, 0, REG_SZ, (CONST BYTE*)value,
+ (lstrlenW(value) + 1) * sizeof(WCHAR));
+ RegCloseKey(key);
+ return res;
+}
+
+/***********************************************************************
+ * regsvr_key_defvalueA
+ */
+static LONG register_key_defvalueA(
+ HKEY base,
+ WCHAR const *name,
+ char const *value)
+{
+ LONG res;
+ HKEY key;
+
+ res = RegCreateKeyExW(base, name, 0, NULL, 0,
+ KEY_READ | KEY_WRITE, NULL, &key, NULL);
+ if (res != ERROR_SUCCESS) return res;
+ res = RegSetValueExA(key, NULL, 0, REG_SZ, (CONST BYTE*)value,
+ lstrlenA(value) + 1);
+ RegCloseKey(key);
+ return res;
+}
+
+/***********************************************************************
+ * regsvr_progid
+ */
+static LONG register_progid(
+ WCHAR const *clsid,
+ char const *progid,
+ char const *curver_progid,
+ char const *name,
+ char const *extra)
+{
+ LONG res;
+ HKEY progid_key;
+
+ res = RegCreateKeyExA(HKEY_CLASSES_ROOT, progid, 0,
+ NULL, 0, KEY_READ | KEY_WRITE, NULL,
+ &progid_key, NULL);
+ if (res != ERROR_SUCCESS) return res;
+
+ if (name) {
+ res = RegSetValueExA(progid_key, NULL, 0, REG_SZ,
+ (CONST BYTE*)name, strlen(name) + 1);
+ if (res != ERROR_SUCCESS) goto error_close_progid_key;
+ }
+
+ if (clsid) {
+ res = register_key_defvalueW(progid_key, clsid_keyname, clsid);
+ if (res != ERROR_SUCCESS) goto error_close_progid_key;
+ }
+
+ if (curver_progid) {
+ res = register_key_defvalueA(progid_key, curver_keyname,
+ curver_progid);
+ if (res != ERROR_SUCCESS) goto error_close_progid_key;
+ }
+
+ if (extra) {
+ HKEY extra_key;
+
+ res = RegCreateKeyExA(progid_key, extra, 0,
+ NULL, 0, KEY_READ | KEY_WRITE, NULL,
+ &extra_key, NULL);
+ if (res == ERROR_SUCCESS)
+ RegCloseKey(extra_key);
+ }
+
+error_close_progid_key:
+ RegCloseKey(progid_key);
+ return res;
+}
+
+/***********************************************************************
+ * recursive_delete_key
+ */
+static LONG recursive_delete_key(HKEY key)
+{
+ LONG res;
+ WCHAR subkey_name[MAX_PATH];
+ DWORD cName;
+ HKEY subkey;
+
+ for (;;) {
+ cName = sizeof(subkey_name) / sizeof(WCHAR);
+ res = RegEnumKeyExW(key, 0, subkey_name, &cName,
+ NULL, NULL, NULL, NULL);
+ if (res != ERROR_SUCCESS && res != ERROR_MORE_DATA) {
+ res = ERROR_SUCCESS; /* presumably we're done enumerating */
+ break;
+ }
+ res = RegOpenKeyExW(key, subkey_name, 0,
+ KEY_READ | KEY_WRITE, &subkey);
+ if (res == ERROR_FILE_NOT_FOUND) continue;
+ if (res != ERROR_SUCCESS) break;
+
+ res = recursive_delete_key(subkey);
+ RegCloseKey(subkey);
+ if (res != ERROR_SUCCESS) break;
+ }
+
+ if (res == ERROR_SUCCESS) res = RegDeleteKeyW(key, 0);
+ return res;
+}
+
+/***********************************************************************
+ * recursive_delete_keyA
+ */
+static LONG recursive_delete_keyA(HKEY base, char const *name)
+{
+ LONG res;
+ HKEY key;
+
+ res = RegOpenKeyExA(base, name, 0, KEY_READ | KEY_WRITE, &key);
+ if (res == ERROR_FILE_NOT_FOUND) return ERROR_SUCCESS;
+ if (res != ERROR_SUCCESS) return res;
+ res = recursive_delete_key(key);
+ RegCloseKey(key);
+ return res;
+}
+
+/***********************************************************************
+ * recursive_delete_keyW
+ */
+static LONG recursive_delete_keyW(HKEY base, WCHAR const *name)
+{
+ LONG res;
+ HKEY key;
+
+ res = RegOpenKeyExW(base, name, 0, KEY_READ | KEY_WRITE, &key);
+ if (res == ERROR_FILE_NOT_FOUND) return ERROR_SUCCESS;
+ if (res != ERROR_SUCCESS) return res;
+ res = recursive_delete_key(key);
+ RegCloseKey(key);
+ return res;
+}
+
+/***********************************************************************
+ * coclass list
+ */
+static struct regsvr_coclass const coclass_list[] = {
+/* { 41B23C28-488E-4E5C-ACE2-BB0BBABE99E8,
+ * "HHCtrl Object",
+ * NULL,
+ * "hhctrl.ocx",
+ * "Apartment"
+ * },
+ * { 4662DAB0-D393-11D0-9A56-00C04FB68B66,
+ * "",
+ * NULL,
+ * "hhctrl.ocx",
+ * "Both"
+ * },
+ * { ADB880A4-D8FF-11CF-9377-00AA003B7A11,
+ * "",
+ * NULL,
+ * "hhctrl.ocx",
+ * "Both"
+ * },
+ * { ADB880A6-D8FF-11CF-9377-00AA003B7A11,
+ * "HHCtrl Object",
+ * NULL,
+ * "hhctrl.ocx",
+ * "Apartment"
+ * },
+ */
+ { NULL } /* list terminator */
+};
+
+/***********************************************************************
+ * interface list
+ */
+
+static struct regsvr_interface const interface_list[] = {
+ { NULL } /* list terminator */
+};
+
+/***********************************************************************
+ * DllRegisterServer (HHCTRL.@)
+ */
+HRESULT WINAPI DllRegisterServer(void)
+{
+ HRESULT hr;
+
+ TRACE("\n");
+
+ hr = register_coclasses(coclass_list);
+ if (SUCCEEDED(hr))
+ hr = register_interfaces(interface_list);
+ return hr;
+}
+
+/***********************************************************************
+ * DllUnregisterServer (HHCTRL.@)
+ */
+HRESULT WINAPI DllUnregisterServer(void)
+{
+ HRESULT hr;
+
+ TRACE("\n");
+
+ hr = unregister_coclasses(coclass_list);
+ if (SUCCEEDED(hr))
+ hr = unregister_interfaces(interface_list);
+ return hr;
+}
diff --git a/reactos/dll/win32/hhctrl.ocx/resource.h b/reactos/dll/win32/hhctrl.ocx/resource.h
new file mode 100644
index 00000000000..02df94641e9
--- /dev/null
+++ b/reactos/dll/win32/hhctrl.ocx/resource.h
@@ -0,0 +1,24 @@
+/*
+ * HTML Help resource definitions
+ *
+ * Copyright 2005 James Hawkins
+ *
+ * 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 IDS_CONTENTS 1
+#define IDS_INDEX 2
+#define IDS_SEARCH 3
+#define IDS_FAVORITES 4
diff --git a/reactos/dll/win32/hhctrl.ocx/version.rc b/reactos/dll/win32/hhctrl.ocx/version.rc
new file mode 100644
index 00000000000..3a89350e684
--- /dev/null
+++ b/reactos/dll/win32/hhctrl.ocx/version.rc
@@ -0,0 +1,29 @@
+/*
+ * Version information for hhctrl.ocx
+ *
+ * Copyright 2004 Hans Leidekker
+ * Copyright 2004 Tom Wickline
+ *
+ * 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 WINE_FILEDESCRIPTION_STR "Wine htmlhelp OCX"
+#define WINE_FILENAME_STR "hhctrl.ocx"
+#define WINE_FILEVERSION 4,72,7325,0
+#define WINE_FILEVERSION_STR "4.72.7325.0"
+#define WINE_PRODUCTVERSION 4,72,7325,0
+#define WINE_PRODUCTVERSION_STR "4.72.7325.0"
+
+#include
diff --git a/reactos/dll/win32/hhctrl.ocx/webbrowser.c b/reactos/dll/win32/hhctrl.ocx/webbrowser.c
new file mode 100644
index 00000000000..e0238b3d4cd
--- /dev/null
+++ b/reactos/dll/win32/hhctrl.ocx/webbrowser.c
@@ -0,0 +1,700 @@
+/*
+ * WebBrowser Implementation
+ *
+ * Copyright 2005 James Hawkins
+ *
+ * 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 "hhctrl.h"
+
+#define ICOM_THIS_MULTI(impl,field,iface) impl* const This=(impl*)((char*)(iface) - offsetof(impl,field))
+
+typedef struct IOleClientSiteImpl
+{
+ const IOleClientSiteVtbl *lpVtbl;
+ const IOleInPlaceSiteVtbl *lpvtblOleInPlaceSite;
+ const IOleInPlaceFrameVtbl *lpvtblOleInPlaceFrame;
+ const IDocHostUIHandlerVtbl *lpvtblDocHostUIHandler;
+
+ /* IOleClientSiteImpl data */
+ IOleObject *pBrowserObject;
+ LONG ref;
+
+ /* IOleInPlaceFrame data */
+ HWND hwndWindow;
+} IOleClientSiteImpl;
+
+static HRESULT STDMETHODCALLTYPE Site_QueryInterface(IOleClientSite *iface, REFIID riid, void **ppvObj)
+{
+ ICOM_THIS_MULTI(IOleClientSiteImpl, lpVtbl, iface);
+ *ppvObj = NULL;
+
+ if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IOleClientSite))
+ {
+ *ppvObj = This;
+ }
+ else if (IsEqualIID(riid, &IID_IOleInPlaceSite))
+ {
+ *ppvObj = &(This->lpvtblOleInPlaceSite);
+ }
+ else if (IsEqualIID(riid, &IID_IDocHostUIHandler))
+ {
+ *ppvObj = &(This->lpvtblDocHostUIHandler);
+ }
+ else
+ return E_NOINTERFACE;
+
+ return S_OK;
+}
+
+static ULONG STDMETHODCALLTYPE Site_AddRef(IOleClientSite *iface)
+{
+ ICOM_THIS_MULTI(IOleClientSiteImpl, lpVtbl, iface);
+ return InterlockedIncrement(&This->ref);
+}
+
+static ULONG STDMETHODCALLTYPE Site_Release(IOleClientSite *iface)
+{
+ ICOM_THIS_MULTI(IOleClientSiteImpl, lpVtbl, iface);
+ LONG refCount = InterlockedDecrement(&This->ref);
+
+ if (refCount)
+ return refCount;
+
+ hhctrl_free(This);
+ return 0;
+}
+
+static HRESULT STDMETHODCALLTYPE Site_SaveObject(IOleClientSite *iface)
+{
+ return E_NOTIMPL;
+}
+
+static HRESULT STDMETHODCALLTYPE Site_GetMoniker(IOleClientSite *iface, DWORD dwAssign, DWORD dwWhichMoniker, IMoniker **ppmk)
+{
+ return E_NOTIMPL;
+}
+
+static HRESULT STDMETHODCALLTYPE Site_GetContainer(IOleClientSite *iface, LPOLECONTAINER *ppContainer)
+{
+ *ppContainer = NULL;
+
+ return E_NOINTERFACE;
+}
+
+static HRESULT STDMETHODCALLTYPE Site_ShowObject(IOleClientSite *iface)
+{
+ return NOERROR;
+}
+
+static HRESULT STDMETHODCALLTYPE Site_OnShowWindow(IOleClientSite *iface, BOOL fShow)
+{
+ return E_NOTIMPL;
+}
+
+static HRESULT STDMETHODCALLTYPE Site_RequestNewObjectLayout(IOleClientSite *iface)
+{
+ return E_NOTIMPL;
+}
+
+static const IOleClientSiteVtbl MyIOleClientSiteTable =
+{
+ Site_QueryInterface,
+ Site_AddRef,
+ Site_Release,
+ Site_SaveObject,
+ Site_GetMoniker,
+ Site_GetContainer,
+ Site_ShowObject,
+ Site_OnShowWindow,
+ Site_RequestNewObjectLayout
+};
+
+static HRESULT STDMETHODCALLTYPE UI_QueryInterface(IDocHostUIHandler *iface, REFIID riid, LPVOID *ppvObj)
+{
+ ICOM_THIS_MULTI(IOleClientSiteImpl, lpvtblDocHostUIHandler, iface);
+ return Site_QueryInterface((IOleClientSite *)This, riid, ppvObj);
+}
+
+static ULONG STDMETHODCALLTYPE UI_AddRef(IDocHostUIHandler *iface)
+{
+ return 1;
+}
+
+static ULONG STDMETHODCALLTYPE UI_Release(IDocHostUIHandler * iface)
+{
+ return 2;
+}
+
+static HRESULT STDMETHODCALLTYPE UI_ShowContextMenu(IDocHostUIHandler *iface, DWORD dwID, POINT *ppt, IUnknown *pcmdtReserved, IDispatch *pdispReserved)
+{
+ return S_OK;
+}
+
+static HRESULT STDMETHODCALLTYPE UI_GetHostInfo(IDocHostUIHandler *iface, DOCHOSTUIINFO *pInfo)
+{
+ pInfo->cbSize = sizeof(DOCHOSTUIINFO);
+ pInfo->dwFlags = DOCHOSTUIFLAG_NO3DBORDER;
+ pInfo->dwDoubleClick = DOCHOSTUIDBLCLK_DEFAULT;
+
+ return S_OK;
+}
+
+static HRESULT STDMETHODCALLTYPE UI_ShowUI(IDocHostUIHandler *iface, DWORD dwID, IOleInPlaceActiveObject *pActiveObject, IOleCommandTarget *pCommandTarget, IOleInPlaceFrame *pFrame, IOleInPlaceUIWindow *pDoc)
+{
+ return S_OK;
+}
+
+static HRESULT STDMETHODCALLTYPE UI_HideUI(IDocHostUIHandler *iface)
+{
+ return S_OK;
+}
+
+static HRESULT STDMETHODCALLTYPE UI_UpdateUI(IDocHostUIHandler *iface)
+{
+ return S_OK;
+}
+
+static HRESULT STDMETHODCALLTYPE UI_EnableModeless(IDocHostUIHandler *iface, BOOL fEnable)
+{
+ return S_OK;
+}
+
+static HRESULT STDMETHODCALLTYPE UI_OnDocWindowActivate(IDocHostUIHandler *iface, BOOL fActivate)
+{
+ return S_OK;
+}
+
+static HRESULT STDMETHODCALLTYPE UI_OnFrameWindowActivate(IDocHostUIHandler *iface, BOOL fActivate)
+{
+ return S_OK;
+}
+
+static HRESULT STDMETHODCALLTYPE UI_ResizeBorder(IDocHostUIHandler *iface, LPCRECT prcBorder, IOleInPlaceUIWindow *pUIWindow, BOOL fRameWindow)
+{
+ return S_OK;
+}
+
+static HRESULT STDMETHODCALLTYPE UI_TranslateAccelerator(IDocHostUIHandler *iface, LPMSG lpMsg, const GUID *pguidCmdGroup, DWORD nCmdID)
+{
+ return S_FALSE;
+}
+
+static HRESULT STDMETHODCALLTYPE UI_GetOptionKeyPath(IDocHostUIHandler *iface, LPOLESTR *pchKey, DWORD dw)
+{
+ return S_FALSE;
+}
+
+static HRESULT STDMETHODCALLTYPE UI_GetDropTarget(IDocHostUIHandler *iface, IDropTarget *pDropTarget, IDropTarget **ppDropTarget)
+{
+ return S_FALSE;
+}
+
+static HRESULT STDMETHODCALLTYPE UI_GetExternal(IDocHostUIHandler *iface, IDispatch **ppDispatch)
+{
+ *ppDispatch = NULL;
+ return S_FALSE;
+}
+
+static HRESULT STDMETHODCALLTYPE UI_TranslateUrl(IDocHostUIHandler *iface, DWORD dwTranslate, OLECHAR *pchURLIn, OLECHAR **ppchURLOut)
+{
+ *ppchURLOut = NULL;
+ return S_FALSE;
+}
+
+static HRESULT STDMETHODCALLTYPE UI_FilterDataObject(IDocHostUIHandler *iface, IDataObject *pDO, IDataObject **ppDORet)
+{
+ *ppDORet = NULL;
+ return S_FALSE;
+}
+
+static const IDocHostUIHandlerVtbl MyIDocHostUIHandlerTable =
+{
+ UI_QueryInterface,
+ UI_AddRef,
+ UI_Release,
+ UI_ShowContextMenu,
+ UI_GetHostInfo,
+ UI_ShowUI,
+ UI_HideUI,
+ UI_UpdateUI,
+ UI_EnableModeless,
+ UI_OnDocWindowActivate,
+ UI_OnFrameWindowActivate,
+ UI_ResizeBorder,
+ UI_TranslateAccelerator,
+ UI_GetOptionKeyPath,
+ UI_GetDropTarget,
+ UI_GetExternal,
+ UI_TranslateUrl,
+ UI_FilterDataObject
+};
+
+static HRESULT STDMETHODCALLTYPE InPlace_QueryInterface(IOleInPlaceSite *iface, REFIID riid, LPVOID *ppvObj)
+{
+ ICOM_THIS_MULTI(IOleClientSiteImpl, lpvtblOleInPlaceSite, iface);
+ return Site_QueryInterface((IOleClientSite *)This, riid, ppvObj);
+}
+
+static ULONG STDMETHODCALLTYPE InPlace_AddRef(IOleInPlaceSite *iface)
+{
+ return 1;
+}
+
+static ULONG STDMETHODCALLTYPE InPlace_Release(IOleInPlaceSite *iface)
+{
+ return 2;
+}
+
+static HRESULT STDMETHODCALLTYPE InPlace_GetWindow(IOleInPlaceSite *iface, HWND *lphwnd)
+{
+ ICOM_THIS_MULTI(IOleClientSiteImpl, lpvtblOleInPlaceSite, iface);
+ *lphwnd = This->hwndWindow;
+
+ return S_OK;
+}
+
+static HRESULT STDMETHODCALLTYPE InPlace_ContextSensitiveHelp(IOleInPlaceSite *iface, BOOL fEnterMode)
+{
+ return E_NOTIMPL;
+}
+
+static HRESULT STDMETHODCALLTYPE InPlace_CanInPlaceActivate(IOleInPlaceSite *iface)
+{
+ return S_OK;
+}
+
+static HRESULT STDMETHODCALLTYPE InPlace_OnInPlaceActivate(IOleInPlaceSite *iface)
+{
+ return S_OK;
+}
+
+static HRESULT STDMETHODCALLTYPE InPlace_OnUIActivate(IOleInPlaceSite *iface)
+{
+ return S_OK;
+}
+
+static HRESULT STDMETHODCALLTYPE InPlace_GetWindowContext(IOleInPlaceSite *iface, LPOLEINPLACEFRAME *lplpFrame, LPOLEINPLACEUIWINDOW *lplpDoc, LPRECT lprcPosRect, LPRECT lprcClipRect, LPOLEINPLACEFRAMEINFO lpFrameInfo)
+{
+ ICOM_THIS_MULTI(IOleClientSiteImpl, lpvtblOleInPlaceSite, iface);
+ *lplpFrame = (LPOLEINPLACEFRAME)&This->lpvtblOleInPlaceFrame;
+ *lplpDoc = NULL;
+
+ lpFrameInfo->fMDIApp = FALSE;
+ lpFrameInfo->hwndFrame = This->hwndWindow;
+ lpFrameInfo->haccel = NULL;
+ lpFrameInfo->cAccelEntries = 0;
+
+ return S_OK;
+}
+
+static HRESULT STDMETHODCALLTYPE InPlace_Scroll(IOleInPlaceSite *iface, SIZE scrollExtent)
+{
+ return E_NOTIMPL;
+}
+
+static HRESULT STDMETHODCALLTYPE InPlace_OnUIDeactivate(IOleInPlaceSite *iface, BOOL fUndoable)
+{
+ return S_OK;
+}
+
+static HRESULT STDMETHODCALLTYPE InPlace_OnInPlaceDeactivate(IOleInPlaceSite *iface)
+{
+ return S_OK;
+}
+
+static HRESULT STDMETHODCALLTYPE InPlace_DiscardUndoState(IOleInPlaceSite *iface)
+{
+ return E_NOTIMPL;
+}
+
+static HRESULT STDMETHODCALLTYPE InPlace_DeactivateAndUndo(IOleInPlaceSite *iface)
+{
+ return E_NOTIMPL;
+}
+
+static HRESULT STDMETHODCALLTYPE InPlace_OnPosRectChange(IOleInPlaceSite *iface, LPCRECT lprcPosRect)
+{
+ ICOM_THIS_MULTI(IOleClientSiteImpl, lpvtblOleInPlaceSite, iface);
+ IOleInPlaceObject *inplace;
+
+ if (!IOleObject_QueryInterface(This->pBrowserObject, &IID_IOleInPlaceObject, (void **)&inplace))
+ IOleInPlaceObject_SetObjectRects(inplace, lprcPosRect, lprcPosRect);
+
+ return S_OK;
+}
+
+static const IOleInPlaceSiteVtbl MyIOleInPlaceSiteTable =
+{
+ InPlace_QueryInterface,
+ InPlace_AddRef,
+ InPlace_Release,
+ InPlace_GetWindow,
+ InPlace_ContextSensitiveHelp,
+ InPlace_CanInPlaceActivate,
+ InPlace_OnInPlaceActivate,
+ InPlace_OnUIActivate,
+ InPlace_GetWindowContext,
+ InPlace_Scroll,
+ InPlace_OnUIDeactivate,
+ InPlace_OnInPlaceDeactivate,
+ InPlace_DiscardUndoState,
+ InPlace_DeactivateAndUndo,
+ InPlace_OnPosRectChange
+};
+
+static HRESULT STDMETHODCALLTYPE Frame_QueryInterface(IOleInPlaceFrame *iface, REFIID riid, LPVOID *ppvObj)
+{
+ return E_NOTIMPL;
+}
+
+static ULONG STDMETHODCALLTYPE Frame_AddRef(IOleInPlaceFrame *iface)
+{
+ return 1;
+}
+
+static ULONG STDMETHODCALLTYPE Frame_Release(IOleInPlaceFrame *iface)
+{
+ return 2;
+}
+
+static HRESULT STDMETHODCALLTYPE Frame_GetWindow(IOleInPlaceFrame *iface, HWND *lphwnd)
+{
+ ICOM_THIS_MULTI(IOleClientSiteImpl, lpvtblOleInPlaceFrame, iface);
+ *lphwnd = This->hwndWindow;
+
+ return S_OK;
+}
+
+static HRESULT STDMETHODCALLTYPE Frame_ContextSensitiveHelp(IOleInPlaceFrame *iface, BOOL fEnterMode)
+{
+ return E_NOTIMPL;
+}
+
+static HRESULT STDMETHODCALLTYPE Frame_GetBorder(IOleInPlaceFrame *iface, LPRECT lprectBorder)
+{
+ return E_NOTIMPL;
+}
+
+static HRESULT STDMETHODCALLTYPE Frame_RequestBorderSpace(IOleInPlaceFrame *iface, LPCBORDERWIDTHS pborderwidths)
+{
+ return E_NOTIMPL;
+}
+
+static HRESULT STDMETHODCALLTYPE Frame_SetBorderSpace(IOleInPlaceFrame *iface, LPCBORDERWIDTHS pborderwidths)
+{
+ return E_NOTIMPL;
+}
+
+static HRESULT STDMETHODCALLTYPE Frame_SetActiveObject(IOleInPlaceFrame *iface, IOleInPlaceActiveObject *pActiveObject, LPCOLESTR pszObjName)
+{
+ return S_OK;
+}
+
+static HRESULT STDMETHODCALLTYPE Frame_InsertMenus(IOleInPlaceFrame *iface, HMENU hmenuShared, LPOLEMENUGROUPWIDTHS lpMenuWidths)
+{
+ return E_NOTIMPL;
+}
+
+static HRESULT STDMETHODCALLTYPE Frame_SetMenu(IOleInPlaceFrame *iface, HMENU hmenuShared, HOLEMENU holemenu, HWND hwndActiveObject)
+{
+ return S_OK;
+}
+
+static HRESULT STDMETHODCALLTYPE Frame_RemoveMenus(IOleInPlaceFrame *iface, HMENU hmenuShared)
+{
+ return E_NOTIMPL;
+}
+
+static HRESULT STDMETHODCALLTYPE Frame_SetStatusText(IOleInPlaceFrame *iface, LPCOLESTR pszStatusText)
+{
+ return S_OK;
+}
+
+static HRESULT STDMETHODCALLTYPE Frame_EnableModeless(IOleInPlaceFrame *iface, BOOL fEnable)
+{
+ return S_OK;
+}
+
+static HRESULT STDMETHODCALLTYPE Frame_TranslateAccelerator(IOleInPlaceFrame *iface, LPMSG lpmsg, WORD wID)
+{
+ return E_NOTIMPL;
+}
+
+static const IOleInPlaceFrameVtbl MyIOleInPlaceFrameTable =
+{
+ Frame_QueryInterface,
+ Frame_AddRef,
+ Frame_Release,
+ Frame_GetWindow,
+ Frame_ContextSensitiveHelp,
+ Frame_GetBorder,
+ Frame_RequestBorderSpace,
+ Frame_SetBorderSpace,
+ Frame_SetActiveObject,
+ Frame_InsertMenus,
+ Frame_SetMenu,
+ Frame_RemoveMenus,
+ Frame_SetStatusText,
+ Frame_EnableModeless,
+ Frame_TranslateAccelerator
+};
+
+static HRESULT STDMETHODCALLTYPE Storage_QueryInterface(IStorage *This, REFIID riid, LPVOID *ppvObj)
+{
+ return E_NOTIMPL;
+}
+
+static ULONG STDMETHODCALLTYPE Storage_AddRef(IStorage *This)
+{
+ return 1;
+}
+
+static ULONG STDMETHODCALLTYPE Storage_Release(IStorage *This)
+{
+ return 2;
+}
+
+static HRESULT STDMETHODCALLTYPE Storage_CreateStream(IStorage *This, const WCHAR *pwcsName, DWORD grfMode, DWORD reserved1, DWORD reserved2, IStream **ppstm)
+{
+ return E_NOTIMPL;
+}
+
+static HRESULT STDMETHODCALLTYPE Storage_OpenStream(IStorage *This, const WCHAR * pwcsName, void *reserved1, DWORD grfMode, DWORD reserved2, IStream **ppstm)
+{
+ return E_NOTIMPL;
+}
+
+static HRESULT STDMETHODCALLTYPE Storage_CreateStorage(IStorage *This, const WCHAR *pwcsName, DWORD grfMode, DWORD reserved1, DWORD reserved2, IStorage **ppstg)
+{
+ return E_NOTIMPL;
+}
+
+static HRESULT STDMETHODCALLTYPE Storage_OpenStorage(IStorage *This, const WCHAR * pwcsName, IStorage * pstgPriority, DWORD grfMode, SNB snbExclude, DWORD reserved, IStorage **ppstg)
+{
+ return E_NOTIMPL;
+}
+
+static HRESULT STDMETHODCALLTYPE Storage_CopyTo(IStorage *This, DWORD ciidExclude, IID const *rgiidExclude, SNB snbExclude,IStorage *pstgDest)
+{
+ return E_NOTIMPL;
+}
+
+static HRESULT STDMETHODCALLTYPE Storage_MoveElementTo(IStorage *This, const OLECHAR *pwcsName,IStorage * pstgDest, const OLECHAR *pwcsNewName, DWORD grfFlags)
+{
+ return E_NOTIMPL;
+}
+
+static HRESULT STDMETHODCALLTYPE Storage_Commit(IStorage *This, DWORD grfCommitFlags)
+{
+ return E_NOTIMPL;
+}
+
+static HRESULT STDMETHODCALLTYPE Storage_Revert(IStorage *This)
+{
+ return E_NOTIMPL;
+}
+
+static HRESULT STDMETHODCALLTYPE Storage_EnumElements(IStorage *This, DWORD reserved1, void *reserved2, DWORD reserved3, IEnumSTATSTG **ppenum)
+{
+ return E_NOTIMPL;
+}
+
+static HRESULT STDMETHODCALLTYPE Storage_DestroyElement(IStorage *This, const OLECHAR *pwcsName)
+{
+ return E_NOTIMPL;
+}
+
+static HRESULT STDMETHODCALLTYPE Storage_RenameElement(IStorage *This, const WCHAR *pwcsOldName, const WCHAR *pwcsNewName)
+{
+ return E_NOTIMPL;
+}
+
+static HRESULT STDMETHODCALLTYPE Storage_SetElementTimes(IStorage *This, const WCHAR *pwcsName, FILETIME const *pctime, FILETIME const *patime, FILETIME const *pmtime)
+{
+ return E_NOTIMPL;
+}
+
+static HRESULT STDMETHODCALLTYPE Storage_SetClass(IStorage *This, REFCLSID clsid)
+{
+ return S_OK;
+}
+
+static HRESULT STDMETHODCALLTYPE Storage_SetStateBits(IStorage *This, DWORD grfStateBits, DWORD grfMask)
+{
+ return E_NOTIMPL;
+}
+
+static HRESULT STDMETHODCALLTYPE Storage_Stat(IStorage *This, STATSTG *pstatstg, DWORD grfStatFlag)
+{
+ return E_NOTIMPL;
+}
+
+static const IStorageVtbl MyIStorageTable =
+{
+ Storage_QueryInterface,
+ Storage_AddRef,
+ Storage_Release,
+ Storage_CreateStream,
+ Storage_OpenStream,
+ Storage_CreateStorage,
+ Storage_OpenStorage,
+ Storage_CopyTo,
+ Storage_MoveElementTo,
+ Storage_Commit,
+ Storage_Revert,
+ Storage_EnumElements,
+ Storage_DestroyElement,
+ Storage_RenameElement,
+ Storage_SetElementTimes,
+ Storage_SetClass,
+ Storage_SetStateBits,
+ Storage_Stat
+};
+
+static IStorage MyIStorage = { &MyIStorageTable };
+
+BOOL InitWebBrowser(HHInfo *info, HWND hwndParent)
+{
+ IOleClientSiteImpl *iOleClientSiteImpl;
+ IOleInPlaceObject *inplace;
+ IOleObject *browserObject;
+ IWebBrowser2 *webBrowser2;
+ HRESULT hr;
+ RECT rc;
+
+ iOleClientSiteImpl = hhctrl_alloc_zero(sizeof(IOleClientSiteImpl));
+ if (!iOleClientSiteImpl)
+ return FALSE;
+
+ iOleClientSiteImpl->ref = 1;
+ iOleClientSiteImpl->lpVtbl = &MyIOleClientSiteTable;
+ iOleClientSiteImpl->lpvtblOleInPlaceSite = &MyIOleInPlaceSiteTable;
+ iOleClientSiteImpl->lpvtblOleInPlaceFrame = &MyIOleInPlaceFrameTable;
+ iOleClientSiteImpl->hwndWindow = hwndParent;
+ iOleClientSiteImpl->lpvtblDocHostUIHandler = &MyIDocHostUIHandlerTable;
+
+ hr = OleCreate(&CLSID_WebBrowser, &IID_IOleObject, OLERENDER_DRAW, 0,
+ (IOleClientSite *)iOleClientSiteImpl, &MyIStorage,
+ (void **)&browserObject);
+
+ info->client_site = (IOleClientSite *)iOleClientSiteImpl;
+ info->wb_object = browserObject;
+
+ if (FAILED(hr)) goto error;
+
+ /* make the browser object accessible to the IOleClientSite implementation */
+ iOleClientSiteImpl->pBrowserObject = browserObject;
+
+ GetClientRect(hwndParent, &rc);
+
+ hr = OleSetContainedObject((struct IUnknown *)browserObject, TRUE);
+ if (FAILED(hr)) goto error;
+
+ hr = IOleObject_DoVerb(browserObject, OLEIVERB_SHOW, NULL,
+ (IOleClientSite *)iOleClientSiteImpl,
+ -1, hwndParent, &rc);
+ if (FAILED(hr)) goto error;
+
+ hr = IOleObject_QueryInterface(browserObject, &IID_IOleInPlaceObject, (void**)&inplace);
+ if (FAILED(hr)) goto error;
+
+ IOleInPlaceObject_SetObjectRects(inplace, &rc, &rc);
+ IOleInPlaceObject_Release(inplace);
+
+ hr = IOleObject_QueryInterface(browserObject, &IID_IWebBrowser2,
+ (void **)&webBrowser2);
+ if (SUCCEEDED(hr))
+ {
+ info->web_browser = webBrowser2;
+ return TRUE;
+ }
+
+error:
+ ReleaseWebBrowser(info);
+ hhctrl_free(iOleClientSiteImpl);
+
+ return FALSE;
+}
+
+void ReleaseWebBrowser(HHInfo *info)
+{
+ HRESULT hres;
+
+ if (info->web_browser)
+ {
+ IWebBrowser2_Release(info->web_browser);
+ info->web_browser = NULL;
+ }
+
+ if (info->client_site)
+ {
+ IOleClientSite_Release(info->client_site);
+ info->client_site = NULL;
+ }
+
+ if(info->wb_object) {
+ IOleInPlaceSite *inplace;
+
+ hres = IOleObject_QueryInterface(info->wb_object, &IID_IOleInPlaceSite, (void**)&inplace);
+ if(SUCCEEDED(hres)) {
+ IOleInPlaceSite_OnInPlaceDeactivate(inplace);
+ IOleInPlaceSite_Release(inplace);
+ }
+
+ IOleObject_SetClientSite(info->wb_object, NULL);
+
+ IOleObject_Release(info->wb_object);
+ info->wb_object = NULL;
+ }
+}
+
+void ResizeWebBrowser(HHInfo *info, DWORD dwWidth, DWORD dwHeight)
+{
+ if (!info->web_browser)
+ return;
+
+ IWebBrowser2_put_Width(info->web_browser, dwWidth);
+ IWebBrowser2_put_Height(info->web_browser, dwHeight);
+}
+
+void DoPageAction(HHInfo *info, DWORD dwAction)
+{
+ IWebBrowser2 *pWebBrowser2 = info->web_browser;
+
+ if (!pWebBrowser2)
+ return;
+
+ switch (dwAction)
+ {
+ case WB_GOBACK:
+ IWebBrowser2_GoBack(pWebBrowser2);
+ break;
+ case WB_GOFORWARD:
+ IWebBrowser2_GoForward(pWebBrowser2);
+ break;
+ case WB_GOHOME:
+ IWebBrowser2_GoHome(pWebBrowser2);
+ break;
+ case WB_SEARCH:
+ IWebBrowser2_GoSearch(pWebBrowser2);
+ break;
+ case WB_REFRESH:
+ IWebBrowser2_Refresh(pWebBrowser2);
+ case WB_STOP:
+ IWebBrowser2_Stop(pWebBrowser2);
+ }
+}
diff --git a/reactos/include/psdk/htmlhelp.h b/reactos/include/psdk/htmlhelp.h
new file mode 100644
index 00000000000..edfae94b787
--- /dev/null
+++ b/reactos/include/psdk/htmlhelp.h
@@ -0,0 +1,451 @@
+/*
+ * Copyright 2004 Jacek 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
+ */
+
+#ifndef __HTMLHELP_H__
+#define __HTMLHELP_H__
+
+#define HH_DISPLAY_TOPIC 0x00
+#define HH_HELP_FINDER 0x00
+#define HH_DISPLAY_TOC 0x01
+#define HH_DISPLAY_INDEX 0x02
+#define HH_DISPLAY_SEARCH 0x03
+#define HH_SET_WIN_TYPE 0x04
+#define HH_GET_WIN_TYPE 0x05
+#define HH_GET_WIN_HANDLE 0x06
+#define HH_ENUM_INFO_TYPE 0x07
+#define HH_SET_INFO_TYPE 0x08
+#define HH_SYNC 0x09
+#define HH_RESERVED1 0x0A
+#define HH_RESERVED2 0x0B
+#define HH_RESERVED3 0x0C
+#define HH_KEYWORD_LOOKUP 0x0D
+#define HH_DISPLAY_TEXT_POPUP 0x0E
+#define HH_HELP_CONTEXT 0x0F
+#define HH_TP_HELP_CONTEXTMENU 0x10
+#define HH_TP_HELP_WM_HELP 0x11
+#define HH_CLOSE_ALL 0x12
+#define HH_ALINK_LOOKUP 0x13
+#define HH_GET_LAST_ERROR 0x14
+#define HH_ENUM_CATEGORY 0x15
+#define HH_ENUM_CATEGORY_IT 0x16
+#define HH_RESET_IT_FILTER 0x17
+#define HH_SET_INCLUSIVE_FILTER 0x18
+#define HH_SET_EXCLUSIVE_FILTER 0x19
+#define HH_INITIALIZE 0x1C
+#define HH_UNINITIALIZE 0x1D
+#define HH_PRETRANSLATEMESSAGE 0xFD
+#define HH_SET_GLOBAL_PROPERTY 0xFC
+
+#define HHWIN_PROP_TAB_AUTOHIDESHOW 0x00000001
+#define HHWIN_PROP_ONTOP 0x00000002
+#define HHWIN_PROP_NOTITLEBAR 0x00000004
+#define HHWIN_PROP_NODEF_STYLES 0x00000008
+#define HHWIN_PROP_NODEF_EXSTYLES 0x00000010
+#define HHWIN_PROP_TRI_PANE 0x00000020
+#define HHWIN_PROP_NOTB_TEXT 0x00000040
+#define HHWIN_PROP_POST_QUIT 0x00000080
+#define HHWIN_PROP_AUTO_SYNC 0x00000100
+#define HHWIN_PROP_TRACKING 0x00000200
+#define HHWIN_PROP_TAB_SEARCH 0x00000400
+#define HHWIN_PROP_TAB_HISTORY 0x00000800
+#define HHWIN_PROP_TAB_FAVORITES 0x00001000
+#define HHWIN_PROP_CHANGE_TITLE 0x00002000
+#define HHWIN_PROP_NAV_ONLY_WIN 0x00004000
+#define HHWIN_PROP_NO_TOOLBAR 0x00008000
+#define HHWIN_PROP_MENU 0x00010000
+#define HHWIN_PROP_TAB_ADVSEARCH 0x00020000
+#define HHWIN_PROP_USER_POS 0x00040000
+#define HHWIN_PROP_TAB_CUSTOM1 0x00080000
+#define HHWIN_PROP_TAB_CUSTOM2 0x00100000
+#define HHWIN_PROP_TAB_CUSTOM3 0x00200000
+#define HHWIN_PROP_TAB_CUSTOM4 0x00400000
+#define HHWIN_PROP_TAB_CUSTOM5 0x00800000
+#define HHWIN_PROP_TAB_CUSTOM6 0x01000000
+#define HHWIN_PROP_TAB_CUSTOM7 0x02000000
+#define HHWIN_PROP_TAB_CUSTOM8 0x04000000
+#define HHWIN_PROP_TAB_CUSTOM9 0x08000000
+#define HHWIN_TB_MARGIN 0x10000000
+
+#define HHWIN_PARAM_PROPERTIES 0x00000002
+#define HHWIN_PARAM_STYLES 0x00000004
+#define HHWIN_PARAM_EXSTYLES 0x00000008
+#define HHWIN_PARAM_RECT 0x00000010
+#define HHWIN_PARAM_NAV_WIDTH 0x00000020
+#define HHWIN_PARAM_SHOWSTATE 0x00000040
+#define HHWIN_PARAM_INFOTYPES 0x00000080
+#define HHWIN_PARAM_TB_FLAGS 0x00000100
+#define HHWIN_PARAM_EXPANSION 0x00000200
+#define HHWIN_PARAM_TABPOS 0x00000400
+#define HHWIN_PARAM_TABORDER 0x00000800
+#define HHWIN_PARAM_HISTORY_COUNT 0x00001000
+#define HHWIN_PARAM_CUR_TAB 0x00002000
+
+#define HHWIN_BUTTON_EXPAND 0x00000002
+#define HHWIN_BUTTON_BACK 0x00000004
+#define HHWIN_BUTTON_FORWARD 0x00000008
+#define HHWIN_BUTTON_STOP 0x00000010
+#define HHWIN_BUTTON_REFRESH 0x00000020
+#define HHWIN_BUTTON_HOME 0x00000040
+#define HHWIN_BUTTON_BROWSE_FWD 0x00000080
+#define HHWIN_BUTTON_BROWSE_BCK 0x00000100
+#define HHWIN_BUTTON_NOTES 0x00000200
+#define HHWIN_BUTTON_CONTENTS 0x00000400
+#define HHWIN_BUTTON_SYNC 0x00000800
+#define HHWIN_BUTTON_OPTIONS 0x00001000
+#define HHWIN_BUTTON_PRINT 0x00002000
+#define HHWIN_BUTTON_INDEX 0x00004000
+#define HHWIN_BUTTON_SEARCH 0x00008000
+#define HHWIN_BUTTON_HISTORY 0x00010000
+#define HHWIN_BUTTON_FAVORITES 0x00020000
+#define HHWIN_BUTTON_JUMP1 0x00040000
+#define HHWIN_BUTTON_JUMP2 0x00080000
+#define HHWIN_BUTTON_ZOOM 0x00100000
+#define HHWIN_BUTTON_TOC_NEXT 0x00200000
+#define HHWIN_BUTTON_TOC_PREV 0x00400000
+
+#define HHWIN_DEF_BUTTONS \
+ (HHWIN_BUTTON_EXPAND | HHWIN_BUTTON_BACK | HHWIN_BUTTON_OPTIONS | HHWIN_BUTTON_PRINT)
+
+#define IDTB_EXPAND 200
+#define IDTB_CONTRACT 201
+#define IDTB_STOP 202
+#define IDTB_REFRESH 203
+#define IDTB_BACK 204
+#define IDTB_HOME 205
+#define IDTB_SYNC 206
+#define IDTB_PRINT 207
+#define IDTB_OPTIONS 208
+#define IDTB_FORWARD 209
+#define IDTB_NOTES 210
+#define IDTB_BROWSE_FWD 211
+#define IDTB_BROWSE_BACK 212
+#define IDTB_CONTENTS 213
+#define IDTB_INDEX 214
+#define IDTB_SEARCH 215
+#define IDTB_HISTORY 216
+#define IDTB_FAVORITES 217
+#define IDTB_JUMP1 218
+#define IDTB_JUMP2 219
+#define IDTB_CUSTOMIZE 221
+#define IDTB_ZOOM 222
+#define IDTB_TOC_NEXT 223
+#define IDTB_TOC_PREV 224
+
+#define HHN_FIRST (0U-860U)
+#define HHN_LAST (0U-879U)
+#define HHN_NAVCOMPLETE HHN_FIRST
+#define HHN_TRACK (HHN_FIRST-1)
+#define HHN_WINDOW_CREATE (HHN_FIRST-2)
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct tagHH_NOTIFY {
+ NMHDR hdr;
+ PCSTR pszurl;
+} HH_NOTIFY;
+
+typedef struct tagHH_POPUPA {
+ int cbStruct;
+ HINSTANCE hinst;
+ UINT idString;
+ LPCSTR pszText;
+ POINT pt;
+ COLORREF clrForeground;
+ COLORREF clrBackground;
+ RECT rcMargins;
+ LPCSTR pszFont;
+} HH_POPUPA;
+
+typedef struct tagHH_POPUPW {
+ int cbStruct;
+ HINSTANCE hinst;
+ UINT idString;
+ LPCWSTR pszText;
+ POINT pt;
+ COLORREF clrForeground;
+ COLORREF clrBackground;
+ RECT rcMargins;
+ LPCWSTR pszFont;
+} HH_POPUPW;
+
+DECL_WINELIB_TYPE_AW(HH_POPUP)
+
+typedef struct tagHH_ALINKA {
+ int cbStruct;
+ BOOL fReserved;
+ LPCSTR pszKeywords;
+ LPCSTR pszUrl;
+ LPCSTR pszMsgText;
+ LPCSTR pszMsgTitle;
+ LPCSTR pszWindow;
+ BOOL fIndexOnFail;
+} HH_ALINKA;
+
+typedef struct tagHH_ALINKW {
+ int cbStruct;
+ BOOL fReserved;
+ LPCWSTR pszKeywords;
+ LPCWSTR pszUrl;
+ LPCWSTR pszMsgText;
+ LPCWSTR pszMsgTitle;
+ LPCWSTR pszWindow;
+ BOOL fIndexOnFail;
+} HH_ALINKW;
+
+DECL_WINELIB_TYPE_AW(HH_ALINK)
+
+enum {
+ HHWIN_NAVTYPE_TOC,
+ HHWIN_NAVTYPE_INDEX,
+ HHWIN_NAVTYPE_SEARCH,
+ HHWIN_NAVTYPE_FAVORITES,
+ HHWIN_NAVTYPE_HISTORY,
+ HHWIN_NAVTYPE_AUTHOR,
+ HHWIN_NAVTYPE_CUSTOM_FIRST = 11
+};
+
+enum {
+ IT_INCLUSIVE,
+ IT_EXCLUSIVE,
+ IT_HIDDEN
+};
+
+typedef struct tagHH_ENUM_IT {
+ int cbStruct;
+ int iType;
+ LPCSTR pszCatName;
+ LPCSTR pszITName;
+ LPCSTR pszITDescription;
+} HH_ENUM_IT, *PHH_ENUM_IT;
+
+typedef struct tagHH_ENUM_CAT {
+ int cbStruct;
+ LPCSTR pszCatName;
+ LPCSTR pszCatDescription;
+} HH_ENUM_CAT, *PHH_ENUM_CAT;
+
+typedef struct tagHH_SET_INFOTYPE {
+ int cbStruct;
+ LPCSTR pszCatName;
+ LPCSTR pszInfoTypeName;
+} HH_SET_INFOTYPE;
+
+typedef DWORD HH_INFOTYPE, *PHH_INFOTYPE;
+
+enum {
+ HHWIN_NAVTAB_TOP,
+ HHWIN_NAVTAB_LEFT,
+ HHWIN_NAVTAB_BOTTOM
+};
+
+#define HH_MAX_TABS 19
+
+enum {
+ HH_TAB_CONTENTS,
+ HH_TAB_INDEX,
+ HH_TAB_SEARCH,
+ HH_TAB_FAVORITES,
+ HH_TAB_HISTORY,
+ HH_TAB_AUTHOR,
+ HH_TAB_CUSTOM_FIRST = 11,
+ HH_TAB_CUSTOM_LAST = HH_MAX_TABS
+};
+
+#define HH_MAX_TABS_CUSTOM (HH_TAB_CUSTOM_LAST-HH_TAB_CUSTOM_FIRST+1)
+#define HH_FTS_DEFAULT_PROXIMITY -1
+
+typedef struct tagHH_FTS_QUERYA {
+ int cbStruct;
+ BOOL fUniCodeStrings;
+ LPCSTR pszSearchQuery;
+ LONG iProximity;
+ BOOL fStemmedSearch;
+ BOOL fTitleOnly;
+ BOOL fExecute;
+ LPCSTR pszWindow;
+} HH_FTS_QUERYA;
+
+typedef struct tagHH_FTS_QUERYW {
+ int cbStruct;
+ BOOL fUniCodeStrings;
+ LPCWSTR pszSearchQuery;
+ LONG iProximity;
+ BOOL fStemmedSearch;
+ BOOL fTitleOnly;
+ BOOL fExecute;
+ LPCWSTR pszWindow;
+} HH_FTS_QUERYW;
+
+DECL_WINELIB_TYPE_AW(HH_FTS_QUERY)
+
+typedef struct tagHH_WINTYPEA {
+ int cbStruct;
+ BOOL fUniCodeStrings;
+ LPCSTR pszType;
+ DWORD fsValidMembers;
+ DWORD fsWinProperties;
+ LPCSTR pszCaption;
+ DWORD dwStyles;
+ DWORD dwExStyles;
+ RECT rcWindowPos;
+ int nShowState;
+ HWND hwndHelp;
+ HWND hwndCaller;
+ PHH_INFOTYPE paInfoTypes;
+ HWND hwndToolBar;
+ HWND hwndNavigation;
+ HWND hwndHTML;
+ int iNavWidth;
+ RECT rcHTML;
+ LPCSTR pszToc;
+ LPCSTR pszIndex;
+ LPCSTR pszFile;
+ LPCSTR pszHome;
+ DWORD fsToolBarFlags;
+ BOOL fNotExpanded;
+ int curNavType;
+ int tabpos;
+ int idNotify;
+ BYTE tabOrder[HH_MAX_TABS+1];
+ int cHistory;
+ LPCSTR pszJump1;
+ LPCSTR pszJump2;
+ LPCSTR pszUrlJump1;
+ LPCSTR pszUrlJump2;
+ RECT rcMinSize;
+ int cbInfoTypes;
+ LPCSTR pszCustomTabs;
+} HH_WINTYPEA, *PHH_WINTYPEA;
+
+typedef struct tagHH_WINTYPEW {
+ int cbStruct;
+ BOOL fUniCodeStrings;
+ LPCWSTR pszType;
+ DWORD fsValidMembers;
+ DWORD fsWinProperties;
+ LPCWSTR pszCaption;
+ DWORD dwStyles;
+ DWORD dwExStyles;
+ RECT rcWindowPos;
+ int nShowState;
+ HWND hwndHelp;
+ HWND hwndCaller;
+ PHH_INFOTYPE paInfoTypes;
+ HWND hwndToolBar;
+ HWND hwndNavigation;
+ HWND hwndHTML;
+ int iNavWidth;
+ RECT rcHTML;
+ LPCWSTR pszToc;
+ LPCWSTR pszIndex;
+ LPCWSTR pszFile;
+ LPCWSTR pszHome;
+ DWORD fsToolBarFlags;
+ BOOL fNotExpanded;
+ int curNavType;
+ int tabpos;
+ int idNotify;
+ BYTE tabOrder[HH_MAX_TABS+1];
+ int cHistory;
+ LPCWSTR pszJump1;
+ LPCWSTR pszJump2;
+ LPCWSTR pszUrlJump1;
+ LPCWSTR pszUrlJump2;
+ RECT rcMinSize;
+ int cbInfoTypes;
+ LPCWSTR pszCustomTabs;
+} HH_WINTYPEW, *PHH_WINTYPEW;
+
+DECL_WINELIB_TYPE_AW(HH_WINTYPE)
+
+enum {
+ HHACT_TAB_CONTENTS,
+ HHACT_TAB_INDEX,
+ HHACT_TAB_SEARCH,
+ HHACT_TAB_HISTORY,
+ HHACT_TAB_FAVORITES,
+ HHACT_EXPAND,
+ HHACT_CONTRACT,
+ HHACT_BACK,
+ HHACT_FORWARD,
+ HHACT_STOP,
+ HHACT_REFRESH,
+ HHACT_HOME,
+ HHACT_SYNC,
+ HHACT_OPTIONS,
+ HHACT_PRINT,
+ HHACT_HIGHLIGHT,
+ HHACT_CUSTOMIZE,
+ HHACT_JUMP1,
+ HHACT_JUMP2,
+ HHACT_ZOOM,
+ HHACT_TOC_NEXT,
+ HHACT_TOC_PREV,
+ HHACT_NOTES,
+ HHACT_LAST_ENUM
+};
+
+typedef struct tagHH_NTRACKA {
+ NMHDR hdr;
+ PCSTR pszCurUrl;
+ int idAction;
+ PHH_WINTYPEA phhWinType;
+} HH_NTRACKA;
+
+typedef struct tagHH_NTRACKW {
+ NMHDR hdr;
+ PCSTR pszCurUrl;
+ int idAction;
+ PHH_WINTYPEW phhWinType;
+} HH_NTRACKW;
+
+DECL_WINELIB_TYPE_AW(HH_NTRACK)
+
+HWND WINAPI HtmlHelpA(HWND,LPCSTR,UINT,DWORD);
+HWND WINAPI HtmlHelpW(HWND,LPCWSTR,UINT,DWORD);
+#define HtmlHelp WINELIB_NAME_AW(HtmlHelp)
+
+#define ATOM_HTMLHELP_API_ANSI (LPTSTR)14
+#define ATOM_HTMLHELP_API_UNICODE (LPTSTR)15
+
+typedef enum tagHH_GPROPID {
+ HH_GPROPID_SINGLETHREAD = 1,
+ HH_GPROPID_TOOLBAR_MARGIN = 2,
+ HH_GPROPID_UI_LANGUAGE = 3,
+ HH_GPROPID_CURRENT_SUBSET = 4,
+ HH_GPROPID_CONTENT_LANGUAGE = 5
+} HH_GPROPID;
+
+#ifdef __WIDL_OAIDL_H
+
+typedef struct tagHH_GLOBAL_PROPERTY
+{
+ HH_GPROPID id;
+ VARIANT var;
+} HH_GLOBAL_PROPERTY ;
+
+#endif /* __WIDL_OAIDL_H */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __HTMLHELP_H__ */