2013-04-23 3 views
4

Я новичок в Win32 и пытаюсь получить код на основе GDI в C++ (по техническим причинам не хотят использовать GDI +)win32 - Как нарисовать прямоугольник вокруг текстовой строки?

Edit: Simplied вопроса:

мне нужно нарисовать прямоугольник вокруг текст, который рисуется в середине окна. - Как я могу заполнить координаты прямоугольника? - Может ли кто-нибудь помочь с линией - Прямоугольник (x1, y1, x2, y2)? - Как рассчитать эти значения (x1, y1) & (x2, y2)?

Спасибо ..

 hdc = BeginPaint(hWnd, &ps); 
    GetClientRect(hWnd, &rcClient); 
    SelectObject(hdc, GetStockObject(DEFAULT_GUI_FONT)); 
    SetTextColor(hdc, RGB(255, 0, 0)); 

    DrawText(hdc, wstring(s.begin(),s.end()).c_str(), -1, &rectResult, DT_SINGLELINE | DT_CALCRECT); 

    DrawText(hdc, wstring(s.begin(),s.end()).c_str(), -1, &rcClient, DT_SINGLELINE | DT_CENTER | DT_VCENTER); 

    // Here I need help - How to I place the rectangle around the Text - which is drawn in the middle of the window? 
    // It looks like need to use - rectResult.bottom/top/left/right - but don't know how.. 
    Rectangle(hdc, 0,0,100,100); 
+0

Это пахнет как домашнее задание. где ваши усилия или структура вашей программы? –

+1

GY - Согласитесь, что это больше домашняя работа, но, будучи относительно новой для программирования win32, и на основе того, что я прочитал, нужно создать DC на основе временной памяти, чтобы вычислить размер/ширину текста. ответы из этого потока, но не знаю, как создать временный DC для выполнения этой задачи. Даже если это один текст, окруженный прямоугольником - я могу расширить его дальше - http://stackoverflow.com/questions/1835749/win32-text-drawing-puzzle – ejuser

+1

Это минимальная версия кода, который у меня есть далеко (для одного текста): \t случае WM_PAINT: \t \t HDC = BeginPaint (HWND, &ps); \t \t GetClientRect (HWND, & rcClient); \t \t SelectObject (HDC, GetStockObject (DEFAULT_GUI_FONT)); \t \t SetTextColor (hdc, RGB (255, 0, 0)); \t \t DrawText (hdc, wstring (s.begin(), s.end()). c_str(), -1 , & rcClient, DT_SINGLELINE | DT_CENTER | DT_VCENTER); \t \t // TODO: добавьте код чертежа здесь ... \t \t EndPaint (HWND, &ps); \t \t перерыва; – ejuser

ответ

8

Вы на самом деле не к центру тексту самостоятельно. Функции вывода текста GDI могут сделать это для вас, если вы передадите соответствующие флаги.

Например, если вы вызываете DrawText и передаете флаг DT_CENTER, он автоматически рисует текст в середине указанного прямоугольника (с горизонтальной ориентацией).

Если у вас есть только одна строка текста (который это звучит, как вы делаете), вы можете получить его автоматически вертикально центр текст, передавая DT_SINGLELINE и DT_VCENTER флаги.

Итак, все, что вам действительно нужно сделать, это написать код, чтобы разделить your window's client area на 4 равные части, а затем передать эти прямоугольники в функцию DrawText. Это не сложно. Положите на него карандаш и бумагу, если вы не можете визуализировать ее в своей голове.

