Watch, Follow, &
Connect with Us

For forums, blogs and more please visit our
Developer Tools Community.


Welcome, Guest
Guest Settings
Help

Thread: HtmlHelp focus issue


This question is answered. Helpful answers available: 2. Correct answers available: 1.


Permlink Replies: 2 - Last Post: Dec 3, 2015 8:45 AM Last Post By: Michael Stammbe...
Michael Stammbe...

Posts: 7
Registered: 8/28/14
HtmlHelp focus issue  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Nov 26, 2015 2:59 AM
Hi everyone,
I'm currently facing an issue regarding HTML help with C++ Builder Seattle Update 1.

If I remember correctly, the usual way to invoke a CHM help file consists of the following steps:
- Set Application->HelpFile to the corresponding CHM file's path.
- Include header Vcl.HtmlHelpViewer.hpp to the main form (or any form which should be able to invoke application help pages).
- link the unit to those forms:
 #pragma link Vcl.Htmlhelpviewer


Then, to invoke help, use HelpCommand. In my specific case, that usually means to use parameters HELP_CONTEXT and some context ID. These work fine, btw.

My form doesn't have any specific settings regarding foreground/background policies (DefaultMonitor, FormStyle, PopupMode and even WindowState are all set to default).
Nevertheless, when opening the application help, it will always open the help popup in the background (it flashes to foreground and vanishes to the back within fractions of a second).
Of course, I don't want that. A user who clicks for help shouldn't have to play peek-a-boo first. But how do I set a help window invoked by HelpCommand to foreground explicitly?

Unfortunately, HelpCommand doesn't allow access to the help window's handle or form, probably due to the fact that this is Windows API and HelpCommand is a generic wrapper. In turn, that doesn't allow me to set the help window's PopupParent to my main form. It most likely isn't a VCL form and therefore doesn't even have a PopupParent in that sense.

I've tried parameter HELP_CONTEXTPOPUP without success. The HelpContext is always selected correctly, though.
Given that I'm running out of ideas how to get things running using HelpCommand, I've been searching elsewhere, too.

In previous Howtos, I found direct use of htmlhelp.lib. According to MSDN documentation, a call to
 
 HtmlHelp(WindowHandle, Application->HelpFile.c_str(), HH_HELP_CONTEXT, contextID) 

(where contextID is my HelpContext as given by Help & Manual) hands over my main form's window handle and creates the Z order I would like to achieve. So I added htmlhelp.h to my main form and coded away.
When I try to use the command there is a linker error for HtmlHelpW.

I've tried to explicitly add the htmlhelp.lib from Embarcadero lib to my project, as well as the one that was used in our SW versions prior to HelpCommand, but the result stays the same; it won't find the implementation for HtmlHelpW and thus won't link.
Investigating, it seems that the Embarcadero version of htmlhelp.lib tries to load some htmlhelp.dll, but there is no such file on my system. Where should that be? How can I obtain it? Or is that htmlhelp.lib outdated? In this case: where can I find an up-to-date version?
Or am I missing some point here? Is there some type of behavior that would bring my main window up front after a button click (other than some explicit ActiveControl setters or calls to BringToFront? Those I've been able to outrule using a debugger and full text search) which I might be able to catch and ignore somehow?

Thanks for reading up to here! Hope someone can push me to the right direction.
Michael Stammbe...

Posts: 7
Registered: 8/28/14
Re: HtmlHelp focus issue  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Dec 3, 2015 3:38 AM   in response to: Michael Stammbe... in response to: Michael Stammbe...
After a bit of research, I can add the following.

If I set the FormStyle to fsStayOnTop, the help just stops flashing in the foreground but opens in the background. So initially, all is well.

If I use any method to set the help window focused by force, it has no effect.

The method I used for focusing the help window is as follows:
int CALLBACK ProcessOpenWindows(HWND hwnd, LPARAM params){
    wchar_t title[21];
    memset(title, 0, sizeof(title)); // make sure the text will end with '\0' so parsing to String works
    GetWindowText(hwnd,title,sizeof(title)-1);
	String t(title);
    int winpos = t.Pos("My Help Window Title");
    if (winpos > 0) { // this window is my help window
        int rv = SetForegroundWindow(hwnd); 
        // in my test, rv is set to 1, the C/C++ equivalent of "true", indicating this worked
        if (rv == 0)
            return 1;
        return 0; // this means "I've found what I needed, stop enumerating" 
    }
    return 1; // "Keep sending me more window handles, please"
}


The help callback is as follows:
...
void TMyForm::ActHelpExecute(TObject *Sender) 
{
    TriggerHelpContext(0);
}
void TMyForm::TriggerHelpContext(int index)
{
    Application->HelpCommand(HELP_CONTEXTPOPUP, index);
    EnumWindows(ProcessOpenWindows, NULL);
}
...


While the EnumWindows approach is perfectly capable of focusing the desired window, it doesn't solve my problem. In fact, if I put a Sleep statement between the call to HelpCommand and the force focus setter, the help form simply stays in the foreground longer before disappearing. So, it disappears on help callback exit.
Given that for the duration of Sleep, the help window doesn't get filled with content, it is equally possible that something obscure is being triggered by help command completion and that that something is focusing my main form.

I've also tested using a StdHelpAction instead and used MyForm->OnHelp for debugging for both.
StdHelp will behave just like the HelpCommand after MenuClick.
OnHelp is being triggered only once (right after triggering HelpCommand). It doesn't wait for the callback to exit.

Any idea what that might be?

Edited by: Ute Witt on Dec 3, 2015 3:52 AM (More info/test results)
Michael Stammbe...

Posts: 7
Registered: 8/28/14
Re: HtmlHelp focus issue  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Dec 3, 2015 8:45 AM   in response to: Michael Stammbe... in response to: Michael Stammbe...
Ute Witt wrote:
Is there some type of behavior that would bring my main window up front after a button click (other than some explicit ActiveControl setters or calls to BringToFront?

Actually, yes, there is.
The phenomenon occurs whenever a hint is displayed for some component on the main form. The hint trigger is so dominant that it shoots the main window back up front.

The core question now is how to control hint behavior, but I guess from here it's manageable.
Legend
Helpful Answer (5 pts)
Correct Answer (10 pts)

Server Response from: ETNAJIVE02