====== Uživatelské vstupy – klávesnice, myš, nástěnka (WinAPI) ====== #include //#include //#include // Global variable HINSTANCE hInst; // Function prototypes. int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int); LRESULT CALLBACK MainWndProc(HWND, UINT, WPARAM, LPARAM); // Application entry point. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { MSG msg; BOOL bRet; WNDCLASS wcx; // register class HWND hWnd; //UINT uResult; // SetTimer's return value hInst = hInstance; // Save the application-instance handle. // Fill in the window class structure with parameters that describe the main window. wcx.style = CS_HREDRAW | CS_VREDRAW; // redraw if size changes wcx.lpfnWndProc = (WNDPROC) MainWndProc; // points to window procedure wcx.cbClsExtra = 0; // no extra class memory wcx.cbWndExtra = 0; // no extra window memory wcx.hInstance = hInstance; // handle to instance wcx.hIcon = LoadIcon(NULL, IDI_APPLICATION); // predefined app. icon wcx.hCursor = LoadCursor(NULL, IDC_ARROW); // predefined arrow wcx.hbrBackground = GetStockObject(WHITE_BRUSH); // white background brush wcx.lpszMenuName = (LPCSTR) "MainMenu"; // name of menu resource wcx.lpszClassName = (LPCSTR) "MainWClass"; // name of window class // Register the window class. if (!RegisterClass(&wcx)) return FALSE; // create window of registered class hWnd = CreateWindow("MainWClass", // name of window class "ITUedit", // title-bar string WS_OVERLAPPEDWINDOW, // top-level window 100, // default horizontal position 100, // default vertical position 300, // default width 300, // default height (HWND) NULL, // no owner window (HMENU) NULL, // use class menu hInstance, // handle to application instance (LPVOID) NULL); // no window-creation data if (!hWnd) return FALSE; // Show the window and send a WM_PAINT message to the window procedure. // Record the current cursor position. ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); // loop of message processing while ((bRet = GetMessage(&msg, NULL, 0, 0)) != 0) { if (bRet == -1) { // handle the error and possibly exit } else { TranslateMessage(&msg); DispatchMessage(&msg); } } return (int) msg.wParam; } #define BUFSIZE 65535 LRESULT APIENTRY MainWndProc(HWND hwndMain, UINT uMsg, WPARAM wParam, LPARAM lParam) { static int nchLast; // amount of chars in the input buffer static RECT TextArea; // client area static PTCHAR pchInputBuf; // input buffer int i; // counter //int nVirtKey; // virtual-key code HDC hdc; // handle to device context PAINTSTRUCT ps; // required by BeginPaint static DWORD dwCharY; // height of characters static int nCaretPosX = 0; // horizontal position of caret - real position static int nCaretPosY = 0; // vertical position of caret - number of lines TCHAR ch; // current character int chWidth; // width of the actual character TEXTMETRIC tm; // structure for text metrics POINT ReleasePoint; // point where mouse button was released HWND hwndTmp; // window handle where mouse button was released //HGLOBAL hglb; // global memory object //LPTSTR lptstr; // handle to the copied text buffer static int caretpos; static int bufptr; static int indent; switch (uMsg) { case WM_CREATE: // Allocate a buffer to store keyboard input. pchInputBuf = (LPTSTR) GlobalAlloc(GPTR, BUFSIZE * sizeof(TCHAR)); nchLast = 0; caretpos = 0; pchInputBuf[nchLast] = TEXT('\0'); // Get the metrics of the current font. hdc = GetDC(hwndMain); GetTextMetrics(hdc, &tm); ReleaseDC(hwndMain, hdc); // Save the average character width and height. dwCharY = tm.tmHeight; break; case WM_CHAR: switch (wParam) { case 0x08: // backspace //FIXME: Mazani odradkovani!!! if (caretpos <= 0) { break; } ch = (TCHAR) pchInputBuf[--caretpos]; HideCaret(hwndMain); // Retrieve the character's width and output the character. hdc = GetDC(hwndMain); GetCharWidth32(hdc, (UINT) ch, (UINT) ch, &chWidth); nCaretPosX -= chWidth; ReleaseDC(hwndMain, hdc); SetCaretPos(nCaretPosX, nCaretPosY * dwCharY); bufptr = caretpos; while (bufptr < nchLast) { pchInputBuf[bufptr] = pchInputBuf[bufptr + 1]; bufptr++; } nchLast--; ShowCaret(hwndMain); break; case 0x0A: // linefeed case 0x1B: // escape MessageBeep((UINT) - 1); break; case 0x09: // tab // Convert tabs to four consecutive spaces. for (i = 0; i < 4; i++) SendMessage(hwndMain, WM_CHAR, 0x20, 0); break; case 0x0D: // carriage return // Record the carriage return and position the caret at the beginning of the new line. pchInputBuf[nchLast++] = 0x0D; nCaretPosY++; nCaretPosX = 0; caretpos++; break; default: // displayable character ch = (TCHAR) wParam; HideCaret(hwndMain); // Retrieve the character's width and output the character. hdc = GetDC(hwndMain); TextOut(hdc, nCaretPosX, nCaretPosY * dwCharY, &ch, 1); GetCharWidth32(hdc, (UINT) ch, (UINT) ch, &chWidth); nCaretPosX += chWidth; ReleaseDC(hwndMain, hdc); SetCaretPos(nCaretPosX, nCaretPosY * dwCharY); ShowCaret(hwndMain); // Store the character in the buffer. if (nchLast != caretpos) { bufptr = nchLast; while (bufptr >= caretpos) { pchInputBuf[bufptr + 1] = pchInputBuf[bufptr]; bufptr--; } } pchInputBuf[caretpos++] = ch; nchLast++; break; } InvalidateRect(hwndMain, NULL, TRUE); break; case WM_KEYDOWN: switch (wParam) { case VK_LEFT: // LEFT ARROW if (caretpos <= 0) { break; } HideCaret(hwndMain); caretpos--; ch = (TCHAR) pchInputBuf[caretpos]; if (ch == 0x0D) { nCaretPosY--; caretpos--; while (caretpos >= 0 && pchInputBuf[caretpos] != 0x0D) { //printf("%d: %c\n", caretpos, (pchInputBuf[caretpos])); caretpos--; } while (caretpos < nchLast && pchInputBuf[++caretpos] != 0x0D) { ch = (TCHAR) pchInputBuf[caretpos]; hdc = GetDC(hwndMain); GetCharWidth32(hdc, (UINT) ch, (UINT) ch, &chWidth); nCaretPosX += chWidth; ReleaseDC(hwndMain, hdc); } } else { hdc = GetDC(hwndMain); GetCharWidth32(hdc, (UINT) ch, (UINT) ch, &chWidth); nCaretPosX -= chWidth; ReleaseDC(hwndMain, hdc); } SetCaretPos(nCaretPosX, nCaretPosY * dwCharY); ShowCaret(hwndMain); break; case VK_RIGHT: // RIGHT ARROW if (caretpos >= nchLast) { break; } HideCaret(hwndMain); ch = (TCHAR) pchInputBuf[caretpos]; caretpos++; if (ch == 0x0D) { nCaretPosY++; nCaretPosX = 0; } else { //caretpos++; hdc = GetDC(hwndMain); GetCharWidth32(hdc, (UINT) ch, (UINT) ch, &chWidth); nCaretPosX += chWidth; ReleaseDC(hwndMain, hdc); } SetCaretPos(nCaretPosX, nCaretPosY * dwCharY); ShowCaret(hwndMain); break; case VK_UP: HideCaret(hwndMain); indent = 0; while (caretpos > 0 && pchInputBuf[caretpos] != 0x0D) { caretpos--; indent++; } if (caretpos > 0) { indent--; } //printf("%d, %d\n", caretpos, indent); if (caretpos == 0) { // 1. radek -> nic se nestane caretpos += indent; ShowCaret(hwndMain); break; } nCaretPosY--; nCaretPosX = 0; caretpos--; while (caretpos > 0 && pchInputBuf[caretpos] != 0x0D) { //posune se na zacatek radku caretpos--; } if (caretpos > 0) { caretpos++; } //putchar(pchInputBuf[caretpos]); for (; indent > 0; indent--) { ch = (TCHAR) pchInputBuf[caretpos]; if (ch == 0x0D) { break; } hdc = GetDC(hwndMain); GetCharWidth32(hdc, (UINT) ch, (UINT) ch, &chWidth); nCaretPosX += chWidth; ReleaseDC(hwndMain, hdc); caretpos++; } SetCaretPos(nCaretPosX, nCaretPosY * dwCharY); ShowCaret(hwndMain); break; case VK_DOWN: HideCaret(hwndMain); indent = 0; while (caretpos > 0 && pchInputBuf[caretpos] != 0x0D) { //posun na zacatek radku a pocitani o kolik znaku caretpos--; indent++; } if (caretpos > 0) { indent--; } caretpos++; while (caretpos < nchLast && pchInputBuf[caretpos] != 0x0D) { //posun na konec radku //putchar(pchInputBuf[caretpos]); caretpos++; } caretpos++; //preskocit odradkovani //printf("%d %d\n", caretpos, nchLast); if (caretpos >= nchLast) { //kdyz jsem na konci textu //printf("Posledni radek!\n"); caretpos = nchLast; while (caretpos > 0 && pchInputBuf[caretpos] != 0x0D) { //posun na zacatek radku //putchar(pchInputBuf[caretpos]); caretpos--; } caretpos++; nCaretPosX = 0; for (; indent > 0; indent--) { //posun od odsazeni ch = (TCHAR) pchInputBuf[caretpos]; if (ch == 0x0D) { break; } hdc = GetDC(hwndMain); GetCharWidth32(hdc, (UINT) ch, (UINT) ch, &chWidth); nCaretPosX += chWidth; ReleaseDC(hwndMain, hdc); caretpos++; } SetCaretPos(nCaretPosX, nCaretPosY * dwCharY); ShowCaret(hwndMain); break; } nCaretPosY++; while (caretpos > 0 && pchInputBuf[caretpos] != 0x0D) { //posun na zacatek radku //putchar(pchInputBuf[caretpos]); caretpos--; } caretpos++; nCaretPosX = 0; for (; indent > 0; indent--) { //posun od odsazeni ch = (TCHAR) pchInputBuf[caretpos]; if (ch == 0x0D) { break; } hdc = GetDC(hwndMain); GetCharWidth32(hdc, (UINT) ch, (UINT) ch, &chWidth); nCaretPosX += chWidth; ReleaseDC(hwndMain, hdc); caretpos++; } SetCaretPos(nCaretPosX, nCaretPosY * dwCharY); ShowCaret(hwndMain); break; case VK_HOME: HideCaret(hwndMain); caretpos--; //zajima me predchozi znak while (caretpos >= 0 && pchInputBuf[caretpos] != 0x0D) { //posun na zacatek radku //printf("%d: %c\n", caretpos, (pchInputBuf[caretpos])); caretpos--; } caretpos++; //preskoci odradkovani nCaretPosX = 0; SetCaretPos(nCaretPosX, nCaretPosY * dwCharY); ShowCaret(hwndMain); break; case VK_END: HideCaret(hwndMain); while (caretpos < nchLast && pchInputBuf[caretpos] != 0x0D) { ch = (TCHAR) pchInputBuf[caretpos]; hdc = GetDC(hwndMain); GetCharWidth32(hdc, (UINT) ch, (UINT) ch, &chWidth); nCaretPosX += chWidth; ReleaseDC(hwndMain, hdc); caretpos++; } SetCaretPos(nCaretPosX, nCaretPosY * dwCharY); ShowCaret(hwndMain); break; case VK_DELETE: break; } break; case WM_SIZE: GetClientRect(hwndMain, &TextArea); break; case WM_SETFOCUS: // Create, position, and display the caret when the window receives the keyboard focus. CreateCaret(hwndMain, (HBITMAP) 0, 0, dwCharY); SetCaretPos(nCaretPosX, nCaretPosY * dwCharY); ShowCaret(hwndMain); break; case WM_KILLFOCUS: // Hide and destroy the caret when the window loses the keyboard focus. HideCaret(hwndMain); DestroyCaret(); break; case WM_PAINT: hdc = BeginPaint(hwndMain, &ps); // Set the clipping rectangle, and then draw the text into it. DrawText(hdc, pchInputBuf, nchLast, &TextArea, DT_LEFT); SetCaretPos(nCaretPosX, nCaretPosY * dwCharY); EndPaint(hwndMain, &ps); break; case WM_DESTROY: PostQuitMessage(0); // Free the input buffer. GlobalFree((HGLOBAL) pchInputBuf); break; default: return DefWindowProc(hwndMain, uMsg, wParam, lParam); } }