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