macro.c 31.8 KB
Newer Older
Alexandre Julliard's avatar
Alexandre Julliard committed
1 2 3 4
/*
 * Help Viewer
 *
 * Copyright 1996 Ulrich Schmid
5
 * Copyright 2002, 2008 Eric Pouech
6 7 8 9 10 11 12 13 14 15 16 17 18
 *
 * 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
19
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
Alexandre Julliard's avatar
Alexandre Julliard committed
20 21
 */

22 23
#define WIN32_LEAN_AND_MEAN

24 25
#include <stdio.h>

Alexandre Julliard's avatar
Alexandre Julliard committed
26 27
#include "windows.h"
#include "commdlg.h"
28
#include "shellapi.h"
Alexandre Julliard's avatar
Alexandre Julliard committed
29 30
#include "winhelp.h"

31 32 33 34
#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(winhelp);

35 36 37 38
/**************************************************/
/*               Macro table                      */
/**************************************************/
struct MacroDesc {
39 40
    const char* name;
    const char* alias;
41
    BOOL        isBool;
42
    const char* arguments;
43
    void       *fn;
44 45 46 47 48
};

static struct MacroDesc*MACRO_Loaded /* = NULL */;
static unsigned         MACRO_NumLoaded /* = 0 */;

49 50
/*******      helper functions     *******/

51 52 53 54 55 56 57 58
static char* StrDup(const char* str)
{
    char* dst;
    dst=HeapAlloc(GetProcessHeap(),0,strlen(str)+1);
    strcpy(dst, str);
    return dst;
}

59
static WINHELP_BUTTON**        MACRO_LookupButton(WINHELP_WINDOW* win, LPCSTR name)
60
{
61
    WINHELP_BUTTON**    b;
62

63
    for (b = &win->first_button; *b; b = &(*b)->next)
64
        if (!lstrcmpiA(name, (*b)->lpszID)) break;
65
    return b;
66 67
}

68 69 70
/******* some forward declarations *******/
static void CALLBACK MACRO_JumpID(LPCSTR lpszPathWindow, LPCSTR topic_id);

71 72 73
/******* real macro implementation *******/

void CALLBACK MACRO_CreateButton(LPCSTR id, LPCSTR name, LPCSTR macro)
74
{
75
    WINHELP_WINDOW *win = MACRO_CurrentWindow();
76 77 78
    WINHELP_BUTTON *button, **b;
    LONG            size;
    LPSTR           ptr;
79

80
    WINE_TRACE("(%s, %s, %s)\n", debugstr_a(id), debugstr_a(name), debugstr_a(macro));
81

82
    size = sizeof(WINHELP_BUTTON) + strlen(id) + strlen(name) + strlen(macro) + 3;
83 84 85 86 87 88 89 90 91

    button = HeapAlloc(GetProcessHeap(), 0, size);
    if (!button) return;

    button->next  = 0;
    button->hWnd  = 0;

    ptr = (char*)button + sizeof(WINHELP_BUTTON);

92
    strcpy(ptr, id);
93
    button->lpszID = ptr;
94
    ptr += strlen(id) + 1;
95

96
    strcpy(ptr, name);
97
    button->lpszName = ptr;
98
    ptr += strlen(name) + 1;
99

100
    strcpy(ptr, macro);
101 102 103 104 105 106 107 108
    button->lpszMacro = ptr;

    button->wParam = WH_FIRST_BUTTON;
    for (b = &win->first_button; *b; b = &(*b)->next)
        button->wParam = max(button->wParam, (*b)->wParam + 1);
    *b = button;

    WINHELP_LayoutMainWindow(win);
109 110
}

111
static void CALLBACK MACRO_DestroyButton(LPCSTR str)
112
{
113
    WINE_FIXME("(%s)\n", debugstr_a(str));
114
}
115

116
void CALLBACK MACRO_DisableButton(LPCSTR id)
117 118 119
{
    WINHELP_BUTTON**    b;

120
    WINE_TRACE("(%s)\n", debugstr_a(id));
121

122
    b = MACRO_LookupButton(MACRO_CurrentWindow(), id);
123
    if (!*b) {WINE_FIXME("Couldn't find button %s\n", debugstr_a(id)); return;}
124 125 126 127

    EnableWindow((*b)->hWnd, FALSE);
}

128
static void CALLBACK MACRO_EnableButton(LPCSTR id)
129 130 131
{
    WINHELP_BUTTON**    b;

132
    WINE_TRACE("(%s)\n", debugstr_a(id));
133

134
    b = MACRO_LookupButton(MACRO_CurrentWindow(), id);
135
    if (!*b) {WINE_FIXME("Couldn't find button %s\n", debugstr_a(id)); return;}
136 137 138 139 140 141 142 143

    EnableWindow((*b)->hWnd, TRUE);
}

void CALLBACK MACRO_JumpContents(LPCSTR lpszPath, LPCSTR lpszWindow)
{
    HLPFILE*    hlpfile;

144
    WINE_TRACE("(%s, %s)\n", debugstr_a(lpszPath), debugstr_a(lpszWindow));
145 146 147 148
    if ((hlpfile = WINHELP_LookupHelpFile(lpszPath)))
        WINHELP_OpenHelpWindow(HLPFILE_PageByHash, hlpfile, 0,
                               WINHELP_GetWindowInfo(hlpfile, lpszWindow),
                               SW_NORMAL);
149 150 151
}


152
void CALLBACK MACRO_About(void)
Alexandre Julliard's avatar
Alexandre Julliard committed
153
{
154 155 156
    WCHAR name[256];
    HICON icon = LoadImageW( Globals.hInstance, MAKEINTRESOURCEW(IDI_WINHELP),
                             IMAGE_ICON, 48, 48, LR_SHARED );
157
    LoadStringW( Globals.hInstance, STID_WINE_HELP, name, ARRAY_SIZE( name ));
158
    ShellAboutW( MACRO_CurrentWindow()->hMainWnd, name, NULL, icon );
Alexandre Julliard's avatar
Alexandre Julliard committed
159 160
}

161
static void CALLBACK MACRO_AddAccelerator(LONG u1, LONG u2, LPCSTR str)
Alexandre Julliard's avatar
Alexandre Julliard committed
162
{
163
    WINE_FIXME("(%u, %u, %s)\n", u1, u2, debugstr_a(str));
Alexandre Julliard's avatar
Alexandre Julliard committed
164 165
}

166
static void CALLBACK MACRO_ALink(LPCSTR str1, LONG u, LPCSTR str2)
Alexandre Julliard's avatar
Alexandre Julliard committed
167
{
168
    WINE_FIXME("(%s, %u, %s)\n", debugstr_a(str1), u, debugstr_a(str2));
Alexandre Julliard's avatar
Alexandre Julliard committed
169 170
}

171
void CALLBACK MACRO_Annotate(void)
Alexandre Julliard's avatar
Alexandre Julliard committed
172
{
173
    WINE_FIXME("()\n");
Alexandre Julliard's avatar
Alexandre Julliard committed
174 175
}

176
static void CALLBACK MACRO_AppendItem(LPCSTR str1, LPCSTR str2, LPCSTR str3, LPCSTR str4)
Alexandre Julliard's avatar
Alexandre Julliard committed
177
{
178
    WINE_FIXME("(%s, %s, %s, %s)\n", debugstr_a(str1), debugstr_a(str2), debugstr_a(str3), debugstr_a(str4));
Alexandre Julliard's avatar
Alexandre Julliard committed
179 180
}

