第一次写博客,尽量以后写的好一点!
#include <windows.h>
static int CreatePosX, CreatePosY;//插入符的位置
static int nCaretOffsetY;//y的位置
static TCHAR *pCharMath;//字符缓冲区
static TEXTMETRIC tm;//字体的信息,比如字体的高和宽
static int nCharWide, nCharHigh;//字符的宽度和高度
static int nTVWide, nTVHigh;//窗口的宽度和高度
static int nCharLine, nCharRow;//每行每列字符的数目
#define BUFFER(x,y) *(pCharMath+y*nCharLine+x)//二维数组的某一位置
static LRESULT CALLBACK DrawProc(HWND, UINT, WPARAM, LPARAM);//消息处理函数声明
static HWND DrawEdit(HWND hwnd, int x, int y, int wide, int High, int id)
{
HWND Hwnd;
WNDCLASS DrawEdits;
HINSTANCE hInst = GetModuleHandle(NULL);
DrawEdits.cbClsExtra = 0;
DrawEdits.cbWndExtra = 0;
DrawEdits.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
DrawEdits.hCursor = LoadCursor(NULL, IDC_IBEAM);
DrawEdits.hIcon = LoadIcon(NULL, IDI_ERROR);
DrawEdits.hInstance = hInst;
DrawEdits.lpfnWndProc = DrawProc;
DrawEdits.lpszClassName = TEXT("文本框");
DrawEdits.lpszMenuName = NULL;
DrawEdits.style = CS_HREDRAW | CS_VREDRAW;
if (!RegisterClass(&DrawEdits))
{
MessageBox(NULL, TEXT("注册失败"), TEXT("警告"), MB_OK);
return 0;
}
Hwnd = CreateWindow(TEXT("文本框"), NULL, WS_CHILD | WS_VISIBLE, x, y, wide, High, hwnd, NULL, hInst, NULL);
return Hwnd;
}
static void DrawChar(HDC hDC, int x, int y, TCHAR *str, int num)
{
RECT rect;
SelectObject(hDC, GetStockObject(SYSTEM_FIXED_FONT));
SetTextColor(hDC, RGB(255, 0, 0));//设置字体颜色
SetBkMode(hDC, TRANSPARENT);
rect.left = x;
rect.top = y;
rect.right = x + num * nCharWide;
rect.bottom = y + nCharHigh;
FillRect(hDC, &rect, (HBRUSH)GetStockObject(BLACK_BRUSH));
TextOut(hDC, CreatePosX * nCharWide, CreatePosY * nCharHigh,
&BUFFER(CreatePosX, CreatePosY), nCharLine - CreatePosX);
}
static LRESULT CALLBACK DrawProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
int x, y;//循环变量
HDC hdc;//设备句柄变量
switch (msg)
{
case WM_CREATE:
hdc = GetDC(hWnd);//获取设备句柄
SelectObject(hdc, GetStockObject(SYSTEM_FIXED_FONT));//设置字体的宽度高度(现在是等宽字体SYSTEM_FIXED_FONT)
GetTextMetrics(hdc, &tm);//获取字体的信息
ReleaseDC(hWnd, hdc);//释放设备的句柄
nCharWide = tm.tmAveCharWidth;//字体的宽度
nCharHigh = tm.tmHeight;//字体的高度
SetTextColor(hdc, RGB(255, 255, 255));//设置字体颜色
nCaretOffsetY = 12;//插入符位置偏移
return 0;
case WM_SIZE:
nTVWide = LOWORD(lParam);//窗口宽度
nCharLine = max(1, nTVWide / nCharWide);//一行可以存多少个字符
nTVHigh = LOWORD(lParam);//窗口高度
nCharRow = max(1, nTVHigh / nCharHigh);//一列可以存多少个字符
if (pCharMath != NULL)//判断字符缓冲区是否有字符,如果有就释放这个缓冲区
{
free(pCharMath);//如果有就释放这个缓冲区
}
pCharMath = (TCHAR*)malloc(nCharLine*nCharRow);
if (pCharMath)
{
for (x = 0; x < nCharLine; x++)
{
for (y = 0; y < nCharRow; y++)
{
BUFFER(x, y) == ' ';//初始化这个二维数组让每个位置都为空格
}
}
}
SetCaretPos(0, nCaretOffsetY);
return 0;
case WM_LBUTTONDOWN:
SetFocus(hWnd);
break;
case WM_KEYDOWN:
switch (wParam)
{
case VK_HOME:
CreatePosX = 0;
break;
case VK_END:
CreatePosX = nCharLine - 1;
break;
case VK_PRIOR:
CreatePosY = 0;
break;
case VK_NEXT:
CreatePosY = nCharRow - 1;
break;
case VK_LEFT:
CreatePosX = max(CreatePosX - 1, 0);
case VK_RIGHT:
CreatePosX = max(CreatePosX + 1, nCharLine - 1);
break;
case VK_UP:
CreatePosY = (CreatePosY , -1);
break;
case VK_DOWN:
CreatePosY = (CreatePosY + 1, nCharRow - 1);
break;
case DELETE:
for (x = CreatePosX; x < nCharLine; x++)
{
BUFFER(x, CreatePosY) = BUFFER(x + 1, CreatePosY);
}
BUFFER(nCharLine - 1, CreatePosY) = ' ';
HideCaret(hWnd);
hdc = GetDC(hWnd);
DrawChar(hdc, CreatePosX*nCharWide, CreatePosY*nCharHigh, &BUFFER(CreatePosX, CreatePosY), nCharLine - CreatePosX / nCharWide);
ReleaseDC(hWnd, hdc);
ShowCaret(hWnd);
break;
}
SetCaretPos(CreatePosX*nCharWide, CreatePosY*nCharHigh + nCaretOffsetY);
return 0;
case WM_SHOWWINDOW:
SetFocus(hWnd);
break;
case WM_SETFOCUS:
CreateCaret(hWnd, NULL, 2, nCharHigh);
SetCaretPos(CreatePosX*nCharWide, CreatePosY*nCharLine + nCaretOffsetY);
ShowCaret(hWnd);
break;
case WM_KILLFOCUS:
case WM_DESTROY:
HideCaret(hWnd);//隐藏插入符
DestroyCaret();//发送关闭消息
break;
case WM_CHAR:
switch (wParam)
{
case 0X08:
if (CreatePosX > 0)
{
CreatePosX--;
SendMessage(hWnd, WM_KEYDOWN, VK_DELETE, 1L);
}
break;
case 0X09:
do
{
SendMessage(hWnd, WM_CHAR, TEXT(' '), 2L);
} while (CreatePosX % 4 != 0);
break;
case 0X0D:
CreatePosX = 0;
if (++CreatePosY == nCharRow)
{
CreatePosY = 0;
}
break;
case 0X1B:
case 0X0A:
MessageBeep((UINT)-1);
break;
default:
BUFFER(CreatePosX, CreatePosY) = (TCHAR)wParam;
HideCaret(hWnd);
hdc = GetDC(hWnd);
DrawChar(hdc, CreatePosX*nCharWide, CreatePosY*nCharHigh, &BUFFER(CreatePosX, CreatePosY), -1);
ReleaseDC(hWnd, hdc);
ShowCaret(hWnd);
if (++CreatePosX == nCharLine)
{
CreatePosX = 0;
if (++CreatePosY == 0)
{
CreatePosY = 0;
}
}
break;
}
SetCaretPos(CreatePosX*nCharWide, CreatePosY*nCharHigh + nCaretOffsetY);
return 0;
case WM_PAINT:
{
PAINTSTRUCT ps;
hdc = BeginPaint(hWnd, &ps);
SelectObject(hdc, GetStockObject(SYSTEM_FIXED_FONT));
SetBkMode(hdc, TRANSPARENT);
SetTextColor(hdc, RGB(255, 255, 255));
for (y = 0; y < nCharLine; y++)
{
TextOut(hdc, 0, y*nCharHigh, &BUFFER(0, y), nCharLine);
}
EndPaint(hWnd, &ps);
}
return 0;
default:
break;
}
return DefWindowProc(hWnd, msg, wParam, lParam);
}
本文介绍如何在Windows环境下使用API自定义一个文本编辑控件,包括创建控件、绘制字符、处理键盘事件等功能,实现类似文本编辑器的基本操作。

被折叠的 条评论
为什么被折叠?



