Alaska Software Inc. - CHM Stay On Top - Solution and Test Results
Username: Password:
AuthorTopic: CHM Stay On Top - Solution and Test Results
Clayton Jones CHM Stay On Top - Solution and Test Results
on Tue, 18 Dec 2012 23:17:41 -0500
Hello Don, Raymond and Andreas,

Raymond alerted me to this thread and we've been corresponding about
it.  To make a long story short, the problem he was having was caused
by a SetAppFocus() call in the keyhandler of the Child window that had
the problem (when called from the Main window in his app the help
window opened normally).

In the Child window an F1 helplink had been attached to the window

   oDlg:helplink := tdHelpLabel(n)

When F1 was pressed the help window opened initially over the app as
would be expected.  But the keystroke also triggered a pass through
the window's keyhandler function, at the bottom of which is this

  SetAppFocus(oBrow)

The purpose of this is to ensure that focus stays on the browse no
matter what the user does.  The result was the help window opened over
the app for a brief instant and then disappeared behind the app when
putting focus on the browse brought the app to front.

The solution was to add some code in the keyhandler to prevent
resetting focus when F1 is pressed.  Once that was done everything
worked ok.

I called Don and relayed this info and he said he'd give it a try and
let me know if it solved his issue.  I haven't heard back yet but he
did say that he had noticed that the help window appeared on top for a
brief instant, so I'm confident it's the same problem.

An important point here is that this issue has nothing to do with the
help object's owner.

Andreas, in your remarks you mentioned some other things that caught
my attention and were worthy of testing, and I have some results to
report.  But first this:

 "I don't have or use TopDown, but I assume that the "AppDesktop()" in
  the "tdHelpObj()" function defines the Owner of the "XbpHelp()"
  object."

That's correct and it deserves some explanation.  tdHelpObj() and
tdHelpLabel() are merely wrapper functions for XbpHelp and
XbpHelpLabel.  tdHelpObj() creates a help object and assigns it to a
static variable, which allows it to serve as a Get/Set function.
tdHelpLabel() creates a helpLabel object and automatically assigns the
help object to it's :helpObject ivar.  So these are just convenience
functions and don't change the default behavior. 


            *** Why AppDesktop() ? ***

I began recommending that in the TD docs quite some years ago while
still using XP and I had begun using chm help files.  There was a
strange problem related to the task bar buttons for the app and the
help file.  I think it was if you clicked on the help file's task bar
button, focus went to it ok, but wouldn't go back to the app later by
clicking on the app's task bar button, or maybe the ALT-TAB feature
couldn't do it...or something like that.  Whatever it was it was a
definite problem and using AppDesktop() as the owner cured it.  I've
been using it that way myself ever since without any problems, and all
these years have never received a problem report from anyone.

Now on to other things, this:
 --------------------------------------------------------------------
 "If that is the case [using AppDesktop()], than this would explain
 why the HTML Help dialog would be shown (randomly) behind other
 dialogs, as it uses the  Desktop as the Owner.

 Instead, create a new "XbpHelp()" object -- or update it with 
 ":Configure()" if you like -- to always have your top-level Dialog as
 the Owner, before you assign it to an "XbpHelpLabel()" object or
 before using it directly.

 The MS HTML Help Viewer requires a valid Window (Dialog) Handle,
 which the Alaska Xbase++ runtime will determine from the "oOwner" of
 the "XbpHelp()" object. So, if you create separate Help Objects for
 each Dialog -- or even for each "XbpHelpLabel()" -- with the correct
 Dialog (or XbasePart) as the Owner of the Help Objects -- or if you
 change the Owner of the Help Object with ":Configure()" -- you
 shouldn't get those issues anymore."
 --------------------------------------------------------------------

