For a few weeks I have been having problems running Silverlight on my machine, especially since I had SL3 installed and also Expression Blend, version 3. I didn't mind much, because I don't need Silverlight most of the time. But since sometimes I do, here is the solution for the "Your Silverlight developer components are out of date" error when trying to install Silverlight.
Go to http://go.microsoft.com/?linkid=9394666 and install the Silverlight tools. Yes, they are version 2. No, I don't know why Silverlight 3 would have problems because of version 2 Silverlight tools. However, installing the tools solved my problem.
Thursday, November 12, 2009
Your Silverlight developer components are out of date
0
comments
Posted by
Siderite
at
10:33
0
comments
Links to this post
related
Labels:
misc,
software,
WPF/Silverlight
The post was:
Thursday, November 05, 2009
Use CSS expression to initialize html elements
0
comments
Internet Explorer added something called expression to CSS, something purists have booed at for mingling javascript and CSS. Well, boo back! I happen to like stuff that can solve problems. If I were at Microsoft I would create an entire subset of javascript and css functionality. But hey, that's just me.
Anyway, I have decided to use expression to run an initialize function on newly created elements. It would work like this:
initialize:expression(window.initializeElement?initializeElement(this):null);This CSS bit tells Internet Explorer (and none of the other browsers) that the initialize style property should get the value of the initializeElement function every time the browser refreshes the layout of the element. In the function itself I would do something like this:
function initializeElement(elem) {
if (!elem.style.initialize) {
doSomethingWith(elem);
}
return true;
}This basically executes doSomethingWith on each element matched by the CSS rule and only once.Good theory, but in practice it was terribly slow and, after a while, it managed to kill Internet Explorer with a strange System.AccessViolationException: Attempted to read or write protected memory error.
What happened? The slowness, I gathered after a while, was caused by the function doSomethingWith because it changed the style of the element. That meant that the css rule was being applied again before the function ended and returned true. Changing things to:
function initializeElement(elem) {
if (!elem.style.initialize) {
elem.style.initialize=true;
doSomethingWith(elem);
}
return true;
} fixed it.The error that killed Internet Explorer was even stranger. After a while I narrowed it down to using jQuery. I have no idea what it did, probably trying to access computedStyle or something like that. The thing is that changing an $(elem).height() with elem.offsetHeight solved it.
Posted by
Siderite
at
14:02
0
comments
Links to this post
related
Labels:
javascript,
programming,
web design
The post was:
Wednesday, November 04, 2009
Get Visual Studio to use (better) more than 2GB of memory
2
comments
I actually didn't know that a 32bit program could not use more than 2Gb of virtual memory by default. It makes sense, now that I think of it, but I just didn't make the connection. My office computer has 3Gb of memory and there is also the swap file, so having a program using more than 2GB of memory would be beneficial. And I am talking about Visual Studio here, especially since today I got an error I've never seen before: "Not enough storage is available to complete this operation".
So I've stumbled upon this article: Hacking Visual Studio to Use More Than 2Gigabytes of Memory which told me how to convince Visual Studio to use more than 2GB of memory. Also, since I am a ReSharper user, I found this little wrapper for Visual Studio that makes it use a different memory allocation method that reduces memory fragmentation: OutOfMemoryException Fix.
Short story shorter (for XP users with Visual Studio 2008 only - read the full articles for other configuration):
- Edit boot.ini to have the /3GB option
- Use editbin /LARGEADDRESSAWARE devenv.exe to change Visual Studio to have IMAGE_FILE_LARGE_ADDRESS_AWARE in the process header (editbin can be found in \Program Files\Microsoft Visual Studio 9.0\VC\bin\
- Download the Jetbrains devenv wrappers and change the signature of the Visual Studio shortcut to point to devenv2008_wrap.exe instead of devenv.exe
- (of course) Restart the computer
Update:
Thanks to the warnings from Lex Li, I went to study the /3G switch some more. The most important thing seems to be to also use the /USERVA switch to tune the /3G functionality.
More details here:
Memory Management - Demystifying /3GB
Summary of the recent spate of /3GB articles.
Posted by
Siderite
at
13:12
2
comments
Links to this post
related
Labels:
programming,
Visual Studio
The post was:
Monday, November 02, 2009
Things I've learned from HotBabe.NET
0
comments

Today I've released version 1.2 of the HotBabe.NET application. It is a program that stays in the traybar, showing a transparent picture, originally of a woman, sitting on top of your other applications. Clicks go through the image and the opacity of the picture is set so that it doesn't bother the use of the computer. When the CPU use or the memory use or other custom measurements change, the image changes as well. The original would show a girl getting naked as the use of CPU went up. Since I couldn't use what images it should use, I did my own program in .NET. This blog post is about what I have learned about Windows Forms while creating this application.
Step 1: Making the form transparent
Making a Windows Form transparent is not as simple as setting the background transparent. It needs to have:
- FormBorderStyle = FormBorderStyle.None
- AllowTransparency = true
- TransparencyKey = BackColor
Step 2: Making the form stay on top all other windows
That is relatively easy. Set TopMost = true. You have to set it to true the first time, during load, otherwise you won't be able to set it later on. I don't know why, it just happened.
Update: I noticed that, even when TopMost was set, the image would vanish beneath other windows. I've doubled the property with setting WS_EX_TopMost on the params ExStyle (see step 4).
Step 3: Show the application icon in the traybar and hide the taskbar
Hiding the taskbar is as easy as ShowInTaskbar = false and putting a notification icon in the traybar is simple as well:
_icon = new NotifyIcon(new Container())Set the ContextMenu to _icon and you have a tray icon with a menu. There is a catch, though. A NotifyIcon control needs an Icon, an image of a certain format. My solution was, instead of bundling an icon especially for this, to convert the main girl image into an icon, so I used this code.
{
Visible = true
};
Step 4: Hide the application from Alt-Tab, make it not get focus and make it so that the mouse clicks through
In order to do that, something must be done at the PInvoke level, in other words, using unsafe system libraries. At first I found out that I need to change a flag value which can be read and written to using GetWindowLong and SetWindowLong from user32.dll. I needed to set the window style with the following attributes:
WS_EX_Layered (Windows Xp/2000+ layered window)
WS_EX_Transparent (Allows the windows to be transparent to the mouse)
WS_EX_ToolWindow (declares the window as a tool window, therefore it does not appear in the Alt-Tab application list)
WS_EX_NoActivate (Windows 2000/XP: A top-level window created with this style does not become the foreground window when the user clicks it).
Then I found out that Form has a virtual method called CreateParams giving me access to the style flag value. Here is the complete code:
protected override CreateParams CreateParams
{
get
{
CreateParams ws = base.CreateParams;
if (ClickThrough)
{
ws.ExStyle |= UnsafeNativeMethods.WS_EX_Layered;
ws.ExStyle |= UnsafeNativeMethods.WS_EX_Transparent;
}
// do not show in Alt-tab
ws.ExStyle |= UnsafeNativeMethods.WS_EX_ToolWindow;
// do not make foreground window
ws.ExStyle |= UnsafeNativeMethods.WS_EX_NoActivate;
return ws;
}
}
However, the problem was that if I changed ClickThrough, it didn't seem to do anything. It was set once and that was it. I noticed that changing Opacity would also set the click through style, so I Reflector-ed the System.Windows.Forms.dll and looked in the source of Opacity. Something called UpdateStyles was used (This method calls the CreateParams method to get the styles to apply) so I used it.
Update: Apparently, the no activate behaviour can also be set by overriding ShowWithoutActivation and returning true. I've set it, too, just to be sure.
Step 5: Now that the form is transparent and has no border or control box, I can't move the window around. I need to make it draggable from anywhere
There is no escape from native methods this time:
Both ReleaseCapture and SendMessage are user32.dll functions. What this mouse down event handler does is say to the Window that no matter where it was clicked, it actually clicked the draggable area.
private void mainMouseDown(object sender, MouseEventArgs e)
{
// Draggable from anywhere
if (e.Button == MouseButtons.Left)
{
UnsafeNativeMethods.ReleaseCapture();
UnsafeNativeMethods.SendMessage(Handle,
UnsafeNativeMethods.WM_NCLBUTTONDOWN,
UnsafeNativeMethods.HT_CAPTION, 0);
}
}
Step 6: Remove flicker
Well, I am getting a bit ahead of myself, here, the flickering becomes annoying only when I implement the blending of an image into another, but since it is also a style setting, I am putting it here:
This piece of code, placed in the Form constructor, tells the form to use a double buffer for drawing and to not clear the form before drawing something else.
SetStyle(ControlStyles.AllPaintingInWmPaint
| ControlStyles.UserPaint
| ControlStyles.OptimizedDoubleBuffer, true);
Update: It seems the same thing can be achieved by setting the Control property DoubleBuffer to true as it seems to be setting ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint and ControlStyles.UserPaint seems to be set by default.
Step 7: Blend the images one into the other
Well, in order to make an image blend nicely into the next, I used a Timer. 10 times a second I would decrease the opacity of the first, increase the opacity of the second and draw them one over the other.
A small detour: if you think about it, this is not absolutely correct. A 70% opacity pixel blocks 70% of the light and lets 30% of the image behind show. If the image underneath has 30% opacity, then it shows 30% left from 30% of the image and it doesn't get opaque. But if I just set the opacity of the bakground image to 100%, it shows really strong on the parts of the images that are not overlapping, where image1 is transparent and image2 is not.
Unfortunately there is no resource friendly way to read write/pixels. It's either GetPixel/SetPixel in a Bitmap class (which are very slow) or using pinvoke again. I prefered to use the opacity hack which looks ok.
I was already using an extension method to invoke any change on the form on its own thread (as the Timer ran on its own thread and I would have gotten the "Cross-thread operation not valid: Control [...] accessed from a thread other than the thread it was created on" exception or "Invoke or BeginInvoke cannot be called on a control until the window handle has been created"):
public static void SafeInvoke(this Control control, Action action)
{
if (control.IsDisposed)
{
return;
}
if (!control.IsHandleCreated)
{
try
{
action();
}
catch (InvalidOperationException ex)
{
}
return;
}
if (control.InvokeRequired)
{
control.BeginInvoke(action);
}
else
{
action();
}
}
This is where I got the "Object is currently in use elsewhere" InvalidOperationException. Apparently the Image class is not thread-safe, so both the timer and the form were trying to access it. I tried locking the setter and getter of the Image property on the class responsible with the image blending effect, with no real effect. Strangely enough, the only solution was to Clone the image when I move it around. I am still looking for a solution that makes sense!
Step 8: Showing the window while dragging it
Using WS_EX_NOACTIVATE was great, but there is a minor inconvenience when trying to move the form around. Not only that the image is not shown while moving the form (On my computer it is set to not show the window contents while dragging it), but the rectangular hint that normally shows is not displayed either. The only way to know where your image ended up was to release the mouse button.
It appears that fixing this is not so easy as it seems. One needs to override WndProc and handle the WM_MOVING message. While handling it, a manual redraw of the form must be initiated via the user32.dll SetWindowPos method.
The nice part is that in this method you can actually specify how you want the form draw. I have chosen SWP_NoActivate, SWP_ShowWindow and SWP_NoSendChanging as flags, where NoActivate is similar with the exstyle flag, ShowWindow shows the entire form (not only the rectangle hint) and NoSendChanging seems to improve the movement smoothness.
Quirky enough, if I start the application without Click through set, then the rectangle hint DOES appear while dragging the window. And with my fix, both the image and the rectangle are shown, but not at the same time. It is a funny effect I don't know how to fix and I thought it was strange enough to not bother me: the rectangle is trying to keep up with the hot babe and never catches on :)
Step 9: Dragging custom images
I am a programmer, that means that it is likely to add too many features in my creations and never make any money out of them. That's why I've decided to add a new feature to HotBabe.NET: droppping your own images on it to display over your applications.
At first I have solved this via ExStyle, where a flag tells Windows the form accepts files dragged over it. A WndProc override handling the WM_DROPFILES message would do the rest. But then I've learned that Windows Forms have their own mechanism for handling file drops.
Here are the steps. First set AllowDrop to true. Then handle the DragEnter and DragDrop events. In my implementation I am checking that only one file is being dropped and that the file itself can be converted into an image BEFORE I display the mouse cursor hint telling the user a drop is allowed. That pretty much makes the ugly MessageBox that I was showing in the previous implementation unnecessary.
The rest are details and you can download the source of HotBabe.NET and see the exact implementation. Please let me know what you think and of any improvement you can imagine.
Posted by
Siderite
at
16:30
0
comments
Links to this post
related
Labels:
.NET,
C#,
essay,
programming,
software,
Windows API,
Windows Forms
The post was:
Monday, October 26, 2009
HotBabe.NET a new project at CodePlex
0
comments
I've stumbled upon this Windows port of a Linux application called HotBabe. What it does is show a transparent image of a girl over your applications that looks more naked as the CPU is used more. I wanted to use my own pictures and explore some of the concepts of desktop programming that are still a bit new to me, so I rewrote it from scratch.
The project is now up on CodePlex and is functional. Please report any bugs or write any feature requests here or on the project page in order to make this even cooler.
Features:
- Custom images responding to custom measurements
- Custom measures (included are Cpu, Memory and Random, but an abstract class for custom monitor classes is included)
- AutoRun, ClickThrough, Opacity control
- Interface for custom images and custom monitors
- XML config file
Additional remarks: yeah, I know, the advanced settings form is really bad, but I am not one for good interface design. Please help with improving the program if you feel you can do better. Also, the blending images effect and command line settings are not yet implemented. I am working on a restructured version of the application.
Enjoy!
Posted by
Siderite
at
13:31
0
comments
Links to this post
related
Labels:
.NET,
C#,
CodePlex,
misc,
programming,
software
The post was:
