Skip to content

Commit

Permalink
Merge pull request #114 from ahmetsait/master
Browse files Browse the repository at this point in the history
Add `_ScintillaManagedDragDrop` & improve error messages
  • Loading branch information
desjarlais authored May 6, 2024
2 parents eb63236 + 26f3b42 commit f07c188
Showing 1 changed file with 58 additions and 52 deletions.
110 changes: 58 additions & 52 deletions Shared/Scintilla.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
Expand All @@ -22,79 +23,71 @@ public class Scintilla : Control
{
static Scintilla()
{
var basePath = LocateNativeDllDirectory();
modulePathScintilla = Path.Combine(basePath, "Scintilla.dll");
modulePathLexilla = Path.Combine(basePath, "Lexilla.dll");

try
{
var info = FileVersionInfo.GetVersionInfo(modulePathScintilla);
scintillaVersion = info.ProductVersion ?? info.FileVersion;
info = FileVersionInfo.GetVersionInfo(modulePathLexilla);
lexillaVersion = info.ProductVersion ?? info.FileVersion;
}
catch
List<string> searchedPathList = new List<string>();
foreach (string path in EnumerateSatelliteLibrarySearchPaths())
{
scintillaVersion = "ERROR";
lexillaVersion = "ERROR";
// the path to the following .NET or .NET Framework satellite assemblies exists but the assemblies are not found in the directory.
// (surely a problem in the package itself or in its installation of the project).
throw new InvalidOperationException(@$"Scintilla.NET satellite assemblies not found in {basePath}");
string scintillaDllPath = Path.Combine(path, "Scintilla.dll");
string lexillaDllPath = Path.Combine(path, "Lexilla.dll");
if (File.Exists(scintillaDllPath) && File.Exists(lexillaDllPath))
{
modulePathScintilla = scintillaDllPath;
modulePathLexilla = lexillaDllPath;
try
{
var info = FileVersionInfo.GetVersionInfo(modulePathScintilla);
scintillaVersion = info.ProductVersion ?? info.FileVersion;
info = FileVersionInfo.GetVersionInfo(modulePathLexilla);
lexillaVersion = info.ProductVersion ?? info.FileVersion;
return;
}
catch
{
searchedPathList.Add(path);
}
}
else
searchedPathList.Add(path);
}

string searchedPaths = string.Join("\n", searchedPathList);

scintillaVersion = "ERROR";
lexillaVersion = "ERROR";
// the path to the following .NET or .NET Framework satellite assemblies exists but the assemblies are not found in the directory.
// (surely a problem in the package itself or in its installation of the project).
throw new InvalidOperationException($"Scintilla.NET satellite assemblies not found in any of the following paths:\n{searchedPaths}");
}

private static string LocateNativeDllDirectory()
public static IEnumerable<string> EnumerateSatelliteLibrarySearchPaths()
{
// check run-time paths
string platform = Environment.Is64BitProcess ? "x64" : "x86";
Assembly runtimeAssembly = Assembly.GetExecutingAssembly();
string managedLocation = Path.GetDirectoryName(runtimeAssembly.Location) ?? AppDomain.CurrentDomain.BaseDirectory;
string basePath = Path.Combine(managedLocation, platform);

if (Directory.Exists(basePath))
{
return basePath;
}
var runtimeAssembly = Assembly.GetExecutingAssembly();
string managedLocation = Path.GetDirectoryName(runtimeAssembly.Location) ?? AppDomain.CurrentDomain.BaseDirectory;
yield return Path.Combine(managedLocation, platform);

// check design-mode paths
string frameworkName = runtimeAssembly?.GetCustomAttribute<TargetFrameworkAttribute>()?.FrameworkName;

if (frameworkName.Contains("NETFramework"))
{
// In.NET Framework, look for the assemblies in the nuget global packages folder
Assembly designtimeAssembly = Assembly.GetAssembly(typeof(Scintilla));
string nugetScintillaPackageFolder = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile) + @"\.nuget\packages\scintilla5.net\";
// In .NET Framework, look for the assemblies in the nuget global packages folder
var designtimeAssembly = Assembly.GetAssembly(typeof(Scintilla));
string nugetScintillaPackageFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), @".nuget\packages\scintilla5.net");
string nugetScintillaPackageVersion = designtimeAssembly.GetName().Version.ToString();
basePath = Path.Combine(nugetScintillaPackageFolder + nugetScintillaPackageVersion + @"\build\" + platform);

if (Directory.Exists(basePath))
{
return basePath;
}
yield return Path.Combine(nugetScintillaPackageFolder, nugetScintillaPackageVersion, "build", platform);

// then check the project folder using the Scintilla.NET assembly location
// move up a few levels to the host project folder and append the location nuget used at install
string nugetScintillaNETLocation = designtimeAssembly.Location;
string nugetScintillaPackageName = designtimeAssembly.GetName().Name;
string rootProjectFolder = Path.GetFullPath(Path.Combine(nugetScintillaNETLocation, @"..\..\..\..\"));
basePath = Path.Combine(rootProjectFolder, @"packages\" + nugetScintillaPackageName + "." + nugetScintillaPackageVersion + @"\build\" + platform);

if (Directory.Exists(basePath))
{
return basePath;
}

throw new InvalidOperationException(@$"Unable to locate the Scintilla.NET satellite assemblies : directory '{basePath}' not found");
string rootProjectFolder = Path.GetFullPath(Path.Combine(nugetScintillaNETLocation, @"..\..\..\.."));
yield return Path.Combine(rootProjectFolder, "packages", nugetScintillaPackageName + "." + nugetScintillaPackageVersion, "build", platform);
}
else
{
// if .NET in design mode
basePath = Path.GetFullPath(Path.Combine(managedLocation, "..", "..", "build", platform));
if (Directory.Exists(basePath))
{
return basePath;
}

throw new InvalidOperationException(@$"Unable to locate the Scintilla.NET satellite assemblies : directory '{basePath}' not found");
yield return Path.GetFullPath(Path.Combine(managedLocation, @"..\..\build", platform));
}
}

Expand Down Expand Up @@ -1818,7 +1811,8 @@ protected override unsafe void OnHandleCreated(EventArgs e)
// ways to solve this, but my favorite is to revoke drag and drop from the
// native Scintilla control before base.OnHandleCreated does the standard
// processing of AllowDrop.
NativeMethods.RevokeDragDrop(Handle);
if (!this._ScintillaManagedDragDrop)
NativeMethods.RevokeDragDrop(this.Handle);

base.OnHandleCreated(e);
}
Expand Down Expand Up @@ -3276,6 +3270,18 @@ public unsafe void ClearRepresentation(string encodedString)

#region Properties

/// <summary>
/// Gets or sets whether Scintilla's native drag & drop should be used instead of WinForms based one.

Check warning on line 3274 in Shared/Scintilla.cs

View workflow job for this annotation

GitHub Actions / build (Debug)

XML comment has badly formed XML -- 'Whitespace is not allowed at this location.'

Check warning on line 3274 in Shared/Scintilla.cs

View workflow job for this annotation

GitHub Actions / build (Release)

XML comment has badly formed XML -- 'Whitespace is not allowed at this location.'
/// </summary>
/// <value><c>true</c> if Scintilla's native drag & drop should be used; otherwise, <c>false</c>. The default is false.</value>

Check warning on line 3276 in Shared/Scintilla.cs

View workflow job for this annotation

GitHub Actions / build (Debug)

XML comment has badly formed XML -- 'Whitespace is not allowed at this location.'

Check warning on line 3276 in Shared/Scintilla.cs

View workflow job for this annotation

GitHub Actions / build (Release)

XML comment has badly formed XML -- 'Whitespace is not allowed at this location.'
[DefaultValue(false)]
[Category("Behaviour")]
[Description("Indicates whether Scintilla's native drag & drop should be used instead of WinForms based one.")]
public bool _ScintillaManagedDragDrop { get; set; }
// Underscore is used so that WinForms Designer sets it before any other
// property. Otherwise ApplyResources gets called on the control before
// the property is set, which then triggers OnHandleCreated before we
// have the final value.

/// <summary>
/// Gets or sets the bi-directionality of the Scintilla control.
Expand Down

0 comments on commit f07c188

Please sign in to comment.