locked
WinApi c++ вывод текста RRS feed

  • Вопрос

  • При установке некоторых шрифтов текст выводится несколько левее, чем должен быть. У меня в программе посимвольный вывод с использованием ::TextOut. Я хочу, например, вывести букву "f" в позицию 0,0, используя шрифт

    GetStockObject(DEFAULT_GUI_FONT);

    Символ выведется немного левее (то есть немного за рамкой). При смещении позиции на ширину символа, полученную GetExtentPoint32() это "обратное смещение" также не учитывается. Что делать чтобы такого смещения не было или узнать его. Я пробовал SetTextAlign, не помогло. GetTextMetrix, там есть поле lfOverhead, но оно оказалось равным 0. Использование DrawText() тоже не помогает.

    Привожу простейший пример.

    LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
        int wmId, wmEvent;
        PAINTSTRUCT ps;
        HDC hdc;
        HFONT font =(HFONT) GetStockObject(DEFAULT_GUI_FONT);
        switch (message)
        {
        case WM_COMMAND:
            wmId    = LOWORD(wParam);
            wmEvent = HIWORD(wParam);
            // Разобрать выбор в меню:
            switch (wmId)
            {
            case IDM_ABOUT:
                DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
                break;
            case IDM_EXIT:
                DestroyWindow(hWnd);
                break;
            default:
                return DefWindowProc(hWnd, message, wParam, lParam);
            }
            break;
        case WM_PAINT:
            hdc = BeginPaint(hWnd, &ps);
            // TODO: добавьте любой код отрисовки...
            
            SelectObject(hdc,font);
            ::TextOut(hdc,0,0,L"fff",3);
            EndPaint(hWnd, &ps);
            break;
        case WM_DESTROY:
            PostQuitMessage(0);
            break;
        default:
            return DefWindowProc(hWnd, message, wParam, lParam);
        }
        return 0;
    }
    Заранее спасибо.
    • Изменено VintPirat 2 ноября 2013 г. 21:40
    2 ноября 2013 г. 21:37

Ответы

  • Решено. Функция GetCharABCWidths(..) вернет ширину символа параметрами A,B,C. (до буквы, буква, после буквы). Так вот, у некоторых шрифтов параметр A может быть меньше нуля, и из-за этого всё и происходит.

    А вам должно быть стыдно за такое недееспособное комьюнити и их участников. Проблему описал до нулей, код приложил, но народу видно абы что-то уточнить, ничего не смотря. Бесите.

    • Помечено в качестве ответа VintPirat 4 ноября 2013 г. 16:24
    4 ноября 2013 г. 16:24

