none
SetTextAlign не понятно как работает с функцией TextOut на visual c++ RRS feed

  • Вопрос

  • среда -  visual studio 2010 | язык-  visual c++| платформа -windows xp 

    Здравствуйте. Хочу узнать всю подноготную этой функции SetTextAlign при работе с функцией TextOut
    Так как, работает нормально если параметры функции такие  SetTextAlign(hdc, TA_LEFT | TA_TOP | TA_UPDATECP ) или просто    SetTextAlign(hdc, TA_LEFT ) но не видно текста если указан параметр  TA_RIGHT а если параметр  TA_CENTER то показывает во первых текст в левом верхнем углу почемуто и то обрезанный  на половину.
    Хочу узнать причины этого  и особенности работы этой функции - SetTextAlign в языке visual c++   ..

    
    
    // GT_HelloWorldWin32.cpp
    // compile with: /D_UNICODE /DUNICODE /DWIN32 /D_WINDOWS /c
    
    #include <windows.h>
    #include <stdlib.h>
    #include <string.h>
    #include <tchar.h>
    
    // Global variables
    // The main window class name. 
    static TCHAR szWindowClass[] = _T("pk");//
    
    // The string that appears in the application's title bar.
    static TCHAR szTitle[] = _T("title some");// 
    
    HINSTANCE hInst_my_prilogenie;//
    
    // Forward declarations of functions included in this code module:
    LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);// 
    
    int WINAPI WinMain(HINSTANCE hInstance,
                       HINSTANCE hPrevInstance,
                       LPSTR lpCmdLine,
                       int nCmdShow)
    {
        WNDCLASSEX wcex; //  
        wcex.cbSize = sizeof(WNDCLASSEX);//
        wcex.style          = CS_HREDRAW | CS_VREDRAW;//
    
        wcex.lpfnWndProc    = WndProc; 
        wcex.cbClsExtra     = 0;
        wcex.cbWndExtra     = 0;
        wcex.hInstance      = hInstance;
        wcex.hIcon          = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_APPLICATION));
        wcex.hCursor        = LoadCursor(NULL, IDC_ARROW);
        wcex.hbrBackground  = (HBRUSH)(COLOR_WINDOW+1); //  кстати говоря  COLOR_WINDOW+5 выдал белый цвет и +3 тоже              (HBRUSH)(COLOR_WINDOW+1);
        wcex.lpszMenuName   = NULL;
        wcex.lpszClassName  = szWindowClass;
        wcex.hIconSm        = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_APPLICATION));
    
        RegisterClassEx(&wcex);
    
        hInst_my_prilogenie = hInstance; //  
    
    
        // The parameters to CreateWindow explained:
        // szWindowClass: the name of the application
        // szTitle: the text that appears in the title bar
        // WS_OVERLAPPEDWINDOW: the type of window to create
        // CW_USEDEFAULT, CW_USEDEFAULT: initial position (x, y)
        // 500, 100: initial size (width, length)
        // NULL: the parent of this window
        // NULL: this application does not have a menu bar
        // hInstance: the first parameter from WinMain
        // NULL: not used in this application
        HWND hWnd = CreateWindow(
            szWindowClass,// 
            szTitle,// 
            WS_OVERLAPPEDWINDOW, // 
            CW_USEDEFAULT, CW_USEDEFAULT,// 
            500, 400,
            NULL,
            NULL,
            hInstance,// 
            NULL
        );
    
      
        ShowWindow(hWnd,
            nCmdShow);
        UpdateWindow(hWnd);
    
        // Main message loop:
        MSG msg;
        while (GetMessage(&msg, NULL, 0, 0))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
    }
    
        return (int) msg.wParam;
    }
    
    //
    //  FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM)
    //
    //  PURPOSE:  Processes messages for the main window.
    //
    //  WM_PAINT    - Paint the main window
    //  WM_DESTROY  - post a quit message and return
    //
    //
    LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
    
        PAINTSTRUCT ps;
        HDC hdc;
    
    		TCHAR greeting[] = _T("must be by centre but..");
    		
    
    
        switch (message)
        {
    
    
        case WM_PAINT:
            hdc = BeginPaint(hWnd, &ps);
    
    
    
    UINT Align;
    Align = SetTextAlign(hdc, TA_CENTER | TA_TOP | TA_UPDATECP  ) ; //
    
    
    
    
            // Here your application is laid out.
            // For this introduction, we just print out "Hello, World!"
            // in the top left corner.
            TextOut(hdc, //TextOut записывает строку символов в заданном месте, используя текущий выбранный шрифт, цвет фона и цвет текста.
                50, 5,
                greeting ,_tcslen(greeting)); /**/
            // End application-specific layout section.
    
    
    SetTextAlign(hdc, Align);
    	
    
    
            EndPaint(hWnd, &ps);
            break;
        case WM_DESTROY:
            PostQuitMessage(0);
            break;
        default:
            return DefWindowProc(hWnd, message, wParam, lParam);
            break;
        }
    
        return 0;
    }
    
    
    
    
    





    • Изменено luch55 19 августа 2013 г. 15:41
    17 августа 2013 г. 17:16

