Skip to content

Commit

Permalink
Revert PR_9884 “Migrate HtmlHelp to CsWin32” and add unit test (dotne…
Browse files Browse the repository at this point in the history
…t#10435)

* revert PR#9884: Migrate HtmlHelp to CsWin32

* Add unit test for Help
  • Loading branch information
Epica3055 authored Dec 13, 2023
1 parent 7dd6544 commit dbc7ce3
Show file tree
Hide file tree
Showing 9 changed files with 194 additions and 67 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

internal partial class Interop
{
internal static partial class Hhctl
{
public enum HH : uint
{
DISPLAY_TOPIC = 0x00,
HELP_FINDER = 0x00,
DISPLAY_TOC = 0x01,
DISPLAY_INDEX = 0x02,
DISPLAY_SEARCH = 0x03,
SET_WIN_TYPE = 0x04,
GET_WIN_TYPE = 0x05,
GET_WIN_HANDLE = 0x06,
ENUM_INFO_TYPE = 0x07,
SET_INFO_TYPE = 0x08,
SYNC = 0x09,
RESERVED1 = 0x0A,
RESERVED2 = 0x0B,
RESERVED3 = 0x0C,
KEYWORD_LOOKUP = 0x0D,
DISPLAY_TEXT_POPUP = 0x0E,
HELP_CONTEXT = 0x0F,
TP_HELP_CONTEXTMENU = 0x10,
TP_HELP_WM_HELP = 0x11,
CLOSE_ALL = 0x12,
ALINK_LOOKUP = 0x13,
GET_LAST_ERROR = 0x14,
ENUM_CATEGORY = 0x15,
ENUM_CATEGORY_IT = 0x16,
RESET_IT_FILTER = 0x17,
SET_INCLUSIVE_FILTER = 0x18,
SET_EXCLUSIVE_FILTER = 0x19,
INITIALIZE = 0x1C,
UNINITIALIZE = 0x1D,
SAFE_DISPLAY_TOPIC = 0x20,
PRETRANSLATEMESSAGE = 0xFD,
SET_GLOBAL_PROPERTY = 0xFC
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

internal partial class Interop
{
internal static partial class Hhctl
{
public unsafe struct HH_ALINKW
{
public int cbStruct;
public BOOL fReserved;
public char* pszKeywords;
public char* pszUrl;
public char* pszMsgText;
public char* pszMsgTitle;
public char* pszWindow;
public BOOL fIndexOnFail;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

internal partial class Interop
{
internal static partial class Hhctl
{
public unsafe struct HH_FTS_QUERYW
{
public const int DEFAULT_PROXIMITY = -1;

public int cbStruct;
public BOOL fUniCodeStrings;
public char* pszSearchQuery;
public int iProximity;
public BOOL fStemmedSearch;
public BOOL fTitleOnly;
public BOOL fExecute;
public char* pszWindow;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Drawing;

internal partial class Interop
{
internal static partial class Hhctl
{
public unsafe struct HH_POPUPW
{
public int cbStruct;
public IntPtr hinst;
public uint idString;
public char* pszText;
public Point pt;
public COLORREF clrForeground;
public COLORREF clrBackground;
public RECT rcMargins;
public char* pszFont;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Runtime.InteropServices;

internal partial class Interop
{
internal static partial class Hhctl
{
[DllImport(Libraries.Hhctrl, CharSet = CharSet.Unicode, ExactSpelling = true)]
public static extern int HtmlHelpW(IntPtr hwndCaller, string? pszFile, HH uCommand, IntPtr dwData);

public static int HtmlHelpW(HandleRef<HWND> hwndCaller, string? pszFile, HH uCommand, IntPtr dwData)
{
int result = HtmlHelpW(hwndCaller.Handle, pszFile, uCommand, dwData);
GC.KeepAlive(hwndCaller.Wrapper);
return result;
}

public static unsafe int HtmlHelpW(HandleRef<HWND> hwndCaller, string? pszFile, HH uCommand, string data)
{
fixed (char* dwData = data)
{
return HtmlHelpW(hwndCaller, pszFile, uCommand, (IntPtr)(void*)dwData);
}
}

public static unsafe int HtmlHelpW<T>(HandleRef<HWND> hwndCaller, string? pszFile, HH uCommand, ref T data) where T : unmanaged
{
fixed (void* dwData = &data)
{
return HtmlHelpW(hwndCaller, pszFile, uCommand, (IntPtr)dwData);
}
}
}
}
5 changes: 0 additions & 5 deletions src/System.Windows.Forms.Primitives/src/NativeMethods.txt
Original file line number Diff line number Diff line change
Expand Up @@ -346,11 +346,6 @@ HIGHCONTRASTW
HitTestThemeBackground
HT*
HTREEITEM
HTML_HELP_COMMAND
HtmlHelpW
HH_AKLINK
HH_FTS_QUERY
HH_POPUP
HWND_*
IAccessible
IAutoComplete2
Expand Down

This file was deleted.

71 changes: 34 additions & 37 deletions src/System.Windows.Forms/src/System/Windows/Forms/Help/Help.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

using System.Drawing;
using System.Globalization;
using Windows.Win32.Data.HtmlHelp;
using static Interop.Hhctl;

namespace System.Windows.Forms;

Expand Down Expand Up @@ -95,9 +95,9 @@ public static unsafe void ShowPopup(Control? parent, string caption, Point locat
{
s_windowsFormsHelpTrace.TraceVerbose("Help:: ShowPopup");

HH_POPUP pop = new()
HH_POPUPW pop = new()
{
cbStruct = sizeof(HH_POPUP),
cbStruct = sizeof(HH_POPUPW),
pt = location,
rcMargins = new RECT(-1, -1, -1, -1), // Ignore
clrForeground = new COLORREF(unchecked((uint)-1)), // Ignore
Expand All @@ -109,8 +109,8 @@ public static unsafe void ShowPopup(Control? parent, string caption, Point locat

fixed (char* pszText = caption, pszFont = captionFont)
{
pop.pszText = (sbyte*)pszText;
pop.pszFont = (sbyte*)pszFont;
pop.pszText = pszText;
pop.pszFont = pszFont;
ShowHTML10Help(parent, null, HelpNavigator.Topic, pop);
}
}
Expand Down Expand Up @@ -160,51 +160,48 @@ private static unsafe void ShowHTML10Help(Control? parent, string? url, HelpNavi
object? htmlParam;
if (param is string stringParam)
{
HTML_HELP_COMMAND htmlCommand = MapCommandToHTMLCommand(command, stringParam, out htmlParam);
HH htmlCommand = MapCommandToHTMLCommand(command, stringParam, out htmlParam);
if (htmlParam is string stringHtmlParam)
{
PInvoke.HtmlHelp(handle, pathAndFileName, htmlCommand, stringHtmlParam);
HtmlHelpW(handle, pathAndFileName, htmlCommand, stringHtmlParam);
}
else if (htmlParam is int intParam)
{
PInvoke.HtmlHelp(handle, pathAndFileName, htmlCommand, (nuint)intParam);
HtmlHelpW(handle, pathAndFileName, htmlCommand, intParam);
}
else if (htmlParam is HH_FTS_QUERY query)
else if (htmlParam is HH_FTS_QUERYW query)
{
HH_FTS_QUERY* dwData = &query;
fixed (char* pszSearchQuery = stringParam)
{
query.pszSearchQuery = (sbyte*)pszSearchQuery;
PInvoke.HtmlHelp(handle, pathAndFileName, htmlCommand, (nuint)dwData);
query.pszSearchQuery = pszSearchQuery;
HtmlHelpW(handle, pathAndFileName, htmlCommand, ref query);
}
}
else if (htmlParam is HH_AKLINK aLink)
else if (htmlParam is HH_ALINKW aLink)
{
// According to MSDN documentation, we have to ensure that the help window is up
// before we call ALINK lookup.
PInvoke.HtmlHelp(HWND.Null, pathAndFileName, HTML_HELP_COMMAND.HH_DISPLAY_TOPIC, nuint.Zero);
HtmlHelpW(IntPtr.Zero, pathAndFileName, HH.DISPLAY_TOPIC, IntPtr.Zero);

HH_AKLINK* dwData = &aLink;
fixed (char* pszKeywords = stringParam)
{
aLink.pszKeywords = (sbyte*)pszKeywords;
PInvoke.HtmlHelp(handle, pathAndFileName, htmlCommand, (nuint)dwData);
aLink.pszKeywords = pszKeywords;
HtmlHelpW(handle, pathAndFileName, htmlCommand, ref aLink);
}
}
else
{
Debug.Fail($"Cannot handle HTML parameter of type: {htmlParam!.GetType()}");
PInvoke.HtmlHelp(handle, pathAndFileName, htmlCommand, (string)param);
HtmlHelpW(handle, pathAndFileName, htmlCommand, (string)param);
}
}
else if (param is null)
{
PInvoke.HtmlHelp(handle, pathAndFileName, MapCommandToHTMLCommand(command, null, out htmlParam), nuint.Zero);
HtmlHelpW(handle, pathAndFileName, MapCommandToHTMLCommand(command, null, out htmlParam), IntPtr.Zero);
}
else if (param is HH_POPUP popup)
else if (param is HH_POPUPW popup)
{
HH_POPUP* dwData = &popup;
PInvoke.HtmlHelp(handle, pathAndFileName, HTML_HELP_COMMAND.HH_DISPLAY_TEXT_POPUP, (nuint)dwData);
HtmlHelpW(handle, pathAndFileName, HH.DISPLAY_TEXT_POPUP, ref popup);
}
else if (param.GetType() == typeof(int))
{
Expand Down Expand Up @@ -353,66 +350,66 @@ private static int GetHelpFileType(string? url)
/// <summary>
/// Maps one of the COMMAND_* constants to the HTML 1.0 Help equivalent.
/// </summary>
private static unsafe HTML_HELP_COMMAND MapCommandToHTMLCommand(HelpNavigator command, string? param, out object? htmlParam)
private static unsafe HH MapCommandToHTMLCommand(HelpNavigator command, string? param, out object? htmlParam)
{
htmlParam = param;

if (string.IsNullOrEmpty(param) && (command == HelpNavigator.AssociateIndex || command == HelpNavigator.KeywordIndex))
{
return HTML_HELP_COMMAND.HH_DISPLAY_INDEX;
return HH.DISPLAY_INDEX;
}

switch (command)
{
case HelpNavigator.Topic:
return HTML_HELP_COMMAND.HH_DISPLAY_TOPIC;
return HH.DISPLAY_TOPIC;

case HelpNavigator.TableOfContents:
return HTML_HELP_COMMAND.HH_DISPLAY_TOC;
return HH.DISPLAY_TOC;

case HelpNavigator.Index:
return HTML_HELP_COMMAND.HH_DISPLAY_INDEX;
return HH.DISPLAY_INDEX;

case HelpNavigator.Find:
{
HH_FTS_QUERY ftsQuery = new()
HH_FTS_QUERYW ftsQuery = new()
{
cbStruct = sizeof(HH_FTS_QUERY),
iProximity = (int)HTML_HELP_COMMAND.HH_FTS_DEFAULT_PROXIMITY,
cbStruct = sizeof(HH_FTS_QUERYW),
iProximity = HH_FTS_QUERYW.DEFAULT_PROXIMITY,
fExecute = true,
fUniCodeStrings = true
};
htmlParam = ftsQuery;
return HTML_HELP_COMMAND.HH_DISPLAY_SEARCH;
return HH.DISPLAY_SEARCH;
}

case HelpNavigator.TopicId:
{
if (int.TryParse(param, out int htmlParamAsInt))
{
htmlParam = htmlParamAsInt;
return HTML_HELP_COMMAND.HH_HELP_CONTEXT;
return HH.HELP_CONTEXT;
}

// default to just showing the index
return HTML_HELP_COMMAND.HH_DISPLAY_INDEX;
return HH.DISPLAY_INDEX;
}

case HelpNavigator.KeywordIndex:
case HelpNavigator.AssociateIndex:
{
HH_AKLINK alink = new()
HH_ALINKW alink = new()
{
cbStruct = sizeof(HH_AKLINK),
cbStruct = sizeof(HH_ALINKW),
fIndexOnFail = true,
fReserved = false
};
htmlParam = alink;
return command == HelpNavigator.KeywordIndex ? HTML_HELP_COMMAND.HH_KEYWORD_LOOKUP : HTML_HELP_COMMAND.HH_ALINK_LOOKUP;
return command == HelpNavigator.KeywordIndex ? HH.KEYWORD_LOOKUP : HH.ALINK_LOOKUP;
}

default:
return (HTML_HELP_COMMAND)command;
return (HH)command;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Drawing;

namespace System.Windows.Forms.Tests;

public class HelpTests
{
[Fact]
public void ShowPopupTest()
{
Help.ShowPopup(null, "Popup", Point.Empty);
}
}

0 comments on commit dbc7ce3

Please sign in to comment.