Návrh HEX Editoru – .NET – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

Návrh HEX Editoru – .NET – Fórum – Programujte.comNávrh HEX Editoru – .NET – Fórum – Programujte.com

 

Matěj Andrle
~ Anonymní uživatel
1347 příspěvků
30. 7. 2013   #1
-
0
-

Dobrý den

vytvářím Forms.Control třídu pro editaci v HEX módu. Chtěl bych v tomto jednom Controlu řešit jak HEX editaci, tak i dekadickou... (I strojové kódy, i ASCII.) A tak se ptám - Co se vyplatí nejvíce? Ve vlastnosti Text mít HEX a v Paint neustále konvertovat do ASCII? Mít pole int HEX a to v Paint vypsat do HEX poloviny a v druhé převést do charů? (Asi cyklem.) Atd. Napadá mne spousta řešení - které ale bude nejvhodnější a nejnenáročnější?

Děkuji.

Nahlásit jako SPAM
IP: 78.136.150.–
liborb
~ Redaktor
+18
Guru
30. 7. 2013   #2
-
0
-

Když děláš něco takového, zejména opakované vyplňování vlastností komponent, tak si zkus začít editovat třeba 10MB soubor a uvidíme, jestli se to vůbec pohne :).

Data jsou jen jedna, ale liší se pouze v zobrazení. Nakonec obé budeš asi procházet po znacích neb když budeš mít vlevo ASCII a vpravo HEX, co uděláš, když tam bude znak odřádkování? Nebo nějaký jiný netisknutelný znak? Nahrazuje se to mezerou nebo něčím definovaným, aby se ti nerozbil "layout".

No a výpis bude spíše vykreslení, protože ty potřebuješ opravdu zobrazit jen tu část, kterou vidíš, jinak budeš mít problém s většími soubory. Nemáš žádné zvýrazňování syntaxe nebo tak něco, takže je ti putna, co bylo předtím, takže když uděláš zobrazení 16 znaků na řádek (což bude celkem 16 znaků ASCII + 48 znaků HEX i s mezerami), tak si to jednoduše odpočítáš (přeskočíš 16 * počet řádků nad prvním viditelným řádkem) a zobrazíš počet viditelných řádků + 1. Pro uložení místo stringu použij nějaký bajtový buffer.

Nahlásit jako SPAM
IP: 188.75.135.–
Matěj Andrle
~ Anonymní uživatel
1347 příspěvků
30. 7. 2013   #3
-
0
-

Jasně, že budu vypisovat jen část - nejsem negramotný. (Udělat Buffer je triviální.) Řeším soulad mezi oběma polovinami. Řeším jak udělat ovlivnění jedné časti druhou... (binding?)

Nahlásit jako SPAM
IP: 78.136.150.–
liborb
~ Redaktor
+18
Guru
31. 7. 2013   #4
-
0
-

Selektivně si vybrat jednu věc z odpovědi a proti ní se vymezit ... napsal jsem toho víc. Třeba jak budeš řešit netisknutélné znaky? Jak budeš řešit odřádkování?

Taky jsem ti prozradil jedno tajemství - nejsou to 2 části, tj. dvoje data, ale pouze jedny data a 2 způsoby zobrazení.

V době, kdy se málokdo oháněl moderními udernými slovy jako binding, se to řešilo tak, že si prováděl vykreslení (ano v OnPaint) obou částí najednou, tj. naformátoval sis řádek (znaky | HEX) a ten se normálně vykreslil nějakým neproporcionálním písmem. Pak si pořešil pouze pozici a zobrazení kurzoru a bylo hotovo.

Tím chci jenom říct, že podle mě řešíš problém, který není resp. cesta, kterou si se vydal nemusí vést k cíli.

Nahlásit jako SPAM
IP: 188.75.135.–
Matěj Andrle
~ Anonymní uživatel
1347 příspěvků
31. 7. 2013   #5
-
0
-

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...

Nahlásit jako SPAM
IP: 78.136.150.–
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 66 hostů

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032024 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý