Friday, November 21, 2008 #

Moving !

After all that time I've moved to
www.thinkbeforecoding.com
The content here will remain available, so don't worry ! Skup

posted @ 3:05 PM | Feedback (1)

Thursday, May 24, 2007 #

Downloading a File with a Save As Dialog in ASP.Net

Scott Guthrie points to Rick Strahl's blog about how to automaticaly open a Save As dialog on a link click. Very useful to download attachments.

I'd just like to add that IE and FireFox have different handling with non ASCII characters that we can use in my french country for instance... IE doesn't like those chars, so you have to URLEncode it. But when URLEncoded, FireFox doesn't catch it, and keeps '+' chars instead of spaces...

The solution is simple.. you just have to check the client browser :

        public static void PrepareAttachmentReponse(HttpContext context, string filename)

        {

            if (context.Request.Browser.Browser == "IE")

                filename = context.Server.UrlPathEncode(filename);

            // send response

            context.Response.AppendHeader("Content-Disposition", "attachment; filename=\"" + filename + "\"");

        }

And that's it.

posted @ 11:49 AM | Feedback (1)

Tuesday, February 27, 2007 #

Disable Screen Saver while running your WPF Application

I'm working on a WFP Media player application, and the first time I used it to watch a video, I just discovered I had forgotten something critical when the screen went black and a 3D stylish 'Woosh' apperead : that f***ing screen saver !

But how to disable it ?!
First I searched the Internet and found something to disable it in the registry. But I don't like this, you need rights to write the registry, and how can you turn the screen saver back if your application quit unexpectedly (Ok you'll say it won't, it's well written, but I can kill it with the task manager :-S ). No way.

Then I found something about the WM_SYSCOMMAND message. The window receives this message with a value of SC_SCREENSAVE when the screen saver should appear and you can prevent it to run by handling the message without doing anything. You can also get the SC_MONITORPOWER value when the monitor enters a low consumption state.

I like it ! But the point is how to handle this Win32 message in WPF, the no-windows-message world ?

Actually, the main WPF Window is hosted in a Win32 window, represented by a HwndSource object. You can get this object using the PresentationSource.FromVisual method. The HwndSource the provides a AddHook method that takes a Hook delegate that you can use to handle the message. It's a bit too easy.

There is just one last thing. Calling PresentationSource.FromVisual from the Window constructor will return null since the window initialization is not terminated and it's not already hosted by the Win32 host. Just call it from the SourceInitialized event.

A minimal sample to summary all we said :

    public partial class MainWindow : Window

    {

        private const int WM_SYSCOMMAND = 0x112;

        private const int SC_SCREENSAVE = 0xF140;

        private const int SC_MONITORPOWER = 0xF170;

 

        public MainWindow()

        {

            SourceInitialized += delegate

            {

                HwndSource source = (HwndSource)

                    PresentationSource.FromVisual(this);

                source.AddHook(Hook);

            };

        }

 

        private static IntPtr Hook(IntPtr hwnd,

            int msg, IntPtr wParam, IntPtr lParam,

            ref bool handled)

        {

            if (msg == WM_SYSCOMMAND &&

                ((((long)wParam & 0xFFF0) == SC_SCREENSAVE) ||

                ((long)wParam & 0xFFF0) == SC_MONITORPOWER))

                handled = true;

            return IntPtr.Zero;

        }

    }

Just notice the 0xFFF0 mask, it's because the system can use the 4 low order bits of the wParam value as stated in the MSDN library article about WM_SYSCOMMAND.

Now I can watch videos without mooving the mouse every 10 minutes ! I hope it can make your apps better to !

posted @ 11:46 PM | Feedback (2)

Tuesday, October 24, 2006 #

FireFox 2.0 clumsy iterators

Has everyone already nows, FireFox 2.0 is shipping this afternoon. It seems to be a nice release, and I'll surely use it often as soon as it's accessible.

I was looking at the new javascript 1.7 features. Especially the iterator thing, that I use a lot in C# since .Net 2.0 and that will be used even further with C# 3.0.

I was really sad to see how poorly it has been designed in javascript 1.7.
It's ok to move to next item in the next() method. But why did they not provide a way to test if there is more items in the iterator ???

When enumerating an iterator you have write something like this :

        var it = Iterator(obj);

 

        try {

          while (true) {

            document.write(it.next() + "\n");

          }

        } catch (err if err instanceof StopIteration) {

          document.write("End of record.\n");

        } catch (err) {

          document.write("Unknown error: " + err.description + "\n");

        }

There are two ugly things about that :

  • having to write while(true) which should be something rather rare.
  • having to catch an exception for a case that is really not exceptionnal ! You should never use exceptions in your main control flow !
Why did they not add a moreItems or any other name property to know if you can call next(). You would write :

        var it = Iterator(obj);

 

          while (it.moreItems) {

            document.write(it.next() + "\n");

          }

And it would be sooooooo clean !

But they'll release it, and any poor web developper will have to deal with this stupidity till FireFox 2.0 becomes obsolete in something like 6-7 years... F...k !

Skup