...and this from another post:
 --------------------------------------------------------------------
 "Another thing that might cause (HTML Help Viewer) dialogs to be
 created behind and hidden by other dialogs, could be that you call
 the Help with the wrong Dialog as Owner.

   oHelp := XbpHelp():New():Create(oOwner, cHelpFile, cTitle)

 You should use the active Dialog -- usually a top-level window -- as
 theoOwner of the XbpHelp object. If you use "SetAppWindow()", or
 re-use thesame XbpHelp object without a valid oOwner, the HTML Help
 Viewer dialog might open behind other dialogs. Basically, each
 top-level dialog should have its own XbpHelp object and each
 XbpHelpLabel object should have the associated XbpPart (or the
 XbpPart's Parent Dialog) as its owner."
 --------------------------------------------------------------------

This all struck me as very odd because I've been using AppDeskTop() as
the owner for years without any problems of any sort.  The help
objects are always created at startup, and the help window can be
called at any time from anywhere within the app, without any sort of
problems.  So I decided to do some tests.

First, I recompiled the TD demo app using SetAppWindow() as the oHelp
owner, and the original problem I experienced using XP was gone.  I'm
testing now on Win7 and Win8.  So apparently whatever caused the
problem has been fixed in win7/8 (and maybe in XP as well on one of
the updates - I don't know and I can't test it now).  So at least for
Win7/8 it's ok to use SetAppWindow().  I see no difference in behavior
with either one.

Next, the top-level window question.  The TD demo app uses several
top-level windows besides the Main window, chief among which is the
print preview window, so I did the test with that.  I attached a
helplink to the preview window 

 ::oPwin:helplink := tdHelpLabel(n)   

I first compiled it with SetAppWindow() as the oHelp owner in
demoMain.prg, then opened a print preview window and pressed F1.  The
help window opened normally over the preview window.  When help was
called from the main menu with the Main window having focus, it opened
normally over the Main window.  I then left the help window open and
went back to the preview window and pressed F1, and it brought the
help window to front over the preview window.  I tested every
combination I could think of and in every case the behavior was normal
and without anomalys.  I then recompiled with AppDeskTop() as owner
and all the behavior was identical.  

Based on these tests I can only conclude that

1) It makes no difference whether the owner is AppDeskTop() or
SetAppWindow().  

2) Top-level windows do not have to be the owner of a help object if
help is called from within them.


Note: this entire discussion assumes that the app is pure GUI and
SetAppWindow() returns a reference to the Main window.


Andreas, I'm wondering if the observations that led you to your
conclusions were from an earlier time and things are different now,
just as my observation that AppDeskTop() was necessary is no longer
valid (at least for Win7/8).  This has happened to me a number of
times over the years, most commonly when a workaround for an Xbase++
problem became unnecessary when the problem was fixed.  In that regard
this all seems rather familiar.  Anyway, this has been an interesting
pursuit and it cleared up some things.

The only unanswered question is whether the original problem in XP,
which required using AppDesktop() as owner, has been fixed in one of
the updates (it's even possible that it was an Xbase++ problem and not
the OS).  If there are any XP-using readers out there, it would be
great if you could test this and let us know what happens.  I will be
updating the TD docs on this.

I hope this has been helpful.


Regards,
Clayton

Clayton Jones   www.cjcom.net 
 Top-Down Library for Xbase++
 X-DBU Database Utility   
 X-MEMO Memo Field Replacement
 Spell-X  Spell Checking for Xbase++
Raymond FischbachRe: CHM Stay On Top - Solution and Test Results
on Wed, 19 Dec 2012 13:46:17 +0100
Clayton Jones a exprimé avec précision :
> The only unanswered question is whether the original problem in XP,
> which required using AppDesktop() as owner, has been fixed in one of
> the updates (it's even possible that it was an Xbase++ problem and not
> the OS).  If there are any XP-using readers out there, it would be
> great if you could test this and let us know what happens.  I will be
> updating the TD docs on this.

Hello Clayton,

I tested your solution(s) on an old XP-SP3 machine.
There is no problem on my system with AppDeskTop() or without.

Everything is OK.

Best regards,
Raymond
Andreas Gehrs-Pahl
Re: CHM Stay On Top - Solution and Test Results
on Sat, 12 Jan 2013 15:43:55 -0500
Clayton,

>Andreas, I'm wondering if the observations that led you to your
>conclusions were from an earlier time and things are different now,
>just as my observation that AppDeskTop() was necessary is no longer
>valid (at least for Win7/8).  This has happened to me a number of
>times over the years, most commonly when a workaround for an Xbase++
>problem became unnecessary when the problem was fixed.  In that regard
>this all seems rather familiar.  Anyway, this has been an interesting
>pursuit and it cleared up some things.

The reason I suspected a wrong Owner for the Help Object was simply based 
on my own (working) code, which always uses the corresponding dialog (or 
object) as the owner for the Help Object. I also read the Help&Manual 
documentation about the MS HTML Help Viewer, which indicated that a valid 
Owner Handle is required to create the HTML Help Viewer dialog. I have 
since found that this Parent/Owner is only needed as the recipient of 
(Windows) messages, and that it can be NULL or simply the Desktop.

The following MSDN web pages seem to clarify this:

http://msdn.microsoft.com/en-us/library/windows/desktop/ms644704(v=vs.85).aspx
http://msdn.microsoft.com/en-us/library/windows/desktop/ms670084(v=vs.85).aspx
http://msdn.microsoft.com/en-us/library/office/aa164218(v=office.10).aspx

Andreas

Andreas Gehrs-Pahl
Absolute Software, LLC

phone: (989) 723-9927
email: Andreas.GP@Charter.net
       Andreas.Gehrs-Pahl@InterAct911.com
       Andreas.Gehrs-Pahl@EJusticeSolutions.com
       Andreas@DDPSoftware.com
web:   http://www.Aerospace-History.net