diff --git a/DoctorApp/App.xaml b/DoctorApp/App.xaml
index 1fcbd5c..aac18d8 100644
--- a/DoctorApp/App.xaml
+++ b/DoctorApp/App.xaml
@@ -6,17 +6,27 @@
xmlns:views="clr-namespace:DoctorApp.Views"
StartupUri="Views/MainWindow.xaml">
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/DoctorApp/Utils/Client.cs b/DoctorApp/Utils/Client.cs
index da77925..26a87fb 100644
--- a/DoctorApp/Utils/Client.cs
+++ b/DoctorApp/Utils/Client.cs
@@ -57,6 +57,9 @@ namespace DoctorApp.Utils
/// the result of the async read
private void OnRead(IAsyncResult ar)
{
+ if (ar == null || (!ar.IsCompleted) || (!this.stream.CanRead))
+ return;
+
int receivedBytes = this.stream.EndRead(ar);
if (totalBufferReceived + receivedBytes > 1024)
@@ -91,7 +94,7 @@ namespace DoctorApp.Utils
Debug.WriteLine("Username and password correct!");
this.LoginViewModel.setLoginStatus(true);
this.connected = true;
-
+
}
else
{
@@ -192,7 +195,7 @@ namespace DoctorApp.Utils
/// the message
public void Bike(byte[] bytes)
{
-
+
if (!sessionRunning)
{
return;
@@ -202,18 +205,18 @@ namespace DoctorApp.Utils
throw new ArgumentNullException("no bytes");
}
byte[] message = DataParser.GetRawDataMessage(bytes);
-
- /* switch (bytes[0])
- {
- case 0x10:
+ /* switch (bytes[0])
+ {
- if (canSendToEngine) engineConnection.BikeSpeed = (bytes[4] | (bytes[5] << 8)) * 0.01f;
- break;
- case 0x19:
- if (canSendToEngine) engineConnection.BikePower = (bytes[5]) | (bytes[6] & 0b00001111) << 8;
- break;
- }*/
+ case 0x10:
+
+ if (canSendToEngine) engineConnection.BikeSpeed = (bytes[4] | (bytes[5] << 8)) * 0.01f;
+ break;
+ case 0x19:
+ if (canSendToEngine) engineConnection.BikePower = (bytes[5]) | (bytes[6] & 0b00001111) << 8;
+ break;
+ }*/
this.stream.BeginWrite(message, 0, message.Length, new AsyncCallback(OnWrite), null);
@@ -234,7 +237,7 @@ namespace DoctorApp.Utils
///
public void tryLogin(string username, string password)
{
-
+
string hashPassword = Util.Hasher.HashString(password);
byte[] message = DataParser.getJsonMessage(DataParser.LoginAsDoctor(username, hashPassword));
@@ -266,5 +269,13 @@ namespace DoctorApp.Utils
{
this.ClientInfoViewModel = clientInfoViewModel;
}
+
+ public void Dispose()
+ {
+ Debug.WriteLine("client dispose called");
+ this.stream.Dispose();
+ this.client.Dispose();
+ this.handler?.stop();
+ }
}
}
diff --git a/DoctorApp/ViewModels/MainWindowViewModel.cs b/DoctorApp/ViewModels/MainWindowViewModel.cs
index fa7a982..a15f026 100644
--- a/DoctorApp/ViewModels/MainWindowViewModel.cs
+++ b/DoctorApp/ViewModels/MainWindowViewModel.cs
@@ -1,26 +1,134 @@
-using DoctorApp.Models;
-using DoctorApp.Utils;
-using System;
-using System.Collections.Generic;
-using System.Text;
+using GalaSoft.MvvmLight.Command;
+using System.Diagnostics;
using Util;
+using System.Windows;
+using System.Windows.Input;
+using DoctorApp.Models;
+using DoctorApp.Utils;
+using Util.MagicCode;
namespace DoctorApp.ViewModels
{
class MainWindowViewModel : ObservableObject
{
+ #region private members
+
+ private Window mWindow;
+
+ private int mOuterMarginSize = 10;
+ private int mWindowRadius = 10;
+
+ #endregion
+
+ #region commands
+
+ public ICommand MinimizeCommand { get; set; }
+
+ public ICommand MaximizeCommand { get; set; }
+
+ public ICommand CloseCommand { get; set; }
+
+ public ICommand MenuCommand { get; set; }
+
+ #endregion
+
+ #region public properties
public Info InfoModel { get; set; }
public ObservableObject SelectedViewModel { get; set; }
+
public Client client { get; }
- public MainWindowViewModel(Client client)
+ ///
+ /// size of the resize border around the window
+ ///
+
+ public double MinimumWidth { get; set; } = 250;
+
+ public double MinimumHeight { get; set; } = 250;
+
+
+
+ public int ResizeBorder { get; set; } = 6;
+
+ public Thickness ResizeBorderThickness { get { return new Thickness(ResizeBorder + OuterMarginSize); } }
+
+ public Thickness InnerContentPadding { get { return new Thickness(ResizeBorder); } }
+
+
+ public Thickness OuterMarginThickness { get { return new Thickness(OuterMarginSize); } }
+
+ public CornerRadius WindowCornerRadius { get { return new CornerRadius(WindowRadius); } }
+
+ public int OuterMarginSize
{
+ get
+ {
+ return mWindow.WindowState == WindowState.Maximized ? 0 : mOuterMarginSize;
+ }
+ set
+ {
+ mOuterMarginSize = value;
+ }
+ }
+
+ public int WindowRadius
+ {
+ get
+ {
+ return mWindow.WindowState == WindowState.Maximized ? 0 : mWindowRadius;
+ }
+ set
+ {
+ mWindowRadius = value;
+ }
+ }
+
+ public int TitleHeight { get; set; } = 42;
+
+ public GridLength TitleHeightGridLength { get { return new GridLength(TitleHeight + ResizeBorder); } }
+
+ #endregion
+
+ public MainWindowViewModel(Window window, Client client)
+ {
+ this.mWindow = window;
+
+ this.mWindow.StateChanged += (sender, e) =>
+ {
+ OnPropertyChanged(nameof(ResizeBorderThickness));
+ OnPropertyChanged(nameof(OuterMarginThickness));
+ OnPropertyChanged(nameof(WindowCornerRadius));
+ OnPropertyChanged(nameof(OuterMarginSize));
+ OnPropertyChanged(nameof(WindowRadius));
+ };
+
this.InfoModel = new Info();
this.client = client;
LoginViewModel loginViewModel = new LoginViewModel(this);
SelectedViewModel = loginViewModel;
this.client.SetLoginViewModel(loginViewModel);
+
+ this.MinimizeCommand = new RelayCommand(() => this.mWindow.WindowState = WindowState.Minimized);
+ this.MaximizeCommand = new RelayCommand(() => this.mWindow.WindowState ^= WindowState.Maximized);
+ this.CloseCommand = new RelayCommand(() => this.mWindow.Close());
+ this.MenuCommand = new RelayCommand(() => SystemCommands.ShowSystemMenu(this.mWindow, GetMousePosition()));
+
+ var resizer = new WindowResizer(this.mWindow);
+
+ this.mWindow.Closed += (sender, e) => this.client.Dispose();
}
+
+
+ #region helper
+
+ private Point GetMousePosition()
+ {
+ Debug.WriteLine("getmousePosition called");
+ var p = Mouse.GetPosition(this.mWindow);
+ return new Point(p.X + this.mWindow.Left, p.Y + this.mWindow.Top);
+ }
+
+ #endregion
}
}
diff --git a/DoctorApp/Views/MainWindow.xaml b/DoctorApp/Views/MainWindow.xaml
index 5535982..024aa68 100644
--- a/DoctorApp/Views/MainWindow.xaml
+++ b/DoctorApp/Views/MainWindow.xaml
@@ -5,10 +5,113 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:DoctorApp"
mc:Ignorable="d"
- Title="MainWindow" Height="450" Width="800"
- WindowState="Maximized">
+ Title="MainWindow" Height="450" Width="800">
+
+
+
+
+
+
+
+
-
+
diff --git a/DoctorApp/Views/MainWindow.xaml.cs b/DoctorApp/Views/MainWindow.xaml.cs
index 19e287d..d38e5c1 100644
--- a/DoctorApp/Views/MainWindow.xaml.cs
+++ b/DoctorApp/Views/MainWindow.xaml.cs
@@ -26,7 +26,7 @@ namespace DoctorApp
{
Client client = new Client();
InitializeComponent();
- DataContext = new MainWindowViewModel(client);
+ DataContext = new MainWindowViewModel(this, client);
}
}
}
diff --git a/Hashing/Hashing.projitems b/Hashing/Hashing.projitems
index 662f597..c169d90 100644
--- a/Hashing/Hashing.projitems
+++ b/Hashing/Hashing.projitems
@@ -11,6 +11,7 @@
+
diff --git a/Hashing/MagicCode/WindowResizer.cs b/Hashing/MagicCode/WindowResizer.cs
new file mode 100644
index 0000000..428ca40
--- /dev/null
+++ b/Hashing/MagicCode/WindowResizer.cs
@@ -0,0 +1,212 @@
+using System;
+using System.Runtime.InteropServices;
+using System.Windows;
+using System.Windows.Interop;
+
+namespace Util.MagicCode
+{
+ ///
+ /// Fixes the issue with Windows of Style covering the taskbar
+ ///
+ public class WindowResizer
+ {
+ #region Private Members
+
+ ///
+ /// The window to handle the resizing for
+ ///
+ private Window mWindow;
+
+ #endregion
+
+ #region Dll Imports
+
+ [DllImport("user32.dll")]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ static extern bool GetCursorPos(out POINT lpPoint);
+
+ [DllImport("user32.dll")]
+ static extern bool GetMonitorInfo(IntPtr hMonitor, MONITORINFO lpmi);
+
+ [DllImport("user32.dll", SetLastError = true)]
+ static extern IntPtr MonitorFromPoint(POINT pt, MonitorOptions dwFlags);
+
+ #endregion
+
+ #region Constructor
+
+ ///
+ /// Default constructor
+ ///
+ /// The window to monitor and correctly maximize
+ /// The callback for the host to adjust the maximum available size if needed
+ public WindowResizer(Window window)
+ {
+ mWindow = window;
+
+ // Listen out for source initialized to setup
+ mWindow.SourceInitialized += Window_SourceInitialized;
+ }
+
+ #endregion
+
+ #region Initialize
+
+ ///
+ /// Initialize and hook into the windows message pump
+ ///
+ ///
+ ///
+ private void Window_SourceInitialized(object sender, System.EventArgs e)
+ {
+ // Get the handle of this window
+ var handle = (new WindowInteropHelper(mWindow)).Handle;
+ var handleSource = HwndSource.FromHwnd(handle);
+
+ // If not found, end
+ if (handleSource == null)
+ return;
+
+ // Hook into it's Windows messages
+ handleSource.AddHook(WindowProc);
+ }
+
+ #endregion
+
+ #region Windows Proc
+
+ ///
+ /// Listens out for all windows messages for this window
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ private IntPtr WindowProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
+ {
+ switch (msg)
+ {
+ // Handle the GetMinMaxInfo of the Window
+ case 0x0024:/* WM_GETMINMAXINFO */
+ WmGetMinMaxInfo(hwnd, lParam);
+ handled = true;
+ break;
+ }
+
+ return (IntPtr)0;
+ }
+
+ #endregion
+
+ ///
+ /// Get the min/max window size for this window
+ /// Correctly accounting for the taskbar size and position
+ ///
+ ///
+ ///
+ private void WmGetMinMaxInfo(System.IntPtr hwnd, System.IntPtr lParam)
+ {
+ POINT lMousePosition;
+ GetCursorPos(out lMousePosition);
+
+ IntPtr lPrimaryScreen = MonitorFromPoint(new POINT(0, 0), MonitorOptions.MONITOR_DEFAULTTOPRIMARY);
+ MONITORINFO lPrimaryScreenInfo = new MONITORINFO();
+ if (GetMonitorInfo(lPrimaryScreen, lPrimaryScreenInfo) == false)
+ {
+ return;
+ }
+
+ IntPtr lCurrentScreen = MonitorFromPoint(lMousePosition, MonitorOptions.MONITOR_DEFAULTTONEAREST);
+
+ MINMAXINFO lMmi = (MINMAXINFO)Marshal.PtrToStructure(lParam, typeof(MINMAXINFO));
+
+ if (lPrimaryScreen.Equals(lCurrentScreen) == true)
+ {
+ lMmi.ptMaxPosition.X = lPrimaryScreenInfo.rcWork.Left;
+ lMmi.ptMaxPosition.Y = lPrimaryScreenInfo.rcWork.Top;
+ lMmi.ptMaxSize.X = lPrimaryScreenInfo.rcWork.Right - lPrimaryScreenInfo.rcWork.Left;
+ lMmi.ptMaxSize.Y = lPrimaryScreenInfo.rcWork.Bottom - lPrimaryScreenInfo.rcWork.Top;
+ }
+ else
+ {
+ lMmi.ptMaxPosition.X = lPrimaryScreenInfo.rcMonitor.Left;
+ lMmi.ptMaxPosition.Y = lPrimaryScreenInfo.rcMonitor.Top;
+ lMmi.ptMaxSize.X = lPrimaryScreenInfo.rcMonitor.Right - lPrimaryScreenInfo.rcMonitor.Left;
+ lMmi.ptMaxSize.Y = lPrimaryScreenInfo.rcMonitor.Bottom - lPrimaryScreenInfo.rcMonitor.Top;
+ }
+
+ // Now we have the max size, allow the host to tweak as needed
+ Marshal.StructureToPtr(lMmi, lParam, true);
+ }
+ }
+
+ #region Dll Helper Structures
+
+ enum MonitorOptions : uint
+ {
+ MONITOR_DEFAULTTONULL = 0x00000000,
+ MONITOR_DEFAULTTOPRIMARY = 0x00000001,
+ MONITOR_DEFAULTTONEAREST = 0x00000002
+ }
+
+
+ [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
+ public class MONITORINFO
+ {
+ public int cbSize = Marshal.SizeOf(typeof(MONITORINFO));
+ public Rectangle rcMonitor = new Rectangle();
+ public Rectangle rcWork = new Rectangle();
+ public int dwFlags = 0;
+ }
+
+
+ [StructLayout(LayoutKind.Sequential)]
+ public struct Rectangle
+ {
+ public int Left, Top, Right, Bottom;
+
+ public Rectangle(int left, int top, int right, int bottom)
+ {
+ this.Left = left;
+ this.Top = top;
+ this.Right = right;
+ this.Bottom = bottom;
+ }
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ public struct MINMAXINFO
+ {
+ public POINT ptReserved;
+ public POINT ptMaxSize;
+ public POINT ptMaxPosition;
+ public POINT ptMinTrackSize;
+ public POINT ptMaxTrackSize;
+ };
+
+ [StructLayout(LayoutKind.Sequential)]
+ public struct POINT
+ {
+ ///
+ /// x coordinate of point.
+ ///
+ public int X;
+ ///
+ /// y coordinate of point.
+ ///
+ public int Y;
+
+ ///
+ /// Construct a point of coordinates (x,y).
+ ///
+ public POINT(int x, int y)
+ {
+ this.X = x;
+ this.Y = y;
+ }
+ }
+
+ #endregion
+}
\ No newline at end of file