posted @ 4:57 PM | Feedback (1)

Tuesday, October 17, 2006 #

Readers, Writers and IDisposable

You know what Readers and Writers are... Wrappers around Streams used to write or read data.
Usually, you make things like this:

        using (Stream stream = new MemoryStream())

        using (BinaryWriter writer = new BinaryWriter(stream))

        {

            writer.Write(10);

            writer.Write(20);

        }

You create your stream and your writer, use it and dispose both. But what if you mustn't dispose the stream?

public void Method()

    {

        using (Stream stream = new MemoryStream())

        {

            WriteToStream(stream);

            stream.Position = 0;

            // .. Read stream

        }

    }

 

    private void WriteToStream(Stream stream)

    {

        using (BinaryWriter writer = new BinaryWriter(stream))

        {

            writer.Write(10);

            writer.Write(20);

        }        // !! Dispose the writer and the underlying stream!

    }

The implicit call to Dispose on the writer at the end of the using block will dispose the writer and the underlying stream... Then you cannot read the stream anymore.

But since the writer is IDisposable, shouldn't I call Dispose on it ? And - more important - won't it dispose the stream at random time when the finalizer is called?

The response is No, and No.

Actually, the Readers and Writers are IDisposable so that you can manage the underlying stream lifetime without having to keep a reference on both objects. If you manually manage your stream lifetime, you don't have to dispose your reader or writer.

And what about the finalizer? It's never safe to use references to other managed objects in the finalizer since they can have been finalized before. Finalizers only release the unmanaged resources. So the writer won't dispose the stream when finalized. The writers and readers often don't directly reference unmanaged resources, and they don't even need a finalizer.

Here is the good way to write code above:

    private void WriteToStream(Stream stream)

    {

        BinaryWriter writer = new BinaryWriter(stream);

        writer.Write(10);

        writer.Write(20);

        // Just let the stream live

    }

Skup

posted @ 6:19 PM | Feedback (1)

Friday, October 13, 2006 #

A good bug is a dead bug

I agree with Lieutenant Jean Rasczak: "The only good bug is a dead bug"...

This one was in the PixVillage database engine core and was teasing me for more than one month ! I had not detected it despite the 97% code coverage and the eavy unit tests. Of course it appeared in a tested condition that gave a bad result in a special data case. What can you do against that ?

Hopefully, once this kind of bug is spotted it's already almost dead...

Skup

posted @ 10:53 AM | Feedback (2)

Tuesday, October 03, 2006 #

About event hooking

Last week I was working on this really useful feature that is MembershipProvider. I had to write my own implementation since I'm working on a custom database schema. I began to write my own provider, and decided to test it.

Easy, I put a Login control on my login page, set some properties, and launch the web site to see if it's working. Ok, it cannot work the first time, so I made little changes. Among them, I hooked a method to the Authenticate event to check if it at least passed through it.

It was executing it, but it still wouldn't execute any code in my provider!?

I continued to make some changes in config. It should work, but nothing.

Guess what ! When you hook the Authenticate event, the Login control stops doing its default behavior - that is authenticating the user with the specified Membership provider - and let you do all the work yourself ! That's why nothing happened, and I spent one day and a half on this!

This means that the OnAuthenticate methods that raise the events should look something like this:

    protected bool OnAuthenticate(AuthenticateEventArgs e)

    {

 

        if (Authenticate != null)

        {

            Authenticate(this, e);

            return e.Authenticated;

        }

        else

            return DefaultAuthenticate();

    }

It seams a bit error prone to me... what about adding a boolean Handled property to the EventArg class to say that you did it on your own? Changing the behavior of a component just because you hooked an event is a good way to drive developpers crazy...

Do you know other events with this behavior in the framework?

posted @ 4:44 PM | Feedback (2)

Friday, June 09, 2006 #

Events, Multithreading and Deadlocks

I made a post today about this sad story on the new MSDN Wiki...

The problem occures when using events in a multithreaded program.
You application get stuck from time to time and when you break execution with you debugger, you find it stopped on a line like this :
AnObject.AnEvent -= new EventHandler(Event_Hanlder);

Wtf ?! Why is this line blocking ?! This is just a -= operator, it cannot block execution !!

So lets take a look at how events are implemented.
Events manage internaly a list of delegates, and protect this list against concurrent access. Thus, the list is locked in two main cases :

  • When raising an event. The event list is locked until returning from the event handler. This prevent the list from changing while enumerating through the handlers.
  • When subscribing or unsubscribing from an event. The prevents the list to be modified from different places.

It's clearer now why deadlocks can occure.
When unsubscribing from an event EventB in an event handler called through EventA, your thread holds two locks, first one on EventA, then one on EventB.
If another thread does the contrary (unsubscribe from EventA in EventB), then it will first lock EventB, then try to lock EventA.

Obviously if the second thead has already locked EventB before the first thread does, the first thread will block on the unsubscription from EventB until the second thread leaves the event handler. But since the second thread will also block on the unsubscription from EventA until the first thread leaves the event handler, a nasty deadlock occures.
You can refere to the sample code in the post on the MSDN Wiki.

