source: trunk/hlpmgr/helpmgr.c@ 26

Last change on this file since 26 was 26, checked in by RBRi, 19 years ago

+ helpmgr files

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