文字框建立方法
第一次寫部落格,儘量以後寫的好一點!
#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); }