Introduction
A simple text editor is the first application which a programmer makes in the beginning of his/her career. The simplest way to create the editor is to realize it by using Microsoft Windows Edit control. The control supports both the Unicode character set in which characters are two bytes, and ANSI character set in which characters are one byte. Microsoft Windows Notepad is a common plain text editor included in all versions of Windows.
I would like to call your attention to my new program Newpad which is a simple text editor similar to Microsoft Windows Notepad. This program serves the purpose to study editor design principles and it represents a complete software product. I hope it will be useful for somebody who has made applications working with text files. This project contains several useful functions that provide access to text files and work with Edit control.
Newpad is a complete organized product with help, installer, source code and documentation. In this article, I will describe the project essence and features in short words. It is impossible to overview all its aspects in details in the compact form. For details, you can see the project source code in the zip package.
What Interesting Things Can be Found in the Project
- Error handling and debugging
- Common window creation and manipulation technique
- Creating and customizing dialog box
- Customizing Save File dialog box
- Work with registry
- Creating toolbar and status bar and manipulation with it
- Sending e-mail from a program
- Common technique work with Edit control (text operations, buffer access, search a string, printing, processing caret position in the control, etc.)
Newpad Overviews
User Appearance
From the user viewpoint, Newpad has several distinguishing features, which make it more user friendly than Notepad. In short, you can use it in the same way as Notepad but there are some differences between Newpad and Notepad. From the user viewpoint, these are:
- The Newpad has a toolbar but Notepad does not.
You can show or hide the Newpad toolbar and status bar by clicking the View menu and then clicking the name of the toolbar that you want to show or hide.
- The Newpad can open and correctly display files which contain UNIX and Macintosh style end of line attribute but Notepad cannot.
When Newpad opens a file, it automatically distinguishes style of the end of line attribute. Newpad correctly displays files Windows and UNIX style end of file attribute. However, if you want to save file Newpad will keep former formatting.
- Notepad has the ability to detect Unicode files even when they are missing a byte order mark. Newpad always check up the byte order mark in Unicode files.
Using the Code
Build Environment
You can find the source code for the program in the zip archive. It has a Microsoft Visual Studio 2008 solution file. However you can use the source code as you wish and create your own project files. Newpad also can be correctly recompiled using Visual C++ 6.0. Newpad is a classical C application that uses only Win API calls. At present, only English and Russian versions of the resource script are available.
Particular Qualities of Debug Build
In debug version of the project you can find an additional project for the library NpDebug.dll. It provides advanced error handling for the project and may be useful for your own application. This library exports several functions which offer sending e-mail message to developer about assertions appearing in the debug version of the program. SimpleAssert
function displays a simple dialog box that informs the user about an assertion without any ability of feedback message sending. AdvancedAssert
function displays a dialog box that informs the user about the originated assertion and offers to send a message to the developer by e-mail. SendMail
is one more useful function which performs sending of message by current Windows e-mail setting. It is called by AdvancedAssert
function, however it may be used independently. This function uses Windows MAPI environment and checks the return value after MAPI functions calling.
About Hyperlink Control
The program uses its own analogue of Hyperlink control. Any button on any dialog may be converted into this control. My hyperlink control is realized by replacing window procedure for the button. DrawHyperlinkControl
function draws the entry of the hyperlink. It is called when the new window procedure is processing WM_PAINT
message. OpenHyperLink
function performs launch of the action that you can set for the hyperlink.
An Interesting Feature of About Dialog
I present an interested feature of dialog box that can be used for freeware application under GPL. You have to fill PRODUCT_INFORMATION
structure fields and send the pointer to the structure in AboutFreewareDialog
function. This function displays a dialog box which includes a banner with icon and formatted text, short GPL fragment and hyper link to full GPL text. Of course, you can customize all of it as you want.
The Project Reference
Functions
As it was said above, because Newpad is a complete product, it is impossible to overview all its aspect in detail in a short article. Please look at the source code of the program for detailed familiarization with the functions.
int ReadTextFile(HANDLE hFile, LPTSTR* ppszText,
LPDWORD pdwTextLength, LPUINT pnEndcoding, LPUINT pnEOL);
Parameters
[in] hFile |
The file handle must have been created with GENERIC_READ access to the file. |
[out] *ppszText |
Pointer to a buffer that receives the text read from the file. This value cannot be NULL . |
[out] pdwTextLength |
Pointer to a DWORD value in which length of the text buffer will be returned. |
[out] pnEndcoding |
Pointer to a UINT value in which encoding of the text will be returned. |
[out] pnEOL |
Pointer to a UINT value in which end-of-line mark of the text will be returned. |
Return Values
If the function succeeds, the return value is 1
. If the function fails, the return value is 0
.
int WriteTextFile(HANDLE hFile, LPCWSTR pwcText,
DWORD dwTextLegth, UINT nEncoding, UINT nEOL);
Parameters
[in] hFile |
Handle to the file to be read. The file handle must have been created with the GENERIC_WRITE access right. |
[in] pwcText |
Pointer to the Unicode buffer containing the text to be written to the file. |
[in] dwTextLegth |
Length of the text in bytes. |
[in] nEncoding |
Text encoding. |
[in] nEOL |
End-of-line mark. |
Return Values
If the function succeeds, the return value is 1
. If the function fails, the return value is 0
.
If you would interrogate about other functions of the project in detail, you have to look at the source code.
Macros
You can use both CRT debug library and NpDebug library to debug this application. You have to include header files crtdbg.h or npdebug.h, correspondingly, and define one of these macros
#define ASSERT(s) _ASSERTE(s) or #define ASSERT(s) NP_ASSERT(s)
Messages
No ordinary messages handling is used in the program in two places. There are additional messages for find-replace dialog and messages, which appear in customized, save file dialog.
In the first case, we use:
uFindReplaceMsg = RegisterWindowMessage(FINDMSGSTRING);
to register new message. After it, the function IsFindReplaceMsg
checks the message and returns TRUE
if it is a message from find-replace modeless dialog. We use this function in the main
message loop (see WinMain
in Newpad.c for details).
In order to save text file in different encoding, we use a customized File Save dialog. We process the WM_NOTIFY
message notification that is sent to the hook dialog procedure for the File Save customized dialog. However, the handlers of the new messages are empty in the hook procedure (MyHookProc
in NpFiles.c for details).
Notifications
We handle notification messages from Edit control in Newpad main window procedure to update caret position message on status bar. In addition, we substitute Edit control window procedure for performing this task when the mouse pointer is fixed into the editor window.
Structures
FRDLG structure holds information about a string
which appears in find-replace dialog. The first member of the structure is Windows FINDREPLACE
structure variable, the second one is searching string
, the third is replacing string
.
EDITUI structure holds Boolean fields that describe toolbar, status bar and word warp user appearances.
EDITSTATE structure manages find-replace dialog user appearance. The first member of it is a pointer to FRDLG structure. Other members describe standard Window find-replace dialog user controls.
The structure TEXTDOC describes a text document. Members of this structure are: byte order mask, the text file encoding, end of line mark and the file name.
Constants
Most of constants are brought out in the header file so that it may be modified at your discretion.
Conclusion
I was struggling to write the code in a more readable form. The creation of the program was a good lesson for me. I did it from “bland print” to a complete application. Now I hope it will be useful for somebody how has taken his/her first steps in programming. For the readers, all your responses and wishes about this program are important. To make a suggestion or report a bug or another feature of this product, write to alexshag@mail.ru.