Category Archives: Windows

Virtual PC: Switching between virtual pc and host pc

Once you start using your virtual PC, how do you get control back to the host PC? The help document of VPC says to press the host key, but what on earth is the host key? It’s the right ALT key of your keyboard. Not any ALT key, but the RIGHT ALT key. Press it and the mouse control comes back to your host PC.

You can launch your virtual PC in full screen mode. Once you have done that, how do you quit full screen mode? Again, press host key and enter. That is RIGHT ALT + Enter.

Simple, yet it took me some time to figure it out.

Datagridview: Get SelectedIndex of DataGridViewComboBoxColumn

This seems to be a straight forward thing, but Microsoft only knows why this simple feature is not supported in DataGridView.

If you have a ComboBoxColumn in your DataGridView and you want to know what is the selected index of the combo box, then you need to do this:

1. Handle the EditingControlShowing event of DataGridView. In this event handler, check if the current column is of our interest. Then we create a temporary ComboBox object and get the selected index:


private void dataGridView1_EditingControlShowing(object sender,
DataGridViewEditingControlShowingEventArgs e)
{
if (dataGridView1.CurrentCell.ColumnIndex == 0)
{
// Check box column
ComboBox comboBox = e.Control as ComboBox;
comboBox.SelectedIndexChanged += new EventHandler(comboBox_SelectedIndexChanged);
}
}

void comboBox_SelectedIndexChanged(object sender, EventArgs e)
{
int selectedIndex = ((ComboBox)sender).SelectedIndex;
MessageBox.Show("Selected Index = " + selectedIndex);
}

A rather round-about solution where a simple one would have sufficed.

Right click on TreeView: Get the node clicked at

Problem:

There is a TreeView control with n number of nodes. When the user right clicks on the TreeView control, get the node on which the right click was performed.

Background:

In TreeView control, SelectedNode property is set whenever left click occurs. This is not true for right clicks. So, we need to have some workaround for this.

Solution 1:

The most popular solution is to handle the MouseDown event. Check if the click was a right click and then use the TreeView control’s GetNodeAt API to get the node which was clicked at.

private void treeView1_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Right)
{
TreeNode selectedNode = treeView1.GetNodeAt(e.X, e.Y);
MessageBox.Show("You clicked on node: " + selectedNode.Text);
}
}


Solution 2:

Handle the NodeMouseClick event. The TreeNodeMouseClickEventArgs has the node which was clicked at.

private void treeView1_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
{
if (e.Button == MouseButtons.Right)
{
MessageBox.Show("You clicked on node: " + e.Node.Text, "Solution 2");
}
}

SelectedNode property of a treeview is set whenever a left click occurs. Why can’t the same be applied for right click? Right click on a treeview is such a common UI event, that users will benefit from it.

Removing items in a list while iterating through it

See the following code:

List list = new List();

for (int i = 1; i < 10; i++) { list.Add(i); } foreach (int i in list) { list.Remove(i); } [/source] Do you see anything wrong in this piece of code? No? Okay. Execute this code and you will get a System.InvalidOperationException with the message “Collection was modified; enumeration operation may not execute.”

The first time foreach loop executes, it deletes the first item and in the second iteration, this nasty exception is thrown. Reason? You deleted the first item and the list has changed. If not for the InvalidOperationException , you could have got a IndexOutOfRange exception while traversing the list.

So, how does one delete some items in the list while iterating through the list? I faced this problem in my project today and I couldn’t come up with an elegant solution. I did come up with a hack. I identify all items that need to be deleted and mark them with a flag (I need one iteration here). In another iteration, I create a new list and copy all those items which are not marked.

Sorry, I couldn’t come up with something better. If you have a solution or a better fix, please do let me know. Please note that if I want to remove all items, I can use list.Clear(). I am talking about a scenario where I want to delete only a select few items.

Update:

I read somewhere that if you use for loop instead of foreach, this problem does not arise. True, you will not get an exception, but you might not delete the items that you actually want to delete. Let’s see what happens in our case.

List list = new List();

for (int i = 1; i < 10; i++) { list.Add(i); } for (int i = 0; i < list.Count; i++) { int remove = list[i]; list.Remove(remove); } [/source] You will delete items 1, 3, 5, 7 and 9. After the for loop exits, your list will still have 2, 4, 6 and 8. Surprised? Let's see why this is so. First iteration: i = 0, remove = 1. Deleted item = 1 Once you delete this item, the list has changed. So, the first element in the list is now 2.
Second iteration: i = 1, remove = 3. Deleted item = 3
Third iteration: i = 2, remove = 5. Deleted item = 5

and so on….

So, replacing foreach with a for is not a solution.

Using App.Config for user defined runtime parameters

These are the steps involved in defining runtime parameters and using them in your code.

1. Create a App.Config file
2. Define the runtime parameters and provide values for these
3. Access these parameters in your code
4. Verify changing the parameter value at runtime affects the application


Step 1: Create App.Config file

1a. Create a Console Application
1b. In Solution Explorer, right click on project. Add->New Item. Select Application Configuration file. This file will be added to your project.


Step 2: Define the runtime parameters and provide values for these