Ответы

  • Успокойтесь, пожалуйста. Я и не думал уклоняться. Наоборот, пытаюсь помочь Вам. Здесь, вообще-то, принято помогать добровольно. И никто ни кому ничего не должен :) Так что, Ваши претензии в таком тоне не обоснованы. Я описал Вам принцип работы механизма отображения текста в окне Windows на русском языке. Если этого не достаточно, вот фрагмент кода на C++:

    const wchar_t *message = L"Hello!";
    int len = wcslen(message);
    
    ::SetTextAlign(hdc, TA_LEFT | TA_TOP);
    ::TextOut(hdc, 10, 10, message, len);
    
    ::SetTextAlign(hdc, TA_RIGHT | TA_BOTTOM);
    ::TextOut(hdc, 48, 40, message, len);
    
    ::SetTextAlign(hdc, TA_CENTER | VTA_CENTER);
    ::TextOut(hdc, 29, 38, message, len);

    В случае использования в контексте устройства шрифта по умолчанию, этот код приводит к отображению 3-х строк, расположенных строго одна под другой.
    21 сентября 2013 г. 21:51

Все ответы

  • Здравствуйте!

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

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

    http://social.msdn.microsoft.com/Forums/en-eu


    Мнения, высказанные здесь, являются отражением моих личных взглядов, а не позиции корпорации Microsoft. Вся информация предоставляется "как есть" без каких-либо гарантий.

    19 августа 2013 г. 9:27
    Модератор
  • Здравствуйте!

    Посмотрите учебник.

    22 августа 2013 г. 10:14
  •  этот учебник я уже пересмотрел ещё до того как написал вопрос. ошибок в коде я не делал .. Так что  , вопрос какой был  ,такой и остаеться
    • Изменено luch55 23 августа 2013 г. 6:26
    23 августа 2013 г. 6:26
  • Координаты в TextOut задают опорную точку, относительно которой будет выведен текст в соответствии с текущим выравниванием (SetTextAlign). Если выравнивание LEFT-TOP, тогда опорная точка является левым верхним углом прямоугольника, в котором появится текст, а если RIGHT-TOP, то правым верхним углом и т.д. Вот и вся премудрость :)
    • Изменено kosuke904 4 сентября 2013 г. 22:28
    • Предложено в качестве ответа kosuke904 4 сентября 2013 г. 22:30
    4 сентября 2013 г. 22:27
  • Спасибо за попытку истолковать  .Но  в вопросе было "...... работает нормально если параметры функции такие SetTextAlign(hdc, TA_LEFT | TA_TOP | TA_UPDATECP ) или просто SetTextAlign(hdc, TA_LEFT ) но не видно текста если указан параметр TA_RIGHT а если параметр TA_CENTER то показывает во первых текст в левом верхнем углу почемуто и то обрезанный на половину.  "

    НЕ только я сталкивался с этим вопросом вот подобная темя с анг. форума майкросовт по висуал 

    ссылка (в новом окне)


    • Изменено luch55 20 сентября 2013 г. 23:45
    20 сентября 2013 г. 4:40
  • Для того, чтобы текст "было видно", координаты в TextOut дожны быть ДРУГИМИ. Для выравнивания RIGHT координата X должна задавать ПРАВУЮ границу.
    20 сентября 2013 г. 5:41
  • Спасибо за уклончивый  ответ .Но возникает другой вопрос к вам почему  - бы не написать "Для того, чтобы текст "было видно" код должен быть ДРУГИМ" 

    Мне в жизни в голову не пришло бы  по програмированию давать уклончивые  ответы.  

    Вы бы показали пример как именно  выравнивать координаты .А если лень то не надо засорять мне мозги .Разве не видете я пытаюсь по полочкам разложить важную  для меня  тему?


    • Изменено luch55 20 сентября 2013 г. 23:54
    20 сентября 2013 г. 23:50
  • Успокойтесь, пожалуйста. Я и не думал уклоняться. Наоборот, пытаюсь помочь Вам. Здесь, вообще-то, принято помогать добровольно. И никто ни кому ничего не должен :) Так что, Ваши претензии в таком тоне не обоснованы. Я описал Вам принцип работы механизма отображения текста в окне Windows на русском языке. Если этого не достаточно, вот фрагмент кода на C++:

    const wchar_t *message = L"Hello!";
    int len = wcslen(message);
    
    ::SetTextAlign(hdc, TA_LEFT | TA_TOP);
    ::TextOut(hdc, 10, 10, message, len);
    
    ::SetTextAlign(hdc, TA_RIGHT | TA_BOTTOM);
    ::TextOut(hdc, 48, 40, message, len);
    
    ::SetTextAlign(hdc, TA_CENTER | VTA_CENTER);
    ::TextOut(hdc, 29, 38, message, len);

    В случае использования в контексте устройства шрифта по умолчанию, этот код приводит к отображению 3-х строк, расположенных строго одна под другой.
    21 сентября 2013 г. 21:51
  •   Да , это не биржа для фрилансеров  и денег вы у меня не крали -  взяв на перед и не сделав работу. 

    Но  , во первых я сам программист , правда по серверным технология (и по браузерным - яваскрипт    ) и считаю дурным тоном в програмировании упускать даже ";" в коде не говоря уже об обобщенном истолковании.

      Порыскав по рунету  и даже англоязычному пришел в негодование - увидев как не разобравшись   с подобной проблеммой при использовании  SetTextAlign() -  сразу перескакивали на функцию   DrawText () , в которой координаты прямоугольника не надо указывать  и использовать TextOut ( ) тоже

      PAINTSTRUCT ps;
       HDC hdc;
       TCHAR szBuffer [40];
      int iLength;
       RECT clientRect;
    
       case WM_PAINT:
         hdc = BeginPaint(hWnd, &ps);
        iLength = wsprintf(szBuffer, TEXT("The sum of %i and %i is %i"), 1, 2, 3)
        GetClientRect (hwnd, &rect);
         DrawText (hdc, szBuffer, iLength, clientRect, DT_CENTER | DT_VCENTER | DT_NOPREFIX);
         EndPaint(hWnd, &ps);

     но я твердо решил -  не смеяться с неудачи ,  не разводить руками и не сваливать на якобы сырость функции SetTextAlign() , а разложить ее по полочкам - вот и не хотел других ответов кроме  тех , которые  все детали данной функции способны осветить... 


    • Изменено luch55 30 сентября 2013 г. 20:11
    30 сентября 2013 г. 20:09
  • Я так и не понял: мой последний ответ Вас удовлетворил или что-то еще не понятно?
    30 сентября 2013 г. 20:16
  • этот фрагмент

    const wchar_t *message = L"Hello!";
    int len = wcslen(message);

    не хочет компилировать-ошибки выкидывает

    если так то так нормально компилирует по крайней мере у меня на XP

     TCHAR greeting[] = _T(" Hello! ");
    _tcslen(greeting)

    то есть чтоб красиво текст  по середине вывести  один "Hello!!" ниже другого надо получить размер окна GetWindowRect() и поделить пополам?  но еще надо ведь размер шрифта учитывать....

    30 сентября 2013 г. 21:35
  • этот фрагмент

    const wchar_t *message = L"Hello!";
    int len = wcslen(message);

    не хочет компилировать-ошибки выкидывает

    если так то так нормально компилирует по крайней мере у меня на XP

     TCHAR greeting[] = _T(" Hello! ");
    _tcslen(greeting)

    Ну, это зависит от настроек проекта "Общие\Набор символов". Если использовать кодировку Юникод (установлена по умолчанию), то и мои строчки скомпилируются. Хотя Ваш вариант лучше с точки зрения переносимости кода.

    В случае выравнивания TA_CENTER, действительно, нужно указать середину области вывода текста. Размер шрифта важен для выбора координаты Y. Тут можно действовать либо подбором подходящего значения, либо воспользоваться функциями типа GetTextMetrics или GetTextExtentPoint32 для вычисления размеров конкретной строки.

    30 сентября 2013 г. 21:53