源程序中一小部分代码:文件名称:MyNotepad.cpp
// MyNotepad.cpp : Defines the entry point for the application.
//
#include "stdafx.h"
#include "resource.h"
#include "MyNotepad.h"
#include "PopFile.h"
#include "PopFont.h"
#include "PopFind.h"
#include "ErrorMessage.h"
#include "GetDllVersion.h"
LONG
OnLineWrap (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
//消息映射与处理函数对照表。
struct MSGMAP_ENTRY _messageEntries[] =
{
WM_CREATE, OnCreate,
WM_DESTROY, OnDestroy,
WM_SIZE, OnSize,
WM_SETFOCUS, OnSetFocus,
WM_CLOSE, OnClose,
WM_COMMAND, OnCommand
};
//COMMAND-ID处理对照表。
struct MSGMAP_ENTRY _commandEntries[] =
{IDM_ABOUT, OnAbout,
IDM_FILE_NEW, OnFileNew,
IDM_FILE_OPEN, OnFileOpen,
IDM_FILE_SAVE, OnFileSave,
IDM_FILE_SAVE_AS, OnFileSaveAs,
IDM_EDIT_FIND, OnEditFind,
IDM_EDIT_FIND_NEXT, OnEditFindNext,
IDM_EDIT_FIND_REPLACE, OnEditFindReplace,
IDM_DATATIME, OnDataTime,
IDM_APP_EXIT, OnAppExit,
IDM_FORMAT_FONT, OnFormatFont,
IDM_EDIT_UNDO, OnEditUndo,
IDM_EDIT_CUT, OnEditCut,
IDM_EDIT_COPY, OnEditCopy,
IDM_EDIT_PASTE, OnEditPaste,
IDM_EDIT_CLEAR, OnEditClear,
IDM_EDIT_SELECT_ALL, OnEditSelectAll,
IDM_STATIC, OnStatic,
IDM_LINE_WRAP, OnLineWrap
};
void SetStatusText (HWND hWndEdit, HWND hWndStatus);
//Edit控件窗口子类。
LRESULT
CALLBACK
EditSubWndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
// Global Variables:
HINSTANCE _hInst; //current instance
TCHAR _szAppName[MAX_LOADSTRING]; //程序名称。
TCHAR _szFileName[MAX_PATH]; //文件名称。
TCHAR _szTitleName[MAX_PATH]; //程序标题。
HWND _hDlgModeless; //查找对话框句柄。
HWND _hWndEdit; //Edit窗体句柄。
HWND _hWndStatus; //状态栏窗体句柄。
UINT _messageFindReplace; //查找对话框ID。
BOOL _bNeedSave; //文件需要保存标记。
WNDPROC _wpOrigEditProc; //原EDIT控件窗口过程函数地址。
int
APIENTRY
WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
MSG msg;
HWND hWnd;
HACCEL hAccel;
INITCOMMONCONTROLSEX cc;//通用控件类信息结构.
cc.dwSize = sizeof(INITCOMMONCONTROLSEX);
cc.dwICC = ICC_BAR_CLASSES;//状态栏类。
if(GetDllVersion (TEXT("comctl32.dll")) < PACKVERSION(4,71))
{
MessageBox (NULL, TEXT("comctl32.dll Version < 4.71"), NULL, MB_OK);
return FALSE;
}
if(!InitCommonControlsEx (&cc))
{
MessageBox (NULL, TEXT("InitCommonControlsEx ()"), NULL, MB_OK);
return FALSE;
}
MyRegisterClass(hInstance);
hWnd = InitInstance (hInstance, nCmdShow);
if(!hWnd) return FALSE;
hAccel = LoadAccelerators (hInstance, MAKEINTRESOURCE(IDR_ACCELERATOR1));
// Main message loop:
while ( GetMessage(&msg, NULL, 0, 0) )
{
if( _hDlgModeless == NULL || !IsDialogMessage (_hDlgModeless, &msg) )
{
if( !TranslateAccelerator (hWnd, hAccel, &msg) )
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
}
return msg.wParam;
}
ATOM
MyRegisterClass(HINSTANCE hInstance)
{
//加载应用程序标题栏文本字符串。
LoadString(hInstance, IDS_APP_TITLE, _szAppName, MAX_LOADSTRING);
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = (WNDPROC)WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ICON1));
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)COLOR_WINDOW+1;
wcex.lpszMenuName = NULL;
wcex.lpszClassName = _szAppName;
wcex.hIconSm = NULL;
return RegisterClassEx(&wcex);
}
HWND
InitInstance(HINSTANCE hInstance, int nCmdShow)
{
HWND hWnd;
_hInst = hInstance;
hWnd = CreateWindow(
_szAppName, //windows class name
_szAppName, //windows标题。
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
LoadMenu (hInstance, MAKEINTRESOURCE(IDR_MENU1)),
hInstance, NULL);
if (!hWnd) return NULL;
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return hWnd;
}
LRESULT
CALLBACK
WndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int i;
for( i=0; i < dim(_messageEntries); i++)
{
if( message == _messageEntries[i].nMessage)
return ( (*_messageEntries[i].pfn)(hWnd, message, wParam, lParam) );
}
//处理查找、替换对话框消息。
if( message == _messageFindReplace )
{
PopFindReplaceText (_hWndEdit, (LPFINDREPLACE)lParam);
SetForegroundWindow (hWnd);//设置前台窗体。
}
return ( DefWindowProc (hWnd, message, wParam, lParam) );
}
LONG
OnCommand (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int i;
for( i=0; i < dim(_commandEntries); i++)
{
if( LOWORD(wParam) == _commandEntries[i].nMessage)
return ( (*_commandEntries[i].pfn)(hWnd, message, wParam, lParam) );
}
//处理编辑控件命令。
if(lParam && LOWORD(wParam) == ID_EDIT)
{
MessageOperationEdit (_hWndEdit, wParam, &_bNeedSave);
}
return ( DefWindowProc (hWnd, message, wParam, lParam) );
}
//处理窗体消息。
LONG
OnCreate (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
if( !CreateEditText (hWnd, wParam, lParam) ) return 0;
if( !InitStatus (hWnd) ) return 0;
_wpOrigEditProc = (WNDPROC)SetWindowLong (_hWndEdit, GWL_WNDPROC, (LONG)EditSubWndProc);
//设置编辑控件可输入的最大字符数(硬极限)。
SendMessage (_hWndEdit, EM_LIMITTEXT, MAX_CHAR_COUNT, 0L);
PopFileInitialize (hWnd);
PopFontInitialize (_hWndEdit);
//注册自定义消息(针对查找、替换对话框)。
_messageFindReplace = RegisterWindowMessage (FINDMSGSTRING);
DoCaption (hWnd, _szTitleName);
return 1;
}
LRESULT
CALLBACK
EditSubWndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch( message )
{
case WM_LBUTTONUP://鼠标左键释放。
SetStatusText (_hWndEdit, _hWndStatus);
break;
/*case EM_LINEFROMCHAR:
{
TCHAR szBuffer[MAX_PATH];
wsprintf (szBuffer, TEXT("%d"), wParam);
MessageBox (NULL, szBuffer, NULL, MB_OK);
}
break;
*/
}
return CallWindowProc (_wpOrigEditProc, hWnd, message, wParam, lParam);
/*
int ich = -1;
int iv;
iv = SendMessage (_hWndEdit, EM_LINEFROMCHAR, wParam, 0);
wsprintf (szBuffer, TEXT("%d"), iv);
MessageBox (NULL, szBuffer, NULL, MB_OK);
return 1;*/
}
LONG
OnSize (HWND hWnd, UINT wMsg, UINT wParam, LONG lParam)
{
RECT rect;
LONG cy;
GetClientRect (_hWndStatus, &rect);//获取状态栏窗体矩形大小。
cy = rect.bottom - rect.top;//计算状态栏窗体矩形宽度。
MoveWindow (_hWndEdit, 0, 0, LOWORD(lParam), HIWORD(lParam) - cy, TRUE);
SendMessage(_hWndStatus,WM_SIZE,wParam,lParam);
return 1;
}
LONG
OnSetFocus (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
SetFocus (_hWndEdit);
return 1;
}
LONG
OnClose (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
if( _bNeedSave && IDCANCEL == AskAboutSave (hWnd, _szTitleName) ) return 0;
return DestroyWindow (hWnd);
}
LONG
OnDestroy (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
PopFontDeinitialize ();//删除字体。
PostQuitMessage(0);
return 1;
}
//处理Command消息。
LONG
OnAbout (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
DialogBox (_hInst, TEXT("AboutBox"), hWnd, AboutDlgProc);
return 1;
}
LONG
OnLineWrap (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
SendMessage (_hWndEdit, EM_LINEFROMCHAR, (WPARAM)1, 0);
return 1;
}
LONG
OnFileNew (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
if( _bNeedSave && IDCANCEL == AskAboutSave (hWnd, _szTitleName) )
return 0;
SetWindowText (_hWndEdit, TEXT("/0")); //清空标题栏文本。
_szFileName[0] = TEXT('/0'); //简单清空字符串。
_szTitleName[0] = TEXT('/0');
DoCaption (hWnd, _szTitleName);
_bNeedSave = FALSE;
return 1;
}
LONG
OnFileOpen (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
if( _bNeedSave && IDCANCEL == AskAboutSave (hWnd, _szTitleName) )
return 0;
if( PopFileOpenDlg (hWnd, _szFileName, _szTitleName) )
{
if( !PopFileRead (_hWndEdit, _szFileName) )
{
OkMessage (hWnd, TEXT("不能打开文件 %s!"), _szTitleName);
_szFileName[0] = TEXT('/0');
_szTitleName[0] = TEXT('/0');
}
}
DoCaption (hWnd, _szTitleName);
_bNeedSave = FALSE;
return 1;
}
LONG
OnFileSave (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
if( _szFileName[0] )
{
if( PopFileWrite (_hWndEdit, _szFileName) )
{
_bNeedSave = FALSE;
return 1;
}
else
{
OkMessage (hWnd, TEXT("不能保存 %s"), _szTitleName);
}
}
return OnFileSaveAs (hWnd, message, wParam, lParam);
}
LONG
OnFileSaveAs (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
if(PopFileSaveDlg (hWnd, _szFileName, _szTitleName))
{
DoCaption (hWnd, _szTitleName);
if(PopFileWrite (_hWndEdit, _szFileName))
{
_bNeedSave = FALSE;
return 1;
}
else
{
OkMessage (hWnd, TEXT("不能保存 %s"), _szTitleName);
}
}
return 0;
}
LONG
OnEditFind (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
_hDlgModeless = PopFindDlg (hWnd);
return 1;
}
LONG
OnEditFindNext (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
if( _hDlgModeless != NULL )
{
return PopFindNextText (_hWndEdit);
}
return 0;
}
LONG
OnEditFindReplace (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
_hDlgModeless = PopReplaceDlg (hWnd);
return 1;
}
LONG
OnDataTime (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
TCHAR szBuffer[MAX_PATH];
SYSTEMTIME systemtime;
GetLocalTime (&systemtime);
wsprintf (szBuffer, TEXT("%d:%d %d-%d-%d"), systemtime.wHour,
systemtime.wMinute, systemtime.wYear,
systemtime.wMonth, systemtime.wDay);
return SendMessage (_hWndEdit, EM_REPLACESEL, TRUE, (LPARAM)szBuffer);
}
LONG
OnAppExit (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
return SendMessage (hWnd, WM_CLOSE, wParam, lParam);
}
LONG
OnFormatFont (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
if( PopFontChooseFont (hWnd) )
PopFontSetFont (_hWndEdit);
return 1;
}
LONG
OnEditUndo (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
return SendMessage (_hWndEdit, WM_UNDO, 0, 0);
}
LONG
OnEditCut (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
return SendMessage (_hWndEdit, WM_CUT, 0, 0);
}
LONG
OnEditCopy (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
return SendMessage (_hWndEdit, WM_COPY, 0, 0);
}
LONG
OnEditPaste (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
return SendMessage (_hWndEdit, WM_PASTE, 0, 0);
}
LONG
OnEditClear (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
return SendMessage (_hWndEdit, WM_CLEAR, 0, 0);
}
LONG
OnEditSelectAll (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
return SendMessage (_hWndEdit, EM_SETSEL, 0, -1);
}
LONG
OnStatic (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
return 1;
}
void
DoCaption (HWND hWnd, TCHAR *szTitleName)
{
//设置窗体标题栏。
TCHAR szCaption[64 + MAX_PATH];
wsprintf (szCaption, TEXT("%s - %s"), szTitleName[0]?szTitleName:UNTITLED, _szAppName);
SetWindowText (hWnd, szCaption);
}
short
AskAboutSave (HWND hWnd, TCHAR *szTitleName)
{
//关于保存对话框。
TCHAR szBuffer[64 + MAX_PATH];
int iRetum = 0;
if(szTitleName[0] == TEXT('/0'))
{
wsprintf (szBuffer, TEXT("文件 %s 的文字已经改变。/n想保存文件吗?"), UNTITLED);
iRetum = MessageBox (hWnd, szBuffer, _szAppName, MB_YESNOCANCEL | MB_ICONQUESTION);
if(iRetum == IDYES)
{
if(!SendMessage (hWnd, WM_COMMAND, IDM_FILE_SAVE_AS, 0))
iRetum = IDCANCEL;
}
}
else
{
wsprintf (szBuffer, TEXT("文件 %s 的文字已经改变。/n想保存文件吗?"), szTitleName);
iRetum = MessageBox (hWnd, szBuffer, _szAppName, MB_YESNOCANCEL | MB_ICONQUESTION);
if(iRetum == IDYES)
{
if(!SendMessage (hWnd, WM_COMMAND, IDM_FILE_SAVE, 0))
iRetum = IDCANCEL;
}
}
return iRetum;
}
void
OkMessage (HWND hWnd, TCHAR *szMessage, TCHAR *szTitleName)
{
TCHAR szBuffer[64 + MAX_PATH];
wsprintf (szBuffer, szMessage, szTitleName[0]?szTitleName:UNTITLED);
MessageBox (hWnd, szBuffer, _szAppName, MB_OK | MB_ICONEXCLAMATION);
}
BOOL
CALLBACK
AboutDlgProc (HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_INITDIALOG:
return TRUE;
case WM_CLOSE:
EndDialog (hDlg, 0);
return TRUE;
}
/*case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDOK:
//case IDCANCEL:
EndDialog (hDlg, 0);
return TRUE;
}
break;*/
return FALSE;
}
BOOL
CreateEditText (HWND hWnd, WPARAM wParam, LPARAM lParam)
{
//创建编辑控件。
_hWndEdit = CreateWindow (
TEXT("edit"),
NULL,
WS_CHILD | //子窗体。
WS_VISIBLE | //显示窗体。
WS_VSCROLL | //垂直滚动条。
WS_HSCROLL | //水平滚动条。
ES_LEFT | //文本左对齐。
ES_AUTOHSCROLL | //自动水平滚动文本。
ES_AUTOVSCROLL | //自动垂直滚动文本。
ES_MULTILINE | //多行编辑。
ES_NOHIDESEL , //失去焦点时不隐藏被选中的文本。
0, 0, 0, 0,
hWnd,
(HMENU)ID_EDIT,
((LPCREATESTRUCT)lParam)->hInstance, NULL);
if(!_hWndEdit) return FALSE;
return TRUE;
}
BOOL
InitStatus(HWND hWnd)
{
RECT rect;
int i, parts[NUMPARTS];
GetClientRect (hWnd, &rect);
for(i=1; i<=NUMPARTS; i++)
parts[i-1] = rect.right / NUMPARTS * i;
_hWndStatus = CreateStatusWindow (WS_CHILD|WS_VISIBLE, NULL, hWnd, NULL);
if( !_hWndStatus ) return FALSE;
return SendMessage (_hWndStatus, SB_SETPARTS, (WPARAM)NUMPARTS, (LPARAM)parts);
}
void
SetStatusText (HWND hWndEdit, HWND hWndStatus)
{
//POINT point;
long iLineCount;
//long iLength;
long iOffset;
TCHAR szBuffer[MAX_LOADSTRING];
int iRow;
//GetCaretPos(&point);
//获取当前光标在字符串中的位置。
//iOffset = SendMessage (hWndEdit, EM_CHARFROMPOS, 0, MAKELPARAM(point.x, point.y));
//iLength = GetWindowTextLength (hWndEdit);//获取窗体文本长度(不含/0字符)。
SendMessage (hWndEdit, EM_SETSEL, (WPARAM)0, (LPARAM)-1);//文本全部选中。
iOffset = SendMessage (hWndEdit, EM_GETSEL, (WPARAM)0, (WPARAM)0);
iLineCount = SendMessage (hWndEdit, EM_LINEFROMCHAR, (WPARAM)iOffset, (WPARAM)NULL);
iRow = SendMessage (hWndEdit, EM_LINELENGTH, iLineCount, 0);
/*
注意:这里需要获取插入符所在的行的字符数。这里暂时没有处理。
*/
wsprintf (szBuffer, TEXT("Ln: %d Col:%d, %d"), iLineCount, iOffset, iRow);
SendMessage (hWndStatus, SB_SETTEXT, 1, (LPARAM)szBuffer);
}
void
MessageOperationEdit (HWND hWndEdit, WPARAM wParam, BOOL *bNeedSave)
{
/*
处理Edit控件消息函数。
BOOL *bNeedSave 文本需要保存标记。
*/
switch(HIWORD(wParam))
{
case EN_UPDATE: //编辑控制的内容已经改变。
*bNeedSave = TRUE;
break;
case EN_ERRSPACE: //编辑控制运行已经超出中间。
case EN_MAXTEXT: //编辑控制在插入时运行超出中间。
MessageBox (hWndEdit, TEXT("编辑输入已经超出空间!"),
_szAppName, MB_OK | MB_ICONSTOP);
break;
}
}