void PaintWindow(HWND hWnd) 
{ 
    // Set up the device context for drawing. 
    PAINTSTRUCT ps; 
    HDC hDC = BeginPaint(hWnd, &ps); 
    HPEN hpenOld = static_cast<HPEN>(SelectObject(hDC, GetStockObject(DC_PEN))); 
    HBRUSH hbrushOld = static_cast<HBRUSH>(SelectObject(hDC, GetStockObject(NULL_BRUSH))); 

    // Calculate the dimensions of the 4 equal rectangles. 
    RECT rcWindow; 
    GetClientRect(hWnd, &rcWindow); 

    RECT rc1, rc2, rc3, rc4; 
    rc1 = rc2 = rc3 = rc4 = rcWindow; 

    rc1.right -= (rcWindow.right - rcWindow.left)/2; 
    rc1.bottom -= (rcWindow.bottom - rcWindow.top)/2; 

    rc2.left = rc1.right; 
    rc2.bottom = rc1.bottom; 

    rc3.top = rc1.bottom; 
    rc3.right = rc1.right; 

    rc4.top = rc1.bottom; 
    rc4.left = rc1.right; 

    // Optionally, deflate each of the rectangles by an arbitrary amount so that 
    // they don't butt up right next to each other and we can distinguish them. 
    InflateRect(&rc1, -5, -5); 
    InflateRect(&rc2, -5, -5); 
    InflateRect(&rc3, -5, -5); 
    InflateRect(&rc4, -5, -5); 

    // Draw (differently-colored) borders around these rectangles. 
    SetDCPenColor(hDC, RGB(255, 0, 0)); // red 
    Rectangle(hDC, rc1.left, rc1.top, rc1.right, rc1.bottom); 
    SetDCPenColor(hDC, RGB(0, 255, 0)); // green 
    Rectangle(hDC, rc2.left, rc2.top, rc2.right, rc2.bottom); 
    SetDCPenColor(hDC, RGB(0, 0, 255)); // blue 
    Rectangle(hDC, rc3.left, rc3.top, rc3.right, rc3.bottom); 
    SetDCPenColor(hDC, RGB(255, 128, 0)); // orange 
    Rectangle(hDC, rc4.left, rc4.top, rc4.right, rc4.bottom); 

    // Draw the text into the center of each of the rectangles. 
    SetBkMode(hDC, TRANSPARENT); 
    SetBkColor(hDC, RGB(0, 0, 0)); // black 
    // TODO: Optionally, set a nicer font than the default. 
    DrawText(hDC, TEXT("Hello World!"), -1, &rc1, DT_CENTER | DT_SINGLELINE | DT_VCENTER); 
    DrawText(hDC, TEXT("Hello World!"), -1, &rc2, DT_CENTER | DT_SINGLELINE | DT_VCENTER); 
    DrawText(hDC, TEXT("Hello World!"), -1, &rc3, DT_CENTER | DT_SINGLELINE | DT_VCENTER); 
    DrawText(hDC, TEXT("Hello World!"), -1, &rc4, DT_CENTER | DT_SINGLELINE | DT_VCENTER); 

    // Clean up after ourselves. 
    SelectObject(hDC, hpenOld); 
    SelectObject(hDC, hbrushOld); 
    EndPaint(hWnd, &ps); 
} 

 

+0

Thank You Cody. Ваше предположение верно в отношении одной строки. Это, безусловно, помогает. Удовлетворение (X, Y) co-o Известны rdinates - может ли этот текст быть сосредоточен вокруг него (вместо прямоугольника)? Представьте себе - для этого нужно вычислить высоту и ширину текста - центрировать вокруг (X, Y)? (извинитесь за вопрос, поскольку я на самом деле пытался найти решение для центрирования текста вокруг (x, y) (как по вертикали, так и по горизонтали). Спасибо – ejuser

+0

@ejuser \t Конечно, если вы знаете координаты, вы можете создать RECT структура с ними заполняется и передает его в «DrawText». И да, вы можете рассчитать ширину и высоту, требуемую для строки текста, если хотите. Для этого вы будете использовать ['GetTextExtentPoint32'] (http: //msdn.microsoft.com/en-us/library/windows/desktop/dd144938.aspx), как я помню, вы упомянули где-то в этом вопросе. Это просто больше работы, чем позволить Windows сделать это за вас. [здесь] (http://stackoverflow.com/a/11600004/366904). –

+0

Спасибо, Коди. Изучит дальше и ответит назад. Надеюсь, что это выяснится с подсказками, которые вы предоставили. – ejuser

1
RECT rect={0,0,0,0}; 
const char *str="Test Text"; 
DrawText(hDC, str, strlen(str), &rect, DT_CALCRECT | DT_NOCLIP); 
Rectangle(hDC,rect.left,rect.top,rect.right,rect.bottom); 
DrawText(hDC, str, strlen(str), &rect, DT_CENTER | DT_VCENTER | DT_SINGLELINE|DT_NOCLIP); 
1

Понял наконец :) Большое спасибо Cody Gray указал мне в правильном направлении, об этом :)

GetTextExtentPoint32(hDC, str, strlen(str), &sz2); 
rect2.top=rect2.bottom+sz2.cy; 
rect2.right=rect2.top+sz2.cx; 
Rectangle(hDC,rect2.left,rect2.top,rect2.right,rect2.bottom); 
DrawText(hDC, str, -1, &rect2, DT_CENTER | DT_VCENTER | DT_SINGLELINE|DT_NOCLIP);