캐럿 사용

이 섹션에는 다음 태스크에 대 한 코드 샘플이 포함 되어 있습니다.

캐럿 만들기 및 표시

키보드 포커스가 수신 되 면 창에서 캐럿을 만들고 표시 합니다. CreateCaret 함수를 사용 하 여 지정 된 창에서 캐럿을 만듭니다. 그런 다음 SetCaretPos 를 호출 하 여 캐럿의 현재 위치와 ShowCaret 를 설정 하 여 캐럿이 표시 되도록 할 수 있습니다.

시스템에서 키보드 포커스를 받는 창에 WM _ SETFOCUS 메시지를 보냅니다. 따라서 응용 프로그램은이 메시지를 처리 하는 동안 캐럿을 만들고 표시 해야 합니다.

HWND hwnd,       // window handle 
int x;           // horizontal coordinate of cursor 
int y;           // vertical coordinate of cursor 
int nWidth;      // width of cursor 
int nHeight;     // height of cursor 
char *lpszChar;  // pointer to character 
 
    case WM_SETFOCUS: 
 
    // Create a solid black caret. 
        CreateCaret(hwnd, (HBITMAP) NULL, nWidth, nHeight); 
 
    // Adjust the caret position, in client coordinates. 
        SetCaretPos(x, y); 
 
    // Display the caret. 
        ShowCaret(hwnd); 
 
        break; 

비트맵을 기반으로 하는 캐럿을 만들려면 CreateCaret를 사용할 때 비트맵 핸들을 지정 해야 합니다. 그래픽 응용 프로그램을 사용 하 여 비트맵을 만들고 리소스 컴파일러를 사용 하 여 응용 프로그램의 리소스에 비트맵을 추가할 수 있습니다. 그런 다음 응용 프로그램은 loadbitmap 함수를 사용 하 여 비트맵 핸들을 로드할 수 있습니다. 예를 들어 앞의 예제에서 CreateCaret 줄을 다음 줄로 바꿔서 비트맵 캐럿을 만들 수 있습니다.

// Load the application-defined caret resource. 
 
    hCaret = LoadBitmap(hinst, MAKEINTRESOURCE(120)); 
 
// Create a bitmap caret. 
 
    CreateCaret(hwnd, hCaret, 0, 0); 

또는 createbitmap 또는 createdibitmap 함수를 사용 하 여 캐럿 비트맵의 핸들을 검색할 수 있습니다. 비트맵에 대 한 자세한 내용은 비트맵을 참조 하십시오.

응용 프로그램이 비트맵 핸들을 지정 하는 경우 CreateCaret 는 width 및 height 매개 변수를 무시 합니다. 비트맵은 캐럿의 크기를 정의 합니다.

캐럿 숨기기

응용 프로그램이 WM _ 그림판이외의 메시지를 처리 하는 동안 화면을 다시 그릴 때마다 HideCaret 함수를 사용 하 여 캐럿을 표시 하지 않도록 설정 해야 합니다. 응용 프로그램이 그리기를 마치면 ShowCaret 함수를 사용 하 여 캐럿을 다시 표시 합니다. 응용 프로그램이 WM _ PAINT 메시지를 처리 하는 경우이 함수는이 함수를 자동으로 수행 하므로 캐럿을 숨기고 다시 표시할 필요가 없습니다.

다음 코드 샘플에서는 화면에 문자를 그리고 WM _ 문자 메시지를 처리 하는 동안 응용 프로그램에서 캐럿을 숨기는 방법을 보여 줍니다.

HWND hwnd,   // window handle 
HDC hdc;     // device context 
 
    case WM_CHAR: 
        switch (wParam) 
        { 
            case 0x08: 
             
             // Process a backspace. 
             
                break; 
 
            case 0x09: 
             
             // Process a tab.  
             
                break; 
 
            case 0x0D: 
             
             // Process a carriage return. 
             
                break; 
 
            case 0x1B: 
             
             // Process an escape. 
             
                break; 
 
            case 0x0A: 
             
             // Process a linefeed. 
             
                break; 
 
            default: 
                // Hide the caret. 
                HideCaret(hwnd); 
 
                // Draw the character on the screen. 
 
                hdc = GetDC(hwnd); 
                SelectObject(hdc, 
                    GetStockObject(SYSTEM_FIXED_FONT)); 
 
                TextOut(hdc, x, y, lpszChar, 1); 
 
                ReleaseDC(hwnd, hdc); 
 
                // Display the caret. 
 
                ShowCaret(hwnd); 
 
        } 

