Now I made it work also in the program in handling F1 key. Upon handling F1 key, I called this API to launch the Help Window and populate the keyword textbox with two levels keywords separated with two spaces:
{
System.Windows.Forms.Help.ShowHelp(this, "file:///C:/apps/MyHelpContentNew/QACT.chm",
System.Windows.Forms.HelpNavigator.KeywordIndex, "key2 x_subkey_of_key2");
}
Then, I need send a "ENTER" key to that Help Window. I read some MSDN doc and figured out the following ways to send the "ENTER" key to that window:
First we need call Win32 function EnumChildWindows() to lookup all open windows. The Win32 function will callback to C# for processing of each open window. So when calling the Win32 function, we need pass a C# function as callback. This C# function is defined as a Delegate and inside it we can filter out the HTML Help Window and send "ENTER" key to it. The HTML Help Window is usually called Your-App-Name+Help. For example, if you application is named "XYZ", then the HTML Help window launched by ShowHelp() is called "XYZ Help". Here is the code:
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Text;
class YourClass {
[DllImport("user32.dll")]
public static extern bool SetForegroundWindow(IntPtr hWnd);
// declare the delegate
public delegate bool WindowEnumDelegate(IntPtr hwnd,
int lParam);
// declare the API function to enumerate child windows
[DllImport("user32.dll")]
public static extern int EnumChildWindows(IntPtr hwnd,
WindowEnumDelegate del,
int lParam);
// declare the GetWindowText API function
[DllImport("user32.dll")]
public static extern int GetWindowText(IntPtr hwnd,
StringBuilder bld, int size);
//define your callback function:
public static bool WindowEnumProc(IntPtr hwnd, int lParam)
{
// get the text from the window
StringBuilder bld = new StringBuilder(256);
GetWindowText(hwnd, bld, 256);
string text = bld.ToString();
if (text.Length > 0 )
{
if (text == "XYZ Help")
{
//IntPtr h = p.MainWindowHandle;
SetForegroundWindow(hwnd);
SendKeys.Send("{ENTER}");
}
}
return true;
}
//In your F1 key handler, after launch the Help Window by calling ShowHelp(), instantiate the //callback function delegate and invoke the EnumChildWindows():
private void GenericTreeView_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.F1)
{
System.Windows.Forms.Help.ShowHelp(this, "file:///C:/apps/MyHelpContentNew/QACT.chm",
System.Windows.Forms.HelpNavigator.KeywordIndex, "key2 x_subkey_of_key2");
// instantiate the delegate
WindowEnumDelegate del
= new WindowEnumDelegate(WindowEnumProc);
// call the win32 function
EnumChildWindows(IntPtr.Zero, del, 0);
}
}
}
Voila!
You will see that upon pressing F1 key, the Help Window nicely opens the correct HTML file and slides to the anchor that is pointed to by the two level keywords!
BTW, I found putting the index inside the HTML file does not help (even if I enable the option of using keyword inside HTML file). I have to put the keyword in the keyword file explicitly.
Enjoy!