Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
29253 Discussions

How to prevent menu item from getting grayed

Jan_S_
Beginner
1,027 Views

Hello,

Recently I became motivated to revise an old Windws Fortran program that I developed with CVF Pro v. 6.6.C . I now have added an HTMLHelp (.chm) file which can be accessed by clicking a menu item "Help | Manual" on the Main window's menu bar. However, when a dialog window is opened in the Main window, all menu items on the menu bar get grayed. This means that the helpfile cannot be accessed if any (dialog) window has been opened.
I hope someone can tell me how this problem can solved, preferably by keeping the menu sub item enabled when any window is opened within the Main window.
Thanks for any suggestion!

Jan S.

0 Kudos
1 Solution
Paul_Curtis
Valued Contributor I
1,027 Views

Here's what works for me.  The .chm file is prepared separately with a help editor, and lives in a defined location relative to the .exe file, whose location is determined  dynamically when the program is started.  WM_HELP messages are processed in the main program loop, and also in the (default section of the) proc function(s) for each dialog.  The Htmlhelp.lib file is added to the project as a resource.

!   Function HtmlHelp() is in HtlmHelp.lib which
!   is added to the project as a resource
INTERFACE
    FUNCTION HtmlHelp (hWndMain, lpszHelp, uCommand, dwData)
        USE ifwinty
        integer(BOOL) :: HtmlHelp ! BOOL
        !DEC$ ATTRIBUTES DEFAULT, STDCALL, DECORATE, ALIAS:'HtmlHelpA' :: HtmlHelp
        integer(HANDLE) hWndMain ! HWND hWndMain
        !DEC$ ATTRIBUTES REFERENCE, ALLOW_NULL :: lpszHelp
        character*(*) lpszHelp ! LPCSTR lpszHelp
        integer(UINT) uCommand ! UINT uCommand
        integer(ULONG_PTR) dwData ! ULONG_PTR dwData
    END FUNCTION
END INTERFACE

! HTML help command flags
INTEGER, PARAMETER                    :: HH_DISPLAY_TOPIC          = #0000
INTEGER, PARAMETER                    :: HH_DISPLAY_TOC         = #0001
INTEGER, PARAMETER                    :: HH_DISPLAY_INDEX         = #0002
INTEGER, PARAMETER                    :: HH_DISPLAY_SEARCH     = #0003
INTEGER, PARAMETER                    :: HH_KEYWORD_LOOKUP     = #000D
INTEGER, PARAMETER                    :: HH_DISPLAY_TEXT_POPUP = #000E
INTEGER, PARAMETER                    :: HH_CLOSE_ALL          = #0012


!   helpfile path, null-terminated
CHARACTER(LEN=200)    :: helppathname
helppathname = localroot//'\bin\yourhelpfile.chm'//CHAR(0)

!   proc function code to process help messages from F1 key
SELECT CASE (msg)
CASE (WM_HELP)
    rval = HtmlHelp (ghwndmain, helppathname, HH_DISPLAY_TOPIC, NULL)    
! ...
END SELECT

View solution in original post

0 Kudos
7 Replies
Paul_Curtis
Valued Contributor I
1,027 Views

Two comments:

First, menus or controls become greyed-out as a signal that their containing window no longer has the user focus, which has been moved to some other window (ie, your new dialog which has appeared on top of its parent).  The API function SetFocus(hwnd) will force the windows focus to a particular window, by handle.  If a window already has the focus, SetFocus() has no effect.  Another approach would be to specify your dialog as modeless, in which case the focus can be shared with other windows and messages will be passed back to the parent window's proc.

Second, html help can always be invoked by the system F1 key, there is no need to have separate help buttons on each menu or dialog.

 

0 Kudos
Jan_S_
Beginner
1,027 Views

Hello Paul,

Thank you for your answer.
The F1 option I like most because it seems the simplest one. However, it does not work (yet). Probably some extra coding is required. The code I use to call the helpfile by clicking the menu sub item "Manual" is as follows:

            CASE (IDM_HELPCONTENTS)

              HelpPath = PATHNM(1:PathLength)//'/HelpHBSH-3.chm'C
              iret = HtmlHelp (hwnd, HelpPath(1:LEN_TRIM(HelpPath)), HH_DISPLAY_TOPIC, NULL)
                if (iret <= 0) then
                    lpszMessage = "Unable to activate help"C
                    iret = MessageBox (hWnd,lpszMessage,"HBSH", &  
                       IOR(MB_SYSTEMMODAL,IOR(MB_OK, MB_ICONHAND)))                                            
                end if

              MainWndProc = 0
              return

I would be happy if you could explain what to do for realizing the F1 option.

Jan Somer

 

0 Kudos
Paul_Curtis
Valued Contributor I
1,027 Views

My help engine is summoned by the WM_HELP message generated by Windows when F1 is pressed, and WM_HELP is serviced both in the main windows proc as well as part of the default message handling for every dialog, calling HtmlHelp().

Also, your HelpPath string should be null-terminated, in which case the LEN_TRIM would be superfluous (and, for that matter, using LEN_TRIM will omit the trailing null byte, good thing the HtmlHelp routine ignores your string prep).

 

0 Kudos
Jan_S_
Beginner
1,027 Views

Paul,

