On this page
MVP
Microsoft MVP (since 2006) in the XNA/DirectX category

Tag cloud
Ajax (8) All (266) Arena Wars (21) Boo (4) BroodWar (10) Conferences (19) dasBlog (2) Development (77) DLR (6) Fun (25) Game Development (164) iPhone (5) IronPython (8) Lost Squadron (17) Lua (10) meinSport.de (4) Other (196) Polynapping (12) Programming (181) Racing Game (11) Reviews (126) Rocket Commander (50) Silverlight (14) SQL (2) StudiHelp.de (2) XNA (60)
Categories
Navigation
Archive
| July, 2009 (1) |
| June, 2009 (4) |
| May, 2009 (6) |
| April, 2009 (7) |
| March, 2009 (13) |
| February, 2009 (10) |
| November, 2008 (2) |
| October, 2008 (1) |
| September, 2008 (1) |
| May, 2008 (2) |
| April, 2008 (14) |
| March, 2008 (1) |
| February, 2008 (3) |
| January, 2008 (4) |
| December, 2007 (2) |
| November, 2007 (2) |
| September, 2007 (2) |
| August, 2007 (2) |
| July, 2007 (10) |
| June, 2007 (6) |
| May, 2007 (9) |
| April, 2007 (11) |
| March, 2007 (10) |
| February, 2007 (3) |
| January, 2007 (1) |
| December, 2006 (4) |
| November, 2006 (13) |
| October, 2006 (1) |
| August, 2006 (14) |
| July, 2006 (5) |
| June, 2006 (7) |
| May, 2006 (9) |
| April, 2006 (5) |
| March, 2006 (8) |
| February, 2006 (8) |
| January, 2006 (2) |
| December, 2005 (9) |
| November, 2005 (7) |
| October, 2005 (5) |
| September, 2005 (2) |
| August, 2005 (5) |
| July, 2005 (3) |
| May, 2005 (2) |
| January, 2005 (2) |
| December, 2004 (16) |
| November, 2004 (12) |
| October, 2004 (8) |
Popular
Blogroll
Projects
Arena Wars (2004)

Rocket Commander (2006)

Pizza Commander (2006)

Rocket Racer (2006)

Coop Commander (2006)

Flower Commander (2006)

Fruit Commander (2006)

Euro Vernichter (2003)

Lost Squadron (2005)

Zombie Quest (very simple 2D Adventure, 2006)

Freifunk Hannover project (GoogleMaps support)

Older projects (2000 and earlier)

MeinSport.de - German Sport Community Site

About
About me: Contact

Email: 
Total Posts: 276 This Year: 43 This Month: 1 This Week: 1 Comments: 457
|
Made with
 |
Disclaimer
The opinions expressed herein are my own personal opinions and do not represent
my employer's view in anyway.
| | 
Sign In
|
Wednesday, July 01, 2009 4:53:29 PM (GMT Standard Time, UTC+00:00) ( All | Development | Game Development | Other | Racing Game | Reviews | XNA )

Buyaa, I'm Microsoft MVP once again in the XNA/DirectX category for one more year (2009/2010). I have been an XNA MVP since 2006 and I'm still very proud of it :) I was pretty busy this year with our current game project "Fireburst" at exDream (a racing game for Xbox 360, PS3 and PC using the Unreal3 engine, more about it soon) and theirfore I did not do many other things (except writing some iPhone games, starting to develop my own dynamic language and some tools). But once that project is done in 1-2 months, I will do lots more XNA fun stuff and hopefully XNA Community Games (now called Indie Games on the Xbox 360, I really hate that term) will be available in Germany so I can finally review and submit some games myself. I'm still pretty fit in XNA 3.1 and DirectX 11 (played around with it a lot in March), but for XNA I'm still waiting for availablilty in Germany and for DirectX 11 I'm really waiting for some cool hardware at the end of this year. At exDream we recently also had some interesting discussions about using .NET for PS3 (recently possible thanks to Novell), Xbox 360 (hello XNA) and PC or even more dynamic script languages for upcoming projects. Maybe also including some other promising platforms such as iPhone (also .NET able thanks to Unity), Android, PSP Go, WII, whatever, but that all should depend more on the game and if we are able to manage so many platforms. Working with XNA was almost no extra work to make a game run on the Xbox 360 plus the PC, the game just has to fit and you obviously should allow control with the Xbox 360 controller. Our multiplatform game Fireburst is also not that bad to develop for because most issues are handled by the great Unreal3 engine (except the fact of course that it is all ugly C++ and UnrealScript code, which just looks like C++ anyway and even has to be compiled), but it is still quite a lot more work than just doing a PC only game, especially because of optimizations and testing required for all platforms. Enough rambling, I'm going to celebrate this day by installing Windows 2008 server (omg) because our pre-release version we had on there just ran out (warg) .. stupid thing has to be completely reinstalled, no upgrade option ..
Thursday, June 25, 2009 10:23:41 PM (GMT Standard Time, UTC+00:00) ( All | BroodWar | Fun | Other | Reviews )

