This isn't a full blown tutorial, but more of something you can look back upon as a reference, it'll only be focusing on some core and some not-so-core subjects but by keeping these things in mind, you've just made your application about a hundred times better
Anyway lets get to it shall we?
Getting Started
This is something that isn't going to be explained here. About a million books and online tutorials exist these days, more often then not made by top professionals who know exactly what they're talking about. So you should find most to be very useful indeed, I know I did.
One thing I will note here though is that we will be primarily focusing on Microsofts C#, but many of the topics covered can pertain to VB and C++ also. C# can be downloaded from THIS page on their website. Alternatively you could buy Visual Studio 2005 from HERE on their website. VS comes with VB, C# and C++ as well as a few other pieces of software.
The Vision
This is where it all starts, the idea. A short sentence or small paragraph, it is what will drive you during the course of development on your new program, and is one of the most important parts of the development cycle.
With the realization of this new idea comes a very important choice: either you decide to let it pass by and continue on with your life, or you decide to realize this idea and do everything in your power to do just that.
Now let me quickly list 2 very important don'ts:
- The program must simplify some sort of process. In the case of Halo2, inserting a longer string into the unicode table means shifting a lot of data, which manually means one hell'uva lot of work. But with a program doing all that work for you the process has just been dramatically simplified. Thus such a program is a good idea.
- If your idea has already been realized in some sort of other application, you should not continue unless you honestly feel that the job could have been done better. In the case of a calculator, theres no point in making it if the eventual result is not going to be better than the one Windows comes with for free.
Planning
Time to get out your pen and paper, or open up some sort of word processor, and begin writing the basis of your application. What is it going to do? Look like? Who is it aimed at? How are the internal workings going to be ordered?
Don't ever just jump into it, that is a very foolhardy thing to do, and believe me I know as I've done it quite a few times myself. With planning comes good structure, which means a good, robust application at the end of it all. It also means then when you open the project back up a few months later, you can quickly get back up to speed with the inner workings and quickly progress on whatever update you wish to implement.
Once you've got down a basic plan for your application, the next step is to start teasing out the possible loopholes.
Scenarios
Things that may happen during runtime that you've got to look out for. For example if the application resigned Halo2 maps; you may have one button to open the map and one to resign the open map. But what if the user presses the resign button without first opening a map? You have two choices in this case:
- Either have a boolean value indicating whether a map has been opened or not. If one has not either do nothing or MessageBox the user telling them what they have done wrong. or just be rude ;o
- OR the resign button is disabled until a map has been opened, in which case it becomes enabled allowing for the map to be resigned.
With larger applications theres bound to be a lot more scenarios, but remember you only need to take note of the ones that do present loopholes in your application. You should have also started going back to the model you created in the planning stages and noting down the precautions that will have to be taken at certain points in your program, to ensure that any loopholes you've found cannot be exploited.
Moving On
I've covered the basis of planning here, as it's beyond the scope of this 'tutorial' to go any further in-depth, but if you do feel the need to, there are several books on offer pertaining to just those stages and that also delve into applying your plan to an object-oriented environment.
Moving on to the actual creation, here are now a few points to keep in mind when making your application.
UI - User Interface - What you SEE
Think of it in stages, first everything is disabled apart from the button that opens the map. But once a map is opened the treeview comes to life displaying the tags of the map. On selecting one of them the meta editor comes to life with the properties of the selected tag. Simple, although this has left a bug in the application: What if the user selects a tag class? (such as 'weap'), we know that a class is not a tag and thus doesn't contain any defining properties/meta. In this case you would instead disable the meta editor. Note that this is also something you should have considered when thinking out possible scenarios.
Multiple windows are generally a bad idea, and you should definitely avoid having very many at all. Tabcontrols on the other hand are better for when you need to display multiple pieces of information about something, but have limited space to work with. There is one thing I should mention though about tabcontrols; their disabled state.
It looks crap. Please never disable a tabcontrol! A more interesting way of doing things is to actually remove the tabpages on startup, and then add them back in when needed. Note that the following code is C#, but should be easily transferable to both VB and C++. If you can't convert then google a converter; theres a lot of them around on the net these days.
C#
Code: Select all
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
tabControl1.TabPages.Clear();
}
private void button1_Click(object sender, EventArgs e)
{
// Open the map here..
if (tabControl1.TabCount == 0)
{
tabControl1.TabPages.AddRange(new TabPage[] {
tabPage1, tabPage2 });
}
}
}
And as you can see if you try it out, a much better effect is achieved.
TextBoxes
Just one small quiff with these, I have no idea why but for some reason the makers of the almighty textbox for VS2005, decided to not add in the Ctrl + A shortcut. Which in my eyes is one of the best shortcuts a textbox could have. Anyway, to implement it modify the PreviewKeyDown event of the textbox as follows:
C#
Code: Select all
private void textBox1_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
{
if (e.Control && e.KeyCode == Keys.A)
textBox1.SelectAll();
}
Commenting
Comments are the nice little green lines that explain whats going on where, but sometimes it is possible to over do it quite spectacularly (again, something else i have fallen trap to).
C#
Code: Select all
//declares 'num' to be an integer that is equal to 0
int num = 0;
//increments 'num' by 5
num += 5;
The other problem with these comments is that they are not needed. It seems as if you are trying to teach someone the language here, but in reality they are expected to already know it. What comments should actually be telling you is the why, there should also be a gap after the slashes for clarity, and the comment itself should be written as a proper sentence/paragraph.
C#
Code: Select all
int num = 0;
// We increment the number as such to make
// things a little more interesting.
num += 5;
C#
Code: Select all
public int num;
C#
Code: Select all
private int num;
public int Num { get { return num; } set { num = value; } }
Accessors should always be uses because it allows you to separate the details of how the data is stored from how it is used. By using accessor functions, you can later change how the data is stored without having to rewrite any of the other functions in your program that use the data.
Although accessors are a pain to implement (we'll come back to this..), they make your program so much easier to manage and maintain, plus add such a layer of professionalism that'd you'd by silly to not use them =|
I haven't exactly mentioned it yet, but the get and set do actually act as functions. There's no limit to how many instructions they can hold but as a general rule you want to keep it pretty small. As an example we will make an accessor that stores the first four letters of the map, which we know to be 'deah':
C#
Code: Select all
#region Instance Data
private string __head__;
#endregion
#region Accessors
///<summary>
/// Head
///</summary>
public string Head { get { return __head__; } set { if (value.Length <= 4) __head__ = value; } }
#endregion
Going back to they're a pain to implement (and you can't deny they aren't ), I have gone and laboured over, well, an application that will generate them for you
Click HERE to download. We will now quickly go over the screenshot:
The first thing you may notice is the rather nice layout ( ).. the 2nd is that two underscores have been added to each side of the private member. This is done with the built in macros in C++, so to not get in the way of any of your own custom names. I think it's a good idea and not to over the top thus its implementation.
Summaries
The next thing you may have noticed is that each accessor has it's own summary. By default the app will insert the name of the accessor, but feel free to change that. Summaries are always useful for explaining properties:
They can also be used to explain methods too:
..and classes and structs..the list goes on and on...
The BinaryReader and BinaryWriter
They're great classes, but there are a few things that may not be so obvious at first:
1.
C#
Code: Select all
string str = "hello";
bw.Write(str);
This will not just write the string, but just before the string the length of the string will actually be written as well. To avoid this, do the following instead:
C#
Code: Select all
string str = "hello";
bw.Write(str.ToCharArray());
2.
C#
Code: Select all
char[] chars = br.ReadChars(4);
The ReadChars method has a tendency to trot off down the stream if at the current position there is not a valid char. This usually results in unexpected, and unwanted results (one of them being the app crashing as the reader tries to continue past the stream). To avoid:
C#
Code: Select all
char[] chars = Encoding.ASCII.GetChars(br.ReadBytes(4));
I have written 2 classes that expand upon the BinaryReader and BinaryWriter, that fix the above 'errors' and add more functionality, and have dubbed them BitReader and BitWriter. You can download them HERE. Enjoy =)
Classes vs Structs
I'm not going to go into it here, but I will point you to a place that explains it in detail. Again the code is C#, but can be applied to both VB and C++ (the .nf2.0 or higher C++ that is). LINK
Security
With visual studio your application is compiled into the Intermediate language (IL). But the thing is it is very easy to reverse engineer this language to get at the original source code, the applications that do this are known as decompilers. To battle them we have what is known as obfusticators. These powerful applications take the source code and scramble it wherever possible, giving the lowlife that is trying to read your source code a real hard time at it.
Buy Visual Studio and you'll get a pretty good obfusticator as an extra, but for those of us with the express editions the best freeware obfusticator I could find was HERE. Its a 'light' version of the proper one being sold on that website, but I have found it to be actually rather good.
End
If I think up anything else I'll be sure to add it in, or if you feel something's missing feel free to post and I'll look into it.
You might wonder why I felt the need to write such a 'reference'. The answer to that, if I'm being honest, is because that many of the applications posted here on halomods have lacked any 'professionalism' in my eyes, including my own, and so I thought by putting up a reference that examined a few 'essential' points, we could stop with the crap (don't take that personally) and move on to the good
Enjoy,
~Prey
Update1 - Link to BitRW.