181
static void CALLBACK MACRO_Back(void)
Alexandre Julliard's avatar
Alexandre Julliard committed
182
{
183
    WINHELP_WINDOW* win = MACRO_CurrentWindow();
184 185 186

    WINE_TRACE("()\n");

187
    if (win && win->back.index >= 2)
188
        WINHELP_CreateHelpWindow(&win->back.set[--win->back.index - 1], SW_SHOW, FALSE);
Alexandre Julliard's avatar
Alexandre Julliard committed
189 190
}

191
static void CALLBACK MACRO_BackFlush(void)
Alexandre Julliard's avatar
Alexandre Julliard committed
192
{
193
    WINHELP_WINDOW* win = MACRO_CurrentWindow();
194 195 196

    WINE_TRACE("()\n");

197
    if (win) WINHELP_DeleteBackSet(win);
Alexandre Julliard's avatar
Alexandre Julliard committed
198 199
}

200
void CALLBACK MACRO_BookmarkDefine(void)
Alexandre Julliard's avatar
Alexandre Julliard committed
201
{
202
    WINE_FIXME("()\n");
Alexandre Julliard's avatar
Alexandre Julliard committed
203 204
}

205
static void CALLBACK MACRO_BookmarkMore(void)
Alexandre Julliard's avatar
Alexandre Julliard committed
206
{
207
    WINE_FIXME("()\n");
Alexandre Julliard's avatar
Alexandre Julliard committed
208 209
}

210
static void CALLBACK MACRO_BrowseButtons(void)
Alexandre Julliard's avatar
Alexandre Julliard committed
211
{
212
    HLPFILE_PAGE*       page = MACRO_CurrentWindow()->page;
213
    ULONG               relative;
214

215 216
    WINE_TRACE("()\n");

217 218
    MACRO_CreateButton("BTN_PREV", "&<<", "Prev()");
    MACRO_CreateButton("BTN_NEXT", "&>>", "Next()");
219

220
    if (!HLPFILE_PageByOffset(page->file, page->browse_bwd, &relative))
221
        MACRO_DisableButton("BTN_PREV");
222
    if (!HLPFILE_PageByOffset(page->file, page->browse_fwd, &relative))
223
        MACRO_DisableButton("BTN_NEXT");
Alexandre Julliard's avatar
Alexandre Julliard committed
224 225
}

226
static void CALLBACK MACRO_ChangeButtonBinding(LPCSTR id, LPCSTR macro)
Alexandre Julliard's avatar
Alexandre Julliard committed
227
{
228
    WINHELP_WINDOW*     win = MACRO_CurrentWindow();
229 230 231 232 233
    WINHELP_BUTTON*     button;
    WINHELP_BUTTON**    b;
    LONG                size;
    LPSTR               ptr;

234
    WINE_TRACE("(%s, %s)\n", debugstr_a(id), debugstr_a(macro));
235

236
    b = MACRO_LookupButton(win, id);
237
    if (!*b) {WINE_FIXME("Couldn't find button %s\n", debugstr_a(id)); return;}
238

239 240
    size = sizeof(WINHELP_BUTTON) + strlen(id) +
        strlen((*b)->lpszName) + strlen(macro) + 3;
241 242 243 244 245 246 247 248 249 250

    button = HeapAlloc(GetProcessHeap(), 0, size);
    if (!button) return;

    button->next  = (*b)->next;
    button->hWnd  = (*b)->hWnd;
    button->wParam = (*b)->wParam;

    ptr = (char*)button + sizeof(WINHELP_BUTTON);

251
    strcpy(ptr, id);
252
    button->lpszID = ptr;
253
    ptr += strlen(id) + 1;
254

255
    strcpy(ptr, (*b)->lpszName);
256
    button->lpszName = ptr;
257
    ptr += strlen((*b)->lpszName) + 1;
258

259
    strcpy(ptr, macro);
260 261 262 263
    button->lpszMacro = ptr;

    *b = button;

264
    WINHELP_LayoutMainWindow(win);
Alexandre Julliard's avatar
Alexandre Julliard committed
265 266
}

267
static void CALLBACK MACRO_ChangeEnable(LPCSTR id, LPCSTR macro)
Alexandre Julliard's avatar
Alexandre Julliard committed
268
{
269
    WINE_TRACE("(%s, %s)\n", debugstr_a(id), debugstr_a(macro));
270

271 272
    MACRO_ChangeButtonBinding(id, macro);
    MACRO_EnableButton(id);
Alexandre Julliard's avatar
Alexandre Julliard committed
273 274
}

275
static void CALLBACK MACRO_ChangeItemBinding(LPCSTR str1, LPCSTR str2)
Alexandre Julliard's avatar
Alexandre Julliard committed
276
{
277
    WINE_FIXME("(%s, %s)\n", debugstr_a(str1), debugstr_a(str2));
Alexandre Julliard's avatar
Alexandre Julliard committed
278 279
}

280
static void CALLBACK MACRO_CheckItem(LPCSTR str)
Alexandre Julliard's avatar
Alexandre Julliard committed
281
{
282
    WINE_FIXME("(%s)\n", debugstr_a(str));
Alexandre Julliard's avatar
Alexandre Julliard committed
283 284
}

285
static void CALLBACK MACRO_CloseSecondarys(void)
Alexandre Julliard's avatar
Alexandre Julliard committed
286
{
287
    WINHELP_WINDOW *win;
288
    WINHELP_WINDOW *next;
289 290

    WINE_TRACE("()\n");
291 292 293
    for (win = Globals.win_list; win; win = next)
    {
        next = win->next;
294
        if (lstrcmpiA(win->info->name, "main"))
295
            WINHELP_ReleaseWindow(win);
296
    }
Alexandre Julliard's avatar
Alexandre Julliard committed
297 298
}

299
static void CALLBACK MACRO_CloseWindow(LPCSTR lpszWindow)
Alexandre Julliard's avatar
Alexandre Julliard committed
300
{
301
    WINHELP_WINDOW *win;
302
    WINHELP_WINDOW *next;
303

304
    WINE_TRACE("(%s)\n", debugstr_a(lpszWindow));
305

306
    if (!lpszWindow || !lpszWindow[0]) lpszWindow = "main";
Alexandre Julliard's avatar
Alexandre Julliard committed
307

308 309 310
    for (win = Globals.win_list; win; win = next)
    {
        next = win->next;
311
        if (!lstrcmpiA(win->info->name, lpszWindow))
312
            WINHELP_ReleaseWindow(win);
313
    }
Alexandre Julliard's avatar
Alexandre Julliard committed
314 315
}

316
static void CALLBACK MACRO_Compare(LPCSTR str)
Alexandre Julliard's avatar
Alexandre Julliard committed
317
{
318
    WINE_FIXME("(%s)\n", debugstr_a(str));
Alexandre Julliard's avatar
Alexandre Julliard committed
319 320
}