For some time I had problems with StarCraft in Windows 7, after playing for 20-30min Windows 7 completely freezes keyboard, mouse and video (background programs and even Skype still work, but a hard reset was always the only way to get out of it). Since I was not playing much (just a few games a week) and it did not happen to me that much, I did not worry at first. But after starting to play ICCUP a few weeks ago with some friends, it just got annoying when I was crashing every 2-3 games. At first I was thinking maybe I overclocked way too much with my 4 Ghz, so I tried playing with normal 2.6 Ghz, but that did not make any difference. I also removed one of my graphic cards and tried playing on my primary screen instead of my third one. Nothing did help. It seems when closing all programs and making sure StarCraft only ran on one core (using the processor affinity setting in the task manager) the crashes occured less often, but I could not really fix this issue. In Windows 7 Beta I also had some crashes (but usually not blue screens or whole computer freezes) with some games and applications, e.g. some Half-Life2 games like Garry's Mod or Left 4 Dead crashed a few times for me, but with WIndows 7 RC this did not happen anymore. In fact other than testing my overclocking settings I never had any crash or bluescreen in Windows 7 RC except for playing StarCraft. After reading a bit on some forums ( TeamLiquid, Blizzard, random Boards on the Internet) I saw many other people having the exact same problem: Windows 7 RC x64 + StarCraft does not work well together. In fact any other 2D DirectX from that time (like Age Of Empires 2, Worms Armageddon, etc.) seems also to cause random crashes in Windows 7 RC, especially on a quad core system. Some people also had another issue with the 256 colors, the trick here was to keep the Screen Resolution dialog open in Windows and then start the game. Well, the solution is kinda retarded, but it seems to work (many people reported it and I did not have any problems since yesterday when I started using this trick): Kill the Explorer.exe process before starting StarCraft.exe and restart it only after closing StarCraft.exe again. Since I also wanted to use the ICCUP Launcher, I wrote a little cmd script for this job. I also had to disable some of my programs like WallRotate to prevent the 256 colors messing up in StarCraft every time my desktop changes. Here is the .cmd file I use for starting StarCraft via the ICCUP Launcher.exe plus all the additional tricks like waiting 2 seconds for the update check of Launcher.exe, killing WallRotate.exe (I commented it out, replace it with any other program you might want to close too) and Explorer.exe and restarting everything after closing StarCraft again. rem First start the ICCUP launcher (it won't work without Explorer.exe)
cmd.exe /C start C:\Games\Starcraft\Launcher.exe
rem Wait a bit for ICCUP Launchers update check! Use ping trick to wait 2 sec!
ping 127.0.0.1 -n 2
rem First kill Explorer.exe, which messes up our colors in StarCraft
taskkill /f /IM explorer.exe
rem Also kill our desktop changer, which messes up the colors in game
rem taskkill /f /IM WallRotate.exe
rem Change to the StarCraft directory to make sure we run normally!
cd C:\Games\Starcraft\
rem And launch StarCraft ourselfs since we can't see the ICCUP launcher without Explorer.exe
rem Please note that /affinity 1 makes sure we only use our first core
rem Using all cores for StarCraft.exe can lead to crashes in Windows 7 :(
cmd.exe /C start /affinity 1 C:\Games\Starcraft\StarCraft.exe
rem Some early tests:
rem C:\Games\Starcraft\StarCraft.exe
rem C:\Games\Starcraft\Launcher.exe
rem Wait for the game to quit, press Enter to continue
pause
rem Restart Explorer.exe and WallRotate, that's it!
start explorer.exe
rem start C:\code\WallRotate\bin\Release\WallRotate.exe
exit
Wednesday, June 24, 2009 6:00:40 PM (GMT Standard Time, UTC+00:00) ( All | Development | Fun | Game Development | Other | Programming | Reviews )
I want to quote from this great article I just read: Singletasking: The Next Trend in Web Working?"Singletasking is just what it sounds like: approaching and tackling
one task at a time, sequentially, instead of trying to do a whole bunch
of things at once, as has become de rigeur in our modern
multitasking age. If you’re like me, the thought is probably at least a
little refreshing, and maybe more than a little appealing right off the
bat. The principle is sound. Take on one task at a time, and don’t begin
another until the one you’ve already started is complete. It sounds
simple, but you know as well as I do that actually implementing that
kind of thing in real life will take a lot more effort than you might
first think. For one, it means ignoring any urge to procrastinate, and
making sure that you prioritize very carefully in advance, lest you
realize too late that what you thought was most urgent actually
could’ve taken a back seat to something else." The article goes on with tools used to track work tasks and even ideas on only use one Tab in Firefox and only using one monitor. I can hardly agree with that, I currently have 10 tabs open (after reading all emails and stuff on the web) because I don't have time right now to finish reading those sites or because some things are still pending (waiting for a response and keeping the tab open as a reminder). I also currently look at 3 monitors. Well not really, I only write this on my right monitor, but I have my main task (some optimization work) on my main screen in the center in Visual Studio. I really hate putting anything above Visual Studio because then I won't focus on writing code, but do other stuff instead. I only do it if I have to write some document, have to do some web research or reading some documentation. While I totally agree with doing (and finishing) one task at a time (that's actually how my TODO list works that I use in every single project for the last 6+ years), I just can't agree with just having one monitor (or just using one at a time like the writer of the article proposes). For example when opening an editor like for our Unreal3 game, you absolutely need 2+ monitors because else you just have 5 overlapping windows and spend half of your time moving them around trying to see whats behind them. In Visual Studio I only have the Solution Explorer sometimes and some Find Results or Console Windows on my secondary screen, but all the screens are filled with useful stuff anyway. I also have basically 2 screens at once at my primary screen anyway because I always look at 2 concurrent tabs in Visual Studio (really can't live without it). That does not mean that I really multitask. I ALWAYS only work on one tab, but I can quickly look over, see all the variables and methods that I need and I can code much faster that way. If you want to have some distractions when working I suggest only checking them out after completing a task. I usually do it as a reward kinda thing, like playing a game I wanted to test out only after I finished my current task. And then continue with the next task.
Tuesday, June 02, 2009 11:57:31 PM (GMT Standard Time, UTC+00:00) ( All | Development | Fun | Game Development | Other | Programming | Reviews )
Download link for CR_RandomBackgroundChanger now at CodePlex.
I used several tools over the years to change my background image automatically every few minutes. I even collected over 50k desktop images over the years ^^ While this is great and always fun to watch at changing backgrounds every few minutes, most of the time I do not even notice because all my screens are completely covered by windows.
As a programmer I have Visual Studio open most of the time, especially at work, where distractions like changing background images would have the biggest impact. Luckily Visual Studio has a boring white (or black for me) background and will not distract us that much. It would be terrible if Visual Studio would have changing background images that even make it harder to look at code and could be distracting having a background image changing every 5 minutes. Let's explore that!
First of all: How to even change or set a background image directly in the Visual Studio code window?
There is a great collection of gadgets from the SlickEdit guys, called Free SlickEdit Gadgets, which are completely free to use and include a feature to set a background image in the code editor. Searching for this on a search engine like Google isn't that easy, it is easier to find if you search for "Visual Studio Dancing Banana" :)
After you have installed the SlickEdit Gadgets (which currently only work on VS2005/VS2008, not on VS2010 yet), you should see a SlickEdit menu item. From there you can select Editor Gadgets, which just opens the Visual Studio Options dialog. There you can go to the Editor graphic tab and select a background image to be displayed in the editor. I use the following settings:
- Display an image: Checked
- Image textbox: The selected image
- Tile Radiobutton checked (use bottom left if you just want a small transparent image there, IMO not distracting enough!)
- Lock the image location checked
- Transparency checked and set to 75% (which means 25% visibility, 75% of your background color remains).
Now your code window might look like the following:
While this is kinda fun, it is not distracting enough yet. We need changing background images and preferably a way to quickly change the editor background image with a click at anytime in case it doesn't fit. First of all we need to find out where SlickEdit saves this background image. After searching for some SlickEdit setting file and not able to find any, I checked the registry and found this key:
HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\9.0\SlickEdit\EditorGadgets\ImageFilename
This is where the image name is saved. Just for fun I changed it to " C:\Users\Public\Pictures\Sample Pictures\Penguins.jpg", but obviously nothing happend because there was no reason for Visual Studio to reload and apply any new settings from the Options dialog. So how to we force that to happen?
Well, after trying to find some solution for that for a while, I gave up. There is no event I can trigger to update this and there is simply no functionality in the SlickEdit Gadgets to get this update working.
Since I would need to write something to set a new background image every few minutes anyway and this won't be easy or even impossible with my little Wallpaper Changer app I decided to write a VS addin myself. I started a new CodeRush plugin (which also runs on the free DXCore framework) and called it CR_RandomBackgroundChanger (a little bit too long for CodePlex, so there it is just called VSBackgroundChanger). Next I used the EditorPaint event and wrote the following code to display an image in the code editor: private void BackgroundChangerPlugIn_EditorPaint(EditorPaintEventArgs ea)
{
//Log.Write("BackgroundChangerPlugIn_EditorPaint");
//tst: ea.DrawLine(1, 1, 50, Color.Red);
if (currentBackgroundImage == null)
currentBackgroundImage = Bitmap.FromFile(
@"C:\Users\Public\Pictures\Sample Pictures\Desert.jpg");
ea.Graphics.DrawImage(backgroundImage, 0, 0);
} // BackgroundChangerPlugIn_EditorPaint(ea)
This produced terrible results. The image got displayed for a fraction of a second and then was replaced by the default background color. Using other events from the StandardPlugIn class in the CodeRush framework like EditorPaintBackground, EditorPaintForeground, EditorPaintLanguageElement, EditorvalidateClipRegion, etc. also did not help much, the background image was usually not displayed and even if it was flickering terribly and disappearing all the time.
So CodeRush was not very helpful in this particular instance, but no reason to give up. Actually I gave up that day after trying out so many things for many frustrating hours. The next day I tried something different: Use the NativeWindow class to intercept any event that is send to the Visual Studio code editor window (called View in CodeRush btw). Basically you derive from NativeWindow and then call the AssignHandle method to set the window handle (I just do it in the constructor). From then on you will get all WndProc events and you can decide whether to pass it on to the original WndProc or do something yourself.
public class ActiveViewBackgroundHelper : NativeWindow
{
#region Constructor
/// <summary>
/// Create active view background helper class, each document view
/// will get an instance of this class to handle the background drawing!
/// </summary>
public ActiveViewBackgroundHelper(IntPtr windowHandle)
{
base.AssignHandle(windowHandle);
} // ActiveViewBackgroundHelper(windowHandle)
#endregion
#region WndProc
/// <summary>
/// WndProc, we are only interested at the WM_PAINT event!
/// If a paint happens and we got a valid we will call DrawBackgroundImage
/// </summary>
/// <param name="m"></param>
protected override void WndProc(ref Message m)
{
// Your own code goes here
base.WndProc(ref m);
} // WndProc()
#endregion
} // class ActiveViewBackgroundHelper
Now I was able to intercept all WM_ERASEBKGND and WM_PAINT messages. WM_ERASEBKGND turned out to be non-relevant because all the rendering happens in WM_PAINT. Otherr events like WM_NCPAINT and all the code rush events happened between a single WM_PAINT event anyway. So I had to dig deeper into WM_PAINT. I could not render a background image at the very start of WM_PAINT and if I aborted rendered right there, it would be displayed in the editor. But there was no text anymore making VS just useless. I had to figure out how to render text on top of my image by copying all the VS editor content to a bitmap and then later drawing it on top of my background image. To make all the flickering go away by drawing into a targetBitmap and then displaying that at once to the window (everything else flickers). There is also a lot of other optimizations and tricks in there. We will get back to the code in a little bit.
After working on this for the better part of the last weekend, I finally got it working and put some extra features in this CR_RandomBackgroundChanger addin, which you can see in this nice option screen for it. Note that I have a black background in Visual Studio, if you have a white one the preview image would be white with black text and it would have 25% of the background image mixed in.
You can download the addin and the source code at http://vsbackgroundchanger.codeplex.com/
I'm trying out CodePlex for this addin. I will probably improve it a little in the future and upgrade it to VS2010. I will also put up other projects on CodePlex like CR_Commenter and maybe some of my XNA games. I also plan to work a little bit more on my language and then put it on CodePlex too when I got a alpha version working with all basic features.
In the option screen of CR_RandomBackgroundChanger you can specify 5 settings:
- Enabled: Whether to use this addin at all. This allows you to quickly disable the addin and keeping all your previous settings once you need more distractions again.
- Directory: All images in this directory and all images in all the sub directories will be used for displaying random background images in your Visual Studio code editor. Please note that searching for 100 000+ images can take a few seconds (I tested it with that many), but the subsequent VS startups and every background image change will be very fast because of all the caching involved. The disadvantage of all the caching is that if you add new images or even delete the whole images folder, you need to update this directory to get all those changes reflected by the addin by either deleting the cached ImageFilenames.txt in your %TEMP% directory or by just selecting the same directory again.
- Transparency (default: 25% opacity): This is the most important setting because having colorful background images at 100% opacity can often make the already colorful editor text unreadable. If you know that your background images have mostly the same color as your code background you can use higher settings (for example I used some black only images with some stuff on the right in the beginning, while this was cool at first, it got boring after a while because I'm used to changing background images every few minutes). If you have photos or other images that do not really fit to having text on top of them use even lower opacity settings (e.g. 10%) to make Visual Studio text easier to read. You can mostly still see the background image if your code window is big enough and you have some empty lines in there :)
- Change image every x seconds: Use this setting to allow the addin to change the background images every 5 minutes (or use whatever number of minutes you like). Note that using 0 minutes will result in constantly changing backgrounds while you are typing and scrolling, not really sure if this is useful, but was good for testing ^^
- And finally the last settings is to use different background images for different document windows. If you have 20 documents opened in Visual Studio, every one of them will get a different background image (which can then change every 5 minutes too). This even makes it easier to figure out where you are, I probably need to improve the Tab-Rendering too to make it more useful like the ColorfulTabs addin for Firefox. And this is of course great fun, usually I get annoyed by having too many documents open so I often close them all after I get 50, but now I really like having many different background images open.
The option screen also features the Preview box, which lets you see your selected background images and tweak the transparency setting until it looks right for you. Once you close the Options screen all settings will be applied to your VS code editor. Please note that this addin only works whenever a WM_PAINT event happens. This is usually only in the active document you are working on. Most of the time the background image will stay even if you change to another tab on the other side (if you use 2 tabs at once, else you will never notice this anyway). Sometimes you see some black or white background lines drawn on top of your background image because just some text was updated, but this happens very rarely. I hope you enjoy the addin, I will probably use it for a long time and I will port it to VS2010 once CodeRush runs there or I'm using VS2010 (still waiting for a working TestDriven.net version). Hopefully implementing this addin with the MEF (Managed Extensibility Framework) is not hard.
Let's go back to the code. Last time I stopped talking about the WndProc method, which is most important for catching and handling the WM_PAINT event. From here we can call our DrawBackgroundImage method, which does all the magic. Please note that the source code for the addin is a lot more complex than the code presented here. This is mostly because of heavy optimizations and a lot of caching to make the code run as fast as possible (one of the most important things about this addin, it would be unusable if it makes VS slow).
#region WndProc
/// <summary>
/// WndProc, we are only interested at the WM_PAINT event!
/// If a paint happens and we got a valid we will call DrawBackgroundImage
/// </summary>
/// <param name="m"></param>
protected override void WndProc(ref Message m)
{
// Just make sure we mark the erase background message as handled.
// Will not do anything anyway (all painting done in WM_PAINT).
if (m.Msg == (int)WindowsMessages.WM_ERASEBKGND)
{
// Mark event is already handled
m.Result = (IntPtr)1;
} // if
// Handle the paint event
if (m.Msg == (int)WindowsMessages.WM_PAINT &&
// Are we currently drawing our own background? Then make sure we do
// not handle this and use the default message handling instead!
drawingBackground == false &&
// Make sure we got a view, else we don't have a windows handle!
CodeRush.TextViews.Active != null &&
// Check for invalid hwnd, then we can't paint backgroundImage!
(int)CodeRush.TextViews.Active.Handle != 0)
{
TextView view = CodeRush.TextViews.Active;
IntPtr activeWindowHandle = view.Handle;
Rectangle rect = new Rectangle();
Win32.GetUpdateRect(activeWindowHandle, ref rect, false);
// Only proceed if we have a valid rect
if (Win32.IsRectEmpty(ref rect) == false)
{
// Make sure we mark this flag so subsequent calls to WM_PAINT
// will actually just paint the normal stuff, not just our
// background rendering!
drawingBackground = true;
DrawBackgroundImage(activeWindowHandle, rect);
drawingBackground = false;
// Mark event is already handled
m.Result = (IntPtr)1;
// Do not call base.WndProc, we don't want to process it here!
// Instead we invalidate inside DrawBackgroundImage and force
// a new WM_PAINT event inside there, which will be executed
// because drawingBackground is still true while in there.
return;
} // if (rect)
} // if (WM_PAINT)
base.WndProc(ref m);
} // WndProc()
#endregion
And finally the DrawBackgroundImage method, which copies the current editor text as an image, applies transparency to it. Then we draw our background image and the now transparent editor text on top into a helper targetBitmap, which is finally displayed on the screen at once (else we would get flickering issues). Please note that in the source code you can download there is a some testing code, e.g. for drawing bitmaps with transparency using ImageAttributes and SetColorMatrix, which works great, but is just too slow. Our approach is to pre-calculate the opacity in the backgroundImage and use that over and over again (3-4 times faster). There is still a performance penalty for all this painting, but any future optimizations will be hard. I recommend using 2 tabs, rendering is twice as fast (because only one side is updated when you type or scroll) and you should have a fast PC :) #region DrawBackgroundImage
/// <summary>
/// This method draws the background and is called from WndProc whenever
/// it intercepts a WM_PAINT message. Again, some caching and confusing
/// optimized code is in here too, again for getting good performance.
/// </summary>
private void DrawBackgroundImage(IntPtr activeWindowHandle,
Rectangle rect)
{
// Create an image for storing the orginal editor screen.
Bitmap sourceImage = new Bitmap(rect.Width, rect.Height);
// Always create new graphics object, else we won't have current data
Graphics sourceImageGraphics = Graphics.FromImage(sourceImage);
// And grab current editor window content and copy it to it!
IntPtr hdc = sourceImageGraphics.GetHdc();
Win32.PrintWindow(activeWindowHandle, hdc, 1);
sourceImageGraphics.ReleaseHdc(hdc);
// Next find the color on the bottom right and use it as the
// transparent color! Note: Antialasing will cause artifacts, make sure
// the backgroundImage fits to the background color, e.g. by using a
// lot of alpha transparency (<25% visibility)!
backgroundColorPixel =
sourceImage.GetPixel(rect.Width - 1, rect.Height - 1);
sourceImage.MakeTransparent(backgroundColorPixel);
// Create target image where we wanna paint to, this is important
// because drawing directly to the VS window will produce flickering!
Bitmap targetBitmap = new Bitmap(rect.Width, rect.Height);
Graphics targetBitmapGraphics = Graphics.FromImage(targetBitmap);
// Clear background with pixel color
//not required, we draw solid image now (use this for transparent drawing):
//targetBitmapGraphics.Clear(backgroundColorPixel);
// Draw background image (tiled and transparent if specified)
float transparency = Options.transparency / 100.0f;
Image backgroundImage = GetBackgroundImage((int)activeWindowHandle,
backgroundColorPixel, transparency);
// Do the drawing as many times as we need to tile to fill everything!
for (int y = 0; y < rect.Height; y+=backgroundImage.Height)
for (int x = 0; x < rect.Width; x += backgroundImage.Width)
{
targetBitmapGraphics.DrawImage(backgroundImage, x, y);
} // for for
// Now draw source image on top (text and foreground stuff), else we
// would only see our distracting background image and while that is
// fun, we sometimes still need to be productive and see the editor
// text ^^
targetBitmapGraphics.DrawImage(sourceImage, 0, 0);
// Finally draw on the VS window, but only do one single draw here
// to make sure we do not have any flickering!
Graphics graphics = Graphics.FromHwnd(activeWindowHandle);
graphics.DrawImage(targetBitmap, 0, 0);
// This is important: Validate the rect so all this can now be
// displayed! All WM_PAINT calls during this method will
// be handled normally (without our background painting), which is
// used for normal updates because we mess everything up ^^
Win32.ValidateRect(activeWindowHandle, ref rect);
// Dispose everything we do not need anymore
// Note: We always have to create new graphics and dispose them here,
// else updating sourceImage, targetBitmap, etc. does not work!
if (graphics != null)
graphics.Dispose();
if (sourceImageGraphics != null)
sourceImageGraphics.Dispose();
if (targetBitmapGraphics != null)
targetBitmapGraphics.Dispose();
} // DrawBackgroundImage(activeWindowHandle, rect)
#endregion
For more information check out the source code, the important code for the addin is in ActiveViewBackgroundHelper.cs and the Options and PlugIn classes. The rest of the classes are just helpers for logging, string operations, random methods and Win32 helpers for some calls.
Download this addin at http://vsbackgroundchanger.codeplex.com/
I hope you will enjoy this addin. Here are 2 more screens from using this addin with different background colors and images: White background theme (25% opacity):
 Black background theme (25% opacity):

Tuesday, May 26, 2009 11:28:45 PM (GMT Standard Time, UTC+00:00) ( All | Development | Fun | Game Development | Other | Programming | Reviews )

Last week when I installed VS2010 I played around with it for a few minutes, but I've been very busy at work because our game is at its final stage and we got a lot of heat going on (this is not a hint, no no, no hint from me, I'm not allowed to talk about it. Damn it, this could be a hint).
Currently the most interesting new feature besides the cool VS2010 IDE is the Parallel Extensions for me. Sadly the IDE still unusable for real work IMO because all the addins just don't work, there isn't even a fix for TestDriven.net yet, Jamie Cansdale is probably busy too ^^
VS2010 support for parallel programming goes beyond just adding a few extra classes in .NET 4.0: You also got a great IDE implementation which lots of useful features and new tool debugging and profiling windows for checking out parallel tasks, threads and the scheduling. Next there are native C++ libraries that work with Parallel Extensions too (using lambda functions) and work good together with STL. You can check out all the new features at the official VS2010 page!
Let's take a quick look on how to use these Parallel Extensions. I wrote this in a few minutes last week, I was just too lazy (I mean busy of course) to post it yet, it is obviously very simple stuff, but was still useful to test out some of the new parallel IDE features and check out some new .NET 4.0 classes. First of all let's do a boring foreach loop, which displays numbers from 0 to 9, which get added to expectedTotalNum. This should obviously be 45 because sum(0..9)=45. Later we will do some parallel foreach adding and check if we got the same result. Since it does not matter in which order we add these numbers, it is also a good test to just start a bunch of parallel tasks and let them do their work. Obviously you would never write parallel code just to add some numbers, but this should illustrate the point and it does not hurt your performance much anyway (as long as you have a few lines of code executing that take more than a few instructions). // Initialize a list for some parallel testing :) List<int> someInts = new List<int>(); for (int num = 0; num < 10; num++) someInts.Add(num);
// Print out numbers sequentially int expectedTotalNum = 0; foreach (int num in someInts) { Console.WriteLine("sequential num=" + num); expectedTotalNum += num; }
Console.WriteLine("expectedTotalNum=" + expectedTotalNum);
This outputs the obvious sequential adding of 0 to 9 to expectedTotalNum, which is 45 at the end of the loop: sequential num=0
sequential num=1
sequential num=2
sequential num=3
sequential num=4
sequential num=5
sequential num=6
sequential num=7
sequential num=8
sequential num=9
expectedTotalNum=45 Now let's do the same in parallel, just by replacing foreach with Parallel.ForEach: // And do it with the new Parallel Programming classes in .NET 4
int totalNum = 0;
System.Threading.Parallel.ForEach(someInts, num =>
{
Console.WriteLine("parallel num=" + num);
totalNum += num;
});
Console.WriteLine("totalNum=" + totalNum);While the result is still the same because totalNum is 45 at the end of this loop, we get there in a different way. As you can see this is a little bit confusing at first because the adding does not happen sequentially anymore, but in parallel instead. Also note that this output can change when you execute it again and can even be much different on different platforms with different number of CPUs: parallel num=0
parallel num=2
parallel num=5
parallel num=7
parallel num=8
parallel num=9
parallel num=6
parallel num=3
parallel num=4
parallel num=1
totalNum=45 Okay, good stuff so far, but you might not always have a foreach loop and you might not want to wait for it to complete anyway. Maybe you just have some work tasks that need to be executed, no matter in what order and you might not even care if they complete their work right away or in a little bit. A method could just add some work that has to be done and then return while the work tasks are executed in the background. This is when you would have used the Thread or ThreadPool classes in the past, which are great on their own, but you always have some setup code and it was hard to test and you could not use them all over the place because setting up threads is a costly operation and if your work is just few lines of code, it was always a better idea to execute it right away. But fear no more, now you can just create new tasks with the new Task class in the System.Threading namespace. This is a much easier job and has many advantages because .NET 4.0 handles all the thread creation for you, will reuse threads once they are completed with their task and all this works in a very performant way. Setting up tasks is a little bit more work than just executing Parallel.ForEach, but it allows much greater flexibility and you can add more tasks from whereever you are. Tasks can even have children and you can have a lot of complex code using all these tasks. Testing multi-threaded code is obviously harder than just writing sequential code, but with all the great additions to the IDE, it is now easier than ever with the new Parallel Tasks window and by checking out the Parallel Stacks, which shows you all the running threads and were all the task code is. The following code will create 10 tasks and do the same thing as above, but with several additions. To be able to wait for all the tasks to finish we will add all 10 tasks to the allTasks list. We also have to make sure that our local foreach variable does not change while we are executing tasks because the foreach loop will quickly create all tasks, but might not execute them right away theirfore using num can cause problems. Instead we just create a local copy of num and use that instead, which can't change because we never increase it like we do with num. Finally we add some boring thread sleeping to make it easier to debug this code and check out whats going on by adding breakpoints. Without the sleep the code still works, but checking out the Parallel Tasks and Parallel Stacks windows will most likely give us no results or only the last few tasks that are still being executed at the end of the foreach loop because the tasks are so simple and executed very quickly. We even wait a little after the foreach to make sure all the tasks have been added and are being executed right now or are scheduled (waiting for execution). // And finally some tasks, yeah!
totalNum = 0;
var allTasks = new List<Task>();
foreach (int num in someInts)
{
// We need a local variable for num because num itself can change
// at the end of this loop before the task might even be executed!
int numToBeAdded = num;
allTasks.Add(Task.Factory.StartNew(delegate
{
totalNum += numToBeAdded;
Console.WriteLine("Adding " + numToBeAdded + " in task with id=" + Task.Current.Id);
// Wait a little for checking out the tasks in the new Tasks window in VS2010!
Thread.Sleep(1000);
}));
} // foreach
Console.WriteLine("Done with foreach loop. Tasks might still be pending");
// Wait a little for all tasks to start
Thread.Sleep(100);
Task.WaitAll(allTasks.ToArray());
// And finally return the result (45 again if everything worked)
Console.WriteLine("totalNum=" + totalNum);First of all the results again, which is 45 again. This only work with numToBeAdded, if you use num instead it will sometimes give you different results because at the time you execute a task num already might have changed, especially if you have more tasks than CPUs used for execution and time consuming code like Console.Writeline or even a Thread.Sleep is in there! Adding 1 in task with id=1
Adding 7 in task with id=6
Adding 8 in task with id=7
Adding 6 in task with id=5
Adding 4 in task with id=3
Adding 3 in task with id=4
Done with foreach loop. Tasks might still be pending
Adding 9 in task with id=8
Adding 0 in task with id=10
Adding 5 in task with id=2
Adding 2 in task with id=9
totalNum=45 As you can see this even looks more confusing than the way Parallel.ForEach added those numbers because while we might create those tasks sequentially (number 1-10) it does not mean there are also executed in exactly that way. To make it easier to check these things out there is the Parallel Tasks window, which shows the following after starting all 10 tasks by adding a breakpoint after Thread.Sleep(100) just before we wait for all tasks to complete:  Not only do we see all over our 10 tasks here, we also see right away that 8 of them are currently being executed (because I have 8 CPUs with my hyper-threaded i7) and all of them are waiting because of our stupid Thread.Sleep(1000) we added for each of those tasks. A second later those tasks are done and the last 2 are also executed, most likely with 2 thread ids already created earlier. You can click on each task and see where it is currently executing in the source code and you can also check out all the thread information in the normal Threads window. But even more useful than the Parallel Tasks window is the Parallel Stacks, which shows how all this code is related, which task or thread created which new task and so on:  All good stuff. While I already have some ideas how to use this on some of my current projects, I have not ported anything to .NET 4.0 / VS2010 yet because of the many issues I have with the IDE (no addins, color theme not really working, I always have to reset it when starting VS2010, also I don't like that the project and solution formats have changed so I cannot easily switch back to VS2008, etc.). But hopefully more and more addins will work for VS2010 and some of the issues are fixed, then it will be great to use all this new .NET 4.0 stuff (dynamics, parallel extensions, MEF, etc.).
Monday, May 18, 2009 11:39:33 PM (GMT Standard Time, UTC+00:00) ( All | Development | Game Development | Other | Reviews )
 VS2010 beta came out a few hours ago, installing it took way too long (over an hour, VS2008 takes less than 10 min for me) and it seems some addins don't install or just don't work, but other than that everything else seems to work great: - TestDriven.NET provides an VS2010 option and it will appear in Addins, but the Menu Items will not appear anywhere. Just use keyboard shortcuts and everything still works :) .. at least it worked for a short while (see below). Hopefully Jamie Cansdale fixes this soon because without TestDriven.NET I can't really use VS2010 right now. MS provides its own unit testing framework, which is implemented into VS2010 and even available in the Pro edition now (was only in more advanced versions before), but I still don't like it. It does not output anything to the console except exceptions; it is not possible to just start some Ad-Hoc unit test and for all my functional tests it is also useless. For just "normal" unit test projects VS test integration is quite ok, but I would suggest trying out NUnit or xUnit together with TestDriven.NET, which is just more flexible, easier to use and improves productivity IMO.
