Nejsem výplodem moderní doby - programovat umím a to do hloubky. Již jsem si to vyřešil sám. Ty jsi totiž nepochopil, že sice se jedná o 2 zobrazení, ale neustálé konverze jsou namáhavé. Proto jsem nechtěl současná řešení, která jsem viděl - přáce se 2ma zdroji, ale současně také ne neustálé analýzy... Proto jsem vzal jeden zdroj, ale nadefinoval dopředu zobrazovací část - buffer:
using System.Collections.Generic;
using System.Windows.Forms;
using System.Drawing;
using System;
namespace QiE
{
public class HexView : Control
{
private int
top = 0,
cursorTop = 0,
cursorLeft = 0,
charTopCount = 0,
charLeftCount = 0;
Dictionary<int, char[]> source = new Dictionary<int, char[]>();
Action<Graphics> drawBuffer;
public Size CharSize { get; private set; }
public int CursorLeft
{
get { return cursorLeft; }
private set
{
if(value < 0)
{
if(top > 0 || cursorTop > 0)
{
CursorTop--;
cursorLeft = source[0].Length - 1;
}
}
else if(value < charLeftCount)
cursorLeft = value;
else
{
cursorLeft = 0;
CursorTop++;
}
}
}
public int CursorTop
{
get { return cursorTop; }
private set
{
if(value < top)
top--;
else if(value < charTopCount)
cursorTop = value;
else
top++;
}
}
public HexView()
{
Font = new Font("Monospace", 10, FontStyle.Bold, GraphicsUnit.Point, 0);
SizeF fCharSize = CreateGraphics().MeasureString(" ", Font);
CharSize = new Size((int)fCharSize.Width, (int)fCharSize.Height);
SizeChanged += (sender, e) => RestoreSource();
RestoreSource();
Cursor = Cursors.IBeam;
}
private void RestoreSource()
{
charTopCount = Bounds.Height / CharSize.Height;
charLeftCount = Bounds.Width / CharSize.Width - 14;
drawBuffer = null;
for(int index = 0; index < charTopCount; index++)
{
int offset = index;
drawBuffer += graphics =>
{
int currentTop = top + offset;
if(!source.ContainsKey(currentTop))
source.Add(currentTop, new char[charLeftCount]);
graphics.DrawString(new string(source[currentTop]),
Font,
new SolidBrush(ForeColor),
new PointF(Padding.Left, Padding.Top + offset * CharSize.Height));
};
}
}
protected override void OnPaint(PaintEventArgs e)
{
e.Graphics.Clear(BackColor);
if(drawBuffer != null)
drawBuffer(e.Graphics);
Cursor.Draw(e.Graphics, new Rectangle((cursorLeft - 1) * CharSize.Width, cursorTop * CharSize.Height - 4, CharSize.Width, CharSize.Height));
}
protected override void OnMouseDown(MouseEventArgs e)
{
cursorLeft = (e.X - Padding.Bottom) / CharSize.Width;
cursorTop = (e.Y - Padding.Top) / CharSize.Height;
Refresh();
}
protected override void OnKeyDown(KeyEventArgs e)
{
switch(e.KeyData)
{
case Keys.Left:
CursorLeft--;
break;
case Keys.Right:
CursorLeft++;
break;
case Keys.Up:
CursorTop--;
break;
case Keys.Down:
CursorTop++;
break;
}
Refresh();
base.OnKeyDown(e);
}
protected override void OnKeyPress(KeyPressEventArgs e)
{
switch(e.KeyChar)
{
case '\r':
CursorTop++;
cursorLeft = 0;
break;
case '\b':
try
{
CursorLeft--;
source[top + cursorTop][cursorLeft] = ' ';
}
catch {}
break;
default:
try
{
source[top + cursorTop][cursorLeft] = e.KeyChar;
}
catch
{
source.Add(top + cursorTop, new char[charLeftCount]);
source[top + cursorTop][cursorLeft] = e.KeyChar;
}
finally
{
CursorLeft++;
}
break;
}
Refresh();
base.OnKeyPress(e);
}
}
}
Ale očividně zde budu muset udělat konverze i pro části, které jsem již konvertoval - a to je to, co jsem nechtěl...