source: branches/2.20_branch/hlpmgr/helpmgr.c@ 429

Last change on this file since 429 was 365, checked in by RBRi, 16 years ago

format updates

  • Property svn:eol-style set to native
File size: 36.9 KB
Line 
1// Standard library
2#include <string.h>
3#include <stdlib.h>
4#include <stdio.h>
5
6// Local
7#include "utility.h"
8#include "Viewer.h"
9#include "log.h"
10#include "messages.h"
11#include "HelpTables.h"
12#include "SharedMemory.h"
13#include "HelpInstance.h"
14
15#if __WATCOMC__>=1200
16
17 /*** HK_HELP Help modes **********************************************/
18 #define HLPM_FRAME (-1)
19 #define HLPM_WINDOW (-2)
20 #define HLPM_MENU (-3)
21
22#endif
23
24//--------------------------------------------------------------------------------
25// Constants
26//--------------------------------------------------------------------------------
27
28char* HelpMgrVersion = "V1.9.1"; // $SS_REQUIRE_NEW_VERSION$
29#define BldLevelVersion "1.9.1"
30
31// Embedded BLDLevel compatible version
32#define Vendor "Aaron Lawrence"
33#define Description "NewView"
34
35char* EmbeddedVersion = "@#" Vendor ":" BldLevelVersion "#@" Description;
36
37//--------------------------------------------------------------------------------
38
39#define MAX_HELP_INSTANCES 100
40#define SHARED_MEM_SIZE 16000
41#define SHARED_MEM_RESERVE_SIZE 256
42#define SHARED_MEM_NAME "NEWVIEW"
43
44char* szNewHelpManagerClass = "NewHelpMgr";
45
46//--------------------------------------------------------------------------------
47// Types
48//--------------------------------------------------------------------------------
49
50typedef struct
51{
52 char Title[ 32 ];
53 char Version[ 32 ];
54} TNewHelpMgrSharedStruct;
55
56//--------------------------------------------------------------------------------
57// Global variables
58//--------------------------------------------------------------------------------
59
60TPHelpInstance g_pHelpInstances[ MAX_HELP_INSTANCES ] = { NULL };
61int g_HelpInstanceCount = 0;
62
63//
64
65MRESULT APIENTRY HelpManagerWndProc( HWND hwnd,
66 ULONG msg,
67 MPARAM mp1,
68 MPARAM mp2 );
69
70BOOL APIENTRY HelpHook( HAB hab,
71 ULONG ulMode,
72 ULONG ulControlID,
73 ULONG ulChildControlID,
74 PRECTL prcPosition );
75
76
77// Find if there is a help instance associated with
78// this window
79//--------------------------------------------------------------------------------
80TPHelpInstance GetAssociatedHelpInstance( HWND hwnd )
81{
82 int i;
83 TPHelpInstance pHelpInstance;
84
85 LogEvent( " GetAssociatedHelpInstance" );
86
87 for ( i = 0; i < MAX_HELP_INSTANCES; i ++ )
88 {
89 pHelpInstance = g_pHelpInstances[ i ];
90 if ( pHelpInstance != NULL )
91 {
92 LogEvent( " Instance %d: %8x", i, pHelpInstance );
93 if ( IsWindowAssociated( pHelpInstance,
94 hwnd ) )
95 {
96 LogEvent( " Found associated window" );
97 return pHelpInstance;
98 }
99 }
100 }
101
102 return NULL;
103}
104
105// Find if there is a help instance associated with
106// this window or any of it's parents or owners
107//--------------------------------------------------------------------------------
108TPHelpInstance GetHelpInstanceForWindowChain( HWND hwndApp )
109{
110 HWND parentOrOwner;
111 HWND hDesktopWindow;
112 HWND hwnd;
113 HWND hClientWnd;
114 TPHelpInstance pHelpInstance;
115 LONG SearchType;
116
117 LogEvent( "QueryHelpInstance" );
118
119 hDesktopWindow = WinQueryDesktopWindow( WinQueryAnchorBlock( hwndApp ),
120 NULLHANDLE );
121
122 SearchType = QW_PARENT;
123 hwnd = hwndApp;
124 while( TRUE )
125 {
126 LogEvent( " hwnd: %8x", hwnd );
127 pHelpInstance = GetAssociatedHelpInstance( hwnd );
128 if ( pHelpInstance )
129 {
130 LogEvent( " Found help instance: %8x", pHelpInstance );
131 return pHelpInstance;
132 }
133
134 LogEvent( " Check if frame" );
135 if ( IsStandardWindowClass( hwnd, WC_FRAME ) )
136 {
137 LogEvent( " This is a frame window" );
138 hClientWnd = WinWindowFromID( hwnd, FID_CLIENT );
139 if ( hClientWnd != NULLHANDLE )
140 {
141 LogEvent( " Got client window: %8x", hClientWnd );
142 pHelpInstance = GetAssociatedHelpInstance( hClientWnd );
143 if ( pHelpInstance )
144 {
145 LogEvent( " Found help instance: %8x", pHelpInstance );
146 return pHelpInstance;
147 }
148 }
149 else
150 {
151 LogEvent( " No client window found" );
152 }
153 }
154
155 LogEvent( " No help instance" );
156
157 parentOrOwner = WinQueryWindow( hwnd, SearchType );
158 if ( parentOrOwner == hDesktopWindow
159 || parentOrOwner == NULLHANDLE )
160 {
161 // swap to other search
162 if ( SearchType == QW_PARENT )
163 {
164 LogEvent( " Search by owner" );
165 SearchType = QW_OWNER;
166 }
167 else
168 {
169 LogEvent( " Search by parent" );
170 SearchType = QW_PARENT;
171 }
172
173 parentOrOwner = WinQueryWindow( hwnd, SearchType );
174 if ( parentOrOwner == hDesktopWindow
175 || parentOrOwner == NULLHANDLE )
176 // the other relation is also the desktop, so stop.
177 {
178 break;
179 }
180 }
181 hwnd = parentOrOwner;
182 }
183
184 LogEvent( " No help instance found" );
185 return NULL;
186}
187
188//--------------------------------------------------------------------------------
189// 32 bit entry points
190//--------------------------------------------------------------------------------
191
192HWND APIENTRY NHM32CreateHelpInstance( HAB hab,
193 PHELPINIT phinitHMInitStructure )
194{
195 BOOL FoundUnusedSlot;
196 ULONG HelpTable;
197 USHORT idHelpTable;
198 APIRET rc;
199 int i;
200 TPHelpInstance pHelpInstance;
201 TNewHelpMgrSharedStruct* pSharedStruct;
202
203 LogEvent( "--------------------------------------------------" );
204 LogEvent( "NHM32CreateHelpInstance" );
205 LogEvent( " Help Manager Version: %s", HelpMgrVersion );
206 LogEvent( " Filename(s): %s", phinitHMInitStructure -> pszHelpLibraryName );
207 LogEvent( " Title: %s", phinitHMInitStructure -> pszHelpWindowTitle );
208
209 pHelpInstance = MakeNewHelpInstance();
210
211 // find blank slot in help instance array
212 FoundUnusedSlot = FALSE;
213 for ( i = 0; i < MAX_HELP_INSTANCES; i ++ )
214 {
215 if ( g_pHelpInstances[ i ] == NULL )
216 {
217 g_pHelpInstances[ i ] = pHelpInstance;
218 FoundUnusedSlot = TRUE;
219 break;
220 }
221 }
222 if ( ! FoundUnusedSlot )
223 {
224 LogEvent( "Too many help instances, out of slots" );
225 return NULLHANDLE;
226 }
227
228 g_HelpInstanceCount ++;
229
230 pHelpInstance -> Fhab = hab;
231
232 // Register help window class.
233 if ( ! WinRegisterClass( hab, // anchor block
234 szNewHelpManagerClass, // class name
235 HelpManagerWndProc, // window proceedure
236 0, // no special style
237 8 ) ) // space for instance ptr and magic number
238 {
239 rc = WinGetLastError( hab );
240 LogEvent( "WinRegisterClass failed, error=%d", rc );
241 return NULLHANDLE;
242 }
243
244 LogEvent( "Registered Window Class OK" );
245
246 // Create help window as an object window (child of HWND_OBJECT)
247 pHelpInstance -> FHandle =
248 WinCreateWindow( HWND_OBJECT, // parent: object window
249 szNewHelpManagerClass, // window class
250 "New Help Manager", // window title - irrelevant
251 0, // style: none (note: invisible)
252 0, 0, 10, 10, // left/bottom/width/height - irrelevant
253 HWND_OBJECT, // owner: object window
254 HWND_BOTTOM, // zorder - irrelevant
255 1, // id - irrelevant
256 NULL, // control data - none
257 NULL ); // presentation parameters - none
258
259 if ( pHelpInstance -> FHandle == NULLHANDLE )
260 {
261 rc = WinGetLastError( hab );
262 LogEvent( "WinCreateWindow failed, error=%d", rc );
263 return NULLHANDLE;
264 }
265 LogEvent( "Created Help Window OK" );
266
267 // store instance pointer and magic number for checking later.
268 // Could just have used class name!
269 WinSetWindowULong( pHelpInstance -> FHandle,
270 QWL_HELPINSTANCEMAGICNUMBER,
271 HELPINSTANCEMAGICNUMBER );
272 WinSetWindowULong( pHelpInstance -> FHandle,
273 QWL_HELPINSTANCEPTR,
274 (ULONG) pHelpInstance );
275
276 LogEvent( "Stored magic number and instance ptr OK" );
277
278 // Copy filename(s), if given
279 StoreString( & pHelpInstance -> FHelpFileNames,
280 phinitHMInitStructure -> pszHelpLibraryName );
281
282 // Copy help window title, if given
283 StoreString( & pHelpInstance -> FHelpWindowTitle,
284 phinitHMInitStructure -> pszHelpWindowTitle );
285
286 LogEvent( "Setting hook" );
287
288 // set hook for catching F1 keypresses & help buttons
289 if ( ! WinSetHook( hab, // Anchor block
290 HMQ_CURRENT, // Message queue: this app's queue
291 HK_HELP, // Hook type: help
292 (PFN) & HelpHook, // Help hook function
293 0 ) ) // Module containing hook function
294 {
295 rc = WinGetLastError( hab );
296 LogEvent( "WinSetHook failed, error=%d", rc );
297 return NULLHANDLE;
298 }
299
300 // load help table if specified
301 HelpTable = (ULONG) phinitHMInitStructure -> phtHelpTable;
302 LogEvent( "HelpTable: %8x", HelpTable );
303
304 pHelpInstance -> HelpTableFromResource = FALSE;
305
306 if ( HelpTable != 0 )
307 {
308 if ( ( HelpTable & 0xffff0000 ) == 0xffff0000 )
309 {
310 // resource ID specified
311 idHelpTable = HelpTable; // truncate to USHORT
312 LogEvent( " Loading from resource" );
313 LoadHelpTableFromResource( &( pHelpInstance -> pHelpTable ),
314 phinitHMInitStructure -> hmodHelpTableModule,
315 idHelpTable );
316 pHelpInstance -> HelpTableFromResource = TRUE;
317 }
318 else
319 {
320 // memory help table
321 LogEvent( " Loading from memory" );
322 pHelpInstance -> pHelpTable = (PHELPTABLE) HelpTable;
323 }
324 }
325 else
326 {
327 pHelpInstance -> pHelpTable = NULL;
328 }
329
330 pHelpInstance -> FViewerStarted = FALSE;
331 pHelpInstance -> FViewerWindow = NULLHANDLE;
332 pHelpInstance -> FViewerStartupMessagesCount = 0;
333
334 LogEvent( " Allocating shared memory: %s", SHARED_MEM_NAME );
335 rc = GetSubAllocatedSharedMemory( SHARED_MEM_NAME,
336 SHARED_MEM_SIZE,
337 SHARED_MEM_RESERVE_SIZE,
338 & pHelpInstance -> SharedMemory );
339 if ( rc != 0 )
340 {
341 LogEvent( "Could not allocate shared mem, rc = %d", rc );
342 return NULLHANDLE;
343 }
344 pSharedStruct =
345 (TNewHelpMgrSharedStruct*) pHelpInstance -> SharedMemory.FMem.FPointer;
346
347 strcpy( pSharedStruct -> Title, "NewView Help Manager" );
348 strcpy( pSharedStruct -> Version, HelpMgrVersion );
349
350 phinitHMInitStructure -> ulReturnCode = 0;
351
352 LogEvent( "Success!" );
353 LogEvent( " Instance: %8x", (ULONG) pHelpInstance );
354 LogEvent( " Handle: %8x", pHelpInstance -> FHandle );
355
356 return pHelpInstance -> FHandle;
357}
358
359void DestroyHelpInstance( TPHelpInstance pHelpInstance )
360{
361 int i;
362
363 LogEvent( " Closing viewer" );
364 CloseViewer( pHelpInstance );
365
366 LogEvent( " Destroying help window" );
367 WinDestroyWindow( pHelpInstance -> FHandle );
368
369 LogEvent( " Freeing help tables" );
370 ReleaseHelpTable( pHelpInstance );
371
372 LogEvent( " Releasing shared memory" );
373 ReleaseSubAllocatedSharedMemory( & pHelpInstance -> SharedMemory );
374
375 // remove from list
376 for ( i = 0; i < MAX_HELP_INSTANCES; i ++ )
377 if ( g_pHelpInstances[ i ] == pHelpInstance )
378 g_pHelpInstances[ i ] = NULL;
379 g_HelpInstanceCount --;
380
381 free( pHelpInstance );
382
383 LogEvent( " Done" );
384}
385
386BOOL APIENTRY NHM32DestroyHelpInstance( HWND hwndHelpInstance )
387{
388 TPHelpInstance pHelpInstance;
389
390 LogEvent( "--------------------------------------------------" );
391 LogEvent( "NHM32DestroyHelpInstance" );
392
393 LogEvent( " Help Instance Handle: %8x", hwndHelpInstance );
394
395 pHelpInstance = GetHelpInstance( hwndHelpInstance );
396
397 if ( pHelpInstance == NULL )
398 {
399 LogEvent( " Not a valid help manager window" );
400 return FALSE;
401 }
402 LogEvent( " Help Instance: %8x", (ULONG) pHelpInstance );
403
404 DestroyHelpInstance( pHelpInstance );
405
406 return TRUE;
407}
408
409HWND APIENTRY NHM32QueryHelpInstance( HWND hwndApp )
410{
411 TPHelpInstance pHelpInstance;
412
413 LogEvent( "--------------------------------------------------" );
414 LogEvent( "NHM32QueryHelpInstance" );
415
416 pHelpInstance = GetHelpInstanceForWindowChain( hwndApp );
417
418 if ( pHelpInstance )
419 return pHelpInstance -> FHandle;
420
421 return NULLHANDLE;
422}
423
424BOOL APIENTRY NHM32AssociateHelpInstance( HWND hwndHelpInstance,
425 HWND hwndApp )
426{
427 int i;
428 TPHelpInstance pHelpInstance;
429 char buffer[ 32 ];
430
431 LogEvent( "--------------------------------------------------" );
432 LogEvent( "NHM32AssociateHelpInstance" );
433
434 LogEvent( " Help Instance Handle: %8x", hwndHelpInstance );
435 LogEvent( " Window: %8x", hwndApp );
436
437 // Notify the window (Only required by SmartSuite?)
438 WinSendMsg( hwndApp,
439 WM_SETHELPINFO,
440 (MPARAM) hwndHelpInstance,
441 0 );
442 // Note this call seems to fail on some apps, so ignore result
443
444 if ( hwndHelpInstance == NULLHANDLE )
445 {
446 // clearing association with this window.
447 LogEvent( " Help Instance NULLHANDLE, clearing" );
448
449 for ( i = 0; i < MAX_HELP_INSTANCES; i ++ )
450 {
451 pHelpInstance = g_pHelpInstances[ i ];
452 if ( pHelpInstance != NULL )
453 {
454 RemoveAssociatedWindow( pHelpInstance,
455 hwndApp );
456 }
457 }
458
459 return TRUE;
460 }
461
462 if ( WinQueryWindowText( hwndApp, sizeof( buffer ), buffer ) )
463 LogEvent( " Window Title: %s", buffer );
464 else
465 LogEvent( " Window Title: Blank/invalid" );
466
467 pHelpInstance = GetHelpInstance( hwndHelpInstance );
468 if ( pHelpInstance == NULL )
469 {
470 LogEvent( " Not a valid help manager window" );
471 return FALSE;
472 }
473
474 LogEvent( " Help Instance: %8x", (ULONG) pHelpInstance );
475
476 LogEvent( " OK" );
477 AssociateWindow( pHelpInstance, hwndApp );
478
479 return TRUE;
480}
481
482BOOL APIENTRY NHM32LoadHelpTable( HWND hwndHelpInstance,
483 ULONG idHelpTable,
484 HMODULE Module )
485{
486 TPHelpInstance pHelpInstance;
487
488 LogEvent( "--------------------------------------------------" );
489 LogEvent( "NHM32LoadHelpTable" );
490
491 pHelpInstance = GetHelpInstance( hwndHelpInstance );
492 if ( pHelpInstance == NULL )
493 {
494 LogEvent( " Not a valid help manager window" );
495 return FALSE;
496 }
497
498 ReleaseHelpTable( pHelpInstance );
499
500 LoadHelpTableFromResource( &( pHelpInstance -> pHelpTable ),
501 Module,
502 idHelpTable );
503
504 return TRUE;
505}
506
507BOOL APIENTRY NHM32CreateHelpTable( HWND hwndHelpInstance,
508 PHELPTABLE phtHelpTable )
509{
510 TPHelpInstance pHelpInstance;
511
512 LogEvent( "--------------------------------------------------" );
513 LogEvent( "NHM32CreateHelpTable" );
514
515 LogEvent( " Help Instance Handle: %8x", hwndHelpInstance );
516 LogEvent( " Help Table: %8x", phtHelpTable );
517
518 pHelpInstance = GetHelpInstance( hwndHelpInstance );
519 if ( pHelpInstance == NULL )
520 {
521 LogEvent( " Not a valid help manager window" );
522 return FALSE;
523 }
524 LogEvent( " Help Instance: %8x", pHelpInstance );
525
526 LogEvent( " Freeing existing table" );
527 ReleaseHelpTable( pHelpInstance );
528
529 LogEvent( " Loading table from memory" );
530 pHelpInstance -> pHelpTable = phtHelpTable;
531
532 return TRUE;
533}
534
535//--------------------------------------------------------------------------------
536// 16 bit entry points
537//--------------------------------------------------------------------------------
538
539// Portions contributed by Aaron Reed at IBM
540
541// typedef void _Far16 * HWND16;
542typedef HWND HWND16;
543typedef USHORT BOOL16;
544typedef char _Far16 * PSZ16;
545typedef USHORT HMODULE16;
546
547// by default 32-bit code is double word aligned in their structures. Gotta
548// make this word (2 bytes) aligned for this structure to work. Thus the
549// pragma pack
550#pragma pack(2)
551
552typedef struct _HELPTABLE16
553{
554 USHORT idAppWindow;
555 PHELPSUBTABLE phstHelpSubTable;
556 USHORT idExtPanel;
557
558} HELPTABLE16, _Far16 *PHELPTABLE16;
559
560typedef struct _HELPINIT16
561{
562 USHORT cb;
563 ULONG ulReturnCode;
564 PSZ16 pszTutorialName;
565 ULONG phtHelpTable;
566 HMODULE16 hmodHelpTableModule;
567 HMODULE16 hmodAccelActionBarModule;
568 USHORT idAccelTable;
569 USHORT idActionBar;
570 PSZ16 pszHelpWindowTitle;
571 USHORT usShowPanelId;
572 PSZ16 pszHelpLibraryName;
573
574} HELPINIT16, _Far16 *PHELPINIT16;
575
576#pragma pack()
577
578HWND16 APIENTRY16 NHM16CreateHelpInstance( HAB hab,
579 PHELPINIT16 phinitHMInitStructure )
580{
581 HELPINIT helpinit;
582 HWND hInstance;
583 ULONG HelpTable;
584
585 LogEvent( "NHM16CreateHelpInstance" );
586
587 if ( !phinitHMInitStructure )
588 {
589 // no init structure
590 LogEvent( " Null init structure pointer, fail" );
591 return NULLHANDLE;
592 }
593
594 LogEvent( " Copying structure to 32 bit" );
595
596 // Copy 16 bit structure to 32 bit
597 memset( &helpinit, 0, sizeof( helpinit ) );
598
599 helpinit.pszTutorialName = (PSZ) phinitHMInitStructure -> pszTutorialName;
600
601 HelpTable = (ULONG) phinitHMInitStructure -> phtHelpTable;
602 LogEvent( " Help Table: %8x", HelpTable );
603 if ( HelpTable )
604 {
605 if ( ( HelpTable & 0xffff0000 ) == 0xffff0000 )
606 {
607 // an ID, so copy literally.
608 LogEvent( " Copying as ID" );
609 helpinit.phtHelpTable = (PHELPTABLE) HelpTable;
610 }
611 else
612 {
613 // It's a pointer, so convert 16->32
614 LogEvent( " Converting pointer" );
615 helpinit.phtHelpTable =
616 (PHELPTABLE) (PHELPTABLE16) HelpTable;
617 }
618 }
619
620 helpinit.hmodHelpTableModule =
621 (HMODULE) phinitHMInitStructure -> hmodHelpTableModule;
622 helpinit.pszHelpWindowTitle =
623 (PSZ) phinitHMInitStructure -> pszHelpWindowTitle;
624 helpinit.pszHelpLibraryName =
625 (PSZ) phinitHMInitStructure -> pszHelpLibraryName;
626
627 LogEvent( " Conversions done, calling 32 bit" );
628
629 hInstance = NHM32CreateHelpInstance( hab, &helpinit );
630
631 LogEvent( " 32 bit returned, copying result code" );
632
633 // copy return code back
634 phinitHMInitStructure -> ulReturnCode = helpinit.ulReturnCode;
635
636 LogEvent( " rc: %u", phinitHMInitStructure -> ulReturnCode );
637 LogEvent( " Done" );
638
639 return (HWND16) hInstance;
640}
641
642BOOL16 APIENTRY16 NHM16DestroyHelpInstance( HWND16 hwndHelpInstance )
643{
644 LogEvent( "NHM16DestroyHelpInstance" );
645 return NHM32DestroyHelpInstance( (HWND) hwndHelpInstance );
646}
647
648HWND16 APIENTRY16 NHM16QueryHelpInstance( HWND16 hwndApp )
649{
650 LogEvent( "NHM16QueryHelpInstance" );
651 return (HWND16) NHM32QueryHelpInstance( (HWND) hwndApp );
652}
653
654BOOL16 APIENTRY16 NHM16AssociateHelpInstance( HWND16 hwndHelpInstance,
655 HWND16 hwndApp )
656{
657 LogEvent( "NHM16AssociateHelpInstance" );
658 return NHM32AssociateHelpInstance( (HWND) hwndHelpInstance,
659 (HWND) hwndApp );
660}
661
662BOOL16 APIENTRY16 NHM16LoadHelpTable( HWND16 hwndHelpInstance,
663 USHORT idHelpTable,
664 HMODULE16 Module )
665{
666 LogEvent( "NHM16QueryHelpInstance" );
667 return NHM32LoadHelpTable( (HWND) hwndHelpInstance,
668 idHelpTable,
669 (HMODULE) Module );
670}
671
672BOOL16 APIENTRY16 NHM16CreateHelpTable( HWND16 hwndHelpInstance,
673 PHELPTABLE phtHelpTable )
674{
675 LogEvent( "NHM16QueryHelpInstance" );
676
677 LogEvent( " Not supported. Fail" );
678
679 // this is tricky because we would have to copy the 16 bit
680 // table (pointers) to a 32 bit variant...
681 return FALSE;
682
683 // return NHM32CreateHelpTable( hwndHelpInstance,
684 // phtHelpTable );
685}
686
687//--------------------------------------------------------------------------------
688
689// Get the application window currently set for the help instance
690// either the set active window, or the first associated window if no active window
691HWND GetAppWindow( TPHelpInstance pHelpInstance )
692{
693 HWND result;
694
695 result = pHelpInstance -> FActiveWindow;
696 if ( result != NULLHANDLE )
697 return result;
698
699 if ( pHelpInstance -> FNumApplicationWindows == 0 )
700 return NULLHANDLE;
701
702 return pHelpInstance -> FApplicationWindows[ 0 ];
703}
704
705BOOL FindHelpTopic( TPHelpInstance pHelpInstance,
706 USHORT WindowID,
707 USHORT ControlID,
708 USHORT ChildControlID,
709 USHORT* pHelpPanelID,
710 ULONG Mode ) // mode only used for passing to app window
711{
712 USHORT ExtendedHelpPanelID;
713 PHELPSUBTABLE2 pHelpSubTable;
714 HWND hAppWindow;
715
716 hAppWindow = GetAppWindow( pHelpInstance );
717
718 if ( ! FindIDInHelpTable( WindowID,
719 pHelpInstance -> pHelpTable,
720 & ExtendedHelpPanelID,
721 & pHelpSubTable ) )
722 {
723 LogEvent( " No match found in help table" );
724
725 if ( hAppWindow != NULLHANDLE )
726 {
727 LogEvent( " Informing application: HM_HELPSUBITEM_NOT_FOUND" );
728 // tell the app we didn't find the subitem in the help table
729 WinSendMsg( hAppWindow,
730 HM_HELPSUBITEM_NOT_FOUND,
731 (MPARAM) Mode,
732 MPFROM2SHORT( ControlID, ChildControlID ) );
733 }
734
735 return FALSE;
736 }
737
738 LogEvent( " Help Subtable found for Window" );
739
740 if ( pHelpSubTable == NULL )
741 {
742 LogEvent( " No help subtable" );
743 LogEvent( " Use extended help panel %hu",
744 ExtendedHelpPanelID );
745 *pHelpPanelID = ExtendedHelpPanelID;
746 return TRUE;
747 }
748
749 if ( ChildControlID != (USHORT) -1 )
750 {
751 // Child control -1 means not applicable (e.g. top level menu)
752 if ( FindIDInHelpSubTable( ChildControlID,
753 pHelpSubTable,
754 pHelpPanelID ) )
755 {
756 LogEvent( " Found Child Control ID, Panel: %hu",
757 *pHelpPanelID );
758 return TRUE;
759 }
760 LogEvent( " Subtopic not found" );
761 }
762 else
763 {
764 LogEvent( " Child Control -1: not applicable" );
765 }
766
767 // Child not found/not applicable, look for main control ID
768
769 if ( FindIDInHelpSubTable( ControlID,
770 pHelpSubTable,
771 pHelpPanelID ) )
772 {
773 LogEvent( " Found Control ID, Panel: %hu",
774 *pHelpPanelID );
775 return TRUE;
776 }
777
778 LogEvent( " Control ID not found" );
779
780 // Control not found, we can only show help for the
781 // Window as a whole. First, see if the subtable
782 // has an entry for the window
783 if ( FindIDInHelpSubTable( WindowID,
784 pHelpSubTable,
785 pHelpPanelID ) )
786 {
787 LogEvent( " Found Window ID in subtable, Panel: %hu",
788 *pHelpPanelID );
789 return TRUE;
790 }
791
792 // No, just use extended help panel
793 LogEvent( " Window ID not found in subtable" );
794 LogEvent( " Use extended help panel %hu",
795 ExtendedHelpPanelID );
796 *pHelpPanelID = ExtendedHelpPanelID;
797
798 return TRUE;
799}
800
801//--------------------------------------------------------------------------------
802// Help Hook function
803//
804// installed during WinCreateHelpInstance
805//
806// This function is called by the standard OS/2 windows on
807// WM_HELP messages.
808//
809// Notes:
810// The parameters are ULONG but passed from USHORTs
811// if the originating program was 16 bit (AFAIK).
812// So I just cast them to USHORTs
813//--------------------------------------------------------------------------------
814BOOL APIENTRY HelpHook( HAB hab,
815 ULONG ulMode,
816 ULONG ulControlID,
817 ULONG ulChildControlID,
818 PRECTL prcPosition )
819{
820 USHORT WindowID;
821 USHORT PanelID;
822 HWND hFocusFrame;
823 HWND hFocusWindow;
824 TPHelpInstance pHelpInstance;
825 USHORT ControlID;
826 USHORT ChildControlID;
827 USHORT Mode;
828
829 ControlID = (USHORT) ulControlID;
830 ChildControlID = (USHORT) ulChildControlID;
831 Mode = (USHORT) ulMode;
832
833 LogEvent( "--------------------------------------------------" );
834 LogEvent( "HelpHook" );
835
836 hFocusWindow = WinQueryFocus( HWND_DESKTOP );
837 hFocusFrame = GetTopLevelWindow( hFocusWindow );
838
839 LogEvent( " Focus Window: %8x", hFocusWindow );
840 LogEvent( " Focus Frame: %8x", hFocusFrame );
841
842 WindowID = WinQueryWindowUShort( hFocusFrame, QWS_ID );
843
844 LogEvent( " Focus Frame ID: %d", WindowID );
845
846 pHelpInstance = GetHelpInstanceForWindowChain( hFocusWindow );
847
848 if ( pHelpInstance == NULL )
849 {
850 LogEvent( " No matching help instance found" );
851 LogEvent( " Picking first one" );
852 if ( g_HelpInstanceCount == 0 )
853 {
854 LogEvent( " No instances present" );
855 return TRUE;
856 }
857 pHelpInstance = g_pHelpInstances[ 0 ];
858 }
859
860 switch( Mode )
861 {
862 case HLPM_MENU:
863 LogEvent( " Menu Mode" );
864 LogEvent( " Frame: %x", hFocusFrame );
865 break;
866
867 case HLPM_FRAME:
868 LogEvent( " Frame Mode" );
869 WindowID = ControlID;
870 break;
871
872 case HLPM_WINDOW:
873 LogEvent( " Window Mode" );
874
875 if ( pHelpInstance -> FActiveWindow != NULLHANDLE )
876 {
877 // override if active window set.
878 WindowID = WinQueryWindowUShort( pHelpInstance -> FActiveWindow,
879 QWS_ID );
880 LogEvent( " Active window set; overriding, Window ID: %d", WindowID );
881 }
882 break;
883
884 default:
885 LogEvent( " Unknown Mode %8hx", Mode );
886 }
887 LogEvent( " Control ID: %hu", (USHORT) ControlID );
888 LogEvent( " Child Control ID: %hu", (USHORT) ChildControlID );
889
890 if ( pHelpInstance -> pHelpTable == NULL )
891 {
892 LogEvent( " No Help Table loaded for instance" );
893 return TRUE;
894 }
895
896 if ( ! FindHelpTopic( pHelpInstance,
897 WindowID,
898 ControlID,
899 ChildControlID,
900 & PanelID,
901 ulMode ) )
902
903 {
904 return TRUE;
905 }
906
907 LogEvent( "Displaying panel: %hu", PanelID );
908
909 EnsureViewerRunning( pHelpInstance );
910 PostViewerMessage( pHelpInstance,
911 NHM_TOPIC_BY_RESOURCE_ID,
912 (MPARAM) PanelID,
913 0 );
914
915 return FALSE; // next hook in chain not required
916}
917
918//--------------------------------------------------------------------------------
919// Help Window procedure
920//--------------------------------------------------------------------------------
921
922MRESULT APIENTRY HelpManagerWndProc( HWND hwnd,
923 ULONG msg,
924 MPARAM mp1,
925 MPARAM mp2 )
926{
927 USHORT PanelID;
928 char buffer[ 256 ];
929
930 PHELPSUBTABLE2 pHelpSubTable;
931 USHORT idExtendedHelpPanel;
932 USHORT WindowID;
933 HWND hFrameWindow;
934 HWND hActiveWindow;
935 TPHelpInstance pHelpInstance;
936 APIRET rc;
937 char* PanelName;
938 char* pMessageMem;
939 HWND hAppWindow;
940
941 if ( msg == WM_CREATE
942 || msg == WM_DESTROY
943 || msg == WM_ADJUSTWINDOWPOS )
944 // ignore window management messages
945 return 0;
946
947 if ( msg >= WM_USER
948 && msg != NHM_VIEWER_READY
949 && msg != NHM_FORGET_VIEWER )
950 // ignore these - somebody sends em, I dunno why
951 return 0;
952
953 LogEvent( "--------------------------------------------------" );
954 LogEvent( "HelpManagerWndProc" );
955 LogEvent( " Window: %8x", hwnd );
956
957 pHelpInstance = GetHelpInstance( hwnd );
958 if ( pHelpInstance == NULL )
959 {
960 LogEvent( " Not a valid help manager window" );
961 LogEvent( " Picking first help instance" );
962 if ( g_HelpInstanceCount == 0 )
963 {
964 LogEvent( " No instances present" );
965 return 0;
966 }
967 pHelpInstance = g_pHelpInstances[ 0 ];
968 }
969
970 hAppWindow = GetAppWindow( pHelpInstance );
971
972 LogEvent( " HelpInstance: %8x", (ULONG) pHelpInstance );
973 LogEvent( " Message: %8x", msg );
974 LogEvent( " App Window: %8x", (ULONG) hAppWindow );
975
976 switch( msg )
977 {
978 case HM_HELP_CONTENTS:
979 LogEvent( "HM_HELP_CONTENTS" );
980 EnsureViewerRunning( pHelpInstance );
981 PostViewerMessage( pHelpInstance,
982 NHM_HELP_CONTENTS,
983 0,
984 0 );
985 break;
986
987 case HM_HELP_INDEX:
988 LogEvent( "HM_HELP_INDEX" );
989 EnsureViewerRunning( pHelpInstance );
990 PostViewerMessage( pHelpInstance,
991 NHM_HELP_INDEX,
992 0,
993 0 );
994 break;
995
996 case HM_DISPLAY_HELP:
997 LogEvent( " HM_DISPLAY_HELP" );
998 switch( (ULONG) mp2 )
999 {
1000 case HM_RESOURCEID:
1001 // is it a pointer or a ushort? Seems it can be either!
1002 if ( (ULONG) mp1 & 0xffff0000 )
1003 PanelID = * ( (PUSHORT) mp1 );
1004 else
1005 PanelID = (USHORT) mp1;
1006
1007 LogEvent( " Resource ID: %hu", PanelID );
1008 // Note: 0 indicates Help for "Using Help"
1009 if ( PanelID == 0 )
1010 {
1011 LogEvent( " ID is 0: Help on Help/Using Help" );
1012 ViewHelpOnHelp( pHelpInstance -> Fhab );
1013 }
1014 else
1015 {
1016 EnsureViewerRunning( pHelpInstance );
1017 PostViewerMessage( pHelpInstance,
1018 NHM_TOPIC_BY_RESOURCE_ID,
1019 (MPARAM) PanelID,
1020 0 );
1021 }
1022 break;
1023
1024 case HM_PANELNAME:
1025 PanelName = (char*) mp1;
1026 LogEvent( " Panel Name: %s", PanelName );
1027 EnsureViewerRunning( pHelpInstance );
1028 rc = SubAllocate( & pHelpInstance -> SharedMemory,
1029 strlen( PanelName ) + 1,
1030 & pMessageMem );
1031 strcpy( pMessageMem, PanelName );
1032 PostViewerMessage( pHelpInstance,
1033 NHM_TOPIC_BY_PANEL_NAME,
1034 (MPARAM) pMessageMem,
1035 0 );
1036
1037 break;
1038 }
1039
1040 break;
1041
1042 case HM_GENERAL_HELP: // == HM_EXT_HELP
1043 LogEvent( "HM_GENERAL_HELP (== HM_EXT_HELP)" );
1044 EnsureViewerRunning( pHelpInstance );
1045
1046 // find active window
1047 hFrameWindow = GetTopLevelWindow( WinQueryFocus( HWND_DESKTOP ) );
1048
1049 // get ID
1050 WindowID = WinQueryWindowUShort( hFrameWindow, QWS_ID );
1051
1052 LogEvent( " Window ID: %hu", WindowID );
1053
1054 if ( ! FindIDInHelpTable( WindowID,
1055 pHelpInstance -> pHelpTable,
1056 & idExtendedHelpPanel,
1057 & pHelpSubTable ) )
1058 {
1059 LogEvent( " No helptable entry found" );
1060 return 0;
1061 }
1062 PostViewerMessage( pHelpInstance,
1063 NHM_TOPIC_BY_RESOURCE_ID,
1064 (MPARAM) idExtendedHelpPanel,
1065 0 );
1066 break;
1067
1068 case HM_KEYS_HELP:
1069 LogEvent( "HM_KEYS_HELP" );
1070 if ( hAppWindow == NULLHANDLE )
1071 {
1072 LogEvent( " No app windows; can't ask for keys help topic" );
1073 return 0;
1074 }
1075 PanelID =
1076 (USHORT) WinSendMsg( hAppWindow,
1077 HM_QUERY_KEYS_HELP,
1078 0,
1079 0 );
1080 LogEvent( " Keys help topic: %d", PanelID );
1081 if ( PanelID != 0 )
1082 {
1083 EnsureViewerRunning( pHelpInstance );
1084 PostViewerMessage( pHelpInstance,
1085 NHM_TOPIC_BY_RESOURCE_ID,
1086 (MPARAM) PanelID,
1087 0 );
1088 }
1089
1090 break;
1091
1092 case HM_DISMISS_WINDOW:
1093 LogEvent( "HM_DISMISS_WINDOW" );
1094 CloseViewer( pHelpInstance );
1095 break;
1096
1097 case HM_SET_ACTIVE_WINDOW:
1098 LogEvent( "HM_SET_ACTIVE_WINDOW" );
1099 hActiveWindow = (HWND) mp1;
1100 LogEvent( " New active window: %8x", (ULONG) hActiveWindow );
1101 WinQueryWindowText( hActiveWindow, sizeof( buffer ), buffer );
1102 LogEvent( " Window Title: %s", buffer );
1103
1104 pHelpInstance -> FActiveWindow = hActiveWindow;
1105 LogEvent( " OK" );
1106 break;
1107
1108 case HM_SET_HELP_LIBRARY_NAME:
1109 LogEvent( "HM_SET_HELP_LIBRARY_NAME" );
1110 LogEvent( " Filename(s): %s", (char*) mp1 );
1111 StoreString( & pHelpInstance -> FHelpFileNames,
1112 (char*) mp1 );
1113 if ( pHelpInstance -> FViewerStarted )
1114 {
1115 rc = SubAllocate( & pHelpInstance -> SharedMemory,
1116 strlen( mp1 ) + 1,
1117 & pMessageMem );
1118 pMessageMem[ 0 ] = 0; // init string, since ModifyFilenames appends.
1119 ModifyFilenames( mp1, pMessageMem );
1120 PostViewerMessage( pHelpInstance,
1121 NHM_SET_FILES,
1122 pMessageMem,
1123 0 );
1124 }
1125 break;
1126
1127 case HM_SET_HELP_WINDOW_TITLE:
1128 LogEvent( "HM_SET_HELP_WINDOW_TITLE" );
1129 LogEvent( " Title: %s", (char*) mp1 );
1130 StoreString( & pHelpInstance -> FHelpWindowTitle,
1131 (char*) mp1 );
1132 if ( pHelpInstance -> FViewerStarted )
1133 {
1134 rc = SubAllocate( & pHelpInstance -> SharedMemory,
1135 strlen( mp1 ) + 1,
1136 & pMessageMem );
1137 strcpy( pMessageMem, mp1 ),
1138 PostViewerMessage( pHelpInstance,
1139 NHM_SET_TITLE,
1140 pMessageMem,
1141 0 );
1142 }
1143 break;
1144
1145 case HM_LOAD_HELP_TABLE:
1146 LogEvent( "HM_LOAD_HELP_TABLE" );
1147 NHM32LoadHelpTable( pHelpInstance -> FHandle,
1148 SHORT1FROMMP( mp1 ),
1149 (HMODULE) mp2 );
1150 break;
1151
1152 case HM_CREATE_HELP_TABLE:
1153 LogEvent( "HM_CREATE_HELP_TABLE" );
1154 NHM32CreateHelpTable( pHelpInstance -> FHandle,
1155 (PHELPTABLE) mp1 );
1156 break;
1157
1158 case NHM_VIEWER_READY:
1159 // viewer notifying us it has started up OK
1160 LogEvent( "Viewer ready" );
1161 // save viewer window handle
1162 pHelpInstance -> FViewerWindow = (HWND) mp1;
1163 PostQueuedViewerMessages( pHelpInstance );
1164 break;
1165
1166 case NHM_FORGET_VIEWER:
1167 // viewer notifying us it is now doing something else
1168 // ie loaded another file.
1169 LogEvent( "Forget viewer" );
1170 pHelpInstance -> FViewerStarted = FALSE;
1171 pHelpInstance -> FViewerWindow = NULLHANDLE;
1172 break;
1173
1174/*
1175// This is worse han useless because View.exe
1176 is just the stub and will always exit immediately.
1177 case WM_APPTERMINATENOTIFY:
1178 // viewer has stopped
1179 LogEvent( "Viewer has stopped" );
1180 pHelpInstance -> FViewerStarted = FALSE;
1181 pHelpInstance -> FViewerWindow = NULLHANDLE;
1182 LogEvent( " Exit Code: %d",
1183 mp2 );
1184 break;
1185*/
1186
1187 // not supported
1188 case HM_SET_SHOW_PANEL_ID: // original debugging aid, redundant
1189 LogEvent( " Ignoring unsupported: HM_SET_SHOW_PANEL_ID" );
1190 break;
1191
1192 case HM_REPLACE_USING_HELP:
1193 LogEvent( " Ignoring unsupported: HM_REPLACE_USING_HELP" );
1194 break;
1195
1196 case HM_SET_OBJCOM_WINDOW:
1197 LogEvent( " Ignoring unsupported: HM_SET_OBJCOM_WINDOW" );
1198 break;
1199
1200 case HM_UPDATE_OBJCOM_WINDOW_CHAIN:
1201 LogEvent( " Ignoring unsupported: HM_UPDATE_OBJCOM_WINDOW_CHAIN" );
1202 break;
1203
1204 case HM_QUERY_DDF_DATA:
1205 LogEvent( " Ignoring unsupported: HM_QUERY_DDF_DATA" );
1206 break;
1207
1208 case HM_INVALIDATE_DDF_DATA:
1209 LogEvent( " Ignoring unsupported: HM_INVALIDATE_DDF_DATA" );
1210 break;
1211
1212 case HM_QUERY:
1213 LogEvent( " HM_QUERY" );
1214 LogEvent( " SelectionID: %d", SHORT1FROMMP( mp1 ) );
1215 LogEvent( " MessageID: %d", SHORT2FROMMP( mp1 ) );
1216 LogEvent( " Param: %08X", mp2 );
1217 if ( SHORT2FROMMP( mp1 ) == 1 )
1218 {
1219 // this is the only one we can sort of do, maybe
1220 return (MRESULT) hwnd;
1221 }
1222 else
1223 {
1224 LogEvent( " This MessageID not supported" );
1225 }
1226 break;
1227
1228 case HM_SET_COVERPAGE_SIZE: // ignore, user controls window size buddy
1229 LogEvent( " Ignoring unsupported: HM_SET_COVERPAGE_SIZE" );
1230 break;
1231
1232 default:
1233 LogEvent( " Unrecognised Message: %x", msg );
1234 }
1235
1236 return 0;
1237}
1238
1239void CloseAllInstances( void )
1240{
1241 int i;
1242 TPHelpInstance pHelpInstance;
1243
1244 LogEvent( "CloseAllInstances" );
1245 for ( i = 0; i < MAX_HELP_INSTANCES; i ++ )
1246 {
1247 pHelpInstance = g_pHelpInstances[ i ];
1248 if ( pHelpInstance != NULL )
1249 {
1250 LogEvent( " %8x (handle: %8x) active, destroying",
1251 pHelpInstance,
1252 pHelpInstance -> FHandle );
1253 DestroyHelpInstance( pHelpInstance );
1254 }
1255 }
1256}
1257
1258// int
1259void p_dll_terminate( void )
1260{
1261 char ApplicationFilename[ 257 ];
1262
1263// stoplog();
1264
1265 LogEvent( "--------------------------------------------------" );
1266
1267 GetApplicationFilename( ApplicationFilename,
1268 sizeof( ApplicationFilename ) );
1269
1270 LogEvent( "p_dll_terminate: %s",
1271 ApplicationFilename );
1272
1273 CloseAllInstances();
1274// return 1;
1275}
1276
1277
1278int __dll_initialize( void )
1279{
1280 char ApplicationFilename[ 257 ];
1281
1282 LogEvent( "--------------------------------------------------" );
1283
1284 GetApplicationFilename( ApplicationFilename,
1285 sizeof( ApplicationFilename ) );
1286
1287 LogEvent( "__dll_initialize: %s",
1288 ApplicationFilename );
1289
1290 atexit( p_dll_terminate );
1291 return 1;
1292}
1293
1294// Blank LibMain - required to get Watcom initialise
1295// runtime library properly.
1296// Tested - still required on Watcom 11.0c, OW 1.0, 1.1, 1.2rc3
1297// NOTE! This function DOES NOT get called
1298unsigned LibMain( unsigned hmod, unsigned termination )
1299{
1300 return 1;
1301}
Note: See TracBrowser for help on using the repository browser.