diff --git a/.github/workflows/dotnet-desktop-x86.yml b/.github/workflows/dotnet-desktop-x86.yml index 8caa33f..91aaed1 100644 --- a/.github/workflows/dotnet-desktop-x86.yml +++ b/.github/workflows/dotnet-desktop-x86.yml @@ -15,22 +15,22 @@ jobs: Solution_Name: Tinke.sln steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@main - name: Setup .NET - uses: actions/setup-dotnet@v3 + uses: actions/setup-dotnet@main with: dotnet-version: 6.0.x # Add MSBuild to the PATH: https://github.com/microsoft/setup-msbuild - name: Setup MSBuild.exe - uses: microsoft/setup-msbuild@v1.1.3 + uses: microsoft/setup-msbuild@main # Build - name: Build run: | ./compile.bat Release x86 - - uses: actions/upload-artifact@master + - uses: actions/upload-artifact@main with: name: TinkeDSi-nightly-x86 path: build diff --git a/.github/workflows/dotnet-desktop.yml b/.github/workflows/dotnet-desktop.yml index 3eecd00..b19de42 100644 --- a/.github/workflows/dotnet-desktop.yml +++ b/.github/workflows/dotnet-desktop.yml @@ -15,22 +15,22 @@ jobs: Solution_Name: Tinke.sln steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@main - name: Setup .NET - uses: actions/setup-dotnet@v3 + uses: actions/setup-dotnet@main with: dotnet-version: 6.0.x # Add MSBuild to the PATH: https://github.com/microsoft/setup-msbuild - name: Setup MSBuild.exe - uses: microsoft/setup-msbuild@v1.1.3 + uses: microsoft/setup-msbuild@main # Build - name: Build run: | ./compile.bat Release x64 - - uses: actions/upload-artifact@master + - uses: actions/upload-artifact@main with: name: TinkeDSi-nightly path: build diff --git a/.github/workflows/mono.yml b/.github/workflows/mono.yml index 7410211..9da8975 100644 --- a/.github/workflows/mono.yml +++ b/.github/workflows/mono.yml @@ -12,8 +12,8 @@ jobs: container: mono:latest steps: - - uses: actions/checkout@v3 - + - uses: actions/checkout@main + - name: Setup build toolchain run: | apt-get update @@ -31,7 +31,7 @@ jobs: mkbundle --deps Tinke.exe -o TinkeDSi --cross mono-6.8.0-ubuntu-16.04-x64 --i18n all -z --static shell: bash - - uses: actions/upload-artifact@master + - uses: actions/upload-artifact@main with: name: TinkeDSi-nightly-mono path: build diff --git a/Be.Windows.Forms.HexBox/AssemblyInfo.cs b/Be.Windows.Forms.HexBox/AssemblyInfo.cs index 36cbe40..f908081 100644 --- a/Be.Windows.Forms.HexBox/AssemblyInfo.cs +++ b/Be.Windows.Forms.HexBox/AssemblyInfo.cs @@ -29,7 +29,7 @@ using System.Runtime.InteropServices; // You can specify all the values or you can default the Revision and Build Numbers // by using the '*' as shown below: -[assembly: AssemblyVersion("1.4.7.*")] +[assembly: AssemblyVersion("1.6.0.*")] // // In order to sign your assembly you must specify a key to use. Refer to the diff --git a/Be.Windows.Forms.HexBox/Be.Windows.Forms.HexBox.csproj b/Be.Windows.Forms.HexBox/Be.Windows.Forms.HexBox.csproj index ba1c13d..d28a41e 100644 --- a/Be.Windows.Forms.HexBox/Be.Windows.Forms.HexBox.csproj +++ b/Be.Windows.Forms.HexBox/Be.Windows.Forms.HexBox.csproj @@ -116,6 +116,7 @@ Code + Component @@ -181,4 +182,4 @@ - + \ No newline at end of file diff --git a/Be.Windows.Forms.HexBox/BuiltInContextMenu.cs b/Be.Windows.Forms.HexBox/BuiltInContextMenu.cs index 55e2622..fc34a89 100644 --- a/Be.Windows.Forms.HexBox/BuiltInContextMenu.cs +++ b/Be.Windows.Forms.HexBox/BuiltInContextMenu.cs @@ -82,7 +82,7 @@ namespace Be.Windows.Forms _contextMenuStrip = cms; } - if (this._hexBox.ByteProvider == null && this._hexBox.ContextMenuStrip != null) + if (this._hexBox.ByteProvider == null && this._hexBox.ContextMenuStrip == this._contextMenuStrip) this._hexBox.ContextMenuStrip = null; else if (this._hexBox.ByteProvider != null && this._hexBox.ContextMenuStrip == null) this._hexBox.ContextMenuStrip = _contextMenuStrip; diff --git a/Be.Windows.Forms.HexBox/ByteCharConverters.cs b/Be.Windows.Forms.HexBox/ByteCharConverters.cs index 298c44a..6c488a9 100644 --- a/Be.Windows.Forms.HexBox/ByteCharConverters.cs +++ b/Be.Windows.Forms.HexBox/ByteCharConverters.cs @@ -55,7 +55,7 @@ namespace Be.Windows.Forms /// public override string ToString() { - return "Default"; + return "ANSI (Default)"; } } diff --git a/Be.Windows.Forms.HexBox/FindOptions.cs b/Be.Windows.Forms.HexBox/FindOptions.cs new file mode 100644 index 0000000..63ad090 --- /dev/null +++ b/Be.Windows.Forms.HexBox/FindOptions.cs @@ -0,0 +1,94 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Be.Windows.Forms +{ + /// + /// Defines the type of the Find operation. + /// + public enum FindType + { + /// + /// Used for Text Find operations + /// + Text, + /// + /// Used for Hex Find operations + /// + Hex + } + + /// + /// Defines all state information nee + /// + public class FindOptions + { + /// + /// Gets or sets whether the Find options are valid + /// + public bool IsValid { get; set; } + /// + /// Gets the Find buffer used for case insensitive Find operations. This is the binary representation of Text. + /// + internal byte[] FindBuffer { get; private set; } + /// + /// Gets the Find buffer used for case sensitive Find operations. This is the binary representation of Text in lower case format. + /// + internal byte[] FindBufferLowerCase { get; private set; } + /// + /// Gets the Find buffer used for case sensitive Find operations. This is the binary representation of Text in upper case format. + /// + internal byte[] FindBufferUpperCase { get; private set; } + /// + /// Contains the MatchCase value + /// + bool _matchCase; + /// + /// Gets or sets the value, whether the Find operation is case sensitive or not. + /// + public bool MatchCase + { + get { return _matchCase; } + set + { + _matchCase = value; + UpdateFindBuffer(); + } + } + /// + /// Contains the text that should be found. + /// + string _text; + /// + /// Gets or sets the text that should be found. Only used, when Type is FindType.Hex. + /// + public string Text + { + get { return _text; } + set + { + _text = value; + UpdateFindBuffer(); + } + } + /// + /// Gets or sets the hex buffer that should be found. Only used, when Type is FindType.Hex. + /// + public byte[] Hex { get; set; } + /// + /// Gets or sets the type what should be searched. + /// + public FindType Type { get; set; } + /// + /// Updates the find buffer. + /// + void UpdateFindBuffer() + { + string text = this.Text != null ? this.Text : string.Empty; + FindBuffer = ASCIIEncoding.ASCII.GetBytes(text); + FindBufferLowerCase = ASCIIEncoding.ASCII.GetBytes(text.ToLower()); + FindBufferUpperCase = ASCIIEncoding.ASCII.GetBytes(text.ToUpper()); + } +} +} diff --git a/Be.Windows.Forms.HexBox/HexBox.cs b/Be.Windows.Forms.HexBox/HexBox.cs index b947f55..7b6480c 100644 --- a/Be.Windows.Forms.HexBox/HexBox.cs +++ b/Be.Windows.Forms.HexBox/HexBox.cs @@ -1106,6 +1106,10 @@ namespace Be.Windows.Forms /// Rectangle _recLineInfo; /// + /// Contains the column info header rectangle bounds + /// + Rectangle _recColumnInfo; + /// /// Contains the hex data bounds /// Rectangle _recHex; @@ -1118,11 +1122,6 @@ namespace Be.Windows.Forms /// Contains string format information for text drawing /// StringFormat _stringFormat; - /// - /// Contains the width and height of a single char - /// - SizeF _charSize; - /// /// Contains the maximum of visible horizontal bytes /// @@ -1283,6 +1282,16 @@ namespace Be.Windows.Forms [Description("Occurs, when the value of LineInfoVisible property has changed.")] public event EventHandler LineInfoVisibleChanged; /// + /// Occurs, when the value of ColumnInfoVisibleChanged property has changed. + /// + [Description("Occurs, when the value of ColumnInfoVisibleChanged property has changed.")] + public event EventHandler ColumnInfoVisibleChanged; + /// + /// Occurs, when the value of GroupSeparatorVisibleChanged property has changed. + /// + [Description("Occurs, when the value of GroupSeparatorVisibleChanged property has changed.")] + public event EventHandler GroupSeparatorVisibleChanged; + /// /// Occurs, when the value of StringViewVisible property has changed. /// [Description("Occurs, when the value of StringViewVisible property has changed.")] @@ -1293,6 +1302,11 @@ namespace Be.Windows.Forms [Description("Occurs, when the value of BorderStyle property has changed.")] public event EventHandler BorderStyleChanged; /// + /// Occurs, when the value of ColumnWidth property has changed. + /// + [Description("Occurs, when the value of GroupSize property has changed.")] + public event EventHandler GroupSizeChanged; + /// /// Occurs, when the value of BytesPerLine property has changed. /// [Description("Occurs, when the value of BytesPerLine property has changed.")] @@ -1332,16 +1346,26 @@ namespace Be.Windows.Forms /// [Description("Occurs, when the value of CurrentPositionInLine property has changed.")] public event EventHandler CurrentPositionInLineChanged; + /// + /// Occurs, when Copy method was invoked and ClipBoardData changed. + /// + [Description("Occurs, when Copy method was invoked and ClipBoardData changed.")] + public event EventHandler Copied; + /// + /// Occurs, when CopyHex method was invoked and ClipBoardData changed. + /// + [Description("Occurs, when CopyHex method was invoked and ClipBoardData changed.")] + public event EventHandler CopiedHex; /// - /// Occurs, when Copy method was invoked and ClipBoardData changed. + /// Occurs, when the CharSize property has changed /// - [Description("Occurs, when Copy method was invoked and ClipBoardData changed.")] - public event EventHandler Copied; + [Description("Occurs, when the CharSize property has changed")] + public event EventHandler CharSizeChanged; /// - /// Occurs, when CopyHex method was invoked and ClipBoardData changed. + /// Occurs, when the RequiredWidth property changes /// - [Description("Occurs, when CopyHex method was invoked and ClipBoardData changed.")] - public event EventHandler CopiedHex; + [Description("Occurs, when the RequiredWidth property changes")] + public event EventHandler RequiredWidthChanged; #endregion #region Ctors @@ -1357,7 +1381,7 @@ namespace Be.Windows.Forms this._builtInContextMenu = new BuiltInContextMenu(this); BackColor = Color.White; - Font = new Font("Courier New", 9F, FontStyle.Regular, GraphicsUnit.Point, ((byte)(0))); + Font = SystemFonts.MessageBoxFont; _stringFormat = new StringFormat(StringFormat.GenericTypographic); _stringFormat.FormatFlags = StringFormatFlags.MeasureTrailingSpaces; @@ -1485,11 +1509,11 @@ namespace Be.Windows.Forms _vScrollBar.Minimum = 0; _vScrollBar.Maximum = max; _vScrollBar.Value = ToScrollPos(_scrollVpos); - _vScrollBar.Enabled = true; + _vScrollBar.Visible = true; } else { - _vScrollBar.Enabled = false; + _vScrollBar.Visible = false; } } @@ -1920,11 +1944,83 @@ namespace Be.Windows.Forms /// /// Searches the current ByteProvider /// - /// the array of bytes to find - /// the start index + /// contains all find options /// the SelectionStart property value if find was successfull or /// -1 if there is no match /// -2 if Find was aborted. + public long Find(FindOptions options) + { + var startIndex = this.SelectionStart + this.SelectionLength; + int match = 0; + + byte[] buffer1 = null; + byte[] buffer2 = null; + if (options.Type == FindType.Text && options.MatchCase) + { + if(options.FindBuffer == null || options.FindBuffer.Length == 0) + throw new ArgumentException("FindBuffer can not be null when Type: Text and MatchCase: false"); + buffer1 = options.FindBuffer; + } + else if (options.Type == FindType.Text && !options.MatchCase) + { + if(options.FindBufferLowerCase == null || options.FindBufferLowerCase.Length == 0) + throw new ArgumentException("FindBufferLowerCase can not be null when Type is Text and MatchCase is true"); + if(options.FindBufferUpperCase == null || options.FindBufferUpperCase.Length == 0) + throw new ArgumentException("FindBufferUpperCase can not be null when Type is Text and MatchCase is true"); + if(options.FindBufferLowerCase.Length != options.FindBufferUpperCase.Length) + throw new ArgumentException("FindBufferUpperCase and FindBufferUpperCase must have the same size when Type is Text and MatchCase is true"); + buffer1 = options.FindBufferLowerCase; + buffer2 = options.FindBufferUpperCase; + + } + else if (options.Type == FindType.Hex) + { + if(options.Hex == null || options.Hex.Length == 0) + throw new ArgumentException("Hex can not be null when Type is Hex"); + buffer1 = options.Hex; + } + + int buffer1Length = buffer1.Length; + + _abortFind = false; + + for (long pos = startIndex; pos < _byteProvider.Length; pos++) + { + if (_abortFind) + return -2; + + if (pos % 1000 == 0) // for performance reasons: DoEvents only 1 times per 1000 loops + Application.DoEvents(); + + byte compareByte = _byteProvider.ReadByte(pos); + bool buffer1Match = compareByte == buffer1[match]; + bool hasBuffer2 = buffer2 != null; + bool buffer2Match = hasBuffer2 ? compareByte == buffer2[match] : false; + bool isMatch = buffer1Match || buffer2Match; + if (!isMatch) + { + pos -= match; + match = 0; + _findingPos = pos; + continue; + } + + match++; + + if (match == buffer1Length) + { + long bytePos = pos - buffer1Length + 1; + Select(bytePos, buffer1Length); + ScrollByteIntoView(_bytePos + _selectionLength); + ScrollByteIntoView(_bytePos); + + return bytePos; + } + } + + return -1; + } + public long Find(byte[] bytes, long startIndex) { int match = 0; @@ -1963,6 +2059,7 @@ namespace Be.Windows.Forms return -1; } + public long Find_Prv(byte[] bytes, long endIndex) { int bytesLength = bytes.Length; @@ -2351,6 +2448,10 @@ namespace Be.Windows.Forms if(_shadowSelectionVisible) PaintCurrentBytesSign(e.Graphics); } + if (_columnInfoVisible) + PaintHeaderRow(e.Graphics); + if (_groupSeparatorVisible) + PaintColumnSeparator(e.Graphics); } @@ -2359,10 +2460,10 @@ namespace Be.Windows.Forms // Ensure endByte isn't > length of array. endByte = Math.Min(_byteProvider.Length-1, endByte); - Color lineInfoColor = (this.LineInfoForeColor != Color.Empty) ? this.LineInfoForeColor : this.ForeColor; - Brush brush = new SolidBrush(lineInfoColor); - - int maxLine = GetGridBytePoint(endByte-startByte).Y+1; + Color lineInfoColor = (this.InfoForeColor != Color.Empty) ? this.InfoForeColor : this.ForeColor; + Brush brush = new SolidBrush(lineInfoColor); + + int maxLine = GetGridBytePoint(endByte - startByte).Y + 1; for(int i = 0; i < maxLine; i++) { @@ -2385,6 +2486,32 @@ namespace Be.Windows.Forms } } + void PaintHeaderRow(Graphics g) + { + Brush brush = new SolidBrush(this.InfoForeColor); + for (int col = 0; col < _iHexMaxHBytes; col++) + { + PaintColumnInfo(g, (byte)col, brush, col); + } + } + + void PaintColumnSeparator(Graphics g) + { + for (int col = GroupSize; col < _iHexMaxHBytes; col += GroupSize) + { + var pen = new Pen(new SolidBrush(this.InfoForeColor), 1); + PointF headerPointF = GetColumnInfoPointF(col); + headerPointF.X -= _charSize.Width / 2; + g.DrawLine(pen, headerPointF, new PointF(headerPointF.X, headerPointF.Y + _recColumnInfo.Height + _recHex.Height)); + if (StringViewVisible) + { + PointF byteStringPointF = GetByteStringPointF(new Point(col, 0)); + headerPointF.X -= 2; + g.DrawLine(pen, new PointF(byteStringPointF.X, byteStringPointF.Y), new PointF(byteStringPointF.X, byteStringPointF.Y + _recHex.Height)); + } + } + } + void PaintHex(Graphics g, long startByte, long endByte) { Brush brush = new SolidBrush(GetDefaultForeColor()); @@ -2423,7 +2550,18 @@ namespace Be.Windows.Forms g.DrawString(sB.Substring(0,1), Font, brush, bytePointF, _stringFormat); bytePointF.X += _charSize.Width; - g.DrawString(sB.Substring(1,1), Font, brush, bytePointF, _stringFormat); + g.DrawString(sB.Substring(1, 1), Font, brush, bytePointF, _stringFormat); + } + + void PaintColumnInfo(Graphics g, byte b, Brush brush, int col) + { + PointF headerPointF = GetColumnInfoPointF(col); + + string sB = ConvertByteToHex(b); + + g.DrawString(sB.Substring(0, 1), Font, brush, headerPointF, _stringFormat); + headerPointF.X += _charSize.Width; + g.DrawString(sB.Substring(1, 1), Font, brush, headerPointF, _stringFormat); } void PaintHexStringSelected(Graphics g, byte b, Brush brush, Brush brushBack, Point gridPoint) @@ -2489,7 +2627,7 @@ namespace Be.Windows.Forms void PaintCurrentBytesSign(Graphics g) { - if(_keyInterpreter != null && Focused && _bytePos != -1 && Enabled) + if (_keyInterpreter != null && _bytePos != -1 && Enabled) { if(_keyInterpreter.GetType() == typeof(KeyInterpreter)) { @@ -2688,8 +2826,14 @@ namespace Be.Windows.Forms void UpdateRectanglePositioning() { // calc char size - SizeF charSize = this.CreateGraphics().MeasureString("A", Font, 100, _stringFormat); - _charSize = new SizeF((float)Math.Ceiling(charSize.Width), (float)Math.Ceiling(charSize.Height)); + SizeF charSize; + using (var graphics = this.CreateGraphics()) + { + charSize = this.CreateGraphics().MeasureString("A", Font, 100, _stringFormat); + } + CharSize = new SizeF((float)Math.Ceiling(charSize.Width), (float)Math.Ceiling(charSize.Height)); + + int requiredWidth = 0; // calc content bounds _recContent = ClientRectangle; @@ -2704,6 +2848,7 @@ namespace Be.Windows.Forms _vScrollBar.Left = _recContent.X+_recContent.Width; _vScrollBar.Top = _recContent.Y; _vScrollBar.Height = _recContent.Height; + requiredWidth += _vScrollBar.Width; } int marginLeft = 4; @@ -2715,31 +2860,59 @@ namespace Be.Windows.Forms _recContent.Y, (int)(_charSize.Width*10), _recContent.Height); + requiredWidth += _recLineInfo.Width; } else { _recLineInfo = Rectangle.Empty; _recLineInfo.X = marginLeft; + requiredWidth += marginLeft; + } + + // calc line info bounds + _recColumnInfo = new Rectangle(_recLineInfo.X + _recLineInfo.Width, _recContent.Y, _recContent.Width - _recLineInfo.Width, (int)charSize.Height + 4); + if (_columnInfoVisible) + { + _recLineInfo.Y += (int)charSize.Height + 4; + _recLineInfo.Height -= (int)charSize.Height + 4; + } + else + { + _recColumnInfo.Height = 0; } // calc hex bounds and grid _recHex = new Rectangle(_recLineInfo.X + _recLineInfo.Width, _recLineInfo.Y, _recContent.Width - _recLineInfo.Width, - _recContent.Height); + _recContent.Height - _recColumnInfo.Height); if(UseFixedBytesPerLine) { SetHorizontalByteCount(_bytesPerLine); - _recHex.Width = (int)Math.Floor(((double)_iHexMaxHBytes)*_charSize.Width*3+(2*_charSize.Width)); + _recHex.Width = (int)Math.Floor(((double)_iHexMaxHBytes) * _charSize.Width * 3 + (2 * _charSize.Width)); + requiredWidth += _recHex.Width; } else { - int hmax = (int)Math.Floor((double)_recHex.Width/(double)_charSize.Width); - if(hmax > 1) - SetHorizontalByteCount((int)Math.Floor((double)hmax/3)); + int hmax = (int)Math.Floor((double)_recHex.Width / (double)_charSize.Width); + if (_stringViewVisible) + { + hmax -= 2; + if (hmax > 1) + SetHorizontalByteCount((int)Math.Floor((double)hmax / 4)); + else + SetHorizontalByteCount(1); + } else - SetHorizontalByteCount(hmax); + { + if (hmax > 1) + SetHorizontalByteCount((int)Math.Floor((double)hmax / 3)); + else + SetHorizontalByteCount(1); + } + _recHex.Width = (int)Math.Floor(((double)_iHexMaxHBytes) * _charSize.Width * 3 + (2 * _charSize.Width)); + requiredWidth += _recHex.Width; } if(_stringViewVisible) @@ -2748,12 +2921,15 @@ namespace Be.Windows.Forms _recHex.Y, (int)(_charSize.Width*_iHexMaxHBytes), _recHex.Height); + requiredWidth += _recStringView.Width; } else { _recStringView = Rectangle.Empty; } + RequiredWidth = requiredWidth; + int vmax = (int)Math.Floor((double)_recHex.Height/(double)_charSize.Height); SetVerticalByteCount(vmax); @@ -2772,7 +2948,15 @@ namespace Be.Windows.Forms PointF GetBytePointF(Point gp) { float x = (3 * _charSize.Width) * gp.X + _recHex.X; - float y = (gp.Y+1)*_charSize.Height-_charSize.Height+_recHex.Y; + float y = (gp.Y + 1) * _charSize.Height - _charSize.Height + _recHex.Y; + + return new PointF(x, y); + } + PointF GetColumnInfoPointF(int col) + { + Point gp = GetGridBytePoint(col); + float x = (3 * _charSize.Width) * gp.X + _recColumnInfo.X; + float y = _recColumnInfo.Y; return new PointF(x,y); } @@ -2823,7 +3007,12 @@ namespace Be.Windows.Forms } set { + if (value == null) + return; + base.Font = value; + this.UpdateRectanglePositioning(); + this.Invalidate(); } } @@ -2921,6 +3110,28 @@ namespace Be.Windows.Forms } } int _bytesPerLine = 16; + /// + /// Gets or sets the number of bytes in a group. Used to show the group separator line (if GroupSeparatorVisible is true) + /// + /// + /// GroupSeparatorVisible property must set to true + /// + [DefaultValue(4), Category("Hex"), Description("Gets or sets the byte-count between group separators (if visible).")] + public int GroupSize + { + get { return _groupSize; } + set + { + if (_groupSize == value) + return; + + _groupSize = value; + OnGroupSizeChanged(EventArgs.Empty); + + UpdateRectanglePositioning(); + Invalidate(); + } + } int _groupSize = 4; /// /// Gets or sets if the count of bytes in one line is fix. /// @@ -3027,7 +3238,46 @@ namespace Be.Windows.Forms } } - IByteProvider _byteProvider; + IByteProvider _byteProvider; + /// + /// Gets or sets the visibility of the group separator. + /// + [DefaultValue(false), Category("Hex"), Description("Gets or sets the visibility of a separator vertical line.")] + public bool GroupSeparatorVisible + { + get { return _groupSeparatorVisible; } + set + { + if (_groupSeparatorVisible == value) + return; + + _groupSeparatorVisible = value; + OnGroupSeparatorVisibleChanged(EventArgs.Empty); + + UpdateRectanglePositioning(); + Invalidate(); + } + } bool _groupSeparatorVisible = false; + + /// + /// Gets or sets the visibility of the column info + /// + [DefaultValue(false), Category("Hex"), Description("Gets or sets the visibility of header row.")] + public bool ColumnInfoVisible + { + get { return _columnInfoVisible; } + set + { + if (_columnInfoVisible == value) + return; + + _columnInfoVisible = value; + OnColumnInfoVisibleChanged(EventArgs.Empty); + + UpdateRectanglePositioning(); + Invalidate(); + } + } bool _columnInfoVisible = false; /// /// Gets or sets the visibility of a line info. @@ -3047,7 +3297,7 @@ namespace Be.Windows.Forms UpdateRectanglePositioning(); Invalidate(); } - } bool _lineInfoVisible; + } bool _lineInfoVisible = false; /// /// Gets or sets the offset of a line info. @@ -3063,9 +3313,9 @@ namespace Be.Windows.Forms _lineInfoOffset = value; - Invalidate(); - } - } long _lineInfoOffset; + Invalidate(); + } + } long _lineInfoOffset = 0; /// /// Gets or sets the hex boxs border style. @@ -3184,14 +3434,14 @@ namespace Be.Windows.Forms /// - /// Gets or sets the line info color. When this property is null, then ForeColor property is used. + /// Gets or sets the info color used for column info and line info. When this property is null, then ForeColor property is used. /// - [DefaultValue(typeof(Color), "Empty"), Category("Hex"), Description("Gets or sets the line info color. When this property is null, then ForeColor property is used.")] - public Color LineInfoForeColor + [DefaultValue(typeof(Color), "Gray"), Category("Hex"), Description("Gets or sets the line info color. When this property is null, then ForeColor property is used.")] + public Color InfoForeColor { - get { return _lineInfoForeColor; } - set { _lineInfoForeColor = value; Invalidate(); } - } Color _lineInfoForeColor = Color.Empty; + get { return _infoForeColor; } + set { _infoForeColor = value; Invalidate(); } + } Color _infoForeColor = Color.Gray; /// /// Gets or sets the background color for the selected bytes. @@ -3243,6 +3493,40 @@ namespace Be.Windows.Forms set { _shadowSelectionColor = value; Invalidate(); } } Color _shadowSelectionColor = Color.FromArgb(100, 60, 188, 255); + /// + /// Contains the size of a single character in pixel + /// + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public SizeF CharSize + { + get { return _charSize; } + private set + { + if (_charSize == value) + return; + _charSize = value; + if (CharSizeChanged != null) + CharSizeChanged(this, EventArgs.Empty); + } + } SizeF _charSize; + + /// + /// Gets the width required for the content + /// + [DefaultValue(0), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public int RequiredWidth + { + get { return _requiredWidth; } + private set + { + if (_requiredWidth == value) + return; + _requiredWidth = value; + if (RequiredWidthChanged != null) + RequiredWidthChanged(this, EventArgs.Empty); + } + } int _requiredWidth; + /// /// Gets the number bytes drawn horizontally. /// @@ -3543,6 +3827,26 @@ namespace Be.Windows.Forms LineInfoVisibleChanged(this, e); } + /// + /// Raises the OnColumnInfoVisibleChanged event. + /// + /// An EventArgs that contains the event data. + protected virtual void OnColumnInfoVisibleChanged(EventArgs e) + { + if (ColumnInfoVisibleChanged != null) + ColumnInfoVisibleChanged(this, e); + } + + /// + /// Raises the ColumnSeparatorVisibleChanged event. + /// + /// An EventArgs that contains the event data. + protected virtual void OnGroupSeparatorVisibleChanged(EventArgs e) + { + if (GroupSeparatorVisibleChanged != null) + GroupSeparatorVisibleChanged(this, e); + } + /// /// Raises the StringViewVisibleChanged event. /// @@ -3573,6 +3877,16 @@ namespace Be.Windows.Forms UseFixedBytesPerLineChanged(this, e); } + /// + /// Raises the GroupSizeChanged event. + /// + /// An EventArgs that contains the event data. + protected virtual void OnGroupSizeChanged(EventArgs e) + { + if (GroupSizeChanged != null) + GroupSizeChanged(this, e); + } + /// /// Raises the BytesPerLineChanged event. /// @@ -3735,5 +4049,28 @@ namespace Be.Windows.Forms UpdateScrollSize(); } #endregion + + #region Scaling Support for High DPI resolution screens + /// + /// For high resolution screen support + /// + /// the factor + /// bounds + protected override void ScaleControl(SizeF factor, BoundsSpecified specified) + { + base.ScaleControl(factor, specified); + + this.BeginInvoke(new MethodInvoker(() => + { + this.UpdateRectanglePositioning(); + if (_caretVisible) + { + DestroyCaret(); + CreateCaret(); + } + this.Invalidate(); + })); + } + #endregion } } diff --git a/Be.Windows.Forms.HexBox/Util.cs b/Be.Windows.Forms.HexBox/Util.cs index 3a1ae76..cfec29a 100644 --- a/Be.Windows.Forms.HexBox/Util.cs +++ b/Be.Windows.Forms.HexBox/Util.cs @@ -16,7 +16,13 @@ namespace Be.Windows.Forms /// static Util() { - _designMode = (System.Diagnostics.Process.GetCurrentProcess().ProcessName.ToLower() == "devenv"); + // design mode is true if host process is: Visual Studio, Visual Studio Express Versions (C#, VB, C++) or SharpDevelop + var designerHosts = new List() { "devenv", "vcsexpress", "vbexpress", "vcexpress", "sharpdevelop" }; + using (var process = System.Diagnostics.Process.GetCurrentProcess()) + { + var processName = process.ProcessName.ToLower(); + _designMode = designerHosts.Contains(processName); + } } /// diff --git a/Tinke/Sistema.cs b/Tinke/Sistema.cs index 65574b0..9a4f8e8 100644 --- a/Tinke/Sistema.cs +++ b/Tinke/Sistema.cs @@ -80,7 +80,6 @@ namespace Tinke "\n True" + "\n True" + "\n True" + - //"\n False" + "\n \n", Encoding.UTF8); } @@ -152,28 +151,46 @@ namespace Tinke } else if (Program.tblRoms.Count() == 1) { - filesToRead[0] = Program.tblRoms[0]; + if (File.Exists(Program.tblRoms[0])) + filesToRead[0] = Program.tblRoms[0]; + else { + MessageBox.Show(Tools.Helper.GetTranslation("Messages", "S2E"), Tools.Helper.GetTranslation("Messages", "S01")); + this.Close(); + Application.Exit(); + return; + } } else { + foreach (string fileName in Program.tblRoms) + { + if (!File.Exists(fileName)) + { + MessageBox.Show(Tools.Helper.GetTranslation("Messages", "S2E"), Tools.Helper.GetTranslation("Messages", "S01")); + this.Close(); + Application.Exit(); + return; + } + } filesToRead = new String[Program.tblRoms.Count()]; Array.Copy(Program.tblRoms.ToArray(), 0, filesToRead, 0, filesToRead.Length); } } else if (Program.curCommand == 1) { - filesToRead[0] = Program.extractFilePath; - ReadGame(filesToRead[0]); - sFolder folderSelect = accion.Root; + if (!File.Exists(Program.extractFilePath)) + Console.WriteLine("The input file not found!"); + else { + filesToRead[0] = Program.extractFilePath; + ReadGame(filesToRead[0]); - if (Program.extractOutputPath is string) - { + sFolder folderSelect = accion.Root; + if (string.IsNullOrWhiteSpace(Program.extractOutputPath)) + Program.extractOutputPath = "."; Directory.CreateDirectory(Program.extractOutputPath + Path.DirectorySeparatorChar + folderSelect.name); RecursivoExtractFolder(folderSelect, Program.extractOutputPath + Path.DirectorySeparatorChar + folderSelect.name); Console.WriteLine("Extract all files to " + Program.extractOutputPath + Path.DirectorySeparatorChar + folderSelect.name); } - else - Console.WriteLine("Param error..."); if (!isMono) { @@ -186,14 +203,22 @@ namespace Tinke } else if (Program.curCommand == 2) { - filesToRead[0] = Program.replaceInputFile; - ReadGame(filesToRead[0]); - if (Program.replaceResPath is string) - { - ChangeByDir(Program.replaceResPath); - } else - Console.WriteLine("Param error..."); - btnSaveROM_Click(null, null); + if (!File.Exists(Program.replaceInputFile)) + Console.WriteLine("The input file not found!"); + else { + filesToRead[0] = Program.replaceInputFile; + ReadGame(filesToRead[0]); + + string fullPath = Path.GetFullPath(Program.replaceResPath); + string lastDirectoryName = Path.GetFileName(fullPath.TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar)); + if (Directory.Exists(Program.replaceResPath) && string.Equals(lastDirectoryName, "root")) + { + ChangeByDir(Program.replaceResPath); + btnSaveROM_Click(null, null); + } else + Console.WriteLine("The nitrofs folder not found or the folder name is not 'root'"); + } + if (!isMono) { Program.FreeConsole(); diff --git a/Tinke/VisorHex.Designer.cs b/Tinke/VisorHex.Designer.cs index 75f6971..3e67531 100644 --- a/Tinke/VisorHex.Designer.cs +++ b/Tinke/VisorHex.Designer.cs @@ -94,7 +94,7 @@ namespace Tinke | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.hexBox1.Font = new System.Drawing.Font("Courier New", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.hexBox1.LineInfoForeColor = System.Drawing.Color.Empty; + this.hexBox1.InfoForeColor = System.Drawing.Color.Empty; this.hexBox1.LineInfoVisible = true; this.hexBox1.Location = new System.Drawing.Point(0, 24); this.hexBox1.Name = "hexBox1"; diff --git a/Tinke/langs/en-us.xml b/Tinke/langs/en-us.xml index d271ffa..fe5b923 100644 --- a/Tinke/langs/en-us.xml +++ b/Tinke/langs/en-us.xml @@ -262,6 +262,7 @@ The DSi Banner is good! The DSi Banner is incomplete or corrupted. The donor iheader mismatch! + File(s) not found! diff --git a/Tinke/langs/es-es.xml b/Tinke/langs/es-es.xml index 7c38313..5a8a713 100644 --- a/Tinke/langs/es-es.xml +++ b/Tinke/langs/es-es.xml @@ -266,6 +266,7 @@ The DSi Banner is good! The DSi Banner is incomplete or corrupted. The donor iheader mismatch! + File(s) not found! diff --git a/Tinke/langs/fr-fr.xml b/Tinke/langs/fr-fr.xml index 7587d76..962a707 100644 --- a/Tinke/langs/fr-fr.xml +++ b/Tinke/langs/fr-fr.xml @@ -262,6 +262,7 @@ The DSi Banner is good! The DSi Banner is incomplete or corrupted. The donor iheader mismatch! + File(s) not found! diff --git a/Tinke/langs/it-it.xml b/Tinke/langs/it-it.xml index 7a9b509..087f996 100644 --- a/Tinke/langs/it-it.xml +++ b/Tinke/langs/it-it.xml @@ -261,6 +261,7 @@ The DSi Banner is good! The DSi Banner is incomplete or corrupted. The donor iheader mismatch! + File(s) not found! diff --git a/Tinke/langs/zh-hans.xml b/Tinke/langs/zh-hans.xml index e7cc24c..d2dac2c 100644 --- a/Tinke/langs/zh-hans.xml +++ b/Tinke/langs/zh-hans.xml @@ -261,6 +261,7 @@ DSi Banner 正确! DSi Banner 不完整或已损坏。 donor iheader 不匹配! + 一个或多个文件未找到!