Compare commits
39 Commits
dotnet5
...
feat/simpl
| Author | SHA1 | Date | |
|---|---|---|---|
| 3ae6e827a5 | |||
| e142513083 | |||
| bc5aec6da8 | |||
| 9100057ae2 | |||
| 67be15157c | |||
| dccd845a3d | |||
| 8fcb6a42d3 | |||
| ef85aea1c5 | |||
| a42ea8d0f3 | |||
| 4393c59ab7 | |||
| 1b0b0e22c2 | |||
| db6fb95dad | |||
| 3c49701873 | |||
| 8dbd0a764e | |||
| 6aa00b360b | |||
| 5002077d9a | |||
| e7e83b9597 | |||
| 8c74ca9553 | |||
|
|
1f12af2a68 | ||
|
|
a7de6c7bd6 | ||
|
|
daf0e8f4a3 | ||
|
|
4ca12b19da | ||
|
|
2415feaca3 | ||
|
|
ad4e8b7e41 | ||
|
|
88524047ff | ||
| 675dd6594a | |||
| 756eb88d26 | |||
| fe2bb8efa1 | |||
| 3376fecd12 | |||
| 6871d6952f | |||
| 45696f2d19 | |||
| 7d7cb0eee0 | |||
| 4480c00cb7 | |||
| f120e7a374 | |||
| 27b348d10a | |||
| ae76557adf | |||
|
|
6a65019bfa | ||
| 8fd06a729c | |||
| 191b2fc319 |
@@ -83,4 +83,7 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Remove="SimpleHistory\Enums.vb" />
|
<Compile Remove="SimpleHistory\Enums.vb" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\Pilz.Cryptography\Pilz.Cryptography.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
@@ -17,6 +17,26 @@ Namespace SimpleHistory
|
|||||||
End Get
|
End Get
|
||||||
End Property
|
End Property
|
||||||
|
|
||||||
|
''' <summary>
|
||||||
|
''' Gets the current stack of all past HistoryPoints that are used for the Undo function.
|
||||||
|
''' </summary>
|
||||||
|
''' <returns></returns>
|
||||||
|
Public ReadOnly Property PastHistoryPoints As HistoryPoint()
|
||||||
|
Get
|
||||||
|
Return stackPast.ToArray
|
||||||
|
End Get
|
||||||
|
End Property
|
||||||
|
|
||||||
|
''' <summary>
|
||||||
|
''' Gets the current stack of all future HistoryPoints that are used for the Redo function.
|
||||||
|
''' </summary>
|
||||||
|
''' <returns></returns>
|
||||||
|
Public ReadOnly Property FutureHistoryPoints As HistoryPoint()
|
||||||
|
Get
|
||||||
|
Return stackFuture.ToArray
|
||||||
|
End Get
|
||||||
|
End Property
|
||||||
|
|
||||||
''' <summary>
|
''' <summary>
|
||||||
''' Checks if the History has past changes.
|
''' Checks if the History has past changes.
|
||||||
''' </summary>
|
''' </summary>
|
||||||
|
|||||||
8
Pilz.Collections/SimpleSorting/ElementSortingPosition.vb
Normal file
8
Pilz.Collections/SimpleSorting/ElementSortingPosition.vb
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
Namespace SimpleSorting
|
||||||
|
|
||||||
|
Public Enum ElementSortingPosition
|
||||||
|
Before
|
||||||
|
After
|
||||||
|
End Enum
|
||||||
|
|
||||||
|
End Namespace
|
||||||
10
Pilz.Collections/SimpleSorting/ISimpleSortingHost.vb
Normal file
10
Pilz.Collections/SimpleSorting/ISimpleSortingHost.vb
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
Namespace SimpleSorting
|
||||||
|
|
||||||
|
Public Interface ISimpleSortingHost
|
||||||
|
Inherits IList
|
||||||
|
|
||||||
|
Event OnInsert(sender As Object, e As SimpleSortingHostEventArgs)
|
||||||
|
Event OnRemove(sender As Object, e As SimpleSortingHostEventArgs)
|
||||||
|
End Interface
|
||||||
|
|
||||||
|
End Namespace
|
||||||
13
Pilz.Collections/SimpleSorting/SimpleSortingEntry.vb
Normal file
13
Pilz.Collections/SimpleSorting/SimpleSortingEntry.vb
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
Imports Pilz.Cryptography
|
||||||
|
|
||||||
|
Namespace SimpleSorting
|
||||||
|
|
||||||
|
Friend Class SimpleSortingEntry
|
||||||
|
|
||||||
|
Public Property Element As UniquieID
|
||||||
|
Public Property Position As ElementSortingPosition
|
||||||
|
Public Property ReferenceElement As UniquieID
|
||||||
|
|
||||||
|
End Class
|
||||||
|
|
||||||
|
End Namespace
|
||||||
18
Pilz.Collections/SimpleSorting/SimpleSortingHostEventArgs.vb
Normal file
18
Pilz.Collections/SimpleSorting/SimpleSortingHostEventArgs.vb
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
Imports Pilz.Cryptography
|
||||||
|
|
||||||
|
Namespace SimpleSorting
|
||||||
|
|
||||||
|
Public Class SimpleSortingHostEventArgs
|
||||||
|
Inherits EventArgs
|
||||||
|
|
||||||
|
Public ReadOnly Property ElementID As UniquieID
|
||||||
|
Public ReadOnly Property ElementIndex As Integer
|
||||||
|
|
||||||
|
Public Sub New(elementID As UniquieID, elementIndex As Integer)
|
||||||
|
Me.ElementID = elementID
|
||||||
|
Me.ElementIndex = elementIndex
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
End Class
|
||||||
|
|
||||||
|
End Namespace
|
||||||
121
Pilz.Collections/SimpleSorting/SimpleSortingList.vb
Normal file
121
Pilz.Collections/SimpleSorting/SimpleSortingList.vb
Normal file
@@ -0,0 +1,121 @@
|
|||||||
|
Imports System.Runtime.InteropServices.ComTypes
|
||||||
|
|
||||||
|
Imports Newtonsoft.Json
|
||||||
|
|
||||||
|
Imports Pilz.Cryptography
|
||||||
|
|
||||||
|
Namespace SimpleSorting
|
||||||
|
|
||||||
|
''' <summary>
|
||||||
|
''' Provides some management methods for sorting a list without changing the list itself.
|
||||||
|
''' Useful if the host list can not be changed or the sorting is indipendent from the required sorting.
|
||||||
|
''' </summary>
|
||||||
|
''' <typeparam name="T">The content of the host list to sort.</typeparam>
|
||||||
|
Public Class SimpleSortingList(Of T As IUniquieIDHost)
|
||||||
|
|
||||||
|
Private ReadOnly host As ISimpleSortingHost
|
||||||
|
|
||||||
|
<JsonProperty("SortingInfo")>
|
||||||
|
Private ReadOnly sortingList As New List(Of SimpleSortingEntry)
|
||||||
|
|
||||||
|
Public Sub New(parentList As ISimpleSortingHost)
|
||||||
|
host = parentList
|
||||||
|
AddHandler host.OnInsert, AddressOf Host_OnInsert
|
||||||
|
AddHandler host.OnRemove, AddressOf Host_OnRemove
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
Protected Overrides Sub Finalize()
|
||||||
|
RemoveHandler host.OnInsert, AddressOf Host_OnInsert
|
||||||
|
RemoveHandler host.OnRemove, AddressOf Host_OnRemove
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
Private Sub Host_OnInsert(sender As Object, e As SimpleSortingHostEventArgs)
|
||||||
|
'...
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
Private Sub Host_OnRemove(sender As Object, e As SimpleSortingHostEventArgs)
|
||||||
|
'...
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
''' <summary>
|
||||||
|
''' Stores positioning infos for the given element.
|
||||||
|
''' </summary>
|
||||||
|
''' <param name="elementID"></param>
|
||||||
|
''' <param name="position"></param>
|
||||||
|
''' <param name="referenceElementID"></param>
|
||||||
|
Public Sub SetElementPosition(elementID As UniquieID, position As ElementSortingPosition, referenceElementID As UniquieID)
|
||||||
|
'...
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
''' <summary>
|
||||||
|
''' Removes the positioning infos for the given element if available.
|
||||||
|
''' </summary>
|
||||||
|
''' <param name="elementID"></param>
|
||||||
|
Public Sub RemoveElementPosition(elementID As UniquieID)
|
||||||
|
Dim infoToRemove = FindSortInfoByID(elementID)
|
||||||
|
|
||||||
|
If infoToRemove IsNot Nothing Then
|
||||||
|
sortingList.Remove(infoToRemove)
|
||||||
|
|
||||||
|
For Each info In sortingList
|
||||||
|
If info.ReferenceElement = elementID Then
|
||||||
|
info.ReferenceElement = infoToRemove.ReferenceElement
|
||||||
|
End If
|
||||||
|
Next
|
||||||
|
End If
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
''' <summary>
|
||||||
|
''' Completely removes an element from all positioning infos. If possible, elements will be assigned to nearby reference or removed completely.
|
||||||
|
''' </summary>
|
||||||
|
''' <param name="elementID"></param>
|
||||||
|
Public Sub InvalidateElement(elementID As UniquieID)
|
||||||
|
'...
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
''' <summary>
|
||||||
|
''' Creates a sorted list with all elements from the host list.
|
||||||
|
''' </summary>
|
||||||
|
''' <returns></returns>
|
||||||
|
Public Function GetSortedList() As List(Of T)
|
||||||
|
Dim list As New List(Of T)
|
||||||
|
list.AddRange(host)
|
||||||
|
|
||||||
|
For Each info In sortingList
|
||||||
|
Dim element As T = list.FirstOrDefault(Function(n) n.ID = info.Element)
|
||||||
|
Dim referenceElement As T = list.FirstOrDefault(Function(n) n.ID = info.ReferenceElement)
|
||||||
|
|
||||||
|
If element IsNot Nothing AndAlso referenceElement IsNot Nothing Then
|
||||||
|
list.Remove(element)
|
||||||
|
Dim referenceElementIndex As Integer = list.IndexOf(referenceElement)
|
||||||
|
|
||||||
|
If info.Position = ElementSortingPosition.After Then
|
||||||
|
referenceElementIndex += 1
|
||||||
|
End If
|
||||||
|
|
||||||
|
list.Insert(referenceElementIndex, element)
|
||||||
|
End If
|
||||||
|
Next
|
||||||
|
|
||||||
|
Return list
|
||||||
|
End Function
|
||||||
|
|
||||||
|
''' <summary>
|
||||||
|
''' Creates a sorted list with all elements from the host list.
|
||||||
|
''' </summary>
|
||||||
|
''' <returns></returns>
|
||||||
|
Public Function GetSortedArray() As T()
|
||||||
|
Return GetSortedList.ToArray
|
||||||
|
End Function
|
||||||
|
|
||||||
|
Private Function FindSortInfoByID(id As UniquieID) As SimpleSortingEntry
|
||||||
|
Return sortingList.FirstOrDefault(Function(n) n.Element = id)
|
||||||
|
End Function
|
||||||
|
|
||||||
|
Private Function FindSortInfoByReferenceID(id As UniquieID) As SimpleSortingEntry
|
||||||
|
Return sortingList.FirstOrDefault(Function(n) n.ReferenceElement = id)
|
||||||
|
End Function
|
||||||
|
|
||||||
|
End Class
|
||||||
|
|
||||||
|
End Namespace
|
||||||
@@ -1,253 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
|
||||||
using System.Security.Cryptography;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace Pilz.Cryptography
|
|
||||||
{
|
|
||||||
public class AESStringCrypter : ICrypter
|
|
||||||
{
|
|
||||||
public delegate void AESStringCrypterEventHandler(AESStringCrypter sender);
|
|
||||||
public delegate void AESStringCrypterErrorEventHandler(AESStringCrypter sender, Exception exception);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// This event throws if no key and no default key was found. You can now provide a key or default key (maybe depending on the given instance). If no value is provided, a default key will be created.
|
|
||||||
/// </summary>
|
|
||||||
public static event AESStringCrypterEventHandler NeedKey;
|
|
||||||
/// <summary>
|
|
||||||
/// This event throws if no IV and no default IV was found. You can now provide a IV or default IV (maybe depending on the given instance). If no value is provided, a default IV will be created.
|
|
||||||
/// </summary>
|
|
||||||
public static event AESStringCrypterEventHandler NeedIV;
|
|
||||||
public static event AESStringCrypterErrorEventHandler ErrorAtDecrypting;
|
|
||||||
public static event AESStringCrypterErrorEventHandler ErrorAtEncrypting;
|
|
||||||
|
|
||||||
private byte[] key = new byte[] { };
|
|
||||||
private byte[] iv = new byte[] { };
|
|
||||||
|
|
||||||
private static byte[] defaultKey = new byte[] { };
|
|
||||||
private static byte[] defaultIV = new byte[] { };
|
|
||||||
|
|
||||||
public Encoding Encoding { get; set; } = Encoding.Default;
|
|
||||||
public string Name { get; set; }
|
|
||||||
public object Tag { get; set; }
|
|
||||||
|
|
||||||
public string Key
|
|
||||||
{
|
|
||||||
get => Convert.ToBase64String(key);
|
|
||||||
set => key = Convert.FromBase64String(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public string IV
|
|
||||||
{
|
|
||||||
get => Convert.ToBase64String(iv);
|
|
||||||
set => iv = Convert.FromBase64String(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string DefaultKey
|
|
||||||
{
|
|
||||||
get => Convert.ToBase64String(defaultKey);
|
|
||||||
set => defaultKey = Convert.FromBase64String(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string DefaultIV
|
|
||||||
{
|
|
||||||
get => Convert.ToBase64String(defaultIV);
|
|
||||||
set => defaultIV = Convert.FromBase64String(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public AESStringCrypter()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public AESStringCrypter(string key, string iv) : this()
|
|
||||||
{
|
|
||||||
Key = key;
|
|
||||||
IV = iv;
|
|
||||||
}
|
|
||||||
|
|
||||||
public string Decrypt(string encryptedValue)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
return DecryptStringFromBytes_Aes(Convert.FromBase64String(encryptedValue), GetKey(), GetIV());
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
ErrorAtDecrypting?.Invoke(this, ex);
|
|
||||||
return string.Empty;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string Decrypt(string encryptedValue, string key, string iv)
|
|
||||||
{
|
|
||||||
var crypter = new AESStringCrypter(key, iv);
|
|
||||||
return crypter.Decrypt(encryptedValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
public string Encrypt(string plainValue)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
return Convert.ToBase64String(EncryptStringToBytes_Aes(plainValue, GetKey(), GetIV()));
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
ErrorAtEncrypting?.Invoke(this, ex);
|
|
||||||
return string.Empty;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string Encrypt(string plainValue, string key, string iv)
|
|
||||||
{
|
|
||||||
var crypter = new AESStringCrypter(key, iv);
|
|
||||||
return crypter.Encrypt(plainValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
private byte[] GetKey(bool createIfFail = false)
|
|
||||||
{
|
|
||||||
byte[] keyToUse;
|
|
||||||
|
|
||||||
if (key.Length != 0)
|
|
||||||
keyToUse = key;
|
|
||||||
else if (defaultKey.Length != 0)
|
|
||||||
keyToUse = defaultKey;
|
|
||||||
else if (createIfFail)
|
|
||||||
keyToUse = defaultKey = GenerateKeyInternal();
|
|
||||||
else
|
|
||||||
{
|
|
||||||
NeedKey?.Invoke(this);
|
|
||||||
keyToUse = GetKey(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
return keyToUse;
|
|
||||||
}
|
|
||||||
|
|
||||||
private byte[] GetIV(bool createIfFail = false)
|
|
||||||
{
|
|
||||||
byte[] ivToUse;
|
|
||||||
|
|
||||||
if (iv.Length != 0)
|
|
||||||
ivToUse = iv;
|
|
||||||
else if (defaultIV.Length != 0)
|
|
||||||
ivToUse = defaultIV;
|
|
||||||
else if (createIfFail)
|
|
||||||
ivToUse = defaultIV = GenerateIVInternal();
|
|
||||||
else
|
|
||||||
{
|
|
||||||
NeedIV?.Invoke(this);
|
|
||||||
ivToUse = GetIV(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ivToUse;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static byte[] GenerateKeyInternal()
|
|
||||||
{
|
|
||||||
var aes = Aes.Create();
|
|
||||||
var key = aes.Key;
|
|
||||||
aes.Dispose();
|
|
||||||
return key;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string GenerateKey()
|
|
||||||
{
|
|
||||||
return Convert.ToBase64String(GenerateKeyInternal());
|
|
||||||
}
|
|
||||||
|
|
||||||
private static byte[] GenerateIVInternal()
|
|
||||||
{
|
|
||||||
var aes = Aes.Create();
|
|
||||||
var iv = aes.IV;
|
|
||||||
aes.Dispose();
|
|
||||||
return iv;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string GenerateIV()
|
|
||||||
{
|
|
||||||
return Convert.ToBase64String(GenerateIVInternal());
|
|
||||||
}
|
|
||||||
|
|
||||||
private static byte[] EncryptStringToBytes_Aes(string plainText, byte[] Key, byte[] IV)
|
|
||||||
{
|
|
||||||
// Check arguments.
|
|
||||||
if (plainText == null || plainText.Length <= 0)
|
|
||||||
throw new ArgumentNullException("plainText");
|
|
||||||
if (Key == null || Key.Length <= 0)
|
|
||||||
throw new ArgumentNullException("Key");
|
|
||||||
if (IV == null || IV.Length <= 0)
|
|
||||||
throw new ArgumentNullException("IV");
|
|
||||||
byte[] encrypted;
|
|
||||||
|
|
||||||
// Create an Aes object
|
|
||||||
// with the specified key and IV.
|
|
||||||
using (Aes aesAlg = Aes.Create())
|
|
||||||
{
|
|
||||||
aesAlg.Key = Key;
|
|
||||||
aesAlg.IV = IV;
|
|
||||||
|
|
||||||
// Create an encryptor to perform the stream transform.
|
|
||||||
ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);
|
|
||||||
|
|
||||||
// Create the streams used for encryption.
|
|
||||||
using (MemoryStream msEncrypt = new MemoryStream())
|
|
||||||
{
|
|
||||||
using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
|
|
||||||
{
|
|
||||||
using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
|
|
||||||
{
|
|
||||||
//Write all data to the stream.
|
|
||||||
swEncrypt.Write(plainText);
|
|
||||||
}
|
|
||||||
encrypted = msEncrypt.ToArray();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return the encrypted bytes from the memory stream.
|
|
||||||
return encrypted;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string DecryptStringFromBytes_Aes(byte[] cipherText, byte[] Key, byte[] IV)
|
|
||||||
{
|
|
||||||
// Check arguments.
|
|
||||||
if (cipherText == null || cipherText.Length <= 0)
|
|
||||||
throw new ArgumentNullException("cipherText");
|
|
||||||
if (Key == null || Key.Length <= 0)
|
|
||||||
throw new ArgumentNullException("Key");
|
|
||||||
if (IV == null || IV.Length <= 0)
|
|
||||||
throw new ArgumentNullException("IV");
|
|
||||||
|
|
||||||
// Declare the string used to hold
|
|
||||||
// the decrypted text.
|
|
||||||
string plaintext = null;
|
|
||||||
|
|
||||||
// Create an Aes object
|
|
||||||
// with the specified key and IV.
|
|
||||||
using (Aes aesAlg = Aes.Create())
|
|
||||||
{
|
|
||||||
aesAlg.Key = Key;
|
|
||||||
aesAlg.IV = IV;
|
|
||||||
|
|
||||||
// Create a decryptor to perform the stream transform.
|
|
||||||
ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV);
|
|
||||||
|
|
||||||
// Create the streams used for decryption.
|
|
||||||
using (MemoryStream msDecrypt = new MemoryStream(cipherText))
|
|
||||||
{
|
|
||||||
using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
|
|
||||||
{
|
|
||||||
using (StreamReader srDecrypt = new StreamReader(csDecrypt))
|
|
||||||
{
|
|
||||||
// Read the decrypted bytes from the decrypting stream
|
|
||||||
// and place them in a string.
|
|
||||||
plaintext = srDecrypt.ReadToEnd();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return plaintext;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
16
Pilz.Cryptography/IUniquieID.cs
Normal file
16
Pilz.Cryptography/IUniquieID.cs
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace Pilz.Cryptography
|
||||||
|
{
|
||||||
|
public interface IUniquieID
|
||||||
|
{
|
||||||
|
bool HasID { get; }
|
||||||
|
string ID { get; }
|
||||||
|
|
||||||
|
void GenerateIfNull();
|
||||||
|
void Generate();
|
||||||
|
bool Equals(object obj);
|
||||||
|
}
|
||||||
|
}
|
||||||
14
Pilz.Cryptography/IUniquieIDHost.cs
Normal file
14
Pilz.Cryptography/IUniquieIDHost.cs
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace Pilz.Cryptography
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Can be implemented on objects that provides an UniquieID.
|
||||||
|
/// </summary>
|
||||||
|
public interface IUniquieIDHost
|
||||||
|
{
|
||||||
|
UniquieID ID { get; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,30 +2,28 @@
|
|||||||
using Pilz.Cryptography;
|
using Pilz.Cryptography;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
|
||||||
using System.IO.Compression;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Pilz.Json.Converters
|
namespace Pilz.Json.Converters
|
||||||
{
|
{
|
||||||
public class UniquiIDStringJsonConverter<TargetType> : JsonConverter
|
public class UniquieIDStringJsonConverter : JsonConverter
|
||||||
{
|
{
|
||||||
|
public static bool EnableCheckForDepricatedTypes { get; set; } = true;
|
||||||
|
|
||||||
public override bool CanConvert(Type objectType)
|
public override bool CanConvert(Type objectType)
|
||||||
{
|
{
|
||||||
return typeof(UniquieID<TargetType>).IsAssignableFrom(objectType);
|
return typeof(UniquieID).IsAssignableFrom(objectType);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
|
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
|
||||||
{
|
{
|
||||||
var idString = serializer.Deserialize<string>(reader);
|
var idString = serializer.Deserialize<string>(reader);
|
||||||
UniquieID<TargetType> id;
|
UniquieID id;
|
||||||
|
|
||||||
if (existingValue is object)
|
if (existingValue is UniquieID existingID && (!EnableCheckForDepricatedTypes || existingID.GetType() == typeof(UniquieID)))
|
||||||
id = (UniquieID<TargetType>)existingValue;
|
id = existingID;
|
||||||
else
|
else
|
||||||
id = new UniquieID<TargetType>();
|
id = new UniquieID();
|
||||||
|
|
||||||
id.ID = idString;
|
id.ID = idString;
|
||||||
|
|
||||||
@@ -34,7 +32,7 @@ namespace Pilz.Json.Converters
|
|||||||
|
|
||||||
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
|
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
|
||||||
{
|
{
|
||||||
serializer.Serialize(writer, ((UniquieID<TargetType>)value).ID);
|
serializer.Serialize(writer, ((UniquieID)value).ID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5,9 +5,6 @@
|
|||||||
<Product>Pilz.Cryptography</Product>
|
<Product>Pilz.Cryptography</Product>
|
||||||
<Copyright>Copyright © 2020</Copyright>
|
<Copyright>Copyright © 2020</Copyright>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
|
|
||||||
<DocumentationFile>D:\repos\Pilz\Pilz.Cryptography\Pilz.Cryptography.xml</DocumentationFile>
|
|
||||||
</PropertyGroup>
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="System.Management" Version="4.7.0" />
|
<PackageReference Include="System.Management" Version="4.7.0" />
|
||||||
<PackageReference Include="System.Data.DataSetExtensions" Version="4.5.0" />
|
<PackageReference Include="System.Data.DataSetExtensions" Version="4.5.0" />
|
||||||
|
|||||||
@@ -11,20 +11,19 @@ namespace Pilz.Cryptography
|
|||||||
public class SecureString
|
public class SecureString
|
||||||
{
|
{
|
||||||
public static ICrypter DefaultCrypter { get; set; }
|
public static ICrypter DefaultCrypter { get; set; }
|
||||||
|
|
||||||
[JsonIgnore]
|
|
||||||
public ICrypter Crypter { get; set; }
|
public ICrypter Crypter { get; set; }
|
||||||
|
|
||||||
[JsonProperty]
|
|
||||||
public string EncryptedValue { get; set; }
|
public string EncryptedValue { get; set; }
|
||||||
|
|
||||||
[JsonIgnore]
|
|
||||||
public string Value
|
public string Value
|
||||||
{
|
{
|
||||||
get => GetCrypter().Decrypt(EncryptedValue);
|
get => GetCrypter()?.Decrypt(EncryptedValue);
|
||||||
set => EncryptedValue = GetCrypter().Encrypt(value);
|
set => EncryptedValue = GetCrypter().Encrypt(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[JsonConstructor]
|
||||||
|
private SecureString(JsonConstructorAttribute dummyAttribute)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
public SecureString() :
|
public SecureString() :
|
||||||
this(string.Empty, true)
|
this(string.Empty, true)
|
||||||
{
|
{
|
||||||
@@ -50,7 +49,7 @@ namespace Pilz.Cryptography
|
|||||||
if (Crypter == null)
|
if (Crypter == null)
|
||||||
{
|
{
|
||||||
if (DefaultCrypter == null)
|
if (DefaultCrypter == null)
|
||||||
DefaultCrypter = new AESStringCrypter();
|
DefaultCrypter = new SimpleStringCrypter(string.Empty);
|
||||||
Crypter = DefaultCrypter;
|
Crypter = DefaultCrypter;
|
||||||
}
|
}
|
||||||
return Crypter;
|
return Crypter;
|
||||||
@@ -73,7 +72,7 @@ namespace Pilz.Cryptography
|
|||||||
public static implicit operator string(SecureString value) => value?.Value;
|
public static implicit operator string(SecureString value) => value?.Value;
|
||||||
public static implicit operator SecureString(string value) => new SecureString(value, false);
|
public static implicit operator SecureString(string value) => new SecureString(value, false);
|
||||||
|
|
||||||
public static bool operator ==(SecureString left, SecureString right) => left.EncryptedValue == right.EncryptedValue;
|
public static bool operator ==(SecureString left, SecureString right) => left?.EncryptedValue == right?.EncryptedValue;
|
||||||
public static bool operator !=(SecureString left, SecureString right) => left.EncryptedValue != right.EncryptedValue;
|
public static bool operator !=(SecureString left, SecureString right) => left?.EncryptedValue != right?.EncryptedValue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,12 +22,13 @@ namespace Pilz.Json.Converters
|
|||||||
var idString = serializer.Deserialize<string>(reader);
|
var idString = serializer.Deserialize<string>(reader);
|
||||||
SecureString id;
|
SecureString id;
|
||||||
|
|
||||||
if (existingValue is object)
|
if (existingValue is SecureString)
|
||||||
|
{
|
||||||
id = (SecureString)existingValue;
|
id = (SecureString)existingValue;
|
||||||
|
id.EncryptedValue = idString;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
id = new SecureString();
|
id = new SecureString(idString, true);
|
||||||
|
|
||||||
id.EncryptedValue = idString;
|
|
||||||
|
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,10 +35,13 @@ namespace Pilz.Cryptography
|
|||||||
byte[] bytes = TextEncoding.GetBytes(key);
|
byte[] bytes = TextEncoding.GetBytes(key);
|
||||||
byte[] array = sha1CryptoServiceProvider.ComputeHash(bytes);
|
byte[] array = sha1CryptoServiceProvider.ComputeHash(bytes);
|
||||||
|
|
||||||
var output = new byte[checked(length - 1 + 1)];
|
var output = new byte[length];
|
||||||
array.CopyTo(output, 0);
|
var lowerLength = Math.Min(array.Length, output.Length);
|
||||||
|
|
||||||
|
for (int i = 0; i < lowerLength; i++)
|
||||||
|
output[i] = array[i];
|
||||||
|
|
||||||
return array;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
private string EncryptData(string plaintext)
|
private string EncryptData(string plaintext)
|
||||||
@@ -63,7 +66,7 @@ namespace Pilz.Cryptography
|
|||||||
|
|
||||||
public string Encrypt(string plainValue)
|
public string Encrypt(string plainValue)
|
||||||
{
|
{
|
||||||
return EncryptData(plainValue);
|
return EncryptData(plainValue ?? string.Empty);
|
||||||
}
|
}
|
||||||
|
|
||||||
public string Decrypt(string encryptedValue)
|
public string Decrypt(string encryptedValue)
|
||||||
|
|||||||
@@ -1,23 +1,31 @@
|
|||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
|
||||||
using System.Management;
|
using System.Management;
|
||||||
using System.Security.Cryptography;
|
using System.Security.Cryptography;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Pilz.Cryptography
|
namespace Pilz.Cryptography
|
||||||
{
|
{
|
||||||
public class UniquieID<TargetType>
|
[JsonConverter(typeof(Json.Converters.UniquieIDStringJsonConverter))]
|
||||||
|
public class UniquieID : IUniquieID
|
||||||
{
|
{
|
||||||
private static int currentSimpleID = 0;
|
protected static ulong currentSimpleID = 0;
|
||||||
|
|
||||||
[JsonProperty(nameof(ID))]
|
[JsonProperty(nameof(ID))]
|
||||||
private string _iD;
|
protected string _iD;
|
||||||
|
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public string ID
|
public virtual bool SimpleMode { get; }
|
||||||
|
|
||||||
|
[JsonIgnore]
|
||||||
|
public virtual bool GenerateOnGet { get; }
|
||||||
|
|
||||||
|
[JsonIgnore]
|
||||||
|
public virtual bool HasID => !string.IsNullOrEmpty(_iD);
|
||||||
|
|
||||||
|
[JsonIgnore]
|
||||||
|
public virtual string ID
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
@@ -29,36 +37,96 @@ namespace Pilz.Cryptography
|
|||||||
=> _iD = value;
|
=> _iD = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
[JsonIgnore]
|
public UniquieID() : this(UniquieIDGenerationMode.None)
|
||||||
public bool HasID { get => !string.IsNullOrEmpty(_iD); }
|
|
||||||
[JsonIgnore]
|
|
||||||
public bool SimpleMode { get; set; } = false;
|
|
||||||
[JsonIgnore]
|
|
||||||
public bool GenerateOnGet { get; set; } = false;
|
|
||||||
|
|
||||||
public UniquieID() : this(false)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public UniquieID(bool autoGenerate)
|
public UniquieID(UniquieIDGenerationMode mode) : this(mode, false)
|
||||||
{
|
{
|
||||||
if (autoGenerate)
|
}
|
||||||
|
|
||||||
|
public UniquieID(UniquieIDGenerationMode mode, bool simpleMode)
|
||||||
|
{
|
||||||
|
SimpleMode = simpleMode;
|
||||||
|
|
||||||
|
if (mode == UniquieIDGenerationMode.GenerateOnInit)
|
||||||
GenerateIfNull();
|
GenerateIfNull();
|
||||||
|
else if (mode == UniquieIDGenerationMode.GenerateOnGet)
|
||||||
|
GenerateOnGet = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Generate()
|
[Obsolete]
|
||||||
|
public UniquieID(bool autoGenerate) : this(autoGenerate ? UniquieIDGenerationMode.GenerateOnInit : UniquieIDGenerationMode.None)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual void Generate()
|
||||||
{
|
{
|
||||||
if (SimpleMode)
|
if (SimpleMode)
|
||||||
ID = typeof(TargetType).ToString() + currentSimpleID++.ToString();
|
ID = GenerateSimple();
|
||||||
else
|
else
|
||||||
ID = GenerateUniquieID<TargetType>(string.Empty);
|
ID = GenerateDefault();
|
||||||
}
|
}
|
||||||
public void GenerateIfNull()
|
|
||||||
|
protected virtual string GenerateSimple()
|
||||||
|
{
|
||||||
|
return new Random().Next().ToString() + DateTime.Now.ToString("yyyyMMddHHmmssfffffff") + currentSimpleID++.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual string GenerateDefault()
|
||||||
|
{
|
||||||
|
return GenerateUniquieID<UniquieID>(currentSimpleID++.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual void GenerateIfNull()
|
||||||
{
|
{
|
||||||
if (!HasID) Generate();
|
if (!HasID) Generate();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string GenerateUniquieID<T>(string var)
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override int GetHashCode()
|
||||||
|
{
|
||||||
|
return -1430039477 + EqualityComparer<string>.Default.GetHashCode(_iD);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool Equals(object obj)
|
||||||
|
{
|
||||||
|
if (obj is UniquieID iD)
|
||||||
|
{
|
||||||
|
if (ReferenceEquals(obj, iD))
|
||||||
|
return true;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var leftHasID = iD.HasID;
|
||||||
|
var rightHasID = HasID;
|
||||||
|
|
||||||
|
if (!leftHasID && iD.GenerateOnGet)
|
||||||
|
{
|
||||||
|
iD.Generate();
|
||||||
|
leftHasID = iD.HasID;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!rightHasID && GenerateOnGet)
|
||||||
|
{
|
||||||
|
Generate();
|
||||||
|
rightHasID = HasID;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (leftHasID && rightHasID)
|
||||||
|
return _iD.Equals(iD._iD);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return base.Equals(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Statics for Generation
|
||||||
|
|
||||||
|
protected static string GenerateUniquieID<T>(string var)
|
||||||
{
|
{
|
||||||
var sn = TryGetSerialNumberOfFirstHardDrive();
|
var sn = TryGetSerialNumberOfFirstHardDrive();
|
||||||
var dateTime = DateTime.UtcNow.ToString("yyyyMMddHHmmssfffffff");
|
var dateTime = DateTime.UtcNow.ToString("yyyyMMddHHmmssfffffff");
|
||||||
@@ -72,39 +140,33 @@ namespace Pilz.Cryptography
|
|||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static string Win32_PhysicalMedia_SerialNumber = null;
|
||||||
private static string TryGetSerialNumberOfFirstHardDrive()
|
private static string TryGetSerialNumberOfFirstHardDrive()
|
||||||
{
|
{
|
||||||
var searcher = new ManagementObjectSearcher("SELECT * FROM Win32_PhysicalMedia");
|
if (Win32_PhysicalMedia_SerialNumber == null)
|
||||||
var sn = string.Empty;
|
|
||||||
|
|
||||||
foreach (ManagementObject wmi_HD in searcher.Get())
|
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(sn) && wmi_HD["SerialNumber"] != null)
|
var searcher = new ManagementObjectSearcher("SELECT * FROM Win32_PhysicalMedia");
|
||||||
sn = wmi_HD["SerialNumber"].ToString().Trim();
|
var sn = string.Empty;
|
||||||
|
|
||||||
|
foreach (ManagementObject wmi_HD in searcher.Get())
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(sn) && wmi_HD["SerialNumber"] != null)
|
||||||
|
sn = wmi_HD["SerialNumber"].ToString().Trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
Win32_PhysicalMedia_SerialNumber = sn;
|
||||||
}
|
}
|
||||||
|
|
||||||
return sn;
|
return Win32_PhysicalMedia_SerialNumber;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string ToString() => ID;
|
#endregion
|
||||||
|
|
||||||
public override bool Equals(object obj)
|
public static implicit operator string(UniquieID id) => id.ID;
|
||||||
{
|
public static implicit operator UniquieID(string id) => new UniquieID() { ID = id };
|
||||||
var iD = obj as UniquieID<TargetType>;
|
public static implicit operator UniquieID(int id) => new UniquieID() { ID = Convert.ToString(id) };
|
||||||
return iD != null &&
|
|
||||||
_iD == iD._iD;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override int GetHashCode()
|
public static bool operator ==(UniquieID left, UniquieID right) => left.ID.Equals(right.ID);
|
||||||
{
|
public static bool operator !=(UniquieID left, UniquieID right) => !left.ID.Equals(right.ID);
|
||||||
return -1430039477 + EqualityComparer<string>.Default.GetHashCode(_iD);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static implicit operator string(UniquieID<TargetType> id) => id.ID;
|
|
||||||
public static implicit operator UniquieID<TargetType>(string id) => new UniquieID<TargetType>() { ID = id };
|
|
||||||
public static implicit operator UniquieID<TargetType>(int id) => new UniquieID<TargetType>() { ID = Convert.ToString(id) };
|
|
||||||
|
|
||||||
public static bool operator ==(UniquieID<TargetType> left, UniquieID<TargetType> right) => left.ID == right.ID;
|
|
||||||
public static bool operator !=(UniquieID<TargetType> left, UniquieID<TargetType> right) => left.ID != right.ID;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
13
Pilz.Cryptography/UniquieIDGenerationMode.cs
Normal file
13
Pilz.Cryptography/UniquieIDGenerationMode.cs
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace Pilz.Cryptography
|
||||||
|
{
|
||||||
|
public enum UniquieIDGenerationMode
|
||||||
|
{
|
||||||
|
None,
|
||||||
|
GenerateOnGet,
|
||||||
|
GenerateOnInit
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,7 +1,5 @@
|
|||||||
Imports System.Windows.Forms
|
Imports System.Windows.Forms
|
||||||
|
|
||||||
Imports OpenTK
|
Imports OpenTK
|
||||||
Imports OpenTK.Mathematics
|
|
||||||
|
|
||||||
Namespace CameraN
|
Namespace CameraN
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<MyType>Windows</MyType>
|
<MyType>Windows</MyType>
|
||||||
<TargetFramework>net5.0-windows7.0</TargetFramework>
|
<TargetFramework>net48</TargetFramework>
|
||||||
<UseWindowsForms>true</UseWindowsForms>
|
|
||||||
<UseWpf>true</UseWpf>
|
|
||||||
<NoWarn>42016,41999,42017,42018,42019,42032,42036,42020,42021,42022</NoWarn>
|
<NoWarn>42016,41999,42017,42018,42019,42032,42036,42020,42021,42022</NoWarn>
|
||||||
<DocumentationFile>Pilz.Drawing.Drawing3D.OpenGLFactory.xml</DocumentationFile>
|
<DocumentationFile>Pilz.Drawing.Drawing3D.OpenGLFactory.xml</DocumentationFile>
|
||||||
<DefineTrace>true</DefineTrace>
|
<DefineTrace>true</DefineTrace>
|
||||||
@@ -27,14 +25,18 @@
|
|||||||
<OptionInfer>On</OptionInfer>
|
<OptionInfer>On</OptionInfer>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="OpenTK.GLWpfControl" Version="4.0.0-pre.9" />
|
|
||||||
<PackageReference Include="System.Data.DataSetExtensions" Version="4.5.0" />
|
<PackageReference Include="System.Data.DataSetExtensions" Version="4.5.0" />
|
||||||
<PackageReference Include="System.Net.Http" Version="4.3.4" />
|
<PackageReference Include="System.Net.Http" Version="4.3.4" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="OpenTK" Version="4.3.0" />
|
<PackageReference Include="OpenTK" Version="3.2" />
|
||||||
|
<PackageReference Include="OpenTK.GLControl" Version="3.1.0" />
|
||||||
<PackageReference Include="System.Numerics.Vectors" Version="4.5.0" />
|
<PackageReference Include="System.Numerics.Vectors" Version="4.5.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Reference Include="Microsoft.VisualBasic" />
|
||||||
|
<Reference Include="System.Windows.Forms" />
|
||||||
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Import Include="Microsoft.VisualBasic" />
|
<Import Include="Microsoft.VisualBasic" />
|
||||||
<Import Include="System" />
|
<Import Include="System" />
|
||||||
@@ -50,7 +52,9 @@
|
|||||||
<Compile Update="Preview\ModelPreview.Designer.vb">
|
<Compile Update="Preview\ModelPreview.Designer.vb">
|
||||||
<DependentUpon>ModelPreview.vb</DependentUpon>
|
<DependentUpon>ModelPreview.vb</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Update="Preview\ModelPreview.vb" />
|
<Compile Update="Preview\ModelPreview.vb">
|
||||||
|
<SubType>Form</SubType>
|
||||||
|
</Compile>
|
||||||
<Compile Update="My Project\Application.Designer.vb">
|
<Compile Update="My Project\Application.Designer.vb">
|
||||||
<AutoGen>True</AutoGen>
|
<AutoGen>True</AutoGen>
|
||||||
<DependentUpon>Application.myapp</DependentUpon>
|
<DependentUpon>Application.myapp</DependentUpon>
|
||||||
@@ -94,9 +98,4 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Remove="ModelPreview.Designer.vb" />
|
<Compile Remove="ModelPreview.Designer.vb" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
|
||||||
<Reference Include="OpenTK3">
|
|
||||||
<HintPath>..\Shared Libs\OpenTK3.dll</HintPath>
|
|
||||||
</Reference>
|
|
||||||
</ItemGroup>
|
|
||||||
</Project>
|
</Project>
|
||||||
@@ -6,19 +6,16 @@ Imports OpenTK
|
|||||||
Imports OpenTK.Graphics.OpenGL
|
Imports OpenTK.Graphics.OpenGL
|
||||||
Imports Pilz.S3DFileParser
|
Imports Pilz.S3DFileParser
|
||||||
Imports Point = System.Drawing.Point
|
Imports Point = System.Drawing.Point
|
||||||
|
Imports KeyboardState = OpenTK.Input.KeyboardState
|
||||||
|
Imports Keyboard = OpenTK.Input.Keyboard
|
||||||
|
Imports Key = OpenTK.Input.Key
|
||||||
Imports Color = System.Drawing.Color
|
Imports Color = System.Drawing.Color
|
||||||
Imports System.Windows.Forms.Integration
|
|
||||||
Imports OpenTK.Mathematics
|
|
||||||
Imports System.Windows.Input
|
|
||||||
Imports Key = OpenTK3.Input.Key
|
|
||||||
Imports OpenTK.Wpf
|
|
||||||
|
|
||||||
Namespace PreviewN
|
Namespace PreviewN
|
||||||
|
|
||||||
Public Class ModelPreview
|
Public Class ModelPreview
|
||||||
|
|
||||||
Private WithEvents glControl1 As Wpf.GLWpfControl
|
Private WithEvents glControl1 As GLControl
|
||||||
Private WithEvents glControlHost As ElementHost
|
|
||||||
Private WithEvents MyCamera As New Camera
|
Private WithEvents MyCamera As New Camera
|
||||||
Private ProjMatrix As Matrix4 = Nothing
|
Private ProjMatrix As Matrix4 = Nothing
|
||||||
Private FOV As Single = 1.048F
|
Private FOV As Single = 1.048F
|
||||||
@@ -29,17 +26,10 @@ Namespace PreviewN
|
|||||||
Private ReadOnly myModels As New Dictionary(Of Object3D, Renderer)
|
Private ReadOnly myModels As New Dictionary(Of Object3D, Renderer)
|
||||||
Private WithEvents RenderTimer As New Timers.Timer(25) With {.AutoReset = True}
|
Private WithEvents RenderTimer As New Timers.Timer(25) With {.AutoReset = True}
|
||||||
Private _EnableCameraControlling As Boolean = False
|
Private _EnableCameraControlling As Boolean = False
|
||||||
Private finishedLoading As Boolean = False
|
|
||||||
|
|
||||||
Public Property Scaling As Single = 500.0F
|
Public Property Scaling As Single = 500.0F
|
||||||
Public Property ClearColor As Color = Color.CornflowerBlue
|
Public Property ClearColor As Color = Color.CornflowerBlue
|
||||||
|
|
||||||
Public ReadOnly Property Keyboard As OpenTK3.Input.KeyboardState
|
|
||||||
Get
|
|
||||||
Return OpenTK3.Input.Keyboard.GetState
|
|
||||||
End Get
|
|
||||||
End Property
|
|
||||||
|
|
||||||
Public Property EnableCameraControlling As Boolean
|
Public Property EnableCameraControlling As Boolean
|
||||||
Get
|
Get
|
||||||
Return _EnableCameraControlling
|
Return _EnableCameraControlling
|
||||||
@@ -84,12 +74,6 @@ Namespace PreviewN
|
|||||||
End Property
|
End Property
|
||||||
|
|
||||||
Public ReadOnly Property GLControl As Control
|
Public ReadOnly Property GLControl As Control
|
||||||
Get
|
|
||||||
Return glControlHost
|
|
||||||
End Get
|
|
||||||
End Property
|
|
||||||
|
|
||||||
Public ReadOnly Property GLControlClient As GLWpfControl
|
|
||||||
Get
|
Get
|
||||||
Return glControl1
|
Return glControl1
|
||||||
End Get
|
End Get
|
||||||
@@ -97,15 +81,15 @@ Namespace PreviewN
|
|||||||
|
|
||||||
Private ReadOnly Property IsStrgPressed As Boolean
|
Private ReadOnly Property IsStrgPressed As Boolean
|
||||||
Get
|
Get
|
||||||
Dim state = Keyboard
|
Dim state As KeyboardState = Keyboard.GetState()
|
||||||
Return state.IsKeyDown(Key.ControlLeft) OrElse state.IsKeyDown(Key.ControlRight)
|
Return state(Key.ControlLeft) OrElse state(Key.ControlRight)
|
||||||
End Get
|
End Get
|
||||||
End Property
|
End Property
|
||||||
|
|
||||||
Private ReadOnly Property IsShiftPressed As Boolean
|
Private ReadOnly Property IsShiftPressed As Boolean
|
||||||
Get
|
Get
|
||||||
Dim state = Keyboard
|
Dim state As KeyboardState = Keyboard.GetState()
|
||||||
Return state.IsKeyDown(Key.ShiftLeft) OrElse state.IsKeyDown(Key.ShiftRight)
|
Return state(Key.ShiftLeft) OrElse state(Key.ShiftRight)
|
||||||
End Get
|
End Get
|
||||||
End Property
|
End Property
|
||||||
|
|
||||||
@@ -115,7 +99,7 @@ Namespace PreviewN
|
|||||||
End Get
|
End Get
|
||||||
Set(value As Boolean)
|
Set(value As Boolean)
|
||||||
_isMouseDown = value
|
_isMouseDown = value
|
||||||
glControlHost.Refresh()
|
glControl1.Refresh()
|
||||||
End Set
|
End Set
|
||||||
End Property
|
End Property
|
||||||
|
|
||||||
@@ -132,49 +116,44 @@ Namespace PreviewN
|
|||||||
End Sub
|
End Sub
|
||||||
|
|
||||||
Public Sub New(objs As Object3D(), scale As Single)
|
Public Sub New(objs As Object3D(), scale As Single)
|
||||||
SuspendLayout()
|
Me.SuspendLayout()
|
||||||
|
|
||||||
InitializeComponent()
|
InitializeComponent()
|
||||||
|
DoubleBuffered = True
|
||||||
|
|
||||||
'glControl1
|
'glControl1
|
||||||
Dim glControl1 As New GLWpfControl
|
Me.glControl1 = New GLControl
|
||||||
Dim glControlHost = New ElementHost
|
Me.glControl1.BackColor = Color.Black
|
||||||
glControlHost.BackColor = Color.Black
|
Me.glControl1.Location = New Point(0, 0)
|
||||||
glControlHost.Name = "glControl1"
|
Me.glControl1.MinimumSize = New Size(600, 120)
|
||||||
glControlHost.Anchor = AnchorStyles.Left Or AnchorStyles.Top Or AnchorStyles.Right Or AnchorStyles.Bottom
|
Me.glControl1.Name = "glControl1"
|
||||||
glControlHost.Location = New Point(0, 0)
|
Me.glControl1.Anchor = AnchorStyles.Left Or AnchorStyles.Top Or AnchorStyles.Right Or AnchorStyles.Bottom
|
||||||
glControlHost.Size = Me.ClientSize
|
Me.glControl1.Location = New Point(0, 0)
|
||||||
glControlHost.MinimumSize = New Size(600, 120)
|
Me.glControl1.Size = Me.ClientSize
|
||||||
glControlHost.TabIndex = 0
|
Me.glControl1.TabIndex = 0
|
||||||
glControlHost.TabStop = False
|
Me.glControl1.TabStop = False
|
||||||
|
Me.glControl1.VSync = False
|
||||||
Me.glControl1 = glControl1
|
Me.Controls.Add(Me.glControl1)
|
||||||
Me.glControlHost = glControlHost
|
Me.ResumeLayout(False)
|
||||||
|
|
||||||
Dim controlSettings As New GLWpfControlSettings With
|
|
||||||
{
|
|
||||||
.RenderContinuously = False,
|
|
||||||
.GraphicsProfile = Windowing.Common.ContextProfile.Compatability
|
|
||||||
}
|
|
||||||
glControl1.Start(controlSettings)
|
|
||||||
|
|
||||||
glControlHost.Child = glControl1
|
|
||||||
Controls.Add(glControlHost)
|
|
||||||
|
|
||||||
|
'RenderTimer.SynchronizingObject = Nothing
|
||||||
Scaling = scale
|
Scaling = scale
|
||||||
|
|
||||||
ProjMatrix = Matrix4.CreatePerspectiveFieldOfView(FOV, glControlHost.Width / glControlHost.Height, 100.0F, 100000.0F)
|
'Toolkit.Init()
|
||||||
|
|
||||||
ResumeLayout()
|
glControl1.CreateControl()
|
||||||
|
AddHandler glControl1.MouseWheel, AddressOf glControl1_Wheel
|
||||||
|
ProjMatrix = Matrix4.CreatePerspectiveFieldOfView(FOV, glControl1.Width / glControl1.Height, 100.0F, 100000.0F)
|
||||||
|
glControl1.Enabled = False
|
||||||
|
|
||||||
MyCamera.SetCameraMode(CameraMode.FLY, camMtx)
|
MyCamera.SetCameraMode(CameraMode.FLY, camMtx)
|
||||||
MyCamera.UpdateMatrix(camMtx)
|
MyCamera.UpdateMatrix(camMtx)
|
||||||
|
|
||||||
|
Me.ResumeLayout()
|
||||||
|
|
||||||
For Each obj As Object3D In objs
|
For Each obj As Object3D In objs
|
||||||
AddModel(obj)
|
AddModel(obj)
|
||||||
Next
|
Next
|
||||||
|
|
||||||
finishedLoading = True
|
|
||||||
End Sub
|
End Sub
|
||||||
|
|
||||||
Public Sub UpdateOrbitCamera()
|
Public Sub UpdateOrbitCamera()
|
||||||
@@ -184,16 +163,11 @@ Namespace PreviewN
|
|||||||
End Sub
|
End Sub
|
||||||
|
|
||||||
Public Sub UpdateView()
|
Public Sub UpdateView()
|
||||||
If glControlHost.Enabled AndAlso finishedLoading Then
|
If glControl1.Enabled Then
|
||||||
Invoke(Sub() InvalidateGL())
|
glControl1.Invoke(Sub() glControl1.Invalidate())
|
||||||
End If
|
End If
|
||||||
End Sub
|
End Sub
|
||||||
|
|
||||||
Private Sub InvalidateGL()
|
|
||||||
glControl1.InvalidateVisual()
|
|
||||||
glControlHost.Invalidate()
|
|
||||||
End Sub
|
|
||||||
|
|
||||||
Public Function AddModel(obj As Object3D) As Renderer
|
Public Function AddModel(obj As Object3D) As Renderer
|
||||||
Dim rndr As New Renderer(obj)
|
Dim rndr As New Renderer(obj)
|
||||||
AddModel(rndr)
|
AddModel(rndr)
|
||||||
@@ -205,8 +179,9 @@ Namespace PreviewN
|
|||||||
End Sub
|
End Sub
|
||||||
|
|
||||||
Public Sub HandlesOnShown(sender As Object, e As EventArgs) Handles MyBase.Shown
|
Public Sub HandlesOnShown(sender As Object, e As EventArgs) Handles MyBase.Shown
|
||||||
|
glControl1.Enabled = True
|
||||||
RenderModels()
|
RenderModels()
|
||||||
InvalidateGL()
|
glControl1.Invalidate()
|
||||||
End Sub
|
End Sub
|
||||||
|
|
||||||
Public Sub RenderModels()
|
Public Sub RenderModels()
|
||||||
@@ -222,7 +197,7 @@ Namespace PreviewN
|
|||||||
End If
|
End If
|
||||||
End Sub
|
End Sub
|
||||||
|
|
||||||
Private Sub glControl1_Load() Handles glControl1.Ready
|
Private Sub glControl1_Load(sender As Object, e As EventArgs) Handles glControl1.Load
|
||||||
GL.Enable(EnableCap.Blend)
|
GL.Enable(EnableCap.Blend)
|
||||||
GL.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha)
|
GL.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha)
|
||||||
|
|
||||||
@@ -252,10 +227,11 @@ Namespace PreviewN
|
|||||||
End If
|
End If
|
||||||
End Sub
|
End Sub
|
||||||
|
|
||||||
Public Sub HandlesOnPaint(renderTime As TimeSpan) Handles glControl1.Render
|
Public Sub HandlesOnPaint(sender As Object, e As PaintEventArgs) Handles glControl1.Paint
|
||||||
GL.ClearColor(ClearColor)
|
GL.ClearColor(ClearColor)
|
||||||
|
|
||||||
GL.Clear(ClearBufferMask.ColorBufferBit Or ClearBufferMask.DepthBufferBit)
|
GL.Clear(ClearBufferMask.ColorBufferBit Or ClearBufferMask.DepthBufferBit)
|
||||||
GL.LoadIdentity()
|
|
||||||
GL.MatrixMode(MatrixMode.Projection)
|
GL.MatrixMode(MatrixMode.Projection)
|
||||||
GL.LoadMatrix(ProjMatrix)
|
GL.LoadMatrix(ProjMatrix)
|
||||||
GL.MatrixMode(MatrixMode.Modelview)
|
GL.MatrixMode(MatrixMode.Modelview)
|
||||||
@@ -267,27 +243,24 @@ Namespace PreviewN
|
|||||||
End If
|
End If
|
||||||
Next
|
Next
|
||||||
|
|
||||||
GL.End()
|
glControl1.SwapBuffers()
|
||||||
GL.Finish()
|
|
||||||
|
|
||||||
'glControl1.SwapBuffers()
|
|
||||||
End Sub
|
End Sub
|
||||||
|
|
||||||
Private Sub glControl1_Resize(sender As Object, e As EventArgs) Handles glControlHost.Resize
|
Private Sub glControl1_Resize(sender As Object, e As EventArgs) Handles glControl1.Resize
|
||||||
'glControl1.Context.Update(glControl1.WindowInfo)
|
glControl1.Context.Update(glControl1.WindowInfo)
|
||||||
GL.Viewport(0, 0, glControlHost.Width, glControlHost.Height)
|
GL.Viewport(0, 0, glControl1.Width, glControl1.Height)
|
||||||
ProjMatrix = Matrix4.CreatePerspectiveFieldOfView(FOV, glControlHost.Width / glControlHost.Height, 100.0F, 100000.0F)
|
ProjMatrix = Matrix4.CreatePerspectiveFieldOfView(FOV, glControl1.Width / glControl1.Height, 100.0F, 100000.0F)
|
||||||
InvalidateGL()
|
glControl1.Invalidate()
|
||||||
End Sub
|
End Sub
|
||||||
|
|
||||||
Private Sub glControl1_Wheel(sender As Object, e As Windows.Input.MouseWheelEventArgs) Handles glControl1.MouseWheel
|
Private Sub glControl1_Wheel(sender As Object, e As MouseEventArgs)
|
||||||
MyCamera.ResetMouseStuff()
|
MyCamera.ResetMouseStuff()
|
||||||
MyCamera.UpdateCameraMatrixWithScrollWheel(CInt(Math.Truncate(e.Delta * (If(IsShiftPressed, 3.5F, 1.5F)))), camMtx)
|
MyCamera.UpdateCameraMatrixWithScrollWheel(CInt(Math.Truncate(e.Delta * (If(IsShiftPressed, 3.5F, 1.5F)))), camMtx)
|
||||||
savedCamPos = MyCamera.Position
|
savedCamPos = MyCamera.Position
|
||||||
InvalidateGL()
|
glControl1.Invalidate()
|
||||||
End Sub
|
End Sub
|
||||||
|
|
||||||
Private Sub glControl1_MouseDown(ByVal sender As Object, ByVal e As Windows.Input.MouseButtonEventArgs) Handles glControl1.MouseDown
|
Private Sub glControl1_MouseDown(ByVal sender As Object, ByVal e As MouseEventArgs) Handles glControl1.MouseDown
|
||||||
IsMouseDown = True
|
IsMouseDown = True
|
||||||
savedCamPos = MyCamera.Position
|
savedCamPos = MyCamera.Position
|
||||||
End Sub
|
End Sub
|
||||||
@@ -297,47 +270,47 @@ Namespace PreviewN
|
|||||||
IsMouseDown = False
|
IsMouseDown = False
|
||||||
End Sub
|
End Sub
|
||||||
|
|
||||||
Private Sub glControl1_MouseMove(ByVal sender As Object, ByVal e As Windows.Input.MouseEventArgs) Handles glControl1.MouseMove
|
Private Sub glControl1_MouseMove(ByVal sender As Object, ByVal e As MouseEventArgs) Handles glControl1.MouseMove
|
||||||
If e.LeftButton = MouseButtonState.Pressed Then
|
If IsMouseDown AndAlso e.Button = MouseButtons.Left Then
|
||||||
Dim pos = e.GetPosition(glControl1)
|
|
||||||
If IsShiftPressed Then
|
If IsShiftPressed Then
|
||||||
MyCamera.UpdateCameraOffsetWithMouse(savedCamPos, pos.X, pos.Y, glControl1.Width, glControl1.Height, camMtx)
|
MyCamera.UpdateCameraOffsetWithMouse(savedCamPos, e.X, e.Y, glControl1.Width, glControl1.Height, camMtx)
|
||||||
Else
|
Else
|
||||||
MyCamera.UpdateCameraMatrixWithMouse(pos.X, pos.Y, camMtx)
|
MyCamera.UpdateCameraMatrixWithMouse(e.X, e.Y, camMtx)
|
||||||
End If
|
End If
|
||||||
InvalidateGL()
|
glControl1.Invalidate()
|
||||||
End If
|
End If
|
||||||
End Sub
|
End Sub
|
||||||
|
|
||||||
Public Sub MoveCameraViaWASDQE()
|
Public Sub MoveCameraViaWASDQE()
|
||||||
Dim moveSpeed As Integer = Convert.ToInt32(Math.Round((If(IsShiftPressed, 60, 30)) * (MyCamera.CamSpeedMultiplier), 0))
|
Dim moveSpeed As Integer = Convert.ToInt32(Math.Round((If(IsShiftPressed, 60, 30)) * (MyCamera.CamSpeedMultiplier), 0))
|
||||||
Dim allowCamMove As Boolean = Not (IsMouseDown AndAlso IsShiftPressed)
|
Dim allowCamMove As Boolean = Not (IsMouseDown AndAlso IsShiftPressed)
|
||||||
Dim state = Keyboard
|
|
||||||
|
|
||||||
If allowCamMove Then
|
If allowCamMove Then
|
||||||
If state.IsKeyDown(Key.W) Then
|
Dim state As KeyboardState = Keyboard.GetState
|
||||||
|
|
||||||
|
If state(Key.W) Then
|
||||||
'camera.Move(moveSpeed, moveSpeed, camMtx)
|
'camera.Move(moveSpeed, moveSpeed, camMtx)
|
||||||
MyCamera.UpdateCameraMatrixWithScrollWheel(moveSpeed, camMtx)
|
MyCamera.UpdateCameraMatrixWithScrollWheel(moveSpeed, camMtx)
|
||||||
savedCamPos = MyCamera.Position
|
savedCamPos = MyCamera.Position
|
||||||
End If
|
End If
|
||||||
If state.IsKeyDown(Key.S) Then
|
If state(Key.S) Then
|
||||||
'camera.Move(-moveSpeed, -moveSpeed, camMtx)
|
'camera.Move(-moveSpeed, -moveSpeed, camMtx)
|
||||||
MyCamera.UpdateCameraMatrixWithScrollWheel(-moveSpeed, camMtx)
|
MyCamera.UpdateCameraMatrixWithScrollWheel(-moveSpeed, camMtx)
|
||||||
savedCamPos = MyCamera.Position
|
savedCamPos = MyCamera.Position
|
||||||
End If
|
End If
|
||||||
If state.IsKeyDown(Key.A) Then
|
If state(Key.A) Then
|
||||||
'camera.Move(-moveSpeed, 0, camMtx)
|
'camera.Move(-moveSpeed, 0, camMtx)
|
||||||
MyCamera.UpdateCameraOffsetDirectly(-moveSpeed, 0, camMtx)
|
MyCamera.UpdateCameraOffsetDirectly(-moveSpeed, 0, camMtx)
|
||||||
End If
|
End If
|
||||||
If state.IsKeyDown(Key.D) Then
|
If state(Key.D) Then
|
||||||
'camera.Move(moveSpeed, 0, camMtx)
|
'camera.Move(moveSpeed, 0, camMtx)
|
||||||
MyCamera.UpdateCameraOffsetDirectly(moveSpeed, 0, camMtx)
|
MyCamera.UpdateCameraOffsetDirectly(moveSpeed, 0, camMtx)
|
||||||
End If
|
End If
|
||||||
If state.IsKeyDown(Key.E) Then
|
If state(Key.E) Then
|
||||||
'camera.Move(0, -moveSpeed, camMtx)
|
'camera.Move(0, -moveSpeed, camMtx)
|
||||||
MyCamera.UpdateCameraOffsetDirectly(0, -moveSpeed, camMtx)
|
MyCamera.UpdateCameraOffsetDirectly(0, -moveSpeed, camMtx)
|
||||||
End If
|
End If
|
||||||
If state.IsKeyDown(Key.Q) Then
|
If state(Key.Q) Then
|
||||||
'camera.Move(0, moveSpeed, camMtx)
|
'camera.Move(0, moveSpeed, camMtx)
|
||||||
MyCamera.UpdateCameraOffsetDirectly(0, moveSpeed, camMtx)
|
MyCamera.UpdateCameraOffsetDirectly(0, moveSpeed, camMtx)
|
||||||
End If
|
End If
|
||||||
|
|||||||
@@ -1,13 +1,9 @@
|
|||||||
Imports System.Drawing
|
Imports System.Drawing
|
||||||
Imports System.Threading
|
Imports System.Threading
|
||||||
Imports System.Windows.Forms
|
Imports System.Windows.Forms
|
||||||
|
|
||||||
Imports OpenTK
|
Imports OpenTK
|
||||||
Imports OpenTK.Graphics.OpenGL
|
Imports OpenTK.Graphics.OpenGL
|
||||||
Imports OpenTK.Mathematics
|
|
||||||
|
|
||||||
Imports Pilz.S3DFileParser
|
Imports Pilz.S3DFileParser
|
||||||
|
|
||||||
Imports Bitmap = System.Drawing.Bitmap
|
Imports Bitmap = System.Drawing.Bitmap
|
||||||
Imports Color = System.Drawing.Color
|
Imports Color = System.Drawing.Color
|
||||||
Imports Image = System.Drawing.Image
|
Imports Image = System.Drawing.Image
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<MyType>Windows</MyType>
|
<MyType>Windows</MyType>
|
||||||
<TargetFramework>net5.0-windows7.0</TargetFramework>
|
<TargetFramework>net48</TargetFramework>
|
||||||
<NoWarn>42016,41999,42017,42018,42019,42032,42036,42020,42021,42022</NoWarn>
|
<NoWarn>42016,41999,42017,42018,42019,42032,42036,42020,42021,42022</NoWarn>
|
||||||
<DocumentationFile>Pilz.Drawing.xml</DocumentationFile>
|
<DocumentationFile>Pilz.Drawing.xml</DocumentationFile>
|
||||||
<DefineTrace>true</DefineTrace>
|
<DefineTrace>true</DefineTrace>
|
||||||
@@ -26,7 +26,6 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="System.Data.DataSetExtensions" Version="4.5.0" />
|
<PackageReference Include="System.Data.DataSetExtensions" Version="4.5.0" />
|
||||||
<PackageReference Include="System.Drawing.Common" Version="4.7.0" />
|
|
||||||
<PackageReference Include="System.Net.Http" Version="4.3.4" />
|
<PackageReference Include="System.Net.Http" Version="4.3.4" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<MyType>Windows</MyType>
|
<MyType>Windows</MyType>
|
||||||
<TargetFramework>net5.0-windows7.0</TargetFramework>
|
<TargetFramework>net48</TargetFramework>
|
||||||
<NoWarn>42016,41999,42017,42018,42019,42032,42036,42020,42021,42022</NoWarn>
|
<NoWarn>42016,41999,42017,42018,42019,42032,42036,42020,42021,42022</NoWarn>
|
||||||
<DocumentationFile>Pilz.Networking.xml</DocumentationFile>
|
<DocumentationFile>Pilz.Networking.xml</DocumentationFile>
|
||||||
<DefineTrace>true</DefineTrace>
|
<DefineTrace>true</DefineTrace>
|
||||||
|
|||||||
@@ -2,6 +2,12 @@
|
|||||||
|
|
||||||
Public Class PluginManager
|
Public Class PluginManager
|
||||||
|
|
||||||
|
''' <summary>
|
||||||
|
''' Gets or sets an indicator if an exception should throw on error while loading a plugin.
|
||||||
|
''' </summary>
|
||||||
|
''' <returns></returns>
|
||||||
|
Public Property ThrowOnError As Boolean = False
|
||||||
|
|
||||||
''' <summary>
|
''' <summary>
|
||||||
''' The name of the type where to search for Methods when loading a new Plugin.
|
''' The name of the type where to search for Methods when loading a new Plugin.
|
||||||
''' </summary>
|
''' </summary>
|
||||||
@@ -79,7 +85,11 @@ Public Class PluginManager
|
|||||||
If addToList Then Plugins.Add(filePath, plugin)
|
If addToList Then Plugins.Add(filePath, plugin)
|
||||||
Return plugin
|
Return plugin
|
||||||
Catch ex As Exception
|
Catch ex As Exception
|
||||||
Return Nothing
|
If ThrowOnError Then
|
||||||
|
Throw
|
||||||
|
Else
|
||||||
|
Return Nothing
|
||||||
|
End If
|
||||||
End Try
|
End Try
|
||||||
End Function
|
End Function
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
Imports System.Numerics
|
Imports System.Numerics
|
||||||
|
|
||||||
Public Class Material
|
Public Class Material
|
||||||
Implements IComparable(Of Material)
|
Implements IComparable
|
||||||
|
|
||||||
Public Property Image As Image = Nothing
|
Public Property Image As Image = Nothing
|
||||||
Public Property Color As Color? = Nothing
|
Public Property Color As Color? = Nothing
|
||||||
@@ -10,11 +10,16 @@ Public Class Material
|
|||||||
Public Property Scale As New Vector2(1.0F, 1.0F)
|
Public Property Scale As New Vector2(1.0F, 1.0F)
|
||||||
Public Property Tag As Object = Nothing
|
Public Property Tag As Object = Nothing
|
||||||
|
|
||||||
Public Function CompareTo(obj As Material) As Integer Implements IComparable(Of Material).CompareTo
|
Public Function CompareTo(obj As Object) As Integer Implements IComparable.CompareTo
|
||||||
'If obj Is Me Then Return 0
|
If obj IsNot Nothing Then
|
||||||
'If obj Is Nothing Then Return 1
|
If obj Is Me Then
|
||||||
'Return -1
|
Return 0
|
||||||
Return GetHashCode() - If(obj?.GetHashCode, 0)
|
Else
|
||||||
|
Return -1
|
||||||
|
End If
|
||||||
|
Else
|
||||||
|
Return 1
|
||||||
|
End If
|
||||||
End Function
|
End Function
|
||||||
|
|
||||||
End Class
|
End Class
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<MyType>Windows</MyType>
|
<MyType>Windows</MyType>
|
||||||
<TargetFramework>net5.0-windows7.0</TargetFramework>
|
<TargetFramework>net48</TargetFramework>
|
||||||
<NoWarn>42016,41999,42017,42018,42019,42032,42036,42020,42021,42022</NoWarn>
|
<NoWarn>42016,41999,42017,42018,42019,42032,42036,42020,42021,42022</NoWarn>
|
||||||
<DocumentationFile>Pilz.Threading.xml</DocumentationFile>
|
<DocumentationFile>Pilz.Threading.xml</DocumentationFile>
|
||||||
<DefineTrace>true</DefineTrace>
|
<DefineTrace>true</DefineTrace>
|
||||||
@@ -38,6 +38,9 @@
|
|||||||
<PackageReference Include="System.Data.DataSetExtensions" Version="4.5.0" />
|
<PackageReference Include="System.Data.DataSetExtensions" Version="4.5.0" />
|
||||||
<PackageReference Include="System.Net.Http" Version="4.3.4" />
|
<PackageReference Include="System.Net.Http" Version="4.3.4" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Reference Include="System.Windows.Forms" />
|
||||||
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Import Include="Microsoft.VisualBasic" />
|
<Import Include="Microsoft.VisualBasic" />
|
||||||
<Import Include="System" />
|
<Import Include="System" />
|
||||||
|
|||||||
163
Pilz.UI/DisplayHelp.vb
Normal file
163
Pilz.UI/DisplayHelp.vb
Normal file
@@ -0,0 +1,163 @@
|
|||||||
|
Imports System.Drawing
|
||||||
|
Imports System.Drawing.Drawing2D
|
||||||
|
|
||||||
|
Public Class DisplayHelp
|
||||||
|
|
||||||
|
Public Shared Sub FillRectangle(ByVal g As Graphics, ByVal bounds As Rectangle, ByVal color1 As Color)
|
||||||
|
FillRectangle(g, bounds, color1, Color.Empty, 90)
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
Public Shared Sub FillRectangle(ByVal g As Graphics, ByVal bounds As Rectangle, ByVal color1 As Color, ByVal color2 As Color)
|
||||||
|
FillRectangle(g, bounds, color1, color2, 90)
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
Public Shared Sub FillRectangle(ByVal g As Graphics, ByVal r As Rectangle, ByVal color1 As Color, ByVal color2 As Color, ByVal gradientAngle As Integer)
|
||||||
|
If r.Width = 0 OrElse r.Height = 0 Then Return
|
||||||
|
|
||||||
|
If color2.IsEmpty Then
|
||||||
|
|
||||||
|
If Not color1.IsEmpty Then
|
||||||
|
Dim sm As SmoothingMode = g.SmoothingMode
|
||||||
|
g.SmoothingMode = SmoothingMode.None
|
||||||
|
|
||||||
|
Using brush As SolidBrush = New SolidBrush(color1)
|
||||||
|
g.FillRectangle(brush, r)
|
||||||
|
End Using
|
||||||
|
|
||||||
|
g.SmoothingMode = sm
|
||||||
|
End If
|
||||||
|
Else
|
||||||
|
|
||||||
|
Using brush As LinearGradientBrush = CreateLinearGradientBrush(r, color1, color2, gradientAngle)
|
||||||
|
g.FillRectangle(brush, r)
|
||||||
|
End Using
|
||||||
|
End If
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
Public Shared Sub FillRectangle(ByVal g As Graphics, ByVal r As Rectangle, ByVal color1 As Color, ByVal color2 As Color, ByVal gradientAngle As Integer, ByVal factors As Single(), ByVal positions As Single())
|
||||||
|
If r.Width = 0 OrElse r.Height = 0 Then Return
|
||||||
|
|
||||||
|
If color2.IsEmpty Then
|
||||||
|
|
||||||
|
If Not color1.IsEmpty Then
|
||||||
|
Dim sm As SmoothingMode = g.SmoothingMode
|
||||||
|
g.SmoothingMode = SmoothingMode.None
|
||||||
|
|
||||||
|
Using brush As SolidBrush = New SolidBrush(color1)
|
||||||
|
g.FillRectangle(brush, r)
|
||||||
|
End Using
|
||||||
|
|
||||||
|
g.SmoothingMode = sm
|
||||||
|
End If
|
||||||
|
Else
|
||||||
|
|
||||||
|
Using brush As LinearGradientBrush = CreateLinearGradientBrush(r, color1, color2, gradientAngle)
|
||||||
|
Dim blend As Blend = New Blend(factors.Length)
|
||||||
|
blend.Factors = factors
|
||||||
|
blend.Positions = positions
|
||||||
|
brush.Blend = blend
|
||||||
|
g.FillRectangle(brush, r)
|
||||||
|
End Using
|
||||||
|
End If
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
Public Shared Sub FillRoundedRectangle(ByVal g As Graphics, ByVal bounds As Rectangle, ByVal cornerSize As Integer, ByVal color1 As Color, ByVal color2 As Color, ByVal gradientAngle As Integer)
|
||||||
|
If color2.IsEmpty Then
|
||||||
|
|
||||||
|
If Not color1.IsEmpty Then
|
||||||
|
|
||||||
|
Using brush As SolidBrush = New SolidBrush(color1)
|
||||||
|
FillRoundedRectangle(g, brush, bounds, cornerSize)
|
||||||
|
End Using
|
||||||
|
End If
|
||||||
|
Else
|
||||||
|
|
||||||
|
Using brush As LinearGradientBrush = CreateLinearGradientBrush(bounds, color1, color2, gradientAngle)
|
||||||
|
FillRoundedRectangle(g, brush, bounds, cornerSize)
|
||||||
|
End Using
|
||||||
|
End If
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
Public Shared Sub FillRoundedRectangle(ByVal g As Graphics, ByVal bounds As Rectangle, ByVal cornerSize As Integer, ByVal color1 As Color, ByVal color2 As Color)
|
||||||
|
FillRoundedRectangle(g, bounds, cornerSize, color1, color2, 90)
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
Public Shared Sub FillRoundedRectangle(ByVal g As Graphics, ByVal bounds As Rectangle, ByVal cornerSize As Integer, ByVal color1 As Color)
|
||||||
|
Using brush As SolidBrush = New SolidBrush(color1)
|
||||||
|
FillRoundedRectangle(g, brush, bounds, cornerSize)
|
||||||
|
End Using
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
Public Shared Sub FillRoundedRectangle(ByVal g As Graphics, ByVal brush As Brush, ByVal bounds As Rectangle, ByVal cornerSize As Integer)
|
||||||
|
If cornerSize <= 0 Then
|
||||||
|
Dim sm As SmoothingMode = g.SmoothingMode
|
||||||
|
g.SmoothingMode = SmoothingMode.None
|
||||||
|
g.FillRectangle(brush, bounds)
|
||||||
|
g.SmoothingMode = sm
|
||||||
|
Else
|
||||||
|
bounds.Width -= 1
|
||||||
|
bounds.Height -= 1
|
||||||
|
|
||||||
|
Using path As GraphicsPath = GetRoundedRectanglePath(bounds, cornerSize)
|
||||||
|
g.FillPath(brush, path)
|
||||||
|
End Using
|
||||||
|
End If
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
Public Shared Sub DrawRectangle(ByVal g As System.Drawing.Graphics, ByVal color As Color, ByVal x As Integer, ByVal y As Integer, ByVal width As Integer, ByVal height As Integer)
|
||||||
|
Using pen As Pen = New Pen(color, 1)
|
||||||
|
DrawRectangle(g, pen, x, y, width, height)
|
||||||
|
End Using
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
Public Shared Sub DrawRectangle(ByVal g As System.Drawing.Graphics, ByVal color As Color, ByVal r As System.Drawing.Rectangle)
|
||||||
|
DrawRectangle(g, color, r.X, r.Y, r.Width, r.Height)
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
Public Shared Sub DrawRectangle(ByVal g As System.Drawing.Graphics, ByVal pen As System.Drawing.Pen, ByVal x As Integer, ByVal y As Integer, ByVal width As Integer, ByVal height As Integer)
|
||||||
|
width -= 1
|
||||||
|
height -= 1
|
||||||
|
g.DrawRectangle(pen, x, y, width, height)
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
Public Shared Sub DrawRoundedRectangle(ByVal g As System.Drawing.Graphics, ByVal color As Color, ByVal bounds As Rectangle, ByVal cornerSize As Integer)
|
||||||
|
If Not color.IsEmpty Then
|
||||||
|
|
||||||
|
Using pen As Pen = New Pen(color)
|
||||||
|
DrawRoundedRectangle(g, pen, bounds.X, bounds.Y, bounds.Width, bounds.Height, cornerSize)
|
||||||
|
End Using
|
||||||
|
End If
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
Public Shared Sub DrawRoundedRectangle(ByVal g As System.Drawing.Graphics, ByVal pen As System.Drawing.Pen, ByVal x As Integer, ByVal y As Integer, ByVal width As Integer, ByVal height As Integer, ByVal cornerSize As Integer)
|
||||||
|
DrawRoundedRectangle(g, pen, Nothing, x, y, width, height, cornerSize)
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
Public Shared Sub DrawRoundedRectangle(ByVal g As System.Drawing.Graphics, ByVal pen As System.Drawing.Pen, ByVal fill As Brush, ByVal x As Integer, ByVal y As Integer, ByVal width As Integer, ByVal height As Integer, ByVal cornerSize As Integer)
|
||||||
|
width -= 1
|
||||||
|
height -= 1
|
||||||
|
Dim r As Rectangle = New Rectangle(x, y, width, height)
|
||||||
|
|
||||||
|
Using path As GraphicsPath = GetRoundedRectanglePath(r, cornerSize)
|
||||||
|
If fill IsNot Nothing Then g.FillPath(fill, path)
|
||||||
|
g.DrawPath(pen, path)
|
||||||
|
End Using
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
Public Shared Function GetRoundedRectanglePath(ByVal r As Rectangle, ByVal cornerSize As Integer) As GraphicsPath
|
||||||
|
Dim path As GraphicsPath = New GraphicsPath()
|
||||||
|
|
||||||
|
If cornerSize = 0 Then
|
||||||
|
path.AddRectangle(r)
|
||||||
|
End If
|
||||||
|
|
||||||
|
Return path
|
||||||
|
End Function
|
||||||
|
|
||||||
|
Public Shared Function CreateLinearGradientBrush(ByVal r As Rectangle, ByVal color1 As Color, ByVal color2 As Color, ByVal gradientAngle As Single) As LinearGradientBrush
|
||||||
|
If r.Width <= 0 Then r.Width = 1
|
||||||
|
If r.Height <= 0 Then r.Height = 1
|
||||||
|
Return New LinearGradientBrush(New Rectangle(r.X, r.Y - 1, r.Width, r.Height + 1), color1, color2, gradientAngle)
|
||||||
|
End Function
|
||||||
|
|
||||||
|
End Class
|
||||||
261
Pilz.UI/HighlightPanel.vb
Normal file
261
Pilz.UI/HighlightPanel.vb
Normal file
@@ -0,0 +1,261 @@
|
|||||||
|
Imports System.Drawing
|
||||||
|
Imports System.Windows.Forms
|
||||||
|
|
||||||
|
Imports Pilz.Win32
|
||||||
|
|
||||||
|
Friend Class HighlightPanel
|
||||||
|
Inherits Control
|
||||||
|
|
||||||
|
Private _Highlights As Dictionary(Of Control, eHighlightColor) = Nothing
|
||||||
|
Private _HighlightRegions As List(Of HighlightRegion) = New List(Of HighlightRegion)()
|
||||||
|
|
||||||
|
Public Sub New(ByVal highlights As Dictionary(Of Control, eHighlightColor))
|
||||||
|
_Highlights = highlights
|
||||||
|
Me.SetStyle(ControlStyles.UserPaint, True)
|
||||||
|
Me.SetStyle(ControlStyles.AllPaintingInWmPaint, True)
|
||||||
|
Me.SetStyle(ControlStyles.Opaque, True)
|
||||||
|
Me.SetStyle(ControlStyles.ResizeRedraw, True)
|
||||||
|
Me.SetStyle(ControlStyles.OptimizedDoubleBuffer, True)
|
||||||
|
Me.SetStyle(ControlStyles.Selectable, False)
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
Protected Overrides Sub OnPaint(ByVal e As PaintEventArgs)
|
||||||
|
Dim g As Graphics = e.Graphics
|
||||||
|
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias
|
||||||
|
|
||||||
|
For Each highlightRegion As HighlightRegion In _HighlightRegions
|
||||||
|
Dim colors As Color() = GetHighlightColors(highlightRegion.HighlightColor)
|
||||||
|
Dim r As Rectangle = highlightRegion.Bounds
|
||||||
|
Dim back As Color = highlightRegion.BackColor
|
||||||
|
r.Inflate(1, 1)
|
||||||
|
DisplayHelp.FillRectangle(g, r, back)
|
||||||
|
r.Inflate(-1, -1)
|
||||||
|
DisplayHelp.FillRoundedRectangle(g, r, 2, colors(0))
|
||||||
|
r.Inflate(-2, -2)
|
||||||
|
DisplayHelp.DrawRectangle(g, colors(2), r)
|
||||||
|
r.Inflate(1, 1)
|
||||||
|
DisplayHelp.DrawRoundedRectangle(g, colors(1), r, 2)
|
||||||
|
Next
|
||||||
|
|
||||||
|
MyBase.OnPaint(e)
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
Private Function GetHighlightColors(ByVal color As eHighlightColor) As Color()
|
||||||
|
Dim colors As Color() = New Color(2) {}
|
||||||
|
|
||||||
|
If color = eHighlightColor.Blue Then
|
||||||
|
colors(0) = GetColor(172, &H6A9CD4)
|
||||||
|
colors(1) = GetColor(&H6A9CD4)
|
||||||
|
colors(2) = GetColor(&H5D7EA4)
|
||||||
|
ElseIf color = eHighlightColor.Orange Then
|
||||||
|
colors(0) = GetColor(172, &HFF9C00)
|
||||||
|
colors(1) = GetColor(&HFF9C00)
|
||||||
|
colors(2) = GetColor(&HCC6600)
|
||||||
|
ElseIf color = eHighlightColor.Green Then
|
||||||
|
colors(0) = GetColor(172, &H71B171)
|
||||||
|
colors(1) = GetColor(&H71B171)
|
||||||
|
colors(2) = GetColor(&H339933)
|
||||||
|
ElseIf color = eHighlightColor.Custom Then
|
||||||
|
If _CustomHighlightColors Is Nothing OrElse _CustomHighlightColors.Length < 3 Then
|
||||||
|
colors(0) = System.Drawing.Color.Red
|
||||||
|
colors(1) = System.Drawing.Color.Red
|
||||||
|
colors(2) = System.Drawing.Color.Red
|
||||||
|
Else
|
||||||
|
colors(0) = _CustomHighlightColors(0)
|
||||||
|
colors(1) = _CustomHighlightColors(1)
|
||||||
|
colors(2) = _CustomHighlightColors(2)
|
||||||
|
End If
|
||||||
|
Else
|
||||||
|
colors(0) = GetColor(172, &HC63030)
|
||||||
|
colors(1) = GetColor(&HC63030)
|
||||||
|
colors(2) = GetColor(&H990000)
|
||||||
|
End If
|
||||||
|
|
||||||
|
Return colors
|
||||||
|
End Function
|
||||||
|
|
||||||
|
Protected Overrides Sub OnVisibleChanged(ByVal e As EventArgs)
|
||||||
|
If Me.Visible AndAlso Not _UpdatingRegion Then UpdateRegion()
|
||||||
|
MyBase.OnVisibleChanged(e)
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
Protected Overrides Sub OnHandleCreated(ByVal e As EventArgs)
|
||||||
|
If Not _RegionInitialized Then UpdateRegion()
|
||||||
|
MyBase.OnHandleCreated(e)
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
Private _RegionInitialized As Boolean = False
|
||||||
|
Private _UpdatingRegion As Boolean = False
|
||||||
|
|
||||||
|
Friend Sub UpdateRegion()
|
||||||
|
If _UpdatingRegion OrElse Not Me.IsHandleCreated Then Return
|
||||||
|
|
||||||
|
Try
|
||||||
|
_UpdatingRegion = True
|
||||||
|
Me.Region = Nothing
|
||||||
|
_HighlightRegions.Clear()
|
||||||
|
If _Highlights Is Nothing Then Return
|
||||||
|
|
||||||
|
If _Highlights.Count = 0 AndAlso _FocusHighlightControl Is Nothing Then
|
||||||
|
Me.Visible = False
|
||||||
|
Return
|
||||||
|
End If
|
||||||
|
|
||||||
|
Dim processFocusControl As Boolean = True
|
||||||
|
Dim region As Region = Nothing
|
||||||
|
|
||||||
|
For Each item As KeyValuePair(Of Control, eHighlightColor) In _Highlights
|
||||||
|
If item.Value = eHighlightColor.None OrElse Not GetIsVisible(item.Key) Then Continue For
|
||||||
|
If item.Key Is _FocusHighlightControl Then processFocusControl = False
|
||||||
|
Dim r As Rectangle = GetControlRect(item.Key)
|
||||||
|
If r.IsEmpty Then Continue For
|
||||||
|
r.Inflate(2, 2)
|
||||||
|
_HighlightRegions.Add(New HighlightRegion(r, GetBackColor(item.Key.Parent), item.Value))
|
||||||
|
|
||||||
|
If region Is Nothing Then
|
||||||
|
region = New Region(r)
|
||||||
|
Else
|
||||||
|
region.Union(r)
|
||||||
|
End If
|
||||||
|
|
||||||
|
r.Inflate(-3, -3)
|
||||||
|
region.Exclude(r)
|
||||||
|
Next
|
||||||
|
|
||||||
|
If processFocusControl AndAlso _FocusHighlightControl IsNot Nothing AndAlso _FocusHighlightControl.Visible Then
|
||||||
|
Dim r As Rectangle = GetControlRect(_FocusHighlightControl)
|
||||||
|
|
||||||
|
If Not r.IsEmpty Then
|
||||||
|
r.Inflate(2, 2)
|
||||||
|
_HighlightRegions.Add(New HighlightRegion(r, GetBackColor(_FocusHighlightControl.Parent), _FocusHighlightColor))
|
||||||
|
|
||||||
|
If region Is Nothing Then
|
||||||
|
region = New Region(r)
|
||||||
|
Else
|
||||||
|
region.Union(r)
|
||||||
|
End If
|
||||||
|
|
||||||
|
r.Inflate(-3, -3)
|
||||||
|
region.Exclude(r)
|
||||||
|
End If
|
||||||
|
End If
|
||||||
|
|
||||||
|
Me.Region = region
|
||||||
|
|
||||||
|
If region Is Nothing Then
|
||||||
|
Me.Visible = False
|
||||||
|
ElseIf Not Me.Visible Then
|
||||||
|
Me.Visible = True
|
||||||
|
Me.BringToFront()
|
||||||
|
End If
|
||||||
|
|
||||||
|
Me.Invalidate()
|
||||||
|
Finally
|
||||||
|
_UpdatingRegion = False
|
||||||
|
_RegionInitialized = True
|
||||||
|
End Try
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
Private Shared Function GetColor(rgb As Integer) As Color
|
||||||
|
If rgb = -1 Then
|
||||||
|
Return Color.Empty
|
||||||
|
Else
|
||||||
|
Return Color.FromArgb((rgb And &HFF0000) >> 16, (rgb And &HFF00) >> 8, rgb And &HFF)
|
||||||
|
End If
|
||||||
|
End Function
|
||||||
|
|
||||||
|
Private Shared Function GetColor(alpha As Integer, rgb As Integer) As Color
|
||||||
|
If rgb = -1 Then
|
||||||
|
Return Color.Empty
|
||||||
|
Else
|
||||||
|
Return Color.FromArgb(alpha, (rgb And &HFF0000) >> 16, (rgb And &HFF00) >> 8, rgb And &HFF)
|
||||||
|
End If
|
||||||
|
End Function
|
||||||
|
|
||||||
|
Private Function GetIsVisible(ByVal control As Control) As Boolean
|
||||||
|
If Not control.Visible Then Return False
|
||||||
|
If control.Parent Is Nothing OrElse Not control.IsHandleCreated Then Return control.Visible
|
||||||
|
Dim rect As New Native.RECT
|
||||||
|
Native.User32.GetWindowRect(control.Handle, rect)
|
||||||
|
Dim pp As Point = control.Parent.PointToClient(New Point(rect.Left + 3, rect.Top + 3))
|
||||||
|
Dim handle As IntPtr = Native.User32.ChildWindowFromPointEx(control.Parent.Handle, New Native.POINT(pp.X, pp.Y), CUInt(Native.WindowFromPointFlags.CWP_SKIPINVISIBLE))
|
||||||
|
If handle = IntPtr.Zero Then Return control.Visible
|
||||||
|
Dim c As Control = Control.FromHandle(handle)
|
||||||
|
|
||||||
|
If c IsNot Nothing AndAlso c IsNot control AndAlso c IsNot Me AndAlso c IsNot control.Parent Then
|
||||||
|
Return False
|
||||||
|
End If
|
||||||
|
|
||||||
|
Return control.Visible
|
||||||
|
End Function
|
||||||
|
|
||||||
|
Private Function GetBackColor(ByVal control As Control) As Color
|
||||||
|
Dim backColor As Color = control.BackColor
|
||||||
|
|
||||||
|
If backColor.IsEmpty OrElse backColor = Color.Transparent Then
|
||||||
|
backColor = SystemColors.Control
|
||||||
|
ElseIf backColor.A < 255 Then
|
||||||
|
backColor = Color.FromArgb(255, backColor)
|
||||||
|
End If
|
||||||
|
|
||||||
|
Return backColor
|
||||||
|
End Function
|
||||||
|
|
||||||
|
Protected Overrides Sub OnResize(ByVal e As EventArgs)
|
||||||
|
UpdateRegion()
|
||||||
|
MyBase.OnResize(e)
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
Private Function GetControlRect(ByVal c As Control) As Rectangle
|
||||||
|
If Not c.IsHandleCreated Then Return Rectangle.Empty
|
||||||
|
Dim rect As Native.RECT
|
||||||
|
Native.User32.GetWindowRect(c.Handle, rect)
|
||||||
|
Dim p As Point = Me.PointToClient(rect.Location)
|
||||||
|
Return New Rectangle(p, rect.Size)
|
||||||
|
End Function
|
||||||
|
|
||||||
|
Private Structure HighlightRegion
|
||||||
|
Public Bounds As Rectangle
|
||||||
|
Public BackColor As Color
|
||||||
|
Public HighlightColor As eHighlightColor
|
||||||
|
|
||||||
|
Public Sub New(ByVal bounds As Rectangle, ByVal backColor As Color, ByVal highlightColor As eHighlightColor)
|
||||||
|
Me.Bounds = bounds
|
||||||
|
Me.BackColor = backColor
|
||||||
|
Me.HighlightColor = highlightColor
|
||||||
|
End Sub
|
||||||
|
End Structure
|
||||||
|
|
||||||
|
Private _FocusHighlightControl As Control
|
||||||
|
|
||||||
|
Public Property FocusHighlightControl As Control
|
||||||
|
Get
|
||||||
|
Return _FocusHighlightControl
|
||||||
|
End Get
|
||||||
|
Set(ByVal value As Control)
|
||||||
|
_FocusHighlightControl = value
|
||||||
|
End Set
|
||||||
|
End Property
|
||||||
|
|
||||||
|
Private _FocusHighlightColor As eHighlightColor = eHighlightColor.Blue
|
||||||
|
|
||||||
|
Public Property FocusHighlightColor As eHighlightColor
|
||||||
|
Get
|
||||||
|
Return _FocusHighlightColor
|
||||||
|
End Get
|
||||||
|
Set(ByVal value As eHighlightColor)
|
||||||
|
_FocusHighlightColor = value
|
||||||
|
End Set
|
||||||
|
End Property
|
||||||
|
|
||||||
|
Private _CustomHighlightColors As Color() = Nothing
|
||||||
|
|
||||||
|
Public Property CustomHighlightColors As Color()
|
||||||
|
Get
|
||||||
|
Return _CustomHighlightColors
|
||||||
|
End Get
|
||||||
|
Set(ByVal value As Color())
|
||||||
|
_CustomHighlightColors = value
|
||||||
|
End Set
|
||||||
|
End Property
|
||||||
|
End Class
|
||||||
409
Pilz.UI/Highlighter.vb
Normal file
409
Pilz.UI/Highlighter.vb
Normal file
@@ -0,0 +1,409 @@
|
|||||||
|
Imports System
|
||||||
|
Imports System.Collections.Generic
|
||||||
|
Imports System.ComponentModel
|
||||||
|
Imports System.Windows.Forms
|
||||||
|
Imports System.Drawing
|
||||||
|
|
||||||
|
Public Class Highlighter
|
||||||
|
Inherits Component
|
||||||
|
|
||||||
|
Private _Highlights As Dictionary(Of Control, eHighlightColor) = New Dictionary(Of Control, eHighlightColor)()
|
||||||
|
Private _HighlightOnFocus As Dictionary(Of Control, Boolean) = New Dictionary(Of Control, Boolean)()
|
||||||
|
|
||||||
|
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
|
||||||
|
If _ContainerControl IsNot Nothing Then
|
||||||
|
RemoveHandler _ContainerControl.SizeChanged, AddressOf ContainerControlSizeChanged
|
||||||
|
RemoveHandler _ContainerControl.HandleCreated, AddressOf ContainerControlHandleCreated
|
||||||
|
End If
|
||||||
|
|
||||||
|
If _HighlightPanel IsNot Nothing AndAlso _HighlightPanel.Parent Is Nothing AndAlso Not _HighlightPanel.IsDisposed Then
|
||||||
|
_HighlightPanel.Dispose()
|
||||||
|
_HighlightPanel = Nothing
|
||||||
|
Else
|
||||||
|
_HighlightPanel = Nothing
|
||||||
|
End If
|
||||||
|
|
||||||
|
MyBase.Dispose(disposing)
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
<DefaultValue(False), Localizable(True), Description("Indicates whether control is highlighted when it receives input focus.")>
|
||||||
|
Public Function GetHighlightOnFocus(ByVal c As Control) As Boolean
|
||||||
|
If _HighlightOnFocus.ContainsKey(c) Then
|
||||||
|
Return _HighlightOnFocus(c)
|
||||||
|
End If
|
||||||
|
|
||||||
|
Return False
|
||||||
|
End Function
|
||||||
|
|
||||||
|
Public Sub SetHighlightOnFocus(ByVal c As Control, ByVal highlight As Boolean)
|
||||||
|
If c Is Nothing Then Throw New NullReferenceException()
|
||||||
|
|
||||||
|
If _HighlightOnFocus.ContainsKey(c) Then
|
||||||
|
|
||||||
|
If Not highlight Then
|
||||||
|
RemoveHighlightOnFocus(_HighlightOnFocus, c)
|
||||||
|
End If
|
||||||
|
|
||||||
|
Return
|
||||||
|
End If
|
||||||
|
|
||||||
|
If highlight Then AddHighlightOnFocus(_HighlightOnFocus, c)
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
Private Sub AddHighlightOnFocus(ByVal highlightOnFocus As Dictionary(Of Control, Boolean), ByVal c As Control)
|
||||||
|
AddHandler c.Enter, AddressOf ControlHighlightEnter
|
||||||
|
AddHandler c.Leave, AddressOf ControlHighlightLeave
|
||||||
|
AddHandler c.VisibleChanged, AddressOf ControlHighlightVisibleChanged
|
||||||
|
highlightOnFocus.Add(c, True)
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
Private Sub ControlHighlightVisibleChanged(ByVal sender As Object, ByVal e As EventArgs)
|
||||||
|
If _HighlightPanel IsNot Nothing AndAlso _HighlightPanel.FocusHighlightControl = sender Then UpdateHighlighterRegion()
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
Private Sub ControlHighlightLeave(ByVal sender As Object, ByVal e As EventArgs)
|
||||||
|
If _HighlightPanel IsNot Nothing Then _HighlightPanel.FocusHighlightControl = Nothing
|
||||||
|
UpdateHighlighterRegion()
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
Private Sub ControlHighlightEnter(ByVal sender As Object, ByVal e As EventArgs)
|
||||||
|
If _HighlightPanel IsNot Nothing Then
|
||||||
|
If Not _HighlightPanel.Visible Then _HighlightPanel.Visible = True
|
||||||
|
_HighlightPanel.BringToFront()
|
||||||
|
_HighlightPanel.FocusHighlightControl = CType(sender, Control)
|
||||||
|
End If
|
||||||
|
|
||||||
|
UpdateHighlighterRegion()
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
Private Sub RemoveHighlightOnFocus(ByVal highlightOnFocus As Dictionary(Of Control, Boolean), ByVal c As Control)
|
||||||
|
RemoveHandler c.Enter, AddressOf ControlHighlightEnter
|
||||||
|
RemoveHandler c.Leave, AddressOf ControlHighlightLeave
|
||||||
|
RemoveHandler c.VisibleChanged, AddressOf ControlHighlightVisibleChanged
|
||||||
|
highlightOnFocus.Remove(c)
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
<DefaultValue(eHighlightColor.None), Localizable(True), Description("Indicates the highlight color that is applied to the control.")>
|
||||||
|
Public Function GetHighlightColor(ByVal c As Control) As eHighlightColor
|
||||||
|
If _Highlights.ContainsKey(c) Then
|
||||||
|
Return _Highlights(c)
|
||||||
|
End If
|
||||||
|
|
||||||
|
Return eHighlightColor.None
|
||||||
|
End Function
|
||||||
|
|
||||||
|
Public Sub SetHighlightColor(ByVal c As Control, ByVal highlightColor As eHighlightColor)
|
||||||
|
If _Highlights.ContainsKey(c) Then
|
||||||
|
|
||||||
|
If highlightColor = eHighlightColor.None Then
|
||||||
|
RemoveHighlight(_Highlights, c)
|
||||||
|
Else
|
||||||
|
Dim color As eHighlightColor = _Highlights(c)
|
||||||
|
RemoveHighlight(_Highlights, c)
|
||||||
|
AddHighlight(_Highlights, c, highlightColor)
|
||||||
|
End If
|
||||||
|
ElseIf highlightColor <> eHighlightColor.None Then
|
||||||
|
AddHighlight(_Highlights, c, highlightColor)
|
||||||
|
End If
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
Private _TabControl2 As Dictionary(Of System.Windows.Forms.TabControl, Integer) = New Dictionary(Of System.Windows.Forms.TabControl, Integer)()
|
||||||
|
Private _ParentPanel As Dictionary(Of Panel, Integer) = New Dictionary(Of Panel, Integer)()
|
||||||
|
|
||||||
|
Private Sub AddHighlight(ByVal highlights As Dictionary(Of Control, eHighlightColor), ByVal c As Control, ByVal highlightColor As eHighlightColor)
|
||||||
|
highlights.Add(c, highlightColor)
|
||||||
|
AddHandler c.LocationChanged, New EventHandler(AddressOf ControlLocationChanged)
|
||||||
|
AddHandler c.SizeChanged, New EventHandler(AddressOf ControlSizeChanged)
|
||||||
|
AddHandler c.VisibleChanged, New EventHandler(AddressOf ControlVisibleChanged)
|
||||||
|
|
||||||
|
If _HighlightPanel IsNot Nothing Then
|
||||||
|
If Not _HighlightPanel.Visible Then _HighlightPanel.Visible = True
|
||||||
|
_HighlightPanel.BringToFront()
|
||||||
|
End If
|
||||||
|
|
||||||
|
If c.Parent Is Nothing Then
|
||||||
|
AddHandler c.ParentChanged, AddressOf ControlParentChanged
|
||||||
|
Else
|
||||||
|
AddTabControlHandlers(c)
|
||||||
|
End If
|
||||||
|
|
||||||
|
UpdateHighlighterRegion()
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
Private Sub ControlParentChanged(ByVal sender As Object, ByVal e As EventArgs)
|
||||||
|
Dim c As Control = CType(sender, Control)
|
||||||
|
RemoveHandler c.ParentChanged, AddressOf ControlParentChanged
|
||||||
|
AddTabControlHandlers(c)
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
Private Sub AddTabControlHandlers(ByVal c As Control)
|
||||||
|
Dim tab2 As System.Windows.Forms.TabControl = TryCast(GetParentControl(c, GetType(System.Windows.Forms.TabControl)), System.Windows.Forms.TabControl)
|
||||||
|
|
||||||
|
If tab2 IsNot Nothing Then
|
||||||
|
|
||||||
|
If _TabControl2.ContainsKey(tab2) Then
|
||||||
|
_TabControl2(tab2) = _TabControl2(tab2) + 1
|
||||||
|
Else
|
||||||
|
_TabControl2.Add(tab2, 1)
|
||||||
|
AddHandler tab2.SelectedIndexChanged, AddressOf WinFormsTabSelectedIndexChanged
|
||||||
|
End If
|
||||||
|
Else
|
||||||
|
Dim parentPanel As Panel = TryCast(GetParentControl(c, GetType(Panel)), Panel)
|
||||||
|
|
||||||
|
If parentPanel IsNot Nothing Then
|
||||||
|
|
||||||
|
If _ParentPanel.ContainsKey(parentPanel) Then
|
||||||
|
_ParentPanel(parentPanel) = _ParentPanel(parentPanel) + 1
|
||||||
|
Else
|
||||||
|
_ParentPanel.Add(parentPanel, 1)
|
||||||
|
AddHandler parentPanel.Resize, AddressOf ParentPanelResized
|
||||||
|
AddHandler parentPanel.LocationChanged, AddressOf ParentPanelLocationChanged
|
||||||
|
End If
|
||||||
|
End If
|
||||||
|
End If
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
Private Sub ParentPanelLocationChanged(ByVal sender As Object, ByVal e As EventArgs)
|
||||||
|
UpdateHighlights()
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
Private Sub ParentPanelResized(ByVal sender As Object, ByVal e As EventArgs)
|
||||||
|
UpdateHighlights()
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
Private Sub WinFormsTabSelectedIndexChanged(ByVal sender As Object, ByVal e As EventArgs)
|
||||||
|
UpdateHighlighterRegion()
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
Private Function GetParentControl(ByVal c As Control, ByVal parentType As Type) As Control
|
||||||
|
Dim parent As Control = c.Parent
|
||||||
|
|
||||||
|
While parent IsNot Nothing
|
||||||
|
If parentType.IsAssignableFrom(parent.[GetType]()) Then Return parent
|
||||||
|
parent = parent.Parent
|
||||||
|
End While
|
||||||
|
|
||||||
|
Return Nothing
|
||||||
|
End Function
|
||||||
|
|
||||||
|
Private Sub ControlVisibleChanged(ByVal sender As Object, ByVal e As EventArgs)
|
||||||
|
UpdateHighlighterRegion()
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
Private Sub ControlSizeChanged(ByVal sender As Object, ByVal e As EventArgs)
|
||||||
|
UpdateHighlighterRegion()
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
Private Sub ControlLocationChanged(ByVal sender As Object, ByVal e As EventArgs)
|
||||||
|
UpdateHighlighterRegion()
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
Private Sub UpdateHighlighterRegion()
|
||||||
|
If _HighlightPanel IsNot Nothing Then _HighlightPanel.UpdateRegion()
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
Public Sub UpdateHighlights()
|
||||||
|
UpdateHighlighterRegion()
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
Private Sub RemoveHighlight(ByVal highlights As Dictionary(Of Control, eHighlightColor), ByVal c As Control)
|
||||||
|
highlights.Remove(c)
|
||||||
|
RemoveHandler c.LocationChanged, New EventHandler(AddressOf ControlLocationChanged)
|
||||||
|
RemoveHandler c.SizeChanged, New EventHandler(AddressOf ControlSizeChanged)
|
||||||
|
RemoveHandler c.VisibleChanged, New EventHandler(AddressOf ControlVisibleChanged)
|
||||||
|
Dim tab2 As System.Windows.Forms.TabControl = TryCast(GetParentControl(c, GetType(System.Windows.Forms.TabControl)), System.Windows.Forms.TabControl)
|
||||||
|
|
||||||
|
If tab2 IsNot Nothing Then
|
||||||
|
|
||||||
|
If _TabControl2.ContainsKey(tab2) Then
|
||||||
|
|
||||||
|
If _TabControl2(tab2) = 1 Then
|
||||||
|
_TabControl2.Remove(tab2)
|
||||||
|
RemoveHandler tab2.SelectedIndexChanged, AddressOf WinFormsTabSelectedIndexChanged
|
||||||
|
Else
|
||||||
|
_TabControl2(tab2) = _TabControl2(tab2) - 1
|
||||||
|
End If
|
||||||
|
End If
|
||||||
|
Else
|
||||||
|
Dim parentPanel As Panel = TryCast(GetParentControl(c, GetType(Panel)), Panel)
|
||||||
|
|
||||||
|
If parentPanel IsNot Nothing Then
|
||||||
|
|
||||||
|
If _ParentPanel.ContainsKey(parentPanel) Then
|
||||||
|
|
||||||
|
If _ParentPanel(parentPanel) = 1 Then
|
||||||
|
_ParentPanel.Remove(parentPanel)
|
||||||
|
RemoveHandler parentPanel.LocationChanged, AddressOf ParentPanelLocationChanged
|
||||||
|
RemoveHandler parentPanel.SizeChanged, AddressOf ParentPanelResized
|
||||||
|
Else
|
||||||
|
_ParentPanel(parentPanel) = _ParentPanel(parentPanel) - 1
|
||||||
|
End If
|
||||||
|
End If
|
||||||
|
End If
|
||||||
|
End If
|
||||||
|
|
||||||
|
UpdateHighlighterRegion()
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
Friend ReadOnly Property Highlights As Dictionary(Of Control, eHighlightColor)
|
||||||
|
Get
|
||||||
|
Return _Highlights
|
||||||
|
End Get
|
||||||
|
End Property
|
||||||
|
|
||||||
|
Private _FocusHighlightColor As eHighlightColor = eHighlightColor.Blue
|
||||||
|
|
||||||
|
<DefaultValue(eHighlightColor.Blue), Category("Appearance"), Description("Indicates the highlight focus color."), Localizable(True)>
|
||||||
|
Public Property FocusHighlightColor As eHighlightColor
|
||||||
|
Get
|
||||||
|
Return _FocusHighlightColor
|
||||||
|
End Get
|
||||||
|
Set(ByVal value As eHighlightColor)
|
||||||
|
_FocusHighlightColor = value
|
||||||
|
|
||||||
|
If _HighlightPanel IsNot Nothing Then
|
||||||
|
_HighlightPanel.FocusHighlightColor = value
|
||||||
|
UpdateHighlighterRegion()
|
||||||
|
End If
|
||||||
|
End Set
|
||||||
|
End Property
|
||||||
|
|
||||||
|
Private _HighlightPanel As HighlightPanel = Nothing
|
||||||
|
Private _ContainerControl As Control = Nothing
|
||||||
|
|
||||||
|
<Description("Indicates container control highlighter is bound to. Should be set to parent form."), Category("Behavior")>
|
||||||
|
Public Property ContainerControl As Control
|
||||||
|
Get
|
||||||
|
Return _ContainerControl
|
||||||
|
End Get
|
||||||
|
Set(ByVal value As Control)
|
||||||
|
|
||||||
|
If Me.DesignMode Then
|
||||||
|
_ContainerControl = value
|
||||||
|
Return
|
||||||
|
End If
|
||||||
|
|
||||||
|
If _ContainerControl IsNot value Then
|
||||||
|
|
||||||
|
If _ContainerControl IsNot Nothing Then
|
||||||
|
RemoveHandler _ContainerControl.SizeChanged, AddressOf ContainerControlSizeChanged
|
||||||
|
RemoveHandler _ContainerControl.HandleCreated, AddressOf ContainerControlHandleCreated
|
||||||
|
If _HighlightPanel IsNot Nothing AndAlso _HighlightPanel.Parent Is _ContainerControl Then _ContainerControl.Controls.Remove(_HighlightPanel)
|
||||||
|
End If
|
||||||
|
|
||||||
|
_ContainerControl = value
|
||||||
|
|
||||||
|
If _ContainerControl IsNot Nothing Then
|
||||||
|
|
||||||
|
If _HighlightPanel Is Nothing Then
|
||||||
|
_HighlightPanel = New HighlightPanel(_Highlights)
|
||||||
|
_HighlightPanel.FocusHighlightColor = _FocusHighlightColor
|
||||||
|
_HighlightPanel.Margin = New System.Windows.Forms.Padding(0)
|
||||||
|
_HighlightPanel.Padding = New System.Windows.Forms.Padding(0)
|
||||||
|
_HighlightPanel.CustomHighlightColors = _CustomHighlightColors
|
||||||
|
_HighlightPanel.Visible = False
|
||||||
|
End If
|
||||||
|
|
||||||
|
AddHandler _ContainerControl.SizeChanged, AddressOf ContainerControlSizeChanged
|
||||||
|
AddHandler _ContainerControl.HandleCreated, AddressOf ContainerControlHandleCreated
|
||||||
|
_ContainerControl.Controls.Add(_HighlightPanel)
|
||||||
|
UpdateHighlightPanelBounds()
|
||||||
|
End If
|
||||||
|
End If
|
||||||
|
End Set
|
||||||
|
End Property
|
||||||
|
|
||||||
|
Private Sub ContainerControlHandleCreated(ByVal sender As Object, ByVal e As EventArgs)
|
||||||
|
If _Highlights.Count > 0 AndAlso _HighlightPanel IsNot Nothing AndAlso Not _HighlightPanel.Visible Then _HighlightPanel.Visible = True
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
Private Sub UpdateHighlightPanelBounds()
|
||||||
|
Dim bounds As Rectangle = New Rectangle(0, 0, _ContainerControl.ClientRectangle.Width, _ContainerControl.ClientRectangle.Height)
|
||||||
|
|
||||||
|
If TypeOf _HighlightPanel.Parent Is Form Then
|
||||||
|
Dim form As Form = TryCast(_HighlightPanel.Parent, Form)
|
||||||
|
|
||||||
|
If form.AutoSize Then
|
||||||
|
bounds.X += form.Padding.Left
|
||||||
|
bounds.Y += form.Padding.Top
|
||||||
|
bounds.Width -= form.Padding.Horizontal
|
||||||
|
bounds.Height -= form.Padding.Vertical
|
||||||
|
End If
|
||||||
|
End If
|
||||||
|
|
||||||
|
If _HighlightPanel.Bounds.Equals(bounds) Then
|
||||||
|
_HighlightPanel.UpdateRegion()
|
||||||
|
Else
|
||||||
|
_HighlightPanel.Bounds = bounds
|
||||||
|
End If
|
||||||
|
|
||||||
|
_HighlightPanel.BringToFront()
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
Private _DelayTimer As Timer = Nothing
|
||||||
|
|
||||||
|
Private Sub ContainerControlSizeChanged(ByVal sender As Object, ByVal e As EventArgs)
|
||||||
|
Dim form As Form = TryCast(sender, Form)
|
||||||
|
|
||||||
|
If form IsNot Nothing Then
|
||||||
|
|
||||||
|
If _DelayTimer Is Nothing Then
|
||||||
|
_DelayTimer = New Timer()
|
||||||
|
_DelayTimer.Interval = 100
|
||||||
|
AddHandler _DelayTimer.Tick, New EventHandler(AddressOf DelayTimerTick)
|
||||||
|
_DelayTimer.Start()
|
||||||
|
End If
|
||||||
|
|
||||||
|
Return
|
||||||
|
End If
|
||||||
|
|
||||||
|
UpdateHighlightPanelBounds()
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
Private Sub DelayTimerTick(ByVal sender As Object, ByVal e As EventArgs)
|
||||||
|
Dim timer As Timer = _DelayTimer
|
||||||
|
_DelayTimer = Nothing
|
||||||
|
RemoveHandler timer.Tick, New EventHandler(AddressOf DelayTimerTick)
|
||||||
|
timer.[Stop]()
|
||||||
|
timer.Dispose()
|
||||||
|
UpdateHighlightPanelBounds()
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
Private _CustomHighlightColors As Color() = Nothing
|
||||||
|
|
||||||
|
<Category("Appearance"), Description("Array of colors used to render custom highlight color. Control expects 3 colors in array to be specified which define the highlight border.")>
|
||||||
|
Public Property CustomHighlightColors As Color()
|
||||||
|
Get
|
||||||
|
Return _CustomHighlightColors
|
||||||
|
End Get
|
||||||
|
Set(ByVal value As Color())
|
||||||
|
_CustomHighlightColors = value
|
||||||
|
|
||||||
|
If _HighlightPanel IsNot Nothing Then
|
||||||
|
_HighlightPanel.CustomHighlightColors = _CustomHighlightColors
|
||||||
|
_HighlightPanel.Invalidate()
|
||||||
|
End If
|
||||||
|
End Set
|
||||||
|
End Property
|
||||||
|
|
||||||
|
Public Function CanExtend(ByVal extendee As Object) As Boolean
|
||||||
|
Return (TypeOf extendee Is Control)
|
||||||
|
End Function
|
||||||
|
|
||||||
|
Private Sub SetError(ByVal control As Control, ByVal value As String)
|
||||||
|
Me.SetHighlightColor(control, eHighlightColor.Red)
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
Private Sub ClearError(ByVal control As Control)
|
||||||
|
Me.SetHighlightColor(control, eHighlightColor.None)
|
||||||
|
End Sub
|
||||||
|
End Class
|
||||||
|
|
||||||
|
Public Enum eHighlightColor
|
||||||
|
None
|
||||||
|
Red
|
||||||
|
Blue
|
||||||
|
Green
|
||||||
|
Orange
|
||||||
|
Custom
|
||||||
|
End Enum
|
||||||
15
Pilz.UI/PaintingControl/ArrowLineCapProps.vb
Normal file
15
Pilz.UI/PaintingControl/ArrowLineCapProps.vb
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
Imports System.Drawing
|
||||||
|
Imports System.Drawing.Drawing2D
|
||||||
|
|
||||||
|
Public Class ArrowLineCapProps
|
||||||
|
Inherits LineCapProps
|
||||||
|
|
||||||
|
Public Property Size As New Size(10, 10)
|
||||||
|
Public Property IsFilles As Boolean = True
|
||||||
|
|
||||||
|
Friend Overrides Function Configure() As LineCapConfigurationArgs
|
||||||
|
Dim cap As New AdjustableArrowCap(Size.Width, Size.Height, IsFilles)
|
||||||
|
Return New LineCapConfigurationArgs(cap)
|
||||||
|
End Function
|
||||||
|
|
||||||
|
End Class
|
||||||
@@ -112,7 +112,22 @@ Public Class DefaultDrawMethodes
|
|||||||
|
|
||||||
Public Shared Sub DrawLine(e As PaintingObjectPaintEventArgs)
|
Public Shared Sub DrawLine(e As PaintingObjectPaintEventArgs)
|
||||||
Dim obj As PaintingObject = e.PaintingObject
|
Dim obj As PaintingObject = e.PaintingObject
|
||||||
Dim p2 As New Pen(obj.OutlineColor, obj.OutlineThicknes) With {.DashStyle = obj.OutlineDashStyle}
|
Dim p2 As New Pen(obj.OutlineColor, obj.OutlineThicknes) With {
|
||||||
|
.DashStyle = obj.OutlineDashStyle
|
||||||
|
}
|
||||||
|
|
||||||
|
If obj.LineEndCap IsNot Nothing Then
|
||||||
|
Dim args As LineCapConfigurationArgs = obj.LineEndCap.Configure
|
||||||
|
p2.StartCap = args.LineCap
|
||||||
|
p2.CustomStartCap = args.CustomLineCap
|
||||||
|
End If
|
||||||
|
|
||||||
|
If obj.LineStartCap IsNot Nothing Then
|
||||||
|
Dim args As LineCapConfigurationArgs = obj.LineStartCap.Configure
|
||||||
|
p2.EndCap = args.LineCap
|
||||||
|
p2.CustomEndCap = args.CustomLineCap
|
||||||
|
End If
|
||||||
|
|
||||||
p2.Alignment = PenAlignment.Center
|
p2.Alignment = PenAlignment.Center
|
||||||
Dim no As PointF = New PointF(e.X, e.Y)
|
Dim no As PointF = New PointF(e.X, e.Y)
|
||||||
e.Graphics.DrawLine(p2, no, no + obj.Size)
|
e.Graphics.DrawLine(p2, no, no + obj.Size)
|
||||||
|
|||||||
13
Pilz.UI/PaintingControl/DefaultLineCapProps.vb
Normal file
13
Pilz.UI/PaintingControl/DefaultLineCapProps.vb
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
Imports System.Drawing.Drawing2D
|
||||||
|
|
||||||
|
Public Class DefaultLineCapProps
|
||||||
|
Inherits LineCapProps
|
||||||
|
|
||||||
|
Public Property LineCap As LineCap = LineCap.Flat
|
||||||
|
Public Property CustomLineCap As CustomLineCap = Nothing
|
||||||
|
|
||||||
|
Friend Overrides Function Configure() As LineCapConfigurationArgs
|
||||||
|
Return New LineCapConfigurationArgs(LineCap, CustomLineCap)
|
||||||
|
End Function
|
||||||
|
|
||||||
|
End Class
|
||||||
21
Pilz.UI/PaintingControl/LineCapConfigurationArgs.vb
Normal file
21
Pilz.UI/PaintingControl/LineCapConfigurationArgs.vb
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
Imports System.Drawing.Drawing2D
|
||||||
|
|
||||||
|
Public Class LineCapConfigurationArgs
|
||||||
|
|
||||||
|
Public ReadOnly Property LineCap As LineCap
|
||||||
|
Public ReadOnly Property CustomLineCap As CustomLineCap
|
||||||
|
|
||||||
|
Public Sub New(lineCap As LineCap)
|
||||||
|
Me.New(lineCap, Nothing)
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
Public Sub New(customLineCap As CustomLineCap)
|
||||||
|
Me.New(Nothing, customLineCap)
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
Public Sub New(lineCap As LineCap, customLineCap As CustomLineCap)
|
||||||
|
Me.LineCap = lineCap
|
||||||
|
Me.CustomLineCap = customLineCap
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
End Class
|
||||||
7
Pilz.UI/PaintingControl/LineCapProps.vb
Normal file
7
Pilz.UI/PaintingControl/LineCapProps.vb
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
Imports System.Drawing
|
||||||
|
|
||||||
|
Public MustInherit Class LineCapProps
|
||||||
|
|
||||||
|
Friend MustOverride Function Configure() As LineCapConfigurationArgs
|
||||||
|
|
||||||
|
End Class
|
||||||
@@ -196,7 +196,7 @@ Public Class PaintingControl
|
|||||||
End If
|
End If
|
||||||
End If
|
End If
|
||||||
|
|
||||||
If pressedControl Then
|
If pressedAlt Then
|
||||||
|
|
||||||
calcOffset_MouseOnTab = New Point(e.X, e.Y)
|
calcOffset_MouseOnTab = New Point(e.X, e.Y)
|
||||||
calcOffset_LastOffset = Offset
|
calcOffset_LastOffset = Offset
|
||||||
@@ -281,7 +281,7 @@ Public Class PaintingControl
|
|||||||
End If
|
End If
|
||||||
|
|
||||||
If calcOffset_IsActive Then
|
If calcOffset_IsActive Then
|
||||||
If pressedControl Then
|
If pressedAlt Then
|
||||||
CalcNewOffset(e.Location)
|
CalcNewOffset(e.Location)
|
||||||
Else
|
Else
|
||||||
calcOffset_IsActive = False
|
calcOffset_IsActive = False
|
||||||
@@ -314,7 +314,7 @@ Public Class PaintingControl
|
|||||||
|
|
||||||
Private Sub SaveObjectPositions(e As MouseEventArgs, objs As IList)
|
Private Sub SaveObjectPositions(e As MouseEventArgs, objs As IList)
|
||||||
For Each obj As PaintingObject In objs
|
For Each obj As PaintingObject In objs
|
||||||
If Not savedPos.ContainsKey(obj) Then
|
If Not obj.HardcodedLocation AndAlso Not savedPos.ContainsKey(obj) Then
|
||||||
savedPos.Add(obj, New PointF(e.X - obj.Location.X + Offset.X, e.Y - obj.Location.Y + Offset.Y))
|
savedPos.Add(obj, New PointF(e.X - obj.Location.X + Offset.X, e.Y - obj.Location.Y + Offset.Y))
|
||||||
SaveObjectPositions(e, obj.PinnedObjects)
|
SaveObjectPositions(e, obj.PinnedObjects)
|
||||||
End If
|
End If
|
||||||
|
|||||||
@@ -19,35 +19,48 @@ Imports Newtonsoft.Json
|
|||||||
Public Property OutlineColor As Color = Color.DarkBlue
|
Public Property OutlineColor As Color = Color.DarkBlue
|
||||||
Public Property OutlineThicknes As Single = 1
|
Public Property OutlineThicknes As Single = 1
|
||||||
Public Property OutlineDashStyle As DashStyle = DashStyle.Solid
|
Public Property OutlineDashStyle As DashStyle = DashStyle.Solid
|
||||||
|
Public Property LineStartCap As LineCapProps = Nothing
|
||||||
|
Public Property LineEndCap As LineCapProps = Nothing
|
||||||
|
<JsonProperty>
|
||||||
Private _Text As String = ""
|
Private _Text As String = ""
|
||||||
Public Property TextPosition As TextPosition = TextPosition.FullCenter
|
Public Property TextPosition As TextPosition = TextPosition.FullCenter
|
||||||
Public Property VerticalTextAlignment As StringAlignment = StringAlignment.Center
|
Public Property VerticalTextAlignment As StringAlignment = StringAlignment.Center
|
||||||
Public Property HorizontalTextAlignment As StringAlignment = StringAlignment.Center
|
Public Property HorizontalTextAlignment As StringAlignment = StringAlignment.Center
|
||||||
Public Property TextFont As New Font(FontFamily.GenericSansSerif, 8.25)
|
Public Property TextFont As New Font(FontFamily.GenericSansSerif, 8.25)
|
||||||
Public Property TextColor As Color = Color.Black
|
Public Property TextColor As Color = Color.Black
|
||||||
|
<JsonProperty>
|
||||||
Private _Location As New PointF(50, 50)
|
Private _Location As New PointF(50, 50)
|
||||||
|
<JsonProperty>
|
||||||
Private _Size As New SizeF(50, 80)
|
Private _Size As New SizeF(50, 80)
|
||||||
Public Property EnableFill As Boolean = True
|
Public Property EnableFill As Boolean = True
|
||||||
Public Property EnableOutline As Boolean = True
|
Public Property EnableOutline As Boolean = True
|
||||||
Public Property SelectionColor As Color = Color.CornflowerBlue
|
Public Property SelectionColor As Color = Color.CornflowerBlue
|
||||||
Public Property SelectionDashStyle As DashStyle = DashStyle.Dot
|
Public Property SelectionDashStyle As DashStyle = DashStyle.Dot
|
||||||
|
<JsonProperty>
|
||||||
Private _EnableSelection As Boolean = True
|
Private _EnableSelection As Boolean = True
|
||||||
Public Property Image As Image = Nothing
|
Public Property Image As Image = Nothing
|
||||||
<JsonIgnore> Public Property BufferedImage As Image = Nothing
|
<JsonIgnore> Public Property BufferedImage As Image = Nothing
|
||||||
Public Property ImageSizeMode As ImageSizeMode
|
Public Property ImageSizeMode As ImageSizeMode
|
||||||
Public Property ImageProperties As New PaintingObjectImageProperties
|
Public Property ImageProperties As New PaintingObjectImageProperties
|
||||||
Public Property Tag As String = Nothing
|
<JsonIgnore>
|
||||||
|
Public Property Tag As Object = Nothing
|
||||||
Public Property Name As String = ""
|
Public Property Name As String = ""
|
||||||
Public ReadOnly Property PinnedObjects As New List(Of PaintingObject)
|
Public ReadOnly Property PinnedObjects As New List(Of PaintingObject)
|
||||||
|
<JsonIgnore>
|
||||||
Public ReadOnly Property DrawMethodes As New List(Of DelegateDrawPaintingObjectMethode)
|
Public ReadOnly Property DrawMethodes As New List(Of DelegateDrawPaintingObjectMethode)
|
||||||
|
<JsonIgnore>
|
||||||
Public ReadOnly Property DrawSelectionMethode As DelegateDrawPaintingObjectMethode = AddressOf DefaultDrawMethodes.DrawSelection
|
Public ReadOnly Property DrawSelectionMethode As DelegateDrawPaintingObjectMethode = AddressOf DefaultDrawMethodes.DrawSelection
|
||||||
Public Property Cursor As Cursor = Cursors.Default
|
Public Property Cursor As Cursor = Cursors.Default
|
||||||
Public Property HardcodedSize As Boolean = False
|
Public Property HardcodedSize As Boolean = False
|
||||||
|
Public Property HardcodedLocation As Boolean = False
|
||||||
|
<JsonProperty>
|
||||||
Private _Visible As Boolean = True
|
Private _Visible As Boolean = True
|
||||||
|
<JsonProperty>
|
||||||
Private _AutoAlignToGrid As Boolean = False
|
Private _AutoAlignToGrid As Boolean = False
|
||||||
Public Property MouseTransparency As Boolean = False
|
Public Property MouseTransparency As Boolean = False
|
||||||
Public ReadOnly Property Layering As New PaintingObjectLayering(Me)
|
Public ReadOnly Property Layering As New PaintingObjectLayering(Me)
|
||||||
Public ReadOnly Property PaintingObjects As New PaintingObjectList(_Parent) With {.EnableRaisingEvents = False}
|
Public ReadOnly Property PaintingObjects As New PaintingObjectList(_Parent) With {.EnableRaisingEvents = False}
|
||||||
|
<JsonIgnore>
|
||||||
Public ReadOnly Property ErrorsAtDrawing As ULong = 0
|
Public ReadOnly Property ErrorsAtDrawing As ULong = 0
|
||||||
|
|
||||||
Public Event MouseClick(sender As PaintingObject, e As MouseEventArgs)
|
Public Event MouseClick(sender As PaintingObject, e As MouseEventArgs)
|
||||||
@@ -172,6 +185,15 @@ Imports Newtonsoft.Json
|
|||||||
End Set
|
End Set
|
||||||
End Property
|
End Property
|
||||||
|
|
||||||
|
<JsonIgnore> Public Property LocationDirect As PointF
|
||||||
|
Get
|
||||||
|
Return _Location
|
||||||
|
End Get
|
||||||
|
Set(value As PointF)
|
||||||
|
_Location = value
|
||||||
|
End Set
|
||||||
|
End Property
|
||||||
|
|
||||||
<JsonIgnore> Public Property Size As SizeF
|
<JsonIgnore> Public Property Size As SizeF
|
||||||
Get
|
Get
|
||||||
If Parent IsNot Nothing Then
|
If Parent IsNot Nothing Then
|
||||||
@@ -246,6 +268,7 @@ Imports Newtonsoft.Json
|
|||||||
End Set
|
End Set
|
||||||
End Property
|
End Property
|
||||||
|
|
||||||
|
<JsonIgnore>
|
||||||
Public Property Selected As Boolean
|
Public Property Selected As Boolean
|
||||||
Get
|
Get
|
||||||
Return _Selected
|
Return _Selected
|
||||||
@@ -321,6 +344,7 @@ Imports Newtonsoft.Json
|
|||||||
End Set
|
End Set
|
||||||
End Property
|
End Property
|
||||||
|
|
||||||
|
<JsonIgnore>
|
||||||
Public Property Rectangle As RectangleF
|
Public Property Rectangle As RectangleF
|
||||||
Get
|
Get
|
||||||
Return New RectangleF(Location, Size)
|
Return New RectangleF(Location, Size)
|
||||||
@@ -408,6 +432,20 @@ Imports Newtonsoft.Json
|
|||||||
End Set
|
End Set
|
||||||
End Property
|
End Property
|
||||||
|
|
||||||
|
<JsonProperty(NameOf(Tag))>
|
||||||
|
Public Property TagString As String
|
||||||
|
Get
|
||||||
|
If TypeOf Tag Is String Then
|
||||||
|
Return Tag
|
||||||
|
Else
|
||||||
|
Return String.Empty
|
||||||
|
End If
|
||||||
|
End Get
|
||||||
|
Set(value As String)
|
||||||
|
Tag = value
|
||||||
|
End Set
|
||||||
|
End Property
|
||||||
|
|
||||||
Public Property EnableResize As Boolean
|
Public Property EnableResize As Boolean
|
||||||
Get
|
Get
|
||||||
If resizeEngine Is Nothing Then
|
If resizeEngine Is Nothing Then
|
||||||
@@ -443,7 +481,7 @@ Imports Newtonsoft.Json
|
|||||||
End Sub
|
End Sub
|
||||||
|
|
||||||
Public Sub Draw(e As PaintEventArgs)
|
Public Sub Draw(e As PaintEventArgs)
|
||||||
Draw(e, PointF.Empty)
|
Draw(e, e.ClipRectangle.Location)
|
||||||
End Sub
|
End Sub
|
||||||
|
|
||||||
Public Sub Draw(e As PaintEventArgs, offset As PointF)
|
Public Sub Draw(e As PaintEventArgs, offset As PointF)
|
||||||
@@ -528,8 +566,10 @@ End Class
|
|||||||
Public Class PaintingObjectList
|
Public Class PaintingObjectList
|
||||||
Inherits List(Of PaintingObject)
|
Inherits List(Of PaintingObject)
|
||||||
|
|
||||||
|
<JsonIgnore>
|
||||||
Friend ReadOnly Property MyParent As PaintingControl
|
Friend ReadOnly Property MyParent As PaintingControl
|
||||||
Friend Property EnableRaisingEvents As Boolean = True
|
Friend Property EnableRaisingEvents As Boolean = True
|
||||||
|
<JsonIgnore>
|
||||||
Public ReadOnly Property Layering As New PaintingObjectListLayering(Me)
|
Public ReadOnly Property Layering As New PaintingObjectListLayering(Me)
|
||||||
|
|
||||||
Public Sub New()
|
Public Sub New()
|
||||||
|
|||||||
3
Pilz.UI/PaintingControl/PaintingObjectJsonSerializer.vb
Normal file
3
Pilz.UI/PaintingControl/PaintingObjectJsonSerializer.vb
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
Public Class PaintingObjectJsonSerializer
|
||||||
|
|
||||||
|
End Class
|
||||||
@@ -1,11 +1,22 @@
|
|||||||
Public Class PaintingObjectLayering
|
Imports Newtonsoft.Json
|
||||||
|
|
||||||
|
Public Class PaintingObjectLayering
|
||||||
|
|
||||||
|
'<JsonProperty(NameOf(PaintingObject))>
|
||||||
|
Private ReadOnly _PaintingObject As PaintingObject
|
||||||
|
|
||||||
|
<JsonIgnore>
|
||||||
Public ReadOnly Property PaintingObject As PaintingObject
|
Public ReadOnly Property PaintingObject As PaintingObject
|
||||||
|
Get
|
||||||
|
Return _PaintingObject
|
||||||
|
End Get
|
||||||
|
End Property
|
||||||
|
|
||||||
''' <summary>
|
''' <summary>
|
||||||
''' Get the current object list from the painting object.
|
''' Get the current object list from the painting object.
|
||||||
''' </summary>
|
''' </summary>
|
||||||
''' <returns>Returns the current object list from the painting object.</returns>
|
''' <returns>Returns the current object list from the painting object.</returns>
|
||||||
|
<JsonIgnore>
|
||||||
Public ReadOnly Property ObjectList As PaintingObjectList
|
Public ReadOnly Property ObjectList As PaintingObjectList
|
||||||
Get
|
Get
|
||||||
Return PaintingObject.Parent.PaintingObjects
|
Return PaintingObject.Parent.PaintingObjects
|
||||||
@@ -17,7 +28,7 @@
|
|||||||
''' </summary>
|
''' </summary>
|
||||||
''' <param name="obj"></param>
|
''' <param name="obj"></param>
|
||||||
Public Sub New(obj As PaintingObject)
|
Public Sub New(obj As PaintingObject)
|
||||||
PaintingObject = obj
|
_PaintingObject = obj
|
||||||
End Sub
|
End Sub
|
||||||
|
|
||||||
''' <summary>
|
''' <summary>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<MyType>Windows</MyType>
|
<MyType>Windows</MyType>
|
||||||
<TargetFramework>net5.0-windows7.0</TargetFramework>
|
<TargetFramework>net48</TargetFramework>
|
||||||
<NoWarn>42016,41999,42017,42018,42019,42032,42036,42020,42021,42022</NoWarn>
|
<NoWarn>42016,41999,42017,42018,42019,42032,42036,42020,42021,42022</NoWarn>
|
||||||
<DocumentationFile>Pilz.UI.xml</DocumentationFile>
|
<DocumentationFile>Pilz.UI.xml</DocumentationFile>
|
||||||
<DefineTrace>true</DefineTrace>
|
<DefineTrace>true</DefineTrace>
|
||||||
@@ -43,6 +43,9 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
|
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Reference Include="System.Windows.Forms" />
|
||||||
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Import Include="Microsoft.VisualBasic" />
|
<Import Include="Microsoft.VisualBasic" />
|
||||||
<Import Include="System" />
|
<Import Include="System" />
|
||||||
@@ -97,5 +100,6 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\Pilz.Drawing\Pilz.Drawing.vbproj" />
|
<ProjectReference Include="..\Pilz.Drawing\Pilz.Drawing.vbproj" />
|
||||||
|
<ProjectReference Include="..\Pilz.Win32\Pilz.Win32.vbproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
Imports System.Runtime.CompilerServices
|
Imports System.Runtime.CompilerServices
|
||||||
Imports System.Windows.Forms
|
Imports System.Windows.Forms
|
||||||
|
|
||||||
Namespace Utils
|
Namespace Utils
|
||||||
@@ -6,10 +6,19 @@ Namespace Utils
|
|||||||
Public Module DrawingControl
|
Public Module DrawingControl
|
||||||
|
|
||||||
Private Const WM_SETREDRAW = 11
|
Private Const WM_SETREDRAW = 11
|
||||||
|
Private ReadOnly dicSuspendCount As New Dictionary(Of IntPtr, Integer)
|
||||||
|
|
||||||
<Extension>
|
<Extension>
|
||||||
Public Sub SuspendDrawing(control As Control)
|
Public Sub SuspendDrawing(control As Control)
|
||||||
SendMessage(control.Handle, WM_SETREDRAW, False, 0)
|
If Not dicSuspendCount.ContainsKey(control.Handle) Then
|
||||||
|
dicSuspendCount.Add(control.Handle, 1)
|
||||||
|
Else
|
||||||
|
dicSuspendCount(control.Handle) += 1
|
||||||
|
End If
|
||||||
|
|
||||||
|
If dicSuspendCount(control.Handle) = 1 Then
|
||||||
|
SendMessage(control.Handle, WM_SETREDRAW, False, 0)
|
||||||
|
End If
|
||||||
End Sub
|
End Sub
|
||||||
|
|
||||||
<Extension>
|
<Extension>
|
||||||
@@ -19,8 +28,19 @@ Namespace Utils
|
|||||||
|
|
||||||
<Extension>
|
<Extension>
|
||||||
Public Sub ResumeDrawing(control As Control, redraw As Boolean)
|
Public Sub ResumeDrawing(control As Control, redraw As Boolean)
|
||||||
SendMessage(control.Handle, WM_SETREDRAW, True, 0)
|
Dim doRedraw As Boolean = True
|
||||||
If redraw Then control.Refresh()
|
|
||||||
|
If dicSuspendCount.ContainsKey(control.Handle) Then
|
||||||
|
dicSuspendCount(control.Handle) -= 1
|
||||||
|
If dicSuspendCount(control.Handle) >= 1 Then
|
||||||
|
doRedraw = False
|
||||||
|
End If
|
||||||
|
End If
|
||||||
|
|
||||||
|
If doRedraw Then
|
||||||
|
SendMessage(control.Handle, WM_SETREDRAW, True, 0)
|
||||||
|
If redraw Then control.Refresh()
|
||||||
|
End If
|
||||||
End Sub
|
End Sub
|
||||||
|
|
||||||
End Module
|
End Module
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
Imports System.Drawing
|
Imports System.Drawing
|
||||||
Imports System.Runtime.InteropServices
|
Imports System.Runtime.InteropServices
|
||||||
|
|
||||||
|
Imports Pilz.Win32.Mapped
|
||||||
Imports Pilz.Win32.Native
|
Imports Pilz.Win32.Native
|
||||||
|
|
||||||
Namespace Internals
|
Namespace Internals
|
||||||
@@ -10,12 +12,13 @@ Namespace Internals
|
|||||||
''' Extrahiert das Icon aus einer Datei oder aus einem Ordner.
|
''' Extrahiert das Icon aus einer Datei oder aus einem Ordner.
|
||||||
''' </summary>
|
''' </summary>
|
||||||
''' <param name="FilePath">Hier übergeben Sie den Pfad der Datei von dem das Icon extrahiert werden soll.</param>
|
''' <param name="FilePath">Hier übergeben Sie den Pfad der Datei von dem das Icon extrahiert werden soll.</param>
|
||||||
''' <param name="Small">Bei übergabe von true wird ein kleines und bei false ein großes Icon zurück gegeben.</param>
|
''' <param name="size">Bei übergabe von true wird ein kleines und bei false ein großes Icon zurück gegeben.</param>
|
||||||
Public Shared Function ExtractIcon(FilePath As String, Small As Boolean) As Icon
|
Public Shared Function ExtractIcon(FilePath As String, size As SystemIconSize) As Icon
|
||||||
Dim icon As Icon
|
Dim icon As Icon
|
||||||
Dim shinfo As New SHFILEINFO
|
Dim shinfo As New SHFILEINFO
|
||||||
|
Dim small As Boolean = size = SystemIconSize.Small
|
||||||
|
|
||||||
LibShell32.SHGetFileInfo(FilePath, 0, shinfo, Math.Truncate(Marshal.SizeOf(shinfo)), SHFILEINFO.SHGFI_ICON Or If(Small, SHFILEINFO.SHGFI_SMALLICON, SHFILEINFO.SHGFI_LARGEICON))
|
Shell32.SHGetFileInfo(FilePath, 0, shinfo, Math.Truncate(Marshal.SizeOf(shinfo)), SHFILEINFO.SHGFI_ICON Or If(small, SHFILEINFO.SHGFI_SMALLICON, SHFILEINFO.SHGFI_LARGEICON))
|
||||||
|
|
||||||
Try
|
Try
|
||||||
icon = Icon.FromHandle(shinfo.hIcon)
|
icon = Icon.FromHandle(shinfo.hIcon)
|
||||||
|
|||||||
208
Pilz.Win32/Internals/IconFactory.vb
Normal file
208
Pilz.Win32/Internals/IconFactory.vb
Normal file
@@ -0,0 +1,208 @@
|
|||||||
|
Imports System
|
||||||
|
Imports System.Runtime.InteropServices
|
||||||
|
Imports Microsoft.Win32
|
||||||
|
Imports System.Reflection
|
||||||
|
Imports System.Collections.Generic
|
||||||
|
Imports System.Drawing
|
||||||
|
Imports Pilz.Win32.Native
|
||||||
|
Imports Pilz.Win32.Native.Shell32
|
||||||
|
Imports Pilz.Win32.Mapped
|
||||||
|
|
||||||
|
Namespace Internals
|
||||||
|
Public Class IconFactory
|
||||||
|
|
||||||
|
#Region "Custom exceptions class"
|
||||||
|
|
||||||
|
Public Class IconNotFoundException
|
||||||
|
Inherits Exception
|
||||||
|
Public Sub New(ByVal fileName As String, ByVal index As Integer)
|
||||||
|
MyBase.New(String.Format("Icon with Id = {0} wasn't found in file {1}", index, fileName))
|
||||||
|
End Sub
|
||||||
|
End Class
|
||||||
|
|
||||||
|
Public Class UnableToExtractIconsException
|
||||||
|
Inherits Exception
|
||||||
|
Public Sub New(ByVal fileName As String, ByVal firstIconIndex As Integer, ByVal iconCount As Integer)
|
||||||
|
MyBase.New(String.Format("Tryed to extract {2} icons starting from the one with id {1} from the ""{0}"" file but failed", fileName, firstIconIndex, iconCount))
|
||||||
|
End Sub
|
||||||
|
End Class
|
||||||
|
|
||||||
|
#End Region
|
||||||
|
|
||||||
|
|
||||||
|
''' <summary>
|
||||||
|
''' Get the number of icons in the specified file.
|
||||||
|
''' </summary>
|
||||||
|
''' <param name="fileName">Full path of the file to look for.</param>
|
||||||
|
''' <returns></returns>
|
||||||
|
Private Shared Function GetIconsCountInFile(fileName As String) As Integer
|
||||||
|
Return ExtractIconEx(fileName, -1, Nothing, Nothing, 0)
|
||||||
|
End Function
|
||||||
|
|
||||||
|
#Region "ExtractIcon-like functions"
|
||||||
|
|
||||||
|
Public Shared Sub ExtractEx(ByVal fileName As String, ByVal largeIcons As List(Of Icon), ByVal smallIcons As List(Of Icon), ByVal firstIconIndex As Integer, ByVal iconCount As Integer)
|
||||||
|
'
|
||||||
|
' Memory allocations
|
||||||
|
'
|
||||||
|
|
||||||
|
Dim smallIconsPtrs As IntPtr() = Nothing
|
||||||
|
Dim largeIconsPtrs As IntPtr() = Nothing
|
||||||
|
|
||||||
|
If smallIcons IsNot Nothing Then
|
||||||
|
smallIconsPtrs = New IntPtr(iconCount - 1) {}
|
||||||
|
End If
|
||||||
|
If largeIcons IsNot Nothing Then
|
||||||
|
largeIconsPtrs = New IntPtr(iconCount - 1) {}
|
||||||
|
End If
|
||||||
|
|
||||||
|
'
|
||||||
|
' Call to native Win32 API
|
||||||
|
'
|
||||||
|
|
||||||
|
Dim apiResult = ExtractIconEx(fileName, firstIconIndex, largeIconsPtrs, smallIconsPtrs, iconCount)
|
||||||
|
If apiResult <> iconCount Then
|
||||||
|
Throw New UnableToExtractIconsException(fileName, firstIconIndex, iconCount)
|
||||||
|
End If
|
||||||
|
|
||||||
|
'
|
||||||
|
' Fill lists
|
||||||
|
'
|
||||||
|
|
||||||
|
If smallIcons IsNot Nothing Then
|
||||||
|
smallIcons.Clear()
|
||||||
|
For Each actualIconPtr In smallIconsPtrs
|
||||||
|
smallIcons.Add(Icon.FromHandle(actualIconPtr))
|
||||||
|
Next
|
||||||
|
End If
|
||||||
|
If largeIcons IsNot Nothing Then
|
||||||
|
largeIcons.Clear()
|
||||||
|
For Each actualIconPtr In largeIconsPtrs
|
||||||
|
largeIcons.Add(Icon.FromHandle(actualIconPtr))
|
||||||
|
Next
|
||||||
|
End If
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
Public Shared Function ExtractEx(ByVal fileName As String, ByVal size As SystemIconSize, ByVal firstIconIndex As Integer, ByVal iconCount As Integer) As List(Of Icon)
|
||||||
|
Dim iconList As New List(Of Icon)()
|
||||||
|
|
||||||
|
Select Case size
|
||||||
|
Case SystemIconSize.Large
|
||||||
|
ExtractEx(fileName, iconList, Nothing, firstIconIndex, iconCount)
|
||||||
|
Case SystemIconSize.Small
|
||||||
|
ExtractEx(fileName, Nothing, iconList, firstIconIndex, iconCount)
|
||||||
|
Case Else
|
||||||
|
Throw New ArgumentOutOfRangeException("size")
|
||||||
|
End Select
|
||||||
|
|
||||||
|
Return iconList
|
||||||
|
End Function
|
||||||
|
|
||||||
|
Public Shared Sub Extract(ByVal fileName As String, ByVal largeIcons As List(Of Icon), ByVal smallIcons As List(Of Icon))
|
||||||
|
Dim iconCount = GetIconsCountInFile(fileName)
|
||||||
|
ExtractEx(fileName, largeIcons, smallIcons, 0, iconCount)
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
Public Shared Function Extract(ByVal fileName As String, ByVal size As SystemIconSize) As List(Of Icon)
|
||||||
|
Dim iconCount = GetIconsCountInFile(fileName)
|
||||||
|
Return ExtractEx(fileName, size, 0, iconCount)
|
||||||
|
End Function
|
||||||
|
|
||||||
|
Public Shared Function ExtractOne(ByVal fileName As String, ByVal index As Integer, ByVal size As SystemIconSize) As Icon
|
||||||
|
Try
|
||||||
|
Dim iconList = ExtractEx(fileName, size, index, 1)
|
||||||
|
Return iconList(0)
|
||||||
|
Catch __unusedUnableToExtractIconsException1__ As UnableToExtractIconsException
|
||||||
|
Throw New IconNotFoundException(fileName, index)
|
||||||
|
End Try
|
||||||
|
End Function
|
||||||
|
|
||||||
|
Public shared Sub ExtractOne(ByVal fileName As String, ByVal index As Integer, <Out> ByRef largeIcon As Icon, <Out> ByRef smallIcon As Icon)
|
||||||
|
Dim smallIconList As List(Of Icon) = New List(Of Icon)()
|
||||||
|
Dim largeIconList As List(Of Icon) = New List(Of Icon)()
|
||||||
|
Try
|
||||||
|
ExtractEx(fileName, largeIconList, smallIconList, index, 1)
|
||||||
|
largeIcon = largeIconList(0)
|
||||||
|
smallIcon = smallIconList(0)
|
||||||
|
Catch __unusedUnableToExtractIconsException1__ As UnableToExtractIconsException
|
||||||
|
Throw New IconNotFoundException(fileName, index)
|
||||||
|
End Try
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
#End Region
|
||||||
|
|
||||||
|
'this will look throw the registry
|
||||||
|
'to find if the Extension have an icon.
|
||||||
|
Public Shared Function IconFromExtension(ByVal extension As String, ByVal size As SystemIconSize) As Icon
|
||||||
|
' Add the '.' to the extension if needed
|
||||||
|
If extension(0) <> "."c Then extension = "."c & extension
|
||||||
|
|
||||||
|
'opens the registry for the wanted key.
|
||||||
|
Dim Root = Registry.ClassesRoot
|
||||||
|
Dim ExtensionKey = Root.OpenSubKey(extension)
|
||||||
|
ExtensionKey.GetValueNames()
|
||||||
|
Dim ApplicationKey As RegistryKey = Root.OpenSubKey(ExtensionKey.GetValue("").ToString())
|
||||||
|
|
||||||
|
'gets the name of the file that have the icon.
|
||||||
|
Dim IconLocation As String = ApplicationKey.OpenSubKey("DefaultIcon").GetValue("").ToString()
|
||||||
|
Dim IconPath = IconLocation.Split(","c)
|
||||||
|
|
||||||
|
If Equals(IconPath(1), Nothing) Then IconPath(1) = "0"
|
||||||
|
Dim Large = New IntPtr(0) {}, Small = New IntPtr(0) {}
|
||||||
|
|
||||||
|
'extracts the icon from the file.
|
||||||
|
ExtractIconEx(IconPath(0), Convert.ToInt16(IconPath(1)), Large, Small, 1)
|
||||||
|
Return If(size = SystemIconSize.Large, Icon.FromHandle(Large(0)), Icon.FromHandle(Small(0)))
|
||||||
|
End Function
|
||||||
|
|
||||||
|
Public Shared Function IconFromExtensionShell(ByVal extension As String, ByVal size As SystemIconSize) As Icon
|
||||||
|
'add '.' if nessesry
|
||||||
|
If extension(0) <> "."c Then extension = "."c & extension
|
||||||
|
|
||||||
|
'temp struct for getting file shell info
|
||||||
|
Dim fileInfo As SHFILEINFO = New SHFILEINFO()
|
||||||
|
|
||||||
|
SHGetFileInfo(extension, 0, fileInfo, Marshal.SizeOf(fileInfo), FileInfoFlags.SHGFI_ICON Or FileInfoFlags.SHGFI_USEFILEATTRIBUTES Or CType(size, FileInfoFlags))
|
||||||
|
|
||||||
|
Return Icon.FromHandle(fileInfo.hIcon)
|
||||||
|
End Function
|
||||||
|
|
||||||
|
Public Shared Function IconFromResource(ByVal resourceName As String) As Icon
|
||||||
|
Dim assembly As Assembly = Assembly.GetCallingAssembly()
|
||||||
|
|
||||||
|
Return New Icon(assembly.GetManifestResourceStream(resourceName))
|
||||||
|
End Function
|
||||||
|
|
||||||
|
''' <summary>
|
||||||
|
''' Parse strings in registry who contains the name of the icon and
|
||||||
|
''' the index of the icon an return both parts.
|
||||||
|
''' </summary>
|
||||||
|
''' <param name="regString">The full string in the form "path,index" as found in registry.</param>
|
||||||
|
''' <param name="fileName">The "path" part of the string.</param>
|
||||||
|
''' <param name="index">The "index" part of the string.</param>
|
||||||
|
Public Shared Sub ExtractInformationsFromRegistryString(ByVal regString As String, <Out> ByRef fileName As String, <Out> ByRef index As Integer)
|
||||||
|
If Equals(regString, Nothing) Then
|
||||||
|
Throw New ArgumentNullException("regString")
|
||||||
|
End If
|
||||||
|
If regString.Length = 0 Then
|
||||||
|
Throw New ArgumentException("The string should not be empty.", "regString")
|
||||||
|
End If
|
||||||
|
|
||||||
|
index = 0
|
||||||
|
Dim strArr = regString.Replace("""", "").Split(","c)
|
||||||
|
fileName = strArr(0).Trim()
|
||||||
|
If strArr.Length > 1 Then
|
||||||
|
Call Integer.TryParse(strArr(1).Trim(), index)
|
||||||
|
End If
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
Public Shared Function ExtractFromRegistryString(ByVal regString As String, ByVal size As SystemIconSize) As Icon
|
||||||
|
Dim fileName As String
|
||||||
|
Dim index As Integer
|
||||||
|
ExtractInformationsFromRegistryString(regString, fileName, index)
|
||||||
|
Return ExtractOne(fileName, index, size)
|
||||||
|
End Function
|
||||||
|
|
||||||
|
End Class
|
||||||
|
|
||||||
|
End Namespace
|
||||||
17
Pilz.Win32/Mapped/FileTypeIcons.vb
Normal file
17
Pilz.Win32/Mapped/FileTypeIcons.vb
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
Imports System.Drawing
|
||||||
|
|
||||||
|
Namespace Mapped
|
||||||
|
|
||||||
|
Public Module FileTypeIcons
|
||||||
|
|
||||||
|
Public Function ExtractIconFromFilePath(filePath As String, size As SystemIconSize) As Icon
|
||||||
|
Return Internals.IconExtractor.ExtractIcon(filePath, size)
|
||||||
|
End Function
|
||||||
|
|
||||||
|
Public Function ExtractIconFromFileExtension(fileExtension As String, size As SystemIconSize) As Icon
|
||||||
|
Return Internals.IconFactory.IconFromExtensionShell(fileExtension, size)
|
||||||
|
End Function
|
||||||
|
|
||||||
|
End Module
|
||||||
|
|
||||||
|
End Namespace
|
||||||
12
Pilz.Win32/Mapped/SystemIconSize.vb
Normal file
12
Pilz.Win32/Mapped/SystemIconSize.vb
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
Namespace Mapped
|
||||||
|
|
||||||
|
''' <summary>
|
||||||
|
''' Two constants extracted from the FileInfoFlags, the only that are
|
||||||
|
''' meaningfull for the user of this class.
|
||||||
|
''' </summary>
|
||||||
|
Public Enum SystemIconSize As Integer
|
||||||
|
Large
|
||||||
|
Small
|
||||||
|
End Enum
|
||||||
|
|
||||||
|
End Namespace
|
||||||
20
Pilz.Win32/Native/FileInfoFlags.vb
Normal file
20
Pilz.Win32/Native/FileInfoFlags.vb
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
Namespace Native
|
||||||
|
|
||||||
|
<Flags>
|
||||||
|
Public Enum FileInfoFlags As Integer
|
||||||
|
''' <summary>
|
||||||
|
''' Retrieve the handle to the icon that represents the file and the index
|
||||||
|
''' of the icon within the system image list. The handle is copied to the
|
||||||
|
''' hIcon member of the structure specified by psfi, and the index is copied
|
||||||
|
''' to the iIcon member.
|
||||||
|
''' </summary>
|
||||||
|
SHGFI_ICON = &H100
|
||||||
|
''' <summary>
|
||||||
|
''' Indicates that the function should not attempt to access the file
|
||||||
|
''' specified by pszPath. Rather, it should act as if the file specified by
|
||||||
|
''' pszPath exists with the file attributes passed in dwFileAttributes.
|
||||||
|
''' </summary>
|
||||||
|
SHGFI_USEFILEATTRIBUTES = &H10
|
||||||
|
End Enum
|
||||||
|
|
||||||
|
End Namespace
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
Namespace Native
|
|
||||||
|
|
||||||
Public Class LibShell32
|
|
||||||
|
|
||||||
Public Declare Function SHGetFileInfo Lib "shell32.dll" (ByVal pszPath As String, ByVal dwFileAttributes As UInteger, ByRef psfi As SHFILEINFO, ByVal cbSizeFileInfo As UInteger, ByVal uFlags As UInteger) As IntPtr
|
|
||||||
|
|
||||||
End Class
|
|
||||||
|
|
||||||
End Namespace
|
|
||||||
21
Pilz.Win32/Native/POINT.vb
Normal file
21
Pilz.Win32/Native/POINT.vb
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
Imports System.Runtime.InteropServices
|
||||||
|
|
||||||
|
Namespace Native
|
||||||
|
|
||||||
|
<StructLayout(LayoutKind.Sequential)>
|
||||||
|
Public Structure POINT
|
||||||
|
Public Sub New(ByVal p As System.Drawing.Point)
|
||||||
|
Me.x = p.X
|
||||||
|
Me.y = p.Y
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
Public Sub New(ByVal x As Integer, ByVal y As Integer)
|
||||||
|
Me.x = x
|
||||||
|
Me.y = y
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
Public x As Integer
|
||||||
|
Public y As Integer
|
||||||
|
End Structure
|
||||||
|
|
||||||
|
End Namespace
|
||||||
82
Pilz.Win32/Native/RECT.vb
Normal file
82
Pilz.Win32/Native/RECT.vb
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
Imports System.Drawing
|
||||||
|
Imports System.Runtime.InteropServices
|
||||||
|
|
||||||
|
Namespace Native
|
||||||
|
|
||||||
|
<Serializable, StructLayout(LayoutKind.Sequential)>
|
||||||
|
Public Structure RECT
|
||||||
|
Public Left As Integer
|
||||||
|
Public Top As Integer
|
||||||
|
Public Right As Integer
|
||||||
|
Public Bottom As Integer
|
||||||
|
|
||||||
|
Public Sub New(ByVal left_ As Integer, ByVal top_ As Integer, ByVal right_ As Integer, ByVal bottom_ As Integer)
|
||||||
|
Left = left_
|
||||||
|
Top = top_
|
||||||
|
Right = right_
|
||||||
|
Bottom = bottom_
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
Public Sub New(ByVal r As Rectangle)
|
||||||
|
Left = r.Left
|
||||||
|
Top = r.Top
|
||||||
|
Right = r.Right
|
||||||
|
Bottom = r.Bottom
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
Public ReadOnly Property Height As Integer
|
||||||
|
Get
|
||||||
|
Return Bottom - Top
|
||||||
|
End Get
|
||||||
|
End Property
|
||||||
|
|
||||||
|
Public ReadOnly Property Width As Integer
|
||||||
|
Get
|
||||||
|
Return Right - Left
|
||||||
|
End Get
|
||||||
|
End Property
|
||||||
|
|
||||||
|
Public ReadOnly Property Size As System.Drawing.Size
|
||||||
|
Get
|
||||||
|
Return New System.Drawing.Size(Width, Height)
|
||||||
|
End Get
|
||||||
|
End Property
|
||||||
|
|
||||||
|
Public ReadOnly Property Location As System.Drawing.Point
|
||||||
|
Get
|
||||||
|
Return New System.Drawing.Point(Left, Top)
|
||||||
|
End Get
|
||||||
|
End Property
|
||||||
|
|
||||||
|
Public Function ToRectangle() As Rectangle
|
||||||
|
Return Rectangle.FromLTRB(Left, Top, Right, Bottom)
|
||||||
|
End Function
|
||||||
|
|
||||||
|
Public Shared Function FromRectangle(ByVal rectangle As Rectangle) As RECT
|
||||||
|
Return New RECT(rectangle.Left, rectangle.Top, rectangle.Right, rectangle.Bottom)
|
||||||
|
End Function
|
||||||
|
|
||||||
|
Public Overrides Function GetHashCode() As Integer
|
||||||
|
Return Left ^ ((Top << 13) Or (Top >> &H13)) _
|
||||||
|
^ ((Width << &H1A) Or (Width >> 6)) _
|
||||||
|
^ ((Height << 7) Or (Height >> &H19))
|
||||||
|
End Function
|
||||||
|
|
||||||
|
Public Shared Function FromXYWH(ByVal x As Integer, ByVal y As Integer, ByVal width As Integer, ByVal height As Integer) As RECT
|
||||||
|
Return New RECT(x, y, x + width, y + height)
|
||||||
|
End Function
|
||||||
|
|
||||||
|
Public Shared Widening Operator CType(ByVal rect As RECT) As Rectangle
|
||||||
|
Return Rectangle.FromLTRB(rect.Left, rect.Top, rect.Right, rect.Bottom)
|
||||||
|
End Operator
|
||||||
|
|
||||||
|
Public Shared Widening Operator CType(ByVal rect As Rectangle) As RECT
|
||||||
|
Return New RECT(rect.Left, rect.Top, rect.Right, rect.Bottom)
|
||||||
|
End Operator
|
||||||
|
|
||||||
|
Public Overrides Function ToString() As String
|
||||||
|
Return "Left=" & Me.Left & ", Top=" & Me.Top & ", Right=" & Me.Right & ", Bottom=" & Me.Bottom
|
||||||
|
End Function
|
||||||
|
End Structure
|
||||||
|
|
||||||
|
End Namespace
|
||||||
@@ -2,18 +2,43 @@
|
|||||||
|
|
||||||
Namespace Native
|
Namespace Native
|
||||||
|
|
||||||
|
''' <summary>
|
||||||
|
''' Contains information about a file object.
|
||||||
|
''' </summary>
|
||||||
<StructLayout(LayoutKind.Sequential)>
|
<StructLayout(LayoutKind.Sequential)>
|
||||||
Public Structure SHFILEINFO
|
Public Structure SHFILEINFO
|
||||||
Public Const SHGFI_ICON As UInteger = &H100
|
Public Const SHGFI_ICON As UInteger = &H100
|
||||||
Public Const SHGFI_LARGEICON As UInteger = &H0
|
Public Const SHGFI_LARGEICON As UInteger = &H0
|
||||||
Public Const SHGFI_SMALLICON As UInteger = &H1
|
Public Const SHGFI_SMALLICON As UInteger = &H1
|
||||||
|
''' <summary>
|
||||||
|
''' Handle to the icon that represents the file. You are responsible for
|
||||||
|
''' destroying this handle with DestroyIcon when you no longer need it.
|
||||||
|
''' </summary>
|
||||||
Public hIcon As IntPtr
|
Public hIcon As IntPtr
|
||||||
|
|
||||||
|
''' <summary>
|
||||||
|
''' Index of the icon image within the system image list.
|
||||||
|
''' </summary>
|
||||||
Public iIcon As IntPtr
|
Public iIcon As IntPtr
|
||||||
|
|
||||||
|
''' <summary>
|
||||||
|
''' Array of values that indicates the attributes of the file object.
|
||||||
|
''' For information about these values, see the IShellFolder::GetAttributesOf
|
||||||
|
''' method.
|
||||||
|
''' </summary>
|
||||||
Public dwAttributes As UInteger
|
Public dwAttributes As UInteger
|
||||||
|
|
||||||
|
''' <summary>
|
||||||
|
''' String that contains the name of the file as it appears in the Microsoft
|
||||||
|
''' Windows Shell, or the path and file name of the file that contains the
|
||||||
|
''' icon representing the file.
|
||||||
|
''' </summary>
|
||||||
<MarshalAs(UnmanagedType.ByValTStr, SizeConst:=260)>
|
<MarshalAs(UnmanagedType.ByValTStr, SizeConst:=260)>
|
||||||
Public szDisplayName As String
|
Public szDisplayName As String
|
||||||
|
|
||||||
|
''' <summary>
|
||||||
|
''' String that describes the type of file.
|
||||||
|
''' </summary>
|
||||||
<MarshalAs(UnmanagedType.ByValTStr, SizeConst:=80)>
|
<MarshalAs(UnmanagedType.ByValTStr, SizeConst:=80)>
|
||||||
Public szTypeName As String
|
Public szTypeName As String
|
||||||
End Structure
|
End Structure
|
||||||
|
|||||||
68
Pilz.Win32/Native/Shell32.vb
Normal file
68
Pilz.Win32/Native/Shell32.vb
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
Imports System.Runtime.InteropServices
|
||||||
|
|
||||||
|
Namespace Native
|
||||||
|
|
||||||
|
Public Class Shell32
|
||||||
|
|
||||||
|
''' <summary>
|
||||||
|
''' Creates an array of handles to large or small icons extracted from
|
||||||
|
''' the specified executable file, dynamic-link library (DLL), or icon
|
||||||
|
''' file.
|
||||||
|
''' </summary>
|
||||||
|
''' <param name="lpszFile">
|
||||||
|
''' Name of an executable file, DLL, or icon file from which icons will
|
||||||
|
''' be extracted.
|
||||||
|
''' </param>
|
||||||
|
''' <param name="nIconIndex">
|
||||||
|
''' <para>
|
||||||
|
''' Specifies the zero-based index of the first icon to extract. For
|
||||||
|
''' example, if this value is zero, the function extracts the first
|
||||||
|
''' icon in the specified file.
|
||||||
|
''' </para>
|
||||||
|
''' <para>
|
||||||
|
''' If this value is <20>1 and <paramrefname="phiconLarge"/> and
|
||||||
|
''' <paramrefname="phiconSmall"/> are both NULL, the function returns
|
||||||
|
''' the total number of icons in the specified file. If the file is an
|
||||||
|
''' executable file or DLL, the return value is the number of
|
||||||
|
''' RT_GROUP_ICON resources. If the file is an .ico file, the return
|
||||||
|
''' value is 1.
|
||||||
|
''' </para>
|
||||||
|
''' <para>
|
||||||
|
''' Windows 95/98/Me, Windows NT 4.0 and later: If this value is a
|
||||||
|
''' negative number and either <paramrefname="phiconLarge"/> or
|
||||||
|
''' <paramrefname="phiconSmall"/> is not NULL, the function begins by
|
||||||
|
''' extracting the icon whose resource identifier is equal to the
|
||||||
|
''' absolute value of <paramrefname="nIconIndex"/>. For example, use -3
|
||||||
|
''' to extract the icon whose resource identifier is 3.
|
||||||
|
''' </para>
|
||||||
|
''' </param>
|
||||||
|
''' <param name="phIconLarge">
|
||||||
|
''' An array of icon handles that receives handles to the large icons
|
||||||
|
''' extracted from the file. If this parameter is NULL, no large icons
|
||||||
|
''' are extracted from the file.
|
||||||
|
''' </param>
|
||||||
|
''' <param name="phIconSmall">
|
||||||
|
''' An array of icon handles that receives handles to the small icons
|
||||||
|
''' extracted from the file. If this parameter is NULL, no small icons
|
||||||
|
''' are extracted from the file.
|
||||||
|
''' </param>
|
||||||
|
''' <param name="nIcons">
|
||||||
|
''' Specifies the number of icons to extract from the file.
|
||||||
|
''' </param>
|
||||||
|
''' <returns>
|
||||||
|
''' If the <paramrefname="nIconIndex"/> parameter is -1, the
|
||||||
|
''' <paramrefname="phIconLarge"/> parameter is NULL, and the
|
||||||
|
''' <paramrefname="phiconSmall"/> parameter is NULL, then the return
|
||||||
|
''' value is the number of icons contained in the specified file.
|
||||||
|
''' Otherwise, the return value is the number of icons successfully
|
||||||
|
''' extracted from the file.
|
||||||
|
''' </returns>
|
||||||
|
<DllImport("Shell32", CharSet:=CharSet.Auto)>
|
||||||
|
Public Shared Function ExtractIconEx(<MarshalAs(UnmanagedType.LPTStr)> ByVal lpszFile As String, ByVal nIconIndex As Integer, ByVal phIconLarge As IntPtr(), ByVal phIconSmall As IntPtr(), ByVal nIcons As Integer) As Integer
|
||||||
|
End Function
|
||||||
|
|
||||||
|
Public Declare Function SHGetFileInfo Lib "shell32.dll" (ByVal pszPath As String, ByVal dwFileAttributes As UInteger, ByRef psfi As SHFILEINFO, ByVal cbSizeFileInfo As UInteger, ByVal uFlags As UInteger) As IntPtr
|
||||||
|
|
||||||
|
End Class
|
||||||
|
|
||||||
|
End Namespace
|
||||||
17
Pilz.Win32/Native/User32.vb
Normal file
17
Pilz.Win32/Native/User32.vb
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
Imports System.Runtime.InteropServices
|
||||||
|
|
||||||
|
Namespace Native
|
||||||
|
|
||||||
|
Public Class User32
|
||||||
|
|
||||||
|
<DllImport("user32")>
|
||||||
|
Public Shared Function GetWindowRect(ByVal hWnd As IntPtr, ByRef r As RECT) As Boolean
|
||||||
|
End Function
|
||||||
|
|
||||||
|
<DllImport("user32.dll")>
|
||||||
|
Public Shared Function ChildWindowFromPointEx(ByVal hWndParent As IntPtr, ByVal pt As POINT, ByVal uFlags As UInteger) As IntPtr
|
||||||
|
End Function
|
||||||
|
|
||||||
|
End Class
|
||||||
|
|
||||||
|
End Namespace
|
||||||
11
Pilz.Win32/Native/WindowFromPointFlags.vb
Normal file
11
Pilz.Win32/Native/WindowFromPointFlags.vb
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
Namespace Native
|
||||||
|
|
||||||
|
<Flags>
|
||||||
|
Public Enum WindowFromPointFlags
|
||||||
|
CWP_ALL = &H0
|
||||||
|
CWP_SKIPINVISIBLE = &H1
|
||||||
|
CWP_SKIPDISABLED = &H2
|
||||||
|
CWP_SKIPTRANSPARENT = &H4
|
||||||
|
End Enum
|
||||||
|
|
||||||
|
End Namespace
|
||||||
4
Pilz.sln
4
Pilz.sln
@@ -1,7 +1,7 @@
|
|||||||
|
|
||||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
# Visual Studio Version 16
|
# Visual Studio 15
|
||||||
VisualStudioVersion = 16.0.30717.126
|
VisualStudioVersion = 15.0.28307.329
|
||||||
MinimumVisualStudioVersion = 10.0.40219.1
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
Project("{778DAE3C-4631-46EA-AA77-85C1314464D9}") = "Pilz", "Pilz\Pilz.vbproj", "{277D2B83-7613-4C49-9CAB-E080195A6E0C}"
|
Project("{778DAE3C-4631-46EA-AA77-85C1314464D9}") = "Pilz", "Pilz\Pilz.vbproj", "{277D2B83-7613-4C49-9CAB-E080195A6E0C}"
|
||||||
EndProject
|
EndProject
|
||||||
|
|||||||
@@ -30,28 +30,45 @@ Namespace Runtime
|
|||||||
Get
|
Get
|
||||||
Static t As OSType? = Nothing
|
Static t As OSType? = Nothing
|
||||||
|
|
||||||
If t Is Nothing Then
|
If t Is Nothing Then
|
||||||
Dim windir As String = Environment.GetEnvironmentVariable("windir")
|
|
||||||
|
|
||||||
If Not String.IsNullOrEmpty(windir) AndAlso windir.Contains("\") AndAlso Directory.Exists(windir) Then
|
Dim windir = Environment.GetEnvironmentVariable("windir")
|
||||||
t = OSType.Windows
|
Const ostypeDirWine = "Z:\proc\sys\kernel\ostype"
|
||||||
ElseIf File.Exists("/proc/sys/kernel/ostype") Then
|
Const ostypeDirNative = "/proc/sys/kernel/ostype"
|
||||||
Dim osTypeString As String = File.ReadAllText("/proc/sys/kernel/ostype")
|
Const systemVersionWine = "Z:\System\Library\CoreServices\SystemVersion.plist"
|
||||||
If osTypeString.StartsWith("Linux", StringComparison.OrdinalIgnoreCase) Then
|
Const systemVersionNative = "/System/Library/CoreServices/SystemVersion.plist"
|
||||||
' Note: Android gets here too
|
|
||||||
t = OSType.Linux
|
|
||||||
Else
|
|
||||||
t = OSType.Unknown
|
|
||||||
End If
|
|
||||||
ElseIf File.Exists("/System/Library/CoreServices/SystemVersion.plist") Then
|
|
||||||
' Note: iOS gets here too
|
|
||||||
t = OSType.OSX
|
|
||||||
Else
|
|
||||||
t = OSType.Unknown
|
|
||||||
End If
|
|
||||||
End If
|
|
||||||
|
|
||||||
Return t
|
If File.Exists(ostypeDirWine) Then ' Linux using wine
|
||||||
|
Dim osTypeString As String = File.ReadAllText(ostypeDirWine)
|
||||||
|
If osTypeString.StartsWith("Linux", StringComparison.OrdinalIgnoreCase) Then
|
||||||
|
' Note: Android gets here too
|
||||||
|
t = OSType.Linux
|
||||||
|
Else
|
||||||
|
t = OSType.Unknown
|
||||||
|
End If
|
||||||
|
ElseIf File.Exists(ostypeDirNative) Then ' Linux native
|
||||||
|
Dim osTypeString As String = File.ReadAllText(ostypeDirNative)
|
||||||
|
If osTypeString.StartsWith("Linux", StringComparison.OrdinalIgnoreCase) Then
|
||||||
|
' Note: Android gets here too
|
||||||
|
t = OSType.Linux
|
||||||
|
Else
|
||||||
|
t = OSType.Unknown
|
||||||
|
End If
|
||||||
|
ElseIf File.Exists(systemVersionWine) Then ' OSX using wine
|
||||||
|
' Note: iOS gets here too
|
||||||
|
t = OSType.OSX
|
||||||
|
ElseIf File.Exists(systemVersionNative) Then ' OSX native
|
||||||
|
' Note: iOS gets here too
|
||||||
|
t = OSType.OSX
|
||||||
|
ElseIf Not String.IsNullOrEmpty(windir) AndAlso Directory.Exists(windir) AndAlso Path.DirectorySeparatorChar = "\"c Then ' Windows
|
||||||
|
t = OSType.Windows
|
||||||
|
Else
|
||||||
|
t = OSType.Unknown
|
||||||
|
End If
|
||||||
|
|
||||||
|
End If
|
||||||
|
|
||||||
|
Return t
|
||||||
End Get
|
End Get
|
||||||
End Property
|
End Property
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
Reference in New Issue
Block a user