응용 프로그램에서 ShowCaret를 호출 하지 않고 HideCaret 함수를 여러 번 호출 하는 경우 응용 프로그램에서 ShowCaret 를 동일한 횟수 만큼 호출 해야 캐럿이 표시 됩니다.

캐럿 제거

창이 키보드 포커스를 잃으면 시스템은 WM _ KILLFOCUS 메시지를 창으로 보냅니다. 응용 프로그램은 DestroyCaret 함수를 사용 하 여이 메시지를 처리 하는 동안 캐럿을 제거 해야 합니다. 다음 코드에서는 더 이상 키보드 포커스가 없는 창에서 캐럿을 제거 하는 방법을 보여 줍니다.

case WM_KILLFOCUS: 
 
// The window is losing the keyboard focus, so destroy the caret. 
 
    DestroyCaret(); 
 
    break; 

16 비트 Windows Windows 기반 응용 프로그램은 GetCaretBlinkTime 함수를 호출 하 여 현재 깜박임 시간을 저장 한 다음 SetCaretBlinkTime 함수를 호출 하 여 WM _ SETFOCUS 메시지를 처리 하는 동안 깜박임 시간을 조정할 수 있습니다. 응용 프로그램은 WM _ KILLFOCUS 메시지를 처리 하는 동안 SetCaretBlinkTime 를 호출 하 여 다른 응용 프로그램을 사용 하기 위해 저장 된 깜빡임 시간을 복원 합니다. 그러나 다중 스레드 환경에서는이 방법이 작동 하지 않습니다. 특히 한 응용 프로그램의 비활성화는 다른 응용 프로그램의 활성화와 동기화 되지 않으므로 한 응용 프로그램이 중단 되는 경우 다른 응용 프로그램을 활성화할 수 있습니다.

응용 프로그램은 사용자가 선택한 깜박임 시간을 준수 해야 합니다. SetCaretBlinkTime 함수는 사용자가 깜박임 시간을 설정 하는 데 사용할 수 있는 응용 프로그램에 의해서만 호출 되어야 합니다.

키보드 입력 처리

다음 예제에서는 간단한 텍스트 편집기에서 캐럿을 사용 하는 방법을 보여 줍니다. 이 예제에서는 사용자가 인쇄 가능한 문자를 입력 하 고 다양 한 키를 사용 하 여 클라이언트 영역을 이동 하는 캐럿 위치를 업데이트 합니다.

#define TEXTMATRIX(x, y) *(pTextMatrix + (y * nWindowCharsX) + x) 
// Global variables.
HINSTANCE hinst;                  // current instance 
HBITMAP hCaret;                   // caret bitmap 
HDC hdc;                          // device context  
PAINTSTRUCT ps;                   // client area paint info 
static char *pTextMatrix = NULL;  // points to text matrix 
static int  nCharX,               // width of char. in logical units 
            nCharY,               // height of char. in logical units 
            nWindowX,             // width of client area 
            nWindowY,             // height of client area 
            nWindowCharsX,        // width of client area 
            nWindowCharsY,        // height of client area 
            nCaretPosX,           // x-position of caret 
            nCaretPosY;           // y-position of caret 
static UINT uOldBlink;            // previous blink rate 
int x, y;                         // coordinates for text matrix 
TEXTMETRIC tm;                    // font information 
 
