OWLNext    7.0
Borland's Object Windows Library for the modern age
Loading...
Searching...
No Matches
hlpmanag.cpp
Go to the documentation of this file.
1//----------------------------------------------------------------------------
2// ObjectWindows
3// Copyright (c) 1995, 1996 by Borland International, All Rights Reserved
4//
5/// \file
6/// Implementation of class THelpFileManager & THelpContext
7//----------------------------------------------------------------------------
8
9#include <owl/pch.h>
10
11#include <owl/hlpmanag.h>
12#include <owl/applicat.h>
13#include <owl/window.h>
14#include <owl/framewin.h>
15#include <owl/gadgetwi.h>
16#include <owl/template.h>
17
18#if !defined(OWL_HLPMANAG_RH)
19# include <owl/hlpmanag.rh>
20#endif
21
22#if defined(__BORLANDC__)
23# pragma option -w-ccc // Disable "Condition is always true/false"
24#endif
25
26namespace owl {
27
29
30static tchar HtmlHelpDllName[] = _T("HHCTRL.OCX");
31
33:
34 TModule(HtmlHelpDllName, true, true, false), // shouldLoad, mustLoad and !addToList
35 DllCanUnloadNow(*this, "DllCanUnloadNow"),
36 DllGetClassObject(*this, "DllGetClassObject"),
38 HtmlHelp(*this, "HtmlHelpW")
39#else
40 HtmlHelp(*this, "HtmlHelpA")
41#endif
42{
43}
44
46{
47 cbStruct = sizeof(HH_POPUP);
48 hinst = nullptr;
49 idString = id;
50 pszText = nullptr;
51 pt = TPoint(-1,-1);
52 clrForeground = static_cast<COLORREF>(-1); //JJH added static casts
53 clrBackground = static_cast<COLORREF>(-1);
54 rcMargins = TRect(-1,-1,-1,-1);
55 pszFont = nullptr;
56}
57
58void
60{
62 dwStyles |= style;
63}
64
65void
71
72void
78
79void
85
86//
87/// Constructor. Saves the name of the help file and creates the global context
88/// table.
89//
91:
92 UseHTMLHelp(false),
93 WinToHTML(true),
94 HelpCursor(nullptr),
95 ContextHelp(false),
96 HelpState(false),
97 LastParent(nullptr)
98{
101}
102
103//
104/// Deletes the allocated context table.
105//
111
112//
113/// Called by EvHelp() to activate the help file with the help context ID.
114//
115void
117{
121 if(UseHTMLHelp){
122 if (app)
123 HelpState = ToBool(HtmlHelp(app->GetMainWindow(), GetHelpFile().c_str(),
124 helpCmd, helpFileContextId) != nullptr);
125 else
127 helpCmd, helpFileContextId) != nullptr);
128 }
129 else{
130 if (app)
131 HelpState = ToBool(app->GetMainWindow()->WinHelp(GetHelpFile().c_str(),
133 else
134 HelpState = ToBool(::WinHelp(nullptr, GetHelpFile().c_str(),
136 }
137}
138
139//
140/// Deactivates the help.
141//
142void
144{
146 if(UseHTMLHelp){
147 if (app)
148 HtmlHelp(app->GetMainWindow(), GetHelpFile().c_str(), HELP_QUIT, 0);
149 else
150 HtmlHelp(nullptr, GetHelpFile().c_str(), HELP_QUIT, 0);
151 }
152 else{
153 if (app)
154 app->GetMainWindow()->WinHelp(GetHelpFile().c_str(), HELP_QUIT, 0);
155 else
156 ::WinHelp(nullptr, GetHelpFile().c_str(), HELP_QUIT, 0);
157 }
158}
159
160//
161// Support for nwe HTML Help
162//
163HWND
165{
166 // translate uCommand into HTML command
167 uint command = uCmd;
168 if(WinToHTML){
169 switch(uCmd){
170 case HELP_FINDER:
172 break;
173 case HELP_CONTENTS: //== HELP_INDEX
175 break;
176 case HELP_WM_HELP:
178 break;
179 case HELP_CONTEXTMENU:
181 break;
182 case HELP_QUIT:
184 break;
185 case HELP_CONTEXTPOPUP: {
187 if(THtmlHelp::IsAvailable()){
188 if(LastHit == TPoint(-1, -1))
189 HtmlHelp(GetWindowPtr(GetDesktopWindow()), lpszHelp, HH_HELP_CONTEXT,data) ;
190 else
191 {
192 HH_POPUP hPop; // HTML Help popup structure
193 memset(&hPop, 0, sizeof(hPop));
194 hPop.cbStruct = sizeof(hPop);
195 hPop.clrBackground = -1;
196 hPop.clrForeground = -1;
197 hPop.rcMargins.left = -1;
198 hPop.rcMargins.bottom = -1;
199 hPop.rcMargins.right = -1;
200 hPop.pt = LastHit;
201 hPop.idString = static_cast<UINT>(data);
202 hPop.pszText = nullptr;
203 hPop.pszFont = nullptr;
204
205 const HWND w = wnd ? wnd->GetHandle() : nullptr;
206 return THtmlHelp::Dll()->HtmlHelp(w, lpszHelp, command, reinterpret_cast<DWORD_PTR>(&hPop));
207 }
208
209 }
210 return nullptr;
211 }
212 }
213 }
214 if(THtmlHelp::IsAvailable()){
215 if(wnd)
216 return THtmlHelp::Dll()->HtmlHelp(*wnd,lpszHelp,command,data);
217 else
218 return THtmlHelp::Dll()->HtmlHelp(nullptr, lpszHelp,command,data);
219 }
220 return nullptr;
221}
222
223//
224/// Changes the name of the help file.
225//
226void
228{
230 UseHTMLHelp = false;
231 LPCTSTR ptr = _tcsrchr(HelpFileName.c_str(),_T('.'));
232 if(ptr && _tcsicmp(ptr, _T(".chm"))==0)
233 UseHTMLHelp = true;
234}
235
237 EV_COMMAND(CM_CONTEXTHELP, CmContextHelp),
243
244//
245//
246//
247void
248THelpFileManager::SetHelpCursor()
249{
250 if(!HelpCursor){
252 if(app)
253 HelpCursor = new TCursor(*app, TResId(IDC_HELPCURSOR));
254 }
255 ::SetCursor(*HelpCursor);
256}
257
258//
259//
260//
261void
267
268//
269//
270//
271void
276
277//
278//
279//
280void
282{
284 if(!LastParent)
285 return;
286 LastParent->ScreenToClient(LastHit); // TWindow
288 HELPINFO Info;
289 Info.cbSize = sizeof(Info);
290 Info.MousePos = LastHit;
291
292 if(hWnd){
294 if(gwin){
295 TGadget* gd = gwin->GadgetFromPoint(LastHit);
296 if(gd){
297 Info.iContextType = HELPINFO_MENUITEM;
298 Info.iCtrlId = gd->GetId();
299 EvHelp(Info);
300 }
301 return;
302 }
303 }
304 Info.iContextType = HELPINFO_WINDOW;
305 Info.dwContextId = 0;
306
307 // If the click wasn't on one of the controls, open Help for dialog.
308 if (hWnd == nullptr || hWnd == LastParent->GetHandle()){
309 Info.iContextType = HELPINFO_MENUITEM;
310 Info.iCtrlId = IDHELP;
311 Info.hItemHandle = LastParent->GetHandle();
312 }
313 else{
314 Info.iCtrlId = ::GetDlgCtrlID(hWnd);
315 Info.hItemHandle = hWnd;
316 }
317 EvHelp(Info);
318}
319
320//
321/// Event handler for the WM_HELP message.
322//
323void
325{
327 bool success = false;
329
330 if (hi.iContextType == HELPINFO_MENUITEM){
333 }
334 else if (hi.iContextType == HELPINFO_WINDOW)
335 success = GetHelpContextFromControl(context, hi.iCtrlId, static_cast<HWND>(hi.hItemHandle));
336
337 LastHit = hi.MousePos;
338 if (::GetKeyState(VK_F1) < 0 && ::GetKeyState(VK_SHIFT) < 0)
339 {
340 TWindow* wnd = context.GetWindow();
341 TWindow* child = wnd->ChildWithId(hi.iCtrlId);
342 LastHit = TPoint(wnd->GetWindowAttr().X + child->GetWindowAttr().X, wnd->GetWindowAttr().Y + child->GetWindowAttr().Y);
343 }
344 else if(::GetKeyState(VK_F1) < 0)
345 LastHit = TPoint(-1, -1);
346
347 if (success)
348 ActivateHelp(context.GetWindow(), context.GetHelpFileContextId(), hlpCmd);
349}
350
351//
352//
353//
354bool
356{
357 if (msg.message == WM_COMMAND) {
358 // help command from menu or from gadget from "what this?" for gadget
359 if (ContextHelp || (::GetKeyState(VK_F1) < 0)) {
360 ContextHelp = false;
361 HELPINFO Info;
362 Info.cbSize = sizeof(Info);
363 Info.iContextType = HELPINFO_MENUITEM;
364 Info.iCtrlId = static_cast<int>(msg.wParam);
365 Info.dwContextId = 0;
366 EvHelp(Info);
367 return true;
368 }
369 }
370 else{
371 switch (msg.message) {
372 case WM_KEYDOWN :
373 if (msg.wParam == VK_F1) {
374 // If the Shift/F1 then set the help cursor and turn on the modal help state.
375 if (::GetKeyState(VK_SHIFT) < 0 && !ContextHelp) {
377 return true; // Gobble up the message.
378 }
379 }
380 else {
381 if (ContextHelp && (msg.wParam == VK_ESCAPE)) {
382 ContextHelp = false;
384 if (app)
385 app->GetMainWindow()->SetCursor(nullptr, IDC_ARROW); //?????????????????
386 return true; // Gobble up the message.
387 }
388 }
389 break;
390
391 case WM_MOUSEMOVE :
392 case WM_NCMOUSEMOVE :
393 if(ContextHelp){
395 return true; // Gobble up the message.
396 }
397 break;
398
399 case WM_INITMENU :
400 if(ContextHelp) {
402 return true; // Gobble up the message.
403 }
404 break;
405
406 case WM_ENTERIDLE :
407 if(msg.wParam == MSGF_MENU)
408 if (GetKeyState(VK_F1) < 0) {
409 ContextHelp = true;
411 if (app)
412 app->GetMainWindow()->PostMessage(WM_KEYDOWN, VK_RETURN, 0L);
413 return true; // Gobble up the message.
414 }
415 break;
416
417 default :
418 ;
419 } // End of switch
420 }
421 // Continue normal processing.
422 return false;
423}
424
425//
426/// Return true if the control id is the same as the context entry's control id.
427//
428static bool
429MatchControlId(const THelpContext& context, int controlId, HWND hwnd)
430{
431 if (context.GetControlContextId() == controlId &&
432 context.GetWindow() && context.GetWindow()->IsChild(hwnd)) {
433 return true;
434 }
435 return false;
436}
437
438//
439/// Returns true if a match for the control ID was found.
440//
441bool
443 int controlId, HWND hwnd) const
444{
445 // for each item in the context table
446 //
447 for(TContextListIterator iterator(*ContextTable); iterator; iterator++){
448 context = iterator.Current();
449
450 // try to match the control id
451 //
453 THelpContext* indirect = reinterpret_cast<THelpContext*>(context.GetWindow());
455 if (MatchControlId(*indirect, controlId, hwnd)) {
456 context = *indirect;
457 return true;
458 }
459 indirect++;
460 }
461 }
462 else if (MatchControlId(context, controlId, hwnd))
463 return true;
464 }
465 return false;
466}
467
468//
469/// Return true if the menu item identifier matches a context entry's menu
470/// item identifier.
471//
472static bool
473MatchMenuId(const THelpContext& context, int menuId)
474{
475 if (context.GetMenuContextId() == menuId) {
476 return true;
477 }
478 return false;
479}
480
481//
482/// Returns true if a match for the menu item ID was found.
483//
484bool
486{
487 // for each item in the context table
488 //
489 for (TContextListIterator iterator(*ContextTable); iterator; iterator++) {
490 context = iterator.Current();
491
492
493 // try to match the menu item identifier
494 //
496 THelpContext* indirect = reinterpret_cast<THelpContext*>(context.GetWindow());
498 if (MatchMenuId(*indirect, menuId)) {
499 context = *indirect;
500 return true;
501 }
502 indirect++;
503 }
504 }
505 else if (MatchMenuId(context, menuId))
506 return true;
507 }
508 return false;
509}
510
511//
512/// Adds an entry into the global context table.
513//
514void
516{
517 ContextTable->Add(THelpContext(window, helpId, menuId, controlId));
518}
519
520static bool
521WindowsEqual(const THelpContext& context, void* ptr)
522{
523 TWindow* targetWindow = static_cast<TWindow*>(ptr);
524 if (context.GetWindow() == targetWindow)
525 return true;
526 return false;
527}
528
529//
530/// Removes all the entries in the context table for the window.
531//
532void
534{
535 THelpContext* context = ContextTable->FirstThat(WindowsEqual, window);
536 while (context) {
537 ContextTable->DetachItem(*context);
538 context = ContextTable->FirstThat(WindowsEqual, window);
539 }
540 if (ContextTable->Empty())
542}
543
544//
545/// Default constructor that initializes every data member to zero.
546//
548:
549 Window(nullptr),
550 HelpFileContextId(0),
551 MenuContextId(0),
552 ControlContextId(0)
553{
554}
555
556//
557/// Convenient constructor to initialize the context entry with the
558/// proper ids.
559//
561:
562 Window(window),
563 HelpFileContextId(helpId),
564 MenuContextId(menuId),
565 ControlContextId(controlId)
566{
567}
568
569//
570/// Makes a copy of the context entry.
571//
573{
574 *this = other;
575}
576
577//
578// Do nothing.
579//
583
584//
585/// Makes a copy of the context entry.
586//
589{
590 HelpFileContextId = other.GetHelpFileContextId();
591 MenuContextId = other.GetMenuContextId();
592 ControlContextId = other.GetControlContextId();
593 Window = other.GetWindow();
594 return *this;
595}
596
597//
598/// Returns true if the context entries match.
599//
600bool
602{
603 return Window == other.GetWindow() &&
604 HelpFileContextId == other.GetHelpFileContextId() &&
605 MenuContextId == other.GetMenuContextId() &&
606 ControlContextId == other.GetControlContextId();
607}
608//
609//
610//
611bool
613{
614 return HelpFileContextId < other.GetHelpFileContextId();
615}
616
617} // OWL namespace
618/* ========================================================================== */
619
Definition of class TApplication.
#define PRECONDITION(condition)
Definition checks.h:227
Derived from TModule and TMsgThread and virtually derived from TEventHandler, TApplication acts as an...
Definition applicat.h:141
Base class for an extensible interface for auto enabling/disabling of commands (menu items,...
Definition window.h:209
TCursor, derived from TGdiBase, represents the GDI cursor object class.
Definition gdiobjec.h:730
TEventHandler is a base class from which you can derive classes that handle messages.
Definition eventhan.h:162
TGadget is the base class for the following derived gadget classes:
Definition gadget.h:120
Derived from TWindow, TGadgetWindow maintains a list of tiled gadgets for a window and lets you dynam...
Definition gadgetwi.h:122
THelpContext is a class that maintains information about a menu item id and a child control id with a...
Definition hlpmanag.h:116
bool operator==(const THelpContext &) const
Returns true if the context entries match.
Definition hlpmanag.cpp:601
bool operator<(const THelpContext &) const
Definition hlpmanag.cpp:612
THelpContext()
Default constructor that initializes every data member to zero.
Definition hlpmanag.cpp:547
THelpContext & operator=(const THelpContext &)
Makes a copy of the context entry.
Definition hlpmanag.cpp:588
THelpFileManager, which is designed to be a mix-in for TApplication, uses the global context table.
Definition hlpmanag.h:154
virtual bool ProcessHelpMsg(MSG &msg)
Definition hlpmanag.cpp:355
HWND HtmlHelp(TWindow *, LPCTSTR lpszHelp, uint hlpCmd, DWORD_PTR data)
Definition hlpmanag.cpp:164
TBaseList< THelpContext > TContextList
Definition hlpmanag.h:197
void RemoveContextInfo(TWindow *)
Removes all the entries in the context table for the window.
Definition hlpmanag.cpp:533
void EvHelp(const HELPINFO &)
Event handler for the WM_HELP message.
Definition hlpmanag.cpp:324
void AddContextInfo(TWindow *, int helpId, int menuId, int controlId)
Adds an entry into the global context table.
Definition hlpmanag.cpp:515
virtual ~THelpFileManager()
Deletes the allocated context table.
Definition hlpmanag.cpp:106
virtual void SetHelpCursor()
Definition hlpmanag.cpp:248
THelpFileManager(const tstring &helpFileName)
Constructor.
Definition hlpmanag.cpp:90
bool GetHelpContextFromMenu(THelpContext &, int menuId) const
Returns true if a match for the menu item ID was found.
Definition hlpmanag.cpp:485
virtual void DeactivateHelp()
Deactivates the help.
Definition hlpmanag.cpp:143
tstring GetHelpFile() const
Returns the name of the help file.
Definition hlpmanag.h:318
virtual void ActivateHelp(TWindow *, int helpFileContextId, uint hlpCmd=HELP_CONTEXT)
Called by EvHelp() to activate the help file with the help context ID.
Definition hlpmanag.cpp:116
TContextList * ContextTable
Definition hlpmanag.h:199
void SetHelpFile(const tstring &helpFileName)
Changes the name of the help file.
Definition hlpmanag.cpp:227
void CeContextHelp(TCommandEnabler &ce)
Definition hlpmanag.cpp:272
bool GetHelpContextFromControl(THelpContext &, int controlId, HWND ctrl) const
Returns true if a match for the control ID was found.
Definition hlpmanag.cpp:442
THlpPopup(uint id=0)
Definition hlpmanag.cpp:45
void SetWindowsPos(const TRect &rect)
Definition hlpmanag.cpp:80
void SetToolBarFlags(int flags)
Definition hlpmanag.cpp:73
void SetProperties(int prop)
Definition hlpmanag.cpp:66
void SetStyle(int style)
Definition hlpmanag.cpp:59
ObjectWindows dynamic-link libraries (DLLs) construct an instance of TModule, which acts as an object...
Definition module.h:75
TPoint is a support class, derived from tagPOINT.
Definition geometry.h:87
TRect is a mathematical class derived from tagRect.
Definition geometry.h:308
TWindow, derived from TEventHandler and TStreamableBase, provides window-specific behavior and encaps...
Definition window.h:414
HWND ChildWindowFromPoint(const TPoint &point) const
Determines which of the child windows contains the point specified in TPoint.
Definition window.h:2238
void ScreenToClient(TPoint &point) const
Uses the screen coordinates specified in point to calculate the client window's coordinates and then ...
Definition window.h:2192
HWND GetHandle() const
Returns the handle of the window.
Definition window.h:2020
#define _tcsicmp
Definition cygwin.h:76
#define _T(x)
Definition cygwin.h:51
#define _tcsrchr
Definition cygwin.h:86
#define DEFINE_RESPONSE_TABLE1(cls, base)
Macro to define a response table for a class with one base.
Definition eventhan.h:492
Definition of class TFrameWindow.
Definition of TGadgetList, TGadgetWindow & TGadgetWindowFont A list holding gadgets,...
Declares THelpContext and THelpFileManager.
Object Windows Library (OWLNext Core)
Definition animctrl.h:22
EV_OWLHELPHIT
Definition hlpmanag.cpp:241
TWindow * GetWindowPtr(HWND, const TApplication *)
Raw function to retrieve a TWindow pointer given an HWND from the a given app, or any app (app==0).
Definition window.cpp:1557
bool IsLastIndirectContext(const THelpContext &context)
Return true if this entry is the last entry.
Definition hlpmanag.h:305
char tchar
Definition defs.h:77
bool ToBool(const T &t)
Definition defs.h:291
bool IsIndirectHelpContext(const THelpContext &context)
Return true if the context entry is a pointer to another table.
Definition hlpmanag.h:292
OWL_DIAGINFO
Definition animctrl.cpp:14
END_RESPONSE_TABLE
Definition button.cpp:26
std::string tstring
Definition defs.h:79
unsigned int uint
Definition number.h:25
EV_WM_HELP
Definition hlpmanag.cpp:240
STDAPI DllCanUnloadNow()
OLE 2.0 entry point for checking if DLL has no clients and can be unloaded.
Definition ocreg.cpp:543
STDAPI DllGetClassObject(const GUID &clsid, const GUID &iid, void **retObj)
OLE 2.0 entry point for obtaining a class factory for a particular CLSID Don't let any exceptions blo...
Definition ocreg.cpp:524
#define TYPESAFE_DOWNCAST(object, toClass)
Definition defs.h:269
Definition of container classes used and made available by OWL.
Base window class TWindow definition, including HWND encapsulation.
#define EV_COMMAND_ENABLE(id, method)
Response table entry for enabling a command.
Definition windowev.h:193
#define EV_COMMAND(id, method)
Response table entry for a menu/accelerator/push button message.
Definition windowev.h:171