Отображение строкового вывода в окне с помощью C (в WIN32 API)

Мне нужен правильный способ, которым я могу вывести строку символов и отобразить ее в созданном окне. Я использовал функцию textout(), но поскольку она только рисует окно, как только окно свернуто и восстановлено, данные, отображаемые в окне, исчезают. Кроме того, когда отображаемые данные превышают размер окна, отображаются только данные, равные размеру окна, а остальные данные усекаются. Есть ли другой способ вывода данных в окно?


person Ayse    schedule 15.03.2013    source источник


Ответы (2)


Вы можете поместить Static или Edit элемент управления (метка и текстовое поле) в окне, чтобы отобразить данные.

Вызовите один из них во время WM_CREATE:

HWND hWndExample = CreateWindow("STATIC", "Text Goes Here", WS_VISIBLE | WS_CHILD | SS_LEFT, 10,10,100,100, hWnd, NULL, hInstance, NULL);

Or

HWND hWndExample = CreateWindow("EDIT", "Text Goes Here", WS_VISIBLE | WS_CHILD | ES_LEFT, 10,10,100,100, hWnd, NULL, hInstance, NULL);

Если вы используете Edit, пользователь также сможет прокручивать, копировать и вставлять текст.

В обоих случаях текст можно обновить с помощью SetWindowText():

SetWindowText(hWndExample, TEXT("Control string"));

(Предоставлено Дабойзука)

person Deanna    schedule 15.03.2013
comment
+1, я даже не подумал, что OP может понадобиться элемент управления, как упоминалось TextOut, я сразу перешел к рисованию текста. Скорее всего, это то, о чем на самом деле просит ОП. - person Daboyzuk; 15.03.2013
comment
@Daboyzuk К сожалению, я недостаточно программирую окна Win32 или C, чтобы вызвать в воображении образец :) - person Deanna; 15.03.2013
comment
В качестве примера должно хватить: HWND StaticExample = CreateWindowEx("STATIC", "Text Goes Here", WS_VISIBLE | WS_CHILD | SS_LEFT, 10,10,100,100,hWnd,NULL,hInstance,NULL); для статики и HWND EditExample = CreateWindowEx("EDIT", "Text Goes Here", WS_VISIBLE | WS_CHILD | ES_LEFT, 10,10,100,100,hWnd,NULL,hInstance,NULL); для редактирования. - person Daboyzuk; 15.03.2013
comment
@Deanna: У меня это сработало, но что, если я хочу отображать текст постоянно? Должен ли я повторно вызывать CreateWindowEx? - person Ayse; 16.03.2013
comment
В основном я постоянно читаю данные из своего сокета в буфере, и я хочу отобразить этот буфер в своем окне. - person Ayse; 16.03.2013
comment
@AyeshaHassan Нет, вы создаете окно в WM_CREATE, а затем просто вызываете SetWindowText(), чтобы установить содержимое. Вот почему я разделил строки в своем ответе, но я сделаю немного яснее, - person Deanna; 16.03.2013
comment
@Deanna: Большое спасибо за помощь :) - person Ayse; 18.03.2013

TextOut должен работать отлично. Если это делается в WM_PAINT, он должен отрисовываться каждый раз. (в том числе по минимизации и изменению размеров)

LRESULT CALLBACK MyWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch(message)
    {
        case WM_PAINT:
            PAINTSTRUCT ps;
            HDC hdc = BeginPaint(hWnd, &ps);

            TextOut(hdc, 10, 10, TEXT("Text Out String"),strlen("Text Out String"));

            EndPaint(hWnd, &ps);
            ReleaseDC(hWnd, hdc);
            break;
        default:
            return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}

Вас также может заинтересовать DrawText

LRESULT CALLBACK MyWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch(message)
    {
        case WM_PAINT:
            PAINTSTRUCT ps;
            HDC hdc = BeginPaint(hWnd, &ps);

            RECT rec;
            //       SetRect(rect, x ,y ,width, height)
            SetRect(&rec,10,10,100,100);
            //       DrawText(HDC, text, text length, drawing area, parameters "DT_XXX")
            DrawText(hdc, TEXT("Text Out String"),strlen("Text Out String"), &rec, DT_TOP|DT_LEFT);

            EndPaint(hWnd, &ps);
            ReleaseDC(hWnd, hdc);
            break;
        default:
            return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}

Который нарисует текст в вашем окне в заданном прямоугольнике,


При рисовании текст будет переноситься по словам внутри заданного прямоугольника.
Если вы хотите, чтобы все окно было областью рисования, вы можете использовать GetClientRect(hWnd, &rec); вместо SetRect(&rec,10,10,100,100);.

person Daboyzuk    schedule 15.03.2013
comment
Аккуратный! Но я не большой поклонник размещения больших блоков кода в таком переключателе — и вам тоже нужно что-то возвращать. Я думаю, что он хотел решение для переноса строки текста, если она слишком длинная. - person Rup; 15.03.2013
comment
Да, ужасно писать код внутри переключателя, но я просто пытался привести минимальный пример. На самом деле слишком минимально, как вы указали, мне удалось упростить возвращаемое значение =) Отредактировано! DrawText перенесет текст, если он выходит за пределы прямоугольника, но я добавлю сноску, спасибо за это. - person Daboyzuk; 15.03.2013
comment
@Dabaooyzuk: Большое спасибо за вашу помощь. Я попробовал это и отлично работает для отображения одной строки. но что, если я хочу отобразить что-то несколько раз? Любая помощь? - person Ayse; 16.03.2013
comment
@Ayesha Hassan Вы вызываете InvalidateRect(RECT,TRUE), когда вам нужно заменить значение, которое вы нарисовали, это сообщает вашему окну, что этот раздел необходимо перерисовать, однако пример Дины, используя SetWindowText (или Static_SetText(hwnd, text) / Edit_SetText(hwnd,text)) будет лучшим решением для того, что вы хотите. - person Daboyzuk; 16.03.2013