1.先创建插入符光标
在WM_CREATE消息中
LRESULT OnCreate(HWND hWnd, WPARAM wParam, LPARAM lParam) { HDC hdc = GetDC(hWnd);
//获取字体信息
TEXTMETRIC txtInfo; GetTextMetrics(hdc, &txtInfo);
//创建插入符
CreateCaret(hWnd, NULL, txtInfo.tmAveCharWidth/8, txtInfo.tmHeight);
//显示插入符 ShowCaret(hWnd); ReleaseDC(hWnd, hdc); return LRESULT(); }
2.定义两个全局变量
//全局变量
POINT g_point = { 0 };//保存鼠标点下的点的位置
CString g_string; //保存输入的字符串
3.在鼠标按下消息中.WM_LBUTTONDOWN
LRESULT OnLButtonDown(HWND hWnd, WPARAM wParam, LPARAM lParam) { //获取鼠标点下时的点的坐标 POINT pt; pt.x = GET_X_LPARAM(lParam); pt.y = GET_Y_LPARAM(lParam); //设置插入符的位置 SetCaretPos(pt.x,pt.y); //把点的坐标保存到全局变量中 g_point = pt; //清空字符串 g_string.Empty(); return LRESULT(); }
3.在键盘消息WM_CHAR中处理字符绘制和光标跟
LRESULT OnChar(HWND hWnd, WPARAM wParam, LPARAM lParam) { //获得键入的字符 UINT nChar = (TCHAR)wParam; HDC hdc = GetDC(hWnd); if (nChar == VK_RETURN)//换行 { g_string.Empty(); //清空字符串 TEXTMETRIC txtInfo; GetTextMetrics(hdc, &txtInfo);//获取字符的高度 g_point.y = g_point.y + txtInfo.tmHeight;//设置插入符Y坐标的位置 } else if (nChar == VK_BACK)//退格 { //获取背景色 COLORREF color = GetBkColor(hdc); //设置文本颜色 COLORREF oldColor = SetTextColor(hdc, color); //用背景色擦除字符串 TextOut(hdc, g_point.x, g_point.y, g_string, g_string.GetLength()); //去掉最后一个字符 g_string = g_string.Left(g_string.GetLength() - 1); //重新设置文本颜色为原来的颜色 SetTextColor(hdc, oldColor); } else { g_string += (TCHAR)nChar;//键入的字符累加到字符串中 } //获得字符串的像素宽度与高度 SIZE size = { 0 }; GetTextExtentPoint32(hdc, g_string, g_string.GetLength(), &size); int x = g_point.x + size.cx; int y = g_point.y; SetCaretPos(x, y);//重新设置光标位置 //绘制字符串到窗口上 TextOut(hdc,g_point.x, g_point.y, g_string,g_string.GetLength()); ReleaseDC(hWnd, hdc); return LRESULT(); }
目前就先学到这里,以后有时间再进一步的去学习.
程序源码:
#include<windows.h> #include <windowsx.h> //这是要用GET_X_LPARAM,GET_Y_LPARAM宏 #include <atlstr.h> //字符串类CString //全局变量 POINT g_point = { 0 }; CString g_string; //函数的前置声明 LRESULT CALLBACK lpWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); LRESULT OnCreate(HWND hWnd, WPARAM wParam, LPARAM lParam); //WM_CREATE LRESULT OnLButtonDown(HWND hWnd, WPARAM wParam, LPARAM lParam);//WM_LBUTTONDOWN LRESULT OnChar(HWND hWnd, WPARAM wParam, LPARAM lParam); //WM_CHAR int WINAPI WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nShowCmd) { //设计窗口类 TCHAR className[] = TEXT("myClass");//窗口类名称 //填充窗口类结构体 WNDCLASSEX wndClass = { 0 }; wndClass.cbSize = sizeof(WNDCLASSEX); //判断是否是系统注册了的类 if (!GetClassInfoEx(hInstance, className, &wndClass)) { wndClass.cbClsExtra = 0; wndClass.cbWndExtra = 0; wndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); wndClass.hCursor = LoadCursor(NULL, IDC_ARROW); wndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION); wndClass.hIconSm = LoadIcon(NULL, IDI_APPLICATION); wndClass.hInstance = hInstance; wndClass.lpfnWndProc = lpWindowProc; wndClass.lpszClassName = className; wndClass.lpszMenuName = NULL; wndClass.style = CS_VREDRAW | CS_HREDRAW; //注册窗口类 if (!RegisterClassEx(&wndClass)) { return 1; } } //创建窗口 HWND hwnd = ::CreateWindowEx(0,className, TEXT("我的窗口"),
WS_OVERLAPPEDWINDOW, 100, 100, 600, 400, NULL, NULL, hInstance, 0);
if (!hwnd) {
return 1;
}
//显示并更新窗口
::ShowWindow(hwnd, nShowCmd); ::UpdateWindow(hwnd);
//消息循环 MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
//销毁插入符
DestroyCaret(); return msg.lParam; } LRESULT CALLBACK lpWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_DESTROY: PostQuitMessage(0); break; case WM_CREATE: return OnCreate( hWnd,wParam, lParam); case WM_LBUTTONDOWN: return OnLButtonDown(hWnd, wParam, lParam); case WM_CHAR: return OnChar(hWnd, wParam, lParam); } return DefWindowProc(hWnd, uMsg, wParam, lParam); } LRESULT OnCreate(HWND hWnd, WPARAM wParam, LPARAM lParam) { //获取字体信息 HDC hdc = GetDC(hWnd); TEXTMETRIC txtInfo; GetTextMetrics(hdc, &txtInfo); //创建插入符 CreateCaret(hWnd, NULL, txtInfo.tmAveCharWidth/8, txtInfo.tmHeight); ShowCaret(hWnd); ReleaseDC(hWnd, hdc); return LRESULT(); } LRESULT OnLButtonDown(HWND hWnd, WPARAM wParam, LPARAM lParam) { POINT pt; pt.x = GET_X_LPARAM(lParam); pt.y = GET_Y_LPARAM(lParam); SetCaretPos(pt.x,pt.y);//设置插入符位置 g_point = pt; g_string.Empty(); return LRESULT(); } LRESULT OnChar(HWND hWnd, WPARAM wParam, LPARAM lParam) { //获得键入的字符 UINT nChar = (TCHAR)wParam; HDC hdc = GetDC(hWnd); if (nChar == VK_RETURN)//换行 { g_string.Empty(); //清空字符串 TEXTMETRIC txtInfo; GetTextMetrics(hdc, &txtInfo);//获取字符的高度 g_point.y = g_point.y + txtInfo.tmHeight;//设置插入符Y坐标的位置 } else if (nChar == VK_BACK)//退格 { //获取背景色 COLORREF color = GetBkColor(hdc); //设置文本颜色 COLORREF oldColor = SetTextColor(hdc, color); //用背景色擦除字符串 TextOut(hdc, g_point.x, g_point.y, g_string, g_string.GetLength()); //去掉最后一个字符 g_string = g_string.Left(g_string.GetLength() - 1); //重新设置文本颜色为原来的颜色 SetTextColor(hdc, oldColor); } else { g_string += (TCHAR)nChar;//键入的字符累加到字符串中 } //获得字符串的像素宽度与高度 SIZE size = { 0 }; GetTextExtentPoint32(hdc, g_string, g_string.GetLength(), &size); int x = g_point.x + size.cx; int y = g_point.y; SetCaretPos(x, y);//重新设置光标位置 //绘制字符串到窗口上 TextOut(hdc,g_point.x, g_point.y, g_string,g_string.GetLength()); ReleaseDC(hWnd, hdc); return LRESULT(); }