This document contains a variety of discussions on C# from the listserv used Summer Quarter 2003

C# supports pointers but when are they ever needed?

Certain situations call for the use of unsafe code such as when interfacing with the underlying operating system, during interactions with COM objects that take structures that contain pointers, when accessing a memory-mapped device or in situations where performance is critical

http://www.25hoursaday.com/CsharpVsJava.html

 

Double buffering is a way to optimize drawing and reduce screen flicker, here’s how you set it up

http://www.programming.de/index.php?learn_cs.php
//Double Buffering
//!!!!!!!
SetStyle(ControlStyles.UserPaint, true);
SetStyle(ControlStyles.AllPaintingInWmPaint, true);
SetStyle(ControlStyles.DoubleBuffer, true);
//These three lines is all you need
put them into your initialization

 

Information on ADO.NET (ActiveX Data Objects)


1) The command object has a commandType property which is an enumerated type CommandType. This has 3 possible values. Text, StoredProcedure, and TableDirect. Text is the default and used for sql stmts. StoredProcedure is a very popular way to configure these because a lot of companies are starting to recognize the advantages of using stored procedures. I currently work on one application where this is the ONLY access to the database from the application (No SQL is possible). The last is TableDirect whereas you can set the command's text to the name of the table and the command will retrieve
the table. This would be handy for students who don't know SQL. :>)

2) Before one can use a DataAdapter to apply updates (be that insert, updates, or deletes), he or she must populate the DataAdapter's InsertCommand, UpdateCommand, and DeleteCommand properties. This can be a pain in the butt there is an easy way. Before that...

The commands will look like
For SQLServer...
INSERT INTO MyTable(MyCol1, MyCol2, MyCol3)
VALUES(@MyCol1, @MyCol2, @MyCol3)

For Access this would look like...
INSERT INTO MyTable(MyCol1, MyCol2, MyCol3)
VALUES(?, ?, ?)


However, who wants to write all that SQL. There are components called a OleDbCommandBuilder and SQLCommandBuilder that can build these for you provided the original select stmt contained no joins. In other words, only retrieve data from one table. Otherwise we have to write this sql ourselves

3) .Net currently ships with 2 providers. (2003 may ship with 3, I don't know for sure). These are OleDB and SQL. OleDB is slower because of added overhead but works with most RDBMS. SQL only works with SQL Server. You can also download (from $soft) an ODBC provider. Don't know anything about this. Oracle provides its own provider that is comparable to the SQL provider in terms of speaking directly using the RDBMS API (means fast). If anyone was wanting to connect to Oracle, this would be the way to do it (though OleDB would work). I would expect that other major RDBMS venders probably have their own providers as well.

 

Form focus issues

 

The form must have the focus in order to process a key event.  I think that if you have a KeyPress event for another control on your form and if that control currently has the focus the only way your forms KeyPress event will get called is if you manually call it.  Try adding a base.KeyPress(e); inside any other controls on your form that
override the KeyPress event.

Then all you have to do is make sure you are not handling any other control's KeyPress events for them... By:

Form1_KeyPress(blah blah) {
if(!someControl.focus) {
  //handle the event
}

Hope this helps, not a lot of time to test my theory for you but it
should hopefully get you in the right direction...
 
> Wrote a KeyPress event on the Form and when the Form is Active why
> does the KeyPress event do not get executes when I presses any key?
> Where as if I write the KeyPress even on a TextBox control, it does
> execute fine when I enter anything in the textBox.
>  
> Does anyone has an answer.
>  

 

 

 

Display issues based on screen resolution

Hello all,

In porting some of my Java GUI code over to C#, I came across something from Java for which I cannot find the C# equivalent (and it's causing some headaches for my code).

The problem goes like this:

The Size property of a System.Windows.Forms.Form in C# is the actual size of the window as displayed on the screen--including the title bar, menu bar and the dragable edges on left, right, and bottom of the window. So naturally, the actual drawing area inside the Form is the size of the window less the space taken up by the title bar, menu bar, etc.

This is exactly how things are in Java.

This presents a slight problem if you want to display, say, an 800x600 image in your form...you can't just make the size of the form 800x600. You have to allow for the space taken up by the title bar, etc.

Now in Java, one can call the method getInsets() (at least when working with the JFrame class). This method returns an object of type Insets (not sure of fully qualified type). This object contains the insets for the current JFrame, that is, the amount of space around the outside of the window taken up by things other than the content pane.

Once you have this Insets object, you can do something like this:

{
    Insets insets = getInsets();

    int width = insets.left + insets.right + 800;
    int height = insets.top*2 + insets.bottom + 600;

    setSize(width, height);
}

And now the window will be just big enough to handle that 800x600 image plus any window borders, the title bar, menu bar, etc.

What I can't figure out is how to do this same thing in C#. I have empirically determined that, for a window with a title bar and no menu bar, the insets are:
left: 4
right: 4
bottom: 4
top: 23

I was able to determine this by accessing the DisplayRectangle property of the Form and then comparing the size of that rectangle to the size of the Form itself. With this information, I can then adjust my form's size in the GUI builder. But this does not meet my needs, as the addition of a menu bar adjusts the top number. Note that the DisplayRectangle property is read-only, so one can't simply assign a "new Rectangle( new Point(0, 0), new Size( 800,600) )" to it to get the desired behavior.

SOLUTION

I feel kinda stupid now, but in going back to the documentation for the classes while writing this email, I stumbled on the solution. Rather than just delete this email and go about my business, I thought I'd share it with everyone else just in case someone else was interested in it (don't know how many of you out there need to get your windows to a very specific and exact size).

The ClientRectangle and ClientSize properties of the System.Windows.Forms.Form class.

The reason I didn't find this earlier is the non-intuitive name (at least to this Java guy-maybe perfectly clear to MFC programmers).

In short, the ClientSize property is the size of the form's client area. That is, "the size of the form excluding the borders and the title bar," to quote the documentation. It is "the area within a form where controls can be placed" and, as it turns out, exactly what I needed. Since this property can be changed, you can simply do something like this:

this.ClientSize = new Size( 800, 600 );

to make room for that 800x600 image or whatever.

ClientRectangle seems to give the same values as the DisplayRectangle (though the docs note that inherited controls you create might want to change this).

I still think Java is the better language and the better GUI programming environment. :)