- Completely unable to install any CodeRush version (neither 2, 3, 9.1, Xpress), so I'm also unable to use my CR_Commenter :( hopefully DevExpress provides a version soon, they always were very quick with early VS2005 and VS2008 support!
- Most other addins I tried also did not install or just do not appear anywhere (only in VS2008)
- One of my own addins I wrote 2 years ago for VS2008 also does not appear, it probably needs to be configured to appear in the VisualStudio/10 reg key!
Most annoying: - Even though Rico Mariani (the .NET performance god) is helping out the VS team to give VS2010 better performance, it currently lags all over the place. I had 10 second delays in Options, Add References and Renaming dialogs already. Seems to be always an issue with opening up stuff for the first time. After a while everything seems to be fast, but I would not say this is faster than VS2008 yet.
- Only tried this at my home PC till now, but everytime I close VS2010 I cannot open it up again until I restart (or at least log off/log on) again, which is REALLY annoying. I will just keep VS2010 open now all the time and hope it never crashes ^^ The start splash-screen is also messed up and completely black. Maybe this is only on my home PC because I tried to install so many addins, will try this tomorrow at work too.
Update 2009-05-18: I just found out what was causing this. Some addins tried to load, but failed for some reasons and then the addin loading code locks up or whatever and VS never finishes starting up (the process devenv.exe is still there, but you just don't see any IDE window, they are never created). It seems to be related to the TestDriven.NET-2.21.2448 version, I also tried TestDriven.NET-2.20.2438 - same problem :( (Jamie Cansdale, the creator of TestDriven.NET was also recently blogging about this). Then I used , which also already has VS2010 support and that seems to work fine (no menus, but keyboard shortcuts work fine). I posted more details on Jamie's blog!
Every project I have opened, had to be converted to the new VS 10 format, which is kinda stupid because it seems nothing has changed. All the code works just fine and no changes were required. I will start using some .NET 4.0 features and test out stuff in the next days, especially using Parallel Programming and MEF (Managed Extensibility Framework). Probably will play around with the C# 4.0 dynamic keyword a bit also, but can't think of anything yet where I would really need it. Maybe to talk easier to IronPython or my own DLR language .. Cool features: - Start page is pretty good, easily customizable, but I will probably never see it as I setup my VS to always load the last solution (like my Firefox ^^)
- It is easy to drag tabs around and move them to different screens. Finally I can use some multi-monitoring.
- Old exported VS2008 settings also work just fine in VS2010, even coloring :) For some strange reason the background color is always white when I start VS2010 for the first time, then after going to options and closing it, it will be the correct color (black for me).
- Overall the IDE is very nice and fits perfectly into my color theme. Its also a lot easier to see whats going on, which tab is selected and positioning tool windows all over the place is better than ever before.
Go check out VS2010 yourself, available on MSDN right now and on MS site on Wednesday for everyone else.
Monday, May 18, 2009 2:31:59 PM (GMT Standard Time, UTC+00:00) ( All | Development | Fun | Game Development | Other | Programming | Reviews )
 While I'm waiting for VS2010 beta today (refreshing blogs and MSDN every few minutes :D), I just found out that you can have your Visual Studio Tabs be automatically ordered by adding the following registry key in HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\9.0: - UseMRUDocOrdering: 1 (DWORD)
