Rider+Fix

This commit is contained in:
CreepyCrafter24 2019-12-22 16:58:16 +01:00
parent 2d636f50b7
commit 53a9bc5fe0
19 changed files with 447 additions and 680 deletions

View File

@ -2,18 +2,14 @@
{ {
public static class ArrayFormatter public static class ArrayFormatter
{ {
public static string ElementsToString(this object[] Input, string Seperator = "\r\n") public static string ElementsToString(this object[] input, string separator = "\r\n")
{ {
try string a = "";
{ for (int i = 0; i < input.Length; i++)
string a = ""; a += input[i] + separator;
for (int i = 0; i < Input.Length; i++) if (separator.Length > 0)
a += Input[i].ToString() + Seperator; a = a.Remove(a.Length - separator.Length);
if (Seperator.Length > 0) return a;
a = a.Remove(a.Length - Seperator.Length);
return a;
}
catch { throw; }
} }
} }
} }

View File

@ -6,23 +6,10 @@ using System.Globalization;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Windows.Forms; using System.Windows.Forms;
namespace GradeCalc namespace CC_Functions.Misc
{ {
public class DataGridViewNumericUpDownCell : DataGridViewTextBoxCell public class DataGridViewNumericUpDownCell : DataGridViewTextBoxCell
{ {
// Used in KeyEntersEditMode function
[DllImport("USER32.DLL", CharSet = CharSet.Auto)]
private static extern short VkKeyScan(char key);
// Used in TranslateAlignment function
private static readonly DataGridViewContentAlignment anyRight = DataGridViewContentAlignment.TopRight |
DataGridViewContentAlignment.MiddleRight |
DataGridViewContentAlignment.BottomRight;
private static readonly DataGridViewContentAlignment anyCenter = DataGridViewContentAlignment.TopCenter |
DataGridViewContentAlignment.MiddleCenter |
DataGridViewContentAlignment.BottomCenter;
// Default dimensions of the static rendering bitmap used for the painting of the non-edited cells // Default dimensions of the static rendering bitmap used for the painting of the non-edited cells
private const int DATAGRIDVIEWNUMERICUPDOWNCELL_defaultRenderingBitmapWidth = 100; private const int DATAGRIDVIEWNUMERICUPDOWNCELL_defaultRenderingBitmapWidth = 100;
@ -35,7 +22,7 @@ namespace GradeCalc
internal const decimal DATAGRIDVIEWNUMERICUPDOWNCELL_defaultIncrement = decimal.One; internal const decimal DATAGRIDVIEWNUMERICUPDOWNCELL_defaultIncrement = decimal.One;
// Default value of the Maximum property // Default value of the Maximum property
internal const decimal DATAGRIDVIEWNUMERICUPDOWNCELL_defaultMaximum = (decimal)100.0; internal const decimal DATAGRIDVIEWNUMERICUPDOWNCELL_defaultMaximum = (decimal) 100.0;
// Default value of the Minimum property // Default value of the Minimum property
internal const decimal DATAGRIDVIEWNUMERICUPDOWNCELL_defaultMinimum = decimal.Zero; internal const decimal DATAGRIDVIEWNUMERICUPDOWNCELL_defaultMinimum = decimal.Zero;
@ -43,36 +30,42 @@ namespace GradeCalc
// Default value of the ThousandsSeparator property // Default value of the ThousandsSeparator property
internal const bool DATAGRIDVIEWNUMERICUPDOWNCELL_defaultThousandsSeparator = false; internal const bool DATAGRIDVIEWNUMERICUPDOWNCELL_defaultThousandsSeparator = false;
// Used in TranslateAlignment function
private static readonly DataGridViewContentAlignment anyRight = DataGridViewContentAlignment.TopRight |
DataGridViewContentAlignment.MiddleRight |
DataGridViewContentAlignment.BottomRight;
private static readonly DataGridViewContentAlignment anyCenter = DataGridViewContentAlignment.TopCenter |
DataGridViewContentAlignment.MiddleCenter |
DataGridViewContentAlignment.BottomCenter;
// Type of this cell's editing control // Type of this cell's editing control
private static Type defaultEditType = typeof(DataGridViewNumericUpDownEditingControl); private static readonly Type defaultEditType = typeof(DataGridViewNumericUpDownEditingControl);
// Type of this cell's value. The formatted value type is string, the same as the base class DataGridViewTextBoxCell // Type of this cell's value. The formatted value type is string, the same as the base class DataGridViewTextBoxCell
private static Type defaultValueType = typeof(decimal); private static readonly Type defaultValueType = typeof(decimal);
// The bitmap used to paint the non-edited cells via a call to NumericUpDown.DrawToBitmap // The bitmap used to paint the non-edited cells via a call to NumericUpDown.DrawToBitmap
[ThreadStatic] [ThreadStatic] private static Bitmap renderingBitmap;
private static Bitmap renderingBitmap;
// The NumericUpDown control used to paint the non-edited cells via a call to NumericUpDown.DrawToBitmap // The NumericUpDown control used to paint the non-edited cells via a call to NumericUpDown.DrawToBitmap
[ThreadStatic] [ThreadStatic] private static NumericUpDown paintingNumericUpDown;
private static NumericUpDown paintingNumericUpDown;
private int decimalPlaces; // Caches the value of the DecimalPlaces property private int decimalPlaces; // Caches the value of the DecimalPlaces property
private decimal increment; // Caches the value of the Increment property private decimal increment; // Caches the value of the Increment property
private decimal minimum; // Caches the value of the Minimum property private decimal maximum; // Caches the value of the Maximum property
private decimal maximum; // Caches the value of the Maximum property private decimal minimum; // Caches the value of the Minimum property
private bool thousandsSeparator; // Caches the value of the ThousandsSeparator property private bool thousandsSeparator; // Caches the value of the ThousandsSeparator property
/// <summary> /// <summary>
/// Constructor for the DataGridViewNumericUpDownCell cell type /// Constructor for the DataGridViewNumericUpDownCell cell type
/// </summary> /// </summary>
public DataGridViewNumericUpDownCell() public DataGridViewNumericUpDownCell()
{ {
// Create a thread specific bitmap used for the painting of the non-edited cells // Create a thread specific bitmap used for the painting of the non-edited cells
if (renderingBitmap == null) if (renderingBitmap == null)
{ renderingBitmap = new Bitmap(DATAGRIDVIEWNUMERICUPDOWNCELL_defaultRenderingBitmapWidth,
renderingBitmap = new Bitmap(DATAGRIDVIEWNUMERICUPDOWNCELL_defaultRenderingBitmapWidth, DATAGRIDVIEWNUMERICUPDOWNCELL_defaultRenderingBitmapHeight); DATAGRIDVIEWNUMERICUPDOWNCELL_defaultRenderingBitmapHeight);
}
// Create a thread specific NumericUpDown control used for the painting of the non-edited cells // Create a thread specific NumericUpDown control used for the painting of the non-edited cells
if (paintingNumericUpDown == null) if (paintingNumericUpDown == null)
@ -93,79 +86,64 @@ namespace GradeCalc
} }
/// <summary> /// <summary>
/// The DecimalPlaces property replicates the one from the NumericUpDown control /// The DecimalPlaces property replicates the one from the NumericUpDown control
/// </summary> /// </summary>
[ [
DefaultValue(DATAGRIDVIEWNUMERICUPDOWNCELL_defaultDecimalPlaces) DefaultValue(DATAGRIDVIEWNUMERICUPDOWNCELL_defaultDecimalPlaces)
] ]
public int DecimalPlaces public int DecimalPlaces
{ {
get { get => decimalPlaces;
return decimalPlaces;
}
set { set
{
if (value < 0 || value > 99) if (value < 0 || value > 99)
{ throw new ArgumentOutOfRangeException(
throw new ArgumentOutOfRangeException("The DecimalPlaces property cannot be smaller than 0 or larger than 99."); "The DecimalPlaces property cannot be smaller than 0 or larger than 99.");
}
if (decimalPlaces != value) if (decimalPlaces != value)
{ {
SetDecimalPlaces(RowIndex, value); SetDecimalPlaces(RowIndex, value);
OnCommonChange(); // Assure that the cell or column gets repainted and autosized if needed OnCommonChange(); // Assure that the cell or column gets repainted and autosized if needed
} }
} }
} }
/// <summary> /// <summary>
/// Returns the current DataGridView EditingControl as a DataGridViewNumericUpDownEditingControl control /// Returns the current DataGridView EditingControl as a DataGridViewNumericUpDownEditingControl control
/// </summary> /// </summary>
private DataGridViewNumericUpDownEditingControl EditingNumericUpDown private DataGridViewNumericUpDownEditingControl EditingNumericUpDown =>
{ DataGridView.EditingControl as DataGridViewNumericUpDownEditingControl;
get {
return DataGridView.EditingControl as DataGridViewNumericUpDownEditingControl;
}
}
/// <summary> /// <summary>
/// Define the type of the cell's editing control /// Define the type of the cell's editing control
/// </summary> /// </summary>
public override Type EditType public override Type EditType => defaultEditType; // the type is DataGridViewNumericUpDownEditingControl
{
get {
return defaultEditType; // the type is DataGridViewNumericUpDownEditingControl
}
}
/// <summary> /// <summary>
/// The Increment property replicates the one from the NumericUpDown control /// The Increment property replicates the one from the NumericUpDown control
/// </summary> /// </summary>
public decimal Increment public decimal Increment
{ {
get { get => increment;
return increment;
}
set { set
if (value < (decimal)0.0) {
{ if (value < (decimal) 0.0)
throw new ArgumentOutOfRangeException("The Increment property cannot be smaller than 0."); throw new ArgumentOutOfRangeException("The Increment property cannot be smaller than 0.");
}
SetIncrement(RowIndex, value); SetIncrement(RowIndex, value);
// No call to OnCommonChange is needed since the increment value does not affect the rendering of the cell. // No call to OnCommonChange is needed since the increment value does not affect the rendering of the cell.
} }
} }
/// <summary> /// <summary>
/// The Maximum property replicates the one from the NumericUpDown control /// The Maximum property replicates the one from the NumericUpDown control
/// </summary> /// </summary>
public decimal Maximum public decimal Maximum
{ {
get { get => maximum;
return maximum;
}
set { set
{
if (maximum != value) if (maximum != value)
{ {
SetMaximum(RowIndex, value); SetMaximum(RowIndex, value);
@ -175,15 +153,14 @@ namespace GradeCalc
} }
/// <summary> /// <summary>
/// The Minimum property replicates the one from the NumericUpDown control /// The Minimum property replicates the one from the NumericUpDown control
/// </summary> /// </summary>
public decimal Minimum public decimal Minimum
{ {
get { get => minimum;
return minimum;
}
set { set
{
if (minimum != value) if (minimum != value)
{ {
SetMinimum(RowIndex, value); SetMinimum(RowIndex, value);
@ -193,18 +170,17 @@ namespace GradeCalc
} }
/// <summary> /// <summary>
/// The ThousandsSeparator property replicates the one from the NumericUpDown control /// The ThousandsSeparator property replicates the one from the NumericUpDown control
/// </summary> /// </summary>
[ [
DefaultValue(DATAGRIDVIEWNUMERICUPDOWNCELL_defaultThousandsSeparator) DefaultValue(DATAGRIDVIEWNUMERICUPDOWNCELL_defaultThousandsSeparator)
] ]
public bool ThousandsSeparator public bool ThousandsSeparator
{ {
get { get => thousandsSeparator;
return thousandsSeparator;
}
set { set
{
if (thousandsSeparator != value) if (thousandsSeparator != value)
{ {
SetThousandsSeparator(RowIndex, value); SetThousandsSeparator(RowIndex, value);
@ -214,22 +190,24 @@ namespace GradeCalc
} }
/// <summary> /// <summary>
/// Returns the type of the cell's Value property /// Returns the type of the cell's Value property
/// </summary> /// </summary>
public override Type ValueType public override Type ValueType
{ {
get { get
{
Type valueType = base.ValueType; Type valueType = base.ValueType;
if (valueType != null) if (valueType != null) return valueType;
{
return valueType;
}
return defaultValueType; return defaultValueType;
} }
} }
// Used in KeyEntersEditMode function
[DllImport("USER32.DLL", CharSet = CharSet.Auto)]
private static extern short VkKeyScan(char key);
/// <summary> /// <summary>
/// Clones a DataGridViewNumericUpDownCell cell, copies all the custom properties. /// Clones a DataGridViewNumericUpDownCell cell, copies all the custom properties.
/// </summary> /// </summary>
public override object Clone() public override object Clone()
{ {
@ -242,28 +220,23 @@ namespace GradeCalc
dataGridViewCell.Minimum = Minimum; dataGridViewCell.Minimum = Minimum;
dataGridViewCell.ThousandsSeparator = ThousandsSeparator; dataGridViewCell.ThousandsSeparator = ThousandsSeparator;
} }
return dataGridViewCell; return dataGridViewCell;
} }
/// <summary> /// <summary>
/// Returns the provided value constrained to be within the min and max. /// Returns the provided value constrained to be within the min and max.
/// </summary> /// </summary>
private decimal Constrain(decimal value) private decimal Constrain(decimal value)
{ {
Debug.Assert(minimum <= maximum); Debug.Assert(minimum <= maximum);
if (value < minimum) if (value < minimum) value = minimum;
{ if (value > maximum) value = maximum;
value = minimum;
}
if (value > maximum)
{
value = maximum;
}
return value; return value;
} }
/// <summary> /// <summary>
/// DetachEditingControl gets called by the DataGridView control when the editing session is ending /// DetachEditingControl gets called by the DataGridView control when the editing session is ending
/// </summary> /// </summary>
[ [
EditorBrowsable(EditorBrowsableState.Advanced) EditorBrowsable(EditorBrowsableState.Advanced)
@ -272,9 +245,7 @@ namespace GradeCalc
{ {
DataGridView dataGridView = DataGridView; DataGridView dataGridView = DataGridView;
if (dataGridView == null || dataGridView.EditingControl == null) if (dataGridView == null || dataGridView.EditingControl == null)
{
throw new InvalidOperationException("Cell is detached or its grid has no editing control."); throw new InvalidOperationException("Cell is detached or its grid has no editing control.");
}
NumericUpDown numericUpDown = dataGridView.EditingControl as NumericUpDown; NumericUpDown numericUpDown = dataGridView.EditingControl as NumericUpDown;
if (numericUpDown != null) if (numericUpDown != null)
@ -285,19 +256,17 @@ namespace GradeCalc
// Here the undo buffer of the TextBox inside the NumericUpDown control gets cleared to avoid // Here the undo buffer of the TextBox inside the NumericUpDown control gets cleared to avoid
// interferences between the editing sessions. // interferences between the editing sessions.
TextBox textBox = numericUpDown.Controls[1] as TextBox; TextBox textBox = numericUpDown.Controls[1] as TextBox;
if (textBox != null) if (textBox != null) textBox.ClearUndo();
{
textBox.ClearUndo();
}
} }
base.DetachEditingControl(); base.DetachEditingControl();
} }
/// <summary> /// <summary>
/// Adjusts the location and size of the editing control given the alignment characteristics of the cell /// Adjusts the location and size of the editing control given the alignment characteristics of the cell
/// </summary> /// </summary>
private Rectangle GetAdjustedEditingControlBounds(Rectangle editingControlBounds, DataGridViewCellStyle cellStyle) private Rectangle GetAdjustedEditingControlBounds(Rectangle editingControlBounds,
DataGridViewCellStyle cellStyle)
{ {
// Add a 1 pixel padding on the left and right of the editing control // Add a 1 pixel padding on the left and right of the editing control
editingControlBounds.X += 1; editingControlBounds.X += 1;
@ -306,7 +275,6 @@ namespace GradeCalc
// Adjust the vertical location of the editing control: // Adjust the vertical location of the editing control:
int preferredHeight = cellStyle.Font.Height + 3; int preferredHeight = cellStyle.Font.Height + 3;
if (preferredHeight < editingControlBounds.Height) if (preferredHeight < editingControlBounds.Height)
{
switch (cellStyle.Alignment) switch (cellStyle.Alignment)
{ {
case DataGridViewContentAlignment.MiddleLeft: case DataGridViewContentAlignment.MiddleLeft:
@ -321,87 +289,83 @@ namespace GradeCalc
editingControlBounds.Y += editingControlBounds.Height - preferredHeight; editingControlBounds.Y += editingControlBounds.Height - preferredHeight;
break; break;
} }
}
return editingControlBounds; return editingControlBounds;
} }
/// <summary> /// <summary>
/// Customized implementation of the GetErrorIconBounds function in order to draw the potential /// Customized implementation of the GetErrorIconBounds function in order to draw the potential
/// error icon next to the up/down buttons and not on top of them. /// error icon next to the up/down buttons and not on top of them.
/// </summary> /// </summary>
protected override Rectangle GetErrorIconBounds(Graphics graphics, DataGridViewCellStyle cellStyle, int rowIndex) protected override Rectangle GetErrorIconBounds(Graphics graphics, DataGridViewCellStyle cellStyle,
int rowIndex)
{ {
const int ButtonsWidth = 16; const int ButtonsWidth = 16;
Rectangle errorIconBounds = base.GetErrorIconBounds(graphics, cellStyle, rowIndex); Rectangle errorIconBounds = base.GetErrorIconBounds(graphics, cellStyle, rowIndex);
if (DataGridView.RightToLeft == RightToLeft.Yes) if (DataGridView.RightToLeft == RightToLeft.Yes)
{
errorIconBounds.X = errorIconBounds.Left + ButtonsWidth; errorIconBounds.X = errorIconBounds.Left + ButtonsWidth;
}
else else
{
errorIconBounds.X = errorIconBounds.Left - ButtonsWidth; errorIconBounds.X = errorIconBounds.Left - ButtonsWidth;
}
return errorIconBounds; return errorIconBounds;
} }
/// <summary> /// <summary>
/// Customized implementation of the GetFormattedValue function in order to include the decimal and thousand separator /// Customized implementation of the GetFormattedValue function in order to include the decimal and thousand separator
/// characters in the formatted representation of the cell value. /// characters in the formatted representation of the cell value.
/// </summary> /// </summary>
protected override object GetFormattedValue(object value, protected override object GetFormattedValue(object value,
int rowIndex, int rowIndex,
ref DataGridViewCellStyle cellStyle, ref DataGridViewCellStyle cellStyle,
TypeConverter valueTypeConverter, TypeConverter valueTypeConverter,
TypeConverter formattedValueTypeConverter, TypeConverter formattedValueTypeConverter,
DataGridViewDataErrorContexts context) DataGridViewDataErrorContexts context)
{ {
// By default, the base implementation converts the Decimal 1234.5 into the string "1234.5" // By default, the base implementation converts the Decimal 1234.5 into the string "1234.5"
object formattedValue = base.GetFormattedValue(value, rowIndex, ref cellStyle, valueTypeConverter, formattedValueTypeConverter, context); object formattedValue = base.GetFormattedValue(value, rowIndex, ref cellStyle, valueTypeConverter,
formattedValueTypeConverter, context);
string formattedNumber = formattedValue as string; string formattedNumber = formattedValue as string;
if (!string.IsNullOrEmpty(formattedNumber) && value != null) if (!string.IsNullOrEmpty(formattedNumber) && value != null)
{ {
decimal unformattedDecimal = Convert.ToDecimal(value); decimal unformattedDecimal = Convert.ToDecimal(value);
decimal formattedDecimal = Convert.ToDecimal(formattedNumber); decimal formattedDecimal = Convert.ToDecimal(formattedNumber);
if (unformattedDecimal == formattedDecimal) if (unformattedDecimal == formattedDecimal)
{
// The base implementation of GetFormattedValue (which triggers the CellFormatting event) did nothing else than // The base implementation of GetFormattedValue (which triggers the CellFormatting event) did nothing else than
// the typical 1234.5 to "1234.5" conversion. But depending on the values of ThousandsSeparator and DecimalPlaces, // the typical 1234.5 to "1234.5" conversion. But depending on the values of ThousandsSeparator and DecimalPlaces,
// this may not be the actual string displayed. The real formatted value may be "1,234.500" // this may not be the actual string displayed. The real formatted value may be "1,234.500"
return formattedDecimal.ToString((ThousandsSeparator ? "N" : "F") + DecimalPlaces.ToString()); return formattedDecimal.ToString((ThousandsSeparator ? "N" : "F") + DecimalPlaces);
}
} }
return formattedValue; return formattedValue;
} }
/// <summary> /// <summary>
/// Custom implementation of the GetPreferredSize function. This implementation uses the preferred size of the base /// Custom implementation of the GetPreferredSize function. This implementation uses the preferred size of the base
/// DataGridViewTextBoxCell cell and adds room for the up/down buttons. /// DataGridViewTextBoxCell cell and adds room for the up/down buttons.
/// </summary> /// </summary>
protected override Size GetPreferredSize(Graphics graphics, DataGridViewCellStyle cellStyle, int rowIndex, Size constraintSize) protected override Size GetPreferredSize(Graphics graphics, DataGridViewCellStyle cellStyle, int rowIndex,
Size constraintSize)
{ {
if (DataGridView == null) if (DataGridView == null) return new Size(-1, -1);
{
return new Size(-1, -1);
}
Size preferredSize = base.GetPreferredSize(graphics, cellStyle, rowIndex, constraintSize); Size preferredSize = base.GetPreferredSize(graphics, cellStyle, rowIndex, constraintSize);
if (constraintSize.Width == 0) if (constraintSize.Width == 0)
{ {
const int ButtonsWidth = 16; // Account for the width of the up/down buttons. const int ButtonsWidth = 16; // Account for the width of the up/down buttons.
const int ButtonMargin = 8; // Account for some blank pixels between the text and buttons. const int ButtonMargin = 8; // Account for some blank pixels between the text and buttons.
preferredSize.Width += ButtonsWidth + ButtonMargin; preferredSize.Width += ButtonsWidth + ButtonMargin;
} }
return preferredSize; return preferredSize;
} }
/// <summary> /// <summary>
/// Custom implementation of the InitializeEditingControl function. This function is called by the DataGridView control /// Custom implementation of the InitializeEditingControl function. This function is called by the DataGridView control
/// at the beginning of an editing session. It makes sure that the properties of the NumericUpDown editing control are /// at the beginning of an editing session. It makes sure that the properties of the NumericUpDown editing control are
/// set according to the cell properties. /// set according to the cell properties.
/// </summary> /// </summary>
public override void InitializeEditingControl(int rowIndex, object initialFormattedValue, DataGridViewCellStyle dataGridViewCellStyle) public override void InitializeEditingControl(int rowIndex, object initialFormattedValue,
DataGridViewCellStyle dataGridViewCellStyle)
{ {
base.InitializeEditingControl(rowIndex, initialFormattedValue, dataGridViewCellStyle); base.InitializeEditingControl(rowIndex, initialFormattedValue, dataGridViewCellStyle);
NumericUpDown numericUpDown = DataGridView.EditingControl as NumericUpDown; NumericUpDown numericUpDown = DataGridView.EditingControl as NumericUpDown;
@ -415,20 +379,16 @@ namespace GradeCalc
numericUpDown.ThousandsSeparator = ThousandsSeparator; numericUpDown.ThousandsSeparator = ThousandsSeparator;
string initialFormattedValueStr = initialFormattedValue as string; string initialFormattedValueStr = initialFormattedValue as string;
if (initialFormattedValueStr == null) if (initialFormattedValueStr == null)
{
numericUpDown.Text = string.Empty; numericUpDown.Text = string.Empty;
}
else else
{
numericUpDown.Text = initialFormattedValueStr; numericUpDown.Text = initialFormattedValueStr;
}
} }
} }
/// <summary> /// <summary>
/// Custom implementation of the KeyEntersEditMode function. This function is called by the DataGridView control /// Custom implementation of the KeyEntersEditMode function. This function is called by the DataGridView control
/// to decide whether a keystroke must start an editing session or not. In this case, a new session is started when /// to decide whether a keystroke must start an editing session or not. In this case, a new session is started when
/// a digit or negative sign key is hit. /// a digit or negative sign key is hit.
/// </summary> /// </summary>
public override bool KeyEntersEditMode(KeyEventArgs e) public override bool KeyEntersEditMode(KeyEventArgs e)
{ {
@ -436,83 +396,74 @@ namespace GradeCalc
Keys negativeSignKey = Keys.None; Keys negativeSignKey = Keys.None;
string negativeSignStr = numberFormatInfo.NegativeSign; string negativeSignStr = numberFormatInfo.NegativeSign;
if (!string.IsNullOrEmpty(negativeSignStr) && negativeSignStr.Length == 1) if (!string.IsNullOrEmpty(negativeSignStr) && negativeSignStr.Length == 1)
{ negativeSignKey = (Keys) VkKeyScan(negativeSignStr[0]);
negativeSignKey = (Keys)VkKeyScan(negativeSignStr[0]);
}
if ((char.IsDigit((char)e.KeyCode) || if ((char.IsDigit((char) e.KeyCode) ||
e.KeyCode >= Keys.NumPad0 && e.KeyCode <= Keys.NumPad9 || (e.KeyCode >= Keys.NumPad0 && e.KeyCode <= Keys.NumPad9) ||
negativeSignKey == e.KeyCode || negativeSignKey == e.KeyCode ||
Keys.Subtract == e.KeyCode) && Keys.Subtract == e.KeyCode) &&
!e.Shift && !e.Alt && !e.Control) !e.Shift && !e.Alt && !e.Control)
{
return true; return true;
}
return false; return false;
} }
/// <summary> /// <summary>
/// Called when a cell characteristic that affects its rendering and/or preferred size has changed. /// Called when a cell characteristic that affects its rendering and/or preferred size has changed.
/// This implementation only takes care of repainting the cells. The DataGridView's autosizing methods /// This implementation only takes care of repainting the cells. The DataGridView's autosizing methods
/// also need to be called in cases where some grid elements autosize. /// also need to be called in cases where some grid elements autosize.
/// </summary> /// </summary>
private void OnCommonChange() private void OnCommonChange()
{ {
if (DataGridView != null && !DataGridView.IsDisposed && !DataGridView.Disposing) if (DataGridView != null && !DataGridView.IsDisposed && !DataGridView.Disposing)
{ {
if (RowIndex == -1) if (RowIndex == -1)
{
// Invalidate and autosize column // Invalidate and autosize column
DataGridView.InvalidateColumn(ColumnIndex); DataGridView.InvalidateColumn(ColumnIndex);
// TODO: Add code to autosize the cell's column, the rows, the column headers // TODO: Add code to autosize the cell's column, the rows, the column headers
// and the row headers depending on their autosize settings. // and the row headers depending on their autosize settings.
// The DataGridView control does not expose a public method that takes care of this. // The DataGridView control does not expose a public method that takes care of this.
}
else else
{
// The DataGridView control exposes a public method called UpdateCellValue // The DataGridView control exposes a public method called UpdateCellValue
// that invalidates the cell so that it gets repainted and also triggers all // that invalidates the cell so that it gets repainted and also triggers all
// the necessary autosizing: the cell's column and/or row, the column headers // the necessary autosizing: the cell's column and/or row, the column headers
// and the row headers are autosized depending on their autosize settings. // and the row headers are autosized depending on their autosize settings.
DataGridView.UpdateCellValue(ColumnIndex, RowIndex); DataGridView.UpdateCellValue(ColumnIndex, RowIndex);
}
} }
} }
/// <summary> /// <summary>
/// Determines whether this cell, at the given row index, shows the grid's editing control or not. /// Determines whether this cell, at the given row index, shows the grid's editing control or not.
/// The row index needs to be provided as a parameter because this cell may be shared among multiple rows. /// The row index needs to be provided as a parameter because this cell may be shared among multiple rows.
/// </summary> /// </summary>
private bool OwnsEditingNumericUpDown(int rowIndex) private bool OwnsEditingNumericUpDown(int rowIndex)
{ {
if (rowIndex == -1 || DataGridView == null) if (rowIndex == -1 || DataGridView == null) return false;
{ DataGridViewNumericUpDownEditingControl numericUpDownEditingControl =
return false; DataGridView.EditingControl as DataGridViewNumericUpDownEditingControl;
} return numericUpDownEditingControl != null && rowIndex ==
DataGridViewNumericUpDownEditingControl numericUpDownEditingControl = DataGridView.EditingControl as DataGridViewNumericUpDownEditingControl; ((IDataGridViewEditingControl) numericUpDownEditingControl).EditingControlRowIndex;
return numericUpDownEditingControl != null && rowIndex == ((IDataGridViewEditingControl)numericUpDownEditingControl).EditingControlRowIndex;
} }
/// <summary> /// <summary>
/// Custom paints the cell. The base implementation of the DataGridViewTextBoxCell type is called first, /// Custom paints the cell. The base implementation of the DataGridViewTextBoxCell type is called first,
/// dropping the icon error and content foreground parts. Those two parts are painted by this custom implementation. /// dropping the icon error and content foreground parts. Those two parts are painted by this custom implementation.
/// In this sample, the non-edited NumericUpDown control is painted by using a call to Control.DrawToBitmap. This is /// In this sample, the non-edited NumericUpDown control is painted by using a call to Control.DrawToBitmap. This is
/// an easy solution for painting controls but it's not necessarily the most performant. An alternative would be to paint /// an easy solution for painting controls but it's not necessarily the most performant. An alternative would be to
/// the NumericUpDown control piece by piece (text and up/down buttons). /// paint
/// the NumericUpDown control piece by piece (text and up/down buttons).
/// </summary> /// </summary>
protected override void Paint(Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, int rowIndex, DataGridViewElementStates cellState, protected override void Paint(Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, int rowIndex,
object value, object formattedValue, string errorText, DataGridViewCellStyle cellStyle, DataGridViewElementStates cellState,
DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts) object value, object formattedValue, string errorText, DataGridViewCellStyle cellStyle,
DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts)
{ {
if (DataGridView == null) if (DataGridView == null) return;
{
return;
}
// First paint the borders and background of the cell. // First paint the borders and background of the cell.
base.Paint(graphics, clipBounds, cellBounds, rowIndex, cellState, value, formattedValue, errorText, cellStyle, advancedBorderStyle, base.Paint(graphics, clipBounds, cellBounds, rowIndex, cellState, value, formattedValue, errorText,
paintParts & ~(DataGridViewPaintParts.ErrorIcon | DataGridViewPaintParts.ContentForeground)); cellStyle, advancedBorderStyle,
paintParts & ~(DataGridViewPaintParts.ErrorIcon | DataGridViewPaintParts.ContentForeground));
Point ptCurrentCell = DataGridView.CurrentCellAddress; Point ptCurrentCell = DataGridView.CurrentCellAddress;
bool cellCurrent = ptCurrentCell.X == ColumnIndex && ptCurrentCell.Y == rowIndex; bool cellCurrent = ptCurrentCell.X == ColumnIndex && ptCurrentCell.Y == rowIndex;
@ -534,16 +485,13 @@ namespace GradeCalc
if (cellStyle.Padding != Padding.Empty) if (cellStyle.Padding != Padding.Empty)
{ {
if (DataGridView.RightToLeft == RightToLeft.Yes) if (DataGridView.RightToLeft == RightToLeft.Yes)
{
valBounds.Offset(cellStyle.Padding.Right, cellStyle.Padding.Top); valBounds.Offset(cellStyle.Padding.Right, cellStyle.Padding.Top);
}
else else
{
valBounds.Offset(cellStyle.Padding.Left, cellStyle.Padding.Top); valBounds.Offset(cellStyle.Padding.Left, cellStyle.Padding.Top);
}
valBounds.Width -= cellStyle.Padding.Horizontal; valBounds.Width -= cellStyle.Padding.Horizontal;
valBounds.Height -= cellStyle.Padding.Vertical; valBounds.Height -= cellStyle.Padding.Vertical;
} }
// Determine the NumericUpDown control location // Determine the NumericUpDown control location
valBounds = GetAdjustedEditingControlBounds(valBounds, cellStyle); valBounds = GetAdjustedEditingControlBounds(valBounds, cellStyle);
@ -556,11 +504,10 @@ namespace GradeCalc
renderingBitmap.Dispose(); renderingBitmap.Dispose();
renderingBitmap = new Bitmap(valBounds.Width, valBounds.Height); renderingBitmap = new Bitmap(valBounds.Width, valBounds.Height);
} }
// Make sure the NumericUpDown control is parented to a visible control // Make sure the NumericUpDown control is parented to a visible control
if (paintingNumericUpDown.Parent == null || !paintingNumericUpDown.Parent.Visible) if (paintingNumericUpDown.Parent == null || !paintingNumericUpDown.Parent.Visible)
{
paintingNumericUpDown.Parent = DataGridView; paintingNumericUpDown.Parent = DataGridView;
}
// Set all the relevant properties // Set all the relevant properties
paintingNumericUpDown.TextAlign = TranslateAlignment(cellStyle.Alignment); paintingNumericUpDown.TextAlign = TranslateAlignment(cellStyle.Alignment);
paintingNumericUpDown.DecimalPlaces = DecimalPlaces; paintingNumericUpDown.DecimalPlaces = DecimalPlaces;
@ -574,89 +521,78 @@ namespace GradeCalc
Color backColor; Color backColor;
if (PartPainted(paintParts, DataGridViewPaintParts.SelectionBackground) && cellSelected) if (PartPainted(paintParts, DataGridViewPaintParts.SelectionBackground) && cellSelected)
{
backColor = cellStyle.SelectionBackColor; backColor = cellStyle.SelectionBackColor;
}
else else
{
backColor = cellStyle.BackColor; backColor = cellStyle.BackColor;
}
if (PartPainted(paintParts, DataGridViewPaintParts.Background)) if (PartPainted(paintParts, DataGridViewPaintParts.Background))
{ {
if (backColor.A < 255) if (backColor.A < 255)
{
// The NumericUpDown control does not support transparent back colors // The NumericUpDown control does not support transparent back colors
backColor = Color.FromArgb(255, backColor); backColor = Color.FromArgb(255, backColor);
}
paintingNumericUpDown.BackColor = backColor; paintingNumericUpDown.BackColor = backColor;
} }
// Finally paint the NumericUpDown control // Finally paint the NumericUpDown control
Rectangle srcRect = new Rectangle(0, 0, valBounds.Width, valBounds.Height); Rectangle srcRect = new Rectangle(0, 0, valBounds.Width, valBounds.Height);
if (srcRect.Width > 0 && srcRect.Height > 0) if (srcRect.Width > 0 && srcRect.Height > 0)
{ {
paintingNumericUpDown.DrawToBitmap(renderingBitmap, srcRect); paintingNumericUpDown.DrawToBitmap(renderingBitmap, srcRect);
graphics.DrawImage(renderingBitmap, new Rectangle(valBounds.Location, valBounds.Size), graphics.DrawImage(renderingBitmap, new Rectangle(valBounds.Location, valBounds.Size),
srcRect, GraphicsUnit.Pixel); srcRect, GraphicsUnit.Pixel);
} }
} }
if (PartPainted(paintParts, DataGridViewPaintParts.ErrorIcon)) if (PartPainted(paintParts, DataGridViewPaintParts.ErrorIcon))
{
// Paint the potential error icon on top of the NumericUpDown control // Paint the potential error icon on top of the NumericUpDown control
base.Paint(graphics, clipBounds, cellBounds, rowIndex, cellState, value, formattedValue, errorText, base.Paint(graphics, clipBounds, cellBounds, rowIndex, cellState, value, formattedValue, errorText,
cellStyle, advancedBorderStyle, DataGridViewPaintParts.ErrorIcon); cellStyle, advancedBorderStyle, DataGridViewPaintParts.ErrorIcon);
}
} }
} }
/// <summary> /// <summary>
/// Little utility function called by the Paint function to see if a particular part needs to be painted. /// Little utility function called by the Paint function to see if a particular part needs to be painted.
/// </summary> /// </summary>
private static bool PartPainted(DataGridViewPaintParts paintParts, DataGridViewPaintParts paintPart) private static bool PartPainted(DataGridViewPaintParts paintParts, DataGridViewPaintParts paintPart) =>
{ (paintParts & paintPart) != 0;
return (paintParts & paintPart) != 0;
}
/// <summary> /// <summary>
/// Custom implementation of the PositionEditingControl method called by the DataGridView control when it /// Custom implementation of the PositionEditingControl method called by the DataGridView control when it
/// needs to relocate and/or resize the editing control. /// needs to relocate and/or resize the editing control.
/// </summary> /// </summary>
public override void PositionEditingControl(bool setLocation, public override void PositionEditingControl(bool setLocation,
bool setSize, bool setSize,
Rectangle cellBounds, Rectangle cellBounds,
Rectangle cellClip, Rectangle cellClip,
DataGridViewCellStyle cellStyle, DataGridViewCellStyle cellStyle,
bool singleVerticalBorderAdded, bool singleVerticalBorderAdded,
bool singleHorizontalBorderAdded, bool singleHorizontalBorderAdded,
bool isFirstDisplayedColumn, bool isFirstDisplayedColumn,
bool isFirstDisplayedRow) bool isFirstDisplayedRow)
{ {
Rectangle editingControlBounds = PositionEditingPanel(cellBounds, Rectangle editingControlBounds = PositionEditingPanel(cellBounds,
cellClip, cellClip,
cellStyle, cellStyle,
singleVerticalBorderAdded, singleVerticalBorderAdded,
singleHorizontalBorderAdded, singleHorizontalBorderAdded,
isFirstDisplayedColumn, isFirstDisplayedColumn,
isFirstDisplayedRow); isFirstDisplayedRow);
editingControlBounds = GetAdjustedEditingControlBounds(editingControlBounds, cellStyle); editingControlBounds = GetAdjustedEditingControlBounds(editingControlBounds, cellStyle);
DataGridView.EditingControl.Location = new Point(editingControlBounds.X, editingControlBounds.Y); DataGridView.EditingControl.Location = new Point(editingControlBounds.X, editingControlBounds.Y);
DataGridView.EditingControl.Size = new Size(editingControlBounds.Width, editingControlBounds.Height); DataGridView.EditingControl.Size = new Size(editingControlBounds.Width, editingControlBounds.Height);
} }
/// <summary> /// <summary>
/// Utility function that sets a new value for the DecimalPlaces property of the cell. This function is used by /// Utility function that sets a new value for the DecimalPlaces property of the cell. This function is used by
/// the cell and column DecimalPlaces property. The column uses this method instead of the DecimalPlaces /// the cell and column DecimalPlaces property. The column uses this method instead of the DecimalPlaces
/// property for performance reasons. This way the column can invalidate the entire column at once instead of /// property for performance reasons. This way the column can invalidate the entire column at once instead of
/// invalidating each cell of the column individually. A row index needs to be provided as a parameter because /// invalidating each cell of the column individually. A row index needs to be provided as a parameter because
/// this cell may be shared among multiple rows. /// this cell may be shared among multiple rows.
/// </summary> /// </summary>
internal void SetDecimalPlaces(int rowIndex, int value) internal void SetDecimalPlaces(int rowIndex, int value)
{ {
Debug.Assert(value >= 0 && value <= 99); Debug.Assert(value >= 0 && value <= 99);
decimalPlaces = value; decimalPlaces = value;
if (OwnsEditingNumericUpDown(rowIndex)) if (OwnsEditingNumericUpDown(rowIndex)) EditingNumericUpDown.DecimalPlaces = value;
{
EditingNumericUpDown.DecimalPlaces = value;
}
} }
/// Utility function that sets a new value for the Increment property of the cell. This function is used by /// Utility function that sets a new value for the Increment property of the cell. This function is used by
@ -664,12 +600,9 @@ namespace GradeCalc
/// this cell may be shared among multiple rows. /// this cell may be shared among multiple rows.
internal void SetIncrement(int rowIndex, decimal value) internal void SetIncrement(int rowIndex, decimal value)
{ {
Debug.Assert(value >= (decimal)0.0); Debug.Assert(value >= (decimal) 0.0);
increment = value; increment = value;
if (OwnsEditingNumericUpDown(rowIndex)) if (OwnsEditingNumericUpDown(rowIndex)) EditingNumericUpDown.Increment = value;
{
EditingNumericUpDown.Increment = value;
}
} }
/// Utility function that sets a new value for the Maximum property of the cell. This function is used by /// Utility function that sets a new value for the Maximum property of the cell. This function is used by
@ -680,25 +613,17 @@ namespace GradeCalc
internal void SetMaximum(int rowIndex, decimal value) internal void SetMaximum(int rowIndex, decimal value)
{ {
maximum = value; maximum = value;
if (minimum > maximum) if (minimum > maximum) minimum = maximum;
{
minimum = maximum;
}
object cellValue = GetValue(rowIndex); object cellValue = GetValue(rowIndex);
if (cellValue != null) if (cellValue != null)
{ {
decimal currentValue = Convert.ToDecimal(cellValue); decimal currentValue = Convert.ToDecimal(cellValue);
decimal constrainedValue = Constrain(currentValue); decimal constrainedValue = Constrain(currentValue);
if (constrainedValue != currentValue) if (constrainedValue != currentValue) SetValue(rowIndex, constrainedValue);
{
SetValue(rowIndex, constrainedValue);
}
} }
Debug.Assert(maximum == value); Debug.Assert(maximum == value);
if (OwnsEditingNumericUpDown(rowIndex)) if (OwnsEditingNumericUpDown(rowIndex)) EditingNumericUpDown.Maximum = value;
{
EditingNumericUpDown.Maximum = value;
}
} }
/// Utility function that sets a new value for the Minimum property of the cell. This function is used by /// Utility function that sets a new value for the Minimum property of the cell. This function is used by
@ -709,25 +634,17 @@ namespace GradeCalc
internal void SetMinimum(int rowIndex, decimal value) internal void SetMinimum(int rowIndex, decimal value)
{ {
minimum = value; minimum = value;
if (minimum > maximum) if (minimum > maximum) maximum = value;
{
maximum = value;
}
object cellValue = GetValue(rowIndex); object cellValue = GetValue(rowIndex);
if (cellValue != null) if (cellValue != null)
{ {
decimal currentValue = Convert.ToDecimal(cellValue); decimal currentValue = Convert.ToDecimal(cellValue);
decimal constrainedValue = Constrain(currentValue); decimal constrainedValue = Constrain(currentValue);
if (constrainedValue != currentValue) if (constrainedValue != currentValue) SetValue(rowIndex, constrainedValue);
{
SetValue(rowIndex, constrainedValue);
}
} }
Debug.Assert(minimum == value); Debug.Assert(minimum == value);
if (OwnsEditingNumericUpDown(rowIndex)) if (OwnsEditingNumericUpDown(rowIndex)) EditingNumericUpDown.Minimum = value;
{
EditingNumericUpDown.Minimum = value;
}
} }
/// Utility function that sets a new value for the ThousandsSeparator property of the cell. This function is used by /// Utility function that sets a new value for the ThousandsSeparator property of the cell. This function is used by
@ -738,38 +655,28 @@ namespace GradeCalc
internal void SetThousandsSeparator(int rowIndex, bool value) internal void SetThousandsSeparator(int rowIndex, bool value)
{ {
thousandsSeparator = value; thousandsSeparator = value;
if (OwnsEditingNumericUpDown(rowIndex)) if (OwnsEditingNumericUpDown(rowIndex)) EditingNumericUpDown.ThousandsSeparator = value;
{
EditingNumericUpDown.ThousandsSeparator = value;
}
} }
/// <summary> /// <summary>
/// Returns a standard textual representation of the cell. /// Returns a standard textual representation of the cell.
/// </summary> /// </summary>
public override string ToString() public override string ToString() =>
{ "DataGridViewNumericUpDownCell { ColumnIndex=" + ColumnIndex.ToString(CultureInfo.CurrentCulture) +
return "DataGridViewNumericUpDownCell { ColumnIndex=" + ColumnIndex.ToString(CultureInfo.CurrentCulture) + ", RowIndex=" + RowIndex.ToString(CultureInfo.CurrentCulture) + " }"; ", RowIndex=" + RowIndex.ToString(CultureInfo.CurrentCulture) + " }";
}
/// <summary> /// <summary>
/// Little utility function used by both the cell and column types to translate a DataGridViewContentAlignment value into /// Little utility function used by both the cell and column types to translate a DataGridViewContentAlignment value
/// a HorizontalAlignment value. /// into
/// a HorizontalAlignment value.
/// </summary> /// </summary>
internal static HorizontalAlignment TranslateAlignment(DataGridViewContentAlignment align) internal static HorizontalAlignment TranslateAlignment(DataGridViewContentAlignment align)
{ {
if ((align & anyRight) != 0) if ((align & anyRight) != 0)
{
return HorizontalAlignment.Right; return HorizontalAlignment.Right;
} if ((align & anyCenter) != 0)
else if ((align & anyCenter) != 0)
{
return HorizontalAlignment.Center; return HorizontalAlignment.Center;
} return HorizontalAlignment.Left;
else
{
return HorizontalAlignment.Left;
}
} }
} }
} }

View File

@ -4,7 +4,7 @@ using System.Globalization;
using System.Text; using System.Text;
using System.Windows.Forms; using System.Windows.Forms;
namespace GradeCalc namespace CC_Functions.Misc
{ {
/// <summary> /// <summary>
/// Custom column type dedicated to the DataGridViewNumericUpDownCell cell type. /// Custom column type dedicated to the DataGridViewNumericUpDownCell cell type.
@ -28,7 +28,7 @@ namespace GradeCalc
get => base.CellTemplate; get => base.CellTemplate;
set set
{ {
var dataGridViewNumericUpDownCell = value as DataGridViewNumericUpDownCell; DataGridViewNumericUpDownCell dataGridViewNumericUpDownCell = value as DataGridViewNumericUpDownCell;
if (value != null && dataGridViewNumericUpDownCell == null) if (value != null && dataGridViewNumericUpDownCell == null)
throw new InvalidCastException( throw new InvalidCastException(
"Value provided for CellTemplate must be of type DataGridViewNumericUpDownElements.DataGridViewNumericUpDownCell or derive from it."); "Value provided for CellTemplate must be of type DataGridViewNumericUpDownElements.DataGridViewNumericUpDownCell or derive from it.");
@ -61,14 +61,15 @@ namespace GradeCalc
if (DataGridView != null) if (DataGridView != null)
{ {
// Update all the existing DataGridViewNumericUpDownCell cells in the column accordingly. // Update all the existing DataGridViewNumericUpDownCell cells in the column accordingly.
var dataGridViewRows = DataGridView.Rows; DataGridViewRowCollection dataGridViewRows = DataGridView.Rows;
var rowCount = dataGridViewRows.Count; int rowCount = dataGridViewRows.Count;
for (var rowIndex = 0; rowIndex < rowCount; rowIndex++) for (int rowIndex = 0; rowIndex < rowCount; rowIndex++)
{ {
// Be careful not to unshare rows unnecessarily. // Be careful not to unshare rows unnecessarily.
// This could have severe performance repercussions. // This could have severe performance repercussions.
var dataGridViewRow = dataGridViewRows.SharedRow(rowIndex); DataGridViewRow dataGridViewRow = dataGridViewRows.SharedRow(rowIndex);
var dataGridViewCell = dataGridViewRow.Cells[Index] as DataGridViewNumericUpDownCell; DataGridViewNumericUpDownCell dataGridViewCell =
dataGridViewRow.Cells[Index] as DataGridViewNumericUpDownCell;
if (dataGridViewCell != null) if (dataGridViewCell != null)
// Call the internal SetDecimalPlaces method instead of the property to avoid invalidation // Call the internal SetDecimalPlaces method instead of the property to avoid invalidation
// of each cell. The whole column is invalidated later in a single operation for better performance. // of each cell. The whole column is invalidated later in a single operation for better performance.
@ -103,12 +104,13 @@ namespace GradeCalc
NumericUpDownCellTemplate.Increment = value; NumericUpDownCellTemplate.Increment = value;
if (DataGridView != null) if (DataGridView != null)
{ {
var dataGridViewRows = DataGridView.Rows; DataGridViewRowCollection dataGridViewRows = DataGridView.Rows;
var rowCount = dataGridViewRows.Count; int rowCount = dataGridViewRows.Count;
for (var rowIndex = 0; rowIndex < rowCount; rowIndex++) for (int rowIndex = 0; rowIndex < rowCount; rowIndex++)
{ {
var dataGridViewRow = dataGridViewRows.SharedRow(rowIndex); DataGridViewRow dataGridViewRow = dataGridViewRows.SharedRow(rowIndex);
var dataGridViewCell = dataGridViewRow.Cells[Index] as DataGridViewNumericUpDownCell; DataGridViewNumericUpDownCell dataGridViewCell =
dataGridViewRow.Cells[Index] as DataGridViewNumericUpDownCell;
if (dataGridViewCell != null) dataGridViewCell.SetIncrement(rowIndex, value); if (dataGridViewCell != null) dataGridViewCell.SetIncrement(rowIndex, value);
} }
} }
@ -138,12 +140,13 @@ namespace GradeCalc
NumericUpDownCellTemplate.Maximum = value; NumericUpDownCellTemplate.Maximum = value;
if (DataGridView != null) if (DataGridView != null)
{ {
var dataGridViewRows = DataGridView.Rows; DataGridViewRowCollection dataGridViewRows = DataGridView.Rows;
var rowCount = dataGridViewRows.Count; int rowCount = dataGridViewRows.Count;
for (var rowIndex = 0; rowIndex < rowCount; rowIndex++) for (int rowIndex = 0; rowIndex < rowCount; rowIndex++)
{ {
var dataGridViewRow = dataGridViewRows.SharedRow(rowIndex); DataGridViewRow dataGridViewRow = dataGridViewRows.SharedRow(rowIndex);
var dataGridViewCell = dataGridViewRow.Cells[Index] as DataGridViewNumericUpDownCell; DataGridViewNumericUpDownCell dataGridViewCell =
dataGridViewRow.Cells[Index] as DataGridViewNumericUpDownCell;
if (dataGridViewCell != null) dataGridViewCell.SetMaximum(rowIndex, value); if (dataGridViewCell != null) dataGridViewCell.SetMaximum(rowIndex, value);
} }
@ -178,12 +181,13 @@ namespace GradeCalc
NumericUpDownCellTemplate.Minimum = value; NumericUpDownCellTemplate.Minimum = value;
if (DataGridView != null) if (DataGridView != null)
{ {
var dataGridViewRows = DataGridView.Rows; DataGridViewRowCollection dataGridViewRows = DataGridView.Rows;
var rowCount = dataGridViewRows.Count; int rowCount = dataGridViewRows.Count;
for (var rowIndex = 0; rowIndex < rowCount; rowIndex++) for (int rowIndex = 0; rowIndex < rowCount; rowIndex++)
{ {
var dataGridViewRow = dataGridViewRows.SharedRow(rowIndex); DataGridViewRow dataGridViewRow = dataGridViewRows.SharedRow(rowIndex);
var dataGridViewCell = dataGridViewRow.Cells[Index] as DataGridViewNumericUpDownCell; DataGridViewNumericUpDownCell dataGridViewCell =
dataGridViewRow.Cells[Index] as DataGridViewNumericUpDownCell;
if (dataGridViewCell != null) dataGridViewCell.SetMinimum(rowIndex, value); if (dataGridViewCell != null) dataGridViewCell.SetMinimum(rowIndex, value);
} }
@ -218,12 +222,13 @@ namespace GradeCalc
NumericUpDownCellTemplate.ThousandsSeparator = value; NumericUpDownCellTemplate.ThousandsSeparator = value;
if (DataGridView != null) if (DataGridView != null)
{ {
var dataGridViewRows = DataGridView.Rows; DataGridViewRowCollection dataGridViewRows = DataGridView.Rows;
var rowCount = dataGridViewRows.Count; int rowCount = dataGridViewRows.Count;
for (var rowIndex = 0; rowIndex < rowCount; rowIndex++) for (int rowIndex = 0; rowIndex < rowCount; rowIndex++)
{ {
var dataGridViewRow = dataGridViewRows.SharedRow(rowIndex); DataGridViewRow dataGridViewRow = dataGridViewRows.SharedRow(rowIndex);
var dataGridViewCell = dataGridViewRow.Cells[Index] as DataGridViewNumericUpDownCell; DataGridViewNumericUpDownCell dataGridViewCell =
dataGridViewRow.Cells[Index] as DataGridViewNumericUpDownCell;
if (dataGridViewCell != null) dataGridViewCell.SetThousandsSeparator(rowIndex, value); if (dataGridViewCell != null) dataGridViewCell.SetThousandsSeparator(rowIndex, value);
} }
@ -241,29 +246,23 @@ namespace GradeCalc
private DataGridViewNumericUpDownCell NumericUpDownCellTemplate => (DataGridViewNumericUpDownCell) CellTemplate; private DataGridViewNumericUpDownCell NumericUpDownCellTemplate => (DataGridViewNumericUpDownCell) CellTemplate;
/// Indicates whether the Increment property should be persisted. /// Indicates whether the Increment property should be persisted.
private bool ShouldSerializeIncrement() private bool ShouldSerializeIncrement() =>
{ !Increment.Equals(DataGridViewNumericUpDownCell.DATAGRIDVIEWNUMERICUPDOWNCELL_defaultIncrement);
return !Increment.Equals(DataGridViewNumericUpDownCell.DATAGRIDVIEWNUMERICUPDOWNCELL_defaultIncrement);
}
/// Indicates whether the Maximum property should be persisted. /// Indicates whether the Maximum property should be persisted.
private bool ShouldSerializeMaximum() private bool ShouldSerializeMaximum() =>
{ !Maximum.Equals(DataGridViewNumericUpDownCell.DATAGRIDVIEWNUMERICUPDOWNCELL_defaultMaximum);
return !Maximum.Equals(DataGridViewNumericUpDownCell.DATAGRIDVIEWNUMERICUPDOWNCELL_defaultMaximum);
}
/// Indicates whether the Maximum property should be persisted. /// Indicates whether the Maximum property should be persisted.
private bool ShouldSerializeMinimum() private bool ShouldSerializeMinimum() =>
{ !Minimum.Equals(DataGridViewNumericUpDownCell.DATAGRIDVIEWNUMERICUPDOWNCELL_defaultMinimum);
return !Minimum.Equals(DataGridViewNumericUpDownCell.DATAGRIDVIEWNUMERICUPDOWNCELL_defaultMinimum);
}
/// <summary> /// <summary>
/// Returns a standard compact string representation of the column. /// Returns a standard compact string representation of the column.
/// </summary> /// </summary>
public override string ToString() public override string ToString()
{ {
var sb = new StringBuilder(100); StringBuilder sb = new StringBuilder(100);
sb.Append("DataGridViewNumericUpDownColumn { Name="); sb.Append("DataGridViewNumericUpDownColumn { Name=");
sb.Append(Name); sb.Append(Name);
sb.Append(", Index="); sb.Append(", Index=");

View File

@ -1,116 +1,79 @@
using System; using System;
using System.Drawing; using System.Drawing;
using System.Globalization;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Windows.Forms; using System.Windows.Forms;
namespace GradeCalc namespace CC_Functions.Misc
{ {
/// <summary> /// <summary>
/// Defines the editing control for the DataGridViewNumericUpDownCell custom cell type. /// Defines the editing control for the DataGridViewNumericUpDownCell custom cell type.
/// </summary> /// </summary>
internal class DataGridViewNumericUpDownEditingControl : NumericUpDown, IDataGridViewEditingControl internal class DataGridViewNumericUpDownEditingControl : NumericUpDown, IDataGridViewEditingControl
{ {
// Needed to forward keyboard messages to the child TextBox control.
[DllImport("USER32.DLL", CharSet = CharSet.Auto)]
private static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam);
// The grid that owns this editing control // The grid that owns this editing control
private DataGridView dataGridView; private DataGridView dataGridView;
// Stores the row index in which the editing control resides
// Stores whether the editing control's value has changed or not // Stores whether the editing control's value has changed or not
private bool valueChanged; private bool valueChanged;
// Stores the row index in which the editing control resides
private int rowIndex;
/// <summary> /// <summary>
/// Constructor of the editing control class /// Constructor of the editing control class
/// </summary> /// </summary>
public DataGridViewNumericUpDownEditingControl() // The editing control must not be part of the tabbing loop
{ public DataGridViewNumericUpDownEditingControl() => TabStop = false;
// The editing control must not be part of the tabbing loop
TabStop = false;
}
// Beginning of the IDataGridViewEditingControl interface implementation // Beginning of the IDataGridViewEditingControl interface implementation
/// <summary> /// <summary>
/// Property which caches the grid that uses this editing control /// Property which caches the grid that uses this editing control
/// </summary> /// </summary>
public virtual DataGridView EditingControlDataGridView public virtual DataGridView EditingControlDataGridView
{ {
get { get => dataGridView;
return dataGridView; set => dataGridView = value;
}
set {
dataGridView = value;
}
} }
/// <summary> /// <summary>
/// Property which represents the current formatted value of the editing control /// Property which represents the current formatted value of the editing control
/// </summary> /// </summary>
public virtual object EditingControlFormattedValue public virtual object EditingControlFormattedValue
{ {
get { get => GetEditingControlFormattedValue(DataGridViewDataErrorContexts.Formatting);
return GetEditingControlFormattedValue(DataGridViewDataErrorContexts.Formatting); set => Text = (string) value;
}
set {
Text = (string)value;
}
} }
/// <summary> /// <summary>
/// Property which represents the row in which the editing control resides /// Property which represents the row in which the editing control resides
/// </summary> /// </summary>
public virtual int EditingControlRowIndex public virtual int EditingControlRowIndex { get; set; }
{
get {
return rowIndex;
}
set {
rowIndex = value;
}
}
/// <summary> /// <summary>
/// Property which indicates whether the value of the editing control has changed or not /// Property which indicates whether the value of the editing control has changed or not
/// </summary> /// </summary>
public virtual bool EditingControlValueChanged public virtual bool EditingControlValueChanged
{ {
get { get => valueChanged;
return valueChanged; set => valueChanged = value;
}
set {
valueChanged = value;
}
} }
/// <summary> /// <summary>
/// Property which determines which cursor must be used for the editing panel, /// Property which determines which cursor must be used for the editing panel,
/// i.e. the parent of the editing control. /// i.e. the parent of the editing control.
/// </summary> /// </summary>
public virtual Cursor EditingPanelCursor public virtual Cursor EditingPanelCursor => Cursors.Default;
{
get {
return Cursors.Default;
}
}
/// <summary> /// <summary>
/// Property which indicates whether the editing control needs to be repositioned /// Property which indicates whether the editing control needs to be repositioned
/// when its value changes. /// when its value changes.
/// </summary> /// </summary>
public virtual bool RepositionEditingControlOnValueChange public virtual bool RepositionEditingControlOnValueChange => false;
{
get {
return false;
}
}
/// <summary> /// <summary>
/// Method called by the grid before the editing control is shown so it can adapt to the /// Method called by the grid before the editing control is shown so it can adapt to the
/// provided cell style. /// provided cell style.
/// </summary> /// </summary>
public virtual void ApplyCellStyleToEditingControl(DataGridViewCellStyle dataGridViewCellStyle) public virtual void ApplyCellStyleToEditingControl(DataGridViewCellStyle dataGridViewCellStyle)
{ {
@ -126,13 +89,14 @@ namespace GradeCalc
{ {
BackColor = dataGridViewCellStyle.BackColor; BackColor = dataGridViewCellStyle.BackColor;
} }
ForeColor = dataGridViewCellStyle.ForeColor; ForeColor = dataGridViewCellStyle.ForeColor;
TextAlign = DataGridViewNumericUpDownCell.TranslateAlignment(dataGridViewCellStyle.Alignment); TextAlign = DataGridViewNumericUpDownCell.TranslateAlignment(dataGridViewCellStyle.Alignment);
} }
/// <summary> /// <summary>
/// Method called by the grid on keystrokes to determine if the editing control is /// Method called by the grid on keystrokes to determine if the editing control is
/// interested in the key or not. /// interested in the key or not.
/// </summary> /// </summary>
public virtual bool EditingControlWantsInputKey(Keys keyData, bool dataGridViewWantsInputKey) public virtual bool EditingControlWantsInputKey(Keys keyData, bool dataGridViewWantsInputKey)
{ {
@ -142,15 +106,13 @@ namespace GradeCalc
{ {
TextBox textBox = Controls[1] as TextBox; TextBox textBox = Controls[1] as TextBox;
if (textBox != null) if (textBox != null)
{
// If the end of the selection is at the end of the string, // If the end of the selection is at the end of the string,
// let the DataGridView treat the key message // let the DataGridView treat the key message
if (RightToLeft == RightToLeft.No && !(textBox.SelectionLength == 0 && textBox.SelectionStart == textBox.Text.Length) || if ((RightToLeft == RightToLeft.No &&
RightToLeft == RightToLeft.Yes && !(textBox.SelectionLength == 0 && textBox.SelectionStart == 0)) !(textBox.SelectionLength == 0 && textBox.SelectionStart == textBox.Text.Length)) ||
{ (RightToLeft == RightToLeft.Yes &&
!(textBox.SelectionLength == 0 && textBox.SelectionStart == 0)))
return true; return true;
}
}
break; break;
} }
@ -158,35 +120,27 @@ namespace GradeCalc
{ {
TextBox textBox = Controls[1] as TextBox; TextBox textBox = Controls[1] as TextBox;
if (textBox != null) if (textBox != null)
{
// If the end of the selection is at the begining of the string // If the end of the selection is at the begining of the string
// or if the entire text is selected and we did not start editing, // or if the entire text is selected and we did not start editing,
// send this character to the dataGridView, else process the key message // send this character to the dataGridView, else process the key message
if (RightToLeft == RightToLeft.No && !(textBox.SelectionLength == 0 && textBox.SelectionStart == 0) || if ((RightToLeft == RightToLeft.No &&
RightToLeft == RightToLeft.Yes && !(textBox.SelectionLength == 0 && textBox.SelectionStart == textBox.Text.Length)) !(textBox.SelectionLength == 0 && textBox.SelectionStart == 0)) ||
{ (RightToLeft == RightToLeft.Yes &&
!(textBox.SelectionLength == 0 && textBox.SelectionStart == textBox.Text.Length)))
return true; return true;
}
}
break; break;
} }
case Keys.Down: case Keys.Down:
// If the current value hasn't reached its minimum yet, handle the key. Otherwise let // If the current value hasn't reached its minimum yet, handle the key. Otherwise let
// the grid handle it. // the grid handle it.
if (Value > Minimum) if (Value > Minimum) return true;
{
return true;
}
break; break;
case Keys.Up: case Keys.Up:
// If the current value hasn't reached its maximum yet, handle the key. Otherwise let // If the current value hasn't reached its maximum yet, handle the key. Otherwise let
// the grid handle it. // the grid handle it.
if (Value < Maximum) if (Value < Maximum) return true;
{
return true;
}
break; break;
case Keys.Home: case Keys.Home:
@ -195,12 +149,8 @@ namespace GradeCalc
// Let the grid handle the key if the entire text is selected. // Let the grid handle the key if the entire text is selected.
TextBox textBox = Controls[1] as TextBox; TextBox textBox = Controls[1] as TextBox;
if (textBox != null) if (textBox != null)
{
if (textBox.SelectionLength != textBox.Text.Length) if (textBox.SelectionLength != textBox.Text.Length)
{
return true; return true;
}
}
break; break;
} }
@ -209,21 +159,18 @@ namespace GradeCalc
// Let the grid handle the key if the carret is at the end of the text. // Let the grid handle the key if the carret is at the end of the text.
TextBox textBox = Controls[1] as TextBox; TextBox textBox = Controls[1] as TextBox;
if (textBox != null) if (textBox != null)
{
if (textBox.SelectionLength > 0 || if (textBox.SelectionLength > 0 ||
textBox.SelectionStart < textBox.Text.Length) textBox.SelectionStart < textBox.Text.Length)
{
return true; return true;
}
}
break; break;
} }
} }
return !dataGridViewWantsInputKey; return !dataGridViewWantsInputKey;
} }
/// <summary> /// <summary>
/// Returns the current value of the editing control. /// Returns the current value of the editing control.
/// </summary> /// </summary>
public virtual object GetEditingControlFormattedValue(DataGridViewDataErrorContexts context) public virtual object GetEditingControlFormattedValue(DataGridViewDataErrorContexts context)
{ {
@ -232,7 +179,7 @@ namespace GradeCalc
{ {
// Prevent the Value from being set to Maximum or Minimum when the cell is being painted. // Prevent the Value from being set to Maximum or Minimum when the cell is being painted.
UserEdit = (context & DataGridViewDataErrorContexts.Display) == 0; UserEdit = (context & DataGridViewDataErrorContexts.Display) == 0;
return Value.ToString((ThousandsSeparator ? "N" : "F") + DecimalPlaces.ToString()); return Value.ToString((ThousandsSeparator ? "N" : "F") + DecimalPlaces);
} }
finally finally
{ {
@ -241,8 +188,8 @@ namespace GradeCalc
} }
/// <summary> /// <summary>
/// Called by the grid to give the editing control a chance to prepare itself for /// Called by the grid to give the editing control a chance to prepare itself for
/// the editing session. /// the editing session.
/// </summary> /// </summary>
public virtual void PrepareEditingControlForEdit(bool selectAll) public virtual void PrepareEditingControlForEdit(bool selectAll)
{ {
@ -250,23 +197,23 @@ namespace GradeCalc
if (textBox != null) if (textBox != null)
{ {
if (selectAll) if (selectAll)
{
textBox.SelectAll(); textBox.SelectAll();
}
else else
{
// Do not select all the text, but // Do not select all the text, but
// position the caret at the end of the text // position the caret at the end of the text
textBox.SelectionStart = textBox.Text.Length; textBox.SelectionStart = textBox.Text.Length;
}
} }
} }
// Needed to forward keyboard messages to the child TextBox control.
[DllImport("USER32.DLL", CharSet = CharSet.Auto)]
private static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam);
// End of the IDataGridViewEditingControl interface implementation // End of the IDataGridViewEditingControl interface implementation
/// <summary> /// <summary>
/// Small utility function that updates the local dirty state and /// Small utility function that updates the local dirty state and
/// notifies the grid of the value change. /// notifies the grid of the value change.
/// </summary> /// </summary>
private void NotifyDataGridViewOfValueChange() private void NotifyDataGridViewOfValueChange()
{ {
@ -278,8 +225,8 @@ namespace GradeCalc
} }
/// <summary> /// <summary>
/// Listen to the KeyPress notification to know when the value changed, and /// Listen to the KeyPress notification to know when the value changed, and
/// notify the grid of the change. /// notify the grid of the change.
/// </summary> /// </summary>
protected override void OnKeyPress(KeyPressEventArgs e) protected override void OnKeyPress(KeyPressEventArgs e)
{ {
@ -294,47 +241,37 @@ namespace GradeCalc
} }
else else
{ {
System.Globalization.NumberFormatInfo numberFormatInfo = System.Globalization.CultureInfo.CurrentCulture.NumberFormat; NumberFormatInfo numberFormatInfo = CultureInfo.CurrentCulture.NumberFormat;
string decimalSeparatorStr = numberFormatInfo.NumberDecimalSeparator; string decimalSeparatorStr = numberFormatInfo.NumberDecimalSeparator;
string groupSeparatorStr = numberFormatInfo.NumberGroupSeparator; string groupSeparatorStr = numberFormatInfo.NumberGroupSeparator;
string negativeSignStr = numberFormatInfo.NegativeSign; string negativeSignStr = numberFormatInfo.NegativeSign;
if (!string.IsNullOrEmpty(decimalSeparatorStr) && decimalSeparatorStr.Length == 1) if (!string.IsNullOrEmpty(decimalSeparatorStr) && decimalSeparatorStr.Length == 1)
{
notifyValueChange = decimalSeparatorStr[0] == e.KeyChar; notifyValueChange = decimalSeparatorStr[0] == e.KeyChar;
}
if (!notifyValueChange && !string.IsNullOrEmpty(groupSeparatorStr) && groupSeparatorStr.Length == 1) if (!notifyValueChange && !string.IsNullOrEmpty(groupSeparatorStr) && groupSeparatorStr.Length == 1)
{
notifyValueChange = groupSeparatorStr[0] == e.KeyChar; notifyValueChange = groupSeparatorStr[0] == e.KeyChar;
}
if (!notifyValueChange && !string.IsNullOrEmpty(negativeSignStr) && negativeSignStr.Length == 1) if (!notifyValueChange && !string.IsNullOrEmpty(negativeSignStr) && negativeSignStr.Length == 1)
{
notifyValueChange = negativeSignStr[0] == e.KeyChar; notifyValueChange = negativeSignStr[0] == e.KeyChar;
}
} }
if (notifyValueChange) if (notifyValueChange)
{
// Let the DataGridView know about the value change // Let the DataGridView know about the value change
NotifyDataGridViewOfValueChange(); NotifyDataGridViewOfValueChange();
}
} }
/// <summary> /// <summary>
/// Listen to the ValueChanged notification to forward the change to the grid. /// Listen to the ValueChanged notification to forward the change to the grid.
/// </summary> /// </summary>
protected override void OnValueChanged(EventArgs e) protected override void OnValueChanged(EventArgs e)
{ {
base.OnValueChanged(e); base.OnValueChanged(e);
if (Focused) if (Focused)
{
// Let the DataGridView know about the value change // Let the DataGridView know about the value change
NotifyDataGridViewOfValueChange(); NotifyDataGridViewOfValueChange();
}
} }
/// <summary> /// <summary>
/// A few keyboard messages need to be forwarded to the inner textbox of the /// A few keyboard messages need to be forwarded to the inner textbox of the
/// NumericUpDown control so that the first character pressed appears in it. /// NumericUpDown control so that the first character pressed appears in it.
/// </summary> /// </summary>
protected override bool ProcessKeyEventArgs(ref Message m) protected override bool ProcessKeyEventArgs(ref Message m)
{ {
@ -344,10 +281,8 @@ namespace GradeCalc
SendMessage(textBox.Handle, m.Msg, m.WParam, m.LParam); SendMessage(textBox.Handle, m.Msg, m.WParam, m.LParam);
return true; return true;
} }
else
{ return base.ProcessKeyEventArgs(ref m);
return base.ProcessKeyEventArgs(ref m);
}
} }
} }
} }

View File

@ -5,17 +5,22 @@ using System.Windows.Forms;
namespace CC_Functions.Misc namespace CC_Functions.Misc
{ {
public delegate void SetPropertyDelegate<TCtl, TProp>(TCtl control, Expression<Func<TCtl, TProp>> propexpr, TProp value) where TCtl : Control; public delegate void SetPropertyDelegate<TCtl, TProp>(TCtl control, Expression<Func<TCtl, TProp>> propexpr,
TProp value) where TCtl : Control;
public delegate TProp GetPropertyDelegate<TCtl, TProp>(TCtl control, Expression<Func<TProp>> propexpr) where TCtl : Control; public delegate TProp GetPropertyDelegate<TCtl, TProp>(TCtl control, Expression<Func<TProp>> propexpr)
where TCtl : Control;
public delegate void InvokeActionDelegate<TCtl>(TCtl control, Delegate dlg, params object[] args) where TCtl : Control; public delegate void InvokeActionDelegate<TCtl>(TCtl control, Delegate dlg, params object[] args)
where TCtl : Control;
public delegate TResult InvokeFuncDelegate<TCtl, TResult>(TCtl control, Delegate dlg, params object[] args) where TCtl : Control; public delegate TResult InvokeFuncDelegate<TCtl, TResult>(TCtl control, Delegate dlg, params object[] args)
where TCtl : Control;
public static class Forms public static class Forms
{ {
public static void SetProperty<TCtl, TProp>(this TCtl control, Expression<Func<TCtl, TProp>> propexpr, TProp value) where TCtl : Control public static void SetProperty<TCtl, TProp>(this TCtl control, Expression<Func<TCtl, TProp>> propexpr,
TProp value) where TCtl : Control
{ {
if (control == null) if (control == null)
throw new ArgumentNullException(nameof(control)); throw new ArgumentNullException(nameof(control));
@ -27,33 +32,36 @@ namespace CC_Functions.Misc
control.Invoke(new SetPropertyDelegate<TCtl, TProp>(SetProperty), control, propexpr, value); control.Invoke(new SetPropertyDelegate<TCtl, TProp>(SetProperty), control, propexpr, value);
return; return;
} }
var propexprm = propexpr.Body as MemberExpression;
MemberExpression propexprm = propexpr.Body as MemberExpression;
if (propexprm == null) if (propexprm == null)
throw new ArgumentException("Invalid member expression.", nameof(propexpr)); throw new ArgumentException("Invalid member expression.", nameof(propexpr));
var prop = propexprm.Member as PropertyInfo; PropertyInfo prop = propexprm.Member as PropertyInfo;
if (prop == null) if (prop == null)
throw new ArgumentException("Invalid property supplied.", nameof(propexpr)); throw new ArgumentException("Invalid property supplied.", nameof(propexpr));
prop.SetValue(control, value); prop.SetValue(control, value);
} }
public static TProp GetProperty<TCtl, TProp>(this TCtl control, Expression<Func<TProp>> propexpr) where TCtl : Control public static TProp GetProperty<TCtl, TProp>(this TCtl control, Expression<Func<TProp>> propexpr)
where TCtl : Control
{ {
if (control == null) if (control == null)
throw new ArgumentNullException(nameof(control)); throw new ArgumentNullException(nameof(control));
if (propexpr == null) if (propexpr == null)
throw new ArgumentNullException(nameof(propexpr)); throw new ArgumentNullException(nameof(propexpr));
if (control.InvokeRequired) if (control.InvokeRequired)
return (TProp)control.Invoke(new GetPropertyDelegate<TCtl, TProp>(GetProperty), control, propexpr); return (TProp) control.Invoke(new GetPropertyDelegate<TCtl, TProp>(GetProperty), control, propexpr);
var propexprm = propexpr.Body as MemberExpression; MemberExpression propexprm = propexpr.Body as MemberExpression;
if (propexprm == null) if (propexprm == null)
throw new ArgumentException("Invalid member expression.", nameof(propexpr)); throw new ArgumentException("Invalid member expression.", nameof(propexpr));
var prop = propexprm.Member as PropertyInfo; PropertyInfo prop = propexprm.Member as PropertyInfo;
if (prop == null) if (prop == null)
throw new ArgumentException("Invalid property supplied.", nameof(propexpr)); throw new ArgumentException("Invalid property supplied.", nameof(propexpr));
return (TProp)prop.GetValue(control); return (TProp) prop.GetValue(control);
} }
public static void InvokeAction<TCtl>(this TCtl control, Delegate dlg, params object[] args) where TCtl : Control public static void InvokeAction<TCtl>(this TCtl control, Delegate dlg, params object[] args)
where TCtl : Control
{ {
if (control == null) if (control == null)
throw new ArgumentNullException(nameof(control)); throw new ArgumentNullException(nameof(control));
@ -64,16 +72,21 @@ namespace CC_Functions.Misc
control.Invoke(new InvokeActionDelegate<TCtl>(InvokeAction), control, dlg, args); control.Invoke(new InvokeActionDelegate<TCtl>(InvokeAction), control, dlg, args);
return; return;
} }
dlg.DynamicInvoke(args); dlg.DynamicInvoke(args);
} }
public static TResult InvokeFunc<TCtl, TResult>(this TCtl control, Delegate dlg, params object[] args) where TCtl : Control public static TResult InvokeFunc<TCtl, TResult>(this TCtl control, Delegate dlg, params object[] args)
where TCtl : Control
{ {
if (control == null) if (control == null)
throw new ArgumentNullException(nameof(control)); throw new ArgumentNullException(nameof(control));
if (dlg == null) if (dlg == null)
throw new ArgumentNullException(nameof(dlg)); throw new ArgumentNullException(nameof(dlg));
return control.InvokeRequired ? (TResult)control.Invoke(new InvokeFuncDelegate<TCtl, TResult>(InvokeFunc<TCtl, TResult>), control, dlg, args) : (TResult)dlg.DynamicInvoke(args); return control.InvokeRequired
? (TResult) control.Invoke(new InvokeFuncDelegate<TCtl, TResult>(InvokeFunc<TCtl, TResult>), control,
dlg, args)
: (TResult) dlg.DynamicInvoke(args);
} }
} }
} }

View File

@ -23,12 +23,12 @@ namespace CC_Functions.Misc
{ {
try try
{ {
parsed = (T)o; parsed = (T) o;
return true; return true;
} }
catch catch
{ {
parsed = default(T); parsed = default;
return false; return false;
} }
} }
@ -41,15 +41,21 @@ namespace CC_Functions.Misc
func(); func();
} }
public static T ParseToEnum<T>(string value) => (T)Enum.Parse(typeof(T), Enum.GetNames(typeof(T)).First(s => s.ToLower() == value.ToLower())); public static T ParseToEnum<T>(string value)
{
return (T) Enum.Parse(typeof(T), Enum.GetNames(typeof(T)).First(s => s.ToLower() == value.ToLower()));
}
public static bool? ParseBool(string value) => (string.IsNullOrWhiteSpace(value) || value.ToLower() == "Indeterminate") ? (bool?)null : bool.Parse(value); public static bool? ParseBool(string value) =>
string.IsNullOrWhiteSpace(value) || value.ToLower() == "Indeterminate"
? (bool?) null
: bool.Parse(value);
public static bool AND(this bool? left, bool? right) => left.TRUE() && right.TRUE(); public static bool AND(this bool? left, bool? right) => left.TRUE() && right.TRUE();
public static bool OR(this bool? left, bool? right) => left.TRUE() || right.TRUE(); public static bool OR(this bool? left, bool? right) => left.TRUE() || right.TRUE();
public static bool XOR(this bool? left, bool? right) => left.OR(right) && (!left.AND(right)); public static bool XOR(this bool? left, bool? right) => left.OR(right) && !left.AND(right);
public static bool TRUE(this bool? self) => self == true; public static bool TRUE(this bool? self) => self == true;

View File

@ -5,7 +5,7 @@ using System.Management;
using System.Security.Cryptography; using System.Security.Cryptography;
using System.Text; using System.Text;
namespace Misc namespace CC_Functions.Misc
{ {
public static class HID public static class HID
{ {
@ -33,7 +33,7 @@ Win32_NetworkAdapterConfiguration:MACAddress:IPEnabled";
{ {
if (_fingerPrint == null) if (_fingerPrint == null)
{ {
var fingerprint_tmp = ""; string fingerprintTmp = "";
if (Type.GetType("Mono.Runtime") == null) if (Type.GetType("Mono.Runtime") == null)
{ {
HIDClasses.Split('\r').Select(s => HIDClasses.Split('\r').Select(s =>
@ -43,20 +43,21 @@ Win32_NetworkAdapterConfiguration:MACAddress:IPEnabled";
return s.Split(':'); return s.Split(':');
}).ToList().ForEach(s => }).ToList().ForEach(s =>
{ {
using (var mc = new ManagementClass(s[0])) using (ManagementClass mc = new ManagementClass(s[0]))
using (var moc = mc.GetInstances()) using (ManagementObjectCollection moc = mc.GetInstances())
{ {
var array = moc.OfType<ManagementBaseObject>().ToArray(); ManagementBaseObject[] array = moc.OfType<ManagementBaseObject>().ToArray();
for (var j = 0; j < array.Length; j++) for (int j = 0; j < array.Length; j++)
{ {
if (s.Length > 2 && array[j][s[2]].ToString() != "True") continue; if (s.Length > 2 && array[j][s[2]].ToString() != "True") continue;
try try
{ {
fingerprint_tmp += array[j][s[1]].ToString(); fingerprintTmp += array[j][s[1]].ToString();
break; break;
} }
catch catch
{ {
Console.WriteLine("Failed to read property");
} }
} }
} }
@ -64,7 +65,7 @@ Win32_NetworkAdapterConfiguration:MACAddress:IPEnabled";
} }
else //Linux implementation. This will not work if you are using Mono on windows or do not have uname and lscpu available else //Linux implementation. This will not work if you are using Mono on windows or do not have uname and lscpu available
{ {
var p = new Process Process p = new Process
{ {
StartInfo = StartInfo =
{ {
@ -75,18 +76,18 @@ Win32_NetworkAdapterConfiguration:MACAddress:IPEnabled";
} }
}; };
p.Start(); p.Start();
fingerprint_tmp = p.StandardOutput.ReadToEnd(); fingerprintTmp = p.StandardOutput.ReadToEnd();
p.WaitForExit(); p.WaitForExit();
p.StartInfo.FileName = "lscpu"; p.StartInfo.FileName = "lscpu";
p.StartInfo.Arguments = ""; p.StartInfo.Arguments = "-ap";
p.Start(); p.Start();
fingerprint_tmp += p.StandardOutput.ReadToEnd(); fingerprintTmp += p.StandardOutput.ReadToEnd();
p.WaitForExit(); p.WaitForExit();
} }
using (MD5 sec = new MD5CryptoServiceProvider()) using (MD5 sec = new MD5CryptoServiceProvider())
{ {
var bt = Encoding.ASCII.GetBytes(fingerprint_tmp); byte[] bt = Encoding.ASCII.GetBytes(fingerprintTmp);
_fingerPrint = sec.ComputeHash(bt); _fingerPrint = sec.ComputeHash(bt);
} }
} }
@ -95,14 +96,10 @@ Win32_NetworkAdapterConfiguration:MACAddress:IPEnabled";
} }
} }
public static byte[] EncryptLocal(byte[] unencrypted) public static byte[] EncryptLocal(byte[] unencrypted) =>
{ ProtectedData.Protect(unencrypted, Value, DataProtectionScope.CurrentUser);
return ProtectedData.Protect(unencrypted, Value, DataProtectionScope.CurrentUser);
}
public static byte[] DecryptLocal(byte[] encrypted) public static byte[] DecryptLocal(byte[] encrypted) =>
{ ProtectedData.Unprotect(encrypted, Value, DataProtectionScope.CurrentUser);
return ProtectedData.Unprotect(encrypted, Value, DataProtectionScope.CurrentUser);
}
} }
} }

View File

@ -6,17 +6,10 @@ namespace CC_Functions.Misc
{ {
public static long GetDirectorySize(string path) public static long GetDirectorySize(string path)
{ {
try string[] a = Directory.GetFiles(path, "*.*", SearchOption.AllDirectories);
{ long size = 0;
string[] a = Directory.GetFiles(path, "*.*", SearchOption.AllDirectories); for (int i = 0; i < a.Length; i++) size += new FileInfo(a[i]).Length;
long size = 0; return size;
for (int i = 0; i < a.Length; i++)
{
size += new FileInfo(a[i]).Length;
}
return size;
}
catch { throw; }
} }
} }
} }