Cheers,

 

Playing mp3s and other things

Hello all,

I don't know about anyone else, but for one of my projects I wanted to be able to play some MP3 files used as in-game soundtracks. Well, the DirectSound "Play Sound" Tom demonstrated Tuesday won't cut it. If you modify the program to accept .mp3 files in the file chooser (by changing the Filter on the open file dialog to something like:

ofd.Filter=  "Wave files(*.wav)|*.wav|MP3 Audio Files (*.mp3)|*.mp3|All
Files (*.*)|*.*";

then the program crashes and burns trying to load an MP3 format audio file.

Doing a bit of research, I found this method for playing MP3s. Since the full DirectShow API (which is what I believe a normal Windows programmer would use for this sort of thing) is not available, you have to make do with the AudioVideoPlayback namespace. There's an example of how to use it in the DX9 SDK (in DXSDK/Samples/C#/AudioVideo/Player).

The real meat of the example is this:

using Microsoft.DirectX;
using Microsoft.DirectX.AudioVideoPlayback;

......

private void playMP3()
{
    Audio bgMusic; // Audio class from AudioVideoPlayback
    bgMusic = new Audio( @"..\..\path\to\mp3_file.mp3");

    // Start playing now
    bgMusic.Play();
}


From what I can tell, since the AudioVideoPlayback classes are not as robust as the full DirectShow API, there's not a whole lot of fancy stuff you can do with it (for example, no buffering [or at least no easy way to do it], to automatic looping of playback [instead, add an event handler to make it start playing again when it reaches the end]). At least the playback seems to be asynchronous (in which case my snippet of code might not work, since the bgMusic reference will go out of scope shortly after the call to Play(), which might cause problems--in my actual code, bgMusic is really a private member of the class, not an instance variable inside a method).

 

Makefile info

 

MakeFiles and Embedding Multiple Resource Files in a single Namespace

 

This is just from my experience in case anyone else comes across a
similar problem...

I have a project with 4 different forms, each with it's own resource
file.  It will compile and run just fine using VS.NET but after
compiling from the command line I would get a
MissingManifestResourceException when I tried to run the winexe.

After a bit of research and testing different makefile configurations I
was able to come up with the following reasoning and solution:

When VS.NET compiles your source code, it automatically converts your
.resx files to .resources and appends to the front of the resource file
names, the name of your namespace. (I learned this using the decompiler
(ildasm) and taking a look at the manifest files for both my command
line compiled version and the VS.NET compiled versions and finally
noticed the difference.

Command Line Version:
    .mresource public Form1.resources
    .mresource public Form2.resources
    etc...

VS.NET Version:

Ex: .mresource public MyNameSpace.Form1.resources
    .mresource public MyNameSpace.Form2.resources
    etc...

So, in order to fix this problem I edited my makefile like so:

<-----makefile contents start below----->
App.exe: Form1.cs Resources
        csc /t:winexe /out:App.exe /win32icon:App.ico\
        /res:MyNameSpace.Form1.resources\
        /res:MyNameSpace.Form2.resources\
        /res:MyNameSpace.Form3.resources\
        /res:MyNameSpace.Form4.resources /recurse:*.cs
        del *.resources
Resources:
        resgen Form1.resx MyNameSpace.Form1.resources
        resgen Form2.resx MyNameSpace.Form2.resources
        resgen Form3.resx MyNameSpace.Form3.resources
        resgen Form4.resx MyNameSpace.Form4.resources
<-----end makefile contents----->

 

 

I found this url useful for working with makefiles!

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cscomp/html/vcrefcsharpcompileroptionsbycategory.asp

 

Security setting info

Hello all,

A couple weeks ago there were a few messages on the listserv regarding security issues and mapped network shares. With the default settings, the .NET Framework appears to not allow execution of code that resides on a mapped network share.

I wanted a way around this, since my primary computer is my Power Mac G4 and that's where all my files are stored, with certain directories shared with Samba so I can access them from my Windows and Linux boxes as necessary.


Here's what I did (under Windows XP Pro--adjust accordingly):

1.  Go to the Start Menu and select Settings->Control Panel->AdministrativeTools->Microsoft .NET Framework 1.1 Wizards

2.  Choose "Adjust .NET Security"

3a.  Choose "Make changes to this computer" if you have administrator privileges and want to have this change affect all users
3b. Or choose "Make changes for the current user only" if you only want this change to affect the current user (duh)

4.  Since my file server and Windows machine are on the same LAN, I selected "Local Intranet" and adjusted the level of trust to "Full."

After applying the changes, I am now able to open projects that reside on the network share without getting the "The project location is not fully trusted by the .NET runtime" error message and I can now build and run code from the network share without any problems.

This is what worked for me, and I thought I'd share it with everyone just in case someone else was interested. Your mileage may vary of course.

 

 

Command line compile with target a windows exe

To specify you want your executable to be a windows exe (as opposed to a
console exe), the switch is as follows

csc /t:winexe sourceFile.cs

More information about compilation can be obtained from typing:

csc /?

at the command prompt.

 

 

Binding controls to data from a database

I recently discovered a neat little thing we can do with C#, and Tom suggested that others might be interested.

In case anyone out there has not done any database programming, many tools (like VB) allow the programmer to bind controls to data. In C#, you can populate a dataset, place the controls Textbox, listbox, combo box, or whatever on the form and then bind the controls to the dataset. This is old hat.  

C# gives us a new twist. We can now bind controls to user defined types (instances of user defined classes). Change the object (class instance) and the control automatically changes, and the reverse is also true.  

To do this, look up DataBinding on the controls in MSDN. This is easy to do.

Also note that many in the industry don't think very highly of using databound controls. I have disliked them myself. However, they can be useful if one is careful not to abuse. One thing to avoid is to have a lot of disjointed controls all bound to the same data, all using that common data different purposes.  

One last tip. If you are doing database programming,  look up strongly typed datasets. Another new thing in C#. They are really cool and a snap to create.

 

 

Example that demonstrates makefile setup/usage

check this link on the website:

http://penguin.ewu.edu/class/cscd498/csharp/labs/1-Architecture/Architecture.htm

and then

http://penguin.ewu.edu/class/cscd498/csharp/labs/2-Types-Stmts-Methods/Types-
Stmts-Methods.htm

Here's a simple example as well (found at:
http://www.dotnet247.com/247reference/msgs/14/70059.aspx):

As it turned out (see thread "CodeDom instead of scripting?" here and in dotnet.framework) JScript is the only .NET language that is fully implemented for run-time compilation without requiring either the .NET Framework SDK (for command-line compilers) or the VSA add-on.

So I've put together a minimal application that demonstrates how to execute a script (i.e. a character string holding commands to be executed at run time) that changes a variable living in another .NET module written in another language, namely C#. It's really impressivehow easy it is (once you know how it's done)!

Note: We need three different files -- one for the main method, one to execute the script, and one to host the data. A separate data DLL is required so that the script DLL can reference the data class at compilation time, and a separate script DLL is required so that we can use JScript's convenient eval function. I think it would be possible to put everything into two files or even a single file but that would require using reflection and/or CodeDom mechanisms.

// file MainClass.cs
public class MainClass {
public static void Main() {
System.Console.WriteLine(DataClass.x); // -> 3
ScriptClass.ScriptMethod(); // changes DataClass.x
System.Console.WriteLine(DataClass.x); // -> 10
}
}

// file DataClass.cs
public class DataClass {
public static int x = 3;
}

// file ScriptClass.js
public class ScriptClass {
public static function ScriptMethod() {
eval("DataClass.x = 10;"); // change C# variable
}
}

And here's the command-line makefile to build everything (save to a file called "makefile" and execute by typing "nmake" in a DOS box):

SCRIPT = Microsoft.JScript.dll # convenient abbreviation

MainClass.exe : MainClass.cs DataClass.dll ScriptClass.dll
csc /debug /r:$(SCRIPT),DataClass.dll,ScriptClass.dll MainClass.cs

ScriptClass.dll : ScriptClass.js
jsc /debug /t:library /r:DataClass.dll ScriptClass.js

DataClass.dll : DataClass.cs
csc /debug /t:library DataClass.cs

clean :
del /q MainClass.exe DataClass.dll ScriptClass.dll *.pdb
-------------------------------------------------------------
to use your makefile, type nmake followed by the name of the target (ex: HeroesAndMonsters.exe -- which is specified at the top of the makefile)

tom

VS.NET shortcuts

Another interesting tidbit...

When blocks of code get really large, it can be hard to mate open and closed braces. Here is a shortcut to find a brace's mate.

Put the cursor just before or after the brace in question, then press ctrl + ]   (ctrl key and then the "]") You will be taken to the brace's mate. Repeat and you will return to
the original brace.

---
I Learned of a new feature today that I thought might interest everyone.

Open any .net project in the IDE and press CTRL+ALT+J. This brings up the Object Browser. Here you can get details on .net framework classes as well as the solution's user defined objects (classes, interfaces). Check it out, it is REALLY cool.

 

 

Carriage return issues
Can Anyone Help Me?
 
In my ToString method override for my class representing an individual I return a String that is just has all the attributes connected with a "\n" character for a carriage return for formatting purposes. That works just fine when I print to the console but for some reason when I print to a file I just get some weird character instead of a carriage return. it does the same thing for the tab character "\t". So my question is, what character do I have to use when printing to a file in order to get a carriage return?

One way to get around this is to use Environment.NewLine

Equals and GetHashCode usage

Folks, here is some more information on overriding the Equals method and why
you need to override GetHashCode as well.  This info is taken from the .NET
Framework documentation.

tom

----

Types that implement IComparable must override Equals.

Types that override Equals must also override GetHashCode; otherwise, Hashtable might not work correctly.

If your programming language supports operator overloading and if you choose to overload the equality operator for a given type, that type must override the Equals method. Such implementations of the Equals method must return the same results as the equality operator. Following this guideline will help ensure that class library code using Equals (such as ArrayList and Hashtable) behaves in a manner that is consistent with the way the equality operator is used by application code.

-----

The default implementation of GetHashCode does not guarantee uniqueness or consistency; therefore, it must not be used as a unique object identifier for hashing purposes. Derived classes must override GetHashCode with an implementation that returns a unique hash code. For best results, the hash code must be based on the value of an instance field or property, instead of a static field or property.

-->THE FOLLOWING GOES DEEPER THAN YOU MAY CARE ABOUT AT THIS POINT, BUT HERE IT IS...

Notes to Implementers:  

A hash function is used to quickly generate a number (hash code) that corresponds to the value of an object. Hash functions are usually specific to each Type and must use at least one of the instance fields as input.

A hash function must have the following properties:

If two objects of the same type represent the same value, the hash function must return the same constant value for either object. For the best performance, a hash function must generate a random distribution for all input. The hash function must return exactly the same value regardless of any changes that are made to the object. For example, the implementation of GetHashCode provided by the String class returns unique hash codes for unique string values. Therefore, two String objects return the same hash code if they represent the same string value. Also, the method uses all the characters in the string to generate reasonably randomly distributed output, even when the input is clustered in certain ranges (for example, many users might have strings that contain only the lower
128 ASCII characters, even though a string can contain any of the 65,535 Unicode characters).

GetHashCode must always return the same value for a given instance of the object. For derived classes of Object, GetHashCode can delegate to the Object.GetHashCode implementation, if and only if that derived class defines value equality to be reference equality and the type is not a value type.

Providing a good hash function on a class can significantly affect the performance of adding those objects to a hash table. In a hash table with a good implementation of a hash function, searching for an element takes constant time (for example, an O(1) operation). In a hash table with a poor implementation of a hash function, the performance of a search depends on the number of items in the hash table (for example, an O(n) operation, where n is the number of items in the hash table). Hash functions must also be inexpensive to compute.