321
static void CALLBACK MACRO_Contents(void)
Alexandre Julliard's avatar
Alexandre Julliard committed
322
{
323 324
    HLPFILE_PAGE*       page = MACRO_CurrentWindow()->page;

325 326
    WINE_TRACE("()\n");

327 328
    if (page)
        MACRO_JumpContents(page->file->lpszPath, NULL);
Alexandre Julliard's avatar
Alexandre Julliard committed
329 330
}

331
static void CALLBACK MACRO_ControlPanel(LPCSTR str1, LPCSTR str2, LONG u)
Alexandre Julliard's avatar
Alexandre Julliard committed
332
{
333
    WINE_FIXME("(%s, %s, %u)\n", debugstr_a(str1), debugstr_a(str2), u);
Alexandre Julliard's avatar
Alexandre Julliard committed
334 335
}

336
void CALLBACK MACRO_CopyDialog(void)
Alexandre Julliard's avatar
Alexandre Julliard committed
337
{
338
    WINE_FIXME("()\n");
Alexandre Julliard's avatar
Alexandre Julliard committed
339 340
}

341
static void CALLBACK MACRO_CopyTopic(void)
Alexandre Julliard's avatar
Alexandre Julliard committed
342
{
343
    WINE_FIXME("()\n");
Alexandre Julliard's avatar
Alexandre Julliard committed
344 345
}

346
static void CALLBACK MACRO_DeleteItem(LPCSTR str)
Alexandre Julliard's avatar
Alexandre Julliard committed
347
{
348
    WINE_FIXME("(%s)\n", debugstr_a(str));
Alexandre Julliard's avatar
Alexandre Julliard committed
349 350
}

351
static void CALLBACK MACRO_DeleteMark(LPCSTR str)
Alexandre Julliard's avatar
Alexandre Julliard committed
352
{
353
    WINE_FIXME("(%s)\n", debugstr_a(str));
Alexandre Julliard's avatar
Alexandre Julliard committed
354 355
}

356
static void CALLBACK MACRO_DisableItem(LPCSTR str)
Alexandre Julliard's avatar
Alexandre Julliard committed
357
{
358
    WINE_FIXME("(%s)\n", debugstr_a(str));
Alexandre Julliard's avatar
Alexandre Julliard committed
359 360
}

361
static void CALLBACK MACRO_EnableItem(LPCSTR str)
Alexandre Julliard's avatar
Alexandre Julliard committed
362
{
363
    WINE_FIXME("(%s)\n", debugstr_a(str));
Alexandre Julliard's avatar
Alexandre Julliard committed
364 365
}

366
static void CALLBACK MACRO_EndMPrint(void)
Alexandre Julliard's avatar
Alexandre Julliard committed
367
{
368
    WINE_FIXME("()\n");
Alexandre Julliard's avatar
Alexandre Julliard committed
369 370
}

371
static void CALLBACK MACRO_ExecFile(LPCSTR pgm, LPCSTR args, LONG cmd_show, LPCSTR topic)
Alexandre Julliard's avatar
Alexandre Julliard committed
372
{
373 374 375
    HINSTANCE ret;

    WINE_TRACE("(%s, %s, %u, %s)\n",
376
               debugstr_a(pgm), debugstr_a(args), cmd_show, debugstr_a(topic));
377 378 379 380 381 382 383 384

    ret = ShellExecuteA(Globals.active_win ? Globals.active_win->hMainWnd : NULL, "open",
                        pgm, args, ".", cmd_show);
    if ((DWORD_PTR)ret < 32)
    {
        WINE_WARN("Failed with %p\n", ret);
        if (topic) MACRO_JumpID(NULL, topic);
    }
Alexandre Julliard's avatar
Alexandre Julliard committed
385 386
}

387
static void CALLBACK MACRO_ExecProgram(LPCSTR str, LONG u)
Alexandre Julliard's avatar
Alexandre Julliard committed
388
{
389
    WINE_FIXME("(%s, %u)\n", debugstr_a(str), u);
Alexandre Julliard's avatar
Alexandre Julliard committed
390 391
}

392
void CALLBACK MACRO_Exit(void)
Alexandre Julliard's avatar
Alexandre Julliard committed
393
{
394 395
    WINE_TRACE("()\n");

396
    while (Globals.win_list)
397
        WINHELP_ReleaseWindow(Globals.win_list);
Alexandre Julliard's avatar
Alexandre Julliard committed
398 399
}

400
static void CALLBACK MACRO_ExtAbleItem(LPCSTR str, LONG u)
Alexandre Julliard's avatar
Alexandre Julliard committed
401
{
402
    WINE_FIXME("(%s, %u)\n", debugstr_a(str), u);
Alexandre Julliard's avatar
Alexandre Julliard committed
403 404
}

405
static void CALLBACK MACRO_ExtInsertItem(LPCSTR str1, LPCSTR str2, LPCSTR str3, LPCSTR str4, LONG u1, LONG u2)
Alexandre Julliard's avatar
Alexandre Julliard committed
406
{
407
    WINE_FIXME("(%s, %s, %s, %s, %u, %u)\n", debugstr_a(str1), debugstr_a(str2), debugstr_a(str3), debugstr_a(str4), u1, u2);
Alexandre Julliard's avatar
Alexandre Julliard committed
408 409
}

410
static void CALLBACK MACRO_ExtInsertMenu(LPCSTR str1, LPCSTR str2, LPCSTR str3, LONG u1, LONG u2)
Alexandre Julliard's avatar
Alexandre Julliard committed
411
{
412
    WINE_FIXME("(%s, %s, %s, %u, %u)\n", debugstr_a(str1), debugstr_a(str2), debugstr_a(str3), u1, u2);
Alexandre Julliard's avatar
Alexandre Julliard committed
413 414
}

415
static BOOL CALLBACK MACRO_FileExist(LPCSTR str)
Alexandre Julliard's avatar
Alexandre Julliard committed
416
{
417
    WINE_TRACE("(%s)\n", debugstr_a(str));
418
    return GetFileAttributesA(str) != INVALID_FILE_ATTRIBUTES;
Alexandre Julliard's avatar
Alexandre Julliard committed
419 420
}

421
void CALLBACK MACRO_FileOpen(void)
Alexandre Julliard's avatar
Alexandre Julliard committed
422
{
423
    char szFile[MAX_PATH];
Alexandre Julliard's avatar
Alexandre Julliard committed
424

425
    if (WINHELP_GetOpenFileName(szFile, MAX_PATH))
426
    {
427
        MACRO_JumpContents(szFile, "main");
428
    }
Alexandre Julliard's avatar
Alexandre Julliard committed
429 430
}

431
static void CALLBACK MACRO_Find(void)
Alexandre Julliard's avatar
Alexandre Julliard committed
432
{
433
    WINE_FIXME("()\n");
Alexandre Julliard's avatar
Alexandre Julliard committed
434 435
}

436
static void CALLBACK MACRO_Finder(void)
Alexandre Julliard's avatar
Alexandre Julliard committed
437
{
438
    WINHELP_CreateIndexWindow(FALSE);
Alexandre Julliard's avatar
Alexandre Julliard committed
439 440
}

441
static void CALLBACK MACRO_FloatingMenu(void)
Alexandre Julliard's avatar
Alexandre Julliard committed
442
{
443
    WINE_FIXME("()\n");
Alexandre Julliard's avatar
Alexandre Julliard committed
444 445
}

