Showing posts with label C#. Show all posts
Showing posts with label C#. Show all posts

Thursday, 4 June 2009

TreeViewScroll

The .net TreeView doesn't expose a scroll event. Make your own by overriding DefWndProc.

   public class TreeViewScroll : TreeView
{
private const int WM_VSCROLL = 0x115;
private IntPtr SB_ENDSCROLL = new IntPtr(8);

public event MethodInvoker Scroll;

protected void OnScroll()
{
if (Scroll != null)
Scroll();
}

protected override void DefWndProc(ref Message m)
{
if (m.Msg == WM_VSCROLL)
{
if (m.WParam != SB_ENDSCROLL)
OnScroll();
}

base.DefWndProc(ref m);
}
}


The code above is sufficient for my needs, but if you need more details about the scroll (direction, where you scrolled to, etc) you need to interrogate the message further.

This link should tell you what the message contains:
http://msdn.microsoft.com/en-us/library/bb787577(VS.85).aspx

This link can tell you the scrollbar values:
http://www.pinvoke.net/default.aspx/Enums/ScrollBarCommands.html

Sunday, 8 March 2009

Zipping in C#

After spending hours digging around, trying to find the .net solution to zipping folders using c#, the easiest solution seems to be to use the command line for 7zip.

String zipper = @"c:\program files\7-zip\7z.exe";
String args = "a -tzip " + compressPath + " " + compressFolder;

Process proc = Process.Start(zipper, args);
proc.WaitForExit();



where compressPath is something like "C:\foo.zip" and compressFolder is something like "C:\foo".

Update: 9th March 2009
It's probably a good idea to make sure both compressPath and compressFolder are surrounded by quotes in case they contain spaces!

Tuesday, 28 October 2008

Minimize to the Notification Area

Cloud Launcher is minimizing to the notification area, then restoring when the notification icon is double clicked.

Only, for hours it wasn't. Instead of restoring, it was appearing as a tiny "minimized" window / title bar.

Turns out the "restore" / "show" order is important.

This:

WindowState = FormWindowState.Normal;
Show();


doesn't work.

This:

Show();
WindowState = FormWindowState.Normal;


works.

Saturday, 9 August 2008

Code Re-use

I've always believed re-using code is a good idea, but it's not until recently that I've felt that I'm doing it properly

When I programmed for myself (before I was hired as a programmer), I wrote in C++. I tried to make libraries (libs and dlls) for re-use in future projects. My friend / housemate / mentor Denis advised me not to bother making libraries and just copy the code into the latest project. I guess for personal projects there isn't really any point wrapping up functionality in dlls. But what about bigger projects? I'm starting to think that even with bigger projects, it's not worth the hassle...

Denis gave me some more advice, when I was trying to put an engine together to help me write games. "Write the game, not the engine". Which I suppose is correct if you want to write the game, but if the process is more of a learning exercise, then i think it's right to work on the engine. But then, I suspect that every closet games-coder is working on their own engine, and a lot of games don't end up written.

I used to write whatever kind of module I thought was necessary for my game, then, when the time came to pull all the code together, I planned to lift all the code from each of the modules and combine them to create my engine / game. Needless to say, I never got round to creating my engine, or my game...

At work, I write tools in C#. Suddenly, I have lots and lots of scope for re-use. I'm not 100% sure of the reason for this, but I feel that the C# language itself makes itself very amenable to code re-use.

Now I don't write everything with re-use in mind. If I only need to use something once, then the time spent making it more generic is wasted. The first time I need a tool to do something, I'll write a very specific tool for the job. Then if I decide I need it again, only then will I make it generic. This process seems to serve me well enough.

So far, I've written the following:

A generic options dialog that can be plugged into any app I write in future. (Currently can store options that are strings or bools - more types planned for in future).

An Argument Parser. (Pass in the args from your program, and then you can ask it for string values or if a bool option is present).

A Serializer. (Until I wrote this, every time I wanted to load or save a binary object I had to create the file reader / writer and the serializer separately, then pass my data to the serializer - now I just create my generic serializer.)

A Cascading Checkbox Tree. (Out of the box, the treeview doesn't propogate ticks up or down the tree. My cascading checkbox tree does.)

A class to convert absolute to relative paths and vice versa.

A class to handle File Operations. (Typically, things like "Close" go through a process of checking if the file needs saving; asking the user if they want to save it; save the file; if the file doesn't have a name present the user with a save dialog; if the user wants to open a file, check that their current file is saved; and so on. My File Operations class handles all of this for me.

And even an OK-Cancel form. (I always seem to be writing dialog boxes that have OK and Cancel buttons on them. And I always have to change the text on the buttons, change the names of the buttons, set up the accept and cancel properties of the form, tell the form to close when either button is pressed. Now I just re-use my OK-Cancel form.

Re-use rocks!

Friday, 6 June 2008

C# Attributes

Just a short post today. Though I'll try to stick to generally applicable programming techniques / articles / entries, I'll occasionally go language or technology specific.

I'm loving working in C# - I only really started C# programming about a year ago and I'm learning more and more about it and really enjoying it.

When I discovered the Property Grid, I thought it was fantastic. The property grid is used to expose properties to the user. The user can view or edit these properties, depending on whether get and set methods are defined. You can do a whole host of things with the property grid, such as putting properties into categories with the Category attribute, specifying default values with the DefaultValue attribute, and you can even specify that a property isn't shown in the grid with the Browsable attribute.

Pretty soon after learning about the property grid, I was using it for everything. Then one day I decided that it would be useful if I could dynamically change what was shown in the property grid at runtime.

I spent a whole day looking for information on how to change attributes at run time. I learned about reflection, I learned about creating attributes, I learned about applying attributes. But I couldn't find out how to change attributes dynamically.

I could have saved a whole day if I'd learned at the start that attributes are compiled into the executable and can't be changed on the fly.

So I'm posting this so that there's a million to one chance that if somebody else is searching for how to change attributes dynamically, they get to read this early on and don't waste the amount of time I did.

Update: 5th July 2008
I've posted some more information on dynamic property grids, in case you were looking for it.