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