In this chapter, we will be covering the fundamentals of Windows. To create a program, also called an application, you derive a class from the MFC's CWinApp. CWinApp stands for Class for a Windows Application.
Let us look into a simple example by creating a new Win32 project.
Step 1 − Open the Visual studio and click on the File → New → Project menu option.
Step 2 − You can now see the New Project dialog box.
Step 3 − From the left pane, select Templates → Visual C++ → Win32.
Step 4 − In the middle pane, select Win32 Project.
Step 5 − Enter the project name ‘MFCWindowDemo’ in the Name field and click OK to continue. You will see the following dialog box.
Step 6 − Click Next.
Step 7 − Select the options as shown in the dialog box given above and click Finish.
Step 8 − An empty project is created.
Step 9 − To make it an MFC project, right-click on the project and select Properties.
Step 10 − In the left section, click Configuration Properties → General.
Step 11 − Select the Use MFC in Shared DLL option in Project Defaults section and click OK.
Step 12 − Add a new source file.
Step 13 − Right-click on your Project and select Add → New Item...
Step 14 − In the Templates section, click C++ File (.cpp).
Step 15 − Set the Name as Example and click Add.
Any application has two main sections −
Let us create a window using the following steps −
Step 1 − To create an application, we need to derive a class from the MFC's CWinApp.
#include class CExample : public CWinApp { BOOL InitInstance() { return TRUE; } };
Step 2 − We also need a frame/window to show the content of our application.
Step 3 − For this, we need to add another class and derive it from the MFC's CFrameWnd class and implement its constructor and a call the Create() method, which will create a frame/window as shown in the following code.
class CMyFrame : public CFrameWnd { public: CMyFrame() { Create(NULL, _T("MFC Application Tutorial")); } };
Step 4 − As you can see that Create() method needs two parameters, the name of the class, which should be passed as NULL, and the name of the window, which is the string that will be shown on the title bar.
After creating a window, to let the application use it, you can use a pointer to show the class used to create the window. In this case, the pointer would be CFrameWnd. To use the frame window, assign its pointer to the CWinThread::m_pMainWnd member variable. This is done in the InitInstance() implementation of your application.
Step 1 − Here is the implementation of InitInstance() in CExample class.
class CExample : public CWinApp { BOOL InitInstance() { CMyFrame *Frame = new CMyFrame(); m_pMainWnd = Frame; Frame->ShowWindow(SW_NORMAL); Frame->UpdateWindow(); return TRUE; } };
Step 2 − Following is the complete implementation of Example.cpp file.
#include <afxwin.h> class CMyFrame : public CFrameWnd { public: CMyFrame() { Create(NULL, _T("MFC Application Tutorial")); } }; class CExample : public CWinApp { BOOL InitInstance() { CMyFrame *Frame = new CMyFrame(); m_pMainWnd = Frame; Frame->ShowWindow(SW_NORMAL); Frame->UpdateWindow(); return TRUE; } }; CExample theApp;
Step 3 − When we run the above application, the following window is created.
Windows styles are characteristics that control features such as window appearance, borders, minimized or maximized state, or other resizing states, etc.
Sr.No. | Style & Description |
---|---|
1 | WS_BORDER Creates a window that has a border. |
2 | WS_CAPTION Creates a window that has a title bar (implies the WS_BORDER style). Cannot be used with the WS_DLGFRAME style. |
3 | WS_CHILD Creates a child window. Cannot be used with the WS_POPUP style. |
4 | WS_CHILDWINDOW Same as the WS_CHILD style. |
5 | WS_CLIPCHILDREN Excludes the area occupied by child windows when you draw within the parent window. Used when you create the parent window. |
6 | WS_CLIPSIBLINGS Clips child windows relative to each other; that is, when a particular child window receives a paint message, the WS_CLIPSIBLINGS style clips all other overlapped child windows out of the region of the child window to be updated. (If WS_CLIPSIBLINGS is not given and child windows overlap, when you draw within the client area of a child window, it is possible to draw within the client area of a neighboring child window.) For use with the WS_CHILD style only. |
7 | WS_DISABLED Creates a window that is initially disabled. |
8 | WS_DLGFRAME Creates a window with a double border but no title. |
9 | WS_GROUP Specifies the first control of a group of controls in which the user can move from one control to the next with the arrow keys. All controls defined with the WS_GROUP style FALSE after the first control belong to the same group. The next control with the WS_GROUP style starts the next group (that is, one group ends where the next begins). |
10 | WS_HSCROLL Creates a window that has a horizontal scroll bar. |
11 | WS_ICONIC Creates a window that is initially minimized. Same as the WS_MINIMIZE style. |
12 | WS_MAXIMIZE Creates a window of maximum size. |
13 | WS_MAXIMIZEBOX Creates a window that has a Maximize button. |
14 | WS_MINIMIZE Creates a window that is initially minimized. For use with the WS_OVERLAPPED style only. |
15 | WS_MINIMIZEBOX Creates a window that has a Minimize button. |
16 | WS_OVERLAPPED Creates an overlapped window. An overlapped window usually has a caption and a border. |
17 | WS_OVERLAPPED WINDOW Creates an overlapped window with the WS_OVERLAPPED, WS_CAPTION, WS_SYSMENU, WS_THICKFRAME, WS_MINIMIZEBOX, and WS_MAXIMIZEBOX styles. |
18 | WS_POPUP Creates a pop-up window. Cannot be used with the WS_CHILD style. |
19 | WS_POPUPWINDOW Creates a pop-up window with the WS_BORDER, WS_POPUP, and WS_SYSMENU styles. The WS_CAPTION style must be combined with the WS_POPUPWINDOW style to make the Control menu visible. |
20 | WS_SIZEBOX Creates a window that has a sizing border. Same as the WS_THICKFRAME style. |
21 | WS_SYSMENU Creates a window that has a Control-menu box in its title bar. Used only for windows with title bars. |
22 | WS_TABSTOP Specifies one of any number of controls through which the user can move by using the TAB key. The TAB key moves the user to the next control specified by the WS_TABSTOP style. |
23 | WS_THICKFRAME Creates a window with a thick frame that can be used to size the window. |
24 | WS_TILED Creates an overlapped window. An overlapped window has a title bar and a border. Same as the WS_OVERLAPPED style. |
25 | WS_TILEDWINDOW Creates an overlapped window with the WS_OVERLAPPED, WS_CAPTION, WS_SYSMENU, WS_THICKFRAME, WS_MINIMIZEBOX, and WS_MAXIMIZEBOX styles. Same as the WS_OVERLAPPEDWINDOW style. |
26 | WS_VISIBLE Creates a window that is initially visible. |
27 | WS_VSCROLL Creates a window that has a vertical scroll bar. |
Step 1 − Let us look into a simple example in which we will add some styling. After creating a window, to display it to the user, we can apply the WS_VISIBLE style to it and additionally, we will also add WS_OVERLAPPED style. Here is an implementation −
class CMyFrame : public CFrameWnd { public: CMyFrame() { Create(NULL, _T("MFC Application Tutorial"), WS_VISIBLE | WS_OVERLAPPED); } };
Step 2 − When you run this application, the following window is created.
You can now see that the minimize, maximize, and close options do not appear anymore.
To locate things displayed on the monitor, the computer uses a coordinate system similar to the Cartesian's, but the origin is located on the top left corner of the screen. Using this coordinate system, any point can be located by its distance from the top left corner of the screen of the horizontal and the vertical axes.
The Win32 library provides a structure called POINT defined as follows −
typedef struct tagPOINT { LONG x; LONG y; } POINT;
The ‘x’ member variable is the distance from the left border of the screen to the point.
The ‘y’ variable represents the distance from the top border of the screen to the point.
Besides the Win32's POINT structure, the Microsoft Foundation Class (MFC) library provides the CPoint class.
This provides the same functionality as the POINT structure. As a C++ class, it adds more functionality needed to locate a point. It provides two constructors.
CPoint(); CPoint(int X, int Y);
While a point is used to locate an object on the screen, each window has a size. The size provides two measures related to an object.
The Win32 library uses the SIZE structure defined as follows −
typedef struct tagSIZE { int cx; int cy; } SIZE;
Besides the Win32's SIZE structure, the MFC provides the CSize class. This class has the same functionality as SIZE but adds features of a C++ class. It provides five constructors that allow you to create a size variable in any way of your choice.
CSize(); CSize(int initCX, int initCY); CSize(SIZE initSize); CSize(POINT initPt); CSize(DWORD dwSize);
When a Window displays, it can be identified on the screen by its location with regards to the borders of the monitor. A Window can also be identified by its width and height. These characteristics are specified or controlled by the rect argument of the Create() method. This argument is a rectangle that can be created through the Win32 RECT structure.
typedef struct _RECT { LONG left; LONG top; LONG right; LONG bottom; } RECT, *PRECT;
Besides the Win32's RECT structure, the MFC provides the CRect class which has the following constructors −
CRect(); CRect(int l, int t, int r, int b); CRect(const RECT& srcRect); CRect(LPCRECT lpSrcRect); CRect(POINT point, SIZE size); CRect(POINT topLeft, POINT bottomRight);
Let us look into a simple example in which we will specify the location and the size of the window
class CMyFrame : public CFrameWnd { public: CMyFrame() { Create(NULL, _T("MFC Application Tutorial"), WS_SYSMENU, CRect(90, 120, 550, 480)); } };
When you run this application, the following window is created on the top left corner of your screen as specified in CRect constructor in the first two parameters. The last two parameters are the size of the Window.
In the real world, many applications are made of different Windows. When an application uses various Windows, most of the objects depend on a particular one. It could be the first Window that was created or another window that you designated. Such a Window is referred to as the Parent Window. All the other windows depend on it directly or indirectly.
If the Window you are creating is dependent of another, you can specify that it has a parent.
This is done with the pParentWnd argument of the CFrameWnd::Create() method.
If the Window does not have a parent, pass the argument with a NULL value.
Let us look into an example which has only one Window, and there is no parent Window available, so we will pass the argument with NULL value as shown in the following code −
class CMyFrame : public CFrameWnd { public: CMyFrame() { Create(NULL, _T("MFC Application Tutorial"), WS_SYSMENU, CRect(90, 120, 550, 480), NULL); } };
When you run the above application, you see the same output.