Monday, February 21, 2005

Boo - New .NET Language

http://boo.codehaus.org/

Something I found yesterday. Quite an interesting language that's very dynamic. Here's the description of it.

Boo is a new object oriented statically typed programming language for the Common Language Infrastructure with a python inspired syntax and a special focus on language and compiler extensibility.

Do check it out.

CS-Script - The C# Script Engine

Something I came across that's quite interesting.

http://www.members.optusnet.com.au/~olegshilo/

CS-Script. Looks good. Wonder if it can be done for websites, instead of using javascript? :)

Friday, February 18, 2005

Non-Rectangular Windows Forms Part 2

I figured nobody could answer my question. Therefore, I solved it myself.

Basically what I did was to use the form's Region property. This Region property selects the region in which it is to display.

Problem, how am I gonna find out the region of an irregular shape? Simple. Parse each pixel bit by bit to check for your transparency key. If it is not transparent, create a graphics path of 1 pixel to create your region. I got the idea from here.

http://weblogs.asp.net/cumpsd/articles/79878.aspx

The code is as follows.

public static Region ConvertFromTransparentBitmap(Bitmap imageRegion, Color transparentColor) {
// First we get the dimensions of our image
GraphicsUnit aPixel = GraphicsUnit.Pixel;
RectangleF imageBoundsF = imageRegion.GetBounds(ref aPixel);
int imageWidth = Convert.ToInt32(imageBoundsF.Width);
int imageHeight = Convert.ToInt32(imageBoundsF.Height);

// This will be the path for our Region
GraphicsPath regionPath = new GraphicsPath();

// We loop over every line in our image, and every pixel per line
for (int intY = 0; intY < imageHeight; intY++) {
for (int intX = 0; intX < imageWidth; intX++) {
if (imageRegion.GetPixel(intX, intY) != transparentColor) {
// We have to see this pixel!
regionPath.AddRectangle(new Rectangle(intX, intY, 1, 1));
}
}
}


Region formRegion = new Region(regionPath);
regionPath.Dispose();
return formRegion;
} /* ConvertFromTransparentBitmap */


But that took 12 secs to load up. So I did it the opposite way, since I have more visible part than transparent. If the pixel matches your transparency key, create the graphics path then. And I did an exclude. Like this.

public static Region ConvertFromTransparentBitmap(Bitmap imageRegion, Color transparentColor) {
// First we get the dimensions of our image
GraphicsUnit aPixel = GraphicsUnit.Pixel;
RectangleF imageBoundsF = imageRegion.GetBounds(ref aPixel);
int imageWidth = Convert.ToInt32(imageBoundsF.Width);
int imageHeight = Convert.ToInt32(imageBoundsF.Height);

// Create an arraylist to store the rectangles
ArrayList rectArray = new ArrayList();

// This will be the path for our Region
GraphicsPath regionPath = new GraphicsPath();

// We loop over every line in our image, and every pixel per line
for (int intY = 0; intY < imageHeight; intY++) {
for (int intX = 0; intX < imageWidth; intX++) {
//Color c = imageRegion.GetPixel(intX, intY);
if (imageRegion.GetPixel(intX, intY) == transparentColor) {
// We have to see this pixel!
//regionPath.AddRectangle(new Rectangle(intX, intY, 1, 1));
// Add a rectangle to the array
rectArray.Add(new Rectangle(intX, intY, 1, 1));
}
}
}

Rectangle[] rectList = new Rectangle[rectArray.Count];

// Now we convert the ArrayList into an array of Rectangles
for(int i=0; i < rectArray.Count; i++) {
rectList = (Rectangle)rectArray;
}

regionPath.AddRectangles(rectList);
Region formRegion = new Region(regionPath);

// we need to create a region which encompasses the entire form
Region fullRegion = new Region(new Rectangle(0, 0, imageRegion.Width, imageRegion.Height));

// we do a simple exclude those parts that intersect
fullRegion.Exclude(formRegion);

formRegion.Dispose();
regionPath.Dispose();
return fullRegion;
} /* ConvertFromTransparentBitmap */

Basically this alternate way speed up the entire loading process down to 4 secs. Of course together with DoubleBuffering on, and using the 32bit-enabled transparency code up there, I was able to create one ultra fast and smooth irregular window, without any flicker to the controls within.

A faster way to speed up the loading process, which I haven't tried yet, is to create the array of points to the graphics path. Meaning you'll have to pre-generate the points first, put it in an array, and use it in a GraphicsPath object. This will speed everything up to the second, theoretically speaking.

This method is called inline masking. If those of you have done low-level graphics and trying to accelerate graphics and transparency, this is how the old school does it.

If anyone has any suggestions whereby how to make it work another way, please post here.

Non-Rectangular Windows Forms

Yo, now a problem from me. I tried to search for it, without any success.

http://www.thecodeproject.com/csharp/nonRectangularForm.asp

I'm trying to create a non-rectangular windows form. Currently it's quite easy if the person uses 24bit and below resolution, you just assign your background image and set your transparencykey. But who uses 24bit and below nowadays? We all use 32bit.

That article above explains to you how to get it done. The modification I made was to make it happen in OnPaintBackground event instead of OnPaint event, because if it was OnPaint event, the controls will flicker and you can see what's behind the form.

So now, the problem is, it still flickers and is very slow. To solve this flickering, you must implement double buffering. But when I set the styles to do double buffering, the transparency of the background is ignored.

Question. How can I achieve double buffering which the background transparency still intact?

Here's the code for reference

protected override void OnPaintBackground(PaintEventArgs e)
{
base.OnPaintBackground(e);
this.SuspendLayout();

// First we create a graphics object using the PiantEventArgs e that will use the
// form
Graphics grfx = e.Graphics;
// Make Antialiasing which avoid stepped look for circular path and curves you
// may use the SmoothingMode.AntiAlias
grfx.SmoothingMode = SmoothingMode.None;
grfx.DrawImage(this.background, this.frmRectangle);

this.ResumeLayout();
}

Setting the styles I'm sure you guys should know. How to I apply transparency over here?

Thursday, February 17, 2005

Thoughts on Integrating DNN 3.0 + CS 1.0

I've been playing around with both applications, and been thinking about how to merge these 2 wonderful applications together.

There are a few ways of doing it.

1. Rewriting the Membership/Role/etc providers and having both applications use the same providers. Then merging of the memberships would be needed, into 1 table. But I'm pondering how can it be done.

2. Writing a DNN module that interfaces with CS 1.0, stripping CS apart into different modules, i.e. Forums module, Blog module, Gallery module and so on. But CS dependencies on HttpContext is alot.

3. Stripping DNN apart and make it part of CS 1.0. I think that's the intention of CS, since I saw an empty web dll, which means the intention of having a Community Server - Web.

4. Quick hack. Sync between the databases and cookies. Which is what most people are doing now.

Personally, I think point 3 would be wonderful to try it out. What do you guys think? Which way is better?

Wednesday, February 16, 2005

DotNetNuke 3.0 & CS 1.0

I just realised something interesting. Both applications are sharing the same MachineValidationKeys. That means that they are preparing to be able to merge and interop with each other.

This is good news.