446
static void CALLBACK MACRO_Flush(void)
Alexandre Julliard's avatar
Alexandre Julliard committed
447
{
448
    WINE_FIXME("()\n");
Alexandre Julliard's avatar
Alexandre Julliard committed
449 450
}

451
static void CALLBACK MACRO_FocusWindow(LPCSTR lpszWindow)
Alexandre Julliard's avatar
Alexandre Julliard committed
452
{
453 454
    WINHELP_WINDOW *win;

455
    WINE_TRACE("(%s)\n", debugstr_a(lpszWindow));
456 457 458 459

    if (!lpszWindow || !lpszWindow[0]) lpszWindow = "main";

    for (win = Globals.win_list; win; win = win->next)
460
        if (!lstrcmpiA(win->info->name, lpszWindow))
461
            SetFocus(win->hMainWnd);
Alexandre Julliard's avatar
Alexandre Julliard committed
462 463
}

464
static void CALLBACK MACRO_Generate(LPCSTR str, LONG w, LONG l)
Alexandre Julliard's avatar
Alexandre Julliard committed
465
{
466
    WINE_FIXME("(%s, %x, %x)\n", debugstr_a(str), w, l);
Alexandre Julliard's avatar
Alexandre Julliard committed
467 468
}

469
static void CALLBACK MACRO_GotoMark(LPCSTR str)
Alexandre Julliard's avatar
Alexandre Julliard committed
470
{
471
    WINE_FIXME("(%s)\n", debugstr_a(str));
Alexandre Julliard's avatar
Alexandre Julliard committed
472 473
}

474
void CALLBACK MACRO_HelpOn(void)
Alexandre Julliard's avatar
Alexandre Julliard committed
475
{
476 477
    WINHELP_WINDOW *win = MACRO_CurrentWindow();
    LPCSTR      file = NULL;
478

479
    WINE_TRACE("()\n");
480 481 482
    if (win && win->page && win->page->file)
        file = win->page->file->help_on_file;

483 484 485 486
    if (!file)
        file = (Globals.wVersion > 4) ? "winhlp32.hlp" : "winhelp.hlp";

    MACRO_JumpContents(file, NULL);
Alexandre Julliard's avatar
Alexandre Julliard committed
487 488
}

489
void CALLBACK MACRO_HelpOnTop(void)
Alexandre Julliard's avatar
Alexandre Julliard committed
490
{
491 492 493 494 495 496
    static BOOL on_top = FALSE;
    WINHELP_WINDOW *win;
    HWND main_wnd = NULL;
    HMENU menu;

    for (win = Globals.win_list; win; win = win->next)
497
        if (!lstrcmpiA(win->info->name, "main"))
498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513
            main_wnd = win->hMainWnd;
    if (!main_wnd)
    {
        WINE_ERR("could not find the main window!\n");
        return;
    }
    menu = GetMenu(main_wnd);

    on_top = !on_top;
    if (on_top) {
        CheckMenuItem(menu, MNID_HELP_HELPTOP, MF_BYCOMMAND|MF_CHECKED);
        SetWindowPos(main_wnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);
    } else {
        CheckMenuItem(menu, MNID_HELP_HELPTOP, MF_BYCOMMAND|MF_UNCHECKED);
        SetWindowPos(main_wnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);
    }
Alexandre Julliard's avatar
Alexandre Julliard committed
514 515
}

516
void CALLBACK MACRO_History(void)
Alexandre Julliard's avatar
Alexandre Julliard committed
517
{
518 519 520 521
    WINE_TRACE("()\n");

    if (Globals.active_win && !Globals.active_win->hHistoryWnd)
    {
522
        HWND hWnd = CreateWindowA(HISTORY_WIN_CLASS_NAME, "History", WS_OVERLAPPEDWINDOW,
523 524 525
                                 0, 0, 0, 0, 0, 0, Globals.hInstance, Globals.active_win);
        ShowWindow(hWnd, SW_NORMAL);
    }
526 527
}

528
static void CALLBACK MACRO_IfThen(BOOL b, LPCSTR t)
529
{
530
    if (b) MACRO_ExecuteMacro(MACRO_CurrentWindow(), t);
531 532
}

533
static void CALLBACK MACRO_IfThenElse(BOOL b, LPCSTR t, LPCSTR f)
534
{
535 536
    if (b) MACRO_ExecuteMacro(MACRO_CurrentWindow(), t);
    else MACRO_ExecuteMacro(MACRO_CurrentWindow(), f);
Alexandre Julliard's avatar
Alexandre Julliard committed
537 538
}

539
static BOOL CALLBACK MACRO_InitMPrint(void)
Alexandre Julliard's avatar
Alexandre Julliard committed
540
{
541
    WINE_FIXME("()\n");
542
    return FALSE;
Alexandre Julliard's avatar
Alexandre Julliard committed
543 544
}

545
static void CALLBACK MACRO_InsertItem(LPCSTR str1, LPCSTR str2, LPCSTR str3, LPCSTR str4, LONG u)
Alexandre Julliard's avatar
Alexandre Julliard committed
546
{
547
    WINE_FIXME("(%s, %s, %s, %s, %u)\n", debugstr_a(str1), debugstr_a(str2), debugstr_a(str3), debugstr_a(str4), u);
Alexandre Julliard's avatar
Alexandre Julliard committed
548 549
}

550
static void CALLBACK MACRO_InsertMenu(LPCSTR str1, LPCSTR str2, LONG u)
Alexandre Julliard's avatar
Alexandre Julliard committed
551
{
552
    WINE_FIXME("(%s, %s, %u)\n", debugstr_a(str1), debugstr_a(str2), u);
Alexandre Julliard's avatar
Alexandre Julliard committed
553 554
}

555
static BOOL CALLBACK MACRO_IsBook(void)
Alexandre Julliard's avatar
Alexandre Julliard committed
556
{
557 558
    WINE_TRACE("()\n");
    return Globals.isBook;
Alexandre Julliard's avatar
Alexandre Julliard committed
559 560
}

561
static BOOL CALLBACK MACRO_IsMark(LPCSTR str)
Alexandre Julliard's avatar
Alexandre Julliard committed
562
{
563
    WINE_FIXME("(%s)\n", debugstr_a(str));
564
    return FALSE;
Alexandre Julliard's avatar
Alexandre Julliard committed
565 566
}

567
static BOOL CALLBACK MACRO_IsNotMark(LPCSTR str)
Alexandre Julliard's avatar
Alexandre Julliard committed
568
{
569
    WINE_FIXME("(%s)\n", debugstr_a(str));
570
    return TRUE;
Alexandre Julliard's avatar
Alexandre Julliard committed
571 572
}

573
void CALLBACK MACRO_JumpContext(LPCSTR lpszPath, LPCSTR lpszWindow, LONG context)
Alexandre Julliard's avatar
Alexandre Julliard committed
574
{
575 576
    HLPFILE*    hlpfile;

577
    WINE_TRACE("(%s, %s, %d)\n", debugstr_a(lpszPath), debugstr_a(lpszWindow), context);
578 579 580 581 582
    if ((hlpfile = WINHELP_LookupHelpFile(lpszPath)))
        /* Some madness: what user calls 'context', hlpfile calls 'map' */
        WINHELP_OpenHelpWindow(HLPFILE_PageByMap, hlpfile, context,
                               WINHELP_GetWindowInfo(hlpfile, lpszWindow),
                               SW_NORMAL);
Alexandre Julliard's avatar
Alexandre Julliard committed
583 584
}