It is not realy kind of event implementers to have hidden locks in the code. There would be a good way to remove one of the two lock reasons : instead of locking the event while calling event handlers, it would be possible to lock the event while making a copy of the handlers, then call the event handlers from the list copy. This way the list cannot be modified during the call, and there is no risk of reentrant calls.
The other solution is to unsubscribe the events out the the event handler thread by launching new threads to perform that task, but it makes the execution far less predictive...

If you have better solution, just tell me !

posted @ 2:05 PM | Feedback (1)

Tuesday, February 28, 2006 #

RSS for Asp.Net 2.0

Dmitryr has released a nice RSS Toolkit for ASP.NET 2.0 that includes a RSS data source component that enables databinding of rss feeds on any asp.net control, and a full support for RSS feeds generation.

You can also refere to scott gutrie's blog for a brief tutorial.

 

Enjoy

posted @ 4:35 PM | Feedback (0)

Thursday, November 24, 2005 #

Single Instance Application - Part 2 : activating existing instance

Well, I did not have post for a long time. I was working hard on the next version of PixVillage, which will be released soon now.

I'm coming back with a new post in the Single Instance Application series.

In the previous post, we have written a ProcessLock object that help us to detect an existing instance of the program we attempt to run, so that we can prevent running it twice.

Today I'm dealing with the ability to activate an existing instance of a Windows Forms application when running a new one. In order to achieve that, we have to notify the application it has to go foreground and get focus.

This can be done though a message send to the main thread of the application. The message is received by the thread, not by a window, so we have to write a specific handler and register it. The IMessageFilter interface helps providing this kind of service. Let's implement it!

Code Copy HideScrollFull
namespace SingleInstance {
/// <summary>
/// Provides a thread message filter and handle messages.
/// </summary>
public class ThreadMessageFilter : IMessageFilter {
private Form owner;

/// <summary>
/// Initializes a new instance of the <see cref="ThreadMessageFilter"/> class.
/// </summary>
/// <param name="owner">The owner.</param>
public ThreadMessageFilter(Form owner) {
this.owner = owner;
}

/// <exclude/>
[SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode=true)]
bool IMessageFilter.PreFilterMessage(ref Message m) {
if (m.HWnd != IntPtr.Zero) // Get rid of message if it's sent to a window...
return false;
// Handle the message here...

return false;
}
}
}
. . .

Now, supposing we want to activate the window when a new instance of the application is launched, we can, for instance, send a WM_SHOWWINDOW message to the thread, using the Windows PostThreadMessage API. The IMessageFilter.PreFilterMessage is implemented as follow:

Code Copy HideScrollFull
/// <exclude/>
[SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode=true)]
bool IMessageFilter.PreFilterMessage(ref Message m) {
if (m.HWnd != IntPtr.Zero) // Get rid of message if it's sent to a window...
return false;
if (m.Msg == WM_SHOWWINDOW) {
// Shows the window
try {
owner.Show();
if (owner.WindowState == FormWindowState.Minimized)
owner.WindowState = FormWindowState.Normal;
return true;
}
catch {} // return false;
}

return false;
}
. . .

With WM_SHOWWINDOW declared as follow:

Code Copy
private const int WM_SHOWWINDOW = 0x18;

Now, we just have to modify the Main() method in order to:

  • Create and show the form the first time the application is started.
  • Registers and unregisters a ThreadMessageFilter object.
  • Send the message to any thread of any process having the same name as the current assembly.

The code is given below. (MainForm is a class derived from System.Windows.Form).

Code Copy HideScrollFull
using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace SingleInstance
{
public sealed class SingleInstance
{
private SingleInstance(){}
private static readonly string assemblyName = Assembly.GetExecutingAssembly().GetName().Name;

[DllImport("user32.dll")]
private static extern bool PostThreadMessage(int threadId, int message, int wParam, int lParam);

private const int WM_SHOWWINDOW = 0x18;

/// <summary>
/// Application entry point.
/// </summary>
[STAThread]
static void Main() {
using(ProcessLock processLock = new ProcessLock(assemblyName)) {
if (processLock.AlreadyExists)
{
// Sets the existing application foreground.
SetForeground();
}
else
{
// The program operation must run inside the 'using' block.
Run();
}
}
}

private static void SetForeground() {
// Find all processes having the same name
Process[] processes = Process.GetProcessesByName(assemblyName);
foreach (Process process in processes)
{
if (process.Id == Process.GetCurrentProcess().Id)                
// This is the current process, pass
continue;
// Activates the other instance window by sending the message to any thread in the process.
foreach (ProcessThread thread in process.Threads)
PostThreadMessage(thread.Id, WM_SHOWWINDOW, 0, 0);
}
}

private static void Run() {
using(MainForm form = new MainForm()) {
IMessageFilter filter = new ThreadMessageFilter(form);
Application.AddMessageFilter(filter);

try
{
form.Show();
Application.Run(form);
}
finally {
Application.RemoveMessageFilter(filter);
}
}
}
}
}
. . .

posted @ 6:00 PM | Feedback (2)