关于插入符号(不是光标)函数
当您往程序中输入文字时,通常有一个底线、竖条或者方框来指示输入的下一个字符将出现
在屏幕上的位置。这个标志通常称为「光标」,但是在Windows下写程序,您必须改变这个
习惯。在Windows中,它称为「插入符号」。
主要的插入符号函数有以下:
1)CreateCaret 建立与窗口有关的插入符号
void CreateCaret( CBitmap* pBitmap );
参数:pBitmap,标识定义插入符号形状的位图
备注:
如果存在,CreateCaret 自动销毁前插入符号形状窗口拥有插入符号。 一旦创建,插入符号最初处于隐藏状态。 若要显示插入符号,必须调用 ShowCaret 成员函数。
系统插入符号是共享资源。 仅当具有输入焦点或处于活动状态时,CWnd 应创建插入符号。 它会失去输入焦点或变为非活动之前,应销毁插入符号。
2)GetCaretPos 取得插入符号目前位置
BOOL GetCaretPos(LPP0lNT IpPoint);
参数:IpPoint:指向POINT结构的指针。该结构接收插入标记的客户坐标信息。
备注:插入标记位置通常是按包含该插入标记的窗口的客户坐标形式给出的。
3)SetCaretPos 在窗口中设定插入符号的位置
static void PASCAL SetCaretPos(POINT point );
参数:
point,指定新的x和Y坐标(在工作区坐标)插入符号。
备注:
插入符号是共享资源。 如果它拥有插入符号,窗口不应将脱字号。
4)ShowCaret 显示插入符号
void ShowCaret( );
备注:
仅当具有当前形状和非连续,隐藏两个或多个次 ShowCaret 成员函数显示插入符号。 如果插入符号未由此窗口拥有,插入符号不会显示。
隐藏插入符号是累积的。 如果 HideCaret 成员函数连续调用五次,必须调用 ShowCaret 五次显示插入符号。
插入符号是共享资源。 仅当具有输入焦点或处于活动状态时,"窗口中显示插入符号。
5)HideCaret 隐藏插入符号
void HideCaret( );
备注
隐藏是累积的。 如果 HideCaret 连续调用五次,必须调用 ShowCaret 成员函数五次,在插入符号将显示之前。
6)DestroyCaret 撤消插入符号
BOOL DestroyCaret(VOLD)
7)GetCaretBlinkTime
该函数返回一个公用的时间,单位为毫秒。该时间是转化插入标记的像素而需要的时间(闪烁时间)。用户可以使用控制面板来设置这个值。
UINT GetCaretBlinkTime(VOLD)
8)SetCaretBlinkTime
该函数将插入标记的闪烁时间设置为一个指定的数目,该数目的单位为毫秒,闪烁时间就是转化插入标记像素所需的时间,单位为毫秒。
BOOL SetCaretBlinkTime(UINT uMSeconds);
程序处理一条非WM_PAINT消息而且希望在窗口内绘制某些东西时,它必须呼叫HideCaret隐藏插入符号。在绘制完毕后,再呼叫ShowCaret显示插入符号。HideCaret
的影响具有累积效果,如果多次呼叫HideCaret而不呼叫ShowCaret,那么只有呼叫ShowCaret相同次数时,才能看到插入符号。
#include <windows.h> //是一个把一维数组当做二维数组来用的功能 #define BUFFER(x,y) *(pBuffer + y * cxBuffer + x) LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM); int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,PSTR szCmdLine,int iCmdShow) { static TCHAR szAppName[] = TEXT("Typer"); HWND hwnd; MSG msg; WNDCLASS wndclass; wndclass.style = CS_HREDRAW | CS_VREDRAW ; wndclass.lpfnWndProc = WndProc; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hInstance = hInstance; wndclass.hIcon = LoadIcon(NULL,IDI_APPLICATION); 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 ; } hwnd = CreateWindow(szAppName,TEXT ("Typing Program"), WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,hInstance,NULL); ShowWindow(hwnd,iCmdShow); UpdateWindow(hwnd); while(GetMessage (&msg,NULL,0,0)) { TranslateMessage (&msg); DispatchMessage (&msg); } return msg.wParam ; } LRESULT CALLBACK WndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam) { static DWORD dwCharSet = DEFAULT_CHARSET; static int cxChar,cyChar,cxClient,cyClient,cxBuffer,cyBuffer,xCaret,yCaret; static TCHAR *pBuffer = NULL; HDC hdc; PAINTSTRUCT ps; TEXTMETRIC tm; switch(message) { case WM_INPUTLANGCHANGE: dwCharSet = wParam; case WM_CREATE: hdc = GetDC(hwnd); SelectObject(hdc,CreateFont(0,0,0,0,0,0,0,0,dwCharSet,0,0,0,FIXED_PITCH,NULL)); GetTextMetrics(hdc,&tm); cxChar = tm.tmAveCharWidth; cyChar = tm.tmHeight; DeleteObject(SelectObject(hdc,GetStockObject(SYSTEM_FONT))); ReleaseDC(hwnd,hdc); case WM_SIZE: // obtain window size in pixels if (message == WM_SIZE) { cxClient = LOWORD (lParam) ; cyClient = HIWORD (lParam) ; } // calculate window size in characters cxBuffer = max (1, cxClient / cxChar) ; cyBuffer = max (1, cyClient / cyChar) ; // allocate memory for buffer and clear it if (pBuffer != NULL) free (pBuffer) ; pBuffer = (TCHAR *)malloc(cxBuffer * cyBuffer * sizeof (TCHAR)) ; for (int y = 0 ; y < cyBuffer ; y++) for (int x = 0 ; x < cxBuffer ; x++) BUFFER(x,y) = ' ' ; xCaret = 0; yCaret = 0; if(hwnd == GetFocus()) SetCaretPos(xCaret * cxChar,yCaret *cyChar); InvalidateRect(hwnd,NULL,TRUE); return 0; case WM_SETFOCUS: CreateCaret(hwnd,NULL,cxChar,cyChar); SetCaretPos(xCaret * cxChar,yCaret *cyChar); ShowCaret (hwnd) ; return 0 ; case WM_KILLFOCUS: HideCaret (hwnd) ; DestroyCaret () ; return 0 ; case WM_KEYDOWN: switch(wParam) { case VK_HOME: xCaret = 0; break; case VK_END: xCaret = cxBuffer -1; break; case VK_NEXT: yCaret = cyBuffer - 1; break; case VK_RIGHT: xCaret = min(xCaret + 1,cxBuffer - 1); break; case VK_UP: yCaret = max(yCaret -1,0); break; case VK_DOWN: yCaret = min(yCaret + 1,cyBuffer - 1); break; case VK_DELETE: for(int x = xCaret;x < cxBuffer -1;x++) BUFFER(x,yCaret) = BUFFER(x+1,yCaret); BUFFER (cxBuffer - 1, yCaret) = ' '; HideCaret (hwnd); hdc = GetDC (hwnd); SelectObject(hdc,CreateFont(0,0,0, 0, 0, 0, 0, 0,dwCharSet, 0,0, 0,FIXED_PITCH, NULL)) ; TextOut(hdc, xCaret * cxChar, yCaret * cyChar,&BUFFER(xCaret, yCaret),cxBuffer - xCaret) ; DeleteObject(SelectObject(hdc,GetStockObject(SYSTEM_FONT))); ReleaseDC (hwnd, hdc); ShowCaret (hwnd); break; } SetCaretPos (xCaret * cxChar, yCaret * cyChar) ; return 0 ; case WM_CHAR: for (int i = 0 ; i < (int) LOWORD (lParam) ; i++) { switch (wParam) { case '\b': if (xCaret > 0) { xCaret-- ; SendMessage(hwnd,WM_KEYDOWN, VK_DELETE, 1); } break; case '\t': do { SendMessage(hwnd,WM_CHAR,' ',1); } while(xCaret % 8 != 0); break; case '\n': if (++yCaret == cyBuffer) yCaret = 0 ; break; case '\r': xCaret = 0; if(++yCaret == cyBuffer) yCaret = 0; break; case '\x1B': for (int y = 0 ; y < cyBuffer ; y++) for (int x = 0 ; x < cxBuffer ; x++) BUFFER (x, y) = ' ' ; xCaret = 0; yCaret = 0; InvalidateRect(hwnd,NULL,FALSE); break; default: BUFFER (xCaret, yCaret) = (TCHAR) wParam; HideCaret (hwnd); hdc = GetDC (hwnd); SelectObject (hdc, CreateFont (0, 0, 0, 0, 0, 0, 0, 0,dwCharSet,0,0,0,FIXED_PITCH, NULL)); TextOut (hdc, xCaret * cxChar, yCaret * cyChar, &BUFFER(xCaret, yCaret), 1); DeleteObject(SelectObject(hdc,GetStockObject(SYSTEM_FONT))); ReleaseDC(hwnd,hdc); ShowCaret(hwnd); if(++xCaret == cxBuffer) { xCaret = 0; if (++yCaret == cyBuffer) yCaret = 0; } break; } } SetCaretPos(xCaret * cxChar,yCaret * cyChar); return 0; case WM_PAINT: hdc = BeginPaint (hwnd, &ps); SelectObject(hdc, CreateFont(0,0,0, 0,0,0,0,0,dwCharSet,0,0,0,FIXED_PITCH, NULL)); for(int y = 0;y < cyBuffer;y++) { TextOut (hdc, 0, y * cyChar, & BUFFER(0,y), cxBuffer) ; } DeleteObject (SelectObject(hdc, GetStockObject (SYSTEM_FONT))); EndPaint (hwnd, &ps) ; return 0; case WM_DESTROY: PostQuitMessage (0) ; return 0 ; } return DefWindowProc (hwnd, message, wParam, lParam) ; }