585
void CALLBACK MACRO_JumpHash(LPCSTR lpszPath, LPCSTR lpszWindow, LONG lHash)
Alexandre Julliard's avatar
Alexandre Julliard committed
586
{
587 588
    HLPFILE*    hlpfile;

589
    WINE_TRACE("(%s, %s, %u)\n", debugstr_a(lpszPath), debugstr_a(lpszWindow), lHash);
590 591 592 593
    if (!lpszPath || !lpszPath[0])
        hlpfile = MACRO_CurrentWindow()->page->file;
    else
        hlpfile = WINHELP_LookupHelpFile(lpszPath);
594 595 596 597
    if (hlpfile)
        WINHELP_OpenHelpWindow(HLPFILE_PageByHash, hlpfile, lHash,
                               WINHELP_GetWindowInfo(hlpfile, lpszWindow),
                               SW_NORMAL);
Alexandre Julliard's avatar
Alexandre Julliard committed
598 599
}

600
static void CALLBACK MACRO_JumpHelpOn(void)
Alexandre Julliard's avatar
Alexandre Julliard committed
601
{
602
    WINE_FIXME("()\n");
Alexandre Julliard's avatar
Alexandre Julliard committed
603 604
}

605
static void CALLBACK MACRO_JumpID(LPCSTR lpszPathWindow, LPCSTR topic_id)
Alexandre Julliard's avatar
Alexandre Julliard committed
606
{
607 608
    LPSTR       ptr;

609
    WINE_TRACE("(%s, %s)\n", debugstr_a(lpszPathWindow), debugstr_a(topic_id));
610
    if (lpszPathWindow && (ptr = strchr(lpszPathWindow, '>')) != NULL)
611 612
    {
        LPSTR   tmp;
613
        size_t  sz;
614

615
        tmp = HeapAlloc(GetProcessHeap(), 0, strlen(lpszPathWindow) + 1);
616 617
        if (tmp)
        {
618 619 620 621 622 623
            strcpy(tmp, lpszPathWindow);
            tmp[ptr - lpszPathWindow] = '\0';
            ptr += tmp - lpszPathWindow; /* ptr now points to '>' in tmp buffer */
            /* in some cases, we have a trailing space that we need to get rid of */
            /* FIXME: check if it has to be done in lexer rather than here */
            for (sz = strlen(ptr + 1); sz >= 1 && ptr[sz] == ' '; sz--) ptr[sz] = '\0';
624 625 626 627 628 629
            MACRO_JumpHash(tmp, ptr + 1, HLPFILE_Hash(topic_id));
            HeapFree(GetProcessHeap(), 0, tmp);
        }
    }
    else
        MACRO_JumpHash(lpszPathWindow, NULL, HLPFILE_Hash(topic_id));
Alexandre Julliard's avatar
Alexandre Julliard committed
630 631
}

632 633 634
/* FIXME: this macros is wrong
 * it should only contain 2 strings, path & window are coded as path>window
 */
635
static void CALLBACK MACRO_JumpKeyword(LPCSTR lpszPath, LPCSTR lpszWindow, LPCSTR keyword)
Alexandre Julliard's avatar
Alexandre Julliard committed
636
{
637
    WINE_FIXME("(%s, %s, %s)\n", debugstr_a(lpszPath), debugstr_a(lpszWindow), debugstr_a(keyword));
Alexandre Julliard's avatar
Alexandre Julliard committed
638 639
}

640
static void CALLBACK MACRO_KLink(LPCSTR str1, LONG u, LPCSTR str2, LPCSTR str3)
Alexandre Julliard's avatar
Alexandre Julliard committed
641
{
642
    WINE_FIXME("(%s, %u, %s, %s)\n", debugstr_a(str1), u, debugstr_a(str2), debugstr_a(str3));
Alexandre Julliard's avatar
Alexandre Julliard committed
643 644
}

645
static void CALLBACK MACRO_Menu(void)
Alexandre Julliard's avatar
Alexandre Julliard committed
646
{
647
    WINE_FIXME("()\n");
Alexandre Julliard's avatar
Alexandre Julliard committed
648 649
}

650
static void CALLBACK MACRO_MPrintHash(LONG u)
Alexandre Julliard's avatar
Alexandre Julliard committed
651
{
652
    WINE_FIXME("(%u)\n", u);
Alexandre Julliard's avatar
Alexandre Julliard committed
653 654
}

655
static void CALLBACK MACRO_MPrintID(LPCSTR str)
Alexandre Julliard's avatar
Alexandre Julliard committed
656
{
657
    WINE_FIXME("(%s)\n", debugstr_a(str));
Alexandre Julliard's avatar
Alexandre Julliard committed
658 659
}

660
static void CALLBACK MACRO_Next(void)
Alexandre Julliard's avatar
Alexandre Julliard committed
661
{
662
    WINHELP_WNDPAGE     wp;
663

664
    WINE_TRACE("()\n");
665
    wp.page = MACRO_CurrentWindow()->page;
666
    wp.page = HLPFILE_PageByOffset(wp.page->file, wp.page->browse_fwd, &wp.relative);
667
    if (wp.page)
668
    {
669
        wp.page->file->wRefCount++;
670
        wp.wininfo = MACRO_CurrentWindow()->info;
671
        WINHELP_CreateHelpWindow(&wp, SW_NORMAL, TRUE);
672
    }
Alexandre Julliard's avatar
Alexandre Julliard committed
673 674
}

675
static void CALLBACK MACRO_NoShow(void)
Alexandre Julliard's avatar
Alexandre Julliard committed
676
{
677
    WINE_FIXME("()\n");
Alexandre Julliard's avatar
Alexandre Julliard committed
678 679
}

680
void CALLBACK MACRO_PopupContext(LPCSTR str, LONG u)
Alexandre Julliard's avatar
Alexandre Julliard committed
681
{
682
    WINE_FIXME("(%s, %u)\n", debugstr_a(str), u);
Alexandre Julliard's avatar
Alexandre Julliard committed
683 684
}

685
static void CALLBACK MACRO_PopupHash(LPCSTR str, LONG u)
Alexandre Julliard's avatar
Alexandre Julliard committed
686
{
687
    WINE_FIXME("(%s, %u)\n", debugstr_a(str), u);
Alexandre Julliard's avatar
Alexandre Julliard committed
688 689
}

690
static void CALLBACK MACRO_PopupId(LPCSTR str1, LPCSTR str2)
Alexandre Julliard's avatar
Alexandre Julliard committed
691
{
692
    WINE_FIXME("(%s, %s)\n", debugstr_a(str1), debugstr_a(str2));
Alexandre Julliard's avatar
Alexandre Julliard committed
693 694
}

695
static void CALLBACK MACRO_PositionWindow(LONG i1, LONG i2, LONG u1, LONG u2, LONG u3, LPCSTR str)
Alexandre Julliard's avatar
Alexandre Julliard committed
696
{
697
    WINE_FIXME("(%i, %i, %u, %u, %u, %s)\n", i1, i2, u1, u2, u3, debugstr_a(str));
Alexandre Julliard's avatar
Alexandre Julliard committed
698 699
}