View File

@ -1,9 +1,10 @@
using System.Security.Principal; using System.Security.Principal;
namespace Misc namespace CC_Functions.Misc
{ {
public static class MiscFunctions public static class MiscFunctions
{ {
public static bool IsAdministrator => new WindowsPrincipal(WindowsIdentity.GetCurrent()).IsInRole(WindowsBuiltInRole.Administrator); public static bool IsAdministrator =>
new WindowsPrincipal(WindowsIdentity.GetCurrent()).IsInRole(WindowsBuiltInRole.Administrator);
} }
} }

View File

@ -1,27 +1,23 @@
using System; using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq; using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms; using System.Windows.Forms;
namespace CC_Functions.Misc namespace CC_Functions.Misc
{ {
partial class SelectBox<T> : Form internal partial class SelectBox<T> : Form
{ {
public T result; public T result;
public SelectBox(T[] Options, string title = "") public SelectBox(T[] Options, string title = "")
{ {
InitializeComponent(); InitializeComponent();
Text = title; Text = title;
listBox1.Items.AddRange(Options.Select(s => (object)s).ToArray()); listBox1.Items.AddRange(Options.Select(s => (object) s).ToArray());
} }
private void listBox1_SelectedIndexChanged(object sender, EventArgs e) private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{ {
result = (T)listBox1.SelectedItem; result = (T) listBox1.SelectedItem;
DialogResult = DialogResult.OK; DialogResult = DialogResult.OK;
Close(); Close();
} }
@ -32,7 +28,7 @@ namespace CC_Functions.Misc
public static T Show<T>(T[] Options, string title = "") public static T Show<T>(T[] Options, string title = "")
{ {
SelectBox<T> sb = new SelectBox<T>(Options, title); SelectBox<T> sb = new SelectBox<T>(Options, title);
return sb.ShowDialog() == DialogResult.OK ? sb.result : default(T); return sb.ShowDialog() == DialogResult.OK ? sb.result : default;
} }
} }
} }