I am getting more and more confused. I understood that replacing IDM_HELPCONTENTS by WM_HELP would be the solution, but then nothing works anymore.
So, the pertinent code has now become like this:

            CASE (IDM_HELPCONTENTS)
              HelpPath = PATHNM(1:PathLength)//'/HelpHBSH-3.chm'C
              iret = HtmlHelp (hwnd, HelpPath, HH_DISPLAY_TOPIC, NULL)
               if (iret <= 0) then
                    lpszMessage = "Unable to activate help"C
                    iret = MessageBox (hWnd,lpszMessage,"HBSH", &  
                      IOR(MB_SYSTEMMODAL,IOR(MB_OK, MB_ICONHAND)))                                            
                end if

              MainWndProc = 0
              return

Probably as a result of leaving out the string (1:LEN_TRIM(HelpPath)) the value of iret after process is no longer =1 but a high positive number. In this situation both menu item "Manual" as well as F1 work fine as long as there is no any dialog opened. If there is, then both F1 and "Manual" do not work.
The problem is also that my knowledge is insufficient to fully understand everything you tel me. It may help when I tell you about the rest of my program.
It may help when I tell you that I started with the stuf that you showed in a post in topic 295837, being an INTERFACE and a CASE (WM_HELP) code and a htmlhelp.lib file. I remember that I had a problem with "HTMLHelpA" in the interface. I did however include the htmlhelp.lib file.
I was rather happy to find elswhere the original module that Jugoslav Dujic composed in 2001. I found that in a topic 275420.
Therefore, in the MainWndProc-function I included the code "use HTMLHELPM".

I hope that will help me any further. If you could supply me with suitable sample code I would be very happy!

Jan Somer

 

 

 

 

 

0 Kudos
Paul_Curtis
Valued Contributor I
1,028 Views

Here's what works for me.  The .chm file is prepared separately with a help editor, and lives in a defined location relative to the .exe file, whose location is determined  dynamically when the program is started.  WM_HELP messages are processed in the main program loop, and also in the (default section of the) proc function(s) for each dialog.  The Htmlhelp.lib file is added to the project as a resource.

!   Function HtmlHelp() is in HtlmHelp.lib which
!   is added to the project as a resource
INTERFACE
    FUNCTION HtmlHelp (hWndMain, lpszHelp, uCommand, dwData)
        USE ifwinty
        integer(BOOL) :: HtmlHelp ! BOOL
        !DEC$ ATTRIBUTES DEFAULT, STDCALL, DECORATE, ALIAS:'HtmlHelpA' :: HtmlHelp
        integer(HANDLE) hWndMain ! HWND hWndMain
        !DEC$ ATTRIBUTES REFERENCE, ALLOW_NULL :: lpszHelp
        character*(*) lpszHelp ! LPCSTR lpszHelp
        integer(UINT) uCommand ! UINT uCommand
        integer(ULONG_PTR) dwData ! ULONG_PTR dwData
    END FUNCTION
END INTERFACE

! HTML help command flags
INTEGER, PARAMETER                    :: HH_DISPLAY_TOPIC          = #0000
INTEGER, PARAMETER                    :: HH_DISPLAY_TOC         = #0001
INTEGER, PARAMETER                    :: HH_DISPLAY_INDEX         = #0002
INTEGER, PARAMETER                    :: HH_DISPLAY_SEARCH     = #0003
INTEGER, PARAMETER                    :: HH_KEYWORD_LOOKUP     = #000D
INTEGER, PARAMETER                    :: HH_DISPLAY_TEXT_POPUP = #000E
INTEGER, PARAMETER                    :: HH_CLOSE_ALL          = #0012


!   helpfile path, null-terminated
CHARACTER(LEN=200)    :: helppathname
helppathname = localroot//'\bin\yourhelpfile.chm'//CHAR(0)

!   proc function code to process help messages from F1 key
SELECT CASE (msg)
CASE (WM_HELP)
    rval = HtmlHelp (ghwndmain, helppathname, HH_DISPLAY_TOPIC, NULL)    
! ...
END SELECT

0 Kudos
andrew_4619
Honored Contributor III
1,027 Views

Hi Jan, I use html from my Fortran apps.

1) I am presuming that this is a Windows  app rather than quickwin?

When you have  a modal dialog open this will be 'blocking' so you will not  have access to the menu's via your mainwndproc until you exit the dialog. If you want to call the help function you can invoke it from the dialog proc  routine. If you create the dialog as modeless it is a separate thread and is not blocking.

2) What handle are you supplying to the html function?

3) Are you trying to access a specific topic or just the index?  Cutting and  pasting some bits of code I use html help

as follows. I access specific topics using the actual html topic urls in the chm rather than trying to match topic ID's for me this is preferable.

[fortran]

gtop='contents.htm'C

igtop=len_trim(gtop)

ghlp=gpath(1:igpath)//'helpfile.chm::/html/'//gtop(1:igtop)//CHAR(0)

dwDATA=0;uCOMMAND=0

reti4=HtmlHelp(hWnd,ghlp,uCOMMAND, dwDATA)[/fortran]

 

0 Kudos
Jan_S_
Beginner
1,027 Views

Paul,
I think I made it. The code you provided does work. Most of it, except for the CASE (WM_HELP) code, I have put in a selfmade module. That saves time end effort when preparing the dialog procs for listenig to F1 . It also means that I can remove Jugoslav's module. Now, in the proper dialog-windows I just have only to insert a USE statement and put CASE (WM_HELP)+code at the right spot. Thanks very much for your great help!

app4619
The code that you showed is quite interesting. It's very well possible that I may need it in future ,  Thanks also very much for your contribution!

0 Kudos
Reply