LONG APIENTRY MainWndProc( 
    HWND hwnd,            // window handle 
    UINT message,         // type of message 
    UINT wParam,          // additional information 
    LONG lParam)          // additional information 
{ 
 
    switch (message) 
    { 
        case WM_CREATE: 
        // Select a fixed-width system font, and get its text metrics.
 
            hdc = GetDC(hwnd); 
            SelectObject(hdc, 
                GetStockObject(SYSTEM_FIXED_FONT)); 
            GetTextMetrics(hdc, &tm); 
            ReleaseDC(hwnd, hdc); 
 
        // Save the avg. width and height of characters. 
 
            nCharX = tm.tmAveCharWidth; 
            nCharY = tm.tmHeight; 
 
            return 0; 
 
        case WM_SIZE: 
        // Determine the width of the client area, in pixels 
        // and in number of characters. 
 
            nWindowX = LOWORD(lParam); 
            nWindowCharsX = max(1, nWindowX/nCharX); 
 
            // Determine the height of the client area, in 
            // pixels and in number of characters. 
 
            nWindowY = HIWORD(lParam); 
            nWindowCharsY = max(1, nWindowY/nCharY); 
 
            // Clear the buffer that holds the text input. 
 
            if (pTextMatrix != NULL) 
                free(pTextMatrix); 
 
            // If there is enough memory, allocate space for the 
            // text input buffer. 
 
            pTextMatrix = malloc(nWindowCharsX * nWindowCharsY); 
 
            if (pTextMatrix == NULL) 
                ErrorHandler("Not enough memory."); 
            else 
                for (y = 0; y < nWindowCharsY; y++) 
                    for (x = 0; x < nWindowCharsX; x++) 
                        TEXTMATRIX(x, y) = ' '; 
 
            // Move the caret to the origin. 
 
            SetCaretPos(0, 0); 
 
            return 0; 
 
        case WM_KEYDOWN: 
            switch (wParam) 
            { 
                case VK_HOME:       // Home 
                    nCaretPosX = 0; 
                    break; 
 
                case VK_END:        // End 
                    nCaretPosX = nWindowCharsX - 1; 
                    break; 
 
                case VK_PRIOR:      // Page Up 
                    nCaretPosY = 0; 
                    break; 
 
                case VK_NEXT:       // Page Down 
                    nCaretPosY = nWindowCharsY -1; 
                    break; 
 
                case VK_LEFT:       // Left arrow 
                    nCaretPosX = max(nCaretPosX - 1, 0); 
                    break; 
 
                case VK_RIGHT:      // Right arrow 
                    nCaretPosX = min(nCaretPosX + 1, 
                        nWindowCharsX - 1); 
                    break; 
 
                case VK_UP:         // Up arrow 
                    nCaretPosY = max(nCaretPosY - 1, 0); 
                    break; 
 
                case VK_DOWN:       // Down arrow 
                    nCaretPosY = min(nCaretPosY + 1, 
                        nWindowCharsY - 1); 
                    break; 
 
                case VK_DELETE:     // Delete 
 
                // Move all the characters that followed the 
                // deleted character (on the same line) one 
                // space back (to the left) in the matrix. 
 
                    for (x = nCaretPosX; x < nWindowCharsX; x++) 
                        TEXTMATRIX(x, nCaretPosY) = 
                            TEXTMATRIX(x + 1, nCaretPosY); 
 
                    // Replace the last character on the 
                    // line with a space. 
 
                    TEXTMATRIX(nWindowCharsX - 1, 
                        nCaretPosY) = ' '; 
 
                    // The application will draw outside the 
                    // WM_PAINT message processing, so hide the caret. 
 
                    HideCaret(hwnd); 
 
                    // Redraw the line, adjusted for the 
                    // deleted character. 
 
                    hdc = GetDC(hwnd); 
                    SelectObject(hdc, 
                        GetStockObject(SYSTEM_FIXED_FONT)); 
 
                    TextOut(hdc, nCaretPosX * nCharX, 
                        nCaretPosY * nCharY, 
                        &TEXTMATRIX(nCaretPosX, nCaretPosY), 
                        nWindowCharsX - nCaretPosX); 
 
                    ReleaseDC(hwnd, hdc); 
 
                    // Display the caret. 
 
                    ShowCaret(hwnd); 
 
                    break; 
            } 
 
            // Adjust the caret position based on the 
            // virtual-key processing. 
 
            SetCaretPos(nCaretPosX * nCharX, 
                nCaretPosY * nCharY); 
 
            return 0; 
 
        case WM_CHAR: 
            switch (wParam) 
            { 
                case 0x08:          // Backspace 
                // Move the caret back one space, and then 
                // process this like the DEL key. 
 
                    if (nCaretPosX > 0) 
                    { 
                        nCaretPosX--; 
                        SendMessage(hwnd, WM_KEYDOWN, 
                            VK_DELETE, 1L); 
                    } 
                    break; 
 
                case 0x09:          // Tab 
                // Tab stops exist every four spaces, so add 
                // spaces until the user hits the next tab. 
 
                    do 
                    { 
                        SendMessage(hwnd, WM_CHAR, ' ', 1L); 
                    } while (nCaretPosX % 4 != 0); 
                    break; 
 
                case 0x0D:          // Carriage return 
                // Go to the beginning of the next line. 
                // The bottom line wraps around to the top. 
 
                    nCaretPosX = 0; 
 
                    if (++nCaretPosY == nWindowCharsY) 
                        nCaretPosY = 0; 
                    break; 
 
                case 0x1B:        // Escape 
                case 0x0A:        // Linefeed 
                    MessageBeep((UINT) -1); 
                    break; 
 
                default: 
                // Add the character to the text buffer. 
 
                    TEXTMATRIX(nCaretPosX, nCaretPosY) = 
                        (char) wParam; 
 
                // The application will draw outside the 
                // WM_PAINT message processing, so hide the caret. 
 
                    HideCaret(hwnd); 
 
                // Draw the character on the screen. 
 
                    hdc = GetDC(hwnd); 
                    SelectObject(hdc, 
                        GetStockObject(SYSTEM_FIXED_FONT)); 
 
                    TextOut(hdc, nCaretPosX * nCharX, 
                        nCaretPosY * nCharY, 
                        &TEXTMATRIX(nCaretPosX, nCaretPosY), 1); 
 
                    ReleaseDC(hwnd, hdc); 
 
                    // Display the caret. 
 
                    ShowCaret(hwnd); 
 
                    // Prepare to wrap around if you reached the 
                    // end of the line. 
 
                    if (++nCaretPosX == nWindowCharsX) 
                    { 
                        nCaretPosX = 0; 
                        if (++nCaretPosY == nWindowCharsY) 
                            nCaretPosY = 0; 
                    } 
                    break; 
            } 
 
            // Adjust the caret position based on the 
            // character processing. 
 
            SetCaretPos(nCaretPosX * nCharX, 
                nCaretPosY * nCharY); 
 
            return 0; 
 
        case WM_PAINT: 
        // Draw all the characters in the buffer, line by line. 
 
            hdc = BeginPaint(hwnd, &ps); 
 
            SelectObject(hdc, 
                GetStockObject(SYSTEM_FIXED_FONT)); 
 
            for (y = 0; y < nWindowCharsY; y++) 
                TextOut(hdc, 0, y * nCharY, &TEXTMATRIX(0, y), 
                    nWindowCharsX); 
 
            EndPaint(hwnd, &ps); 
 
        case WM_SETFOCUS: 
        // The window has the input focus. Load the 
        // application-defined caret resource. 
 
            hCaret = LoadBitmap(hinst, MAKEINTRESOURCE(120)); 
 
            // Create the caret. 
 
            CreateCaret(hwnd, hCaret, 0, 0); 
 
            // Adjust the caret position. 
 
            SetCaretPos(nCaretPosX * nCharX, 
                nCaretPosY * nCharY); 
 
            // Display the caret. 
 
            ShowCaret(hwnd); 
 
            break; 
 
        case WM_KILLFOCUS: 
        // The window is losing the input focus, 
        // so destroy the caret. 
 
            DestroyCaret(); 
 
            break; 
 
        default: 
            return DefWindowProc(hwnd, message, wParam, lParam); 
 
    } 
 
    return NULL; 
}