700
static void CALLBACK MACRO_Prev(void)
Alexandre Julliard's avatar
Alexandre Julliard committed
701
{
702
    WINHELP_WNDPAGE     wp;
703

704
    WINE_TRACE("()\n");
705
    wp.page = MACRO_CurrentWindow()->page;
706
    wp.page = HLPFILE_PageByOffset(wp.page->file, wp.page->browse_bwd, &wp.relative);
707
    if (wp.page)
708
    {
709
        wp.page->file->wRefCount++;
710
        wp.wininfo = MACRO_CurrentWindow()->info;
711
        WINHELP_CreateHelpWindow(&wp, SW_NORMAL, TRUE);
712
    }
Alexandre Julliard's avatar
Alexandre Julliard committed
713 714
}

715
void CALLBACK MACRO_Print(void)
Alexandre Julliard's avatar
Alexandre Julliard committed
716
{
717
    PRINTDLGW printer;
718

719 720
    WINE_TRACE("()\n");

Alexandre Julliard's avatar
Alexandre Julliard committed
721
    printer.lStructSize         = sizeof(printer);
722
    printer.hwndOwner           = MACRO_CurrentWindow()->hMainWnd;
Alexandre Julliard's avatar
Alexandre Julliard committed
723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739
    printer.hInstance           = Globals.hInstance;
    printer.hDevMode            = 0;
    printer.hDevNames           = 0;
    printer.hDC                 = 0;
    printer.Flags               = 0;
    printer.nFromPage           = 0;
    printer.nToPage             = 0;
    printer.nMinPage            = 0;
    printer.nMaxPage            = 0;
    printer.nCopies             = 0;
    printer.lCustData           = 0;
    printer.lpfnPrintHook       = 0;
    printer.lpfnSetupHook       = 0;
    printer.lpPrintTemplateName = 0;
    printer.lpSetupTemplateName = 0;
    printer.hPrintTemplate      = 0;
    printer.hSetupTemplate      = 0;
740

741
    if (PrintDlgW(&printer)) {
742 743
        WINE_FIXME("Print()\n");
    }
Alexandre Julliard's avatar
Alexandre Julliard committed
744 745
}

746
void CALLBACK MACRO_PrinterSetup(void)
Alexandre Julliard's avatar
Alexandre Julliard committed
747
{
748
    WINE_FIXME("()\n");
Alexandre Julliard's avatar
Alexandre Julliard committed
749 750
}

751
static void CALLBACK MACRO_RegisterRoutine(LPCSTR dll_name, LPCSTR proc, LPCSTR args)
Alexandre Julliard's avatar
Alexandre Julliard committed
752
{
753
    void               *fn = NULL;
754 755
    int                 size;
    WINHELP_DLL*        dll;
756

757
    WINE_TRACE("(%s, %s, %s)\n", debugstr_a(dll_name), debugstr_a(proc), debugstr_a(args));
758

759 760 761 762
    /* FIXME: are the registered DLLs global or linked to the current file ???
     * We assume globals (as we did for macros, but is this really the case ???)
     */
    for (dll = Globals.dlls; dll; dll = dll->next)
763
    {
764 765 766 767
        if (!strcmp(dll->name, dll_name)) break;
    }
    if (!dll)
    {
768
        HANDLE hLib = LoadLibraryA(dll_name);
769 770 771 772

        /* FIXME: the library will not be unloaded until exit of program 
         * We don't send the DW_TERM message
         */
773
        WINE_TRACE("Loading %s\n", debugstr_a(dll_name));
774 775 776 777 778 779
        /* FIXME: should look in the directory where current hlpfile
         * is loaded from
         */
        if (hLib == NULL)
        {
            /* FIXME: internationalisation for error messages */
780
            WINE_FIXME("Cannot find dll %s\n", debugstr_a(dll_name));
781 782 783 784
        }
        else if ((dll = HeapAlloc(GetProcessHeap(), 0, sizeof(*dll))))
        {
            dll->hLib = hLib;
785
            dll->name = StrDup(dll_name); /* FIXME: never freed */
786 787 788 789
            dll->next = Globals.dlls;
            Globals.dlls = dll;
            dll->handler = (WINHELP_LDLLHandler)GetProcAddress(dll->hLib, "LDLLHandler");
            dll->class = dll->handler ? (dll->handler)(DW_WHATMSG, 0, 0) : DC_NOMSG;
790
            WINE_TRACE("Got class %x for DLL %s\n", dll->class, debugstr_a(dll_name));
791
            if (dll->class & DC_INITTERM) dll->handler(DW_INIT, 0, 0);
792
            if (dll->class & DC_CALLBACKS) dll->handler(DW_CALLBACKS, (LONG_PTR)&Callbacks, 0);
793 794
        }
        else WINE_WARN("OOM\n");
795
    }
796
    if (dll && !(fn = GetProcAddress(dll->hLib, proc)))
797 798
    {
        /* FIXME: internationalisation for error messages */
799
        WINE_FIXME("Cannot find proc %s in dll %s\n", debugstr_a(dll_name), debugstr_a(proc));
800 801
    }

802 803 804
    size = ++MACRO_NumLoaded * sizeof(struct MacroDesc);
    if (!MACRO_Loaded) MACRO_Loaded = HeapAlloc(GetProcessHeap(), 0, size);
    else MACRO_Loaded = HeapReAlloc(GetProcessHeap(), 0, MACRO_Loaded, size);
805
    MACRO_Loaded[MACRO_NumLoaded - 1].name      = StrDup(proc); /* FIXME: never freed */
806
    MACRO_Loaded[MACRO_NumLoaded - 1].alias     = NULL;
807
    MACRO_Loaded[MACRO_NumLoaded - 1].isBool    = FALSE;
808
    MACRO_Loaded[MACRO_NumLoaded - 1].arguments = StrDup(args); /* FIXME: never freed */
809
    MACRO_Loaded[MACRO_NumLoaded - 1].fn        = fn;
810
    WINE_TRACE("Added %s(%s) at %p\n", debugstr_a(proc), debugstr_a(args), fn);
Alexandre Julliard's avatar
Alexandre Julliard committed
811 812
}

813
static void CALLBACK MACRO_RemoveAccelerator(LONG u1, LONG u2)
Alexandre Julliard's avatar
Alexandre Julliard committed
814
{
815
    WINE_FIXME("(%u, %u)\n", u1, u2);
Alexandre Julliard's avatar
Alexandre Julliard committed
816 817
}

818
static void CALLBACK MACRO_ResetMenu(void)
Alexandre Julliard's avatar
Alexandre Julliard committed
819
{
820
    WINE_FIXME("()\n");
Alexandre Julliard's avatar
Alexandre Julliard committed
821 822
}

823
static void CALLBACK MACRO_SaveMark(LPCSTR str)
Alexandre Julliard's avatar
Alexandre Julliard committed
824
{
825
    WINE_FIXME("(%s)\n", debugstr_a(str));
Alexandre Julliard's avatar
Alexandre Julliard committed
826 827
}

828
static void CALLBACK MACRO_Search(void)
Alexandre Julliard's avatar
Alexandre Julliard committed
829
{
830
    WINHELP_CreateIndexWindow(TRUE);
Alexandre Julliard's avatar
Alexandre Julliard committed
831 832
}

