//==============================================================================
下面用VC+RichEd20.Dll实现的,效果不错。
不知道98有没带RichEd20.Dll动态库,我没试~~~
谁能改成Delphi代码!
//==============================================================================
/*
;--------------------------------------------------------------------------------
;程序名:notepad
;功能:一个很简单的RichEdit记事本程序。可以显示行号,这里用SDK的方式创建程序。
;
;使用环境:2000/xp
;开发环境:win2000 + VC++6.0 英文版 + sp4
;
;作者:jhkdiy
;E-mail:jhkdiy_gzb@21cn.net
;创建日期:2005/5/24
;版本:1.0
;最后修改日期:2005/5/27
;注意: 你可以自由传播本代码,但请保留代码的完整性和作者信息,且本代码不可用于
; 任何形式的商业活动,谢谢.
;
; 这个显示行号的实例共包括3种语言版本(Win32汇编,C语言 , VB6)。
*/
#include <windows.h>
#include <RICHEDIT.H> //加载有关RichEdit中使用到的一些常数定义和结构声明
#include "resource.h"
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
TCHAR szAppName[] = TEXT ("notepad"
;
TCHAR szRichClass[] = TEXT("RichEdit20A"
;
HMODULE hRichDll;
HWND hWinMain;
HWND hWinEdit;
HINSTANCE hMainInstance;
WNDPROC lpEditProc;
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
HWND hwnd ;
MSG msg ;
WNDCLASS wndclass ;
HMENU hMenu;
HANDLE hAccel;
hMainInstance = hInstance;
hRichDll = LoadLibrary("RichEd20.Dll"
; //加载RichEdit窗口的动态链接库
wndclass.style = CS_HREDRAW | CS_VREDRAW ;
wndclass.lpfnWndProc = WndProc ;
wndclass.cbClsExtra = 0 ;
wndclass.cbWndExtra = 0 ;
wndclass.hInstance = hInstance ;
wndclass.hIcon = LoadIcon (hInstance, MAKEINTRESOURCE(IDI_MAIN)) ;
wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;
wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = szAppName ;
if (!RegisterClass (&wndclass))
{
MessageBox (NULL, TEXT ("This program requires Windows NT!"
,
szAppName, MB_ICONERROR) ;
return 0 ;
}
hMenu = LoadMenu(hInstance, MAKEINTRESOURCE(IDM_MAIN));
hAccel = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDR_MAIN));
hwnd = CreateWindow (szAppName, TEXT ("notepad( C_SDK ), Created by jhkdiy"
,
WS_OVERLAPPEDWINDOW,
200, 150, 700, 500,
NULL, hMenu, hInstance, NULL) ;
ShowWindow (hwnd, iCmdShow) ;
UpdateWindow (hwnd) ;
while (GetMessage (&msg, NULL, 0, 0))
{
if( !TranslateAccelerator(hwnd, hAccel, &msg) )
{
TranslateMessage (&msg) ;
DispatchMessage (&msg) ;
}
}
FreeLibrary(hRichDll);
return msg.wParam ;
}
void ShowLineNum( HWND hEdit )
{
/*
功能:显示文本的总行数
参数:
hEdit:要显示行号的文本框,普通的Edit控件没有测试过,这里只用RichEdit
返回值:没有。
--------------------------------------------------------------------------------
*/
RECT ClientRect; //RichEdit的客户区大小
HDC hdcEdit; //RichEdit的Dc(设备环境)
HDC hdcCpb; //与RichEdit兼容的Dc
HBITMAP hdcBmp; //RichEdit兼容的位图dc
int CharHeight; //字符的高度
int chHeight; //字符的高度,常量
int FirstLine; //文本框中的第一个可见行的行号。
int ClientHeight; //RichEdit的客户区高度
int LineCount; //文本的总行数
char countBuf[10]; //显示行号的缓冲区
CHARFORMAT CharFmt; //RichEdit中的一个结构,用于获取字符的一系列信息,这里只用它来获取字符高度
//获取RichEdit的Dc
hdcEdit = GetDC( hEdit );
GetClientRect( hEdit, &ClientRect);
//获取RichEdit的客户区高度
ClientHeight = ClientRect.bottom - ClientRect.top;
//创建与RichEdit兼容的Dc
hdcCpb = CreateCompatibleDC( hdcEdit );
//创建与RichEdit兼容的位图Dc,我们用来显示行号用的。
hdcBmp = CreateCompatibleBitmap( hdcEdit, 40, ClientHeight );
//将位图dc选入RichEdit环境中
SelectObject( hdcCpb, hdcBmp );
//填充显示行号dc的背景颜色。大家可以试试其它颜色
FillRect( hdcCpb, &ClientRect, CreateSolidBrush(0x8080ff) );
SetBkMode( hdcCpb, TRANSPARENT );
//获取当前RichEdit文本中的总行数
LineCount = SendMessage( hEdit, EM_GETLINECOUNT, 0, 0 );
RtlZeroMemory( &CharFmt, sizeof(CharFmt) );
CharFmt.cbSize = sizeof( CharFmt );
SendMessage( hEdit, EM_GETCHARFORMAT, TRUE, (long)&CharFmt );
//获取字符高度,以英寸为单位,需转化为磅,只要除以20就行。
CharHeight = CharFmt.yHeight / 20;
chHeight = CharHeight;
CharHeight = 1;
//设置显示行号的前景色
SetTextColor( hdcCpb, 0x000000 );
//获取文本框中第一个可见的行的行号,没有这个行号,显示不会跟着文本的滚动而滚动。
FirstLine = SendMessage( hEdit, EM_GETFIRSTVISIBLELINE, 0, 0 );
FirstLine++;
//在位图dc中循环输出行号
while( FirstLine <= LineCount )
{
TextOut( hdcCpb, 1, CharHeight, countBuf, wsprintf( countBuf, TEXT("%4u"
, FirstLine++ ));
CharHeight += chHeight + 4;
if( CharHeight > ClientHeight ) break;
}
//将已"画好"的位图真正"贴"到RichEdit中
BitBlt( hdcEdit, 0, 0, 40, ClientHeight, hdcCpb, 0, 0, SRCCOPY );
DeleteDC( hdcCpb );
ReleaseDC( hEdit, hdcEdit );
DeleteObject( hdcBmp );
}
long SubEditProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
//功能:截获RichEdit的WM_PAINT消息,用于当RichEdit刷新时显示行号。
//参数:
// hWnd, uMsg, wParam, lParam 都为原有Windows发给RichEdit的消息和参数
//返回值:没有
//说明:当消息处理完毕后必须把消息回送给默认的RichEdit的窗口处理过程,
// lpEditProc为RichEdit的旧窗口地址。
PAINTSTRUCT ps;
if( uMsg == WM_PAINT )
{
CallWindowProc( lpEditProc, hWnd, uMsg, wParam, lParam);
BeginPaint( hWnd, &ps);
//下列函数完成显示行号的功能
ShowLineNum( hWinEdit );
return EndPaint( hWnd, &ps);
}
return CallWindowProc( lpEditProc, hWnd, uMsg, wParam, lParam);
}
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
CHARFORMAT stCF;
HMENU hMenu;
RECT rect;
hWinMain = hwnd;
switch (message)
{
case WM_COMMAND:
hMenu = GetMenu (hwnd) ;
switch (LOWORD (wParam))
{
case IDM_OPENFILE:
return 0 ;
case IDM_SAVEFILE:
MessageBeep (0) ;
return 0 ;
case IDM_EXITAPP:
SendMessage (hwnd, WM_CLOSE, 0, 0) ;
return 0 ;
case IDM_UNDO:
SendMessage( hWinEdit, EM_UNDO, 0, 0 );
return 0 ;
case IDM_REDO:
SendMessage( hWinEdit, EM_REDO, 0, 0 );
return 0 ;
case IDM_CUT:
SendMessage( hWinEdit, WM_CUT, 0, 0 );
return 0 ;
case IDM_COPY:
SendMessage( hWinEdit, WM_COPY, 0, 0 );
return 0 ;
case IDM_PASTE:
SendMessage( hWinEdit, WM_PASTE, 0, 0 );
return 0 ;
case IDM_ABOUT:
MessageBox (hwnd, TEXT ("作者:jhkdiy/nE-mail:jhkdiy_gzb@21cn.net/n日期:2005/5/24/n版本:1.0/n最后修改日期:2005/5/27"
,
szAppName, MB_ICONINFORMATION | MB_OK) ;
return 0 ;
}
break ;
case WM_SIZE:
GetClientRect(hwnd, &rect);
MoveWindow(hWinEdit, 0, 0, rect.right, rect.bottom, TRUE);
return 0;
case WM_CREATE:
GetClientRect(hwnd, &rect);
//创建RichEdit窗口.
hWinEdit = CreateWindowEx( WS_EX_CLIENTEDGE, TEXT(RICHEDIT_CLASS), NULL, WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_HSCROLL | ES_MULTILINE | ES_NOHIDESEL, 0, 0, rect.right, rect.bottom, hwnd, 0, hMainInstance, NULL);
SendMessage(hWinEdit, EM_SETTEXTMODE, TM_PLAINTEXT, 0);
stCF.cbSize = sizeof(stCF);
stCF.yHeight = 11*20; //设置字符高度.
stCF.dwMask = CFM_FACE | CFM_SIZE | CFM_BOLD;
lstrcpy( stCF.szFaceName, TEXT("宋体"
);
//设置RichEdit的字体和相关参数
SendMessage( hWinEdit, EM_SETCHARFORMAT, 0, (long)&stCF );
//设置RichEdit为无文本长度限制,否则为64Kb的文本长度。
SendMessage( hWinEdit, EM_EXLIMITTEXT, 0, -1 );
//这里设置RichEdit窗口的编辑区域,我们左边留出40像素宽度用于显示行号。
SendMessage( hWinEdit, EM_SETMARGINS, EC_RIGHTMARGIN | EC_LEFTMARGIN, 0x00050005+40);
//设置新的窗口地址,lpEditProc为RichEdit的内置窗口处理地址。
(long)lpEditProc = SetWindowLong( hWinEdit, GWL_WNDPROC, (long)&SubEditProc );
SetWindowText( hWinEdit, TEXT(" 这是一个简单的测试 /n 这是第2行。/n 这是第3行 "
);
return 0;
case WM_DESTROY:
PostQuitMessage (0) ;
return 0 ;
}
return DefWindowProc (hwnd, message, wParam, lParam) ;
}