2a. Open App.Config.
2b. Define the keys and values for your runtime parameters.

Example:

<configuration>
<appSettings>
<add key="OperatorName" value="Rita"></add>
<add key="LoggerLevel" value="5"></add>
</appSettings>
</configuration>

You can define any key and provide values. Ensure you don’t have duplicate keys.


Step 3: Access these parameters in your code

3a. Add a refernce System.Configuration DLL.1
3b. Add the following lines in your code. You can directly add these lines in Main.

string name = System.Configuration.ConfigurationManager.AppSettings["OperatorName"];
Console.Writeline("Welcome " + name);
string level = System.Configuration.ConfigurationManager.AppSettings["LoggerLevel"];

Console.Writeline("Logger level: " + level);

3c. Build your project and execute it.The output should be:

Welcome Rita
Logger level: 5


Step 4: Verify changing the parameter value at runtime affects the application

4a. When you build your project, the App.Config file is copied to your Debug/Release folder with the name .exe.config. My project is named UseAppConfig. The App.Config in my Debug folder is UseAppConfig.exe.config

Open the .config file in your working directory (Debug/Release). Change the values to Mary and 1. In the same folder you will see your executbale. Double click on this and you should see the new values.2

You are all set. You can identify all those parameters that make sense as runtime parameters, define a meaningful key for each parameter and start using it. You no longer have to build your application every time you want to change the parameter value.


Notes

1: You need this reference only if you are using .NET 2.0
2: If you change the App.Config from Visual Studio IDE, then you need to rebuild your project to see the new values.

Tagged

Setting up Darwin Streaming Server – Part 2

Part 1 can be found here.

Darwin Streaming Server documentation states that the video clips that need to be streamed should be under the Movies folder. This, on Windows, is C:\Program Files\Darwin Streaming Server\Movies. When the server receives a RTSP request for a video clip, it checks this folder for that file. What is not documented is that the server looks recursively under the sub-folders for the requested video clip.

So, if you have folders like Songs, FunnyVideos etc. under Movies folder, Darwin server will be able to stream all video clips under these sub-folders. Catch: These sub-folders should not contain spaces! If a sub-folder ‘Funny Videos’ is present under Movies folder and you request for a file which is under ‘Funny Videos’, Darwin server will return a 404 Not Found error.

I wonder why this is not included in Darwin Streaming Server documentation.

Main Form loses focus

Apologies if this post comes across as naive. I recently put my foot into the Windows Forms world and I have been learning new things. This might be a problem which all GUI programmers have encountered on day one and also know the solution to it. This post is to those souls like me who make a late entry into this magical world and seem to get lost, err… lose focus.

Problem:

We have a main form called MainForm. Whenever the user clicks a button on this MainForm, a method Copy in a class HelperClass is called. This method Copy uses the kernel call FileSystem.CopyFile to carry out the copying. One reason to use the kernel call is you need not re-write the progress bar and cancel features, just reuse the features provided by the kernel call. This will display the standard Windows file copying dialog with a cancel button.

The problem is, whenever you click Cancel on the file copying dialog, the MainForm loses focus.

Solution:

Since we are using the file copying dialog provided by the kernel, we have no access to the dialog directly. Hence, we cannot set the MainForm as the owner of the file copying dialog.

The solution to this problem is, in MainForm, right after we make a call to Copy method, set the focus back to MainForm.

    Copy(source, destination);
this.Focus();

Problem solved.

How to setup Darwin Streaming Server on Windows

PS: Part 2 of this article can be found here.

What is Darwin Streaming Server?

Darwin Streaming Server is an open source, free to use streaming server from Apple. The commercial version of this server is the Quick Time Streaming Server.

Where do I get it from?

The Darwin streaming server source code can be downloaded here. You need an Apple ID for this. Registration is free – go get an Apple ID for yourself.

How do I install?

Once you download the source code, you will see a install.bat in the root directory. Just double click on it and the batch file will copy the necessary files under C:\Program Files\Darwin Streaming Server. This is all the installation required.

How do I start streaming?

Along with the source code, Apple ships a few sample video clips which are ready to be streamed. All these video clips are under the C:\Program Files\Darwin Streaming Server\Movies folder. You can stream any of these video clips and view it on a player. Open up a command prompt. Go to C:\Program Files\Darwin Streaming Server and start Darwin server by typing DarwinStreamingServer.exe -d. If all is fine, you will get some INFO messages and a message that says ‘Streaming Server done starting up’. This means the server is up and ready to accept client connections.

If you get an error something like ‘WARNING: Another process is already using the following RTSP port: 554’, then the Darwin Service is already running in the background and you don’t have to start the server explicitly.

Your server is ready and all set to stream.

How do I connect using a player?

VLC Player: File->Open Network Stream. Select RTSP and give the URL as rtsp://localhost:554/sample_100kbit.mp4

QuickTime player: File->Open URL. Give the URL as rtsp://localhost:554/sample_100kbit.mp4

If all is fine, you should see an animated ‘Q’ – logo of Quick Time.

More info?

Google is of course there.

Administrator’s guide.

FAQ.

Darwin users mailing list.

16 things I did not know about Windows XP

Thanks to StumbleUpon for the link.