SECI  1
 All Classes Namespaces Files Functions Variables Enumerations Enumerator Properties Events
ViHost.cs
Go to the documentation of this file.
1 using System;
2 using System.Collections.Generic;
3 using System.ComponentModel;
4 using System.Drawing;
5 using System.Data;
6 using System.Linq;
7 using System.Text;
8 using System.Windows.Forms;
9 using System.Diagnostics;
10 using System.Runtime.InteropServices;
11 
12 namespace SeciControls
13 {
23  public partial class ViHost : UserControl
24  {
25  Dictionary<string, TitleHandleTuple> _viNames = new Dictionary<string, TitleHandleTuple>();
26  Dictionary<string, string> _formNames = new Dictionary<string, string>();
27  public List<string> ViNames { get { return _viNames.Keys.ToList<String>(); } }
28 
29  private Boolean _visible = false;
30  private Boolean _isFirstTime = true;
31  BackgroundWorker _worker = new BackgroundWorker();
32  private delegate void UpdateGuiDelegate();
33 
34  public ViHost()
35  {
37  _worker.DoWork += new DoWorkEventHandler(_worker_DoWork);
38  _worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(_worker_RunWorkerCompleted);
39  }
40 
47  public void AddVI(String filename, int x, int y)
48  {
49  if (_viNames.ContainsKey(filename))
50  {
51  _viNames.Remove(filename);
52  }
53 
54  Seci.Managers.LabViewMgr.ShowVI(filename);
55 
56  //Get the title of the frontpanel (needed for finding the window handle)
57  Seci.Managers.LabViewMgr.UpdateFrontPanelTitle(filename);
58 
59  //Give the VI time to load
60  System.Threading.Thread.Sleep(500);
61 
62  //Find the handle
63  TitleHandleTuple viHandle = findViHandle(filename);
64 
65  if (viHandle != null)
66  {
67  //Capture the VI window
68  WinApi.SetParent(viHandle.Handle, this.panel1.Handle);
69 
70  //Force the VI to redraw itself
71  repaintVi(filename);
72 
73  //Move the VI to the required position
74  positionVi(filename, x, y);
75 
76  _viNames.Add(filename, viHandle);
77  }
78  }
79 
80  public void RemoveVI(String filename)
81  {
82  IntPtr viHandle = IntPtr.Zero;
83 
84  viHandle = _viNames[filename].Handle;
85 
86  //Free the VI from the MDI
87  WinApi.SetParent(viHandle, IntPtr.Zero);
88 
89  Seci.Managers.LabViewMgr.SetVisibilityToDefault(filename);
90 
91  _viNames.Remove(filename);
92 
93  if (_viNames.Count == 0)
94  {
95  timer1.Stop();
96  }
97  }
98 
99  public void RemoveAllVIs()
100  {
101  foreach (String name in ViNames)
102  {
103  RemoveVI(name);
104  }
105  }
106 
107  private static TitleHandleTuple findViHandle(String viName)
108  {
109  String viTitle = Seci.Managers.LabViewMgr.GetFrontPanelTitle(viName);
110 
111  return getHandle(viTitle);
112  }
113 
119  private static TitleHandleTuple getHandle(String windowTitle)
120  {
121  IntPtr viHandle = WinApi.FindWindow(null, windowTitle);
122 
123  if (viHandle == IntPtr.Zero)
124  {
125  //Try adding "Front Panel" to windowTitle
126  windowTitle += " Front Panel";
127  viHandle = WinApi.FindWindow(null, windowTitle);
128  }
129 
130  if (viHandle == IntPtr.Zero)
131  {
132  windowTitle += " *";
133  viHandle = WinApi.FindWindow(null, windowTitle);
134  }
135 
136  if (viHandle != IntPtr.Zero)
137  {
138  return new TitleHandleTuple(windowTitle.Trim(), viHandle);
139  }
140 
141  return null;
142  }
143 
144  private void repaintVi(String filename)
145  {
146  Seci.Managers.LabViewMgr.MinimiseVI(filename);
147  Seci.Managers.LabViewMgr.RestoreVI(filename);
148  }
149 
150  private void positionVi(String filename, int x, int y)
151  {
152  Seci.Managers.LabViewMgr.RestoreVI(filename);
153  Seci.Managers.LabViewMgr.SetFrontPanelBounds(filename, new int[] { x, y });
154  }
155 
156  private void bringViToFront(String filename)
157  {
158  Seci.Managers.LabViewMgr.ShowVI(filename);
159  }
160 
161  public void CascadeVis()
162  {
163  int count = 0;
164 
165  //Move the scrollbars back to their start position
166  this.panel1.HorizontalScroll.Value = 0;
167  this.panel1.VerticalScroll.Value = 0;
168 
169  for (int i = 0; i < ViNames.Count; ++i)
170  {
171  if (!Seci.Managers.LabViewMgr.IsVIHidden(ViNames[i]))
172  {
173  positionVi(ViNames[i], 40 * count, 40 * count);
175  ++count;
176  }
177  }
178  }
179 
180  private void cascadeVIsToolStripMenuItem_Click(object sender, EventArgs e)
181  {
182  CascadeVis();
183  }
184 
190  {
191  //updateHandles();
192  foreach (String name in ViNames)
193  {
194  if (Seci.Managers.LabViewMgr.DoesVIExist(name))
195  {
196  int[] bounds = Seci.Managers.ConfigurationMgr.GetConfigPanelPosition(name, false);
197 
198  if (bounds != null && bounds.Length == 2)
199  {
200  //DO WE NEED THIS LOOP?
201  while (true)
202  {
203  positionVi(name, bounds[0], bounds[1]);
204 
205  WinApi.Rect viRect;
206  int x;
207  int y;
208  getVIPosition(name, out viRect, out x, out y);
209 
210  if (x - 1 == bounds[0] && y - 1 == bounds[1]) break;
211  }
212  }
213  }
214  }
215  }
216 
223  private void updateHandles()
224  {
225  foreach (String name in ViNames)
226  {
227  try
228  {
229  //If the VI window is closed for any reason then we need to skip
230  //it, otherwise Seci will try to use all 100% of the processor!
231  if (Seci.Managers.LabViewMgr.DoesVIExist(name) && !Seci.Managers.LabViewMgr.IsVIHidden(name))
232  {
233  int length = WinApi.GetWindowTextLength(_viNames[name].Handle.ToInt32()) + 1;
234  StringBuilder title = new StringBuilder(length);
235  WinApi.GetWindowText(_viNames[name].Handle.ToInt32(), title, length);
236 
237  //If the title has changed then it is likely the handle has changed
238  //So find the new handle...
239  if (title.ToString().Trim() != _viNames[name].Title || _viNames[name].Handle == IntPtr.Zero)
240  {
241  TitleHandleTuple viHandle = findViHandle(name);
242 
243  if (viHandle != null)
244  {
245  WinApi.SetParent(viHandle.Handle, this.panel1.Handle);
246  _viNames[name].Handle = viHandle.Handle;
247  _viNames[name].Title = viHandle.Title.Trim(); //title.ToString().Trim();
248 
249  //Get the previous position as the most recent position may be wrong
250  int[] bounds = Seci.Managers.ConfigurationMgr.GetConfigPanelPosition(name, true);
251  if (bounds != null)
252  {
253  positionVi(name, bounds[0] - 1, bounds[1] - 1);
254  }
255  else
256  {
257  positionVi(name, 0, 0);
258  }
259  }
260  }
261  }
262  }
263  catch
264  {
265  }
266  }
267  }
268 
274  private void timer1_Tick(object sender, EventArgs e)
275  {
276  try
277  {
278  if (!_worker.IsBusy)
279  {
280  if (this.Handle != null)
281  {
282  _worker.RunWorkerAsync();
283  }
284  }
285  }
286  catch (Exception err)
287  {
288  }
289  }
290 
291  void _worker_DoWork(object sender, DoWorkEventArgs e)
292  {
293  timer1.Stop();
294 
295  if (this.InvokeRequired)
296  {
297  this.Invoke(new UpdateGuiDelegate(work), null);
298  }
299  }
300 
301  void _worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
302  {
303  timer1.Start();
304  }
305 
306  private void work()
307  {
308  int Xmax = 0;
309  int Ymax = 0;
310 
311  //Here we go through all the VIs and work out the maximum x and y positions of the VI.
312  //The size marker is moved to this position and the MDI will respond to this,
313  //for example: if the marker is off the MDI then the MDI will have scroll bars.
314  foreach (string vi in ViNames)
315  {
316  try
317  {
318  if (Seci.Managers.LabViewMgr.DoesVIExist(vi))
319  {
320  if (!Seci.Managers.LabViewMgr.IsVIHidden(vi))
321  {
322  WinApi.Rect viRect;
323  int x;
324  int y;
325 
326  //Get the current position of the VI
327  getVIPosition(vi, out viRect, out x, out y);
328 
329  //Need to write the position back for saving.
330  //When a VI is started the position will change temporary
331  //we don't want to update the value in that case, when this
332  //happens the y will go to a unlikely -ve value
333  if (y >= -30 && _visible)
334  {
335  Seci.Managers.ConfigurationMgr.SetConfigPanelPosition(vi, x, y);
336  }
337 
338  int adjustedX = x + viRect.Width - viRect.X;
339  int adjustedY = y + viRect.Height - viRect.Y;
340 
341  if (adjustedX > Xmax)
342  {
343  Xmax = adjustedX;
344  }
345 
346  if (adjustedY > Ymax)
347  {
348  Ymax = adjustedY;
349  }
350  }
351  }
352  }
353  catch
354  {
355  }
356  }
357 
358  updateHandles();
359 
360  //Move the marker to the correct position
361  sizeMarker.Location = new Point(Xmax, Ymax);
362  }
363 
364  private void getVIPosition(string vi, out WinApi.Rect viRect, out int x, out int y)
365  {
366  viRect = new WinApi.Rect();
367  WinApi.GetWindowRect(_viNames[vi].Handle, out viRect);
368 
369  WinApi.Rect thisRect = new WinApi.Rect();
370  WinApi.GetWindowRect(this.Handle, out thisRect);
371 
372  x = viRect.X - thisRect.X;
373  y = viRect.Y - thisRect.Y;
374  }
375 
376  private class TitleHandleTuple
377  {
378  public string Title;
379  public IntPtr Handle;
380 
381  public TitleHandleTuple(String title, IntPtr handle)
382  {
383  Title = title;
384  Handle = handle;
385  }
386  }
387 
388  public void StartTimer(int interval)
389  {
390  timer1.Interval = interval;
391  timer1.Start();
392  }
393 
394  public void SetVisible(Boolean visible)
395  {
396  //A crude hack to get round the problem where the VI is moved to the
397  //wrong position the first time the tab is selected
398  if (_isFirstTime)
399  {
401  _isFirstTime = false;
402  }
403 
404  _visible = visible;
405 
406  //If the user has "accidently" closed a VI then reopen it next time the tab is opened
407  if (visible == true)
408  {
409  foreach (string vi in ViNames)
410  {
411  if (Seci.Managers.LabViewMgr.IsVIHidden(vi))
412  {
413  Seci.Managers.LabViewMgr.ShowVI(vi);
414  }
415  }
416  }
417  }
418  }
419 }
void SetVisible(Boolean visible)
Definition: ViHost.cs:394
void CascadeVis()
Definition: ViHost.cs:161
void cascadeVIsToolStripMenuItem_Click(object sender, EventArgs e)
Definition: ViHost.cs:180
void RemoveAllVIs()
Definition: ViHost.cs:99
void updateHandles()
Unfortunately when a VI is started or stopped its window handle changes, so we have to update the sto...
Definition: ViHost.cs:223
BackgroundWorker _worker
Definition: ViHost.cs:31
void timer1_Tick(object sender, EventArgs e)
This method is called when the timer object &quot;ticks.&quot;
Definition: ViHost.cs:274
Dictionary< string, TitleHandleTuple > _viNames
Definition: ViHost.cs:25
void StartTimer(int interval)
Definition: ViHost.cs:388
void InitializeComponent()
Required method for Designer support - do not modify the contents of this method with the code editor...
void RemoveVI(String filename)
Definition: ViHost.cs:80
void _worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
Definition: ViHost.cs:301
void bringViToFront(String filename)
Definition: ViHost.cs:156
static TitleHandleTuple getHandle(String windowTitle)
Get the window handle of the VI based on the window&#39;s title.
Definition: ViHost.cs:119
void repaintVi(String filename)
Definition: ViHost.cs:144
List< string > ViNames
Definition: ViHost.cs:27
static TitleHandleTuple findViHandle(String viName)
Definition: ViHost.cs:107
void moveVisToConfigPositions()
When the configuration is loaded it is necessary to move the VIs to the positions saved in the config...
Definition: ViHost.cs:189
void positionVi(String filename, int x, int y)
Definition: ViHost.cs:150
Boolean _isFirstTime
Definition: ViHost.cs:30
void getVIPosition(string vi, out WinApi.Rect viRect, out int x, out int y)
Definition: ViHost.cs:364
Boolean _visible
Definition: ViHost.cs:29
void _worker_DoWork(object sender, DoWorkEventArgs e)
Definition: ViHost.cs:291
delegate void UpdateGuiDelegate()
void AddVI(String filename, int x, int y)
This method captures the VI and inserts it into the MDI using the WinAPI.
Definition: ViHost.cs:47
Dictionary< string, string > _formNames
Definition: ViHost.cs:26
TitleHandleTuple(String title, IntPtr handle)
Definition: ViHost.cs:381