diff --git a/MT5Connector/AssemblyInfo.cpp b/MT5Connector/AssemblyInfo.cpp deleted file mode 100755 index 97ac31b8..00000000 --- a/MT5Connector/AssemblyInfo.cpp +++ /dev/null @@ -1,38 +0,0 @@ -#include "stdafx.h" - -using namespace System; -using namespace System::Reflection; -using namespace System::Runtime::CompilerServices; -using namespace System::Runtime::InteropServices; -using namespace System::Security::Permissions; - -// -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -// -[assembly:AssemblyTitleAttribute("MT5Connector")]; -[assembly:AssemblyDescriptionAttribute("")]; -[assembly:AssemblyConfigurationAttribute("")]; -[assembly:AssemblyCompanyAttribute("")]; -[assembly:AssemblyProductAttribute("MT5Connector")]; -[assembly:AssemblyCopyrightAttribute("Copyright (c) 2013")]; -[assembly:AssemblyTrademarkAttribute("")]; -[assembly:AssemblyCultureAttribute("")]; - -// -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the value or you can default the Revision and Build Numbers -// by using the '*' as shown below: - -[assembly:AssemblyVersionAttribute("1.0.*")]; - -[assembly:ComVisible(false)]; - -[assembly:CLSCompliantAttribute(true)]; \ No newline at end of file diff --git a/MT5Connector/MT5Connector.cpp b/MT5Connector/MT5Connector.cpp index ebbbf234..f5d1b186 100755 --- a/MT5Connector/MT5Connector.cpp +++ b/MT5Connector/MT5Connector.cpp @@ -2,51 +2,28 @@ #include "Stdafx.h" -#include "MT5Connector.h" -#include "MT5Handler.h" - -#include "Windows.h" -#include +#include #include +#include +#include +#include "Mt5Handler.h" +#include "MtService.h" -using namespace System; -using namespace MTApiService; -using namespace System::Runtime::InteropServices; -using namespace System::Reflection; -using namespace System::Text; -using namespace System::Collections::Generic; -using namespace System::Diagnostics; -using namespace System::Security::Cryptography; -using namespace System::Security; - -#pragma pack(push, 1) -public struct CMqlRates +static void convertSystemString(wchar_t* dest, const std::string& src) { - __int64 time; // Period start time - double open; // Open price - double high; // The highest price of the period - double low; // The lowest price of the period - double close; // Close price - __int64 tick_volume; // Tick volume - int spread; // Spread - __int64 real_volume; // Trade volume -}; -#pragma pack(pop) - -void convertSystemString(wchar_t* dest, String^ src) -{ - if (src != nullptr) { - pin_ptr wch = PtrToStringChars(src); - memcpy(dest, wch, wcsnlen(wch, 1000) * sizeof(wchar_t)); - dest[wcsnlen(wch, 1000)] = L'\0'; - } - else - { - dest[0] = L'\0'; - } + using convert_typeX = std::codecvt_utf8; + std::wstring_convert converterX; + auto wstr = converterX.from_bytes(src); + memcpy(dest, wstr.c_str(), wcsnlen(wstr.c_str(), 1000) * sizeof(wchar_t)); } -#define _DLLAPI extern "C" __declspec(dllexport) +static std::string convertWString(const wchar_t* src) +{ + std::wstring string_to_convert(src); + using convert_typeX = std::codecvt_utf8; + std::wstring_convert converterX; + return converterX.to_bytes(string_to_convert); +} template T Execute(std::function func, wchar_t* err, T default_value) { @@ -55,233 +32,60 @@ template T Execute(std::function func, wchar_t* err, T default { result = func(); } - catch (Exception^ e) + catch (std::exception& e) { - convertSystemString(err, e->Message); - MtAdapter::GetInstance()->LogError(e->Message); + convertSystemString(err, e.what()); + MtService::GetInstance().LogError(e.what()); } return result; } -_DLLAPI int _stdcall initExpert(int expertHandle, int port, wchar_t* symbol, double bid, double ask, int isTestMode, wchar_t* err) +int initExpert(int expertHandle, int port, int isTestMode, wchar_t* err) { - return Execute([&expertHandle, &port, symbol, &bid, &ask, &isTestMode]() { + return Execute([&expertHandle, &port, &isTestMode]() { bool isTesting = (isTestMode != 0) ? true : false; - auto expert = gcnew Mt5Expert(expertHandle, gcnew String(symbol), bid, ask, gcnew MT5Handler(), isTesting); - MtAdapter::GetInstance()->AddExpert(port, expert); + auto mt_handler = std::make_unique(expertHandle); + MtService::GetInstance().InitExpert(port, expertHandle, std::move(mt_handler)); return 1; - }, err, 0); + }, err, 0); } -_DLLAPI int _stdcall deinitExpert(int expertHandle, wchar_t* err) +int deinitExpert(int expertHandle, wchar_t* err) { return Execute([&expertHandle]() { - MtAdapter::GetInstance()->RemoveExpert(expertHandle); + MtService::GetInstance().DeinitExpert(expertHandle); return 1; - }, err, 0); + }, err, 0); } -_DLLAPI int _stdcall updateQuote(int expertHandle, wchar_t* symbol, double bid, double ask, wchar_t* err) +bool sendEvent(int expertHandle, int event_type, const wchar_t* payload, wchar_t* err) { - return Execute([&expertHandle, symbol, &bid, &ask]() { - MtAdapter::GetInstance()->SendQuote(expertHandle, gcnew String(symbol), bid, ask); - return 1; - }, err, 0); -} - -_DLLAPI bool _stdcall sendEvent(int expertHandle, int eventType, wchar_t* payload, wchar_t* err) -{ - return Execute([&expertHandle, &eventType, payload]() { - MtAdapter::GetInstance()->SendEvent(expertHandle, eventType, gcnew String(payload)); + return Execute([&expertHandle, &event_type, payload]() { + MtService::GetInstance().SendEvent(expertHandle, event_type, convertWString(payload)); return true; - }, err, false); + }, err, false); } -_DLLAPI int _stdcall sendIntResponse(int expertHandle, int response, wchar_t* err) -{ - return Execute([&expertHandle, &response]() { - MtAdapter::GetInstance()->SendResponse(expertHandle, gcnew MtResponseInt(response)); - return 1; - }, err, 0); -} - -_DLLAPI int _stdcall sendLongResponse(int expertHandle, __int64 response, wchar_t* err) -{ - return Execute([&expertHandle, &response]() { - MtAdapter::GetInstance()->SendResponse(expertHandle, gcnew MtResponseLong(response)); - return 1; - }, err, 0); -} - -_DLLAPI int _stdcall sendULongResponse(int expertHandle, unsigned __int64 response, wchar_t* err) -{ - return Execute([&expertHandle, &response]() { - MtAdapter::GetInstance()->SendResponse(expertHandle, gcnew MtResponseULong(response)); - return 1; - }, err, 0); -} - -_DLLAPI int _stdcall sendBooleanResponse(int expertHandle, int response, wchar_t* err) -{ - return Execute([&expertHandle, &response]() { - bool value = (response != 0) ? true : false; - MtAdapter::GetInstance()->SendResponse(expertHandle, gcnew MtResponseBool(value)); - return 1; - }, err, 0); -} - -_DLLAPI int _stdcall sendDoubleResponse(int expertHandle, double response, wchar_t* err) -{ - return Execute([&expertHandle, &response]() { - MtAdapter::GetInstance()->SendResponse(expertHandle, gcnew MtResponseDouble(response)); - return 1; - }, err, 0); -} - -_DLLAPI int _stdcall sendStringResponse(int expertHandle, wchar_t* response, wchar_t* err) +int sendResponse(int expertHandle, const wchar_t* response, wchar_t* err) { return Execute([&expertHandle, response]() { - MtAdapter::GetInstance()->SendResponse(expertHandle, gcnew MtResponseString(gcnew String(response))); + MtService::GetInstance().SendResponse(expertHandle, convertWString(response)); return 1; - }, err, 0); + }, err, 0); } -_DLLAPI int _stdcall sendVoidResponse(int expertHandle, wchar_t* err) -{ - return Execute([&expertHandle]() { - MtAdapter::GetInstance()->SendResponse(expertHandle, gcnew MtResponseObject(nullptr)); - return 1; - }, err, 0); -} - -_DLLAPI int _stdcall sendDoubleArrayResponse(int expertHandle, double* values, int size, wchar_t* err) -{ - return Execute([&expertHandle, values, &size]() { - array^ list = gcnew array(size); - for (int i = 0; i < size; i++) - list[i] = values[i]; - MtAdapter::GetInstance()->SendResponse(expertHandle, gcnew MtResponseDoubleArray(list)); - return 1; - }, err, 0); -} - -_DLLAPI int _stdcall sendIntArrayResponse(int expertHandle, int* values, int size, wchar_t* err) -{ - return Execute([&expertHandle, values, &size]() { - array^ list = gcnew array(size); - for (int i = 0; i < size; i++) - list[i] = values[i]; - MtAdapter::GetInstance()->SendResponse(expertHandle, gcnew MtResponseIntArray(list)); - return 1; - }, err, 0); -} - -_DLLAPI int _stdcall sendLongArrayResponse(int expertHandle, __int64* values, int size, wchar_t* err) -{ - return Execute([&expertHandle, values, &size]() { - array^ list = gcnew array(size); - for (int i = 0; i < size; i++) - list[i] = values[i]; - MtAdapter::GetInstance()->SendResponse(expertHandle, gcnew MtResponseLongArray(list)); - return 1; - }, err, 0); -} - -_DLLAPI int _stdcall sendMqlRatesArrayResponse(int expertHandle, CMqlRates values[], int size, wchar_t* err) -{ - return Execute([&expertHandle, values, &size]() { - array^ list = gcnew array(size); - for (int i = 0; i < size; i++) - { - MtMqlRates^ rates = gcnew MtMqlRates(); - rates->time = values[i].time; - rates->open = values[i].open; - rates->high = values[i].high; - rates->low = values[i].low; - rates->close = values[i].close; - rates->tick_volume = values[i].tick_volume; - rates->spread = values[i].spread; - rates->real_volume = values[i].real_volume; - list[i] = rates; - } - MtAdapter::GetInstance()->SendResponse(expertHandle, gcnew MtResponseMqlRatesArray(list)); - return 1; - }, err, 0); -} - -_DLLAPI int _stdcall sendErrorResponse(int expertHandle, int code, wchar_t* message, wchar_t* err) -{ - return Execute([&expertHandle, &code, message]() { - MtResponseString^ res = gcnew MtResponseString(gcnew String(message)); - res->ErrorCode = code; - MtAdapter::GetInstance()->SendResponse(expertHandle, res); - return true; - }, err, 0); -} - -//----------- get values ------------------------------- - -_DLLAPI int _stdcall getCommandType(int expertHandle, int& res, wchar_t* err) +int getCommandType(int expertHandle, int& res, wchar_t* err) { return Execute([&expertHandle, &res]() { - res = MtAdapter::GetInstance()->GetCommandType(expertHandle); + res = MtService::GetInstance().GetCommandType(expertHandle); return 1; - }, err, 0); + }, err, 0); } -_DLLAPI int _stdcall getIntValue(int expertHandle, int paramIndex, int& res, wchar_t* err) +int getPayload(int expertHandle, wchar_t* res, wchar_t* err) { - return Execute([&expertHandle, ¶mIndex, &res]() { - res = MtAdapter::GetInstance()->GetCommandParameter(expertHandle, paramIndex); + return Execute([&expertHandle, res]() { + convertSystemString(res, MtService::GetInstance().GetCommandPayload(expertHandle)); return 1; - }, err, 0); -} - -_DLLAPI int _stdcall getDoubleValue(int expertHandle, int paramIndex, double& res, wchar_t* err) -{ - return Execute([&expertHandle, ¶mIndex, &res]() { - res = MtAdapter::GetInstance()->GetCommandParameter(expertHandle, paramIndex); - return 1; - }, err, 0); -} - -_DLLAPI int _stdcall getStringValue(int expertHandle, int paramIndex, wchar_t* res, wchar_t* err) -{ - return Execute([&expertHandle, ¶mIndex, res]() { - convertSystemString(res, MtAdapter::GetInstance()->GetCommandParameter(expertHandle, paramIndex)); - return 1; - }, err, 0); -} - -_DLLAPI int _stdcall getULongValue(int expertHandle, int paramIndex, unsigned __int64& res, wchar_t* err) -{ - return Execute([&expertHandle, ¶mIndex, &res]() { - res = MtAdapter::GetInstance()->GetCommandParameter(expertHandle, paramIndex); - return 1; - }, err, 0); -} - -_DLLAPI int _stdcall getLongValue(int expertHandle, int paramIndex, __int64& res, wchar_t* err) -{ - return Execute([&expertHandle, ¶mIndex, &res]() { - res = MtAdapter::GetInstance()->GetCommandParameter<__int64>(expertHandle, paramIndex); - return 1; - }, err, 0); -} - -_DLLAPI int _stdcall getBooleanValue(int expertHandle, int paramIndex, int& res, wchar_t* err) -{ - return Execute([&expertHandle, ¶mIndex, &res]() { - bool val = MtAdapter::GetInstance()->GetCommandParameter(expertHandle, paramIndex); - res = val == true ? 1 : 0; - return 1; - }, err, 0); -} - -_DLLAPI int _stdcall getUIntValue(int expertHandle, int paramIndex, unsigned int& res, wchar_t* err) -{ - return Execute([&expertHandle, ¶mIndex, &res]() { - res = MtAdapter::GetInstance()->GetCommandParameter(expertHandle, paramIndex); - return 1; - }, err, 0); -} + }, err, 0); +} \ No newline at end of file diff --git a/MT5Connector/MT5Connector.vcxproj b/MT5Connector/MT5Connector.vcxproj index c0f1fc27..8266eaec 100755 --- a/MT5Connector/MT5Connector.vcxproj +++ b/MT5Connector/MT5Connector.vcxproj @@ -20,10 +20,9 @@ {CB6D4A3E-2F2E-4C67-929D-3C2A8FD1C556} - v4.5.2 ManagedCProj MT5Connector - 10.0.17134.0 + 10.0 @@ -36,9 +35,8 @@ DynamicLibrary true - true Unicode - v141 + v143 DynamicLibrary @@ -77,6 +75,7 @@ true $(SolutionDir)build\products\$(Configuration)\$(Platform)\ + $(SolutionDir)thirdparty\libs;$(LibraryPath) false @@ -104,10 +103,10 @@ Disabled WIN32;_DEBUG;%(PreprocessorDefinitions) Use + $(SolutionDir)MtService;%(AdditionalIncludeDirectories) true - user32.lib;%(AdditionalDependencies) @@ -143,7 +142,6 @@ - Create @@ -154,7 +152,6 @@ - @@ -171,6 +168,9 @@ true false + + {3effff03-2a1d-48aa-a49a-9f90889f31e0} + diff --git a/MT5Connector/MT5Handler.h b/MT5Connector/MT5Handler.h index d7ccc368..154013b5 100755 --- a/MT5Connector/MT5Handler.h +++ b/MT5Connector/MT5Handler.h @@ -3,22 +3,25 @@ #pragma once #include +#include -using namespace MTApiService; - -ref class MT5Handler: IMetaTraderHandler +class MT5Handler: public MetaTraderHandler { public: - MT5Handler() + MT5Handler(int handle) + : handle_(handle) { msgId = WM_TIMER; } - virtual void SendTickToMetaTrader(int handle) - { - PostMessage((HWND)handle, msgId, 0, 0); - } + ~MT5Handler() override = default; private: + void SendTickToMetaTrader() override + { + PostMessage((HWND)handle_, msgId, 0, 0); + } + + int handle_; unsigned int msgId; }; \ No newline at end of file diff --git a/MT5Connector/ReadMe.txt b/MT5Connector/ReadMe.txt deleted file mode 100755 index 4af02826..00000000 --- a/MT5Connector/ReadMe.txt +++ /dev/null @@ -1,38 +0,0 @@ -======================================================================== - DYNAMIC LINK LIBRARY : MT5Connector Project Overview -======================================================================== - -AppWizard has created this MT5Connector DLL for you. - -This file contains a summary of what you will find in each of the files that -make up your MT5Connector application. - -MT5Connector.vcxproj - This is the main project file for VC++ projects generated using an Application Wizard. - It contains information about the version of Visual C++ that generated the file, and - information about the platforms, configurations, and project features selected with the - Application Wizard. - -MT5Connector.vcxproj.filters - This is the filters file for VC++ projects generated using an Application Wizard. - It contains information about the association between the files in your project - and the filters. This association is used in the IDE to show grouping of files with - similar extensions under a specific node (for e.g. ".cpp" files are associated with the - "Source Files" filter). - -MT5Connector.cpp - This is the main DLL source file. - -MT5Connector.h - This file contains a class declaration. - -AssemblyInfo.cpp - Contains custom attributes for modifying assembly metadata. - -///////////////////////////////////////////////////////////////////////////// -Other notes: - -AppWizard uses "TODO:" to indicate parts of the source code you -should add to or customize. - -///////////////////////////////////////////////////////////////////////////// diff --git a/MetaTraderApi_2022.sln b/MetaTraderApi_2022.sln index 27fe20f3..fcbe7646 100755 --- a/MetaTraderApi_2022.sln +++ b/MetaTraderApi_2022.sln @@ -7,6 +7,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MtClient", "MtClient\MtClie EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MtService", "MtService\MtService.vcxproj", "{3EFFFF03-2A1D-48AA-A49A-9F90889F31E0}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MT5Connector", "MT5Connector\MT5Connector.vcxproj", "{CB6D4A3E-2F2E-4C67-929D-3C2A8FD1C556}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -41,6 +43,18 @@ Global {3EFFFF03-2A1D-48AA-A49A-9F90889F31E0}.Release|x64.Build.0 = Release|x64 {3EFFFF03-2A1D-48AA-A49A-9F90889F31E0}.Release|x86.ActiveCfg = Release|Win32 {3EFFFF03-2A1D-48AA-A49A-9F90889F31E0}.Release|x86.Build.0 = Release|Win32 + {CB6D4A3E-2F2E-4C67-929D-3C2A8FD1C556}.Debug|Any CPU.ActiveCfg = Debug|x64 + {CB6D4A3E-2F2E-4C67-929D-3C2A8FD1C556}.Debug|Any CPU.Build.0 = Debug|x64 + {CB6D4A3E-2F2E-4C67-929D-3C2A8FD1C556}.Debug|x64.ActiveCfg = Debug|x64 + {CB6D4A3E-2F2E-4C67-929D-3C2A8FD1C556}.Debug|x64.Build.0 = Debug|x64 + {CB6D4A3E-2F2E-4C67-929D-3C2A8FD1C556}.Debug|x86.ActiveCfg = Debug|Win32 + {CB6D4A3E-2F2E-4C67-929D-3C2A8FD1C556}.Debug|x86.Build.0 = Debug|Win32 + {CB6D4A3E-2F2E-4C67-929D-3C2A8FD1C556}.Release|Any CPU.ActiveCfg = Release|x64 + {CB6D4A3E-2F2E-4C67-929D-3C2A8FD1C556}.Release|Any CPU.Build.0 = Release|x64 + {CB6D4A3E-2F2E-4C67-929D-3C2A8FD1C556}.Release|x64.ActiveCfg = Release|x64 + {CB6D4A3E-2F2E-4C67-929D-3C2A8FD1C556}.Release|x64.Build.0 = Release|x64 + {CB6D4A3E-2F2E-4C67-929D-3C2A8FD1C556}.Release|x86.ActiveCfg = Release|Win32 + {CB6D4A3E-2F2E-4C67-929D-3C2A8FD1C556}.Release|x86.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/MtService/MtService.vcxproj b/MtService/MtService.vcxproj index d50e4e44..c815bc55 100755 --- a/MtService/MtService.vcxproj +++ b/MtService/MtService.vcxproj @@ -112,8 +112,7 @@ true Use pch.h - C:\Users\vdemy\source\repos\MtService\MtService;C:\Users\vdemy\source\repos\MtService\thirdparty\include;%(AdditionalIncludeDirectories) - Default + $(SolutionDir)thirdparty\include;%(AdditionalIncludeDirectories)