diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 50d86335..fa630c38 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -10,11 +10,6 @@ variables: output_path: "$CI_PROJECT_DIR/output/" output_packages_path: "$output_path/packages/" -cache: - key: ${CI_COMMIT_REF_SLUG} - paths: - - src/packages/ - - .tmp/ before_script: - cd $build_path @@ -34,7 +29,7 @@ sonarqube: variables: GIT_STRATEGY: "none" script: - - powershell -File $CI_PROJECT_DIR\build.ps1 SonarQube --Configuation $Configuration --SonarUrl $SONAR_URL --SonarUser $SONAR_USER --SonarProjectKey $SONAR_PROJECT_KEY --SonarProjectName $SONAR_PROJECT_NAME + - powershell -File $CI_PROJECT_DIR\build.ps1 SonarQube --Configuation $Configuration --SonarUrl $SONAR_URL --SonarUser $SONAR_USER --SonarProjectKey $SONAR_PROJECT_KEY --SonarProjectName $SONAR_PROJECT_NAME --RequestSourceBranch $CI_MERGE_REQUEST_SOURCE_BRANCH_NAME --RequestTargetBranch $CI_MERGE_REQUEST_TARGET_BRANCH_NAME --RequestId $CI_MERGE_REQUEST_IID integrationTests: stage: test @@ -71,6 +66,7 @@ artifacts: paths: - output/ - tests/ + expire_in: 1 week deploy_release: stage: deploy diff --git a/GitVersion.yml b/GitVersion.yml index 89fe40f1..8bc5befa 100644 --- a/GitVersion.yml +++ b/GitVersion.yml @@ -1,9 +1,32 @@ -next-version: 4.60.2167 assembly-versioning-scheme: MajorMinorPatchTag assembly-file-versioning-scheme: MajorMinorPatchTag -mode: Mainline branches: - release: - regex: ^release?[/-] - tag: '' - increment: Patch + master: + regex: master + mode: ContinuousDelivery + tag: stable + increment: None + prevent-increment-of-merged-branch-version: true + track-merge-target: false + tracks-release-branches: false + is-release-branch: false + bugfix: + regex: ^bugfix?[/-] + mode: ContinuousDeployment + tag: preview + increment: None + prevent-increment-of-merged-branch-version: false + track-merge-target: false + tracks-release-branches: false + is-release-branch: false + source-branches: ['master'] + feature: + regex: ^feature?[/] + mode: ContinuousDeployment + tag: preview + increment: None + prevent-increment-of-merged-branch-version: false + track-merge-target: false + tracks-release-branches: false + is-release-branch: false + source-branches: ['master'] diff --git a/build/Build.cs b/build/Build.cs index 157f92ab..5c1363df 100644 --- a/build/Build.cs +++ b/build/Build.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.IO; using System.IO.Compression; using System.Linq; @@ -9,12 +10,10 @@ using Nuke.Common.IO; using Nuke.Common.ProjectModel; using Nuke.Common.Tooling; -using Nuke.Common.Tools.DotNet; using Nuke.Common.Tools.GitVersion; using Nuke.Common.Tools.MSBuild; using Nuke.Common.Tools.NuGet; using Nuke.Common.Tools.SonarScanner; -using Nuke.Common.Utilities; using Nuke.Common.Utilities.Collections; using static Nuke.Common.IO.FileSystemTasks; using static Nuke.Common.IO.PathConstruction; @@ -42,6 +41,10 @@ partial class Build : NukeBuild [Parameter] readonly string Source; [Parameter] readonly string NugetApiKey; + [Parameter] readonly string RequestSourceBranch; + [Parameter] readonly string RequestTargetBranch; + [Parameter] readonly string RequestId; + AbsolutePath SourceDirectory => RootDirectory / "src"; AbsolutePath TestsDirectory => RootDirectory / "tests"; AbsolutePath OutputDirectory => RootDirectory / "output"; @@ -93,7 +96,7 @@ partial class Build : NukeBuild Logger.Info($"Update version for '{rcFile}'"); Logger.Info($"Assembly version: {GitVersion.AssemblySemVer}"); var fileContent = File.ReadAllText(rcFile); - fileContent = fileContent.Replace("1,0,0,1", _version).Replace("1.0.0.1",_version); + fileContent = fileContent.Replace("1,0,0,1", _version.Replace(".", ",")).Replace("1.0.0.1",_version); File.WriteAllText(rcFile, fileContent); } }); @@ -140,6 +143,14 @@ partial class Build : NukeBuild configuration = configuration.SetProjectBaseDir(SourceDirectory); + if (!string.IsNullOrWhiteSpace(RequestSourceBranch) && !string.IsNullOrWhiteSpace(RequestTargetBranch)) + { + configuration = configuration + .SetPullRequestBase(RequestSourceBranch) + .SetPullRequestBranch(RequestTargetBranch) + .SetPullRequestKey(RequestId); + } + var path = ToolPathResolver.GetPackageExecutable( packageId: "dotnet-sonarscanner|MSBuild.SonarQube.Runner.Tool", packageExecutable: "SonarScanner.MSBuild.exe", @@ -224,6 +235,7 @@ partial class Build : NukeBuild Target Artifacts => _ => _ .Executes(() => { + List plugins = new List(); EnsureCleanDirectory(OutputDirectory / "Artifacts"); Directory.CreateDirectory(OutputDirectory / "Artifacts"); @@ -233,9 +245,10 @@ partial class Build : NukeBuild { var di = new DirectoryInfo(directory); var pluginName = di.Parent?.Parent?.Name; + plugins.Add(pluginName); Directory.CreateDirectory(OutputDirectory / "Artifacts" / "Plugins" / pluginName); - + Logger.Info(pluginName); var files = di.GetFiles("*.dll"); foreach (var file in files) { @@ -255,6 +268,7 @@ partial class Build : NukeBuild outFile = OutputDirectory / "Artifacts" / "Plugins" / pluginName / $"{pluginName}.dll"; } + Logger.Normal($"Copy '{file.FullName}' to '{outFile}'"); file.CopyTo(outFile, true); } } @@ -269,6 +283,34 @@ partial class Build : NukeBuild file.CopyTo(outFile, true); } + Logger.Info("Validate output"); + + bool validatePluginFolder(string plugin, IEnumerable files) + { + var isValid = true; + + isValid &= files.Any(c => c.Name.StartsWith("AIMP.SDK")); + isValid &= files.Any(c => c.Name == $"{plugin}.dll"); + isValid &= files.Any(c => c.Name == $"{plugin}_plugin.dll"); + + return isValid; + } + + var isValid = true; + foreach (var plugin in plugins) + { + var pluginFolder = OutputDirectory / "Artifacts" / "Plugins" / plugin; + var di = new DirectoryInfo(pluginFolder); + var files = di.GetFiles("*.dll"); + if (!validatePluginFolder(plugin, files)) + { + Logger.Error($"Plugin {plugin} not valid."); + isValid = false; + } + } + + ControlFlow.Assert(isValid, "Artifacts not valid"); + Logger.Info("Compress artifacts"); ZipFile.CreateFromDirectory(OutputDirectory / "Artifacts", OutputDirectory / "aimp.sdk.zip"); }); diff --git a/build/IntegrationTest.Build.cs b/build/IntegrationTest.Build.cs index e152c860..ad3dc345 100644 --- a/build/IntegrationTest.Build.cs +++ b/build/IntegrationTest.Build.cs @@ -1,6 +1,7 @@ using System.Collections.Generic; using System.IO; using System.Text; +using System.Text.RegularExpressions; using System.Xml; using System.Xml.XPath; using System.Xml.Xsl; @@ -86,7 +87,7 @@ void copyFilesFromFolder(string folder) { if (file.EndsWith("aimp_dotnet.dll")) { - CopyFile(file, IntegrationTestPluginPath / "AimpTestRunner.dll"); + //CopyFile(file, IntegrationTestPluginPath / "AimpTestRunner.dll"); } else if (file.EndsWith("AimpTestRunner.dll")) { @@ -113,6 +114,16 @@ void copyFilesFromFolder(string folder) Logger.Normal($"Copy {d}/nunit.engine.addins to {IntegrationTestPluginPath}"); CopyFileToDirectory(d / "nunit.engine.addins", IntegrationTestPluginPath); }); + + var sdkFolder = new DirectoryInfo(SourceDirectory / $"{Configuration}"); + var sdkFiles = sdkFolder.GetFiles("*.dll"); + foreach (var file in sdkFiles) + { + if (file.FullName.EndsWith("aimp_dotnet.dll")) + { + file.CopyTo(IntegrationTestPluginPath / "AimpTestRunner.dll", true); + } + } } CopyDirectoryRecursively(ResourcesPath / "integrationTests", IntegrationTestPluginPath / "resources"); @@ -154,10 +165,27 @@ void copyFilesFromFolder(string folder) } else { - CopyFileToDirectory(testResultFile, OutputDirectory); - CopyFileToDirectory(testResultLogFile, OutputDirectory); + var isValid = true; + + CopyFileToDirectory(testResultFile, OutputDirectory, FileExistsPolicy.Overwrite); + CopyFileToDirectory(testResultLogFile, OutputDirectory, FileExistsPolicy.Overwrite); + + var content = File.ReadAllText(testResultLogFile); + var r = new Regex(@"Failed:\s(\d*)"); + var matches = r.Matches(content); - Logger.Info(File.ReadAllText(testResultLogFile)); + if (matches.Count > 0 && matches[0].Groups.Count >= 1) + { + if (int.TryParse(matches[0].Groups[1].Value, out var failed)) + { + if (failed > 0) + { + isValid = false; + } + } + } + + Logger.Info(content); if (IsJUnit) { @@ -172,6 +200,11 @@ void copyFilesFromFolder(string folder) }; xslt.Transform(doc, null, writer, null); } + + if (!isValid) + { + ControlFlow.Fail("Test is failed."); + } } } else @@ -181,7 +214,7 @@ void copyFilesFromFolder(string folder) } }); - private void LogError(string message) + void LogError(string message) { Logger.Error(message); } diff --git a/resources/integrationTests/img1.jpg b/resources/integrationTests/img1.jpg new file mode 100644 index 00000000..8461bc99 Binary files /dev/null and b/resources/integrationTests/img1.jpg differ diff --git a/resources/integrationTests/img2.bmp b/resources/integrationTests/img2.bmp new file mode 100644 index 00000000..c8ac5012 Binary files /dev/null and b/resources/integrationTests/img2.bmp differ diff --git a/src/AIMP.SDK/AIMP.SDK.csproj b/src/AIMP.SDK/AIMP.SDK.csproj index ba8f4802..064697a8 100644 --- a/src/AIMP.SDK/AIMP.SDK.csproj +++ b/src/AIMP.SDK/AIMP.SDK.csproj @@ -65,7 +65,10 @@ + + + @@ -102,12 +105,15 @@ - + + + + diff --git a/src/AIMP.SDK/AimpPlugin.cs b/src/AIMP.SDK/AimpPlugin.cs index 2ebca8ae..5949535a 100644 --- a/src/AIMP.SDK/AimpPlugin.cs +++ b/src/AIMP.SDK/AimpPlugin.cs @@ -10,6 +10,9 @@ // ---------------------------------------------------- using System; +using System.IO; +using System.Threading; +using AIMP.SDK.MessageDispatcher; using AIMP.SDK.Player; namespace AIMP.SDK @@ -84,6 +87,9 @@ internal void OnInitialize(IAimpPlayer player, int unId) { PluginId = unId; AimpPlayer = player; + var path = Path.GetDirectoryName(GetType().Assembly.Location); + AppDomain.CurrentDomain.SetData("APPBASE", path); + Environment.CurrentDirectory = path; Initialize(); } } diff --git a/src/AIMP.SDK/FileManager/IAimpServiceFileStreaming.cs b/src/AIMP.SDK/FileManager/IAimpServiceFileStreaming.cs index 54d9fe2f..9860cf14 100644 --- a/src/AIMP.SDK/FileManager/IAimpServiceFileStreaming.cs +++ b/src/AIMP.SDK/FileManager/IAimpServiceFileStreaming.cs @@ -22,35 +22,35 @@ public enum FileStreamingType /// /// The aimp service filestreaming flag read /// - AIMP_SERVICE_FILESTREAMING_FLAG_READ = 0, + Read = 0, /// /// The aimp service filestreaming flag createnew /// - AIMP_SERVICE_FILESTREAMING_FLAG_CREATENEW = 1, + CreateNew = 1, /// /// The aimp service filestreaming flag readwrite /// - AIMP_SERVICE_FILESTREAMING_FLAG_READWRITE = 2, + ReadWrite = 2, /// /// The aimp service filestreaming flag maptomemory /// - AIMP_SERVICE_FILESTREAMING_FLAG_MAPTOMEMORY = 4 + MapToMemory = 4 } /// /// Class CeateStreamResult. /// - public class CeateStreamResult + public class CreateStreamResult { /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The virtual file. /// The stream. - public CeateStreamResult(IAimpVirtualFile virtualFile, IAimpStream stream) + public CreateStreamResult(IAimpVirtualFile virtualFile, IAimpStream stream) { VirtualFile = virtualFile; Stream = stream; @@ -84,14 +84,13 @@ public interface IAimpServiceFileStreaming : IAimpService /// The offset. /// The size. /// AimpActionResult<IAimpStream>. - AimpActionResult CreateStreamForFile(string fileName, FileStreamingType flags, long offset, - long size); + AimpActionResult CreateStreamForFile(string fileName, FileStreamingType flags, long offset, long size); /// /// Creates the stream for file URI. /// /// The file URL. /// AimpActionResult<CeateStreamResult>. - AimpActionResult CreateStreamForFileUri(string fileUrl); + AimpActionResult CreateStreamForFileUri(string fileUrl); } } diff --git a/src/AIMP.SDK/IAimpDPIAware.cs b/src/AIMP.SDK/IAimpDPIAware.cs new file mode 100644 index 00000000..d5766acf --- /dev/null +++ b/src/AIMP.SDK/IAimpDPIAware.cs @@ -0,0 +1,22 @@ +// ---------------------------------------------------- +// +// AIMP DotNet SDK +// +// Copyright (c) 2014 - 2020 Evgeniy Bogdan +// https://github.com/martin211/aimp_dotnet +// +// Mail: mail4evgeniy@gmail.com +// +// ---------------------------------------------------- + +namespace AIMP.SDK +{ + public interface IAimpDPIAware : IAimpObject + { + /// + /// Gets or sets the dpi. + /// + /// The dpi. + int DPI { get; set; } + } +} diff --git a/src/AIMP.SDK/IAimpErrorInfo.cs b/src/AIMP.SDK/IAimpErrorInfo.cs index 707883a3..c41478cb 100644 --- a/src/AIMP.SDK/IAimpErrorInfo.cs +++ b/src/AIMP.SDK/IAimpErrorInfo.cs @@ -29,7 +29,7 @@ public ErrorInfo(int errorCode, string message, string details) public string Details { get; set; } } - public interface IAimpErrorInfo : IDisposable, IAimpObject + public interface IAimpErrorInfo : IAimpObject { AimpActionResult GetInfo(); diff --git a/src/AIMP.SDK/IAimpObject.cs b/src/AIMP.SDK/IAimpObject.cs index c231c191..67ad4e47 100644 --- a/src/AIMP.SDK/IAimpObject.cs +++ b/src/AIMP.SDK/IAimpObject.cs @@ -65,7 +65,7 @@ public AimpErrorArgs(ActionResultType aimpActionResult, string message, string s /// /// Interface IAimpObject /// - public interface IAimpObject + public interface IAimpObject : IDisposable { } } diff --git a/src/AIMP.SDK/MessageDispatcher/AimpMessages.cs b/src/AIMP.SDK/MessageDispatcher/AimpMessages.cs index c4b60d93..408d08d7 100644 --- a/src/AIMP.SDK/MessageDispatcher/AimpMessages.cs +++ b/src/AIMP.SDK/MessageDispatcher/AimpMessages.cs @@ -135,7 +135,7 @@ public enum AimpCoreMessageType /// Start playback of previous playing playlist. ///
  • Param1 - Not used.
  • Param2 - Not used.
  • /// - CmdPrevPlaylist = Constants.MessageCommandBase + 16, + CmdPlayPrevPlaylist = Constants.MessageCommandBase + 16, /// /// Pause / Resume. @@ -229,7 +229,7 @@ public enum AimpCoreMessageType /// Activate playable playlist and focus playable file. ///
  • Param1 - Not used.
  • Param2 - Not used.
  • ///
    - CmdPlaylistFocusPlayable = Constants.MessageCommandBase + 28, + CmdPlaylistFocusPlaying = Constants.MessageCommandBase + 28, /// /// Delete all tracks from active playlist. @@ -373,7 +373,7 @@ public enum AimpCoreMessageType /// Show the "File Information" dialog for playable track. ///
  • Param1 - Not used.
  • Param2 - Not used.
  • ///
    - CmdQTEPlayableTrack = Constants.MessageCommandBase + 51, + CmdQTEPlayingTrack = Constants.MessageCommandBase + 51, /// /// Show the "Advanced Search" dialog. @@ -419,6 +419,17 @@ public enum AimpCoreMessageType /// CmdVisualStop = Constants.MessageCommandBase + 58, + /// + /// The command playlist rescan selected. + /// + CmdPlaylistRescanSelected = Constants.MessageCommandBase + 59, + + /// + /// Extended control of "Quick File Info" card that displaying information about playing file + /// AParam2: pointer to TAIMPQuickFileInfoParams + /// + CmdQFI = Constants.MessageCommandBase + 60, + #endregion #region Events @@ -542,7 +553,7 @@ public enum AimpCoreMessageType /// 2. On stop playback(See AIMP_MSG_EVENT_STREAM_END) ///
  • Param1: Not used.
  • Param2: Not used.
  • /// - EventPlayableFileInfo = Constants.BaseEvent + 20, + EventPlayingFileInfo = Constants.BaseEvent + 20, /// /// Unlike the AIMP_MSG_EVENT_PLAYER_UPDATE_POSITION event this event has higher resolution (about 10-15 calls per @@ -561,6 +572,10 @@ public enum AimpCoreMessageType #region Properties + PropertyValueGet = 0, + + PropertyValueSet = 1, + /// /// ///
  • Param1: Access direction: Read / Write (AIMP_MSG_PROPVALUE_GET / AIMP_MSG_PROPVALUE_SET)
  • @@ -901,11 +916,26 @@ public enum AimpCoreMessageType /// Displays buffering progress of playing track. ///
  • Param1: Access direction: Read / Write (AIMP_MSG_PROPVALUE_GET / AIMP_MSG_PROPVALUE_SET)
  • Param2: Pointer to the 32-bit floating point variable (Single). Value in percents (from 0.0 to 100.0 %)
  • ///
    - PropertyPlayerBuffering = Constants.MessagePropertyBase + 32 + PropertyPlayerBuffering = Constants.MessagePropertyBase + 32, + + PropertyRadioCapSingleTrack = Constants.MessagePropertyBase + 33, + + PropertyCrossmixing = Constants.MessagePropertyBase + 34, + + PropertyActionOnEndOfTrack = Constants.MessagePropertyBase + 35, #endregion } + public enum AimpDescriptorType + { + MainForm = 0, + Application = 1, + TrayControl = 2, + PlaylistForm = 3, + EqualizerForm = 4 + } + /// /// Path type. diff --git a/src/AIMP.SDK/MessageDispatcher/IAimpMessageHook.cs b/src/AIMP.SDK/MessageDispatcher/IAimpMessageHook.cs index 57087738..c9169cc8 100644 --- a/src/AIMP.SDK/MessageDispatcher/IAimpMessageHook.cs +++ b/src/AIMP.SDK/MessageDispatcher/IAimpMessageHook.cs @@ -9,6 +9,8 @@ // // ---------------------------------------------------- +using System; + namespace AIMP.SDK.MessageDispatcher { /// @@ -23,8 +25,8 @@ public interface IAimpMessageHook /// /// The message. /// The param1. - /// The param2. + /// The param2. See official SDK documentation to get more info about output parameter. /// AimpActionResult. - AimpActionResult CoreMessage(AimpCoreMessageType message, int param1, int param2); + AimpActionResult CoreMessage(AimpCoreMessageType message, int param1, IntPtr param2); } } diff --git a/src/AIMP.SDK/MessageDispatcher/PointerExtension.cs b/src/AIMP.SDK/MessageDispatcher/PointerExtension.cs new file mode 100644 index 00000000..afa0a6ca --- /dev/null +++ b/src/AIMP.SDK/MessageDispatcher/PointerExtension.cs @@ -0,0 +1,97 @@ +// ---------------------------------------------------- +// +// AIMP DotNet SDK +// +// Copyright (c) 2014 - 2020 Evgeniy Bogdan +// https://github.com/martin211/aimp_dotnet +// +// Mail: mail4evgeniy@gmail.com +// +// ---------------------------------------------------- + +using System; +using System.Runtime.InteropServices; + +namespace AIMP.SDK.MessageDispatcher +{ + public static class PointerExtension + { + public static byte ToByte(this IntPtr pointer) + { + return Marshal.ReadByte(pointer); + } + + public static bool ToBool(this IntPtr pointer) + { + return Convert.ToBoolean(ToByte(pointer)); + } + + public static int ToInt(this IntPtr pointer) + { + byte[] ba = new byte[sizeof(int)]; + + for (int i = 0; i < ba.Length; i++) + { + ba[i] = Marshal.ReadByte(pointer, i); + } + int v = BitConverter.ToInt32(ba, 0); + return v; + } + + public static double ToDouble(this IntPtr pointer) + { + byte[] ba = new byte[sizeof(double)]; + + for (int i = 0; i < ba.Length; i++) + { + ba[i] = Marshal.ReadByte(pointer, i); + } + double v = BitConverter.ToDouble(ba, 0); + return v; + } + + public static IntPtr ToPointer(this bool value) + { + int size = Marshal.SizeOf(typeof(int)); + IntPtr pointer = Marshal.AllocHGlobal(size); + Marshal.WriteInt32(pointer, 0, value ? 1 : 0); + return pointer; + } + + public static IntPtr ToPointer(this double value) + { + var ptr = Marshal.AllocHGlobal(sizeof(double)); + byte[] byteDouble = BitConverter.GetBytes(value); + Marshal.Copy(byteDouble, 0, ptr, byteDouble.Length); + return ptr; + } + + public static IntPtr ToPointer(this int value) + { + int size = Marshal.SizeOf(typeof(int)); + IntPtr pointer = Marshal.AllocHGlobal(size); + Marshal.WriteInt32(pointer, 0, value); + return pointer; + } + + public static IntPtr ToPointer(this object value) + { + if (value is bool boolVal) + { + return ToPointer(boolVal); + } + + if (value is double doubleVal) + { + return ToPointer(doubleVal); + } + + if (value is int intVal) + { + return ToPointer(intVal); + } + + return IntPtr.Zero; + } + } +} diff --git a/src/AIMP.SDK/MusicLibrary/DataStorage/IAimpDataStorage.cs b/src/AIMP.SDK/MusicLibrary/DataStorage/IAimpDataStorage.cs index 89b66f71..5d190268 100644 --- a/src/AIMP.SDK/MusicLibrary/DataStorage/IAimpDataStorage.cs +++ b/src/AIMP.SDK/MusicLibrary/DataStorage/IAimpDataStorage.cs @@ -17,7 +17,7 @@ namespace AIMP.SDK.MusicLibrary.DataStorage /// Interface provides an access to common to all data storages settings. /// The is implemented on same level. /// - public interface IAimpDataStorage + public interface IAimpDataStorage : IAimpObject { /// /// Gets the storage identifier. diff --git a/src/AIMP.SDK/MusicLibrary/IAimpFileList.cs b/src/AIMP.SDK/MusicLibrary/IAimpFileList.cs index 47a1f40c..aaccae7b 100644 --- a/src/AIMP.SDK/MusicLibrary/IAimpFileList.cs +++ b/src/AIMP.SDK/MusicLibrary/IAimpFileList.cs @@ -14,7 +14,7 @@ namespace AIMP.SDK.MusicLibrary /// /// Represents the pair {File name, ID} for data provider. /// - public interface IAimpFileList + public interface IAimpFileList : IAimpObject { /// /// Adds new file to the list. diff --git a/src/AIMP.SDK/Objects/IAimpFileStream.cs b/src/AIMP.SDK/Objects/IAimpFileStream.cs new file mode 100644 index 00000000..445ec603 --- /dev/null +++ b/src/AIMP.SDK/Objects/IAimpFileStream.cs @@ -0,0 +1,48 @@ +// ---------------------------------------------------- +// +// AIMP DotNet SDK +// +// Copyright (c) 2014 - 2020 Evgeniy Bogdan +// https://github.com/martin211/aimp_dotnet +// +// Mail: mail4evgeniy@gmail.com +// +// ---------------------------------------------------- + +using System.Drawing; +using AIMP.SDK.Options; + +namespace AIMP.SDK.Objects +{ + public class Clipping + { + public Clipping(int offset, int size) + { + Offset = offset; + Size = size; + } + + public int Offset { get; } + + public int Size { get; } + } + + /// + /// IAimpFileStream is extended variant of IAimpStream specially for file-based streams. + /// Implements the + /// + public interface IAimpFileStream : IAimpStream + { + /// + /// If file is clipped the method will return clipping bounds. See the IAimpServiceFileStreaming.CreateStreamForFile. + /// + /// AimpActionResult. + AimpActionResult GetClipping(); + + /// + /// + /// + /// + AimpActionResult GetFileName(); + } +} diff --git a/src/AIMP.SDK/Objects/IAimpImage.cs b/src/AIMP.SDK/Objects/IAimpImage.cs new file mode 100644 index 00000000..5a2f1ee4 --- /dev/null +++ b/src/AIMP.SDK/Objects/IAimpImage.cs @@ -0,0 +1,47 @@ +// ---------------------------------------------------- +// +// AIMP DotNet SDK +// +// Copyright (c) 2014 - 2020 Evgeniy Bogdan +// https://github.com/martin211/aimp_dotnet +// +// Mail: mail4evgeniy@gmail.com +// +// ---------------------------------------------------- + +using System; +using System.Drawing; +using AIMP.SDK.Objects; + +namespace AIMP.SDK +{ + public enum AimpImageFormat + { + Unknown = 0, + BPM = 1, + GIF = 2, + JPG = 3, + PNG = 4 + } + + public interface IAimpImage : IAimpObject, IAimpImage2 + { + AimpImageFormat FormatId { get; } + + PointF Size { get; } + + AimpActionResult LoadFromFile(string fileName); + + AimpActionResult LoadFromStream(IAimpStream stream); + + AimpActionResult SaveToFile(string fileName, AimpImageFormat format); + + AimpActionResult SaveToStream(IAimpStream stream, AimpImageFormat format); + + AimpActionResult Clone(); + + AimpActionResult Draw(IntPtr dc, RectangleF rect); + + AimpActionResult Resize(int width, int height); + } +} diff --git a/src/AIMP.SDK/Objects/IAimpImage2.cs b/src/AIMP.SDK/Objects/IAimpImage2.cs new file mode 100644 index 00000000..a9431bda --- /dev/null +++ b/src/AIMP.SDK/Objects/IAimpImage2.cs @@ -0,0 +1,40 @@ +// ---------------------------------------------------- +// +// AIMP DotNet SDK +// +// Copyright (c) 2014 - 2020 Evgeniy Bogdan +// https://github.com/martin211/aimp_dotnet +// +// Mail: mail4evgeniy@gmail.com +// +// ---------------------------------------------------- + +using System; +using System.Runtime.InteropServices; + +namespace AIMP.SDK.Objects +{ + [StructLayout(LayoutKind.Sequential, Pack = 1)] + public struct RGBQUAD + { + public byte rgbBlue; + public byte rgbGreen; + public byte rgbRed; + public byte rgbReserved; + } + + public interface IAimpImage2 + { + AimpActionResult LoadFromResource(); + + AimpActionResult LoadFromBitmap(IntPtr bitmap); + + AimpActionResult LoadFromBits(RGBQUAD bits, int width, int height); + + AimpActionResult CopyToClipboard(); + + AimpActionResult CanPasteFromClipboard(); + + AimpActionResult PasteFromClipboard(); + } +} diff --git a/src/AIMP.SDK/Objects/IAimpMemoryStream.cs b/src/AIMP.SDK/Objects/IAimpMemoryStream.cs new file mode 100644 index 00000000..39e1604f --- /dev/null +++ b/src/AIMP.SDK/Objects/IAimpMemoryStream.cs @@ -0,0 +1,27 @@ +// ---------------------------------------------------- +// +// AIMP DotNet SDK +// +// Copyright (c) 2014 - 2020 Evgeniy Bogdan +// https://github.com/martin211/aimp_dotnet +// +// Mail: mail4evgeniy@gmail.com +// +// ---------------------------------------------------- + +namespace AIMP.SDK.Objects +{ + /// + /// Interface IAimpMemoryStream + /// Implements the + /// + /// + public interface IAimpMemoryStream : IAimpStream + { + /// + /// Gets the data. + /// + /// AimpActionResult<System.Byte[]>. + AimpActionResult GetData(); + } +} diff --git a/src/AIMP.SDK/IAimpStream.cs b/src/AIMP.SDK/Objects/IAimpStream.cs similarity index 92% rename from src/AIMP.SDK/IAimpStream.cs rename to src/AIMP.SDK/Objects/IAimpStream.cs index c7dbfea8..0fa6ca86 100644 --- a/src/AIMP.SDK/IAimpStream.cs +++ b/src/AIMP.SDK/Objects/IAimpStream.cs @@ -21,7 +21,7 @@ namespace AIMP.SDK /// /// /// - public interface IAimpStream : IDisposable, IAimpObject + public interface IAimpStream : IAimpObject { /// /// Gets the size of stream, in bytes. @@ -70,9 +70,9 @@ public interface IAimpStream : IDisposable, IAimpObject /// /// The buffer to write data from. /// The maximum number of bytes to write. - /// Parameter displays what bytes has been really written to the stream. + /// Parameter displays what bytes has been really written to the stream. /// This parameter is optional - can be null. /// AimpActionResult. - AimpActionResult Write(byte[] buffer, int count, out int writen); + AimpActionResult Write(byte[] buffer, int count, out int written); } } diff --git a/src/AIMP.SDK/Objects/IAimpString.cs b/src/AIMP.SDK/Objects/IAimpString.cs index 47552513..74f2c438 100644 --- a/src/AIMP.SDK/Objects/IAimpString.cs +++ b/src/AIMP.SDK/Objects/IAimpString.cs @@ -64,7 +64,7 @@ public enum AimpStringFindFlags /// /// Interface IAimpString /// - public interface IAimpString + public interface IAimpString : IAimpObject { /// /// Gets the character. diff --git a/src/AIMP.SDK/TagEditor/IAimpFileTagEditor.cs b/src/AIMP.SDK/TagEditor/IAimpFileTagEditor.cs index 3d248edc..d705430d 100644 --- a/src/AIMP.SDK/TagEditor/IAimpFileTagEditor.cs +++ b/src/AIMP.SDK/TagEditor/IAimpFileTagEditor.cs @@ -9,6 +9,7 @@ // // ---------------------------------------------------- +using System; using AIMP.SDK.FileManager; namespace AIMP.SDK.TagEditor @@ -16,7 +17,7 @@ namespace AIMP.SDK.TagEditor /// /// Provide ability to get access to tag editor. /// - public interface IAimpFileTagEditor + public interface IAimpFileTagEditor : IDisposable { /// /// Gets the mixed information from all tags and returns it as a . diff --git a/src/IntegrationTest/AimpTestRunner/AimpTestRunner.cs b/src/IntegrationTest/AimpTestRunner/AimpTestRunner.cs index ba74a282..4a3a6664 100644 --- a/src/IntegrationTest/AimpTestRunner/AimpTestRunner.cs +++ b/src/IntegrationTest/AimpTestRunner/AimpTestRunner.cs @@ -29,14 +29,14 @@ public class AimpTestRunnerPlugin : AimpPlugin, ITestEventListener { public class Hook : IAimpMessageHook { - private readonly Func _hook; + private readonly Func _hook; - public Hook(Func hook) + public Hook(Func hook) { _hook = hook; } - public AimpActionResult CoreMessage(AimpCoreMessageType message, int param1, int param2) + public AimpActionResult CoreMessage(AimpCoreMessageType message, int param1, IntPtr param2) { return _hook(message, param1, param2); } diff --git a/src/IntegrationTest/AimpTestRunner/AimpTestRunner.csproj b/src/IntegrationTest/AimpTestRunner/AimpTestRunner.csproj index 0f50bc39..8f71a58a 100644 --- a/src/IntegrationTest/AimpTestRunner/AimpTestRunner.csproj +++ b/src/IntegrationTest/AimpTestRunner/AimpTestRunner.csproj @@ -30,6 +30,7 @@ DEBUG;TRACE prompt 4 + latest pdbonly @@ -38,6 +39,7 @@ TRACE prompt 4 + latest @@ -69,6 +71,7 @@ + @@ -82,11 +85,13 @@ + + @@ -104,6 +109,9 @@ + + + diff --git a/src/IntegrationTest/AimpTestRunner/Issues/Issue_19.cs b/src/IntegrationTest/AimpTestRunner/Issues/Issue_19.cs index 93e2eb6f..eea40378 100644 --- a/src/IntegrationTest/AimpTestRunner/Issues/Issue_19.cs +++ b/src/IntegrationTest/AimpTestRunner/Issues/Issue_19.cs @@ -16,7 +16,10 @@ namespace Aimp.TestRunner.UnitTests.FileManager { - [TestFixture(Description = "Issue #19. FileInfo rating issue")] + [TestFixture( + Description = "Issue #19. FileInfo rating issue", + Category = "Issues" + )] [Ignore("Can be run only locally with correct media DB")] public class Issue_19 : AimpIntegrationTest { diff --git a/src/IntegrationTest/AimpTestRunner/Issues/Issue_37.cs b/src/IntegrationTest/AimpTestRunner/Issues/Issue_37.cs new file mode 100644 index 00000000..86015fe2 --- /dev/null +++ b/src/IntegrationTest/AimpTestRunner/Issues/Issue_37.cs @@ -0,0 +1,70 @@ +// ---------------------------------------------------- +// +// AIMP DotNet SDK +// +// Copyright (c) 2014 - 2020 Evgeniy Bogdan +// https://github.com/martin211/aimp_dotnet +// +// Mail: mail4evgeniy@gmail.com +// +// ---------------------------------------------------- + +using System; +using System.IO; +using AIMP.SDK; +using AIMP.SDK.FileManager; +using Aimp.TestRunner.UnitTests; +using NUnit.Framework; + +namespace Aimp.TestRunner.Issues +{ + [TestFixture( + Description = "Issue 37. The TagEditor is locks file until Aimp is closed", + Category = "Issues")] + public class Issue_37 : AimpIntegrationTest + { + [Test] + public void EditFile() + { + ExecuteInMainThread(() => + { + if (IsLock(TrackPath1)) + { + TestContext.Error.WriteLine("File is locked"); + return; + } + + var res = Player.ServiceFileTagEditor.EditFile(TrackPath1); + this.AreEqual(ActionResultType.OK, res.ResultType); + var editor = res.Result; + + var fileInfo = Player.Core.CreateAimpObject().Result; + fileInfo.Title = "Test"; + editor.SetToAll(fileInfo); + var saveResult = editor.Save(); + this.AreEqual(ActionResultType.OK, saveResult.ResultType); + fileInfo.Dispose(); + editor.Dispose(); + + if (IsLock(TrackPath1)) + { + TestContext.Error.WriteLine("File is locked"); + } + }); + } + + private bool IsLock(string fileName) + { + try + { + using var stream = File.Open(TrackPath1, FileMode.Open, FileAccess.Read, FileShare.None); + stream.Close(); + return false; + } + catch (Exception e) + { + return true; + } + } + } +} diff --git a/src/IntegrationTest/AimpTestRunner/UnitTests/AimpCoreTests.cs b/src/IntegrationTest/AimpTestRunner/UnitTests/AimpCoreTests.cs index 3878c76b..e2147b74 100644 --- a/src/IntegrationTest/AimpTestRunner/UnitTests/AimpCoreTests.cs +++ b/src/IntegrationTest/AimpTestRunner/UnitTests/AimpCoreTests.cs @@ -91,13 +91,13 @@ public void Service_IsExists_AllServicesShouldExists(string service) { Assert.Fail($"Service {service} was not found at Player."); } - this.IsTrue(((IAimpService)m.GetValue(Player)).IsExists).Validate(); + this.IsTrue(((IAimpService)m.GetValue(Player)).IsExists).Validate(this); } private void AssertResult(AimpActionResult result) { - this.AreEqual(ActionResultType.OK, result.ResultType).Validate(); - this.NotNull(result.Result).Validate(); + this.AreEqual(ActionResultType.OK, result.ResultType).Validate(this); + this.NotNull(result.Result).Validate(this); } } } \ No newline at end of file diff --git a/src/IntegrationTest/AimpTestRunner/UnitTests/AimpImageUnitTests.cs b/src/IntegrationTest/AimpTestRunner/UnitTests/AimpImageUnitTests.cs new file mode 100644 index 00000000..0cf8870a --- /dev/null +++ b/src/IntegrationTest/AimpTestRunner/UnitTests/AimpImageUnitTests.cs @@ -0,0 +1,134 @@ +// ---------------------------------------------------- +// +// AIMP DotNet SDK +// +// Copyright (c) 2014 - 2020 Evgeniy Bogdan +// https://github.com/martin211/aimp_dotnet +// +// Mail: mail4evgeniy@gmail.com +// +// ---------------------------------------------------- + +using System; +using System.Drawing; +using System.IO; +using AIMP.SDK; +using NUnit.Framework; + +namespace Aimp.TestRunner.UnitTests +{ + [TestFixture] + public class AimpImageUnitTests : AimpIntegrationTest + { + private string Image1; + + public override void RunBeforeAnyTests() + { + base.RunBeforeAnyTests(); + Image1 = Path.Combine(RootPath, "resources", "img1.jpg"); + } + + [Test] + [Order(1)] + public void Create_ShouldReturnNewObject() + { + var res = Player.Core.CreateObject(); + this.AreEqual(ActionResultType.OK, res.ResultType); + this.NotNull(res.Result); + } + + [Test] + [Order(2)] + public void LoadFromFile_NotEmptyPath_OK() + { + var res = Player.Core.CreateAimpObject(); + this.AreEqual(ActionResultType.OK, res.ResultType); + + if (!IsValid) + { + return; + } + + var img = res.Result; + var loadFromFileResult = img.LoadFromFile(Image1); + this.AreEqual(ActionResultType.OK, loadFromFileResult.ResultType); + this.IsTrue(img.Size != PointF.Empty); + } + + [Test] + public void LoadFromFile_EmptyPath_ShouldThrowException() + { + var res = Player.Core.CreateAimpObject(); + this.AreEqual(ActionResultType.OK, res.ResultType); + + if (!IsValid) + { + return; + } + + var img = res.Result; + var exception = this.Throw(() => img.LoadFromFile(string.Empty)); + this.IsTrue(exception.Message.Contains("fileName cannot be empty")); + } + + [TestCase("img1.bmp", AimpImageFormat.BPM)] + [TestCase("img1.gif", AimpImageFormat.GIF)] + [TestCase("img1.jpg", AimpImageFormat.JPG)] + [TestCase("img1.png", AimpImageFormat.PNG)] + public void SaveToFile_OK(string fileName, AimpImageFormat format) + { + var res = Player.Core.CreateAimpObject(); + this.AreEqual(ActionResultType.OK, res.ResultType); + + if (!IsValid) + { + return; + } + + var file = Path.Combine(TmpPath, fileName); + + var img = res.Result; + img.LoadFromFile(Image1); + + var saveResult = img.SaveToFile(file, format); + this.AreEqual(ActionResultType.OK, saveResult.ResultType, $"Unable save file to {file}, format {format}"); + } + + [Test] + [Ignore("Clone not working, AccessViolationException")] + public void Clone_OK() + { + ExecuteInMainThread(() => + { + var res = Player.Core.CreateAimpObject(); + this.AreEqual(ActionResultType.OK, res.ResultType); + + if (!IsValid) + { + return; + } + + res.Result.LoadFromFile(Image1); + var cloneResult = res.Result.Clone(); + this.AreEqual(ActionResultType.OK, cloneResult.ResultType); + this.NotNull(cloneResult.Result); + }); + } + + [Test] + public void Resize_OK() + { + var res = Player.Core.CreateAimpObject(); + this.AreEqual(ActionResultType.OK, res.ResultType); + + if (!IsValid) + { + return; + } + + res.Result.LoadFromFile(Image1); + var resizeResult = res.Result.Resize(100, 100); + this.AreEqual(ActionResultType.OK, resizeResult.ResultType); + } + } +} diff --git a/src/IntegrationTest/AimpTestRunner/UnitTests/AimpIntegrationTest.cs b/src/IntegrationTest/AimpTestRunner/UnitTests/AimpIntegrationTest.cs index a5612a96..fe0a01c0 100644 --- a/src/IntegrationTest/AimpTestRunner/UnitTests/AimpIntegrationTest.cs +++ b/src/IntegrationTest/AimpTestRunner/UnitTests/AimpIntegrationTest.cs @@ -13,6 +13,7 @@ using System.Collections.Generic; using System.IO; using System.Linq.Expressions; +using System.Runtime.CompilerServices; using AIMP.SDK; using AIMP.SDK.MessageDispatcher; using AIMP.SDK.Player; @@ -51,7 +52,10 @@ public static EqualAssert AreEqual(this AimpIntegrationTest testClass, } finally { - assert.Validate(); + if (testClass.IsValid) + { + assert.Validate(testClass); + } } } @@ -97,18 +101,32 @@ public static NotEqualAssert AreNotEqual(this AimpIntegrationTest testC return assert; } - public static TrueAssert IsTrue(this AimpIntegrationTest testClass, bool value) + public static TrueAssert IsTrue(this AimpIntegrationTest testClass, bool value, string message = "") { - var assert = new TrueAssert(null, value, null); - testClass.Asserts.Add(assert); - return assert; + var assert = new TrueAssert(null, value, message); + try + { + AddAssertion(testClass, assert); + return assert; + } + finally + { + assert.Validate(testClass); + } } public static FalseAssert IsFalse(this AimpIntegrationTest testClass, bool value) { var assert = new FalseAssert(null, value, null); - testClass.Asserts.Add(assert); - return assert; + try + { + AddAssertion(testClass, assert); + return assert; + } + finally + { + assert.Validate(testClass); + } } public static TException Throw(this AimpIntegrationTest testClass, TestDelegate action) @@ -180,7 +198,7 @@ private static object GetExpressionValue(this Expression> private static void AddAssertion(AimpIntegrationTest testClass, AimpAssert assertion) { - if (_testExecutionContext.CurrentResult.FailCount == 0) + if (_testExecutionContext.CurrentResult.FailCount == 0 || testClass.IsValid) { testClass.Asserts.Add(assertion); } @@ -189,7 +207,7 @@ private static void AddAssertion(AimpIntegrationTest testClass, AimpAssert asser public abstract class AimpAssert { - public abstract void Validate(); + public abstract void Validate(AimpIntegrationTest testClass); } public abstract class MemberAssert : MemberAssert @@ -202,7 +220,7 @@ protected MemberAssert(string name, object value, string message) Message = message; } - public abstract override void Validate(); + public abstract override void Validate(AimpIntegrationTest testClass); } @@ -221,7 +239,7 @@ protected MemberAssert(string name, TValue value, string message) Message = message; } - public abstract override void Validate(); + public abstract override void Validate(AimpIntegrationTest testClass); } public class NotNullAssert : MemberAssert @@ -230,7 +248,7 @@ public NotNullAssert(string name, object value, string message) : base(name, val { } - public override void Validate() + public override void Validate(AimpIntegrationTest testClass) { Assert.NotNull(Value, FieldName); } @@ -242,7 +260,7 @@ public NullAssert(string name, object value, string message) : base(name, value, { } - public override void Validate() + public override void Validate(AimpIntegrationTest testClass) { Assert.Null(Value, FieldName); } @@ -258,7 +276,7 @@ public EqualAssert(string name, object value, object expected, string message) Expected = expected; } - public override void Validate() + public override void Validate(AimpIntegrationTest testClass) { try { @@ -289,7 +307,7 @@ public NotEqualAssert(string name, object value, object expected, string message Expected = expected; } - public override void Validate() + public override void Validate(AimpIntegrationTest testClass) { Assert.AreNotEqual(Expected, Value, Message ?? $"Expected '{Expected}' but was '{Value}'"); } @@ -312,7 +330,7 @@ public ThrowAssert(TestDelegate action) } } - public override void Validate() + public override void Validate(AimpIntegrationTest testClass) { var expectedType = typeof(TException); Assert.That(CatchedException, new ExceptionTypeConstraint(expectedType)); @@ -326,9 +344,17 @@ public TrueAssert(string name, bool value, string message) { } - public override void Validate() + public override void Validate(AimpIntegrationTest testClass) { - Assert.True(Value, $"Expected 'true' but was '{Value}'"); + try + { + Assert.True(Value, $"Expected 'true' but was '{Value}'"); + } + catch (AssertionException) + { + testClass.IsValid = false; + throw; + } } } @@ -339,16 +365,28 @@ public FalseAssert(string name, bool value, string message) { } - public override void Validate() + public override void Validate(AimpIntegrationTest testClass) { - Assert.False(Value, $"Expected 'False' but was '{Value}'"); + try + { + Assert.False(Value, $"Expected 'False' but was '{Value}'"); + } + catch (AssertionException) + { + testClass.IsValid = false; + throw; + } } } public abstract class AimpIntegrationTest { + public bool IsValid { get; set; } = true; + internal string RootPath { get; } + internal string TmpPath { get; } + internal string PlaylistPath { get; } internal string TrackPath1 { get; } @@ -381,6 +419,22 @@ protected AimpIntegrationTest() TrackPath3 = Path.Combine(RootPath, "resources", "03_atmosphere.mp3"); TrackPath4 = Path.Combine(RootPath, "resources", "04_loop-mix.mp3"); TrackUrl1 = "https://freesound.org/data/previews/514/514101_4397472-lq.mp3"; + TmpPath = Path.Combine(RootPath, "tmp"); + + if (Directory.Exists(TmpPath)) + { + var files = Directory.GetFiles(TmpPath); + + foreach (var file in files) + { + File.SetAttributes(file, FileAttributes.Normal); + File.Delete(file); + } + + Directory.Delete(TmpPath, true); + } + + Directory.CreateDirectory(TmpPath); } [OneTimeSetUp] @@ -402,7 +456,7 @@ public virtual void TearDown() { if (Asserts.Count > 0) { - Validate(); + Validate(this); } } @@ -434,11 +488,11 @@ public AimpActionResult ExecuteAndWait(Action func) return res; } - internal void Validate() + internal void Validate(AimpIntegrationTest testClass) { foreach (var fieldValidator in Asserts) { - fieldValidator.Validate(); + fieldValidator.Validate(testClass); } } diff --git a/src/IntegrationTest/AimpTestRunner/UnitTests/FileManager/AimpServiceFileStreamingUnitTests.cs b/src/IntegrationTest/AimpTestRunner/UnitTests/FileManager/AimpServiceFileStreamingUnitTests.cs new file mode 100644 index 00000000..719e16bb --- /dev/null +++ b/src/IntegrationTest/AimpTestRunner/UnitTests/FileManager/AimpServiceFileStreamingUnitTests.cs @@ -0,0 +1,49 @@ +// ---------------------------------------------------- +// +// AIMP DotNet SDK +// +// Copyright (c) 2014 - 2020 Evgeniy Bogdan +// https://github.com/martin211/aimp_dotnet +// +// Mail: mail4evgeniy@gmail.com +// +// ---------------------------------------------------- + +using AIMP.SDK; +using AIMP.SDK.FileManager; +using NUnit.Framework; + +namespace Aimp.TestRunner.UnitTests.FileManager +{ + [TestFixture] + public class AimpServiceFileStreamingUnitTests : AimpIntegrationTest + { + [Test] + public void CreateStreamForFile_OK() + { + var createStream = Player.ServiceFileStreaming.CreateStreamForFile(TrackPath1, FileStreamingType.Read, -1, -1); + this.AreEqual(ActionResultType.OK, createStream.ResultType); + + if (!IsValid) + { + return; + } + + this.NotNull(createStream.Result); + createStream.Result.Dispose(); + } + + [Test] + [Ignore("TODO")] + public void GetClipping_OK() + { + var createStream = Player.ServiceFileStreaming.CreateStreamForFileUri(""); + this.AreEqual(ActionResultType.OK, createStream.ResultType); + + if (!IsValid) + { + return; + } + } + } +} diff --git a/src/IntegrationTest/AimpTestRunner/UnitTests/MessageDispatcher/AimpServiceMessageDispatcherTests.cs b/src/IntegrationTest/AimpTestRunner/UnitTests/MessageDispatcher/AimpServiceMessageDispatcherTests.cs index b9698d42..f368d84b 100644 --- a/src/IntegrationTest/AimpTestRunner/UnitTests/MessageDispatcher/AimpServiceMessageDispatcherTests.cs +++ b/src/IntegrationTest/AimpTestRunner/UnitTests/MessageDispatcher/AimpServiceMessageDispatcherTests.cs @@ -21,71 +21,301 @@ public class AimpServiceMessageDispatcherTests : AimpIntegrationTest { private class TestHook : IAimpMessageHook { - public AimpActionResult CoreMessage(AimpCoreMessageType message, int param1, int param2) + private readonly Action _callBack; + + public TestHook() { + } + + public TestHook(Action callBack) + { + _callBack = callBack; + } + + public AimpActionResult CoreMessage(AimpCoreMessageType message, int param1, IntPtr param2) + { + _callBack?.Invoke(message, param1, param2); + TestContext.Write($"Receive hook: {message}, p1: {param1}, p2: {param2}"); return new AimpActionResult(ActionResultType.OK); } } + public override void RunBeforeAnyTests() + { + base.RunBeforeAnyTests(); + //Player.ServicePlaylistManager.CreatePlaylistFromFile(PlaylistPath, false); + //Player.ServicePlaylistManager.CreatePlaylistFromFile(PlaylistPath, true); + //Player.ServicePlaylistManager.CreatePlaylistFromFile(PlaylistPath, false); + } + [Test] - public void Send_ShouldBeOK() + [Order(1)] + public void Hook_ShouldSetHook() { ExecuteInMainThread(() => { - var result = Player.ServiceMessageDispatcher.Send(AimpCoreMessageType.CmdPause, 0, IntPtr.Zero); - this.AreEqual(ActionResultType.OK, result.ResultType); + var hook = new TestHook(); + var result = Player.ServiceMessageDispatcher.Hook(hook); + this.AreEqual(ActionResultType.OK, result.ResultType, "Cannot hook a new hook"); + Player.ServiceMessageDispatcher.Unhook(hook); }); } [Test] - public void Register_EmptyMessage_ShouldThrowException() + [Order(2)] + public void Unhook_ShouldUnhook() { ExecuteInMainThread(() => { - this.Throw(() => Player.ServiceMessageDispatcher.Register(string.Empty)); + var hook = new TestHook(); + + Player.ServiceMessageDispatcher.Hook(hook); + + var result = Player.ServiceMessageDispatcher.Unhook(hook); + this.AreEqual(ActionResultType.OK, result.ResultType, "Cannot unhook a hook"); }); } - [Test] - public void Register_ShouldReturnMessageId() + [TestCase(AimpCoreMessageType.CmdStateGet, AimpCoreMessageType.CmdAbout)] + [TestCase(AimpCoreMessageType.CmdStateGet, AimpCoreMessageType.CmdAddFiles)] + [TestCase(AimpCoreMessageType.CmdStateGet, AimpCoreMessageType.CmdAddFolders)] + [TestCase(AimpCoreMessageType.CmdStateGet, AimpCoreMessageType.CmdAddPlaylists)] + [TestCase(AimpCoreMessageType.CmdStateGet, AimpCoreMessageType.CmdAddUrl)] + [TestCase(AimpCoreMessageType.CmdStateGet, AimpCoreMessageType.CmdBookmarks)] + [TestCase(AimpCoreMessageType.CmdStateGet, AimpCoreMessageType.CmdBookmarksAdd)] + [TestCase(AimpCoreMessageType.CmdStateGet, AimpCoreMessageType.CmdDSPManager)] + [TestCase(AimpCoreMessageType.CmdStateGet, AimpCoreMessageType.CmdNext)] + [TestCase(AimpCoreMessageType.CmdStateGet, AimpCoreMessageType.CmdOpenFiles)] + [TestCase(AimpCoreMessageType.CmdStateGet, AimpCoreMessageType.CmdOpenFolders)] + [TestCase(AimpCoreMessageType.CmdStateGet, AimpCoreMessageType.CmdOpenPlaylists)] + [TestCase(AimpCoreMessageType.CmdStateGet, AimpCoreMessageType.CmdOptions)] + [TestCase(AimpCoreMessageType.CmdStateGet, AimpCoreMessageType.CmdPause)] + [TestCase(AimpCoreMessageType.CmdStateGet, AimpCoreMessageType.CmdPlay)] + [TestCase(AimpCoreMessageType.CmdStateGet, AimpCoreMessageType.CmdPlayPause)] + [TestCase(AimpCoreMessageType.CmdStateGet, AimpCoreMessageType.CmdPlayPrevPlaylist)] + [TestCase(AimpCoreMessageType.CmdStateGet, AimpCoreMessageType.CmdPlaylistDeleteAll)] + [TestCase(AimpCoreMessageType.CmdStateGet, AimpCoreMessageType.CmdPlaylistDeleteDuplicates)] + [TestCase(AimpCoreMessageType.CmdStateGet, AimpCoreMessageType.CmdPlaylistDeleteNonExists)] + [TestCase(AimpCoreMessageType.CmdStateGet, AimpCoreMessageType.CmdPlaylistDeleteNonSelected)] + [TestCase(AimpCoreMessageType.CmdStateGet, AimpCoreMessageType.CmdPlaylistDeletePlayingFromHDD)] + [TestCase(AimpCoreMessageType.CmdStateGet, AimpCoreMessageType.CmdPlaylistDeleteSwitchedOff)] + [TestCase(AimpCoreMessageType.CmdStateGet, AimpCoreMessageType.CmdPlaylistDeleteSwitchedOffFromHDD)] + [TestCase(AimpCoreMessageType.CmdStateGet, AimpCoreMessageType.CmdPlaylistFocusPlaying)] + [TestCase(AimpCoreMessageType.CmdStateGet, AimpCoreMessageType.CmdPlaylistReloadFromPreimage)] + [TestCase(AimpCoreMessageType.CmdStateGet, AimpCoreMessageType.CmdPlaylistRescan)] + [TestCase(AimpCoreMessageType.CmdStateGet, AimpCoreMessageType.CmdPlaylistRescanSelected)] + [TestCase(AimpCoreMessageType.CmdStateGet, AimpCoreMessageType.CmdPlaylistSortByArtist)] + [TestCase(AimpCoreMessageType.CmdStateGet, AimpCoreMessageType.CmdPlaylistSortByDuration)] + [TestCase(AimpCoreMessageType.CmdStateGet, AimpCoreMessageType.CmdPlaylistSortByPath)] + [TestCase(AimpCoreMessageType.CmdStateGet, AimpCoreMessageType.CmdPlaylistSortByTitle)] + [TestCase(AimpCoreMessageType.CmdStateGet, AimpCoreMessageType.CmdPlaylistSortInvert)] + [TestCase(AimpCoreMessageType.CmdStateGet, AimpCoreMessageType.CmdPlaylistSortRandomize)] + [TestCase(AimpCoreMessageType.CmdStateGet, AimpCoreMessageType.CmdPlaylistSwitchOn)] + [TestCase(AimpCoreMessageType.CmdStateGet, AimpCoreMessageType.CmdPlaylistSwitchOff)] + [TestCase(AimpCoreMessageType.CmdStateGet, AimpCoreMessageType.CmdPlugins)] + [TestCase(AimpCoreMessageType.CmdStateGet, AimpCoreMessageType.CmdPrev)] + [TestCase(AimpCoreMessageType.CmdStateGet, AimpCoreMessageType.CmdQFIPlaybackTrack)] + [TestCase(AimpCoreMessageType.CmdStateGet, AimpCoreMessageType.CmdQTEPlayingTrack)] + [TestCase(AimpCoreMessageType.CmdStateGet, AimpCoreMessageType.CmdQuit)] + [TestCase(AimpCoreMessageType.CmdStateGet, AimpCoreMessageType.CmdShowNotification)] + [TestCase(AimpCoreMessageType.CmdStateGet, AimpCoreMessageType.CmdSavePlaylists)] + [TestCase(AimpCoreMessageType.CmdStateGet, AimpCoreMessageType.CmdScheduler)] + [TestCase(AimpCoreMessageType.CmdStateGet, AimpCoreMessageType.CmdSearch)] + [TestCase(AimpCoreMessageType.CmdStateGet, AimpCoreMessageType.CmdStop)] + [TestCase(AimpCoreMessageType.CmdStateGet, AimpCoreMessageType.CmdTogglePartRepeat)] + [TestCase(AimpCoreMessageType.CmdStateGet, AimpCoreMessageType.CmdVisualNext)] + [TestCase(AimpCoreMessageType.CmdStateGet, AimpCoreMessageType.CmdVisualPrev)] + [TestCase(AimpCoreMessageType.CmdStateGet, AimpCoreMessageType.CmdVisualStart)] + [TestCase(AimpCoreMessageType.CmdStateGet, AimpCoreMessageType.CmdVisualStop)] + [TestCase(AimpCoreMessageType.CmdStateGet, AimpCoreMessageType.CmdQFI)] + public void Send_CheckIsCommandAllowed_ShouldBeOK(AimpCoreMessageType messageType, AimpCoreMessageType param1) { ExecuteInMainThread(() => { - var result = Player.ServiceMessageDispatcher.Register("Test"); - this.IsTrue(result > 0); + var result = Player.ServiceMessageDispatcher.Send(messageType, (int)param1, IntPtr.Zero); + this.IsTrue(result.ResultType == ActionResultType.OK || result.ResultType == ActionResultType.Fail || result.ResultType == ActionResultType.NotImplemented, $"Current value {result.ResultType}"); }); } - [Test] - public void Hook_Null_ShouldThrowException() + [TestCase(AimpCoreMessageType.PropertyEcho, 0.5, Description = "Set echo to 0.5")] + [TestCase(AimpCoreMessageType.PropertyBalance, 0.5, Description = "Set balance to 0.5")] + [TestCase(AimpCoreMessageType.PropertyChorus, 0.5, Description = "Set chorus to 0.5")] + [TestCase(AimpCoreMessageType.PropertyCrossmixing, true, Description = "Enable Crossmixing")] + [TestCase(AimpCoreMessageType.PropertyCrossmixing, false, Description = "Disable Crossmixing")] + [TestCase(AimpCoreMessageType.PropertyEnhancer, 1.5, Description = "Set Enhancer to 1.5")] + [TestCase(AimpCoreMessageType.PropertyEqualizer, true, Description = "Enable Equalizer")] + [TestCase(AimpCoreMessageType.PropertyEqualizer, false, Description = "Disable Equalizer")] + [TestCase(AimpCoreMessageType.PropertyFlanger, 0.5, Description = "Set Flanger to 0.5")] + [TestCase(AimpCoreMessageType.PropertyMinimizedToTray, true)] + [TestCase(AimpCoreMessageType.PropertyMinimizedToTray, false)] + [TestCase(AimpCoreMessageType.PropertyMute, true)] + [TestCase(AimpCoreMessageType.PropertyMute, false)] + [TestCase(AimpCoreMessageType.PropertyPitch, 2.1)] + [TestCase(AimpCoreMessageType.PropertyPlayerBuffering, 50.5)] + [TestCase(AimpCoreMessageType.PropertyPlayerPosition, 10.5)] + [TestCase(AimpCoreMessageType.PropertyPreamp, 10.5)] + [TestCase(AimpCoreMessageType.PropertyRadioCap, true)] + [TestCase(AimpCoreMessageType.PropertyRadioCap, false)] + [TestCase(AimpCoreMessageType.PropertyRadioCapSingleTrack, true)] + [TestCase(AimpCoreMessageType.PropertyRadioCapSingleTrack, false)] + [TestCase(AimpCoreMessageType.PropertyRepeat, true)] + [TestCase(AimpCoreMessageType.PropertyRepeat, false)] + [TestCase(AimpCoreMessageType.PropertyRepeatSingleFilePlaylists, true)] + [TestCase(AimpCoreMessageType.PropertyRepeatSingleFilePlaylists, false)] + [TestCase(AimpCoreMessageType.PropertyReverb, 0.5, Description = "Set Reverb to 0.5")] + [TestCase(AimpCoreMessageType.PropertyReverseTime, true)] + [TestCase(AimpCoreMessageType.PropertyReverseTime, false)] + [TestCase(AimpCoreMessageType.PropertyShuffle, true)] + [TestCase(AimpCoreMessageType.PropertyShuffle, false)] + [TestCase(AimpCoreMessageType.PropertySpeed, 1.1)] + [TestCase(AimpCoreMessageType.PropertyStayOnTop, true, Description = "Enable Stay on top")] + [TestCase(AimpCoreMessageType.PropertyStayOnTop, false, Description = "Disable Stay on top")] + [TestCase(AimpCoreMessageType.PropertyTempo, 1.1)] + [TestCase(AimpCoreMessageType.PropertyTruebass, 1.1)] +#if !DEBUG + [TestCase(AimpCoreMessageType.PropertyVisualFullscreen, true)] + [TestCase(AimpCoreMessageType.PropertyVisualFullscreen, false)] +#endif + [TestCase(AimpCoreMessageType.PropertyVolume, 0.5)] + [Ignore("Should reset to default before run")] + public void Send_PropertyValueSet_ShouldBeCorrect(AimpCoreMessageType command, object param2) { ExecuteInMainThread(() => { - this.Throw(() => Player.ServiceMessageDispatcher.Hook(null)); + bool validate = true; + IntPtr outParam2 = IntPtr.Zero; + AimpCoreMessageType outType = AimpCoreMessageType.CmdAbout; + + var hook = new TestHook((t, p1, p2) => + { + if (validate && p1 == (int) AimpCoreMessageType.PropertyValueSet) + { + outType = t; + outParam2 = p2; + } + + validate = false; + }); + var result = Player.ServiceMessageDispatcher.Hook(hook); + this.AreEqual(ActionResultType.OK, result.ResultType, "Cannot register a new hook"); + + if (!IsValid) + { + return; + } + + var cmdResult = Player.ServiceMessageDispatcher.Send(command, (int)AimpCoreMessageType.PropertyValueSet, param2.ToPointer()); + this.AreEqual(ActionResultType.OK, cmdResult.ResultType); + this.IsTrue(outParam2 != IntPtr.Zero); + Player.ServiceMessageDispatcher.Unhook(hook); + + if (!IsValid) + { + return; + } + + switch (outType) + { + case AimpCoreMessageType.PropertyStayOnTop: + case AimpCoreMessageType.PropertyCrossmixing: + case AimpCoreMessageType.PropertyEqualizer: + case AimpCoreMessageType.PropertyMinimizedToTray: + case AimpCoreMessageType.PropertyMute: + case AimpCoreMessageType.PropertyRadioCap: + case AimpCoreMessageType.PropertyRadioCapSingleTrack: + case AimpCoreMessageType.PropertyRepeat: + case AimpCoreMessageType.PropertyRepeatSingleFilePlaylists: + case AimpCoreMessageType.PropertyShuffle: + this.AreEqual(param2, outParam2.ToBool()); + break; + case AimpCoreMessageType.PropertyEcho: + case AimpCoreMessageType.PropertyBalance: + case AimpCoreMessageType.PropertyChorus: + case AimpCoreMessageType.PropertyEnhancer: + case AimpCoreMessageType.PropertyPitch: + case AimpCoreMessageType.PropertyPlayerBuffering: + case AimpCoreMessageType.PropertyPlayerPosition: + case AimpCoreMessageType.PropertyPreamp: + case AimpCoreMessageType.PropertyReverb: + case AimpCoreMessageType.PropertyReverseTime: + case AimpCoreMessageType.PropertySpeed: + case AimpCoreMessageType.PropertyTempo: + case AimpCoreMessageType.PropertyTruebass: + case AimpCoreMessageType.PropertyVisualFullscreen: + case AimpCoreMessageType.PropertyVolume: + this.AreEqual(param2, outParam2.ToDouble()); + break; + } }); } - [Test] - public void Hook_ShouldSetHook() + [TestCase(AimpDescriptorType.MainForm)] + [TestCase(AimpDescriptorType.Application)] + [TestCase(AimpDescriptorType.TrayControl)] + [TestCase(AimpDescriptorType.PlaylistForm)] + [TestCase(AimpDescriptorType.EqualizerForm)] + [Ignore("Not working?")] + public void Send_HWND_ShouldReturnDescriptor(AimpDescriptorType windowId) { ExecuteInMainThread(() => { - var result = Player.ServiceMessageDispatcher.Hook(new TestHook()); - this.AreEqual(ActionResultType.OK, result.ResultType, "Cannot hook a new hook"); + bool validate = true; + IntPtr outParam2 = IntPtr.Zero; + AimpCoreMessageType outType = AimpCoreMessageType.CmdAbout; + + var hook = new TestHook((t, p1, p2) => + { + if (validate && p1 == (int) AimpCoreMessageType.PropertyValueSet) + { + outType = t; + outParam2 = p2; + } + + validate = false; + }); + + var result = Player.ServiceMessageDispatcher.Hook(hook); + this.AreEqual(ActionResultType.OK, result.ResultType, "Cannot register a new hook"); + + if (!IsValid) + { + return; + } + + var cmdResult = Player.ServiceMessageDispatcher.Send(AimpCoreMessageType.PropertyHwnd, (int)windowId, IntPtr.Zero); + this.AreEqual(ActionResultType.OK, cmdResult.ResultType); + + this.IsTrue(outParam2 != IntPtr.Zero); + + Player.ServiceMessageDispatcher.Unhook(hook); }); } [Test] - public void Unhook_ShouldUnhook() + public void Register_EmptyMessage_ShouldThrowException() { ExecuteInMainThread(() => { - var hook = new TestHook(); + this.Throw(() => Player.ServiceMessageDispatcher.Register(string.Empty)); + }); + } - Player.ServiceMessageDispatcher.Hook(hook); + [Test] + public void Register_ShouldReturnMessageId() + { + ExecuteInMainThread(() => + { + var result = Player.ServiceMessageDispatcher.Register("Test"); + this.IsTrue(result > 0); + }); + } - var result = Player.ServiceMessageDispatcher.Unhook(hook); - this.AreEqual(ActionResultType.OK, result.ResultType, "Cannot unhook a hook"); + [Test] + public void Hook_Null_ShouldThrowException() + { + ExecuteInMainThread(() => + { + this.Throw(() => Player.ServiceMessageDispatcher.Hook(null)); }); } } diff --git a/src/IntegrationTest/AimpTestRunner/UnitTests/Objects/AimpFileStreamUnitTests.cs b/src/IntegrationTest/AimpTestRunner/UnitTests/Objects/AimpFileStreamUnitTests.cs new file mode 100644 index 00000000..3d697260 --- /dev/null +++ b/src/IntegrationTest/AimpTestRunner/UnitTests/Objects/AimpFileStreamUnitTests.cs @@ -0,0 +1,64 @@ +// ---------------------------------------------------- +// +// AIMP DotNet SDK +// +// Copyright (c) 2014 - 2020 Evgeniy Bogdan +// https://github.com/martin211/aimp_dotnet +// +// Mail: mail4evgeniy@gmail.com +// +// ---------------------------------------------------- + +using AIMP.SDK; +using AIMP.SDK.FileManager; +using AIMP.SDK.Objects; +using NUnit.Framework; + +namespace Aimp.TestRunner.UnitTests.Objects +{ + [TestFixture] + public class AimpFileStreamUnitTests : AimpIntegrationTest + { + [Test] + [Ignore("Not working")] + public void GetClipping_OK() + { + var fileStream = Player.ServiceFileStreaming.CreateStreamForFile(TrackPath1, FileStreamingType.Read, -1, -1); + this.AreEqual(ActionResultType.OK, fileStream.ResultType); + + if (!IsValid) + { + return; + } + + var stream = fileStream.Result as IAimpFileStream; + this.NotNull(stream); + + var clippingResult = stream.GetClipping(); + this.AreEqual(ActionResultType.OK, clippingResult.ResultType); + + this.IsTrue(clippingResult.Result.Size > 0); + this.IsTrue(clippingResult.Result.Offset > 0); + } + + [Test] + [Ignore("Not working")] + public void GetFileName_OK() + { + var fileStream = Player.ServiceFileStreaming.CreateStreamForFile(TrackPath1, FileStreamingType.Read, -1, -1); + this.AreEqual(ActionResultType.OK, fileStream.ResultType); + + if (!IsValid) + { + return; + } + + var stream = fileStream.Result as IAimpFileStream; + this.NotNull(stream); + + var result = stream.GetFileName(); + this.AreEqual(ActionResultType.OK, result.ResultType); + this.NotNull(result.Result); + } + } +} diff --git a/src/IntegrationTest/AimpTestRunner/UnitTests/Objects/AimpStreamUnitTests.cs b/src/IntegrationTest/AimpTestRunner/UnitTests/Objects/AimpStreamUnitTests.cs new file mode 100644 index 00000000..9ceeb331 --- /dev/null +++ b/src/IntegrationTest/AimpTestRunner/UnitTests/Objects/AimpStreamUnitTests.cs @@ -0,0 +1,174 @@ +// ---------------------------------------------------- +// +// AIMP DotNet SDK +// +// Copyright (c) 2014 - 2020 Evgeniy Bogdan +// https://github.com/martin211/aimp_dotnet +// +// Mail: mail4evgeniy@gmail.com +// +// ---------------------------------------------------- + +using System.IO; +using AIMP.SDK; +using AIMP.SDK.Objects; +using NUnit.Framework; + +namespace Aimp.TestRunner.UnitTests.Objects +{ + [TestFixture] + public class AimpStreamUnitTests : AimpIntegrationTest + { + [Test] + [Order(1)] + public void Stream_Write_OK() + { + var res = Player.Core.CreateAimpObject(); + this.AreEqual(ActionResultType.OK, res.ResultType); + + if (!IsValid) + { + return; + } + + var buf = new byte[] + { + 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 + }; + + using var stream = res.Result; + var res2 = stream.Write(buf, buf.Length, out var written); + + this.AreEqual(ActionResultType.OK, res2.ResultType); + this.AreEqual(buf.Length, written); + } + + [Test] + [Order(2)] + public void Stream_GetSize_OK() + { + var res = Player.Core.CreateAimpObject(); + this.AreEqual(ActionResultType.OK, res.ResultType); + + if (!IsValid) + { + return; + } + + var buf = new byte[] + { + 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 + }; + + using var stream = res.Result; + var res2 = stream.Write(buf, buf.Length, out var written); + this.AreEqual(ActionResultType.OK, res2.ResultType); + this.AreEqual(buf.Length, stream.GetSize()); + } + + [Test] + [Order(3)] + public void Stream_Read_OK() + { + var res = Player.Core.CreateAimpObject(); + this.AreEqual(ActionResultType.OK, res.ResultType); + + if (!IsValid) + { + return; + } + + var buf = new byte[] + { + 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 + }; + + using var stream = res.Result; + stream.Write(buf, buf.Length, out var written); + var readBuf = new byte[stream.GetSize()]; + stream.Seek(0, SeekOrigin.Begin); + int readLength = stream.Read(readBuf, readBuf.Length); + this.AreEqual(readLength, readBuf.Length); + } + + [Test] + [Order(4)] + public void Stream_Seek_OK() + { + var res = Player.Core.CreateAimpObject(); + this.AreEqual(ActionResultType.OK, res.ResultType); + + if (!IsValid) + { + return; + } + + var buf = new byte[] + { + 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 + }; + + using var stream = res.Result; + stream.Write(buf, buf.Length, out _); + + this.AreEqual(buf.Length, stream.GetPosition()); + stream.Seek(2, SeekOrigin.Begin); + this.AreEqual(2, stream.GetPosition()); + stream.Seek(-2, SeekOrigin.Current); + this.AreEqual(0, stream.GetPosition()); + stream.Seek(-2, SeekOrigin.End); + this.AreEqual(8, stream.GetPosition()); + } + + [Test] + [Order(10)] + public void Stream_GetPosition_OK() + { + var res = Player.Core.CreateAimpObject(); + this.AreEqual(ActionResultType.OK, res.ResultType); + + if (!IsValid) + { + return; + } + + var buf = new byte[] + { + 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 + }; + + using var stream = res.Result; + stream.Write(buf, buf.Length, out _); + var readBuf = new byte[stream.GetSize()]; + stream.Seek(0, SeekOrigin.Begin); + stream.Read(readBuf, 4); + + var pos = stream.GetPosition(); + this.AreEqual(4, pos); + } + + [Test] + [Order(20)] + public void MemoryStream_GetData_OK() + { + var res = Player.Core.CreateAimpObject(); + this.AreEqual(ActionResultType.OK, res.ResultType); + if (!IsValid) + { + return; + } + var buf = new byte[] + { + 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 + }; + + using var stream = res.Result; + stream.Write(buf, buf.Length, out _); + stream.Seek(0, SeekOrigin.Begin); + var getDataResult = stream.GetData(); + this.AreEqual(ActionResultType.OK, getDataResult.ResultType); + this.NotNull(getDataResult.Result); + this.AreEqual(10, getDataResult.Result.Length); + } + } +} diff --git a/src/IntegrationTest/AimpTestRunner/UnitTests/TagEditor/AimpServiceFileTagEditorTests.cs b/src/IntegrationTest/AimpTestRunner/UnitTests/TagEditor/AimpServiceFileTagEditorTests.cs index e62f7385..534aaf5d 100644 --- a/src/IntegrationTest/AimpTestRunner/UnitTests/TagEditor/AimpServiceFileTagEditorTests.cs +++ b/src/IntegrationTest/AimpTestRunner/UnitTests/TagEditor/AimpServiceFileTagEditorTests.cs @@ -26,6 +26,7 @@ public void EditFile_ShouldReturnTagEditorForFile() var result = Player.ServiceFileTagEditor.EditFile(TrackPath1); this.AreEqual(ActionResultType.OK, result.ResultType, "Unable to get tag editor for file."); this.NotNull(result.Result); + result.Result.Dispose(); }); } @@ -39,6 +40,7 @@ public void EditTag_FilePath_ShouldBeOK(TagType tag) var result = Player.ServiceFileTagEditor.EditTag(TrackPath1, tag); this.AreEqual(ActionResultType.OK, result.ResultType, "Unable to edit tag for file."); this.NotNull(result.Result); + result.Result.Dispose(); }); } @@ -53,6 +55,7 @@ public void EditTag_FilePath_ShouldBeFailForWrongFileFormat(TagType tag) var result = Player.ServiceFileTagEditor.EditTag(TrackPath1, tag); this.AreEqual(ActionResultType.Fail, result.ResultType, "Unable to edit tag for file."); this.Null(() => result.Result); + result.Result.Dispose(); }); } } diff --git a/src/Plugins/dotnet_demo/PlayerForm.Designer.cs b/src/Plugins/dotnet_demo/PlayerForm.Designer.cs index 06d3e8ba..ac4bca63 100644 --- a/src/Plugins/dotnet_demo/PlayerForm.Designer.cs +++ b/src/Plugins/dotnet_demo/PlayerForm.Designer.cs @@ -45,6 +45,8 @@ private void InitializeComponent() this.button9 = new System.Windows.Forms.Button(); this.menuStrip1 = new System.Windows.Forms.MenuStrip(); this.toolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripMenuItem2 = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripMenuItem3 = new System.Windows.Forms.ToolStripMenuItem(); ((System.ComponentModel.ISupportInitialize)(this.trackBar1)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.trackBar2)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit(); @@ -197,7 +199,8 @@ private void InitializeComponent() // menuStrip1 // this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.toolStripMenuItem1}); + this.toolStripMenuItem1, + this.toolStripMenuItem2}); this.menuStrip1.Location = new System.Drawing.Point(0, 0); this.menuStrip1.Name = "menuStrip1"; this.menuStrip1.Size = new System.Drawing.Size(687, 24); @@ -211,6 +214,21 @@ private void InitializeComponent() this.toolStripMenuItem1.Text = "View log"; this.toolStripMenuItem1.Click += new System.EventHandler(this.toolStripMenuItem1_Click); // + // toolStripMenuItem2 + // + this.toolStripMenuItem2.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.toolStripMenuItem3}); + this.toolStripMenuItem2.Name = "toolStripMenuItem2"; + this.toolStripMenuItem2.Size = new System.Drawing.Size(125, 20); + this.toolStripMenuItem2.Text = "toolStripMenuItem2"; + // + // toolStripMenuItem3 + // + this.toolStripMenuItem3.Name = "toolStripMenuItem3"; + this.toolStripMenuItem3.Size = new System.Drawing.Size(180, 22); + this.toolStripMenuItem3.Text = "On Top"; + this.toolStripMenuItem3.Click += new System.EventHandler(this.toolStripMenuItem3_Click); + // // PlayerForm // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); @@ -265,7 +283,9 @@ private void InitializeComponent() private System.Windows.Forms.ToolStripStatusLabel toolStripStatusLabel1; private System.Windows.Forms.Button button9; private System.Windows.Forms.MenuStrip menuStrip1; - private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem1; + private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem1; + private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem2; + private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem3; } } diff --git a/src/Plugins/dotnet_demo/PlayerForm.cs b/src/Plugins/dotnet_demo/PlayerForm.cs index 3f141ec8..ca2412f4 100644 --- a/src/Plugins/dotnet_demo/PlayerForm.cs +++ b/src/Plugins/dotnet_demo/PlayerForm.cs @@ -12,6 +12,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Runtime.InteropServices; using System.Windows.Forms; using AIMP.SDK; using AIMP.SDK.MessageDispatcher; @@ -39,7 +40,9 @@ public PlayerForm(IAimpPlayer player, MessageHook coreMessage) coreMessage.OnCoreMessage += (message, param1, param2) => { - if (message == AimpCoreMessageType.EventPlayableFileInfo) + System.Diagnostics.Debug.WriteLine($"message: {message}, param1: {(AimpCoreMessageType)param1}, param2: {param2}"); + + if (message == AimpCoreMessageType.EventPlayingFileInfo) { var cover = _aimpPlayer.CurrentFileInfo.AlbumArt; if (cover != null) @@ -64,6 +67,17 @@ public PlayerForm(IAimpPlayer player, MessageHook coreMessage) break; } } + else if (message == AimpCoreMessageType.EventPropertyValue) + { + if (param1 == (int) AimpCoreMessageType.PropertyStayOnTop) + { + var val = Convert.ToBoolean(Marshal.ReadByte(param2)); + } + } + else if (message == AimpCoreMessageType.PropertyStayOnTop) + { + var val2 = param2.ToBool(); + } return ActionResultType.OK; }; @@ -319,5 +333,13 @@ private void PlayerForm_Shown(object sender, EventArgs e) } } } + + private bool _onTop = false; + + private void toolStripMenuItem3_Click(object sender, EventArgs e) + { + var val = !_onTop; + _aimpPlayer.ServiceMessageDispatcher.Send(AimpCoreMessageType.PropertyStayOnTop, (int)AimpCoreMessageType.PropertyValueSet, val.ToPointer()); + } } } diff --git a/src/Plugins/dotnet_demo/Program.cs b/src/Plugins/dotnet_demo/Program.cs index c93d0e2b..9c6ac7f6 100644 --- a/src/Plugins/dotnet_demo/Program.cs +++ b/src/Plugins/dotnet_demo/Program.cs @@ -24,11 +24,11 @@ namespace TestPlugin using AIMP.SDK.MenuManager; using AIMP.SDK.Options; - public delegate ActionResultType HookMessage(AimpCoreMessageType message, int param1, int param2); + public delegate ActionResultType HookMessage(AimpCoreMessageType message, int param1, IntPtr param2); public class MessageHook : IAimpMessageHook { - public AimpActionResult CoreMessage(AimpCoreMessageType message, int param1, int param2) + public AimpActionResult CoreMessage(AimpCoreMessageType message, int param1, IntPtr param2) { OnCoreMessage?.Invoke(message, param1, param2); return new AimpActionResult(ActionResultType.OK); diff --git a/src/Plugins/native_plugin/gulpfile.js b/src/Plugins/native_plugin/gulpfile.js deleted file mode 100644 index 38686d31..00000000 --- a/src/Plugins/native_plugin/gulpfile.js +++ /dev/null @@ -1,42 +0,0 @@ -/// -/* -This file is the main entry point for defining Gulp tasks and using Gulp plugins. -Click here to learn more. https://go.microsoft.com/fwlink/?LinkId=518007 -*/ - -var gulp = require("gulp"); -var gulpRename = require("gulp-rename"); -var gulpCopy = require("gulp-copy"); -var concat = require("gulp-concat"); -var clean = require("gulp-clean"); - -var configuration = "Debug"; -var pluginName = "native_plugin"; -var aimpFolder = "AIMP4.51"; - -var paths = { - plugin: "./" + configuration, - output: "../../../../" + aimpFolder + "/Plugins/" + pluginName -}; - -gulp.task("default", - ["clean", "copy"], - function() { - // place code for your default task here - }); - -gulp.task("copy", ["copy:plugin"]); - -gulp.task("clean", - function() { - gulp.src(paths.output, { read: false }) - .pipe(clean({ force: true })); - }); - -gulp.task("copy:plugin", - function() { - gulp.src([ - paths.plugin + "/*.dll" - ]) - .pipe(gulp.dest(paths.output)); - }); diff --git a/src/Plugins/native_plugin/native_plugin.h b/src/Plugins/native_plugin/native_plugin.h index 492b2ec8..cb4015cd 100644 --- a/src/Plugins/native_plugin/native_plugin.h +++ b/src/Plugins/native_plugin/native_plugin.h @@ -20,12 +20,12 @@ #include "TMyMusicFileSystem.h" -#define DBOUT( s ) \ -{ \ - std::wostringstream os_; \ - os_ << s; \ - OutputDebugStringW( os_.str().c_str() ); \ -} +//#define DBOUT( s ) \ +//{ \ +// std::wostringstream os_; \ +// os_ << s; \ +// OutputDebugStringW( os_.str().c_str() ); \ +//} class AimpTask : public IUnknownInterfaceImpl { public: @@ -54,7 +54,7 @@ class AimpTask : public IUnknownInterfaceImpl { } virtual void WINAPI Execute(IAIMPTaskOwner* Owner) { - DBOUT("Tasl execute"); + } }; @@ -68,7 +68,6 @@ class AimpActionEvent : public IUnknownInterfaceImpl { } virtual void WINAPI OnExecute(IUnknown* Data) { - System::Diagnostics::Debugger::Launch(); System::String^ folder = System::Environment::GetFolderPath(System::Environment::SpecialFolder::MyMusic); gcroot^> arr = System::IO::Directory::GetFiles(folder, "*.mp3"); @@ -148,10 +147,9 @@ class NativePlugin : public IUnknownInterfaceImpl { RegisterMenu(Core); IUnknown* fs = (IAIMPExtensionFileSystem*)new TMyMusicFileSystem(); - HRESULT res = Core->RegisterExtension(IID_IAIMPExtensionFileSystem, fs); - DBOUT("RegisterExtension result " << res); - + ImageTest(Core); + FileStreamTest(Core); return S_OK; } @@ -195,4 +193,41 @@ class NativePlugin : public IUnknownInterfaceImpl { core->RegisterExtension(IID_IAIMPServiceMenuManager, item); } } + + void ImageTest(IAIMPCore* core) { + IAIMPImage2* img = nullptr; + SIZE* s = new SIZE(); + IAIMPString* fn = nullptr; + IAIMPString* fn2 = nullptr; + + HRESULT r1 = core->CreateObject(IID_IAIMPString, (void**)&fn); + core->CreateObject(IID_IAIMPString, (void**)&fn2); + HRESULT r2 = core->CreateObject(IID_IAIMPImage2, (void**)&img); + + HRESULT r3 = fn->SetData(L"z:/AIMP/aimp_dotnet/resources/integrationTests/img1.jpg", 56); + fn2->SetData(L"z:/AIMP/aimp_dotnet/resources/integrationTests/img2.bmp", 56); + + HRESULT r4 = img->LoadFromFile(fn); + HRESULT r5 = img->GetSize(s); + const auto x = s->cx; + const auto y = s->cy; + + IAIMPImage* cloneImg = nullptr; + //core->CreateObject(IID_IAIMPImage, (void**)&cloneImg); + + //HRESULT r6 = img->Clone(&cloneImg); + img->SaveToFile(fn2, AIMP_IMAGE_FORMAT_BMP); + } + + void FileStreamTest(IAIMPCore* core) { + IAIMPServiceFileStreaming* service = nullptr; + IAIMPString* s = nullptr; + IAIMPStream* stream = nullptr; + core->CreateObject(IID_IAIMPString, (void**)&s); + core->QueryInterface(IID_IAIMPServiceFileStreaming, (void**)&service); + s->SetData(L"z:/AIMP/aimp_dotnet/resources/integrationTests/01_atmosphere.mp3", 65); + service->CreateStreamForFile(s, AIMP_SERVICE_FILESTREAMING_FLAG_READWRITE, -1, -1, &stream); + IAIMPString* fn = nullptr; + ((IAIMPFileStream*)stream)->GetFileName(&fn); + } }; diff --git a/src/Plugins/native_plugin/native_plugin.vcxproj b/src/Plugins/native_plugin/native_plugin.vcxproj index ffbddbea..0723cb71 100644 --- a/src/Plugins/native_plugin/native_plugin.vcxproj +++ b/src/Plugins/native_plugin/native_plugin.vcxproj @@ -106,7 +106,7 @@ - + diff --git a/src/Plugins/native_plugin/native_plugin.vcxproj.filters b/src/Plugins/native_plugin/native_plugin.vcxproj.filters index d4cf7b96..c0ec1975 100644 --- a/src/Plugins/native_plugin/native_plugin.vcxproj.filters +++ b/src/Plugins/native_plugin/native_plugin.vcxproj.filters @@ -101,8 +101,8 @@ Source Files - + diff --git a/src/aimp_dotnet.sln b/src/aimp_dotnet.sln index e6641dd1..02e33001 100644 --- a/src/aimp_dotnet.sln +++ b/src/aimp_dotnet.sln @@ -5,34 +5,17 @@ VisualStudioVersion = 16.0.29519.87 MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Plugins", "Plugins", "{56B57E6A-FD0A-4479-B8D9-149BBD6F9C73}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "aimp_dotnet", "aimp_dotnet\Aimp_DotNetPlugin.vcxproj", "{8D30D1F5-1925-4926-83F2-F0B21B45646F}" -EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AIMP.SDK", "AIMP.SDK\AIMP.SDK.csproj", "{154C60CF-2DAE-4227-AD2C-CCE7C63CDE5A}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "dotnet_ExtendDialogWindow", "Plugins\dotnet_ExtendDialogWindow\dotnet_ExtendDialogWindow.csproj", "{8B2B3BD6-C90C-40FA-8655-CFE1CC12CBD3}" - ProjectSection(ProjectDependencies) = postProject - {8D30D1F5-1925-4926-83F2-F0B21B45646F} = {8D30D1F5-1925-4926-83F2-F0B21B45646F} - EndProjectSection EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "dotnet_albumart", "Plugins\dotnet_albumart\dotnet_albumart.csproj", "{6961D299-1D2B-435E-8222-A82FF8EECA1C}" - ProjectSection(ProjectDependencies) = postProject - {8D30D1F5-1925-4926-83F2-F0B21B45646F} = {8D30D1F5-1925-4926-83F2-F0B21B45646F} - EndProjectSection EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "dotnet_visual", "Plugins\dotnet_visual\dotnet_visual.csproj", "{CB62443E-69B5-43B3-9785-647CAA36D175}" - ProjectSection(ProjectDependencies) = postProject - {8D30D1F5-1925-4926-83F2-F0B21B45646F} = {8D30D1F5-1925-4926-83F2-F0B21B45646F} - EndProjectSection EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "dotnet_threading", "Plugins\dotnet_threading\dotnet_threading.csproj", "{E9D9E53D-40D5-4965-9770-FAADF73CEEEA}" - ProjectSection(ProjectDependencies) = postProject - {8D30D1F5-1925-4926-83F2-F0B21B45646F} = {8D30D1F5-1925-4926-83F2-F0B21B45646F} - EndProjectSection EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "dotnet_musiclibrary", "Plugins\dotnet_musiclibrary\dotnet_musiclibrary.csproj", "{9C155223-D1C5-4943-A4E6-02131544E5FD}" - ProjectSection(ProjectDependencies) = postProject - {8D30D1F5-1925-4926-83F2-F0B21B45646F} = {8D30D1F5-1925-4926-83F2-F0B21B45646F} - EndProjectSection EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "SolutionItems", "SolutionItems", "{E560656D-14CC-48E6-A94E-9992D99B5BA0}" ProjectSection(SolutionItems) = preProject @@ -45,14 +28,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "SolutionItems", "SolutionIt EndProjectSection EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "dotnet_demo", "Plugins\dotnet_demo\dotnet_demo.csproj", "{72CBA5F8-494D-4EEB-803B-7D1802A91D4A}" - ProjectSection(ProjectDependencies) = postProject - {8D30D1F5-1925-4926-83F2-F0B21B45646F} = {8D30D1F5-1925-4926-83F2-F0B21B45646F} - EndProjectSection EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "dotnet_SmartPlaylist", "Plugins\dotnet_SmartPlaylist\dotnet_SmartPlaylist.csproj", "{2B1CD6EA-5B3B-44FE-A242-F06C1D6A41F9}" - ProjectSection(ProjectDependencies) = postProject - {8D30D1F5-1925-4926-83F2-F0B21B45646F} = {8D30D1F5-1925-4926-83F2-F0B21B45646F} - EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "native_plugin", "Plugins\native_plugin\native_plugin.vcxproj", "{7D283154-7CF9-434E-BA5A-5FB3D03AC271}" EndProject @@ -62,108 +39,172 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "IntegrationTest", "Integrat EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AimpTestRunner", "IntegrationTest\AimpTestRunner\AimpTestRunner.csproj", "{35DC3E20-FF8D-42B4-991A-85296A243FA1}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "aimp_dotnet", "aimp_dotnet\Aimp_DotNetPlugin.vcxproj", "{8D30D1F5-1925-4926-83F2-F0B21B45646F}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "_build", "..\build\_build.csproj", "{1D813DFE-338B-4C36-AAB0-98D7C6A949CC}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{DABC64E2-6F5D-4E43-AF76-2B177C5E2353}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU + Debug|x64 = Debug|x64 Debug|x86 = Debug|x86 Release|Any CPU = Release|Any CPU + Release|x64 = Release|x64 Release|x86 = Release|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {8D30D1F5-1925-4926-83F2-F0B21B45646F}.Debug|Any CPU.ActiveCfg = Debug|Win32 - {8D30D1F5-1925-4926-83F2-F0B21B45646F}.Debug|Any CPU.Build.0 = Debug|Win32 - {8D30D1F5-1925-4926-83F2-F0B21B45646F}.Debug|x86.ActiveCfg = Debug|Win32 - {8D30D1F5-1925-4926-83F2-F0B21B45646F}.Debug|x86.Build.0 = Debug|Win32 - {8D30D1F5-1925-4926-83F2-F0B21B45646F}.Release|Any CPU.ActiveCfg = Release|Win32 - {8D30D1F5-1925-4926-83F2-F0B21B45646F}.Release|Any CPU.Build.0 = Release|Win32 - {8D30D1F5-1925-4926-83F2-F0B21B45646F}.Release|x86.ActiveCfg = Release|Win32 - {8D30D1F5-1925-4926-83F2-F0B21B45646F}.Release|x86.Build.0 = Release|Win32 {154C60CF-2DAE-4227-AD2C-CCE7C63CDE5A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {154C60CF-2DAE-4227-AD2C-CCE7C63CDE5A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {154C60CF-2DAE-4227-AD2C-CCE7C63CDE5A}.Debug|x64.ActiveCfg = Debug|Any CPU + {154C60CF-2DAE-4227-AD2C-CCE7C63CDE5A}.Debug|x64.Build.0 = Debug|Any CPU {154C60CF-2DAE-4227-AD2C-CCE7C63CDE5A}.Debug|x86.ActiveCfg = Debug|Any CPU {154C60CF-2DAE-4227-AD2C-CCE7C63CDE5A}.Debug|x86.Build.0 = Debug|Any CPU {154C60CF-2DAE-4227-AD2C-CCE7C63CDE5A}.Release|Any CPU.ActiveCfg = Release|Any CPU {154C60CF-2DAE-4227-AD2C-CCE7C63CDE5A}.Release|Any CPU.Build.0 = Release|Any CPU + {154C60CF-2DAE-4227-AD2C-CCE7C63CDE5A}.Release|x64.ActiveCfg = Release|Any CPU + {154C60CF-2DAE-4227-AD2C-CCE7C63CDE5A}.Release|x64.Build.0 = Release|Any CPU {154C60CF-2DAE-4227-AD2C-CCE7C63CDE5A}.Release|x86.ActiveCfg = Release|Any CPU {154C60CF-2DAE-4227-AD2C-CCE7C63CDE5A}.Release|x86.Build.0 = Release|Any CPU {8B2B3BD6-C90C-40FA-8655-CFE1CC12CBD3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {8B2B3BD6-C90C-40FA-8655-CFE1CC12CBD3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8B2B3BD6-C90C-40FA-8655-CFE1CC12CBD3}.Debug|x64.ActiveCfg = Debug|Any CPU + {8B2B3BD6-C90C-40FA-8655-CFE1CC12CBD3}.Debug|x64.Build.0 = Debug|Any CPU {8B2B3BD6-C90C-40FA-8655-CFE1CC12CBD3}.Debug|x86.ActiveCfg = Debug|Any CPU {8B2B3BD6-C90C-40FA-8655-CFE1CC12CBD3}.Debug|x86.Build.0 = Debug|Any CPU {8B2B3BD6-C90C-40FA-8655-CFE1CC12CBD3}.Release|Any CPU.ActiveCfg = Release|Any CPU {8B2B3BD6-C90C-40FA-8655-CFE1CC12CBD3}.Release|Any CPU.Build.0 = Release|Any CPU + {8B2B3BD6-C90C-40FA-8655-CFE1CC12CBD3}.Release|x64.ActiveCfg = Release|Any CPU + {8B2B3BD6-C90C-40FA-8655-CFE1CC12CBD3}.Release|x64.Build.0 = Release|Any CPU {8B2B3BD6-C90C-40FA-8655-CFE1CC12CBD3}.Release|x86.ActiveCfg = Release|Any CPU {8B2B3BD6-C90C-40FA-8655-CFE1CC12CBD3}.Release|x86.Build.0 = Release|Any CPU {6961D299-1D2B-435E-8222-A82FF8EECA1C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {6961D299-1D2B-435E-8222-A82FF8EECA1C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6961D299-1D2B-435E-8222-A82FF8EECA1C}.Debug|x64.ActiveCfg = Debug|Any CPU + {6961D299-1D2B-435E-8222-A82FF8EECA1C}.Debug|x64.Build.0 = Debug|Any CPU {6961D299-1D2B-435E-8222-A82FF8EECA1C}.Debug|x86.ActiveCfg = Debug|Any CPU {6961D299-1D2B-435E-8222-A82FF8EECA1C}.Debug|x86.Build.0 = Debug|Any CPU {6961D299-1D2B-435E-8222-A82FF8EECA1C}.Release|Any CPU.ActiveCfg = Release|Any CPU {6961D299-1D2B-435E-8222-A82FF8EECA1C}.Release|Any CPU.Build.0 = Release|Any CPU + {6961D299-1D2B-435E-8222-A82FF8EECA1C}.Release|x64.ActiveCfg = Release|Any CPU + {6961D299-1D2B-435E-8222-A82FF8EECA1C}.Release|x64.Build.0 = Release|Any CPU {6961D299-1D2B-435E-8222-A82FF8EECA1C}.Release|x86.ActiveCfg = Release|Any CPU {6961D299-1D2B-435E-8222-A82FF8EECA1C}.Release|x86.Build.0 = Release|Any CPU {CB62443E-69B5-43B3-9785-647CAA36D175}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {CB62443E-69B5-43B3-9785-647CAA36D175}.Debug|Any CPU.Build.0 = Debug|Any CPU + {CB62443E-69B5-43B3-9785-647CAA36D175}.Debug|x64.ActiveCfg = Debug|Any CPU + {CB62443E-69B5-43B3-9785-647CAA36D175}.Debug|x64.Build.0 = Debug|Any CPU {CB62443E-69B5-43B3-9785-647CAA36D175}.Debug|x86.ActiveCfg = Debug|Any CPU {CB62443E-69B5-43B3-9785-647CAA36D175}.Debug|x86.Build.0 = Debug|Any CPU {CB62443E-69B5-43B3-9785-647CAA36D175}.Release|Any CPU.ActiveCfg = Release|Any CPU {CB62443E-69B5-43B3-9785-647CAA36D175}.Release|Any CPU.Build.0 = Release|Any CPU + {CB62443E-69B5-43B3-9785-647CAA36D175}.Release|x64.ActiveCfg = Release|Any CPU + {CB62443E-69B5-43B3-9785-647CAA36D175}.Release|x64.Build.0 = Release|Any CPU {CB62443E-69B5-43B3-9785-647CAA36D175}.Release|x86.ActiveCfg = Release|Any CPU {CB62443E-69B5-43B3-9785-647CAA36D175}.Release|x86.Build.0 = Release|Any CPU {E9D9E53D-40D5-4965-9770-FAADF73CEEEA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {E9D9E53D-40D5-4965-9770-FAADF73CEEEA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E9D9E53D-40D5-4965-9770-FAADF73CEEEA}.Debug|x64.ActiveCfg = Debug|Any CPU + {E9D9E53D-40D5-4965-9770-FAADF73CEEEA}.Debug|x64.Build.0 = Debug|Any CPU {E9D9E53D-40D5-4965-9770-FAADF73CEEEA}.Debug|x86.ActiveCfg = Debug|Any CPU {E9D9E53D-40D5-4965-9770-FAADF73CEEEA}.Debug|x86.Build.0 = Debug|Any CPU {E9D9E53D-40D5-4965-9770-FAADF73CEEEA}.Release|Any CPU.ActiveCfg = Release|Any CPU {E9D9E53D-40D5-4965-9770-FAADF73CEEEA}.Release|Any CPU.Build.0 = Release|Any CPU + {E9D9E53D-40D5-4965-9770-FAADF73CEEEA}.Release|x64.ActiveCfg = Release|Any CPU + {E9D9E53D-40D5-4965-9770-FAADF73CEEEA}.Release|x64.Build.0 = Release|Any CPU {E9D9E53D-40D5-4965-9770-FAADF73CEEEA}.Release|x86.ActiveCfg = Release|Any CPU {E9D9E53D-40D5-4965-9770-FAADF73CEEEA}.Release|x86.Build.0 = Release|Any CPU {9C155223-D1C5-4943-A4E6-02131544E5FD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {9C155223-D1C5-4943-A4E6-02131544E5FD}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9C155223-D1C5-4943-A4E6-02131544E5FD}.Debug|x64.ActiveCfg = Debug|Any CPU + {9C155223-D1C5-4943-A4E6-02131544E5FD}.Debug|x64.Build.0 = Debug|Any CPU {9C155223-D1C5-4943-A4E6-02131544E5FD}.Debug|x86.ActiveCfg = Debug|Any CPU {9C155223-D1C5-4943-A4E6-02131544E5FD}.Debug|x86.Build.0 = Debug|Any CPU {9C155223-D1C5-4943-A4E6-02131544E5FD}.Release|Any CPU.ActiveCfg = Release|Any CPU {9C155223-D1C5-4943-A4E6-02131544E5FD}.Release|Any CPU.Build.0 = Release|Any CPU + {9C155223-D1C5-4943-A4E6-02131544E5FD}.Release|x64.ActiveCfg = Release|Any CPU + {9C155223-D1C5-4943-A4E6-02131544E5FD}.Release|x64.Build.0 = Release|Any CPU {9C155223-D1C5-4943-A4E6-02131544E5FD}.Release|x86.ActiveCfg = Release|Any CPU {9C155223-D1C5-4943-A4E6-02131544E5FD}.Release|x86.Build.0 = Release|Any CPU {72CBA5F8-494D-4EEB-803B-7D1802A91D4A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {72CBA5F8-494D-4EEB-803B-7D1802A91D4A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {72CBA5F8-494D-4EEB-803B-7D1802A91D4A}.Debug|x64.ActiveCfg = Debug|Any CPU + {72CBA5F8-494D-4EEB-803B-7D1802A91D4A}.Debug|x64.Build.0 = Debug|Any CPU {72CBA5F8-494D-4EEB-803B-7D1802A91D4A}.Debug|x86.ActiveCfg = Debug|Any CPU {72CBA5F8-494D-4EEB-803B-7D1802A91D4A}.Debug|x86.Build.0 = Debug|Any CPU {72CBA5F8-494D-4EEB-803B-7D1802A91D4A}.Release|Any CPU.ActiveCfg = Release|Any CPU {72CBA5F8-494D-4EEB-803B-7D1802A91D4A}.Release|Any CPU.Build.0 = Release|Any CPU + {72CBA5F8-494D-4EEB-803B-7D1802A91D4A}.Release|x64.ActiveCfg = Release|Any CPU + {72CBA5F8-494D-4EEB-803B-7D1802A91D4A}.Release|x64.Build.0 = Release|Any CPU {72CBA5F8-494D-4EEB-803B-7D1802A91D4A}.Release|x86.ActiveCfg = Release|Any CPU {72CBA5F8-494D-4EEB-803B-7D1802A91D4A}.Release|x86.Build.0 = Release|Any CPU {2B1CD6EA-5B3B-44FE-A242-F06C1D6A41F9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {2B1CD6EA-5B3B-44FE-A242-F06C1D6A41F9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2B1CD6EA-5B3B-44FE-A242-F06C1D6A41F9}.Debug|x64.ActiveCfg = Debug|Any CPU + {2B1CD6EA-5B3B-44FE-A242-F06C1D6A41F9}.Debug|x64.Build.0 = Debug|Any CPU {2B1CD6EA-5B3B-44FE-A242-F06C1D6A41F9}.Debug|x86.ActiveCfg = Debug|Any CPU {2B1CD6EA-5B3B-44FE-A242-F06C1D6A41F9}.Debug|x86.Build.0 = Debug|Any CPU {2B1CD6EA-5B3B-44FE-A242-F06C1D6A41F9}.Release|Any CPU.ActiveCfg = Release|Any CPU {2B1CD6EA-5B3B-44FE-A242-F06C1D6A41F9}.Release|Any CPU.Build.0 = Release|Any CPU + {2B1CD6EA-5B3B-44FE-A242-F06C1D6A41F9}.Release|x64.ActiveCfg = Release|Any CPU + {2B1CD6EA-5B3B-44FE-A242-F06C1D6A41F9}.Release|x64.Build.0 = Release|Any CPU {2B1CD6EA-5B3B-44FE-A242-F06C1D6A41F9}.Release|x86.ActiveCfg = Release|Any CPU {2B1CD6EA-5B3B-44FE-A242-F06C1D6A41F9}.Release|x86.Build.0 = Release|Any CPU {7D283154-7CF9-434E-BA5A-5FB3D03AC271}.Debug|Any CPU.ActiveCfg = Debug|Win32 + {7D283154-7CF9-434E-BA5A-5FB3D03AC271}.Debug|x64.ActiveCfg = Debug|Win32 {7D283154-7CF9-434E-BA5A-5FB3D03AC271}.Debug|x86.ActiveCfg = Debug|Win32 {7D283154-7CF9-434E-BA5A-5FB3D03AC271}.Debug|x86.Build.0 = Debug|Win32 {7D283154-7CF9-434E-BA5A-5FB3D03AC271}.Release|Any CPU.ActiveCfg = Release|Win32 + {7D283154-7CF9-434E-BA5A-5FB3D03AC271}.Release|x64.ActiveCfg = Release|Win32 {7D283154-7CF9-434E-BA5A-5FB3D03AC271}.Release|x86.ActiveCfg = Release|Win32 {7D283154-7CF9-434E-BA5A-5FB3D03AC271}.Release|x86.Build.0 = Release|Win32 {7AD77F60-D0F1-4241-A67D-0733EF4A5DEE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {7AD77F60-D0F1-4241-A67D-0733EF4A5DEE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7AD77F60-D0F1-4241-A67D-0733EF4A5DEE}.Debug|x64.ActiveCfg = Debug|Any CPU + {7AD77F60-D0F1-4241-A67D-0733EF4A5DEE}.Debug|x64.Build.0 = Debug|Any CPU {7AD77F60-D0F1-4241-A67D-0733EF4A5DEE}.Debug|x86.ActiveCfg = Debug|Any CPU {7AD77F60-D0F1-4241-A67D-0733EF4A5DEE}.Debug|x86.Build.0 = Debug|Any CPU {7AD77F60-D0F1-4241-A67D-0733EF4A5DEE}.Release|Any CPU.ActiveCfg = Release|Any CPU {7AD77F60-D0F1-4241-A67D-0733EF4A5DEE}.Release|Any CPU.Build.0 = Release|Any CPU + {7AD77F60-D0F1-4241-A67D-0733EF4A5DEE}.Release|x64.ActiveCfg = Release|Any CPU + {7AD77F60-D0F1-4241-A67D-0733EF4A5DEE}.Release|x64.Build.0 = Release|Any CPU {7AD77F60-D0F1-4241-A67D-0733EF4A5DEE}.Release|x86.ActiveCfg = Release|Any CPU {7AD77F60-D0F1-4241-A67D-0733EF4A5DEE}.Release|x86.Build.0 = Release|Any CPU {35DC3E20-FF8D-42B4-991A-85296A243FA1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {35DC3E20-FF8D-42B4-991A-85296A243FA1}.Debug|Any CPU.Build.0 = Debug|Any CPU + {35DC3E20-FF8D-42B4-991A-85296A243FA1}.Debug|x64.ActiveCfg = Debug|Any CPU + {35DC3E20-FF8D-42B4-991A-85296A243FA1}.Debug|x64.Build.0 = Debug|Any CPU {35DC3E20-FF8D-42B4-991A-85296A243FA1}.Debug|x86.ActiveCfg = Debug|Any CPU {35DC3E20-FF8D-42B4-991A-85296A243FA1}.Debug|x86.Build.0 = Debug|Any CPU {35DC3E20-FF8D-42B4-991A-85296A243FA1}.Release|Any CPU.ActiveCfg = Release|Any CPU {35DC3E20-FF8D-42B4-991A-85296A243FA1}.Release|Any CPU.Build.0 = Release|Any CPU + {35DC3E20-FF8D-42B4-991A-85296A243FA1}.Release|x64.ActiveCfg = Release|Any CPU + {35DC3E20-FF8D-42B4-991A-85296A243FA1}.Release|x64.Build.0 = Release|Any CPU {35DC3E20-FF8D-42B4-991A-85296A243FA1}.Release|x86.ActiveCfg = Release|Any CPU {35DC3E20-FF8D-42B4-991A-85296A243FA1}.Release|x86.Build.0 = Release|Any CPU + {8D30D1F5-1925-4926-83F2-F0B21B45646F}.Debug|Any CPU.ActiveCfg = Debug|Win32 + {8D30D1F5-1925-4926-83F2-F0B21B45646F}.Debug|Any CPU.Build.0 = Debug|Win32 + {8D30D1F5-1925-4926-83F2-F0B21B45646F}.Debug|x64.ActiveCfg = Debug|x64 + {8D30D1F5-1925-4926-83F2-F0B21B45646F}.Debug|x64.Build.0 = Debug|x64 + {8D30D1F5-1925-4926-83F2-F0B21B45646F}.Debug|x86.ActiveCfg = Debug|Win32 + {8D30D1F5-1925-4926-83F2-F0B21B45646F}.Debug|x86.Build.0 = Debug|Win32 + {8D30D1F5-1925-4926-83F2-F0B21B45646F}.Release|Any CPU.ActiveCfg = Release|Win32 + {8D30D1F5-1925-4926-83F2-F0B21B45646F}.Release|Any CPU.Build.0 = Release|Win32 + {8D30D1F5-1925-4926-83F2-F0B21B45646F}.Release|x64.ActiveCfg = Release|x64 + {8D30D1F5-1925-4926-83F2-F0B21B45646F}.Release|x64.Build.0 = Release|x64 + {8D30D1F5-1925-4926-83F2-F0B21B45646F}.Release|x86.ActiveCfg = Release|Win32 + {8D30D1F5-1925-4926-83F2-F0B21B45646F}.Release|x86.Build.0 = Release|Win32 + {1D813DFE-338B-4C36-AAB0-98D7C6A949CC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1D813DFE-338B-4C36-AAB0-98D7C6A949CC}.Debug|x64.ActiveCfg = Debug|Any CPU + {1D813DFE-338B-4C36-AAB0-98D7C6A949CC}.Debug|x64.Build.0 = Debug|Any CPU + {1D813DFE-338B-4C36-AAB0-98D7C6A949CC}.Debug|x86.ActiveCfg = Debug|Any CPU + {1D813DFE-338B-4C36-AAB0-98D7C6A949CC}.Debug|x86.Build.0 = Debug|Any CPU + {1D813DFE-338B-4C36-AAB0-98D7C6A949CC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1D813DFE-338B-4C36-AAB0-98D7C6A949CC}.Release|x64.ActiveCfg = Release|Any CPU + {1D813DFE-338B-4C36-AAB0-98D7C6A949CC}.Release|x64.Build.0 = Release|Any CPU + {1D813DFE-338B-4C36-AAB0-98D7C6A949CC}.Release|x86.ActiveCfg = Release|Any CPU + {1D813DFE-338B-4C36-AAB0-98D7C6A949CC}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -179,6 +220,7 @@ Global {7D283154-7CF9-434E-BA5A-5FB3D03AC271} = {56B57E6A-FD0A-4479-B8D9-149BBD6F9C73} {7AD77F60-D0F1-4241-A67D-0733EF4A5DEE} = {56B57E6A-FD0A-4479-B8D9-149BBD6F9C73} {35DC3E20-FF8D-42B4-991A-85296A243FA1} = {F16C4DCE-5A69-45D5-8C04-4DCFA76CD643} + {1D813DFE-338B-4C36-AAB0-98D7C6A949CC} = {DABC64E2-6F5D-4E43-AF76-2B177C5E2353} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {F89DDEBD-4CC1-4C55-811B-096227CFE66C} diff --git a/src/aimp_dotnet/AIMPSDK/AIMP400/apiDepricated.h b/src/aimp_dotnet/AIMPSDK/AIMP400/apiDepricated.h new file mode 100644 index 00000000..30e88730 --- /dev/null +++ b/src/aimp_dotnet/AIMPSDK/AIMP400/apiDepricated.h @@ -0,0 +1,35 @@ +// ---------------------------------------------------- +// AIMP DotNet SDK +// Copyright (c) 2014 - 2020 Evgeniy Bogdan +// https://github.com/martin211/aimp_dotnet +// Mail: mail4evgeniy@gmail.com +// ---------------------------------------------------- + +#ifndef apiDeprecated +#define apiDeprecated + +#include +#include +#include "apiThreading.h" + +static const GUID IID_IAIMPServiceSynchronizer = { 0x41494D50, 0x5372, 0x7653, 0x79, 0x6E, 0x63, 0x72, 0x00, 0x00, 0x00, 0x00 }; +static const GUID IID_IAIMPServiceThreadPool = { 0x41494D50, 0x5372, 0x7654, 0x68, 0x72, 0x64, 0x50, 0x6F, 0x6F, 0x6C, 0x00 }; + +class IAIMPServiceSynchronizer : public IUnknown +{ +public: + virtual HRESULT WINAPI ExecuteInMainThread(IAIMPTask* Task, BOOL ExecuteNow) = 0; +}; + +/* IAIMPServiceThreadPool */ + +class IAIMPServiceThreadPool : public IUnknown +{ +public: + virtual HRESULT WINAPI Cancel(DWORD_PTR TaskHandle, DWORD Flags) = 0; + virtual HRESULT WINAPI Execute(IAIMPTask* Task, DWORD_PTR* TaskHandle) = 0; + virtual HRESULT WINAPI WaitFor(DWORD_PTR TaskHandle) = 0; +}; + + +#endif // !apiDeprecated \ No newline at end of file diff --git a/src/aimp_dotnet/AIMPSDK/AIMP400/apiMessages.h b/src/aimp_dotnet/AIMPSDK/AIMP400/apiMessages.h index eed7b288..4263ac7e 100644 --- a/src/aimp_dotnet/AIMPSDK/AIMP400/apiMessages.h +++ b/src/aimp_dotnet/AIMPSDK/AIMP400/apiMessages.h @@ -1,10 +1,10 @@ /************************************************/ /* */ /* AIMP Programming Interface */ -/* v4.50 build 2000 */ +/* v4.70 build 2200 */ /* */ /* Artem Izmaylov */ -/* (C) 2006-2017 */ +/* (C) 2006-2020 */ /* www.aimp.ru */ /* */ /* Mail: support@aimp.ru */ @@ -16,10 +16,11 @@ #include #include +#include "apiFileManager.h" -//============================================================================== +// --------------------------------------------------------------------------------------------------------------------- // Commands -//============================================================================== +// --------------------------------------------------------------------------------------------------------------------- const int AIMP_MSG_CMD_BASE = 0; @@ -33,7 +34,7 @@ const int AIMP_MSG_CMD_STATE_GET = AIMP_MSG_CMD_BASE + 1; // HiWord: 0 - Popup near system tray, // 1 - Popup near mouse cursor // AParam2: unused -const int AIMP_MSG_CMD_QFI_PLAYBACK_TRACK = AIMP_MSG_CMD_BASE + 2; +const int AIMP_MSG_CMD_QFI_PLAYING_TRACK = AIMP_MSG_CMD_BASE + 2; // Show custom text in display of RunningLine or Text elements // AParam1: 0 - Hide text automaticly after 2 seconds @@ -128,9 +129,9 @@ const int AIMP_MSG_CMD_BOOKMARKS_ADD = AIMP_MSG_CMD_BASE + 26; // AParam1, AParam2: unused const int AIMP_MSG_CMD_PLS_RESCAN = AIMP_MSG_CMD_BASE + 27; -// Jump focus in playlist to now playing file +// Jump focus in playlist to playing file // AParam1, AParam2: unused -const int AIMP_MSG_CMD_PLS_FOCUS_PLAYABLE = AIMP_MSG_CMD_BASE + 28; +const int AIMP_MSG_CMD_PLS_FOCUS_PLAYING = AIMP_MSG_CMD_BASE + 28; // Delete all items from active playlist // AParam1, AParam2: unused @@ -210,9 +211,9 @@ const int AIMP_MSG_CMD_ADD_PLAYLISTS = AIMP_MSG_CMD_BASE + 48; // AParam1, AParam2: unused const int AIMP_MSG_CMD_ADD_URL = AIMP_MSG_CMD_BASE + 49; -// Execute "Quick Tag Editor" for now playing file +// Execute "Quick Tag Editor" for playing file // AParam1, AParam2: unused -const int AIMP_MSG_CMD_QTE_PLAYABLE_TRACK = AIMP_MSG_CMD_BASE + 51; +const int AIMP_MSG_CMD_QTE_PLAYING_TRACK = AIMP_MSG_CMD_BASE + 51; // Show Advanced Search Dialog // AParam1, AParam2: unused @@ -239,9 +240,13 @@ const int AIMP_MSG_CMD_VISUAL_STOP = AIMP_MSG_CMD_BASE + 58; // AParam1, AParam2: unused const int AIMP_MSG_CMD_PLS_RESCAN_SELECTED = AIMP_MSG_CMD_BASE + 59; -//============================================================================== +// Extended control of "Quick File Info" card that displaying information about playing file +// AParam2: pointer to TAIMPQuickFileInfoParams +const int AIMP_MSG_CMD_QFI = AIMP_MSG_CMD_BASE + 60; + +// --------------------------------------------------------------------------------------------------------------------- // Properties -//============================================================================== +// --------------------------------------------------------------------------------------------------------------------- const int AIMP_MSG_PROPERTY_BASE = 0x1000; @@ -431,9 +436,10 @@ const int AIMP_MSG_PROPERTY_CROSSMIXING = AIMP_MSG_PROPERTY_BASE + 34; // 1 - Jump to next track and stop playback // 2 - Jump to next track and pause playback const int AIMP_MSG_PROPERTY_ACTION_ON_END_OF_TRACK = AIMP_MSG_PROPERTY_BASE + 35; -//============================================================================== + +// --------------------------------------------------------------------------------------------------------------------- // Events -//============================================================================== +// --------------------------------------------------------------------------------------------------------------------- const int AIMP_MSG_EVENT_BASE = 0x2000; @@ -507,9 +513,9 @@ const int AIMP_MSG_EVENT_LOADED = AIMP_MSG_EVENT_BASE + 18; // AParam1, AParam2: unused const int AIMP_MSG_EVENT_TERMINATING = AIMP_MSG_EVENT_BASE + 19; -// Called, when information about playable file changed (album, title, album art and etc) +// Called, when information about playing file changed (album, title, album art and etc) // AParam1, AParam2: unused -const int AIMP_MSG_EVENT_PLAYABLE_FILE_INFO = AIMP_MSG_EVENT_BASE + 20; +const int AIMP_MSG_EVENT_PLAYING_FILE_INFO = AIMP_MSG_EVENT_BASE + 20; // High resolution version of the AIMP_MSG_EVENT_PLAYER_UPDATE_POSITION event // Called few times per second by a timer (is about 10 fps, real FPS is depended from some internal and external factors) @@ -521,7 +527,32 @@ const int AIMP_MSG_EVENT_PLAYER_UPDATE_POSITION_HR = AIMP_MSG_EVENT_BASE + 21; // AParam2: Pointer to WideChar array, can be = nil (ReadOnly!) const int AIMP_MSG_EVENT_EQUALIZER_PRESET_NAME = AIMP_MSG_EVENT_BASE + 22; -//============================================================================== +// --------------------------------------------------------------------------------------------------------------------- +// Quick File Info +// --------------------------------------------------------------------------------------------------------------------- + +const int AIMP_QFI_ANIMATION_NONE = 0; +const int AIMP_QFI_ANIMATION_FADE = 1; +const int AIMP_QFI_SW_HIDE = 0; +const int AIMP_QFI_SW_SHOW = 1; + +#pragma pack(push, 1) +struct TAIMPQuickFileInfoParams +{ + int cbSize; // struct size + int CmdShow; // refer to AIMP_QFI_SW_XXX + int AnimationType; // show / hide animation type, refer to AIMP_QFI_ANIMATION_XXX + int AnimationTime; // animation time in milliseconds + int DisplayTime; // in milliseconds, 0 - use default display time + byte Opacity; // 0..100% + IAIMPFileInfo* FileInfo; // file information to display +}; +#pragma pack(pop) +typedef TAIMPQuickFileInfoParams* PAIMPQuickFileInfoParams; + +// --------------------------------------------------------------------------------------------------------------------- +// General +// --------------------------------------------------------------------------------------------------------------------- static const GUID IID_IAIMPMessageHook = {0xFC6FB524, 0xA959, 0x4089, 0xAA, 0x0A, 0xEA, 0x40, 0xAB, 0x73, 0x74, 0xCD}; static const GUID IID_IAIMPServiceMessageDispatcher = {0x41494D50, 0x5372, 0x764D, 0x73, 0x67, 0x44, 0x73, 0x70, 0x72, 0x00, 0x00}; diff --git a/src/aimp_dotnet/AIMPSDK/AIMP400/apiThreading.h b/src/aimp_dotnet/AIMPSDK/AIMP400/apiThreading.h index fc007b8a..4fee5726 100644 --- a/src/aimp_dotnet/AIMPSDK/AIMP400/apiThreading.h +++ b/src/aimp_dotnet/AIMPSDK/AIMP400/apiThreading.h @@ -17,75 +17,52 @@ #include #include -static const GUID IID_IAIMPTask = { 0x41494D50, 0x5461, 0x736B, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; -static const GUID IID_IAIMPTaskOwner = { 0x41494D50, 0x5461, 0x736B, 0x4F, 0x77, 0x6E, 0x65, 0x72, 0x32, 0x00, 0x00 }; -static const GUID IID_IAIMPTaskPriority = { 0x41494D50, 0x5461, 0x736B, 0x50, 0x72, 0x69, 0x6F, 0x72, 0x69, 0x74, 0x79 }; -static const GUID IID_IAIMPServiceThreads = { 0x41494D50, 0x5372, 0x7654, 0x68, 0x72, 0x65, 0x61, 0x64, 0x73, 0x00, 0x00 }; +static const GUID IID_IAIMPTask = {0x41494D50, 0x5461, 0x736B, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; +static const GUID IID_IAIMPTaskOwner = {0x41494D50, 0x5461, 0x736B, 0x4F, 0x77, 0x6E, 0x65, 0x72, 0x32, 0x00, 0x00}; +static const GUID IID_IAIMPTaskPriority = {0x41494D50, 0x5461, 0x736B, 0x50, 0x72, 0x69, 0x6F, 0x72, 0x69, 0x74, 0x79}; +static const GUID IID_IAIMPServiceThreads = {0x41494D50, 0x5372, 0x7654, 0x68, 0x72, 0x65, 0x61, 0x64, 0x73, 0x00, 0x00}; // Flags for IAIMPServiceThreads.Cancel and IAIMPServiceThreads.ExecuteInMainThread const int AIMP_SERVICE_THREADS_FLAGS_WAITFOR = 0x1; // IAIMPTaskPriority.GetPriority const int AIMP_TASK_PRIORITY_NORMAL = 0; -const int AIMP_TASK_PRIORITY_LOW = 1; -const int AIMP_TASK_PRIORITY_HIGH = 2; +const int AIMP_TASK_PRIORITY_LOW = 1; +const int AIMP_TASK_PRIORITY_HIGH = 2; /* IAIMPTaskOwner */ -class IAIMPTaskOwner : public IUnknown +class IAIMPTaskOwner: public IUnknown { -public: - virtual BOOL WINAPI IsCanceled() = 0; + public: + virtual BOOL WINAPI IsCanceled() = 0; }; /* IAIMPTask */ -class IAIMPTask : public IUnknown +class IAIMPTask: public IUnknown { -public: - virtual void WINAPI Execute(IAIMPTaskOwner* Owner) = 0; + public: + virtual void WINAPI Execute(IAIMPTaskOwner* Owner) = 0; }; /* IAIMPTaskPriority */ -class IAIMPTaskPriority : public IUnknown +class IAIMPTaskPriority: public IUnknown { -public: - virtual int WINAPI GetPriority() = 0; + public: + virtual int WINAPI GetPriority() = 0; }; /* IAIMPServiceThreads */ -class IAIMPServiceThreads : public IUnknown +class IAIMPServiceThreads: public IUnknown { -public: - virtual HRESULT WINAPI ExecuteInMainThread(IAIMPTask* Task, DWORD Flags) = 0; - virtual HRESULT WINAPI ExecuteInThread(IAIMPTask* Task, DWORD_PTR* TaskHandle) = 0; - virtual HRESULT WINAPI Cancel(DWORD_PTR TaskHandle, DWORD Flags) = 0; - virtual HRESULT WINAPI WaitFor(DWORD_PTR TaskHandle) = 0; -}; - -/* IAIMPServiceSynchronizer */ - -// OBSOLETE - -static const GUID IID_IAIMPServiceSynchronizer = { 0x41494D50, 0x5372, 0x7653, 0x79, 0x6E, 0x63, 0x72, 0x00, 0x00, 0x00, 0x00 }; -static const GUID IID_IAIMPServiceThreadPool = { 0x41494D50, 0x5372, 0x7654, 0x68, 0x72, 0x64, 0x50, 0x6F, 0x6F, 0x6C, 0x00 }; - -class IAIMPServiceSynchronizer : public IUnknown -{ -public: - virtual HRESULT WINAPI ExecuteInMainThread(IAIMPTask* Task, BOOL ExecuteNow) = 0; -}; - -/* IAIMPServiceThreadPool */ - -class IAIMPServiceThreadPool : public IUnknown -{ -public: - virtual HRESULT WINAPI Cancel(DWORD_PTR TaskHandle, DWORD Flags) = 0; - virtual HRESULT WINAPI Execute(IAIMPTask* Task, DWORD_PTR* TaskHandle) = 0; - virtual HRESULT WINAPI WaitFor(DWORD_PTR TaskHandle) = 0; + public: + virtual HRESULT WINAPI ExecuteInMainThread(IAIMPTask* Task, DWORD Flags) = 0; + virtual HRESULT WINAPI ExecuteInThread(IAIMPTask* Task, DWORD_PTR *TaskHandle) = 0; + virtual HRESULT WINAPI Cancel(DWORD_PTR TaskHandle, DWORD Flags) = 0; + virtual HRESULT WINAPI WaitFor(DWORD_PTR TaskHandle) = 0; }; #endif // !apiThreadingH diff --git a/src/aimp_dotnet/AIMPSDK/AIMPSDK.h b/src/aimp_dotnet/AIMPSDK/AIMPSDK.h index 8d8e253e..65638e4d 100644 --- a/src/aimp_dotnet/AIMPSDK/AIMPSDK.h +++ b/src/aimp_dotnet/AIMPSDK/AIMPSDK.h @@ -26,3 +26,4 @@ #include "AIMPSDK\AIMP400\apiVisuals.h" #include "AIMPSDK\AIMP400\apiMusicLibrary.h" #include "AIMPSDK\AIMP400\apiTagEditor.h" +#include "AIMPSDK\AIMP400\apiDepricated.h" diff --git a/src/aimp_dotnet/AimpMemoryManager.cpp b/src/aimp_dotnet/AimpMemoryManager.cpp index 0083c516..4b54aa72 100644 --- a/src/aimp_dotnet/AimpMemoryManager.cpp +++ b/src/aimp_dotnet/AimpMemoryManager.cpp @@ -28,17 +28,6 @@ void AimpMemoryManager::AddObject(int key, void* obj) info->disposed = false; instance->objects[key] = info; //static_cast(obj)->AddRef(); - - // TODO: #18 -#ifdef DEBUG - System::Diagnostics::Debug::WriteLine("Register key: " + key); - const auto st = gcnew System::Diagnostics::StackTrace(true); - const auto sb = gcnew System::Text::StringBuilder("Stack trace:"); - for (int i = 0; i < st->FrameCount; ++i) { - sb->AppendLine(st->GetFrame(i)->GetMethod()->ToString()); - } - System::Diagnostics::Debug::WriteLine(sb->ToString()); -#endif } void AimpMemoryManager::Release(int key) @@ -58,12 +47,6 @@ void AimpMemoryManager::Release(int key) } obj->disposed = true; } -#ifdef DEBUG - else - { - System::Diagnostics::Debug::WriteLine("KEY not found"); - } -#endif } catch (...) { diff --git a/src/aimp_dotnet/AimpSdk.h b/src/aimp_dotnet/AimpSdk.h index a0e34842..606f54fd 100644 --- a/src/aimp_dotnet/AimpSdk.h +++ b/src/aimp_dotnet/AimpSdk.h @@ -15,4 +15,4 @@ #include "Utils.h" #include "SDK\AimpObject.h" #include "IUnknownInterfaceImpl.h" -#include "SDK\AimpStream.h" +#include "SDK/Objects/AimpStream.h" diff --git a/src/aimp_dotnet/Aimp_DotNetPlugin.vcxproj b/src/aimp_dotnet/Aimp_DotNetPlugin.vcxproj index 700eccb8..2b01de6e 100644 --- a/src/aimp_dotnet/Aimp_DotNetPlugin.vcxproj +++ b/src/aimp_dotnet/Aimp_DotNetPlugin.vcxproj @@ -12,6 +12,9 @@ + + + @@ -34,7 +37,8 @@ - + + @@ -136,6 +140,10 @@ + + + + @@ -155,7 +163,8 @@ - + + @@ -262,7 +271,6 @@ - @@ -358,6 +366,7 @@ aimp_dotnet $(ProjectDir);$(VC_IncludePath);$(WindowsSDK_IncludePath) $(SolutionDir)lib;$(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86) + true @@ -372,6 +381,7 @@ AIMP_Exports.def $(NETFXKitsDir)$(DotNetSdk_LibraryPath_x86);%(AdditionalLibraryDirectories) + LinkVerbose @@ -382,12 +392,14 @@ true true Use + stdcpp17 true true AIMP_Exports.def $(NETFXKitsDir)$(DotNetSdk_LibraryPath_x86);%(AdditionalLibraryDirectories) + true diff --git a/src/aimp_dotnet/Aimp_DotNetPlugin.vcxproj.filters b/src/aimp_dotnet/Aimp_DotNetPlugin.vcxproj.filters index 474a85bf..2d1940c9 100644 --- a/src/aimp_dotnet/Aimp_DotNetPlugin.vcxproj.filters +++ b/src/aimp_dotnet/Aimp_DotNetPlugin.vcxproj.filters @@ -5,6 +5,8 @@ + + @@ -22,7 +24,7 @@ - + @@ -118,17 +120,21 @@ - - + + Source Files + + + + @@ -143,7 +149,7 @@ - + @@ -250,7 +256,6 @@ - @@ -277,11 +282,14 @@ - - - + + + Header Files + + + diff --git a/src/aimp_dotnet/IUnknownInterfaceImpl.h b/src/aimp_dotnet/IUnknownInterfaceImpl.h index 4f2dc823..55495910 100644 --- a/src/aimp_dotnet/IUnknownInterfaceImpl.h +++ b/src/aimp_dotnet/IUnknownInterfaceImpl.h @@ -7,9 +7,6 @@ #pragma once -#include - -//! Helper implements IUnknown interface. template class IUnknownInterfaceImpl : public T { diff --git a/src/aimp_dotnet/SDK/AimpConverter.h b/src/aimp_dotnet/SDK/AimpConverter.h index 483bc97c..78b11bd6 100644 --- a/src/aimp_dotnet/SDK/AimpConverter.h +++ b/src/aimp_dotnet/SDK/AimpConverter.h @@ -6,8 +6,6 @@ // ---------------------------------------------------- #pragma once -#include "guiddef.h" -#include "vcclr.h" #include "AIMPSDK\AIMPSDK.h" #include "Utils.h" diff --git a/src/aimp_dotnet/SDK/AimpCore.h b/src/aimp_dotnet/SDK/AimpCore.h index ca5f5429..75d74a88 100644 --- a/src/aimp_dotnet/SDK/AimpCore.h +++ b/src/aimp_dotnet/SDK/AimpCore.h @@ -7,11 +7,12 @@ #pragma once #include "AimpErrorInfo.h" -#include "SDK/AimpExtensionBase.h" -#include "AimpStream.h" #include "Action/AimpAction.h" #include "Lyrics/AimpLyrics.h" #include "Menu/AimpMenuItem.h" +#include "Objects/AimpFileStream.h" +#include "Objects/AimpImage.h" +#include "Objects/AimpMemoryStream.h" namespace AIMP { namespace SDK { @@ -160,6 +161,30 @@ namespace AIMP { return gcnew AimpActionResult(result, m); } + if (t == IAimpImage::typeid) { + IAIMPImage2* obj = nullptr; + IAimpImage^ img = nullptr; + + const auto res = Utils::CheckResult(core->CreateObject(IID_IAIMPImage2, reinterpret_cast(&obj))); + if (res == ActionResultType::OK) { + img = gcnew AimpImage(obj, _aimpCore); + } + + return gcnew AimpActionResult(res, img); + } + + if (t == Objects::IAimpMemoryStream::typeid) { + IAIMPMemoryStream* stream = nullptr; + Objects::IAimpMemoryStream^ obj = nullptr; + + const auto res = Utils::CheckResult(core->CreateObject(IID_IAIMPMemoryStream, reinterpret_cast(&stream))); + if (res == ActionResultType::OK) { + obj = gcnew Objects::AimpMemoryStream(stream); + } + + return gcnew AimpActionResult(res, obj); + } + return nullptr; } }; diff --git a/src/aimp_dotnet/SDK/AimpDPIAware.cpp b/src/aimp_dotnet/SDK/AimpDPIAware.cpp new file mode 100644 index 00000000..e9429b84 --- /dev/null +++ b/src/aimp_dotnet/SDK/AimpDPIAware.cpp @@ -0,0 +1,20 @@ +// ---------------------------------------------------- +// AIMP DotNet SDK +// Copyright (c) 2014 - 2020 Evgeniy Bogdan +// https://github.com/martin211/aimp_dotnet +// Mail: mail4evgeniy@gmail.com +// ---------------------------------------------------- + +#include "Stdafx.h" +#include "AimpDPIAware.h" + +AimpDPIAware::AimpDPIAware(IAIMPDPIAware* obj) : AimpObject(obj) { +} + +int AimpDPIAware::DPI::get() { + return InternalAimpObject->GetDPI(); +} + +void AimpDPIAware::DPI::set(int dpi) { + InternalAimpObject->SetDPI(dpi); +} diff --git a/src/aimp_dotnet/SDK/AimpDPIAware.h b/src/aimp_dotnet/SDK/AimpDPIAware.h new file mode 100644 index 00000000..4859868b --- /dev/null +++ b/src/aimp_dotnet/SDK/AimpDPIAware.h @@ -0,0 +1,25 @@ +// ---------------------------------------------------- +// AIMP DotNet SDK +// Copyright (c) 2014 - 2020 Evgeniy Bogdan +// https://github.com/martin211/aimp_dotnet +// Mail: mail4evgeniy@gmail.com +// ---------------------------------------------------- + +#pragma once + +namespace AIMP { + namespace SDK { + public ref class AimpDPIAware : + public AimpObject, + public IAimpDPIAware { + + public: + explicit AimpDPIAware(IAIMPDPIAware* obj); + + property int DPI { + virtual int get(); + virtual void set(int dpi); + } + }; + } +} diff --git a/src/aimp_dotnet/SDK/AimpExtensionBase.h b/src/aimp_dotnet/SDK/AimpExtensionBase.h deleted file mode 100644 index 8c9c92bf..00000000 --- a/src/aimp_dotnet/SDK/AimpExtensionBase.h +++ /dev/null @@ -1,34 +0,0 @@ -// ---------------------------------------------------- -// AIMP DotNet SDK -// Copyright (c) 2014 - 2020 Evgeniy Bogdan -// https://github.com/martin211/aimp_dotnet -// Mail: mail4evgeniy@gmail.com -// ---------------------------------------------------- - -#pragma once -#include - -namespace AIMP { - namespace SDK { - using namespace System; - - public ref class AimpExtensionBase abstract { - internal: - property GUID ExtensionId - { - virtual GUID get() abstract; - } - - property String^ Name - { - virtual String^ get() abstract; - } - - property IUnknown* InternalProxyExtension - { - virtual IUnknown* get() abstract; - virtual void set(IUnknown* value) abstract; - } - }; - } -} diff --git a/src/aimp_dotnet/SDK/AimpPropertyList.h b/src/aimp_dotnet/SDK/AimpPropertyList.h index c7ff7ab9..fd7773ed 100644 --- a/src/aimp_dotnet/SDK/AimpPropertyList.h +++ b/src/aimp_dotnet/SDK/AimpPropertyList.h @@ -6,7 +6,6 @@ // ---------------------------------------------------- #pragma once -#include "IUnknownInterfaceImpl.h" class AimpPropertyList : public IAIMPPropertyList, IAIMPPropertyList2 { public: diff --git a/src/aimp_dotnet/SDK/FileManager/AimpServiceFileStreaming.cpp b/src/aimp_dotnet/SDK/FileManager/AimpServiceFileStreaming.cpp index 87cba432..47ba9871 100644 --- a/src/aimp_dotnet/SDK/FileManager/AimpServiceFileStreaming.cpp +++ b/src/aimp_dotnet/SDK/FileManager/AimpServiceFileStreaming.cpp @@ -7,9 +7,9 @@ #include "stdafx.h" #include "AimpServiceFileStreaming.h" +#include "SDK/Objects/AimpFileStream.h" -StreamResult AimpServiceFileStreaming::CreateStreamForFile(String^ fileName, FileStreamingType flags, long long offset, - long long size) { +StreamResult AimpServiceFileStreaming::CreateStreamForFile(String^ fileName, FileStreamingType flags, long long offset, long long size) { IAIMPServiceFileStreaming* service = GetAimpService(); IAIMPString* str = nullptr; IAIMPStream* aimpStream = nullptr; @@ -19,10 +19,10 @@ StreamResult AimpServiceFileStreaming::CreateStreamForFile(String^ fileName, Fil try { if (service != nullptr) { str = AimpConverter::ToAimpString(fileName); - result = CheckResult(service->CreateStreamForFile(str, DWORD(flags), offset, size, &aimpStream)); - + result = CheckResult(service->CreateStreamForFile(str, static_cast(flags), offset, size, &aimpStream)); if (result == ActionResultType::OK) { - stream = gcnew AimpStream(aimpStream); + IAIMPFileStream* s = (IAIMPFileStream*)aimpStream; + stream = gcnew Objects::AimpFileStream(s); } } } @@ -34,7 +34,7 @@ StreamResult AimpServiceFileStreaming::CreateStreamForFile(String^ fileName, Fil return gcnew AimpActionResult(result, stream); } -AimpActionResult^ AimpServiceFileStreaming::CreateStreamForFileUri(String^ fileUrl) { +AimpActionResult^ AimpServiceFileStreaming::CreateStreamForFileUri(String^ fileUrl) { IAIMPServiceFileStreaming* service = GetAimpService(); IAIMPString* str = nullptr; IAIMPStream* aimpStream = nullptr; @@ -49,7 +49,7 @@ AimpActionResult^ AimpServiceFileStreaming::CreateStreamForF result = CheckResult(service->CreateStreamForFileURI(str, &vf, &aimpStream)); if (result == ActionResultType::OK && aimpStream != nullptr) { - stream = gcnew AimpStream(aimpStream); + stream = gcnew Objects::AimpFileStream(nullptr); } } } @@ -58,7 +58,7 @@ AimpActionResult^ AimpServiceFileStreaming::CreateStreamForF ReleaseObject(str); } - return gcnew AimpActionResult(result, gcnew CeateStreamResult(virtualFile, stream)); + return gcnew AimpActionResult(result, gcnew CreateStreamResult(virtualFile, stream)); } IAIMPServiceFileStreaming* AimpServiceFileStreaming::GetAimpService() { diff --git a/src/aimp_dotnet/SDK/FileManager/AimpServiceFileStreaming.h b/src/aimp_dotnet/SDK/FileManager/AimpServiceFileStreaming.h index 1e56f169..09830ef6 100644 --- a/src/aimp_dotnet/SDK/FileManager/AimpServiceFileStreaming.h +++ b/src/aimp_dotnet/SDK/FileManager/AimpServiceFileStreaming.h @@ -22,7 +22,7 @@ namespace AIMP { virtual StreamResult CreateStreamForFile(String^ fileName, FileStreamingType flags, long long offset, long long size); - virtual AimpActionResult^ CreateStreamForFileUri(String^ fileUrl); + virtual AimpActionResult^ CreateStreamForFileUri(String^ fileUrl); protected: IAIMPServiceFileStreaming* GetAimpService() override; }; diff --git a/src/aimp_dotnet/SDK/ManagedAimpCore.h b/src/aimp_dotnet/SDK/ManagedAimpCore.h index aee62c64..b5739a1e 100644 --- a/src/aimp_dotnet/SDK/ManagedAimpCore.h +++ b/src/aimp_dotnet/SDK/ManagedAimpCore.h @@ -6,8 +6,6 @@ // ---------------------------------------------------- #pragma once -#include -#include "AimpSdk.h" #include "FileManager/Extensions/InternalAimpExtensionFileFormat.h" #include "MusicLibrary/Extension/AimpExtensionDataStorage.h" #include "Playback/AimpExtensionPlaybackQueue.h" @@ -18,10 +16,8 @@ #include "SDK\PlayList\AimpExtensionPlaylistManagerListener.h" #include "SDK\Visuals\AimpExtensionEmbeddedVisualization.h" #include "SDK\Visuals\AimpExtensionCustomVisualization.h" -#include "SDK\MusicLibrary\InternalAimpGroupingTreeDataProvider.h" #include "SDK\FileManager\Extensions\InternalAimpExtensionFileInfoProvider.h" #include "SDK\FileManager\Extensions\InternalAimpExtensionFileSystem.h" -#include "SDK\Visuals\AimpServiceVisualizations.h" #include "SDK\PlayList\Internal\InternalAimpExtensionPlaylistPreimageFactory.h" #include "SDK\Lyrics\AimpExtensionLyricsProvider.h" diff --git a/src/aimp_dotnet/SDK/MessageDispatcher/AimpServiceMessageDispatcher.cpp b/src/aimp_dotnet/SDK/MessageDispatcher/AimpServiceMessageDispatcher.cpp index 9de58c5a..04393afd 100644 --- a/src/aimp_dotnet/SDK/MessageDispatcher/AimpServiceMessageDispatcher.cpp +++ b/src/aimp_dotnet/SDK/MessageDispatcher/AimpServiceMessageDispatcher.cpp @@ -28,11 +28,7 @@ ActionResult AimpServiceMessageDispatcher::Send(AimpCoreMessageType message, int try { if (service != nullptr) { - HWND handle = nullptr; - result = CheckResult(service->Send(DWORD(message), static_cast(param1), &handle)); - if (result == ActionResultType::OK) { - param2 = IntPtr(handle); - } + result = CheckResult(service->Send(static_cast(message), static_cast(param1), param2 != IntPtr::Zero ? param2.ToPointer() : nullptr)); } } finally { diff --git a/src/aimp_dotnet/SDK/MessageDispatcher/InternalAimpMessageHook.cpp b/src/aimp_dotnet/SDK/MessageDispatcher/InternalAimpMessageHook.cpp index 155d5d26..2258fc81 100644 --- a/src/aimp_dotnet/SDK/MessageDispatcher/InternalAimpMessageHook.cpp +++ b/src/aimp_dotnet/SDK/MessageDispatcher/InternalAimpMessageHook.cpp @@ -13,7 +13,7 @@ InternalAimpMessageHook::InternalAimpMessageHook(gcroot manag } void InternalAimpMessageHook::CoreMessage(DWORD message, int param1, void* param2, HRESULT* result) { - const auto res = _managedCore->CoreMessage(static_cast(message), param1, (int)param2); + const auto res = _managedCore->CoreMessage(static_cast(message), param1, IntPtr(param2)); // do not set AResult here. It breaks a modal dialog } diff --git a/src/aimp_dotnet/SDK/Objects/AimpFileStream.cpp b/src/aimp_dotnet/SDK/Objects/AimpFileStream.cpp new file mode 100644 index 00000000..23dc6a50 --- /dev/null +++ b/src/aimp_dotnet/SDK/Objects/AimpFileStream.cpp @@ -0,0 +1,40 @@ +// ---------------------------------------------------- +// AIMP DotNet SDK +// Copyright (c) 2014 - 2020 Evgeniy Bogdan +// https://github.com/martin211/aimp_dotnet +// Mail: mail4evgeniy@gmail.com +// ---------------------------------------------------- + +#include "Stdafx.h" +#include "AimpFileStream.h" +#include "SDK/AimpString.h" + +AimpFileStream::AimpFileStream(IAIMPFileStream* aimpObject) : AimpStream(aimpObject) { +} + +AimpActionResult^ AimpFileStream::GetClipping() { + IAIMPFileStream* stream = static_cast(InternalAimpObject); + INT64* offset = new INT64(); + INT64* size = new INT64(); + const auto res = CheckResult(stream->GetClipping(offset, size)); + + if (res == ActionResultType::OK) { + return gcnew AimpActionResult( + res, + gcnew Clipping(reinterpret_cast(offset), reinterpret_cast(size))); + } + + return nullptr; +} + +AimpActionResult^ AimpFileStream::GetFileName() { + IAIMPFileStream* stream = static_cast(InternalAimpObject); + IAIMPString* fn = nullptr; + IAimpString^ result = nullptr; + const auto res = CheckResult(stream->GetFileName(&fn)); + if (res == ActionResultType::OK) { + result = gcnew AimpString(fn); + } + + return gcnew AimpActionResult(res, result); +} diff --git a/src/aimp_dotnet/SDK/Objects/AimpFileStream.h b/src/aimp_dotnet/SDK/Objects/AimpFileStream.h new file mode 100644 index 00000000..6d5a765d --- /dev/null +++ b/src/aimp_dotnet/SDK/Objects/AimpFileStream.h @@ -0,0 +1,23 @@ +// ---------------------------------------------------- +// AIMP DotNet SDK +// Copyright (c) 2014 - 2020 Evgeniy Bogdan +// https://github.com/martin211/aimp_dotnet +// Mail: mail4evgeniy@gmail.com +// ---------------------------------------------------- + +#pragma once + +namespace AIMP { + namespace SDK { + namespace Objects { + public ref class AimpFileStream : + public AimpStream, + public IAimpFileStream { + public: + explicit AimpFileStream(IAIMPFileStream* aimpObject); + virtual AimpActionResult^ GetClipping(); + virtual AimpActionResult^ GetFileName(); + }; + } + } +} diff --git a/src/aimp_dotnet/SDK/Objects/AimpImage.cpp b/src/aimp_dotnet/SDK/Objects/AimpImage.cpp new file mode 100644 index 00000000..d1e8939c --- /dev/null +++ b/src/aimp_dotnet/SDK/Objects/AimpImage.cpp @@ -0,0 +1,115 @@ +// ---------------------------------------------------- +// AIMP DotNet SDK +// Copyright (c) 2014 - 2020 Evgeniy Bogdan +// https://github.com/martin211/aimp_dotnet +// Mail: mail4evgeniy@gmail.com +// ---------------------------------------------------- + +#include "Stdafx.h" +#include "AimpImage.h" + +#include "SDK/ManagedAimpCore.h" + +AimpImage::AimpImage(IAIMPImage2* obj, ManagedAimpCore^ core) : AimpObject(obj) { + _core = core; +} + +AimpImageFormat AimpImage::FormatId::get() { + return static_cast(InternalAimpObject->GetFormatID()); +} + +Drawing::PointF AimpImage::Size::get() { + SIZE* s = new SIZE(); + const auto res = CheckResult(InternalAimpObject->GetSize(s)); + if (res == ActionResultType::OK) { + const auto result = Drawing::PointF(s->cx, s->cy); + delete s; + return result; + } + + return Drawing::PointF::Empty; +} + +AimpActionResult^ AimpImage::LoadFromFile(String^ fileName) { + if (String::IsNullOrEmpty(fileName)) { + ARGUMENT_NULL("fileName", "fileName cannot be empty"); + } + + const auto res = CheckResult(InternalAimpObject->LoadFromFile(AimpConverter::ToAimpString(fileName))); + return gcnew AimpActionResult(res); +} + +AimpActionResult^ AimpImage::LoadFromStream(IAimpStream^ stream) { + const auto res = CheckResult(InternalAimpObject->LoadFromStream(static_cast(stream)->InternalAimpObject)); + return gcnew AimpActionResult(res); +} + +AimpActionResult^ AimpImage::SaveToFile(String^ fileName, AimpImageFormat format) { + const auto path = AimpConverter::ToAimpString(fileName); + try { + const auto res = CheckResult(InternalAimpObject->SaveToFile(path, static_cast(format))); + return gcnew AimpActionResult(res); + } + finally { + path->Release(); + } +} + +AimpActionResult^ AimpImage::SaveToStream(IAimpStream^ stream, AimpImageFormat format) { + const auto res = CheckResult(InternalAimpObject->SaveToStream(static_cast(stream)->InternalAimpObject, static_cast(format))); + return gcnew AimpActionResult(res); +} + +AimpActionResult^ AimpImage::Clone() { + IAIMPImage2* img = nullptr; + //_core->GetAimpCore()->CreateObject(IID_IAIMPImage2, reinterpret_cast(&img)); + //const auto res = CheckResult(InternalAimpObject->Clone(&img)); + //if (res == ActionResultType::OK) { + // return gcnew AimpActionResult(res, gcnew AimpImage(img, _core)); + //} + + return gcnew AimpActionResult(ActionResultType::NotImplemented); +} + +AimpActionResult^ AimpImage::Draw(IntPtr dc, Drawing::RectangleF rect) { + RECT r = RECT(); + r.top = rect.Top; + r.bottom = rect.Bottom; + r.left = rect.Left; + r.right = rect.Right; + //TODO complete + const auto res = CheckResult(InternalAimpObject->Draw(static_cast(dc.ToPointer()), r, 0, nullptr)); + return gcnew AimpActionResult(res); +} + +AimpActionResult^ AimpImage::Resize(int width, int height) { + const auto res = CheckResult(InternalAimpObject->Resize(width, height)); + return gcnew AimpActionResult(res); +} + +AimpActionResult^ AimpImage::LoadFromResource() { + // TODO: Not implemented + return gcnew AimpActionResult(ActionResultType::NotImplemented); +} + +AimpActionResult^ AimpImage::LoadFromBitmap(IntPtr bitmap) { + // TODO: Not implemented + return gcnew AimpActionResult(ActionResultType::NotImplemented); +} + +AimpActionResult^ AimpImage::LoadFromBits(Objects::RGBQUAD bits, int width, int height) { + // TODO: Not implemented + return gcnew AimpActionResult(ActionResultType::NotImplemented); +} + +AimpActionResult^ AimpImage::CopyToClipboard() { + return gcnew AimpActionResult(CheckResult(InternalAimpObject->CopyToClipboard())); +} + +AimpActionResult^ AimpImage::CanPasteFromClipboard() { + return gcnew AimpActionResult(CheckResult(InternalAimpObject->CanPasteFromClipboard())); +} + +AimpActionResult^ AimpImage::PasteFromClipboard() { + return gcnew AimpActionResult(CheckResult(InternalAimpObject->PasteFromClipboard())); +} diff --git a/src/aimp_dotnet/SDK/Objects/AimpImage.h b/src/aimp_dotnet/SDK/Objects/AimpImage.h new file mode 100644 index 00000000..451fa30e --- /dev/null +++ b/src/aimp_dotnet/SDK/Objects/AimpImage.h @@ -0,0 +1,40 @@ +// ---------------------------------------------------- +// AIMP DotNet SDK +// Copyright (c) 2014 - 2020 Evgeniy Bogdan +// https://github.com/martin211/aimp_dotnet +// Mail: mail4evgeniy@gmail.com +// ---------------------------------------------------- + +#pragma once + +namespace AIMP { + namespace SDK { + ref class ManagedAimpCore; + + public ref class AimpImage : + public AimpObject, + public IAimpImage { + private: + ManagedAimpCore^ _core; + public: + explicit AimpImage(IAIMPImage2* obj, ManagedAimpCore^ core); + property AimpImageFormat FormatId { virtual AimpImageFormat get(); } + property Drawing::PointF Size { virtual Drawing::PointF get(); } + virtual AimpActionResult^ LoadFromFile(String^ fileName); + virtual AimpActionResult^ LoadFromStream(IAimpStream^ stream); + virtual AimpActionResult^ SaveToFile(String^ fileName, AimpImageFormat format); + virtual AimpActionResult^ SaveToStream(IAimpStream^ stream, AimpImageFormat format); + virtual AimpActionResult^ Clone(); + virtual AimpActionResult^ Draw(IntPtr dc, Drawing::RectangleF rect); + virtual AimpActionResult^ Resize(int width, int height); + + // IAIMPImage2 + virtual AimpActionResult^ LoadFromResource(); + virtual AimpActionResult^ LoadFromBitmap(IntPtr bitmap); + virtual AimpActionResult^ LoadFromBits(Objects::RGBQUAD bits, int width, int height); + virtual AimpActionResult^ CopyToClipboard(); + virtual AimpActionResult^ CanPasteFromClipboard(); + virtual AimpActionResult^ PasteFromClipboard(); + }; + } +} diff --git a/src/aimp_dotnet/SDK/Objects/AimpMemoryStream.cpp b/src/aimp_dotnet/SDK/Objects/AimpMemoryStream.cpp new file mode 100644 index 00000000..cf3a9b44 --- /dev/null +++ b/src/aimp_dotnet/SDK/Objects/AimpMemoryStream.cpp @@ -0,0 +1,25 @@ +// ---------------------------------------------------- +// AIMP DotNet SDK +// Copyright (c) 2014 - 2020 Evgeniy Bogdan +// https://github.com/martin211/aimp_dotnet +// Mail: mail4evgeniy@gmail.com +// ---------------------------------------------------- + +#include "Stdafx.h" +#include "AimpMemoryStream.h" + +Objects::AimpMemoryStream::AimpMemoryStream(IAIMPMemoryStream* aimpObject) : AimpStream(static_cast(aimpObject)) { +} + +AimpActionResult^>^ Objects::AimpMemoryStream::GetData() { + const auto size = InternalAimpObject->GetSize(); + array^ arr = gcnew array(size); + IAIMPMemoryStream* stream = static_cast(InternalAimpObject); + byte* pointer = static_cast(stream->GetData()); + + for (int i = 0; i < size; i++) { + arr[i] = pointer[i]; + } + + return gcnew AimpActionResult^>(ActionResultType::OK, arr); +} diff --git a/src/aimp_dotnet/SDK/Objects/AimpMemoryStream.h b/src/aimp_dotnet/SDK/Objects/AimpMemoryStream.h new file mode 100644 index 00000000..661ec470 --- /dev/null +++ b/src/aimp_dotnet/SDK/Objects/AimpMemoryStream.h @@ -0,0 +1,22 @@ +// ---------------------------------------------------- +// AIMP DotNet SDK +// Copyright (c) 2014 - 2020 Evgeniy Bogdan +// https://github.com/martin211/aimp_dotnet +// Mail: mail4evgeniy@gmail.com +// ---------------------------------------------------- + +#pragma once + +namespace AIMP { + namespace SDK { + namespace Objects { + public ref class AimpMemoryStream : + public AimpStream, + public IAimpMemoryStream { + public: + AimpMemoryStream(IAIMPMemoryStream* aimpObject); + virtual AimpActionResult^>^ GetData(); + }; + } + } +} diff --git a/src/aimp_dotnet/SDK/AimpStream.cpp b/src/aimp_dotnet/SDK/Objects/AimpStream.cpp similarity index 93% rename from src/aimp_dotnet/SDK/AimpStream.cpp rename to src/aimp_dotnet/SDK/Objects/AimpStream.cpp index e788dc44..e92373de 100644 --- a/src/aimp_dotnet/SDK/AimpStream.cpp +++ b/src/aimp_dotnet/SDK/Objects/AimpStream.cpp @@ -24,7 +24,6 @@ AimpStream::!AimpStream() { //InternalAimpObject->Release(); } catch (const std::exception& e) { - System::Diagnostics::Debugger::Break(); } } } diff --git a/src/aimp_dotnet/SDK/AimpStream.h b/src/aimp_dotnet/SDK/Objects/AimpStream.h similarity index 100% rename from src/aimp_dotnet/SDK/AimpStream.h rename to src/aimp_dotnet/SDK/Objects/AimpStream.h diff --git a/src/aimp_dotnet/SDK/PlayList/AimpPlaylistPreimageFactory.cpp b/src/aimp_dotnet/SDK/PlayList/AimpPlaylistPreimageFactory.cpp index 61fb2d98..a1a37613 100644 --- a/src/aimp_dotnet/SDK/PlayList/AimpPlaylistPreimageFactory.cpp +++ b/src/aimp_dotnet/SDK/PlayList/AimpPlaylistPreimageFactory.cpp @@ -13,8 +13,7 @@ AimpPlaylistPreimageFactory::AimpPlaylistPreimageFactory(gcroot - namespace AIMP { namespace Win32 { using namespace System; diff --git a/src/aimp_dotnet/Stdafx.h b/src/aimp_dotnet/Stdafx.h index 01b68902..4118ea0f 100644 --- a/src/aimp_dotnet/Stdafx.h +++ b/src/aimp_dotnet/Stdafx.h @@ -7,11 +7,6 @@ #pragma once -//using namespace System::Runtime::CompilerServices; -////using namespace System; -// -//[assembly:InternalsVisibleTo("AimpTestRunner")]; - using namespace AIMP::SDK; typedef AimpActionResult^ ActionResult; @@ -39,22 +34,6 @@ typedef AimpActionResult^ MenuItemResult; #define RETURN_TYPED_RESULT(type, value1, value2) gcnew AimpActionResult(value1, value2) -//-V122_NOPTR - -#ifdef _DEBUG -#define _CRTDBG_MAP_ALLOC -#include -#include -#endif // _DEBUG - #include -#include #include "AimpSdk.h" - - -#ifdef _DEBUG -#ifndef DBG_NEW -#define DBG_NEW new ( _NORMAL_BLOCK , __FILE__ , __LINE__ ) -#define new DBG_NEW -#endif -#endif // _DEBUG +#include "vcclr.h"