macro.c 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062
  1. /*
  2. * Help Viewer
  3. *
  4. * Copyright 1996 Ulrich Schmid
  5. * Copyright 2002, 2008 Eric Pouech
  6. *
  7. * This library is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU Lesser General Public
  9. * License as published by the Free Software Foundation; either
  10. * version 2.1 of the License, or (at your option) any later version.
  11. *
  12. * This library is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * Lesser General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU Lesser General Public
  18. * License along with this library; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  20. */
  21. #define WIN32_LEAN_AND_MEAN
  22. #include <stdio.h>
  23. #include "windows.h"
  24. #include "commdlg.h"
  25. #include "shellapi.h"
  26. #include "winhelp.h"
  27. #include "wine/debug.h"
  28. WINE_DEFAULT_DEBUG_CHANNEL(winhelp);
  29. /**************************************************/
  30. /* Macro table */
  31. /**************************************************/
  32. struct MacroDesc {
  33. const char* name;
  34. const char* alias;
  35. BOOL isBool;
  36. const char* arguments;
  37. void *fn;
  38. };
  39. static struct MacroDesc*MACRO_Loaded /* = NULL */;
  40. static unsigned MACRO_NumLoaded /* = 0 */;
  41. /******* helper functions *******/
  42. static char* StrDup(const char* str)
  43. {
  44. char* dst;
  45. dst=HeapAlloc(GetProcessHeap(),0,strlen(str)+1);
  46. strcpy(dst, str);
  47. return dst;
  48. }
  49. static WINHELP_BUTTON** MACRO_LookupButton(WINHELP_WINDOW* win, LPCSTR name)
  50. {
  51. WINHELP_BUTTON** b;
  52. for (b = &win->first_button; *b; b = &(*b)->next)
  53. if (!lstrcmpiA(name, (*b)->lpszID)) break;
  54. return b;
  55. }
  56. /******* some forward declarations *******/
  57. static void CALLBACK MACRO_JumpID(LPCSTR lpszPathWindow, LPCSTR topic_id);
  58. /******* real macro implementation *******/
  59. void CALLBACK MACRO_CreateButton(LPCSTR id, LPCSTR name, LPCSTR macro)
  60. {
  61. WINHELP_WINDOW *win = MACRO_CurrentWindow();
  62. WINHELP_BUTTON *button, **b;
  63. LONG size;
  64. LPSTR ptr;
  65. WINE_TRACE("(%s, %s, %s)\n", debugstr_a(id), debugstr_a(name), debugstr_a(macro));
  66. size = sizeof(WINHELP_BUTTON) + strlen(id) + strlen(name) + strlen(macro) + 3;
  67. button = HeapAlloc(GetProcessHeap(), 0, size);
  68. if (!button) return;
  69. button->next = 0;
  70. button->hWnd = 0;
  71. ptr = (char*)button + sizeof(WINHELP_BUTTON);
  72. strcpy(ptr, id);
  73. button->lpszID = ptr;
  74. ptr += strlen(id) + 1;
  75. strcpy(ptr, name);
  76. button->lpszName = ptr;
  77. ptr += strlen(name) + 1;
  78. strcpy(ptr, macro);
  79. button->lpszMacro = ptr;
  80. button->wParam = WH_FIRST_BUTTON;
  81. for (b = &win->first_button; *b; b = &(*b)->next)
  82. button->wParam = max(button->wParam, (*b)->wParam + 1);
  83. *b = button;
  84. WINHELP_LayoutMainWindow(win);
  85. }
  86. static void CALLBACK MACRO_DestroyButton(LPCSTR str)
  87. {
  88. WINE_FIXME("(%s)\n", debugstr_a(str));
  89. }
  90. void CALLBACK MACRO_DisableButton(LPCSTR id)
  91. {
  92. WINHELP_BUTTON** b;
  93. WINE_TRACE("(%s)\n", debugstr_a(id));
  94. b = MACRO_LookupButton(MACRO_CurrentWindow(), id);
  95. if (!*b) {WINE_FIXME("Couldn't find button %s\n", debugstr_a(id)); return;}
  96. EnableWindow((*b)->hWnd, FALSE);
  97. }
  98. static void CALLBACK MACRO_EnableButton(LPCSTR id)
  99. {
  100. WINHELP_BUTTON** b;
  101. WINE_TRACE("(%s)\n", debugstr_a(id));
  102. b = MACRO_LookupButton(MACRO_CurrentWindow(), id);
  103. if (!*b) {WINE_FIXME("Couldn't find button %s\n", debugstr_a(id)); return;}
  104. EnableWindow((*b)->hWnd, TRUE);
  105. }
  106. void CALLBACK MACRO_JumpContents(LPCSTR lpszPath, LPCSTR lpszWindow)
  107. {
  108. HLPFILE* hlpfile;
  109. WINE_TRACE("(%s, %s)\n", debugstr_a(lpszPath), debugstr_a(lpszWindow));
  110. if ((hlpfile = WINHELP_LookupHelpFile(lpszPath)))
  111. WINHELP_OpenHelpWindow(HLPFILE_PageByHash, hlpfile, 0,
  112. WINHELP_GetWindowInfo(hlpfile, lpszWindow),
  113. SW_NORMAL);
  114. }
  115. void CALLBACK MACRO_About(void)
  116. {
  117. WCHAR name[256];
  118. HICON icon = LoadImageW( Globals.hInstance, MAKEINTRESOURCEW(IDI_WINHELP),
  119. IMAGE_ICON, 48, 48, LR_SHARED );
  120. LoadStringW( Globals.hInstance, STID_WINE_HELP, name, ARRAY_SIZE( name ));
  121. ShellAboutW( MACRO_CurrentWindow()->hMainWnd, name, NULL, icon );
  122. }
  123. static void CALLBACK MACRO_AddAccelerator(LONG u1, LONG u2, LPCSTR str)
  124. {
  125. WINE_FIXME("(%lu, %lu, %s)\n", u1, u2, debugstr_a(str));
  126. }
  127. static void CALLBACK MACRO_ALink(LPCSTR str1, LONG u, LPCSTR str2)
  128. {
  129. WINE_FIXME("(%s, %lu, %s)\n", debugstr_a(str1), u, debugstr_a(str2));
  130. }
  131. void CALLBACK MACRO_Annotate(void)
  132. {
  133. WINE_FIXME("()\n");
  134. }
  135. static void CALLBACK MACRO_AppendItem(LPCSTR str1, LPCSTR str2, LPCSTR str3, LPCSTR str4)
  136. {
  137. WINE_FIXME("(%s, %s, %s, %s)\n", debugstr_a(str1), debugstr_a(str2), debugstr_a(str3), debugstr_a(str4));
  138. }
  139. static void CALLBACK MACRO_Back(void)
  140. {
  141. WINHELP_WINDOW* win = MACRO_CurrentWindow();
  142. WINE_TRACE("()\n");
  143. if (win && win->back.index >= 2)
  144. WINHELP_CreateHelpWindow(&win->back.set[--win->back.index - 1], SW_SHOW, FALSE);
  145. }
  146. static void CALLBACK MACRO_BackFlush(void)
  147. {
  148. WINHELP_WINDOW* win = MACRO_CurrentWindow();
  149. WINE_TRACE("()\n");
  150. if (win) WINHELP_DeleteBackSet(win);
  151. }
  152. void CALLBACK MACRO_BookmarkDefine(void)
  153. {
  154. WINE_FIXME("()\n");
  155. }
  156. static void CALLBACK MACRO_BookmarkMore(void)
  157. {
  158. WINE_FIXME("()\n");
  159. }
  160. static void CALLBACK MACRO_BrowseButtons(void)
  161. {
  162. HLPFILE_PAGE* page = MACRO_CurrentWindow()->page;
  163. ULONG relative;
  164. WINE_TRACE("()\n");
  165. MACRO_CreateButton("BTN_PREV", "&<<", "Prev()");
  166. MACRO_CreateButton("BTN_NEXT", "&>>", "Next()");
  167. if (!HLPFILE_PageByOffset(page->file, page->browse_bwd, &relative))
  168. MACRO_DisableButton("BTN_PREV");
  169. if (!HLPFILE_PageByOffset(page->file, page->browse_fwd, &relative))
  170. MACRO_DisableButton("BTN_NEXT");
  171. }
  172. static void CALLBACK MACRO_ChangeButtonBinding(LPCSTR id, LPCSTR macro)
  173. {
  174. WINHELP_WINDOW* win = MACRO_CurrentWindow();
  175. WINHELP_BUTTON* button;
  176. WINHELP_BUTTON** b;
  177. LONG size;
  178. LPSTR ptr;
  179. WINE_TRACE("(%s, %s)\n", debugstr_a(id), debugstr_a(macro));
  180. b = MACRO_LookupButton(win, id);
  181. if (!*b) {WINE_FIXME("Couldn't find button %s\n", debugstr_a(id)); return;}
  182. size = sizeof(WINHELP_BUTTON) + strlen(id) +
  183. strlen((*b)->lpszName) + strlen(macro) + 3;
  184. button = HeapAlloc(GetProcessHeap(), 0, size);
  185. if (!button) return;
  186. button->next = (*b)->next;
  187. button->hWnd = (*b)->hWnd;
  188. button->wParam = (*b)->wParam;
  189. ptr = (char*)button + sizeof(WINHELP_BUTTON);
  190. strcpy(ptr, id);
  191. button->lpszID = ptr;
  192. ptr += strlen(id) + 1;
  193. strcpy(ptr, (*b)->lpszName);
  194. button->lpszName = ptr;
  195. ptr += strlen((*b)->lpszName) + 1;
  196. strcpy(ptr, macro);
  197. button->lpszMacro = ptr;
  198. *b = button;
  199. WINHELP_LayoutMainWindow(win);
  200. }
  201. static void CALLBACK MACRO_ChangeEnable(LPCSTR id, LPCSTR macro)
  202. {
  203. WINE_TRACE("(%s, %s)\n", debugstr_a(id), debugstr_a(macro));
  204. MACRO_ChangeButtonBinding(id, macro);
  205. MACRO_EnableButton(id);
  206. }
  207. static void CALLBACK MACRO_ChangeItemBinding(LPCSTR str1, LPCSTR str2)
  208. {
  209. WINE_FIXME("(%s, %s)\n", debugstr_a(str1), debugstr_a(str2));
  210. }
  211. static void CALLBACK MACRO_CheckItem(LPCSTR str)
  212. {
  213. WINE_FIXME("(%s)\n", debugstr_a(str));
  214. }
  215. static void CALLBACK MACRO_CloseSecondarys(void)
  216. {
  217. WINHELP_WINDOW *win;
  218. WINHELP_WINDOW *next;
  219. WINE_TRACE("()\n");
  220. for (win = Globals.win_list; win; win = next)
  221. {
  222. next = win->next;
  223. if (lstrcmpiA(win->info->name, "main"))
  224. WINHELP_ReleaseWindow(win);
  225. }
  226. }
  227. static void CALLBACK MACRO_CloseWindow(LPCSTR lpszWindow)
  228. {
  229. WINHELP_WINDOW *win;
  230. WINHELP_WINDOW *next;
  231. WINE_TRACE("(%s)\n", debugstr_a(lpszWindow));
  232. if (!lpszWindow || !lpszWindow[0]) lpszWindow = "main";
  233. for (win = Globals.win_list; win; win = next)
  234. {
  235. next = win->next;
  236. if (!lstrcmpiA(win->info->name, lpszWindow))
  237. WINHELP_ReleaseWindow(win);
  238. }
  239. }
  240. static void CALLBACK MACRO_Compare(LPCSTR str)
  241. {
  242. WINE_FIXME("(%s)\n", debugstr_a(str));
  243. }
  244. static void CALLBACK MACRO_Contents(void)
  245. {
  246. HLPFILE_PAGE* page = MACRO_CurrentWindow()->page;
  247. WINE_TRACE("()\n");
  248. if (page)
  249. MACRO_JumpContents(page->file->lpszPath, NULL);
  250. }
  251. static void CALLBACK MACRO_ControlPanel(LPCSTR str1, LPCSTR str2, LONG u)
  252. {
  253. WINE_FIXME("(%s, %s, %lu)\n", debugstr_a(str1), debugstr_a(str2), u);
  254. }
  255. void CALLBACK MACRO_CopyDialog(void)
  256. {
  257. WINE_FIXME("()\n");
  258. }
  259. static void CALLBACK MACRO_CopyTopic(void)
  260. {
  261. WINE_FIXME("()\n");
  262. }
  263. static void CALLBACK MACRO_DeleteItem(LPCSTR str)
  264. {
  265. WINE_FIXME("(%s)\n", debugstr_a(str));
  266. }
  267. static void CALLBACK MACRO_DeleteMark(LPCSTR str)
  268. {
  269. WINE_FIXME("(%s)\n", debugstr_a(str));
  270. }
  271. static void CALLBACK MACRO_DisableItem(LPCSTR str)
  272. {
  273. WINE_FIXME("(%s)\n", debugstr_a(str));
  274. }
  275. static void CALLBACK MACRO_EnableItem(LPCSTR str)
  276. {
  277. WINE_FIXME("(%s)\n", debugstr_a(str));
  278. }
  279. static void CALLBACK MACRO_EndMPrint(void)
  280. {
  281. WINE_FIXME("()\n");
  282. }
  283. static void CALLBACK MACRO_ExecFile(LPCSTR pgm, LPCSTR args, LONG cmd_show, LPCSTR topic)
  284. {
  285. HINSTANCE ret;
  286. WINE_TRACE("(%s, %s, %lu, %s)\n",
  287. debugstr_a(pgm), debugstr_a(args), cmd_show, debugstr_a(topic));
  288. ret = ShellExecuteA(Globals.active_win ? Globals.active_win->hMainWnd : NULL, "open",
  289. pgm, args, ".", cmd_show);
  290. if ((DWORD_PTR)ret < 32)
  291. {
  292. WINE_WARN("Failed with %p\n", ret);
  293. if (topic) MACRO_JumpID(NULL, topic);
  294. }
  295. }
  296. static void CALLBACK MACRO_ExecProgram(LPCSTR str, LONG u)
  297. {
  298. WINE_FIXME("(%s, %lu)\n", debugstr_a(str), u);
  299. }
  300. void CALLBACK MACRO_Exit(void)
  301. {
  302. WINE_TRACE("()\n");
  303. while (Globals.win_list)
  304. WINHELP_ReleaseWindow(Globals.win_list);
  305. }
  306. static void CALLBACK MACRO_ExtAbleItem(LPCSTR str, LONG u)
  307. {
  308. WINE_FIXME("(%s, %lu)\n", debugstr_a(str), u);
  309. }
  310. static void CALLBACK MACRO_ExtInsertItem(LPCSTR str1, LPCSTR str2, LPCSTR str3, LPCSTR str4, LONG u1, LONG u2)
  311. {
  312. WINE_FIXME("(%s, %s, %s, %s, %lu, %lu)\n", debugstr_a(str1), debugstr_a(str2), debugstr_a(str3), debugstr_a(str4), u1, u2);
  313. }
  314. static void CALLBACK MACRO_ExtInsertMenu(LPCSTR str1, LPCSTR str2, LPCSTR str3, LONG u1, LONG u2)
  315. {
  316. WINE_FIXME("(%s, %s, %s, %lu, %lu)\n", debugstr_a(str1), debugstr_a(str2), debugstr_a(str3), u1, u2);
  317. }
  318. static BOOL CALLBACK MACRO_FileExist(LPCSTR str)
  319. {
  320. WINE_TRACE("(%s)\n", debugstr_a(str));
  321. return GetFileAttributesA(str) != INVALID_FILE_ATTRIBUTES;
  322. }
  323. void CALLBACK MACRO_FileOpen(void)
  324. {
  325. char szFile[MAX_PATH];
  326. if (WINHELP_GetOpenFileName(szFile, MAX_PATH))
  327. {
  328. MACRO_JumpContents(szFile, "main");
  329. }
  330. }
  331. static void CALLBACK MACRO_Find(void)
  332. {
  333. WINE_FIXME("()\n");
  334. }
  335. static void CALLBACK MACRO_Finder(void)
  336. {
  337. WINHELP_CreateIndexWindow(FALSE);
  338. }
  339. static void CALLBACK MACRO_FloatingMenu(void)
  340. {
  341. WINE_FIXME("()\n");
  342. }
  343. static void CALLBACK MACRO_Flush(void)
  344. {
  345. WINE_FIXME("()\n");
  346. }
  347. static void CALLBACK MACRO_FocusWindow(LPCSTR lpszWindow)
  348. {
  349. WINHELP_WINDOW *win;
  350. WINE_TRACE("(%s)\n", debugstr_a(lpszWindow));
  351. if (!lpszWindow || !lpszWindow[0]) lpszWindow = "main";
  352. for (win = Globals.win_list; win; win = win->next)
  353. if (!lstrcmpiA(win->info->name, lpszWindow))
  354. SetFocus(win->hMainWnd);
  355. }
  356. static void CALLBACK MACRO_Generate(LPCSTR str, LONG w, LONG l)
  357. {
  358. WINE_FIXME("(%s, %lx, %lx)\n", debugstr_a(str), w, l);
  359. }
  360. static void CALLBACK MACRO_GotoMark(LPCSTR str)
  361. {
  362. WINE_FIXME("(%s)\n", debugstr_a(str));
  363. }
  364. void CALLBACK MACRO_HelpOn(void)
  365. {
  366. WINHELP_WINDOW *win = MACRO_CurrentWindow();
  367. LPCSTR file = NULL;
  368. WINE_TRACE("()\n");
  369. if (win && win->page && win->page->file)
  370. file = win->page->file->help_on_file;
  371. if (!file)
  372. file = (Globals.wVersion > 4) ? "winhlp32.hlp" : "winhelp.hlp";
  373. MACRO_JumpContents(file, NULL);
  374. }
  375. void CALLBACK MACRO_HelpOnTop(void)
  376. {
  377. static BOOL on_top = FALSE;
  378. WINHELP_WINDOW *win;
  379. HWND main_wnd = NULL;
  380. HMENU menu;
  381. for (win = Globals.win_list; win; win = win->next)
  382. if (!lstrcmpiA(win->info->name, "main"))
  383. main_wnd = win->hMainWnd;
  384. if (!main_wnd)
  385. {
  386. WINE_ERR("could not find the main window!\n");
  387. return;
  388. }
  389. menu = GetMenu(main_wnd);
  390. on_top = !on_top;
  391. if (on_top) {
  392. CheckMenuItem(menu, MNID_HELP_HELPTOP, MF_BYCOMMAND|MF_CHECKED);
  393. SetWindowPos(main_wnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);
  394. } else {
  395. CheckMenuItem(menu, MNID_HELP_HELPTOP, MF_BYCOMMAND|MF_UNCHECKED);
  396. SetWindowPos(main_wnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);
  397. }
  398. }
  399. void CALLBACK MACRO_History(void)
  400. {
  401. WINE_TRACE("()\n");
  402. if (Globals.active_win && !Globals.active_win->hHistoryWnd)
  403. {
  404. HWND hWnd = CreateWindowA(HISTORY_WIN_CLASS_NAME, "History", WS_OVERLAPPEDWINDOW,
  405. 0, 0, 0, 0, 0, 0, Globals.hInstance, Globals.active_win);
  406. ShowWindow(hWnd, SW_NORMAL);
  407. }
  408. }
  409. static void CALLBACK MACRO_IfThen(BOOL b, LPCSTR t)
  410. {
  411. if (b) MACRO_ExecuteMacro(MACRO_CurrentWindow(), t);
  412. }
  413. static void CALLBACK MACRO_IfThenElse(BOOL b, LPCSTR t, LPCSTR f)
  414. {
  415. if (b) MACRO_ExecuteMacro(MACRO_CurrentWindow(), t);
  416. else MACRO_ExecuteMacro(MACRO_CurrentWindow(), f);
  417. }
  418. static BOOL CALLBACK MACRO_InitMPrint(void)
  419. {
  420. WINE_FIXME("()\n");
  421. return FALSE;
  422. }
  423. static void CALLBACK MACRO_InsertItem(LPCSTR str1, LPCSTR str2, LPCSTR str3, LPCSTR str4, LONG u)
  424. {
  425. WINE_FIXME("(%s, %s, %s, %s, %lu)\n", debugstr_a(str1), debugstr_a(str2), debugstr_a(str3), debugstr_a(str4), u);
  426. }
  427. static void CALLBACK MACRO_InsertMenu(LPCSTR str1, LPCSTR str2, LONG u)
  428. {
  429. WINE_FIXME("(%s, %s, %lu)\n", debugstr_a(str1), debugstr_a(str2), u);
  430. }
  431. static BOOL CALLBACK MACRO_IsBook(void)
  432. {
  433. WINE_TRACE("()\n");
  434. return Globals.isBook;
  435. }
  436. static BOOL CALLBACK MACRO_IsMark(LPCSTR str)
  437. {
  438. WINE_FIXME("(%s)\n", debugstr_a(str));
  439. return FALSE;
  440. }
  441. static BOOL CALLBACK MACRO_IsNotMark(LPCSTR str)
  442. {
  443. WINE_FIXME("(%s)\n", debugstr_a(str));
  444. return TRUE;
  445. }
  446. void CALLBACK MACRO_JumpContext(LPCSTR lpszPath, LPCSTR lpszWindow, LONG context)
  447. {
  448. HLPFILE* hlpfile;
  449. WINE_TRACE("(%s, %s, %ld)\n", debugstr_a(lpszPath), debugstr_a(lpszWindow), context);
  450. if ((hlpfile = WINHELP_LookupHelpFile(lpszPath)))
  451. /* Some madness: what user calls 'context', hlpfile calls 'map' */
  452. WINHELP_OpenHelpWindow(HLPFILE_PageByMap, hlpfile, context,
  453. WINHELP_GetWindowInfo(hlpfile, lpszWindow),
  454. SW_NORMAL);
  455. }
  456. void CALLBACK MACRO_JumpHash(LPCSTR lpszPath, LPCSTR lpszWindow, LONG lHash)
  457. {
  458. HLPFILE* hlpfile;
  459. WINE_TRACE("(%s, %s, %lu)\n", debugstr_a(lpszPath), debugstr_a(lpszWindow), lHash);
  460. if (!lpszPath || !lpszPath[0])
  461. hlpfile = MACRO_CurrentWindow()->page->file;
  462. else
  463. hlpfile = WINHELP_LookupHelpFile(lpszPath);
  464. if (hlpfile)
  465. WINHELP_OpenHelpWindow(HLPFILE_PageByHash, hlpfile, lHash,
  466. WINHELP_GetWindowInfo(hlpfile, lpszWindow),
  467. SW_NORMAL);
  468. }
  469. static void CALLBACK MACRO_JumpHelpOn(void)
  470. {
  471. WINE_FIXME("()\n");
  472. }
  473. static void CALLBACK MACRO_JumpID(LPCSTR lpszPathWindow, LPCSTR topic_id)
  474. {
  475. LPSTR ptr;
  476. WINE_TRACE("(%s, %s)\n", debugstr_a(lpszPathWindow), debugstr_a(topic_id));
  477. if (lpszPathWindow && (ptr = strchr(lpszPathWindow, '>')) != NULL)
  478. {
  479. LPSTR tmp;
  480. size_t sz;
  481. tmp = HeapAlloc(GetProcessHeap(), 0, strlen(lpszPathWindow) + 1);
  482. if (tmp)
  483. {
  484. strcpy(tmp, lpszPathWindow);
  485. tmp[ptr - lpszPathWindow] = '\0';
  486. ptr += tmp - lpszPathWindow; /* ptr now points to '>' in tmp buffer */
  487. /* in some cases, we have a trailing space that we need to get rid of */
  488. /* FIXME: check if it has to be done in lexer rather than here */
  489. for (sz = strlen(ptr + 1); sz >= 1 && ptr[sz] == ' '; sz--) ptr[sz] = '\0';
  490. MACRO_JumpHash(tmp, ptr + 1, HLPFILE_Hash(topic_id));
  491. HeapFree(GetProcessHeap(), 0, tmp);
  492. }
  493. }
  494. else
  495. MACRO_JumpHash(lpszPathWindow, NULL, HLPFILE_Hash(topic_id));
  496. }
  497. /* FIXME: this macros is wrong
  498. * it should only contain 2 strings, path & window are coded as path>window
  499. */
  500. static void CALLBACK MACRO_JumpKeyword(LPCSTR lpszPath, LPCSTR lpszWindow, LPCSTR keyword)
  501. {
  502. WINE_FIXME("(%s, %s, %s)\n", debugstr_a(lpszPath), debugstr_a(lpszWindow), debugstr_a(keyword));
  503. }
  504. static void CALLBACK MACRO_KLink(LPCSTR str1, LONG u, LPCSTR str2, LPCSTR str3)
  505. {
  506. WINE_FIXME("(%s, %lu, %s, %s)\n", debugstr_a(str1), u, debugstr_a(str2), debugstr_a(str3));
  507. }
  508. static void CALLBACK MACRO_Menu(void)
  509. {
  510. WINE_FIXME("()\n");
  511. }
  512. static void CALLBACK MACRO_MPrintHash(LONG u)
  513. {
  514. WINE_FIXME("(%lu)\n", u);
  515. }
  516. static void CALLBACK MACRO_MPrintID(LPCSTR str)
  517. {
  518. WINE_FIXME("(%s)\n", debugstr_a(str));
  519. }
  520. static void CALLBACK MACRO_Next(void)
  521. {
  522. WINHELP_WNDPAGE wp;
  523. WINE_TRACE("()\n");
  524. wp.page = MACRO_CurrentWindow()->page;
  525. wp.page = HLPFILE_PageByOffset(wp.page->file, wp.page->browse_fwd, &wp.relative);
  526. if (wp.page)
  527. {
  528. wp.page->file->wRefCount++;
  529. wp.wininfo = MACRO_CurrentWindow()->info;
  530. WINHELP_CreateHelpWindow(&wp, SW_NORMAL, TRUE);
  531. }
  532. }
  533. static void CALLBACK MACRO_NoShow(void)
  534. {
  535. WINE_FIXME("()\n");
  536. }
  537. void CALLBACK MACRO_PopupContext(LPCSTR str, LONG u)
  538. {
  539. WINE_FIXME("(%s, %lu)\n", debugstr_a(str), u);
  540. }
  541. static void CALLBACK MACRO_PopupHash(LPCSTR str, LONG u)
  542. {
  543. WINE_FIXME("(%s, %lu)\n", debugstr_a(str), u);
  544. }
  545. static void CALLBACK MACRO_PopupId(LPCSTR str1, LPCSTR str2)
  546. {
  547. WINE_FIXME("(%s, %s)\n", debugstr_a(str1), debugstr_a(str2));
  548. }
  549. static void CALLBACK MACRO_PositionWindow(LONG i1, LONG i2, LONG u1, LONG u2, LONG u3, LPCSTR str)
  550. {
  551. WINE_FIXME("(%li, %li, %lu, %lu, %lu, %s)\n", i1, i2, u1, u2, u3, debugstr_a(str));
  552. }
  553. static void CALLBACK MACRO_Prev(void)
  554. {
  555. WINHELP_WNDPAGE wp;
  556. WINE_TRACE("()\n");
  557. wp.page = MACRO_CurrentWindow()->page;
  558. wp.page = HLPFILE_PageByOffset(wp.page->file, wp.page->browse_bwd, &wp.relative);
  559. if (wp.page)
  560. {
  561. wp.page->file->wRefCount++;
  562. wp.wininfo = MACRO_CurrentWindow()->info;
  563. WINHELP_CreateHelpWindow(&wp, SW_NORMAL, TRUE);
  564. }
  565. }
  566. void CALLBACK MACRO_Print(void)
  567. {
  568. PRINTDLGW printer;
  569. WINE_TRACE("()\n");
  570. printer.lStructSize = sizeof(printer);
  571. printer.hwndOwner = MACRO_CurrentWindow()->hMainWnd;
  572. printer.hInstance = Globals.hInstance;
  573. printer.hDevMode = 0;
  574. printer.hDevNames = 0;
  575. printer.hDC = 0;
  576. printer.Flags = 0;
  577. printer.nFromPage = 0;
  578. printer.nToPage = 0;
  579. printer.nMinPage = 0;
  580. printer.nMaxPage = 0;
  581. printer.nCopies = 0;
  582. printer.lCustData = 0;
  583. printer.lpfnPrintHook = 0;
  584. printer.lpfnSetupHook = 0;
  585. printer.lpPrintTemplateName = 0;
  586. printer.lpSetupTemplateName = 0;
  587. printer.hPrintTemplate = 0;
  588. printer.hSetupTemplate = 0;
  589. if (PrintDlgW(&printer)) {
  590. WINE_FIXME("Print()\n");
  591. }
  592. }
  593. void CALLBACK MACRO_PrinterSetup(void)
  594. {
  595. WINE_FIXME("()\n");
  596. }
  597. static void CALLBACK MACRO_RegisterRoutine(LPCSTR dll_name, LPCSTR proc, LPCSTR args)
  598. {
  599. void *fn = NULL;
  600. int size;
  601. WINHELP_DLL* dll;
  602. WINE_TRACE("(%s, %s, %s)\n", debugstr_a(dll_name), debugstr_a(proc), debugstr_a(args));
  603. /* FIXME: are the registered DLLs global or linked to the current file ???
  604. * We assume globals (as we did for macros, but is this really the case ???)
  605. */
  606. for (dll = Globals.dlls; dll; dll = dll->next)
  607. {
  608. if (!strcmp(dll->name, dll_name)) break;
  609. }
  610. if (!dll)
  611. {
  612. HANDLE hLib = LoadLibraryA(dll_name);
  613. /* FIXME: the library will not be unloaded until exit of program
  614. * We don't send the DW_TERM message
  615. */
  616. WINE_TRACE("Loading %s\n", debugstr_a(dll_name));
  617. /* FIXME: should look in the directory where current hlpfile
  618. * is loaded from
  619. */
  620. if (hLib == NULL)
  621. {
  622. /* FIXME: internationalisation for error messages */
  623. WINE_FIXME("Cannot find dll %s\n", debugstr_a(dll_name));
  624. }
  625. else if ((dll = HeapAlloc(GetProcessHeap(), 0, sizeof(*dll))))
  626. {
  627. dll->hLib = hLib;
  628. dll->name = StrDup(dll_name); /* FIXME: never freed */
  629. dll->next = Globals.dlls;
  630. Globals.dlls = dll;
  631. dll->handler = (WINHELP_LDLLHandler)GetProcAddress(dll->hLib, "LDLLHandler");
  632. dll->class = dll->handler ? (dll->handler)(DW_WHATMSG, 0, 0) : DC_NOMSG;
  633. WINE_TRACE("Got class %lx for DLL %s\n", dll->class, debugstr_a(dll_name));
  634. if (dll->class & DC_INITTERM) dll->handler(DW_INIT, 0, 0);
  635. if (dll->class & DC_CALLBACKS) dll->handler(DW_CALLBACKS, (LONG_PTR)&Callbacks, 0);
  636. }
  637. else WINE_WARN("OOM\n");
  638. }
  639. if (dll && !(fn = GetProcAddress(dll->hLib, proc)))
  640. {
  641. /* FIXME: internationalisation for error messages */
  642. WINE_FIXME("Cannot find proc %s in dll %s\n", debugstr_a(dll_name), debugstr_a(proc));
  643. }
  644. size = ++MACRO_NumLoaded * sizeof(struct MacroDesc);
  645. if (!MACRO_Loaded) MACRO_Loaded = HeapAlloc(GetProcessHeap(), 0, size);
  646. else MACRO_Loaded = HeapReAlloc(GetProcessHeap(), 0, MACRO_Loaded, size);
  647. MACRO_Loaded[MACRO_NumLoaded - 1].name = StrDup(proc); /* FIXME: never freed */
  648. MACRO_Loaded[MACRO_NumLoaded - 1].alias = NULL;
  649. MACRO_Loaded[MACRO_NumLoaded - 1].isBool = FALSE;
  650. MACRO_Loaded[MACRO_NumLoaded - 1].arguments = StrDup(args); /* FIXME: never freed */
  651. MACRO_Loaded[MACRO_NumLoaded - 1].fn = fn;
  652. WINE_TRACE("Added %s(%s) at %p\n", debugstr_a(proc), debugstr_a(args), fn);
  653. }
  654. static void CALLBACK MACRO_RemoveAccelerator(LONG u1, LONG u2)
  655. {
  656. WINE_FIXME("(%lu, %lu)\n", u1, u2);
  657. }
  658. static void CALLBACK MACRO_ResetMenu(void)
  659. {
  660. WINE_FIXME("()\n");
  661. }
  662. static void CALLBACK MACRO_SaveMark(LPCSTR str)
  663. {
  664. WINE_FIXME("(%s)\n", debugstr_a(str));
  665. }
  666. static void CALLBACK MACRO_Search(void)
  667. {
  668. WINHELP_CreateIndexWindow(TRUE);
  669. }
  670. void CALLBACK MACRO_SetContents(LPCSTR str, LONG u)
  671. {
  672. WINE_FIXME("(%s, %lu)\n", debugstr_a(str), u);
  673. }
  674. static void CALLBACK MACRO_SetHelpOnFile(LPCSTR str)
  675. {
  676. HLPFILE_PAGE* page = MACRO_CurrentWindow()->page;
  677. WINE_TRACE("(%s)\n", debugstr_a(str));
  678. HeapFree(GetProcessHeap(), 0, page->file->help_on_file);
  679. page->file->help_on_file = HeapAlloc(GetProcessHeap(), 0, strlen(str) + 1);
  680. if (page->file->help_on_file)
  681. strcpy(page->file->help_on_file, str);
  682. }
  683. static void CALLBACK MACRO_SetPopupColor(LONG r, LONG g, LONG b)
  684. {
  685. HLPFILE_PAGE* page = MACRO_CurrentWindow()->page;
  686. WINE_TRACE("(%lx, %lx, %lx)\n", r, g, b);
  687. page->file->has_popup_color = TRUE;
  688. page->file->popup_color = RGB(r, g, b);
  689. }
  690. static void CALLBACK MACRO_ShellExecute(LPCSTR str1, LPCSTR str2, LONG u1, LONG u2, LPCSTR str3, LPCSTR str4)
  691. {
  692. WINE_FIXME("(%s, %s, %lu, %lu, %s, %s)\n", debugstr_a(str1), debugstr_a(str2), u1, u2, debugstr_a(str3), debugstr_a(str4));
  693. }
  694. static void CALLBACK MACRO_ShortCut(LPCSTR str1, LPCSTR str2, LONG w, LONG l, LPCSTR str)
  695. {
  696. WINE_FIXME("(%s, %s, %lx, %lx, %s)\n", debugstr_a(str1), debugstr_a(str2), w, l, debugstr_a(str));
  697. }
  698. static void CALLBACK MACRO_TCard(LONG u)
  699. {
  700. WINE_FIXME("(%lu)\n", u);
  701. }
  702. static void CALLBACK MACRO_Test(LONG u)
  703. {
  704. WINE_FIXME("(%lu)\n", u);
  705. }
  706. static BOOL CALLBACK MACRO_TestALink(LPCSTR str)
  707. {
  708. WINE_FIXME("(%s)\n", debugstr_a(str));
  709. return FALSE;
  710. }
  711. static BOOL CALLBACK MACRO_TestKLink(LPCSTR str)
  712. {
  713. WINE_FIXME("(%s)\n", debugstr_a(str));
  714. return FALSE;
  715. }
  716. static void CALLBACK MACRO_UncheckItem(LPCSTR str)
  717. {
  718. WINE_FIXME("(%s)\n", debugstr_a(str));
  719. }
  720. static void CALLBACK MACRO_UpdateWindow(LPCSTR str1, LPCSTR str2)
  721. {
  722. WINE_FIXME("(%s, %s)\n", debugstr_a(str1), debugstr_a(str2));
  723. }
  724. /**************************************************/
  725. /* Macro table */
  726. /**************************************************/
  727. /* types:
  728. * U: 32 bit unsigned int
  729. * I: 32 bit signed int
  730. * S: string
  731. * v: unknown (32 bit entity)
  732. */
  733. static struct MacroDesc MACRO_Builtins[] = {
  734. {"About", NULL, 0, "", MACRO_About},
  735. {"AddAccelerator", "AA", 0, "UUS", MACRO_AddAccelerator},
  736. {"ALink", "AL", 0, "SUS", MACRO_ALink},
  737. {"Annotate", NULL, 0, "", MACRO_Annotate},
  738. {"AppendItem", NULL, 0, "SSSS", MACRO_AppendItem},
  739. {"Back", NULL, 0, "", MACRO_Back},
  740. {"BackFlush", "BF", 0, "", MACRO_BackFlush},
  741. {"BookmarkDefine", NULL, 0, "", MACRO_BookmarkDefine},
  742. {"BookmarkMore", NULL, 0, "", MACRO_BookmarkMore},
  743. {"BrowseButtons", NULL, 0, "", MACRO_BrowseButtons},
  744. {"ChangeButtonBinding", "CBB",0, "SS", MACRO_ChangeButtonBinding},
  745. {"ChangeEnable", "CE", 0, "SS", MACRO_ChangeEnable},
  746. {"ChangeItemBinding", "CIB",0, "SS", MACRO_ChangeItemBinding},
  747. {"CheckItem", "CI", 0, "S", MACRO_CheckItem},
  748. {"CloseSecondarys", "CS", 0, "", MACRO_CloseSecondarys},
  749. {"CloseWindow", "CW", 0, "S", MACRO_CloseWindow},
  750. {"Compare", NULL, 0, "S", MACRO_Compare},
  751. {"Contents", NULL, 0, "", MACRO_Contents},
  752. {"ControlPanel", NULL, 0, "SSU", MACRO_ControlPanel},
  753. {"CopyDialog", NULL, 0, "", MACRO_CopyDialog},
  754. {"CopyTopic", "CT", 0, "", MACRO_CopyTopic},
  755. {"CreateButton", "CB", 0, "SSS", MACRO_CreateButton},
  756. {"DeleteItem", NULL, 0, "S", MACRO_DeleteItem},
  757. {"DeleteMark", NULL, 0, "S", MACRO_DeleteMark},
  758. {"DestroyButton", NULL, 0, "S", MACRO_DestroyButton},
  759. {"DisableButton", "DB", 0, "S", MACRO_DisableButton},
  760. {"DisableItem", "DI", 0, "S", MACRO_DisableItem},
  761. {"EnableButton", "EB", 0, "S", MACRO_EnableButton},
  762. {"EnableItem", "EI", 0, "S", MACRO_EnableItem},
  763. {"EndMPrint", NULL, 0, "", MACRO_EndMPrint},
  764. {"ExecFile", "EF", 0, "SSUS", MACRO_ExecFile},
  765. {"ExecProgram", "EP", 0, "SU", MACRO_ExecProgram},
  766. {"Exit", NULL, 0, "", MACRO_Exit},
  767. {"ExtAbleItem", NULL, 0, "SU", MACRO_ExtAbleItem},
  768. {"ExtInsertItem", NULL, 0, "SSSSUU", MACRO_ExtInsertItem},
  769. {"ExtInsertMenu", NULL, 0, "SSSUU", MACRO_ExtInsertMenu},
  770. {"FileExist", "FE", 1, "S", MACRO_FileExist},
  771. {"FileOpen", "FO", 0, "", MACRO_FileOpen},
  772. {"Find", NULL, 0, "", MACRO_Find},
  773. {"Finder", "FD", 0, "", MACRO_Finder},
  774. {"FloatingMenu", NULL, 0, "", MACRO_FloatingMenu},
  775. {"Flush", "FH", 0, "", MACRO_Flush},
  776. {"FocusWindow", NULL, 0, "S", MACRO_FocusWindow},
  777. {"Generate", NULL, 0, "SUU", MACRO_Generate},
  778. {"GotoMark", NULL, 0, "S", MACRO_GotoMark},
  779. {"HelpOn", NULL, 0, "", MACRO_HelpOn},
  780. {"HelpOnTop", NULL, 0, "", MACRO_HelpOnTop},
  781. {"History", NULL, 0, "", MACRO_History},
  782. {"InitMPrint", NULL, 1, "", MACRO_InitMPrint},
  783. {"InsertItem", NULL, 0, "SSSSU", MACRO_InsertItem},
  784. {"InsertMenu", NULL, 0, "SSU", MACRO_InsertMenu},
  785. {"IfThen", "IF", 0, "BS", MACRO_IfThen},
  786. {"IfThenElse", "IE", 0, "BSS", MACRO_IfThenElse},
  787. {"IsBook", NULL, 1, "", MACRO_IsBook},
  788. {"IsMark", NULL, 1, "S", MACRO_IsMark},
  789. {"IsNotMark", "NM", 1, "S", MACRO_IsNotMark},
  790. {"JumpContents", NULL, 0, "SS", MACRO_JumpContents},
  791. {"JumpContext", "JC", 0, "SSU", MACRO_JumpContext},
  792. {"JumpHash", "JH", 0, "SSU", MACRO_JumpHash},
  793. {"JumpHelpOn", NULL, 0, "", MACRO_JumpHelpOn},
  794. {"JumpID", "JI", 0, "SS", MACRO_JumpID},
  795. {"JumpKeyword", "JK", 0, "SSS", MACRO_JumpKeyword},
  796. {"KLink", "KL", 0, "SUSS", MACRO_KLink},
  797. {"Menu", "MU", 0, "", MACRO_Menu},
  798. {"MPrintHash", NULL, 0, "U", MACRO_MPrintHash},
  799. {"MPrintID", NULL, 0, "S", MACRO_MPrintID},
  800. {"Next", NULL, 0, "", MACRO_Next},
  801. {"NoShow", "NS", 0, "", MACRO_NoShow},
  802. {"PopupContext", "PC", 0, "SU", MACRO_PopupContext},
  803. {"PopupHash", NULL, 0, "SU", MACRO_PopupHash},
  804. {"PopupId", "PI", 0, "SS", MACRO_PopupId},
  805. {"PositionWindow", "PW", 0, "IIUUUS", MACRO_PositionWindow},
  806. {"Prev", NULL, 0, "", MACRO_Prev},
  807. {"Print", NULL, 0, "", MACRO_Print},
  808. {"PrinterSetup", NULL, 0, "", MACRO_PrinterSetup},
  809. {"RegisterRoutine", "RR", 0, "SSS", MACRO_RegisterRoutine},
  810. {"RemoveAccelerator", "RA", 0, "UU", MACRO_RemoveAccelerator},
  811. {"ResetMenu", NULL, 0, "", MACRO_ResetMenu},
  812. {"SaveMark", NULL, 0, "S", MACRO_SaveMark},
  813. {"Search", NULL, 0, "", MACRO_Search},
  814. {"SetContents", NULL, 0, "SU", MACRO_SetContents},
  815. {"SetHelpOnFile", NULL, 0, "S", MACRO_SetHelpOnFile},
  816. {"SetPopupColor", "SPC",0, "UUU", MACRO_SetPopupColor},
  817. {"ShellExecute", "SE", 0, "SSUUSS", MACRO_ShellExecute},
  818. {"ShortCut", "SH", 0, "SSUUS", MACRO_ShortCut},
  819. {"TCard", NULL, 0, "U", MACRO_TCard},
  820. {"Test", NULL, 0, "U", MACRO_Test},
  821. {"TestALink", NULL, 1, "S", MACRO_TestALink},
  822. {"TestKLink", NULL, 1, "S", MACRO_TestKLink},
  823. {"UncheckItem", "UI", 0, "S", MACRO_UncheckItem},
  824. {"UpdateWindow", "UW", 0, "SS", MACRO_UpdateWindow},
  825. {NULL, NULL, 0, NULL, NULL}
  826. };
  827. static int MACRO_DoLookUp(struct MacroDesc* start, const char* name, struct lexret* lr, unsigned len)
  828. {
  829. struct MacroDesc* md;
  830. for (md = start; md->name && len != 0; md++, len--)
  831. {
  832. if (strcasecmp(md->name, name) == 0 || (md->alias != NULL && strcasecmp(md->alias, name) == 0))
  833. {
  834. lr->proto = md->arguments;
  835. lr->function = md->fn;
  836. return md->isBool ? BOOL_FUNCTION : VOID_FUNCTION;
  837. }
  838. }
  839. return EMPTY;
  840. }
  841. int MACRO_Lookup(const char* name, struct lexret* lr)
  842. {
  843. int ret;
  844. if ((ret = MACRO_DoLookUp(MACRO_Builtins, name, lr, -1)) != EMPTY)
  845. return ret;
  846. if (MACRO_Loaded && (ret = MACRO_DoLookUp(MACRO_Loaded, name, lr, MACRO_NumLoaded)) != EMPTY)
  847. return ret;
  848. if (!strcmp(name, "hwndApp"))
  849. {
  850. WINHELP_WINDOW* win;
  851. lr->integer = 0;
  852. for (win = Globals.win_list; win; win = win->next)
  853. {
  854. if (!strcmp(win->info->name, "main"))
  855. {
  856. lr->integer = (LONG_PTR)win->hMainWnd;
  857. break;
  858. }
  859. }
  860. return INTEGER;
  861. }
  862. if (!strcmp(name, "hwndContext"))
  863. {
  864. lr->integer = Globals.active_win ?
  865. (LONG_PTR)Globals.active_win->hMainWnd : 0;
  866. return INTEGER;
  867. }
  868. if (!strcmp(name, "qchPath") || !strcmp(name, "qError") || !strcmp(name, "lTopicNo") ||
  869. !strcmp(name, "hfs") || !strcmp(name, "coForeground") || !strcmp(name, "coBackground"))
  870. {
  871. WINE_FIXME("keyword %s not substituted in macro parsing\n", debugstr_a(name));
  872. return EMPTY;
  873. }
  874. lr->string = name;
  875. return IDENTIFIER;
  876. }