Tag Archives: Delphi/Object Pascal/Pascal

TabIndex tool in Visual Studio

I remember from old times that I was using some plug-in into Delphi IDE to set tab order by clicking on components in order you wanted the ordering to be. Today I was reviewing the tab ordering in ID3 renamer as somebody reported in forum it’s wrong. I was scared doing all the work through Properties window in Visual Studio.

But it turned out, that Visual Studio has this tool in the box. You can find the description here. You’ll simply select form, go to View > Tab Order and click on different controls to change the ordering. You see the numbers directly in designer and go through possible options by clicking.

Pretty nice, don’t you think?

Memory mapped files in .NET 4

Similarly to my way to CountdownEvent class, I found MemoryMappedFiles namespace, which is new in .NET 4. It’s in System.IO.

If you’ve done some work in stone ages in C/C++ or maybe ObjectPascal (Delphi) you may remember using these files. I used these for exchanging data between two applications, but the usage is pretty much endless. And now you can benefit from it in .NET directly, without using P/Invoke.

To see what’s inside, I wrote two simple applications that are reading and writing some data (no synchronization ;) ).

The first one is doing writing and reading:

using (MemoryMappedFile mmf = MemoryMappedFile.CreateOrOpen("TestMemoryMappedFile", 1024 * 1024))
{
	using (MemoryMappedViewAccessor accessor = mmf.CreateViewAccessor())
	{
		HelperStuff.WriteData(accessor, 0);

		Console.ReadLine();

		HelperStuff.ReadData(accessor, 0);
	}
}

and the second one is just reading:

using (MemoryMappedFile mmf = MemoryMappedFile.CreateOrOpen("TestMemoryMappedFile", 1024 * 1024))
{
	using (MemoryMappedViewAccessor accessor = mmf.CreateViewAccessor())
	{
		HelperStuff.WriteData(accessor, 0);

		Console.ReadLine();

		HelperStuff.ReadData(accessor, 0);
	}
}

Nothing magical. The reading and writing methods (placed in shared library) are simply creating some dummy data. In my case struct and string, saved as array of bytes.

public static void ReadData(MemoryMappedViewAccessor accessor, int position)
{
	SomeData data1;

	accessor.Read<SomeData>(position, out data1);
	position += Marshal.SizeOf(typeof(SomeData));

	int length = accessor.ReadInt32(position);
	position += Marshal.SizeOf(typeof(int));

	byte[] data2 = new byte[length];

	accessor.ReadArray<byte>(position, data2, 0, data2.Length);

	Console.WriteLine(data1.CurrentDate);
	Console.WriteLine(Encoding.Unicode.GetString(data2));
}

public static void WriteData(MemoryMappedViewAccessor accessor, int position)
{
	SomeData data1 = new SomeData() { CurrentDate = DateTime.Today.Ticks };
	byte[] data2 = Encoding.Unicode.GetBytes(DateTime.Today.ToLongDateString());

	accessor.Write<SomeData>(position, ref data1);
	position += Marshal.SizeOf(typeof(SomeData));

	accessor.Write(position, data2.Length);
	position += Marshal.SizeOf(typeof(int));

	accessor.WriteArray<byte>(position, data2, 0, data2.Length);
}

The struct is really dummy:

public struct SomeData
{
	public long CurrentDate { get; set; }
}

The reading and writing is little bit limited, as you’re in fact dealing with just a bunch of memory, not some structured storage. But if you like working with it directly as stream (or you have some smart wrappers around streams), you can also use method CreateViewStream instead of CreateViewAccessor used in my example. These method have some overloads with option to specify also the access rights using MemoryMappedFileAccess, so you can i.e. use CopyOnWrite and any write operations will not be seen by other processes.

Windows 7, mouse, multitouch, gravitation – flashback

While reading Mike Taulty’s posts about playing with Windows 7 and multitouch some words like deceleration, inertia etc. started some process in my head and I recalled some very old program everybody was creating. I don’t know if everybody, but at least 99,9% of Delphi developers.

The idea behind program was pretty simple. No window, somehow hook the mouse (I don’t remember whether it was classic hook, because it was in Win98/95 era). And everytime you put the mouse to the top, it started falling down, like if the gravitation worker for mouse cursor too. I remember too some modification, that if you done some horizontal move with mouse it had some inertia and decelerated. So it was fun try to click on some button or similar stuff. :) And if you put the mouse to the top of the screen with this move, it was falling down with parabola path.

Sure, the code and/or program was absolutely useless, but it was a great rest during long day at work. I wish I found the program somewhere now and look at it. :)

Rotační hyperboloid? Ale kdepak.

Minulý týden jsem byl v Liberci, kde jsem prováděl školení pro firmu INISOFT. Mimochodem skvělá parta lidí – a BabySmash, náhodou zmíněný, zaznamenal fenomenální úspěch. ;-)

Mimo to jsem měl možnost se podívat na horu Ještěd (1012m). Na vrcholu je stavba (televizní vysílač a hotel), jejíž tvar má být rotační hyperboloid. Z dálky možná, ale na místě … Některé plochy jsou prostě víc rovné než “oblé”. Podvod. :) Nicméně i tak doporučuji navštívít. Výhled je super a stavba opravdu pěkně následuje tvar terénu.

if, else, return

Občas vidím ve zdrojácích funkce s konstrukcí:

if (<condition>)
{
  x = DoSomething(y);
  return x;
}
return z;

Což je víceméně to samé jako:

if (<condition>)
{
  x = DoSomething(y);
  return x;
}
else
{
  return z;
}

Osobně používám druhý zápis. Přijde mi o něco přehlednější a explicitnější. Pravděpodobně vliv Delphi/ObjectPascalu.

Je však v těchto zápisech nějaký rozdíl? Nějaký praktický aspekt, který mi uniká?

Creating Firebird database programatically (Delphi)

Today my colleague asked me the question, “How to create FB database programatically from Delphi?”. Well, the solution is very easy, just use the following code (it’s using the InterBase Express components):


IBDatabase1.DatabaseName := ChangeFileExt(Application.ExeName, ‘.fdb’);
IBDatabase1.Params.Add(‘USER ”SYSDBA”’);
IBDatabase1.Params.Add(‘PASSWORD ”masterkey”’);
IBDatabase1.Params.Add(‘PAGE_SIZE 4096′);
IBDatabase1.Params.Add(‘DEFAULT CHARACTER SET WIN1250′);
IBDatabase1.CreateDatabase;