View File

@ -1,21 +1,23 @@
using System; using System;
using System.Collections.Generic;
using System.Drawing; using System.Drawing;
using System.Linq; using System.Linq;
using System.Windows.Forms; using System.Windows.Forms;
using CC_Functions.Misc; using CC_Functions.Misc;
using CC_Functions.W32.Hooks;
using static CC_Functions.W32.Power; using static CC_Functions.W32.Power;
namespace CC_Functions.W32.Test namespace CC_Functions.W32.Test
{ {
public partial class Form1 : Form public partial class Form1 : Form
{ {
public static Wnd32 tmpWnd; private static Wnd32 tmpWnd;
public static Form1 mainF; private static Form1 mainF;
public static Form frm; private static Form frm;
public static Label lab; private static Label lab;
private readonly KeyboardHook kHook; private readonly KeyboardHook kHook;
private Point locDelB;
private readonly MouseHook mHook; private readonly MouseHook mHook;
private Point locDelB;
private bool moving; private bool moving;
private DateTime mST; private DateTime mST;
@ -44,20 +46,17 @@ namespace CC_Functions.W32.Test
public void set_up_box(ComboBox box, Type enumT) public void set_up_box(ComboBox box, Type enumT)
{ {
box.DataSource = Enum.GetNames(enumT); box.DataSource = Enum.GetNames(enumT);
var tmp = Enum.GetValues(enumT); Array tmp = Enum.GetValues(enumT);
box.Tag = new object[tmp.Length]; box.Tag = new object[tmp.Length];
var i = 0; int i = 0;
foreach (var o in tmp) foreach (object o in tmp)
{ {
((object[]) box.Tag)[i] = o; ((object[]) box.Tag)[i] = o;
i++; i++;
} }
} }
public object get_box_value(ComboBox box) public object get_box_value(ComboBox box) => ((object[]) box.Tag)[box.SelectedIndex];
{
return ((object[]) box.Tag)[box.SelectedIndex];
}
private void Power_execute_Click(object sender, EventArgs e) private void Power_execute_Click(object sender, EventArgs e)
{ {
@ -142,30 +141,15 @@ namespace CC_Functions.W32.Test
} }
} }
private void Wnd_action_enabled_CheckedChanged(object sender, EventArgs e) private void Wnd_action_enabled_CheckedChanged(object sender, EventArgs e) =>
{
tmpWnd.enabled = wnd_action_enabled.Checked; tmpWnd.enabled = wnd_action_enabled.Checked;
}
private void Wnd_action_visible_CheckedChanged(object sender, EventArgs e) private void Wnd_action_visible_CheckedChanged(object sender, EventArgs e) =>
{
tmpWnd.shown = wnd_action_visible.Checked; tmpWnd.shown = wnd_action_visible.Checked;
}
private void Wnd_action_front_Click(object sender, EventArgs e) private void Wnd_action_front_Click(object sender, EventArgs e) => tmpWnd.isForeground = true;
{
tmpWnd.isForeground = true;
}
private void Wnd_action_overlay_Click(object sender, EventArgs e) private void Wnd_action_destroy_Click(object sender, EventArgs e) => tmpWnd.Destroy();
{
tmpWnd.MakeOverlay();
}
private void Wnd_action_destroy_Click(object sender, EventArgs e)
{
tmpWnd.Destroy();
}
private void Wnd_select_mouse_Click(object sender, EventArgs e) private void Wnd_select_mouse_Click(object sender, EventArgs e)
{ {
@ -189,7 +173,7 @@ namespace CC_Functions.W32.Test
{ {
frm.Hide(); frm.Hide();
frm.WindowState = FormWindowState.Minimized; frm.WindowState = FormWindowState.Minimized;
var tmp = Wnd32.fromPoint(MousePosition); Wnd32 tmp = Wnd32.fromPoint(MousePosition);
tmpWnd.enabled = true; tmpWnd.enabled = true;
tmpWnd.isForeground = true; tmpWnd.isForeground = true;
tmpWnd = tmp; tmpWnd = tmp;
@ -211,16 +195,14 @@ namespace CC_Functions.W32.Test
mHook.OnMouse -= MHook_OnMouse; mHook.OnMouse -= MHook_OnMouse;
} }
private void MHook_OnMouse(MouseHookEventArgs _args) private void MHook_OnMouse(MouseHookEventArgs args) =>
{ mouse_log.Text = args.Message + " -|- " + args.Point + "\r\n" + mouse_log.Text;
mouse_log.Text = _args.Message + " -|- " + _args.Point + "\r\n" + mouse_log.Text;
}
private void Mouse_log_TextChanged(object sender, EventArgs e) private void Mouse_log_TextChanged(object sender, EventArgs e)
{ {
if (mouse_log.Lines.Length > 10) if (mouse_log.Lines.Length > 10)
{ {
var tmp = mouse_log.Lines.ToList(); List<string> tmp = mouse_log.Lines.ToList();
tmp.RemoveRange(9, mouse_log.Lines.Length - 9); tmp.RemoveRange(9, mouse_log.Lines.Length - 9);
mouse_log.Lines = tmp.ToArray(); mouse_log.Lines = tmp.ToArray();
tmp = null; tmp = null;
@ -235,27 +217,23 @@ namespace CC_Functions.W32.Test
kHook.OnKeyPress -= KHook_OnKeyPress; kHook.OnKeyPress -= KHook_OnKeyPress;
} }
private void KHook_OnKeyPress(KeyboardHookEventArgs _args) private void KHook_OnKeyPress(KeyboardHookEventArgs args) =>
{ keyboard_log.Text = args.Key + "\r\n" + keyboard_log.Text;
keyboard_log.Text = _args.Key + "\r\n" + keyboard_log.Text;
}
private void Keyboard_log_TextChanged(object sender, EventArgs e) private void Keyboard_log_TextChanged(object sender, EventArgs e)
{ {
if (keyboard_log.Lines.Length > 10) if (keyboard_log.Lines.Length > 10)
{ {
var tmp = keyboard_log.Lines.ToList(); List<string> tmp = keyboard_log.Lines.ToList();
tmp.RemoveRange(9, keyboard_log.Lines.Length - 9); tmp.RemoveRange(9, keyboard_log.Lines.Length - 9);
keyboard_log.Lines = tmp.ToArray(); keyboard_log.Lines = tmp.ToArray();
tmp = null; tmp = null;
} }
} }
private void Wnd_action_pos_Click(object sender, EventArgs e) private void Wnd_action_pos_Click(object sender, EventArgs e) =>
{
tmpWnd.position = new Rectangle(wnd_action_pos_x_bar.Value, wnd_action_pos_y_bar.Value, tmpWnd.position = new Rectangle(wnd_action_pos_x_bar.Value, wnd_action_pos_y_bar.Value,
wnd_action_pos_w_bar.Value, wnd_action_pos_h_bar.Value); wnd_action_pos_w_bar.Value, wnd_action_pos_h_bar.Value);
}
private void Exit_Click(object sender, EventArgs e) private void Exit_Click(object sender, EventArgs e)
{ {
@ -276,10 +254,7 @@ namespace CC_Functions.W32.Test
moving = true; moving = true;
} }
private void Exit_MouseUp(object sender, MouseEventArgs e) private void Exit_MouseUp(object sender, MouseEventArgs e) => moving = false;
{
moving = false;
}
private void Wnd_action_style_SelectedIndexChanged(object sender, EventArgs e) private void Wnd_action_style_SelectedIndexChanged(object sender, EventArgs e)
{ {
@ -287,9 +262,7 @@ namespace CC_Functions.W32.Test
tmpWnd.state = status; tmpWnd.state = status;
} }
private void wnd_action_overlay_CheckedChanged(object sender, EventArgs e) private void wnd_action_overlay_CheckedChanged(object sender, EventArgs e) =>
{
tmpWnd.overlay = wnd_action_overlay.Checked; tmpWnd.overlay = wnd_action_overlay.Checked;
}
} }
} }

View File

@ -4,39 +4,39 @@ using System.Diagnostics;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Windows.Forms; using System.Windows.Forms;
namespace CC_Functions.W32 namespace CC_Functions.W32.Hooks
{ {
public sealed class KeyboardHook : IDisposable public sealed class KeyboardHook : IDisposable
{ {
public delegate void keyPress(KeyboardHookEventArgs _args); public delegate void KeyPress(KeyboardHookEventArgs args);
private const int WH_KEYBOARD_LL = 13; private const int WH_KEYBOARD_LL = 13;
private const int WM_KEYDOWN = 0x0100; private const int WM_KEYDOWN = 0x0100;
private static readonly List<KeyboardHook> instances = new List<KeyboardHook>(); private static readonly List<KeyboardHook> Instances = new List<KeyboardHook>();
private static readonly LowLevelKeyboardProc _proc = HookCallback; private static readonly LowLevelKeyboardProc Proc = HookCallback;
private static IntPtr _hookID = IntPtr.Zero; private static IntPtr _hookID = IntPtr.Zero;
public KeyboardHook() public KeyboardHook()
{ {
if (instances.Count == 0) if (Instances.Count == 0)
_hookID = SetHook(_proc); _hookID = SetHook(Proc);
instances.Add(this); Instances.Add(this);
} }
public void Dispose() public void Dispose()
{ {
instances.Remove(this); Instances.Remove(this);
if (instances.Count == 0) if (Instances.Count == 0)
UnhookWindowsHookEx(_hookID); UnhookWindowsHookEx(_hookID);
} }
public event keyPress OnKeyPress; public event KeyPress OnKeyPress;
private IntPtr SetHook(LowLevelKeyboardProc proc) private IntPtr SetHook(LowLevelKeyboardProc proc)
{ {
using (var curProcess = Process.GetCurrentProcess()) using (Process curProcess = Process.GetCurrentProcess())
using (var curModule = curProcess.MainModule) using (ProcessModule curModule = curProcess.MainModule)
{ {
return SetWindowsHookEx(WH_KEYBOARD_LL, proc, GetModuleHandle(curModule.ModuleName), 0); return SetWindowsHookEx(WH_KEYBOARD_LL, proc, GetModuleHandle(curModule.ModuleName), 0);
} }
@ -46,9 +46,9 @@ namespace CC_Functions.W32
{ {
if (nCode >= 0 && wParam == (IntPtr) WM_KEYDOWN) if (nCode >= 0 && wParam == (IntPtr) WM_KEYDOWN)
{ {
var vkCode = Marshal.ReadInt32(lParam); int vkCode = Marshal.ReadInt32(lParam);
for (var i = 0; i < instances.Count; i++) for (int i = 0; i < Instances.Count; i++)
instances[i].OnKeyPress?.Invoke(new KeyboardHookEventArgs((Keys) vkCode)); Instances[i].OnKeyPress?.Invoke(new KeyboardHookEventArgs((Keys) vkCode));
} }
return CallNextHookEx(_hookID, nCode, wParam, lParam); return CallNextHookEx(_hookID, nCode, wParam, lParam);

View File

@ -1,20 +1,14 @@
using System; using System;
using System.Windows.Forms; using System.Windows.Forms;
namespace CC_Functions.W32 namespace CC_Functions.W32.Hooks
{ {
public sealed class KeyboardHookEventArgs : EventArgs public sealed class KeyboardHookEventArgs : EventArgs
{ {
public KeyboardHookEventArgs(Keys key) public KeyboardHookEventArgs(Keys key) => Key = key;
{
Key = key;
}
public Keys Key { get; } public Keys Key { get; }
public override string ToString() public override string ToString() => Key.ToString();
{
return Key.ToString();
}
} }
} }

View File

@ -4,11 +4,11 @@ using System.Diagnostics;
using System.Drawing; using System.Drawing;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
namespace CC_Functions.W32 namespace CC_Functions.W32.Hooks
{ {
public sealed class MouseHook : IDisposable public sealed class MouseHook : IDisposable
{ {
public delegate void mouseEvent(MouseHookEventArgs _args); public delegate void MouseEvent(MouseHookEventArgs args);
public enum MouseMessages public enum MouseMessages
{ {
@ -22,30 +22,30 @@ namespace CC_Functions.W32
private const int WH_MOUSE_LL = 14; private const int WH_MOUSE_LL = 14;
private static readonly List<MouseHook> instances = new List<MouseHook>(); private static readonly List<MouseHook> Instances = new List<MouseHook>();
private static readonly LowLevelMouseProc _proc = HookCallback; private static readonly LowLevelMouseProc Proc = HookCallback;
private static IntPtr _hookID = IntPtr.Zero; private static IntPtr _hookID = IntPtr.Zero;
public MouseHook() public MouseHook()
{ {
if (instances.Count == 0) if (Instances.Count == 0)
_hookID = SetHook(_proc); _hookID = SetHook(Proc);
instances.Add(this); Instances.Add(this);
} }
public void Dispose() public void Dispose()
{ {
instances.Remove(this); Instances.Remove(this);
if (instances.Count == 0) if (Instances.Count == 0)
UnhookWindowsHookEx(_hookID); UnhookWindowsHookEx(_hookID);
} }
public event mouseEvent OnMouse; public event MouseEvent OnMouse;
private static IntPtr SetHook(LowLevelMouseProc proc) private static IntPtr SetHook(LowLevelMouseProc proc)
{ {
using (var curProcess = Process.GetCurrentProcess()) using (Process curProcess = Process.GetCurrentProcess())
using (var curModule = curProcess.MainModule) using (ProcessModule curModule = curProcess.MainModule)
{ {
return SetWindowsHookEx(WH_MOUSE_LL, proc, GetModuleHandle(curModule.ModuleName), 0); return SetWindowsHookEx(WH_MOUSE_LL, proc, GetModuleHandle(curModule.ModuleName), 0);
} }
@ -55,9 +55,9 @@ namespace CC_Functions.W32
{ {
if (nCode >= 0) if (nCode >= 0)
{ {
var hookStruct = (MSLLHOOKSTRUCT) Marshal.PtrToStructure(lParam, typeof(MSLLHOOKSTRUCT)); MSLLHOOKSTRUCT hookStruct = (MSLLHOOKSTRUCT) Marshal.PtrToStructure(lParam, typeof(MSLLHOOKSTRUCT));
for (var i = 0; i < instances.Count; i++) for (int i = 0; i < Instances.Count; i++)
instances[i].OnMouse?.Invoke(new MouseHookEventArgs(new Point(hookStruct.pt.x, hookStruct.pt.y), Instances[i].OnMouse?.Invoke(new MouseHookEventArgs(new Point(hookStruct.pt.x, hookStruct.pt.y),
(MouseMessages) wParam)); (MouseMessages) wParam));
} }

View File

@ -1,7 +1,7 @@
using System; using System;
using System.Drawing; using System.Drawing;
namespace CC_Functions.W32 namespace CC_Functions.W32.Hooks
{ {
public class MouseHookEventArgs : EventArgs public class MouseHookEventArgs : EventArgs
{ {
@ -14,9 +14,6 @@ namespace CC_Functions.W32
public Point Point { get; } public Point Point { get; }
public MouseHook.MouseMessages Message { get; } public MouseHook.MouseMessages Message { get; }
public override string ToString() public override string ToString() => Message + "; " + Point;
{
return Message + "; " + Point;
}
} }
} }

View File

@ -10,8 +10,8 @@ namespace CC_Functions.W32
public static bool IsKeyDown(Keys key) public static bool IsKeyDown(Keys key)
{ {
var state = 0; int state = 0;
var retVal = GetKeyState((int) key); short retVal = GetKeyState((int) key);
if ((retVal & 0x8000) == 0x8000) if ((retVal & 0x8000) == 0x8000)
state |= 1; state |= 1;
if ((retVal & 1) == 1) if ((retVal & 1) == 1)

View File

@ -108,10 +108,8 @@ namespace CC_Functions.W32
{ {
if (mode == ShutdownMode.BSoD) if (mode == ShutdownMode.BSoD)
{ {
bool t1; RtlAdjustPrivilege(19, true, false, out bool _);
uint t2; NtRaiseHardError(0xc0000022, 0, 0, IntPtr.Zero, 6, out uint _);
RtlAdjustPrivilege(19, true, false, out t1);
NtRaiseHardError(0xc0000022, 0, 0, IntPtr.Zero, 6, out t2);
} }
else else
{ {

View File

@ -91,22 +91,22 @@ namespace CC_Functions.W32
{ {
if (!Enum.IsDefined(typeof(SecurityEntity), securityEntity)) if (!Enum.IsDefined(typeof(SecurityEntity), securityEntity))
throw new InvalidEnumArgumentException("securityEntity", (int) securityEntity, typeof(SecurityEntity)); throw new InvalidEnumArgumentException("securityEntity", (int) securityEntity, typeof(SecurityEntity));
var securityEntityValue = securityEntity.ToString(); string securityEntityValue = securityEntity.ToString();
try try
{ {
var locallyUniqueIdentifier = new NativeMethods.LUID(); NativeMethods.LUID locallyUniqueIdentifier = new NativeMethods.LUID();
if (NativeMethods.LookupPrivilegeValue(null, securityEntityValue, ref locallyUniqueIdentifier)) if (NativeMethods.LookupPrivilegeValue(null, securityEntityValue, ref locallyUniqueIdentifier))
{ {
var TOKEN_PRIVILEGES = new NativeMethods.TOKEN_PRIVILEGES NativeMethods.TOKEN_PRIVILEGES TOKEN_PRIVILEGES = new NativeMethods.TOKEN_PRIVILEGES
{ {
PrivilegeCount = 1, PrivilegeCount = 1,
Attributes = NativeMethods.SE_PRIVILEGE_ENABLED, Attributes = NativeMethods.SE_PRIVILEGE_ENABLED,
Luid = locallyUniqueIdentifier Luid = locallyUniqueIdentifier
}; };
var tokenHandle = IntPtr.Zero; IntPtr tokenHandle = IntPtr.Zero;
try try
{ {
var currentProcess = NativeMethods.GetCurrentProcess(); IntPtr currentProcess = NativeMethods.GetCurrentProcess();
if (NativeMethods.OpenProcessToken(currentProcess, if (NativeMethods.OpenProcessToken(currentProcess,
NativeMethods.TOKEN_ADJUST_PRIVILEGES | NativeMethods.TOKEN_QUERY, out tokenHandle)) NativeMethods.TOKEN_ADJUST_PRIVILEGES | NativeMethods.TOKEN_QUERY, out tokenHandle))
{ {
@ -153,10 +153,7 @@ namespace CC_Functions.W32
} }
} }
public static SecurityEntity EntityToEntity(SecurityEntity2 entity) public static SecurityEntity EntityToEntity(SecurityEntity2 entity) => (SecurityEntity) entity;
{
return (SecurityEntity) entity;
}
internal static class NativeMethods internal static class NativeMethods
{ {

View File

@ -15,35 +15,18 @@ namespace CC_Functions.W32
#region CreateInstance #region CreateInstance
private Wnd32(IntPtr wndref) private Wnd32(IntPtr wndref) => hWnd = wndref;
{
hWnd = wndref;
}
public static Wnd32 fromHandle(IntPtr handle) public static Wnd32 fromHandle(IntPtr handle) => new Wnd32(handle);
{
return new Wnd32(handle);
}
public static Wnd32 fromMetadata(string lpClassName = null, string lpWindowName = null) public static Wnd32 fromMetadata(string lpClassName = null, string lpWindowName = null) =>
{ fromHandle(FindWindow(lpClassName, lpWindowName));
return fromHandle(FindWindow(lpClassName, lpWindowName));
}
public static Wnd32 fromPoint(Point point) public static Wnd32 fromPoint(Point point) => fromHandle(WindowFromPoint(point.X, point.Y));
{
return fromHandle(WindowFromPoint(point.X, point.Y));
}
public static Wnd32 fromForm(Form form) public static Wnd32 fromForm(Form form) => fromHandle(form.Handle);
{
return fromHandle(form.Handle);
}
public static Wnd32 foreground() public static Wnd32 foreground() => fromHandle(GetForegroundWindow());
{
return fromHandle(GetForegroundWindow());
}
public static Wnd32[] getVisible() public static Wnd32[] getVisible()
{ {
@ -61,8 +44,8 @@ namespace CC_Functions.W32
{ {
get get
{ {
var length = GetWindowTextLength(hWnd); int length = GetWindowTextLength(hWnd);
var sb = new StringBuilder(length + 1); StringBuilder sb = new StringBuilder(length + 1);
GetWindowText(hWnd, sb, sb.Capacity); GetWindowText(hWnd, sb, sb.Capacity);
return sb.ToString(); return sb.ToString();
} }
@ -73,14 +56,14 @@ namespace CC_Functions.W32
{ {
get get
{ {
var Rect = new RECT(); RECT Rect = new RECT();
GetWindowRect(hWnd, ref Rect); GetWindowRect(hWnd, ref Rect);
return new Rectangle(new Point(Rect.left, Rect.top), return new Rectangle(new Point(Rect.left, Rect.top),
new Size(Rect.right - Rect.left, Rect.bottom - Rect.top)); new Size(Rect.right - Rect.left, Rect.bottom - Rect.top));
} }
set set
{ {
var Rect = new RECT(); RECT Rect = new RECT();
GetWindowRect(hWnd, ref Rect); GetWindowRect(hWnd, ref Rect);
MoveWindow(hWnd, value.X, value.Y, value.Width, value.Height, true); MoveWindow(hWnd, value.X, value.Y, value.Width, value.Height, true);
} }
@ -109,7 +92,7 @@ namespace CC_Functions.W32
{ {
get get
{ {
var hicon = SendMessage(hWnd, 0x7F, 1, 0); IntPtr hicon = SendMessage(hWnd, 0x7F, 1, 0);
if (hicon == IntPtr.Zero) if (hicon == IntPtr.Zero)
hicon = SendMessage(hWnd, 0x7F, 0, 0); hicon = SendMessage(hWnd, 0x7F, 0, 0);
if (hicon == IntPtr.Zero) if (hicon == IntPtr.Zero)
@ -134,7 +117,7 @@ namespace CC_Functions.W32
{ {
get get
{ {
var ClassName = new StringBuilder(256); StringBuilder ClassName = new StringBuilder(256);
_ = GetClassName(hWnd, ClassName, ClassName.Capacity); _ = GetClassName(hWnd, ClassName, ClassName.Capacity);
return ClassName.ToString(); return ClassName.ToString();
} }
@ -144,7 +127,7 @@ namespace CC_Functions.W32
{ {
get get
{ {
var style = GetWindowLong(hWnd, -16); int style = GetWindowLong(hWnd, -16);
if ((style & 0x01000000) == 0x01000000) if ((style & 0x01000000) == 0x01000000)
return FormWindowState.Maximized; return FormWindowState.Maximized;
if ((style & 0x20000000) == 0x20000000) if ((style & 0x20000000) == 0x20000000)
@ -179,7 +162,7 @@ namespace CC_Functions.W32
{ {
set set
{ {
var tmp = position; Rectangle tmp = position;
_ = SetWindowPos(hWnd, value ? HWND_TOPMOST : HWND_NOTOPMOST, tmp.X, tmp.Y, tmp.Width, tmp.Height, _ = SetWindowPos(hWnd, value ? HWND_TOPMOST : HWND_NOTOPMOST, tmp.X, tmp.Y, tmp.Width, tmp.Height,
value ? SWP_NOMOVE | SWP_NOSIZE : 0); value ? SWP_NOMOVE | SWP_NOSIZE : 0);
} }
@ -194,35 +177,17 @@ namespace CC_Functions.W32
public bool stillExists => IsWindow(hWnd); public bool stillExists => IsWindow(hWnd);
public override string ToString() public override string ToString() => hWnd + "; " + title + "; " + position;
{
return hWnd + "; " + title + "; " + position;
}
public override bool Equals(object obj) public override bool Equals(object obj) => Equals(obj as Wnd32);
{
return Equals(obj as Wnd32);
}
public bool Equals(Wnd32 other) public bool Equals(Wnd32 other) => other != null && EqualityComparer<IntPtr>.Default.Equals(hWnd, other.hWnd);
{
return other != null && EqualityComparer<IntPtr>.Default.Equals(hWnd, other.hWnd);
}
public override int GetHashCode() public override int GetHashCode() => -75345830 + EqualityComparer<IntPtr>.Default.GetHashCode(hWnd);
{
return -75345830 + EqualityComparer<IntPtr>.Default.GetHashCode(hWnd);
}
public static bool operator ==(Wnd32 left, Wnd32 right) public static bool operator ==(Wnd32 left, Wnd32 right) => EqualityComparer<Wnd32>.Default.Equals(left, right);
{
return EqualityComparer<Wnd32>.Default.Equals(left, right);
}
public static bool operator !=(Wnd32 left, Wnd32 right) public static bool operator !=(Wnd32 left, Wnd32 right) => !(left == right);
{
return !(left == right);
}
#endregion InstanceActions #endregion InstanceActions
@ -322,7 +287,7 @@ namespace CC_Functions.W32
private static bool FilterCallback(IntPtr hWnd, int lParam) private static bool FilterCallback(IntPtr hWnd, int lParam)
{ {
var sb_title = new StringBuilder(1024); StringBuilder sb_title = new StringBuilder(1024);
GetWindowText(hWnd, sb_title, sb_title.Capacity); GetWindowText(hWnd, sb_title, sb_title.Capacity);
if (IsWindowVisible(hWnd) && string.IsNullOrEmpty(sb_title.ToString()) == false) WindowHandles.Add(hWnd); if (IsWindowVisible(hWnd) && string.IsNullOrEmpty(sb_title.ToString()) == false) WindowHandles.Add(hWnd);
return true; return true;