DCSIMG
February 2009 - Posts - Pavel's Blog
Sign in | Join | Help

Pavel's Blog

Pavel is a software guy that is interested in almost everything
software related... way too much for too little time

February 2009 - Posts

Presentation & Demos from C# LINQ Open House

Published at Feb 18 2009, 01:54 PM by pavely

Today I presented a Microsoft Open House event focused on C# 3.0 features and LINQ. Thank you all for coming!

I have attached the presentation and demos. Note that to make the LINQ to SQL samples work, you must change the connection string appropriately in the app.config file, or pass another one in the NorthwindDataContext constructor.

Why 2D Transforms use 3x3 Matrices

Published at Feb 15 2009, 09:41 AM by pavely

If you’re working with WPF or other sophisticated graphics framework (e.g. DirectX, OpenGL) you probably know that to create 2D transforms, you build a 3x3 Matrix, either explicitly or implicitly by using classes such as RotateTransform, ScaleTransform or TranslateTransform.
it might seem somewhat strange, that for 2D transformations we need a 3x3 matrix: after all, we take an X and a Y and transform them into some X2 and Y2. So, why a 3x3 matrix? Why not just 2x2?

The reason has to do with the ability to create a 2x2 matrix that can represent any transform. Unfortunately, this can’t be done for any transformation. It can be done for rotation and scale, but not for translation. i.e., you can’t create a 2x2 matrix, that when multiplying a 2D vector by it will yield translation of the original vector by some (dx,dy).

We want this:

[x1 y1] x [a b; c d] = [x1+dx y1+dy] (the ; denotes a “new line” – Matlab syntax :))

We want some (a, b, c, d) that can give this result. This simply is impossible!

One way this can be done is by enlarging the matrix to 3x3. In this case the formula becomes:

[x1 y1 1] x [1 0 0; 0 1 0; dx dy 1] = [x1+dx y1+dy 1]

Voila! The input vector is enlarged with an extra “1” and is simply discarded from the final result.

This idea is carried over to the 3D world. To do transformations using matrices, a 3D vector [x y z] is expanded to [x y z 1] and 4x4 matrices are used, which can produce any transformation desired.

Non-Square Caption Buttons

Published at Feb 12 2009, 09:18 AM by pavely

In the last few months, my Windows captions look something like this:

image

The caption buttons are not square. Someone asked me how I did it…

Well, Windows UI (Personalize…, etc.) allows changing the size of the caption buttons, but the width must be the same as the height. To make the caption buttons rectangular, one needs to call the SystemParametersInfo native API. Here’s some C++ code that does what you see here (width = 3 times height):

NONCLIENTMETRICS metrics = { sizeof(metrics) };

::SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof (metrics), &metrics, 0);

metrics.iCaptionWidth = metrics.iCaptionHeight * 3;

::SystemParametersInfo(SPI_SETNONCLIENTMETRICS, sizeof(metrics), &metrics, 0);

 

To do the same with .NET, some interop is required:

[DllImport("user32", CharSet = CharSet.Auto)]

private static extern int SystemParametersInfo(int uAction, int uParam, ref NONCLIENTMETRICS lpvParam, int fuWinIni);

 

private const int LF_FACESIZE = 32;

 

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]

private struct LOGFONT {

    public int lfHeight;

    public int lfWidth;

    public int lfEscapement;

    public int lfOrientation;

    public int lfWeight;

    public byte lfItalic;

    public byte lfUnderline;

    public byte lfStrikeOut;

    public byte lfCharSet;

    public byte lfOutPrecision;

    public byte lfClipPrecision;

    public byte lfQuality;

    public byte lfPitchAndFamily;

 

   [MarshalAs(UnmanagedType.ByValTStr, SizeConst = LF_FACESIZE)]

   public string lfFaceName;

 

   public LOGFONT(string lfFaceName) {

       this.lfFaceName = lfFaceName;

       lfHeight = lfWidth = lfEscapement = lfOrientation = lfWeight = 0;

       lfItalic = lfUnderline = lfStrikeOut = lfCharSet =

       lfOutPrecision = lfClipPrecision = lfQuality = 

       lfPitchAndFamily = 0;

       }

   }

   private struct NONCLIENTMETRICS {

       public int cbSize;

       public int iBorderWidth;

       public int iScrollWidth;

       public int iScrollHeight;

       public int iCaptionWidth;

       public int iCaptionHeight;

       public LOGFONT lfCaptionFont;

       public int iSMCaptionWidth;

       public int iSMCaptionHeight;

       public LOGFONT lfSMCaptionFont;

       public int iMenuWidth;

       public int iMenuHeight;

       public LOGFONT lfMenuFont;

       public LOGFONT lfStatusFont;

       public LOGFONT lfMessageFont;

   }

 

   private const int SPI_GETNONCLIENTMETRICS = 41;

   private const int SPI_SETNONCLIENTMETRICS = 42;

 

   static void Main(string[] args) {

       NONCLIENTMETRICS metrics = new NONCLIENTMETRICS();

       metrics.cbSize = Marshal.SizeOf(metrics);

       SystemParametersInfo(SPI_GETNONCLIENTMETRICS, 0, ref metrics, 0);

       metrics.iCaptionWidth = 3 * metrics.iMenuHeight;

       SystemParametersInfo(SPI_SETNONCLIENTMETRICS, 0, ref metrics, 0);

    }

Not pretty… but can’t be helped.

There is a class, System.Windows.Forms.SystemInformation that exposes most of these values, but all as read-only.

You may have to “refresh” the caption to see the change, e.g. minimize & restore windows.

Upcoming Courses and an Event

Published at Feb 09 2009, 11:28 AM by pavely

I’ll be teaching next week (starting from the 16th) a five day course (split) entitled “The C# 3.0 programming language” on .NET and C# fundamentals.

On the 18th of this month, I’ll do an open house at Microsoft on C# 3.0 and LINQ (same thing I did a few months back at Air Force house, so if you were there, no need to come again – unless you really like the food). You can register here.

On March 1st, I’ll be teaching my Windows Internals class (for developers) on the (obviously) internals of the Windows OS. Mostly suitable for Win32 and device drivers programmers, but .NET developers can gain a deeper understanding of the way things work (e.g. in the threading department) by attending the course.

Maybe I’ll see you out there!

Math.Net – Math Library for .NET

Published at Feb 08 2009, 08:55 AM by pavely

Recently I was searching for a mathematics library for use in .NET applications and I stumbled upon Math.Net, an open source math library that includes two main components: The first, called Iridium, deals with the basics: numbers, vectors, matrices and the like. The second, Neodym, is a digital signal processing toolkit, containing things like various filters, modulators, time-frequency processing tools and the like.

Worth checking out if you’re in the math business.