833
void CALLBACK MACRO_SetContents(LPCSTR str, LONG u)
Alexandre Julliard's avatar
Alexandre Julliard committed
834
{
835
    WINE_FIXME("(%s, %u)\n", debugstr_a(str), u);
Alexandre Julliard's avatar
Alexandre Julliard committed
836 837
}

838
static void CALLBACK MACRO_SetHelpOnFile(LPCSTR str)
Alexandre Julliard's avatar
Alexandre Julliard committed
839
{
840 841
    HLPFILE_PAGE*       page = MACRO_CurrentWindow()->page;

842
    WINE_TRACE("(%s)\n", debugstr_a(str));
843

844 845 846 847
    HeapFree(GetProcessHeap(), 0, page->file->help_on_file);
    page->file->help_on_file = HeapAlloc(GetProcessHeap(), 0, strlen(str) + 1);
    if (page->file->help_on_file)
        strcpy(page->file->help_on_file, str);
Alexandre Julliard's avatar
Alexandre Julliard committed
848 849
}

850
static void CALLBACK MACRO_SetPopupColor(LONG r, LONG g, LONG b)
Alexandre Julliard's avatar
Alexandre Julliard committed
851
{
852 853
    HLPFILE_PAGE*       page = MACRO_CurrentWindow()->page;

854
    WINE_TRACE("(%x, %x, %x)\n", r, g, b);
855 856
    page->file->has_popup_color = TRUE;
    page->file->popup_color = RGB(r, g, b);
Alexandre Julliard's avatar
Alexandre Julliard committed
857 858
}

859
static void CALLBACK MACRO_ShellExecute(LPCSTR str1, LPCSTR str2, LONG u1, LONG u2, LPCSTR str3, LPCSTR str4)
Alexandre Julliard's avatar
Alexandre Julliard committed
860
{
861
    WINE_FIXME("(%s, %s, %u, %u, %s, %s)\n", debugstr_a(str1), debugstr_a(str2), u1, u2, debugstr_a(str3), debugstr_a(str4));
Alexandre Julliard's avatar
Alexandre Julliard committed
862 863
}

864
static void CALLBACK MACRO_ShortCut(LPCSTR str1, LPCSTR str2, LONG w, LONG l, LPCSTR str)
Alexandre Julliard's avatar
Alexandre Julliard committed
865
{
866
    WINE_FIXME("(%s, %s, %x, %x, %s)\n", debugstr_a(str1), debugstr_a(str2), w, l, debugstr_a(str));
Alexandre Julliard's avatar
Alexandre Julliard committed
867 868
}

869
static void CALLBACK MACRO_TCard(LONG u)
Alexandre Julliard's avatar
Alexandre Julliard committed
870
{
871
    WINE_FIXME("(%u)\n", u);
Alexandre Julliard's avatar
Alexandre Julliard committed
872 873
}

874
static void CALLBACK MACRO_Test(LONG u)
Alexandre Julliard's avatar
Alexandre Julliard committed
875
{
876
    WINE_FIXME("(%u)\n", u);
Alexandre Julliard's avatar
Alexandre Julliard committed
877 878
}

879
static BOOL CALLBACK MACRO_TestALink(LPCSTR str)
Alexandre Julliard's avatar
Alexandre Julliard committed
880
{
881
    WINE_FIXME("(%s)\n", debugstr_a(str));
882
    return FALSE;
Alexandre Julliard's avatar
Alexandre Julliard committed
883 884
}

885
static BOOL CALLBACK MACRO_TestKLink(LPCSTR str)
Alexandre Julliard's avatar
Alexandre Julliard committed
886
{
887
    WINE_FIXME("(%s)\n", debugstr_a(str));
888
    return FALSE;
Alexandre Julliard's avatar
Alexandre Julliard committed
889 890
}

891
static void CALLBACK MACRO_UncheckItem(LPCSTR str)
Alexandre Julliard's avatar
Alexandre Julliard committed
892
{
893
    WINE_FIXME("(%s)\n", debugstr_a(str));
Alexandre Julliard's avatar
Alexandre Julliard committed
894 895
}

896
static void CALLBACK MACRO_UpdateWindow(LPCSTR str1, LPCSTR str2)
Alexandre Julliard's avatar
Alexandre Julliard committed
897
{
898
    WINE_FIXME("(%s, %s)\n", debugstr_a(str1), debugstr_a(str2));
Alexandre Julliard's avatar
Alexandre Julliard committed
899
}
900 901 902 903 904 905 906 907 908 909 910 911 912 913


/**************************************************/
/*               Macro table                      */
/**************************************************/

/* types:
 *      U:      32 bit unsigned int
 *      I:      32 bit signed int
 *      S:      string
 *      v:      unknown (32 bit entity)
 */

