├── .gitattributes
├── .gitignore
├── MtGuiController.sln
└── MtGuiController
├── Controller.cs
├── IController.cs
├── MtGuiController.csproj
└── Properties
└── AssemblyInfo.cs
/.gitattributes:
--------------------------------------------------------------------------------
1 | ###############################################################################
2 | # Set default behavior to automatically normalize line endings.
3 | ###############################################################################
4 | * text=auto
5 |
6 | ###############################################################################
7 | # Set default behavior for command prompt diff.
8 | #
9 | # This is need for earlier builds of msysgit that does not have it on by
10 | # default for csharp files.
11 | # Note: This is only used by command line
12 | ###############################################################################
13 | #*.cs diff=csharp
14 |
15 | ###############################################################################
16 | # Set the merge driver for project and solution files
17 | #
18 | # Merging from the command prompt will add diff markers to the files if there
19 | # are conflicts (Merging from VS is not affected by the settings below, in VS
20 | # the diff markers are never inserted). Diff markers may cause the following
21 | # file extensions to fail to load in VS. An alternative would be to treat
22 | # these files as binary and thus will always conflict and require user
23 | # intervention with every merge. To do so, just uncomment the entries below
24 | ###############################################################################
25 | #*.sln merge=binary
26 | #*.csproj merge=binary
27 | #*.vbproj merge=binary
28 | #*.vcxproj merge=binary
29 | #*.vcproj merge=binary
30 | #*.dbproj merge=binary
31 | #*.fsproj merge=binary
32 | #*.lsproj merge=binary
33 | #*.wixproj merge=binary
34 | #*.modelproj merge=binary
35 | #*.sqlproj merge=binary
36 | #*.wwaproj merge=binary
37 |
38 | ###############################################################################
39 | # behavior for image files
40 | #
41 | # image files are treated as binary by default.
42 | ###############################################################################
43 | #*.jpg binary
44 | #*.png binary
45 | #*.gif binary
46 |
47 | ###############################################################################
48 | # diff behavior for common document formats
49 | #
50 | # Convert binary document formats to text before diffing them. This feature
51 | # is only available from the command line. Turn it on by uncommenting the
52 | # entries below.
53 | ###############################################################################
54 | #*.doc diff=astextplain
55 | #*.DOC diff=astextplain
56 | #*.docx diff=astextplain
57 | #*.DOCX diff=astextplain
58 | #*.dot diff=astextplain
59 | #*.DOT diff=astextplain
60 | #*.pdf diff=astextplain
61 | #*.PDF diff=astextplain
62 | #*.rtf diff=astextplain
63 | #*.RTF diff=astextplain
64 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 |
4 | # User-specific files
5 | *.suo
6 | *.user
7 | *.userosscache
8 | *.sln.docstates
9 |
10 | # User-specific files (MonoDevelop/Xamarin Studio)
11 | *.userprefs
12 |
13 | # Build results
14 | [Dd]ebug/
15 | [Dd]ebugPublic/
16 | [Rr]elease/
17 | [Rr]eleases/
18 | x64/
19 | x86/
20 | bld/
21 | [Bb]in/
22 | [Oo]bj/
23 | [Ll]og/
24 |
25 | # Visual Studio 2015 cache/options directory
26 | .vs/
27 | # Uncomment if you have tasks that create the project's static files in wwwroot
28 | #wwwroot/
29 |
30 | # MSTest test Results
31 | [Tt]est[Rr]esult*/
32 | [Bb]uild[Ll]og.*
33 |
34 | # NUNIT
35 | *.VisualState.xml
36 | TestResult.xml
37 |
38 | # Build Results of an ATL Project
39 | [Dd]ebugPS/
40 | [Rr]eleasePS/
41 | dlldata.c
42 |
43 | # DNX
44 | project.lock.json
45 | project.fragment.lock.json
46 | artifacts/
47 |
48 | *_i.c
49 | *_p.c
50 | *_i.h
51 | *.ilk
52 | *.meta
53 | *.obj
54 | *.pch
55 | *.pdb
56 | *.pgc
57 | *.pgd
58 | *.rsp
59 | *.sbr
60 | *.tlb
61 | *.tli
62 | *.tlh
63 | *.tmp
64 | *.tmp_proj
65 | *.log
66 | *.vspscc
67 | *.vssscc
68 | .builds
69 | *.pidb
70 | *.svclog
71 | *.scc
72 |
73 | # Chutzpah Test files
74 | _Chutzpah*
75 |
76 | # Visual C++ cache files
77 | ipch/
78 | *.aps
79 | *.ncb
80 | *.opendb
81 | *.opensdf
82 | *.sdf
83 | *.cachefile
84 | *.VC.db
85 | *.VC.VC.opendb
86 |
87 | # Visual Studio profiler
88 | *.psess
89 | *.vsp
90 | *.vspx
91 | *.sap
92 |
93 | # TFS 2012 Local Workspace
94 | $tf/
95 |
96 | # Guidance Automation Toolkit
97 | *.gpState
98 |
99 | # ReSharper is a .NET coding add-in
100 | _ReSharper*/
101 | *.[Rr]e[Ss]harper
102 | *.DotSettings.user
103 |
104 | # JustCode is a .NET coding add-in
105 | .JustCode
106 |
107 | # TeamCity is a build add-in
108 | _TeamCity*
109 |
110 | # DotCover is a Code Coverage Tool
111 | *.dotCover
112 |
113 | # NCrunch
114 | _NCrunch_*
115 | .*crunch*.local.xml
116 | nCrunchTemp_*
117 |
118 | # MightyMoose
119 | *.mm.*
120 | AutoTest.Net/
121 |
122 | # Web workbench (sass)
123 | .sass-cache/
124 |
125 | # Installshield output folder
126 | [Ee]xpress/
127 |
128 | # DocProject is a documentation generator add-in
129 | DocProject/buildhelp/
130 | DocProject/Help/*.HxT
131 | DocProject/Help/*.HxC
132 | DocProject/Help/*.hhc
133 | DocProject/Help/*.hhk
134 | DocProject/Help/*.hhp
135 | DocProject/Help/Html2
136 | DocProject/Help/html
137 |
138 | # Click-Once directory
139 | publish/
140 |
141 | # Publish Web Output
142 | *.[Pp]ublish.xml
143 | *.azurePubxml
144 | # TODO: Comment the next line if you want to checkin your web deploy settings
145 | # but database connection strings (with potential passwords) will be unencrypted
146 | #*.pubxml
147 | *.publishproj
148 |
149 | # Microsoft Azure Web App publish settings. Comment the next line if you want to
150 | # checkin your Azure Web App publish settings, but sensitive information contained
151 | # in these scripts will be unencrypted
152 | PublishScripts/
153 |
154 | # NuGet Packages
155 | *.nupkg
156 | # The packages folder can be ignored because of Package Restore
157 | **/packages/*
158 | # except build/, which is used as an MSBuild target.
159 | !**/packages/build/
160 | # Uncomment if necessary however generally it will be regenerated when needed
161 | #!**/packages/repositories.config
162 | # NuGet v3's project.json files produces more ignoreable files
163 | *.nuget.props
164 | *.nuget.targets
165 |
166 | # Microsoft Azure Build Output
167 | csx/
168 | *.build.csdef
169 |
170 | # Microsoft Azure Emulator
171 | ecf/
172 | rcf/
173 |
174 | # Windows Store app package directories and files
175 | AppPackages/
176 | BundleArtifacts/
177 | Package.StoreAssociation.xml
178 | _pkginfo.txt
179 |
180 | # Visual Studio cache files
181 | # files ending in .cache can be ignored
182 | *.[Cc]ache
183 | # but keep track of directories ending in .cache
184 | !*.[Cc]ache/
185 |
186 | # Others
187 | ClientBin/
188 | ~$*
189 | *~
190 | *.dbmdl
191 | *.dbproj.schemaview
192 | *.jfm
193 | *.pfx
194 | *.publishsettings
195 | node_modules/
196 | orleans.codegen.cs
197 |
198 | # Since there are multiple workflows, uncomment next line to ignore bower_components
199 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
200 | #bower_components/
201 |
202 | # RIA/Silverlight projects
203 | Generated_Code/
204 |
205 | # Backup & report files from converting an old project file
206 | # to a newer Visual Studio version. Backup files are not needed,
207 | # because we have git ;-)
208 | _UpgradeReport_Files/
209 | Backup*/
210 | UpgradeLog*.XML
211 | UpgradeLog*.htm
212 |
213 | # SQL Server files
214 | *.mdf
215 | *.ldf
216 |
217 | # Business Intelligence projects
218 | *.rdl.data
219 | *.bim.layout
220 | *.bim_*.settings
221 |
222 | # Microsoft Fakes
223 | FakesAssemblies/
224 |
225 | # GhostDoc plugin setting file
226 | *.GhostDoc.xml
227 |
228 | # Node.js Tools for Visual Studio
229 | .ntvs_analysis.dat
230 |
231 | # Visual Studio 6 build log
232 | *.plg
233 |
234 | # Visual Studio 6 workspace options file
235 | *.opt
236 |
237 | # Visual Studio LightSwitch build output
238 | **/*.HTMLClient/GeneratedArtifacts
239 | **/*.DesktopClient/GeneratedArtifacts
240 | **/*.DesktopClient/ModelManifest.xml
241 | **/*.Server/GeneratedArtifacts
242 | **/*.Server/ModelManifest.xml
243 | _Pvt_Extensions
244 |
245 | # Paket dependency manager
246 | .paket/paket.exe
247 | paket-files/
248 |
249 | # FAKE - F# Make
250 | .fake/
251 |
252 | # JetBrains Rider
253 | .idea/
254 | *.sln.iml
255 |
256 | # CodeRush
257 | .cr/
258 |
259 | # Python Tools for Visual Studio (PTVS)
260 | __pycache__/
261 | *.pyc
--------------------------------------------------------------------------------
/MtGuiController.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 15
4 | VisualStudioVersion = 15.0.27703.2035
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MtGuiController", "MtGuiController\MtGuiController.csproj", "{C55DF26C-CE58-4E23-A6C5-8E2AD1D1F7B2}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|Any CPU = Debug|Any CPU
11 | Release|Any CPU = Release|Any CPU
12 | EndGlobalSection
13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
14 | {C55DF26C-CE58-4E23-A6C5-8E2AD1D1F7B2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
15 | {C55DF26C-CE58-4E23-A6C5-8E2AD1D1F7B2}.Debug|Any CPU.Build.0 = Debug|Any CPU
16 | {C55DF26C-CE58-4E23-A6C5-8E2AD1D1F7B2}.Release|Any CPU.ActiveCfg = Release|Any CPU
17 | {C55DF26C-CE58-4E23-A6C5-8E2AD1D1F7B2}.Release|Any CPU.Build.0 = Release|Any CPU
18 | EndGlobalSection
19 | GlobalSection(SolutionProperties) = preSolution
20 | HideSolutionNode = FALSE
21 | EndGlobalSection
22 | GlobalSection(ExtensibilityGlobals) = postSolution
23 | SolutionGuid = {FB37DBBB-67EA-495C-BFD3-5FA442ACFF2E}
24 | EndGlobalSection
25 | EndGlobal
26 |
--------------------------------------------------------------------------------
/MtGuiController/Controller.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Windows.Forms;
4 | using System.Reflection;
5 | using System.IO;
6 | using System.Threading;
7 | using System.Threading.Tasks;
8 |
9 | namespace MtGuiController
10 | {
11 | ///
12 | /// Class contein not-static methods and handlers for abstract windows form
13 | ///
14 | public partial class GuiController
15 | {
16 | #region Private fileds
17 | ///
18 | ///
19 | ///
20 | private Assembly m_assembly = null;
21 | ///
22 | /// Windows form
23 | ///
24 | private Form m_form = null;
25 | ///
26 | ///
27 | ///
28 | private bool m_is_closing = false;
29 | ///
30 | /// Global events list
31 | ///
32 | private List m_events = null;
33 | ///
34 | /// Controls collection
35 | ///
36 | private Dictionary m_controls = new Dictionary();
37 |
38 | ///
39 | /// Abstract handler of any event of win-form element
40 | ///
41 | ///
42 | private delegate void HandlerControl(Control control);
43 | #endregion
44 | #region Handlers of events
45 |
46 | ///
47 | /// This method receives a scroll event and sends it's to MetaTrader
48 | ///
49 | /// ScrollBar element
50 | /// Params of scroll
51 | private void OnScroll(object sender, EventArgs e)
52 | {
53 | Control control = (Control)sender;
54 | ScrollEventArgs scroll_args = (ScrollEventArgs)e;
55 | if (scroll_args.Type != ScrollEventType.SmallIncrement &&
56 | scroll_args.Type != ScrollEventType.SmallDecrement)
57 | return;
58 | GuiEvent evnt = new GuiEvent
59 | {
60 | id = GuiEventType.ScrollChange,
61 | el_name = control.Name,
62 | lparam = scroll_args.OldValue,
63 | dparam = scroll_args.NewValue,
64 | };
65 | m_events.Add(evnt);
66 | }
67 | ///
68 | /// This method receives a click event and sends it's to MetaTrader
69 | ///
70 | /// Any winform element
71 | ///
72 | private void OnClick(object sender, EventArgs e)
73 | {
74 | Control control = (Control)sender;
75 | GuiEvent evnt = new GuiEvent
76 | {
77 | id = GuiEventType.ClickOnElement,
78 | el_name = control.Name,
79 | sparam = control.Text
80 | };
81 | m_events.Add(evnt);
82 | }
83 | ///
84 | /// This method receives a click event and sends it's to MetaTrader
85 | ///
86 | /// Any winform element
87 | ///
88 | private void OnChecked(object sender, EventArgs e)
89 | {
90 | CheckBox control = (CheckBox)sender;
91 | GuiEvent evnt = new GuiEvent
92 | {
93 | id = GuiEventType.CheckBoxChange,
94 | el_name = control.Name,
95 | sparam = control.Text,
96 | lparam = (long)control.CheckState
97 | };
98 | m_events.Add(evnt);
99 | }
100 | private void OnRadioBtnCheckedChange(object sender, EventArgs e)
101 | {
102 | RadioButton control = (RadioButton)sender;
103 | GuiEvent evnt = new GuiEvent
104 | {
105 | id = GuiEventType.RadioButtonChange,
106 | el_name = control.Name,
107 | sparam = control.Text,
108 | lparam = control.Checked ? 1 : 0
109 | };
110 | m_events.Add(evnt);
111 | }
112 | private void OnComboBoxChange(object sender, EventArgs e)
113 | {
114 | ComboBox control = (ComboBox)sender;
115 | string item_text = control.SelectedItem as string;
116 | GuiEvent evnt = new GuiEvent
117 | {
118 | id = GuiEventType.ComboBoxChange,
119 | el_name = control.Name,
120 | sparam = item_text,
121 | lparam = control.SelectedIndex
122 | };
123 | m_events.Add(evnt);
124 | }
125 | ///
126 | /// This method receives the availability of the objec to MetaTrader
127 | ///
128 | /// Any winform element
129 | ///
130 | private void OnEnableChange(object sender, EventArgs e)
131 | {
132 | Control control = (Control)sender;
133 | GuiEvent evnt = new GuiEvent
134 | {
135 | id = GuiEventType.ElementEnable,
136 | el_name = control.Name,
137 | sparam = control.Text,
138 | lparam = control.Enabled ? 1 : 0,
139 | };
140 | m_events.Add(evnt);
141 | }
142 |
143 | private void OnNumericChanged(object sender, EventArgs e)
144 | {
145 | NumericUpDown numeric = (NumericUpDown)sender;
146 | GuiEvent evnt = new GuiEvent
147 | {
148 | id = GuiEventType.NumericChange,
149 | el_name = numeric.Name,
150 | dparam = (double)numeric.Value
151 | };
152 | m_events.Add(evnt);
153 | }
154 | ///
155 | ///
156 | ///
157 | ///
158 | ///
159 | private void OnDateTimePickerChanged(object sender, EventArgs e)
160 | {
161 | DateTimePicker picker = (DateTimePicker)sender;
162 | GuiEvent evnt = new GuiEvent
163 | {
164 | id = GuiEventType.DateTimePickerChange,
165 | el_name = picker.Name,
166 | lparam = MtConverter.ToMqlDateTime(picker.Value)
167 | };
168 | m_events.Add(evnt);
169 | }
170 | ///
171 | /// This method receives a click event and sends it's to MetaTrader
172 | ///
173 | /// Any winform element
174 | ///
175 | private void OnTabChanged(object sender, EventArgs e)
176 | {
177 | TabControl control = (TabControl)sender;
178 | GuiEvent evnt = new GuiEvent
179 | {
180 | id = GuiEventType.TabIndexChange,
181 | el_name = control.Name,
182 | lparam = control.SelectedIndex,
183 | sparam = control.SelectedTab.Name
184 | };
185 | m_events.Add(evnt);
186 | }
187 | ///
188 | /// This method receives a change text event and sends it's to MetaTrader
189 | ///
190 | ///
191 | ///
192 | private void OnTextChange(object c, EventArgs e)
193 | {
194 | Control control = (Control)c;
195 | GuiEvent evnt = new GuiEvent
196 | {
197 | id = GuiEventType.TextChange,
198 | el_name = control.Name,
199 | sparam = control.Text
200 | };
201 | m_events.Add(evnt);
202 | }
203 | ///
204 | /// This method receives a lost focus event and interprets it as end text changed event
205 | ///
206 | ///
207 | ///
208 | private void OnLostFocus(object sender, EventArgs e)
209 | {
210 | Control control = (Control)sender;
211 | OnTextChange(sender, e);
212 | }
213 | ///
214 | /// This method receives a key down event and if pressed key is enter interprets it as end text changed event
215 | ///
216 | ///
217 | ///
218 | private void OnKeyDown(object sender, EventArgs e)
219 | {
220 | KeyEventArgs key_args = (KeyEventArgs)e;
221 | if (key_args.KeyCode == Keys.Enter)
222 | OnTextChange(sender, e);
223 | }
224 |
225 | #endregion
226 |
227 | ///
228 | /// Create new gui controller
229 | ///
230 | private GuiController(Assembly assembly, Form form, List global_events_list)
231 | {
232 | m_assembly = assembly;
233 | m_form = form;
234 | m_events = global_events_list;
235 | SubscribeOnElements(m_form);
236 | }
237 | ///
238 | /// Subscribe on supported events
239 | ///
240 | /// Windows form
241 | private void SubscribeOnElements(Form form)
242 | {
243 | form.FormClosing += OnClosingForm;
244 | //-- define resolve events
245 | Dictionary> types_and_events = new Dictionary>();
246 | types_and_events.Add(typeof(VScrollBar), new List() { vscrol => ((VScrollBar)vscrol).Scroll += OnScroll });
247 | types_and_events.Add(typeof(Button), new List() { button => ((Button)button).Click += OnClick });
248 | types_and_events.Add(typeof(Label), new List());
249 | types_and_events.Add(typeof(TextBox), new List() { text_box => text_box.LostFocus += OnLostFocus,
250 | text_box => text_box.KeyDown += OnKeyDown });
251 | types_and_events.Add(typeof(CheckBox), new List() { check_box => ((CheckBox)check_box).CheckStateChanged += OnChecked });
252 | types_and_events.Add(typeof(TabControl), new List() { tab_box => ((TabControl)tab_box).SelectedIndexChanged += OnTabChanged });
253 | types_and_events.Add(typeof(RadioButton), new List() { radio_box => ((RadioButton)radio_box).CheckedChanged += OnRadioBtnCheckedChange });
254 | types_and_events.Add(typeof(ComboBox), new List() { combo_box => ((ComboBox)combo_box).SelectedIndexChanged += OnComboBoxChange,
255 | combo_box => ((ComboBox)combo_box).TextChanged += OnTextChange});
256 | types_and_events.Add(typeof(NumericUpDown), new List() { numeric => ((NumericUpDown)numeric).ValueChanged += OnNumericChanged});
257 | types_and_events.Add(typeof(DateTimePicker), new List() { numeric => ((DateTimePicker)numeric).ValueChanged += OnDateTimePickerChanged });
258 | //-- Recursive subscribe on controls
259 | SubscribeOnControls(types_and_events, form);
260 | }
261 | ///
262 | /// Recursive subscribe on controls
263 | ///
264 | ///
265 | private void SubscribeOnControls(Dictionary> types_and_events, Control control)
266 | {
267 | if (control.GetType() != typeof(NumericUpDown))
268 | {
269 | foreach (Control cnt in control.Controls)
270 | SubscribeOnControls(types_and_events, cnt);
271 | }
272 | try
273 | {
274 | m_controls.Add(control.Name, control);
275 | }
276 | catch(ArgumentException ex)
277 | {
278 | throw new ArgumentException("Ключ с таким именем уже существует", control.Name, ex);
279 | }
280 | if (types_and_events.ContainsKey(control.GetType()))
281 | types_and_events[control.GetType()].ForEach(el => el.Invoke(control));
282 | }
283 | ///
284 | /// Recursive subscribe on controls
285 | ///
286 | ///
287 | private void SubscribeOnControls_old(Dictionary> types_and_events, Control control)
288 | {
289 | foreach (Control cnt in control.Controls)
290 | SubscribeOnControls(types_and_events, cnt);
291 | if (control.GetType().BaseType == typeof(Form))
292 | m_controls.Add(control.Name, control);
293 | control.EnabledChanged += OnEnableChange;
294 | if (types_and_events.ContainsKey(control.GetType()))
295 | {
296 | types_and_events[control.GetType()].ForEach(el => el.Invoke(control));
297 | m_controls.Add(control.Name, control);
298 | }
299 | }
300 | ///
301 | ///
302 | ///
303 | private void MessageBoxCreate(string el_name, bool is_blocked, string info)
304 | {
305 |
306 | }
307 | ///
308 | /// Run form
309 | ///
310 | public void RunForm()
311 | {
312 | Thread thread = new Thread(() => Application.Run(m_form));
313 | thread.SetApartmentState(ApartmentState.STA);
314 | thread.Start();
315 | Thread.Sleep(200);
316 | }
317 | #region Dispose
318 |
319 | ///
320 | /// Dispose form
321 | ///
322 | public void DisposeForm()
323 | {
324 | m_form.Dispose();
325 | }
326 |
327 | ///
328 | /// Handler on dispose of form
329 | ///
330 | ///
331 | ///
332 | private void OnClosingForm(object sender, EventArgs e)
333 | {
334 | m_is_closing = true;
335 | m_controls.Clear();
336 | }
337 | ///
338 | /// Dispose status
339 | ///
340 | private bool IsDiposed
341 | {
342 | get
343 | {
344 | if (m_is_closing)
345 | return true;
346 | if (m_form == null)
347 | return true;
348 | return m_form.IsDisposed;
349 | }
350 | }
351 | #endregion
352 | }
353 | }
354 |
--------------------------------------------------------------------------------
/MtGuiController/IController.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Windows.Forms;
4 | using System.Reflection;
5 |
6 | namespace MtGuiController.Published
7 | {
8 | public enum BlockingControl
9 | {
10 | NotLockControl,
11 | LockControl
12 | }
13 | //
14 | // Summary:
15 | // Specifies constants defining which buttons to display on a System.Windows.Forms.MessageBox.
16 | public enum MessageBoxButtons
17 | {
18 | //
19 | // Summary:
20 | // The message box contains an OK button.
21 | OK = 0,
22 | //
23 | // Summary:
24 | // The message box contains OK and Cancel buttons.
25 | OKCancel = 1,
26 | //
27 | // Summary:
28 | // The message box contains Abort, Retry, and Ignore buttons.
29 | AbortRetryIgnore = 2,
30 | //
31 | // Summary:
32 | // The message box contains Yes, No, and Cancel buttons.
33 | YesNoCancel = 3,
34 | //
35 | // Summary:
36 | // The message box contains Yes and No buttons.
37 | YesNo = 4,
38 | //
39 | // Summary:
40 | // The message box contains Retry and Cancel buttons.
41 | RetryCancel = 5
42 | }
43 | }
44 |
45 |
46 | namespace MtGuiController
47 | {
48 |
49 | ///
50 | /// Type of gui event
51 | ///
52 | public enum GuiEventType
53 | {
54 | Exception,
55 | MessageBox,
56 | ClickOnElement,
57 | TextChange,
58 | ScrollChange,
59 | TabIndexChange,
60 | CheckBoxChange,
61 | ElementEnable,
62 | RadioButtonChange,
63 | ComboBoxChange,
64 | NumericChange,
65 | NumericFormatChange,
66 | NumericMaxChange,
67 | NumericMinChange,
68 | DateTimePickerChange,
69 | ElementHide,
70 | AddItem,
71 | }
72 | ///
73 | /// Container for event
74 | ///
75 | public class GuiEvent
76 | {
77 | public string assembly_name;
78 | public string form_name;
79 | public string el_name;
80 | public GuiEventType id;
81 | public long lparam;
82 | public double dparam;
83 | public string sparam;
84 | }
85 |
86 | public partial class GuiController
87 | {
88 | ///
89 | /// One controller for each windows form
90 | ///
91 | private static Dictionary m_controllers = new Dictionary();
92 | ///
93 | /// Events list
94 | ///
95 | private static List m_global_events = new List();
96 |
97 | #region private methods
98 | ///
99 | /// Create GuiController for windows form
100 | ///
101 | /// Path to assembly
102 | /// Windows Form's name
103 | ///
104 | private static GuiController GetGuiController(string assembly_path, string form_name)
105 | {
106 | Assembly assembly = Assembly.LoadFile(assembly_path);
107 | Form form = FindForm(assembly, form_name);
108 | GuiController controller = new GuiController(assembly, form, m_global_events);
109 | return controller;
110 | }
111 | ///
112 | /// Find needed form
113 | ///
114 | /// Assembly
115 | ///
116 | private static Form FindForm(Assembly assembly, string form_name)
117 | {
118 | Type[] types = assembly.GetTypes();
119 | foreach (Type type in types)
120 | {
121 | //assembly.CreateInstance()
122 | if (type.BaseType == typeof(Form) && type.Name == form_name)
123 | {
124 | object obj_form = type.Assembly.CreateInstance(type.FullName);
125 | return (Form)obj_form;
126 | }
127 | }
128 | throw new Exception("Form with name " + form_name + " in assembly " + assembly.FullName + " not find");
129 | }
130 | ///
131 | ///
132 | ///
133 | ///
134 | private static void SendExceptionEvent(Exception ex)
135 | {
136 | GuiEvent ex_event = new GuiEvent()
137 | {
138 | id = (int)GuiEventType.Exception,
139 | sparam = ex.Message
140 | };
141 | m_global_events.Add(ex_event);
142 | }
143 |
144 | #endregion
145 | #region MetaTrader Interface methods
146 | ///
147 | /// Show Windows form
148 | ///
149 | [STAThread]
150 | public static void ShowForm(string assembly_path, string form_name)
151 | {
152 | try
153 | {
154 | GuiController controller = GetGuiController(assembly_path, form_name);
155 | string full_path = assembly_path + "/" + form_name;
156 | m_controllers.Add(full_path, controller);
157 | controller.RunForm();
158 | }
159 | catch(ArgumentException e)
160 | {
161 | Type t = e.GetType();
162 | SendExceptionEvent(e);
163 | }
164 | }
165 |
166 | ///
167 | /// Hide Windows Form
168 | ///
169 | public static void HideForm(string assembly_path, string form_name)
170 | {
171 | try
172 | {
173 | string full_path = assembly_path + "/" + form_name;
174 | if (!m_controllers.ContainsKey(full_path))
175 | return;
176 | GuiController controller = m_controllers[full_path];
177 | controller.DisposeForm();
178 | m_controllers.Remove(full_path);
179 | }
180 | catch(Exception ex)
181 | {
182 | SendExceptionEvent(ex);
183 | }
184 | }
185 |
186 | ///
187 | /// Send event
188 | ///
189 | /// name of control
190 | /// Event type
191 | /// long value
192 | /// double value
193 | /// string value
194 | public static void SendEvent(string el_name, int id, long lparam, double dparam, string sparam)
195 | {
196 | SendEventRef(el_name, ref id, ref lparam, ref dparam, sparam);
197 | }
198 | ///
199 | /// Send event
200 | ///
201 | /// name of control
202 | /// Event type
203 | /// long value
204 | /// double value
205 | /// string value
206 | public static void SendEventRef(string el_name, ref int id, ref long lparam, ref double dparam, string sparam)
207 | {
208 | try
209 | {
210 | foreach (var kvp in m_controllers)
211 | {
212 | GuiController controller = kvp.Value;
213 | if (controller.IsDiposed)
214 | {
215 | m_controllers.Remove(kvp.Key);
216 | return;
217 | }
218 | Control control = null;
219 | if (!controller.m_controls.TryGetValue(el_name, out control))
220 | {
221 | SendExceptionEvent(new Exception("SendEvent: element with name '" + el_name + "' not find"));
222 | continue;
223 | }
224 | GuiEventType event_type = (GuiEventType)id;
225 | switch (event_type)
226 | {
227 | case GuiEventType.TextChange:
228 | control.Invoke((MethodInvoker)delegate { control.Text = sparam; });
229 | break;
230 | case GuiEventType.CheckBoxChange:
231 | {
232 | CheckBox checkBox = (CheckBox)control;
233 | CheckState state = (CheckState)lparam;
234 | control.Invoke((MethodInvoker)delegate { checkBox.CheckState = state; });
235 | break;
236 | }
237 | case GuiEventType.RadioButtonChange:
238 | RadioButton radio_btn = (RadioButton)control;
239 | bool check = lparam == 0 ? false : true;
240 | control.Invoke((MethodInvoker)delegate { radio_btn.Checked = check; });
241 | break;
242 | case GuiEventType.ComboBoxChange:
243 | ComboBox combo_box = (ComboBox)control;
244 | if(combo_box.SelectedIndex != (int)lparam)
245 | combo_box.SelectedIndex = (int)lparam;
246 | break;
247 | case GuiEventType.NumericChange:
248 | NumericUpDown numeric = (NumericUpDown)control;
249 | if (numeric.Value != (decimal)dparam)
250 | numeric.Value = (decimal)dparam;
251 | break;
252 | case GuiEventType.NumericFormatChange:
253 | if (control.GetType() != typeof(NumericUpDown))
254 | {
255 | SendExceptionEvent(new Exception("Element " + control.Name + " doesn't support 'NumericStepsChange' event"));
256 | break;
257 | }
258 | NumericUpDown num = (NumericUpDown)control;
259 | num.DecimalPlaces = (int)lparam;
260 | num.Increment = (decimal)dparam;
261 | break;
262 | case GuiEventType.NumericMaxChange:
263 | if (control.GetType() != typeof(NumericUpDown))
264 | {
265 | SendExceptionEvent(new Exception("Element " + control.Name + " doesn't support 'NumericMaxChange' event"));
266 | break;
267 | }
268 | NumericUpDown nummax = (NumericUpDown)control;
269 | nummax.Maximum = (decimal)dparam;
270 | break;
271 | case GuiEventType.NumericMinChange:
272 | if (control.GetType() != typeof(NumericUpDown))
273 | {
274 | SendExceptionEvent(new Exception("Element " + control.Name + " doesn't support 'NumericMinChange' event"));
275 | break;
276 | }
277 | NumericUpDown nummin = (NumericUpDown)control;
278 | nummin.Minimum = (decimal)dparam;
279 | break;
280 | case GuiEventType.ElementHide:
281 | if (lparam != 0)
282 | control.Hide();
283 | else
284 | control.Show();
285 | break;
286 | case GuiEventType.DateTimePickerChange:
287 | DateTimePicker picker = (DateTimePicker)control;
288 | picker.Value = MtConverter.ToSharpDateTime(lparam);
289 | break;
290 | case GuiEventType.ElementEnable:
291 | {
292 | bool enable = lparam == 0 ? false : true;
293 | if (enable != control.Enabled)
294 | {
295 | control.Invoke((MethodInvoker)delegate { control.Enabled = enable; });
296 | controller.OnEnableChange(control, new EventArgs());
297 | }
298 | break;
299 | }
300 | case GuiEventType.MessageBox:
301 | {
302 | if (lparam == 1)
303 | control.Enabled = false;
304 | string[] nodes = sparam.Split('|');
305 | MessageBoxButtons buttons;
306 | if (dparam == 0.0)
307 | buttons = MessageBoxButtons.OK;
308 | else
309 | buttons = (MessageBoxButtons)(int)dparam;
310 | if (nodes.Length == 1)
311 | MessageBox.Show(sparam, sparam, buttons);
312 | else if (nodes.Length == 2)
313 | {
314 | var icon = ParseIcon(nodes[0]);
315 | if(icon == MessageBoxIcon.None)
316 | MessageBox.Show(nodes[0], nodes[1], buttons);
317 | else
318 | MessageBox.Show(nodes[1], nodes[1], buttons, icon);
319 | }
320 | else
321 | {
322 | var icon = ParseIcon(nodes[0]);
323 | MessageBox.Show(nodes[1], nodes[2], buttons, icon);
324 | }
325 | control.Enabled = true;
326 | break;
327 | }
328 | case GuiEventType.AddItem:
329 | if (control.GetType() != typeof(ComboBox))
330 | {
331 | SendExceptionEvent(new Exception("Element " + control.Name + " doesn't support 'Add Item' event"));
332 | break;
333 | }
334 | ComboBox box = (ComboBox)control;
335 | box.Items.Add(sparam);
336 | break;
337 |
338 | }
339 | }
340 | }
341 | catch (Exception ex)
342 | {
343 | SendExceptionEvent(ex);
344 | }
345 | }
346 | ///
347 | /// Parse Icon
348 | ///
349 | ///
350 | ///
351 | private static MessageBoxIcon ParseIcon(string text)
352 | {
353 | if (text == "i" || text == "Info")
354 | return MessageBoxIcon.Information;
355 | else if (text == "?" || text == "Question")
356 | return MessageBoxIcon.Question;
357 | else if (text == "!!!" || text == "Error")
358 | return MessageBoxIcon.Error;
359 | else if (text == "!" || text == "Warning")
360 | return MessageBoxIcon.Warning;
361 | return MessageBoxIcon.None;
362 | }
363 | ///
364 | /// Get event
365 | ///
366 | /// Number of event
367 | /// element name
368 | /// Event type
369 | /// long value
370 | /// double value
371 | /// string value
372 | public static void GetEvent(int event_n, ref string el_name, ref int id, ref long lparam, ref double dparam, ref string sparam)
373 | {
374 | GuiEvent e = m_global_events[event_n];
375 | el_name = e.el_name;
376 | id = (int)e.id;
377 | lparam = e.lparam;
378 | dparam = e.dparam;
379 | sparam = e.sparam;
380 | }
381 | ///
382 | ///
383 | ///
384 | ///
385 | public static int EventsTotal()
386 | {
387 | return m_global_events.Count;
388 | }
389 | #endregion
390 | }
391 | ///
392 | /// System Converter MetaTrader - C#
393 | ///
394 | public static class MtConverter
395 | {
396 | ///
397 | /// Convert C# DateTime format to MQL (POSIX) DateTime format.
398 | ///
399 | ///
400 | ///
401 | public static long ToMqlDateTime(DateTime date_time)
402 | {
403 | DateTime tiks_1970 = new DateTime(1970, 01, 01);
404 | if (date_time < tiks_1970)
405 | return 0;
406 | TimeSpan time_delta = date_time - tiks_1970;
407 | return (long)Math.Floor(time_delta.TotalSeconds);
408 | }
409 | ///
410 | /// Convert MQL (Posix) time format to sharp DateTime value.
411 | ///
412 | /// MQL datetime as tiks
413 | ///
414 | public static DateTime ToSharpDateTime(long mql_time)
415 | {
416 | DateTime tiks_1970 = new DateTime(1970, 01, 01);
417 | if (mql_time <= 0 || mql_time > int.MaxValue)
418 | return tiks_1970;
419 | TimeSpan time_delta = new TimeSpan(0, 0, (int)mql_time);
420 | DateTime sharp_time = tiks_1970 + time_delta;
421 | return sharp_time;
422 | }
423 |
424 | public static double DecimalMax()
425 | {
426 | return (double)decimal.MaxValue;
427 | }
428 | }
429 | }
430 |
--------------------------------------------------------------------------------
/MtGuiController/MtGuiController.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {C55DF26C-CE58-4E23-A6C5-8E2AD1D1F7B2}
8 | Library
9 | Properties
10 | MtGuiController
11 | MtGuiController
12 | v4.6.1
13 | 512
14 |
15 |
16 | true
17 | full
18 | false
19 | bin\Debug\
20 | DEBUG;TRACE
21 | prompt
22 | 4
23 |
24 |
25 | pdbonly
26 | true
27 | bin\Release\
28 | TRACE
29 | prompt
30 | 4
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
--------------------------------------------------------------------------------
/MtGuiController/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("MtGuiController")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("MtGuiController")]
13 | [assembly: AssemblyCopyright("Copyright © 2019")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("c55df26c-ce58-4e23-a6c5-8e2ad1d1f7b2")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
37 |
--------------------------------------------------------------------------------