September 2004 - Posts
Today’s class was pretty much boring because all that we learnt was “The Programming Elements in VC++”. It is the plain old stuff. I was curious to know more about Windows Message Processing. I had once read about it in “Visual Basic 6.0 Bible”. The context was the difference between event-based programming platform (like MS VB 6.0) and something like VC++, where we deal with Windows Messages directly. So I just collected some info about Windows Messages and I’m including the same here.
Programming elements in VC++
1. Compiler
2. Source code editor
3. Class view window
4. Debugger
5. Linker
6. Resource view window
1. Compiler: Used to compile the source code written in C/C++
2. Source code editor: It is a window wherein you can type the source code of an MFC Application
3. Class view window: The classes created can be hierarchically viewed here
4. Debugger: Used to debug the program. It is displayed on the bottom panel and once the error is clicked, the source code editor, points to the corresponding line. This makes debugging easier
5. Linker: Links the resource files and the source code and creates an EXE
6. Resource view window: Displays the various resources used in the MFC application. Eg.: Bitmaps, Icons etc.
Windows Message Processing
I am sure you would have written at least one C program by now. It is known that the operating system calls the main function when the program is run. So this is a pre-requisite for the operating system to identify the starting point of execution of the program. Thereon, we write the application in the structure we want. If we have to get an input from the user in the C program, we use getchar. The program uses the calls appropriate functions to avail the services provided by the OS.
When Windows launches a program, it calls the WinMain function. So all our Windows-based application WILL have a function called WinMain defined somewhere or the other. Some programming platforms like VB and VC++ hide it from the developer to redude complexity. The important task of WinMain is to create the application window. In case of VC++, the structured message handling process is also hidden to reduce the code complexity and allows the developer to concentrate on more niche areas.
The main difference between an MS DOS based application and a Windows-based application is that the MS DOS program calls the OS (or its system calls) to get user input, whereas in case of Windows programs receive input via “messages” from the OS.
Examples of some Windows Messages
WM_CREATE: message is sent when a window is being created
WM_LBUTTONDOWN: message is sent when the user presses the left mouse button
WM_CHAR: message is sent when the user types a character
WM_CLOSE: message is sent when the user closes a window
Creating a simple MFC application
1. Run AppWizard to generate SDI application source code. Choose New from Visual C++'s File menu, and then click the Projects tab in the resulting New dialog box, as shown here.
2. Type TestApp as shown in the Project Name edit box, and then click the OK button. Now you will step through a sequence of AppWizard screens
3. Select the Single Document option. Accept the defaults in the next four screens.
4. Click the Finish button. Just before AppWizard generates your code, it displays the New Project Information dialog box.
5. Use F7 to compile and F5 to run the EXE
The The CTestAppView View Class
AppWizard generates the CTestAppView view class, and this class is specific to the TestApp application. (AppWizard generates classes based on the project name you entered in the first AppWizard dialog box.) CTestAppView is at the bottom of a long inheritance chain of MFC library classes.
Drawing an object inside the View Window
The OnDraw Member Function
OnDraw is a virtual member function of the CView class that the application framework calls every time the view window needs to be repainted (This wasn’t known to me until I fetched it from Google).
The Windows Device Context
Windows doesn't allow direct access to the display hardware but communicates through an abstraction called a "device context" that is associated with the window. In the MFC library, the device context is a C++ object of class CDC (I think it stands for C Device Context) that is passed (by reference) as a parameter to OnDraw. After you have the device context pointer, you can call the many CDC member functions that do the work of drawing.
Edit the OnDraw function in TestAppView.cpp. Find the AppWizard-generated OnDraw function in TestAppView.cpp:
void CEx03aView::OnDraw(CDC* pDC)
{
pDC->TextOut(0, 0, "Hello, world!"); // prints in default font & size, top left corner
pDC->SelectStockObject(GRAY_BRUSH); // selects a brush for the interior
pDC->Ellipse(CRect(0, 20, 100, 120)); // draws a gray circle 100 units in diameter
}
Just hit F7 and compile and run the application by pressing F5. Yo! That’s it for now.
I have joined a course for MS VC++. I’ve thought of putting up stuff o’er here as and when I am learning. I have classes on Saturday & Sunday. So, I’ll be summarizing stuff what I learnt for the day.
Today it was a class on basics of VC++ and its architecture. The topics that are going to be covered as a part of the course are:
1. Intro to MFC
2. MFC Base classes and Dialog boxes
3. MFC Applications
4. Intro to Com
5. COM objects and libraries
6. COM Interfaces
7. ActiveX Template Library
8. Creation of COM client
9. Automation and dual interfaces
10. ActiveX controls
11. Data access with ADO
12. Marshalling and COM threading models
13. ActiveX server components
14. COM using Microsoft Transaction Server
15. COM+ and Windows DNA
Class 1: Introduction to MFC
Overview of MFC
• MFC class library is an application framework for writing applications for Windows platform or any other platform that supports Win32 APIs
• It is a collection of C++ classes or in other words MFC is an encapsulation of large portion of Windows API in C++ form
• Using MFCs, we can create Windows dialog boxes, device context and other common graphic objects
• Classes provided by MFCs are accessed through interfaces. MFC code is compiled and converted into Win32 API calls.
Execution of MFC
There are two steps of execution:
1. Code compilation
2. Resource compilation
Code compilation: The source code is compiled along with the required libraries (windows headers and runtime header files) and an obj file is created.
Resource compilation: Resource files like images, icons, bitmaps etc compiled separately and a RES file is obtained.
The outputs of both the compilers (code and resource) are linked together and the final executable file is obtained.
MFC Base Classes
There are two main base classes in MFC:
1. cWinApp
2. cFrameWnd
cWinApp class: This is the base class from which a windows application object is derived. An application object consists of member functions for initializing applications. cWinApp class provides3 methods:
1. InitInstance(): This method is called when the application object is loaded into the memory.
2. Run(): This method acquires tand dispatches windows calls until the application receives the WM_QUIT (a constant), message. (ie. when “X” button is pressed)
3. ExitInstance(): It is called when an application object is removed from the memory
Just a sample program to create a frame and display a message box when InitInstance() is invoked
#include<afxwin.h>
class MyWindow : Public cFrameWnd
{
Public:
MyWindow()
{
// NULL is for icon
create(NULL, “Sample window”);
}
~MyWindow()
{
messageBox(“Sample window”, “cFrameWnd”);
}
};
class MyApp : Public cWinApp
{
Public:
// Override these methods
BOOL InitInstance();
BOOL ExitInstance();
}
BOOL MyApp :: InitInstance()
{
:: messageBox(o, “Sample Window”, “InitInstance”, MB_OK | MB_ICONASTERIX);
MyWindow mywinobj;
Mywinobj = new MyWindow;
// Speicify the main window
M_PMainWnd = mywinobj;
Mywinobj->showwindow(SW_SHOWMAXIMIZED);
return TRUE;
}
It is always better to understand these concepts with an example rather than trying to understand paragraphs of explanation.
Example:
class sharpTest
{
static void Main() {
string s = "Sunil";
string t = string.Copy(s);
Console.WriteLine(s == t);
Console.WriteLine((object)s == (object)t);
}
}
Output:
True
False
Inference:
Two expressions of type object are considered equal if both refer to the same object, or if both are null.
Two expressions of type string are considered equal if the string instances have identical lengths and identical characters in each character position, or if both are null.
Type conversions are similar to C++. Implicit conversions like int to long are done without any loss of data. Explicit conversions are done with a cast expression.
Arrays in C#
As usual, single-dimensional and multi-dimensional arrays are supported.
// Creates a single-dimensional array of 5 elements
int[] arr = new int[5];
What is to be noted is that arrays are also reference types and hence have to be explicitly allocate the memory by specifying the size of the array.
// Some more arrays
int[,,] a3; // 3-dimensional array of int
int[][] j2; // "jagged" array: array of (array of int)
int[][][] j3; // array of (array of (array of int))
Type system unification
class Test
{
static void Main() {
Console.WriteLine(3.ToString());
}
}
All types including value types are derived from the type object. It is possible to call object methods on any value, even values of “primitive” types such as int.
First time I saw the C# code in a magazine, I thought “Oh Damn it. Another new language, new syntax, new keywords…more confusion”. But now I don’t think so. C# is not completely different from other languages speaking of its syntax and approach. Moving further on, I learnt about the data types in C#.
C# supports two kinds of types: value types and reference types. No big deal. The name says it all. In case of values types, the variable stores the value directly and in case of reference types, it stores the reference to the variable (address). Other concepts like possibility of two variables referencing the same object are possible as in the case of C++.
A sample program to understand the types:
using System;
class ClassObj
{
public int num = 0;
}
class ClassTest
{
static void Main()
{
int x = 0;
int y = x;
y = 101;
ClassObj ref1 = new ClassObj();
ClassObj ref2 = ref1;
ref2.num = 999;
Console.WriteLine("Values: {0}, {1}", x, y);
Console.WriteLine("Refs: {0}, {1}", ref1.num, ref2.num);
}
}
C:\WINNT\Microsoft.NET\Framework\v1.0.3705>csc D:\cstypes.cs
Microsoft (R) Visual C# .NET Compiler version 7.00.9466
for Microsoft (R) .NET Framework version 1.0.3705
Copyright (C) Microsoft Corporation 2001. All rights reserved.
C:\WINNT\Microsoft.NET\Framework\v1.0.3705>cstypes
Values: 0, 101
Refs: 999, 999
An interesting thing that I’ve observed is the method used to print the formatted output in Console.WriteLine
Console.WriteLine takes a variable number of arguments. The first argument is a string, which may contain numbered placeholders like {0} and {1}. Each placeholder refers to a trailing argument with {0} referring to the second argument, {1} referring to the third argument, and so on. Before the output is sent to the console, each placeholder is replaced with the formatted value of its corresponding argument.
I was going through a list of articles available on the INETA website. I came across an article with the heading “Why C # is sharp and why is VB.NET basic?” Hmmm… However, the author has no intentions of looking down upon VB. I have done quite a few projects in VB 6. I am still a VB enthusiast because what I like most about it, is its simplicity and ability to do amazing stuff with little effort (directly proportional to coding?? Ahem…).
A few days back, I had read an extensive comparison between 11 languages in the September 2004 edition of DIQ (Developer IQ http://www.developeriq.com). It was called “The Great Language Shootout”. The article tabulates the results with C# scoring an overall 68pts and Java landing at 65pts. The article also explains in detail about the evaluation process. These figures are clearly just indicators of a test process and cannot form the basis to decide the power and application of any language or its future.
Unable to resist the temptation, I decided to write a simple HelloWorld… nope not just World… HelloManagedWorld program in C#. Managed because, I’m using the .NET csc compiler.
The code:
using System;
class helloManagedWorld
{
static void Main()
{
Console.WriteLine("Hello Managed World!");
}
}
Some explanation:
The using System; directive references a namespace called System that is provided by the Microsoft .NET Framework class library. This namespace contains the Console class referred to in the Main method. Namespaces provide a hierarchical means of organizing the elements of one or more programs. A “using” directive enables unqualified use of the types that are members of the namespace. The “Hello Managed World!” program uses Console.WriteLine as shorthand for System.Console.WriteLine.
The Main method is a member of the class helloManagedWorld. It has the static modifier, and so it is a method on the class helloManagedWorld rather than on instances of this class.
The entry point for an application—the method that is called to begin execution—is always a static method named Main.
How to compile the geeky way (ie. if you only have the .NET Framework, without VS.NET):
I started off with some errors as usual... case sensitivity and some syntax problems…
C:\WINNT\Microsoft.NET\Framework\v1.0.3705>csc helloWorld.cs
Microsoft (R) Visual C# .NET Compiler version 7.00.9466
for Microsoft (R) .NET Framework version 1.0.3705
Copyright (C) Microsoft Corporation 2001. All rights reserved.
helloWorld.cs(4,30): error CS1552: Array type specifier, [], must appear before
parameter name
C:\WINNT\Microsoft.NET\Framework\v1.0.3705>csc helloWorld.cs
Microsoft (R) Visual C# .NET Compiler version 7.00.9466
for Microsoft (R) .NET Framework version 1.0.3705
Copyright (C) Microsoft Corporation 2001. All rights reserved.
error CS5001: Program 'helloWorld.exe' does not have an entry point defined
C:\WINNT\Microsoft.NET\Framework\v1.0.3705>csc helloWorld.cs
Microsoft (R) Visual C# .NET Compiler version 7.00.9466
for Microsoft (R) .NET Framework version 1.0.3705
Copyright (C) Microsoft Corporation 2001. All rights reserved.
C:\WINNT\Microsoft.NET\Framework\v1.0.3705>helloWorld
Hello World!
Wasn’t that simple enough? So this is just the beginning. Lets see where I go from here. :-)
Hi!
I am Sunil Jagadish (a.k.a HandledException – Sounds geeky eh? Not to worry. I am not so.) Ok if you know about me, that’s fine. Lets get down to business. If you don’t know much about me, I suggest you take a peek at my general blog http://suniljagadish.blogspot.com
I am learning .NET now. So the info what you can find about .NET o’er here would be basic stuff. If you still think that you would be interested, go ahead!
Critical comments, views, suggestions etc are solicited.
Happy programming!!