static struct MacroDesc MACRO_Builtins[] = {
914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004
    {"About",               NULL, 0, "",       MACRO_About},
    {"AddAccelerator",      "AA", 0, "UUS",    MACRO_AddAccelerator},
    {"ALink",               "AL", 0, "SUS",    MACRO_ALink},
    {"Annotate",            NULL, 0, "",       MACRO_Annotate},
    {"AppendItem",          NULL, 0, "SSSS",   MACRO_AppendItem},
    {"Back",                NULL, 0, "",       MACRO_Back},
    {"BackFlush",           "BF", 0, "",       MACRO_BackFlush},
    {"BookmarkDefine",      NULL, 0, "",       MACRO_BookmarkDefine},
    {"BookmarkMore",        NULL, 0, "",       MACRO_BookmarkMore},
    {"BrowseButtons",       NULL, 0, "",       MACRO_BrowseButtons},
    {"ChangeButtonBinding", "CBB",0, "SS",     MACRO_ChangeButtonBinding},
    {"ChangeEnable",        "CE", 0, "SS",     MACRO_ChangeEnable},
    {"ChangeItemBinding",   "CIB",0, "SS",     MACRO_ChangeItemBinding},
    {"CheckItem",           "CI", 0, "S",      MACRO_CheckItem},
    {"CloseSecondarys",     "CS", 0, "",       MACRO_CloseSecondarys},
    {"CloseWindow",         "CW", 0, "S",      MACRO_CloseWindow},
    {"Compare",             NULL, 0, "S",      MACRO_Compare},
    {"Contents",            NULL, 0, "",       MACRO_Contents},
    {"ControlPanel",        NULL, 0, "SSU",    MACRO_ControlPanel},
    {"CopyDialog",          NULL, 0, "",       MACRO_CopyDialog},
    {"CopyTopic",           "CT", 0, "",       MACRO_CopyTopic},
    {"CreateButton",        "CB", 0, "SSS",    MACRO_CreateButton},
    {"DeleteItem",          NULL, 0, "S",      MACRO_DeleteItem},
    {"DeleteMark",          NULL, 0, "S",      MACRO_DeleteMark},
    {"DestroyButton",       NULL, 0, "S",      MACRO_DestroyButton},
    {"DisableButton",       "DB", 0, "S",      MACRO_DisableButton},
    {"DisableItem",         "DI", 0, "S",      MACRO_DisableItem},
    {"EnableButton",        "EB", 0, "S",      MACRO_EnableButton},
    {"EnableItem",          "EI", 0, "S",      MACRO_EnableItem},
    {"EndMPrint",           NULL, 0, "",       MACRO_EndMPrint},
    {"ExecFile",            "EF", 0, "SSUS",   MACRO_ExecFile},
    {"ExecProgram",         "EP", 0, "SU",     MACRO_ExecProgram},
    {"Exit",                NULL, 0, "",       MACRO_Exit},
    {"ExtAbleItem",         NULL, 0, "SU",     MACRO_ExtAbleItem},
    {"ExtInsertItem",       NULL, 0, "SSSSUU", MACRO_ExtInsertItem},
    {"ExtInsertMenu",       NULL, 0, "SSSUU",  MACRO_ExtInsertMenu},
    {"FileExist",           "FE", 1, "S",      MACRO_FileExist},
    {"FileOpen",            "FO", 0, "",       MACRO_FileOpen},
    {"Find",                NULL, 0, "",       MACRO_Find},
    {"Finder",              "FD", 0, "",       MACRO_Finder},
    {"FloatingMenu",        NULL, 0, "",       MACRO_FloatingMenu},
    {"Flush",               "FH", 0, "",       MACRO_Flush},
    {"FocusWindow",         NULL, 0, "S",      MACRO_FocusWindow},
    {"Generate",            NULL, 0, "SUU",    MACRO_Generate},
    {"GotoMark",            NULL, 0, "S",      MACRO_GotoMark},
    {"HelpOn",              NULL, 0, "",       MACRO_HelpOn},
    {"HelpOnTop",           NULL, 0, "",       MACRO_HelpOnTop},
    {"History",             NULL, 0, "",       MACRO_History},
    {"InitMPrint",          NULL, 1, "",       MACRO_InitMPrint},
    {"InsertItem",          NULL, 0, "SSSSU",  MACRO_InsertItem},
    {"InsertMenu",          NULL, 0, "SSU",    MACRO_InsertMenu},
    {"IfThen",              "IF", 0, "BS",     MACRO_IfThen},
    {"IfThenElse",          "IE", 0, "BSS",    MACRO_IfThenElse},
    {"IsBook",              NULL, 1, "",       MACRO_IsBook},
    {"IsMark",              NULL, 1, "S",      MACRO_IsMark},
    {"IsNotMark",           "NM", 1, "S",      MACRO_IsNotMark},
    {"JumpContents",        NULL, 0, "SS",     MACRO_JumpContents},
    {"JumpContext",         "JC", 0, "SSU",    MACRO_JumpContext},
    {"JumpHash",            "JH", 0, "SSU",    MACRO_JumpHash},
    {"JumpHelpOn",          NULL, 0, "",       MACRO_JumpHelpOn},
    {"JumpID",              "JI", 0, "SS",     MACRO_JumpID},
    {"JumpKeyword",         "JK", 0, "SSS",    MACRO_JumpKeyword},
    {"KLink",               "KL", 0, "SUSS",   MACRO_KLink},
    {"Menu",                "MU", 0, "",       MACRO_Menu},
    {"MPrintHash",          NULL, 0, "U",      MACRO_MPrintHash},
    {"MPrintID",            NULL, 0, "S",      MACRO_MPrintID},
    {"Next",                NULL, 0, "",       MACRO_Next},
    {"NoShow",              "NS", 0, "",       MACRO_NoShow},
    {"PopupContext",        "PC", 0, "SU",     MACRO_PopupContext},
    {"PopupHash",           NULL, 0, "SU",     MACRO_PopupHash},
    {"PopupId",             "PI", 0, "SS",     MACRO_PopupId},
    {"PositionWindow",      "PW", 0, "IIUUUS", MACRO_PositionWindow},
    {"Prev",                NULL, 0, "",       MACRO_Prev},
    {"Print",               NULL, 0, "",       MACRO_Print},
    {"PrinterSetup",        NULL, 0, "",       MACRO_PrinterSetup},
    {"RegisterRoutine",     "RR", 0, "SSS",    MACRO_RegisterRoutine},
    {"RemoveAccelerator",   "RA", 0, "UU",     MACRO_RemoveAccelerator},
    {"ResetMenu",           NULL, 0, "",       MACRO_ResetMenu},
    {"SaveMark",            NULL, 0, "S",      MACRO_SaveMark},
    {"Search",              NULL, 0, "",       MACRO_Search},
    {"SetContents",         NULL, 0, "SU",     MACRO_SetContents},
    {"SetHelpOnFile",       NULL, 0, "S",      MACRO_SetHelpOnFile},
    {"SetPopupColor",       "SPC",0, "UUU",    MACRO_SetPopupColor},
    {"ShellExecute",        "SE", 0, "SSUUSS", MACRO_ShellExecute},
    {"ShortCut",            "SH", 0, "SSUUS",  MACRO_ShortCut},
    {"TCard",               NULL, 0, "U",      MACRO_TCard},
    {"Test",                NULL, 0, "U",      MACRO_Test},
    {"TestALink",           NULL, 1, "S",      MACRO_TestALink},
    {"TestKLink",           NULL, 1, "S",      MACRO_TestKLink},
    {"UncheckItem",         "UI", 0, "S",      MACRO_UncheckItem},
    {"UpdateWindow",        "UW", 0, "SS",     MACRO_UpdateWindow},
1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031
    {NULL,                  NULL, 0, NULL,     NULL}
};

static int MACRO_DoLookUp(struct MacroDesc* start, const char* name, struct lexret* lr, unsigned len)
{
    struct MacroDesc*   md;

    for (md = start; md->name && len != 0; md++, len--)
    {
        if (strcasecmp(md->name, name) == 0 || (md->alias != NULL && strcasecmp(md->alias, name) == 0))
        {
            lr->proto = md->arguments;
            lr->function = md->fn;
            return md->isBool ? BOOL_FUNCTION : VOID_FUNCTION;
        }
    }
    return EMPTY;
}

int MACRO_Lookup(const char* name, struct lexret* lr)
{
    int ret;

    if ((ret = MACRO_DoLookUp(MACRO_Builtins, name, lr, -1)) != EMPTY)
        return ret;
    if (MACRO_Loaded && (ret = MACRO_DoLookUp(MACRO_Loaded, name, lr, MACRO_NumLoaded)) != EMPTY)
        return ret;
1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054
    if (!strcmp(name, "hwndApp"))
    {
        WINHELP_WINDOW* win;
        lr->integer = 0;
        for (win = Globals.win_list; win; win = win->next)
        {
            if (!strcmp(win->info->name, "main"))
            {
                lr->integer = (LONG_PTR)win->hMainWnd;
                break;
            }
        }
        return INTEGER;
    }
    if (!strcmp(name, "hwndContext"))
    {
        lr->integer = Globals.active_win ?
            (LONG_PTR)Globals.active_win->hMainWnd : 0;
        return INTEGER;
    }
    if (!strcmp(name, "qchPath") || !strcmp(name, "qError") || !strcmp(name, "lTopicNo") ||
        !strcmp(name, "hfs") || !strcmp(name, "coForeground") || !strcmp(name, "coBackground"))
    {
1055
        WINE_FIXME("keyword %s not substituted in macro parsing\n", debugstr_a(name));
1056 1057
        return EMPTY;
    }
1058 1059 1060 1061

    lr->string = name;
    return IDENTIFIER;
}