Все ответы

  • Посмотрите эту тему
    3 ноября 2013 г. 7:56
  • Я уже написал, что SetTextAlign не работает. Тут дело в шрифте.
    3 ноября 2013 г. 13:08
  • Я уже написал, что SetTextAlign не работает. Тут дело в шрифте.

    А может все-таки Ваша программа не работает, а не функция Windows API, которая тестировалась много лет тысячами людей. Вы какую-нибудь книгу прочитали об использовании программного интерфейса Windows, прежде чем писать подобные глупости.
    3 ноября 2013 г. 15:44
  • Как знал, что нормальных людей на русском msdn не найду.
    3 ноября 2013 г. 16:27
  • Все относительно, знаете ли... :) Удачи в программировании.
    3 ноября 2013 г. 16:41
  • А какой именно шрифт используется?
    3 ноября 2013 г. 17:03
  • Я написал, 

    используя шрифт

    GetStockObject(DEFAULT_GUI_FONT);

    3 ноября 2013 г. 17:23
  • Я написал, 

    используя шрифт

    GetStockObject(DEFAULT_GUI_FONT);

    А какой именно шрифт установлен у вас в системе в качестве дефолтного? Название, размер, прочие характеристики?
    3 ноября 2013 г. 18:45
  • C msdn:

    DEFAULT_GUI_FONT

    Default font for user interface objects such as menus and dialog boxes. It is not recommended that you use DEFAULT_GUI_FONT or SYSTEM_FONT to obtain the font used by dialogs and windows; for more information, see the remarks section.

    The default font is Tahoma.

    3 ноября 2013 г. 20:34


  •  It is not recommended that you use DEFAULT_GUI_FONT

    выберите другой подход
    3 ноября 2013 г. 21:25
  • Оооооо...

    У меня в программе есть возможно выбора шрифта с помощью ChooseFont(). Так вот, с некоторыми шрифтами такая же проблема. Пожалуйста, пишите только по делу.

    3 ноября 2013 г. 21:53
  • Хотя конечно же можно ответить "так не используй те шрифты, что с проблемами, епрст".
    3 ноября 2013 г. 21:54
  • если DEFAULT_GUI_FONT = Tahoma,

    попробуйте вставить сам шрифт Tahoma

    Вроде бы одинаковые действия, но если результат будет не идентичным, то это покажет где копать

    4 ноября 2013 г. 8:59
  • епрст

    Два раза спросил: "Какой шрифт используется?" Ответа нет...

    Спрашиваю в третий раз: "С какими именно шрифтами возникает проблема?" А также какая ось используется?

    Воистину, отвечать на англоязычных форумах одно удовольствие: задаёшь уточняющий вопрос топикстартеру, он тебе приводит всю необходимую информацию, вплоть до номера своего банковского счёта.

    На наших форумах клещами вытягиваешь из вопрошающего дополнительную инфу... В итоге слышишь от авторов вопросов, что у нас нихрена не помогают, на SO отвечают лучше...

    Пожалуйста, пишите только по делу.
    Пожалуйста!..
    4 ноября 2013 г. 11:23
  • =)  
    4 ноября 2013 г. 11:41
  • Если вам сложно было прочитать мой пост целиком.

    При установке некоторых шрифтов текст выводится несколько левее, чем должен быть. У меня в программе посимвольный вывод с использованием ::TextOut. Я хочу, например, вывести букву "f" в позицию 0,0, используя шрифт

    GetStockObject(DEFAULT_GUI_FONT); - вот это шрифт. Та же проблема появляется и с Ариалом. 

    Винда 8.

    4 ноября 2013 г. 12:13
  • GetStockObject(DEFAULT_GUI_FONT); - вот это шрифт.

    Это шрифт по умолчанию установленный в вашей системе! У вас это может быть, например, Arial, у меня, допустим, Times, у третьего - Verdana, и т. д.

    Какой именно шрифт используется у вас?

    -----

    Попробуйте строку

    HFONT font = (HFONT) GetStockObject(DEFAULT_GUI_FONT);

    заменить на код

    LOGFONT lf;
        lf.lfHeight = 0;
        lf.lfWidth = 0;
        lf.lfEscapement = 0;
        lf.lfOrientation = 0;
        lf.lfWeight = FW_DONTCARE;
        lf.lfItalic = false;
        lf.lfUnderline = false;
        lf.lfStrikeOut = false;
        lf.lfCharSet = ANSI_CHARSET;
        lf.lfOutPrecision = OUT_DEFAULT_PRECIS;
        lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
        lf.lfQuality = DEFAULT_QUALITY;
        lf.lfPitchAndFamily = DEFAULT_PITCH;
        strcpy(lf.lfFaceName, "Arial");
    
        HFONT font = CreateFont (
            lf.lfHeight,
            lf.lfWidth,
            lf.lfEscapement,
            lf.lfOrientation,
            lf.lfWeight,
            lf.lfItalic,
            lf.lfUnderline,
            lf.lfStrikeOut,
            lf.lfCharSet,
            lf.lfOutPrecision,
            lf.lfClipPrecision,
            lf.lfQuality,
            lf.lfPitchAndFamily,
            lf.lfFaceName
        );

    Всё равно выводится неправильно?

    Попробуйте разные названия шрифтов. Есть проблемы с ними?

    -----

    Вангану: имеет место быть несоответствие unicode/ascii.

    4 ноября 2013 г. 14:11
  • "На наших форумах клещами вытягиваешь из вопрошающего дополнительную инфу... В итоге слышишь от авторов вопросов, что у нас нихрена не помогают, на SO отвечают лучше..." - вот именно. Тут это дело обычное.

    Сделаем содержимое сообщества лучше, вместе!

    4 ноября 2013 г. 14:55
    Модератор
  • Решено. Функция GetCharABCWidths(..) вернет ширину символа параметрами A,B,C. (до буквы, буква, после буквы). Так вот, у некоторых шрифтов параметр A может быть меньше нуля, и из-за этого всё и происходит.

    А вам должно быть стыдно за такое недееспособное комьюнити и их участников. Проблему описал до нулей, код приложил, но народу видно абы что-то уточнить, ничего не смотря. Бесите.

    • Помечено в качестве ответа VintPirat 4 ноября 2013 г. 16:24
    4 ноября 2013 г. 16:24
  • Так вот, у некоторых шрифтов параметр A может быть меньше нуля, и из-за этого всё и происходит.

    А вам должно быть стыдно за такое недееспособное комьюнити и их участников.

    Я четыре раза спросил, какой именно шрифт используется. Ответа не получил ни разу. Кому должно быть стыдно?

    Проблему описал до нулей, код приложил, но народу видно абы что-то уточнить, ничего не смотря.
    Нет, проблема не описана полностью. Спрашиваю в пятый раз: с какими именно шрифтами наблюдается проблема? Код у вас не полный, если просто его скопировать, он не скомпилируется. Не указана среда разработки, не указан компилятор, не указаны настройки проекта, ОС изначально не была указана.
    Бесите.
    Обратитесь к психиатру.
    4 ноября 2013 г. 16:41