Now when you select any tab in Visual Studio it will automatically move to the very front thus keeping your recent documents at the start. It is kinda weird at first, but it seems to be a very useful feature. I like it already :)  In case you don't want to create the registry key yourself and want me to help you out modifying your registry (always a safe idea), just execute this file to do the job:
PS: Since my brother is running a TOR exit node server Google does not like when I do searches anymore because it thinks I search too much stuff now and might be infected with viruses and trojans (yeah, sure ..). I could use Google Custom Search sites like Blackle.com, which return the exact same results as Google, but for now I'm trying out Yahoo once again (was using it a lot almost 15 years ago, when there was no Google). Sometimes Yahoo is stupid and does not give good answers, e.g. searching for "year yahoo was launched" gives you random answers on Yahoo, but google returns the Yahoo Questions link with the correct answer as the first result, wtf?
However, most of the time you do not get stupid SEO optimized search results and totally messed up product searches you get when using Google or Live Search. As an Microsoft MVP I also get asked a lot why I would not use Live Search and Microsoft is constantly trying to get more people (and MVPs) using Live Search, but the results are very close to Google most of the time anyway and the interface is just strange if you are used to Google for 10 years (the English Live Search is actually nice with a new image every day, but the German version is totally messed up, just white boxes??). Yahoo at least gives different results, which are sometimes better, sometimes worse .. Maybe we all should switch search engines from time to time, its really stupid Google has 95% market share here in Germany almost and it returns so crappy results so often (finding drivers has become 10 times as hard in the last years, searching files or torrents is impossible, because you only get SEO sites, no real results, product searches are totally messed up, Google groups is not used much anymore, etc.). Okay, enough ranting about search engines .. time to refresh MSDN again.
Thursday, May 14, 2009 2:17:28 PM (GMT Standard Time, UTC+00:00) ( All | Development | Fun | Other | Programming )
Visual Studio 2010 beta is apparently coming soon. Since I used VS2005 beta and VS2008 beta when they came out, I will be an early adopter once again. I really want to use the cool Parallel APIs in VS2010 and C# 4.0 dynamic stuff :)
Another topic: I try to synchronize several of my servers at different locations every day. This way it does not matter where I download or create a file, I still can use it the next day wherever I am (home, work, different work ^^). I use SyncBackSE for that job, great tool, but the problem with it is that on slow internet connections (e.g. slow DSL at work right now) it takes forever to even scan the directories. Its about 30000 directories that have to be synchronized and this takes a lot of hours, especially if the internet connection is already doing something else. Obviously uploading and downloading a few GB can also take a lot of time, but in 95% of the cases nothing or just a few MB change every day.
Because searching sub directories is so slow I tried to make it faster by removing directories when not necessary (just compressing 100 directories into a zip file, removing empty directories or old files, etc.). But this is obviously a lot of work for this many directories and I can easily overlook that in sub directory 3592 there is 1500 empty folders of some crap from some years ago no one will ever need again. For this reason I quickly wrote this little tool called KillEmptyDirectories, you can see a picture on the right! It only took me an hour to write, so there is no rocket science here and it is very straight forward. I did not even unit test it, I just tested it by executing on several directories. It also can remove hidden and read-only files by changing the file attributes (otherwise File.Delete will always throw UnauthorizedAccessException). I tested it on around 30000 directories and was able to kill around 8000 of those (deleting a lot of old stuff) ^^ with some additional compression of unused older directories I was able to get it down to around 3000 directories (from 30000), so the scanning process is now about 10 times faster.
If you want to try it out, you can download it here. But use with care, you can obviously kill directories with it and by using the "Always kill these directories" options you can even delete directories with files in it. An extra confirmation message will appear if you try to use that feature.
And this is the main function that does all the directory killing:
/// <summary>
/// Recursively kill directories, will be called as many times as we have
/// sub directories (can be many thousand times). Will always go through
/// all subdirectories first in case we can remove them, which makes it
/// much easier to delete directories with just empty sub directories.
/// </summary>
private int RecursivelyKillDirectories(string directory,
string[] includeFiles, string[] alwaysKillDirectories,
bool alwaysKillThisDirectory)
{
int directoriesKilled = 0;
string[] subDirectories = Directory.GetDirectories(directory);
// Only delete this directory if there are no useful files in here!
// Note: GetFileName will give us the last part of the directory!
if (alwaysKillDirectories.Contains(Path.GetFileName(directory)))
alwaysKillThisDirectory = true;
// Handle subdirectories always first (maybe we can kill them too)
foreach (string subDir in subDirectories)
directoriesKilled += RecursivelyKillDirectories(subDir, includeFiles,
alwaysKillDirectories, alwaysKillThisDirectory);
// Get all files here and count how many of those we can ignore
string[] files = Directory.GetFiles(directory);
int ignoreFileCount = 0;
foreach (string file in files)
if (includeFiles.Contains(Path.GetFileName(file)))
ignoreFileCount++;
// Only found ignored files (or no files at all) or do we want to kill
// this directory anyway?
if (files.Length == ignoreFileCount ||
alwaysKillThisDirectory)
{
// Check again if we don't have any sub directories left here
// Maybe the subdirectories above were already killed now!
subDirectories = Directory.GetDirectories(directory);
if (subDirectories.Length == 0 ||
alwaysKillThisDirectory)
{
try
{
// Kill all files in it (only ignored files anyway)
foreach (string file in files)
{
// Make sure we can delete hidden and readonly files
FileAttributes attributes = File.GetAttributes(file);
if ((attributes & FileAttributes.ReadOnly) != 0 ||
(attributes & FileAttributes.Hidden) != 0)
File.SetAttributes(file, FileAttributes.Normal);
File.Delete(file);
} // foreach
Directory.Delete(directory);
// We killed something, yeah
directoriesKilled++;
} // try
catch (Exception ex)
{
MessageBox.Show("Failed to delete " + directory + ": " +
ex.ToString());
} // catch
} // if
} // if
// Most of the time nothing was killed
return directoriesKilled;
} // RecursivelyKillDirectories(directory, includeFiles)
|
|