Log Edit Demo
A log control window

Introduction
Have you seen the output window of Developer Studio? It is actually an edit box, but you cannot write anything to it, it scrolls automatically and the cursor blinks at the end of the last line. Even AutoCAD has a similar command window. So, how do we make a similar control for our own applications? Read on...

Background
Using only a CEdit
class will not solve the problem. So, we have to derive a class from CEdit
and add the necessary lines of code to modify the control. You can implement this in one of two ways:
- Download the source files and attach them to your project. Add some modifications like a header file and resource ID.
- You can do it manually and do the coding yourself. Unlike the MS-DOS mode programming where the
printf();
function prints a line to the screen, updates the cursor position and scrolls to the next line, aCEdit::SetWindowText()
function doesn't do all that. Everything will have to be done by writing the code.
Here is how to do it.
Using the Code
Method 1: the Easy Way
First, add the files LogEdit.cpp and LogEdit.h (after downloading the files) to your project. Then add the header files to YourDlg.h file.
//YourDlg.h
#include "LogEdit.h" // Add this line
To the same file, add this:
//YourDlg.h
// Dialog Data
//{{AFX_DATA(YourDlg)
enum { IDD = IDD_YOUR_DIALOG };
CLogEdit m_LogEdit; //
Add this line
//}}AFX_DATA
To the YourDlg.cpp file, add this:
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CLog_Edit_DemoDlg)
DDX_Control(pDX, IDC_LOG_EDIT, m_LogEdit);//
Add this line
//}}AFX_DATA_MAP
In the resource editor, draw a text box and change the ID from IDC_EDIT1
to IDC_LOG_EDIT
. Now let us look at the CLogEdit
class:
// ClogEdit.h file
public:
int flag;
CString PromptStr;
// Operations
public:
void InsertLines(CString Line, BOOL st);
void UpdateCaretPos();
In the CPP file, you need to add these. While some will use message handling code like WM_LBUTTONDOWN
, others will use the class wizard to add the lines instead of doing it themselves.
// ClogEdit.cpp file
CLogEdit::CLogEdit()
{
flag=1;
PromptStr="Prompt::";
}
CLogEdit::~CLogEdit()
{
}
BEGIN_MESSAGE_MAP(CLogEdit, CEdit)
//{{AFX_MSG_MAP(CLogEdit)
ON_WM_SETFOCUS()
ON_WM_CHAR()
ON_WM_LBUTTONDBLCLK()
ON_WM_LBUTTONDOWN()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CLogEdit message handlers
void CLogEdit::InsertLines(CString Line,BOOL st)
{
CString wndtext;
GetWindowText ( wndtext );
int text_length = wndtext.GetLength() ;
if( text_length <=1)
{
if(!st)wndtext = wndtext + Line ;
else
wndtext = wndtext + PromptStr + Line ;
}
else
{
if(!st)wndtext = wndtext +"\r\n"+ Line ;
else
wndtext = wndtext + "\r\n"+PromptStr + Line ;
}
// Writing to the screen
SetWindowText ( wndtext );
// Scrolling to the next line
LineScroll ( GetLineCount(), 0x0 );
}
void CLogEdit::UpdateCaretPos()
{
// This is the real tricky part where you have to take the cursor to the ed
//of the last character of the last line
// Take the cursor to the last line first
for ( int i = 0 ; i < GetLineCount() ; i++ )
SendMessage( WM_KEYDOWN, VK_DOWN , 0x0 ) ;
// Then take the cursor to the last character
for ( i = 0 ; i < LineLength( GetLineCount() - 1 ) ; i++ )
SendMessage( WM_KEYDOWN, VK_RIGHT , 0x0 ) ;
}
void CLogEdit::OnSetFocus(CWnd* pOldWnd)
{
CEdit::OnSetFocus(pOldWnd);
//Do the initialization like printing something
if(flag==1)
{
flag=0;
InsertLines("Log Edit Demo Version 1.0 Feb-2008",FALSE);
InsertLines("------------------------------------------ ",FALSE);
}
UpdateCaretPos();
}
void CLogEdit::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
{
UpdateCaretPos();
//Forcefully return the function so that no text is entered by the
//user and the control becomes read-only
return;
// CEdit::OnChar(nChar, nRepCnt, nFlags);
}
void CLogEdit::OnLButtonDblClk(UINT nFlags, CPoint point)
{
// Update the Caret position
UpdateCaretPos();
}
void CLogEdit::OnLButtonDown(UINT nFlags, CPoint point)
{
// Update the Caret position
UpdateCaretPos();
}
This is almost finished.
Method 2: Now Try the Hard way
Here you have to make a new project first. Select a dialog-based application and let the AppWizard do the initial set of coding for you. Then select the edit box control and draw an edit box of your own size. Give it some ID like IDC_MY_LOG_EDIT
. Once you're done with it, from the class wizard select the Add a Class button and New MFC Class. Derive it from the CEdit
class and give it some appropriate name like CMyLogEdit
, etc.
After this, again use the class wizard and go to the Member Variables tab. Select the ID, i.e. IDC_MY_LOG_EDIT
, and click the Add Variable button. Then from the Category, select Control. From Variable Type, select the new class (CMyLogEdit
) you have just made. Now the control you see on screen is not the CEdit
control of MFC, but it is our own hand-made control. Do the necessary modification to the new class to obtain the desired output.
Points of Interest
So, that’s it. This class may help you to learn how to modify the in-built classes and make them look like yours
History
- 8 February, 2008 -- Original version posted