IMHO.WS

IMHO.WS (http://www.imho.ws/index.php)
-   Программирование (http://www.imho.ws/forumdisplay.php?f=40)
-   -   DrawText (http://www.imho.ws/showthread.php?t=94029)

doro 11.10.2005 09:50

DrawText
 
Господа! Помогите (с помощью реального кода ;) ) погонять текст на принтере на листе А4 с помощью функции DrawText. Т.е. чтобы текст печатался, например, в любом из углов листа, в центре, в верху, внизу и т.д..
Заранее признателен!

_Lynx_ 11.10.2005 13:46

void CMyView::OnPrint(CDC* pDC, CPrintInfo* pInfo)
{
int adx, ady;
adx=200;
ady=500;
CString str;
POINT curPos;
double mask;
CPoemDoc* curDoc = GetDocument();
str.Format("Документ: %s",(LPCSTR)curDoc->GetTitle());
CSize size;
size = pDC->GetTextExtent(str);

...

pDC->TextOut((pInfo->m_rectDraw.Width()-size.cx)/2, 200, str);
curPos.x = 400;
curPos.y = ady + curRect.Height()*mask + 200;
str = "Информация ...";
pDC->TextOut(curPos.x, curPos.y, str);
pDC->SelectStockObject(BLACK_BRUSH);
for(i=0;i<curDoc->m_objSel.CountElems();i++){
Temp = curDoc->m_objSel[i];
curPos.y += 100;
pDC->Rectangle(curPos.x,curPos.y,1700,curPos.y+3);
curPos.y += 30;
str.Format("%10.10s %5.50s","...:",Temp->code);
str.TrimRight();
if(str.GetLength()>10){
pDC->TextOut(curPos.x, curPos.y, str);
curPos.y += 100;
}
str.Format("%7.10s%15.2d.%.2d.%.4d %5.2d:%.2d","Время:",Temp->dt.wDay,Temp->dt.wMonth,Temp->dt.wYear/*Temp->date*/,Temp->dt.wHour, Temp->dt.wMinute/*Temp->time*/);
str.TrimRight();
if(str.GetLength()>7){
pDC->TextOut(curPos.x, curPos.y, str);
curPos.y += 100;
}

...

}

doro 13.10.2005 20:12

_Lynx_
Огромное спасибо! Но где же работа DrawText? :idontnow:

_Lynx_ 14.10.2005 18:54

не заметил :) использовал TextOut

RECT rect={0,0,100,20};
pDC->DrawText("Какая-то фраза", -1, &rect, DT_CENTER);

doro 15.10.2005 16:16

_Lynx_

В rect что определяется? Размер области печати?

Вот что родил:
Код:

        TPrinter *Prntr = Printer();
        TRect r = Rect(0,0, Prntr->PageWidth, Prntr->PageHeight);

        AnsiString MyText="Проверка";

        Prntr->BeginDoc();

                DrawText(Prntr->Canvas->Handle, MyText.c_str(),                        MyText.Length(), &r, DT_SINGLELINE |DT_VCENTER | DT_CENTER);
        Prntr->EndDoc();

Но вот другая проблема появилась. Как перевести каретку на новую строку (насильно), чтобы следующий DrawText можно было напечатать. А то лепятся в одну строку или в конце текста.
И всё же на счёт rect'а не совсем ясно.

kot_ 24.10.2005 17:57

Цитата:

Сообщение от doro
_Lynx_

В rect что определяется? Размер области печати?

Вот что родил:
Код:

        TPrinter *Prntr = Printer();
        TRect r = Rect(0,0, Prntr->PageWidth, Prntr->PageHeight);

        AnsiString MyText="Проверка";

        Prntr->BeginDoc();

                DrawText(Prntr->Canvas->Handle, MyText.c_str(),                        MyText.Length(), &r, DT_SINGLELINE |DT_VCENTER | DT_CENTER);
        Prntr->EndDoc();

Но вот другая проблема появилась. Как перевести каретку на новую строку (насильно), чтобы следующий DrawText можно было напечатать. А то лепятся в одну строку или в конце текста.
И всё же на счёт rect'а не совсем ясно.

Rect определяет границы в которых ты рисуешь. Его размеры вовсе не обязательно должны быть на всю страницу. Потому у тебя текст и лепится один к одному - используй для каждой строки свой rect и все нормально будет. Пример как перенести строку - извини правда что с текстаут - но разницы большой нет - фрагмент - pCanvas->TextOutA(PosGor,PosVert,String); просто заменяешь на DrawText(Prntr->Canvas->Handle, MyText.c_str(), MyText.Length(), &r, DT_SINGLELINE |DT_VCENTER | DT_CENTER); а в TRect r = Rect(PosGor,PosVer,Prntr->Canvas->TextWidth(MyText), Prntr->Canvas->TextHeight(MyText)); указывай соответственно координаты нужной тебе строки.
PosGor - горизонтальная координата,PosVer - вертикальная координата, BottomWidth&&RightWidth - отступы соответственно снизу и справа от края страницы.
Код:

...
    if(g!="\r"&&g!="\n"){
    pCanvas->TextOutA(PosGor,PosVert,g);
    PosGor += pCanvas->TextWidth(g);
    }
    j++;
  }while(String.Length()>= j);
 String = "Получатель: "+Form1->stFirmAddress->Caption+"\r\n";
  j = 1;
  PosGor = LeftWidth;
    do{
    AnsiString g = String[j];
    if(PosGor >= (Prn->PageWidth-RightWidth)||g=="\r"){
    PosGor = LeftWidth+pCanvas->TextWidth("Поставщик: ");
    if(PosVert >= (Prn->PageHeight-BottomWidth)){
      Prn->NewPage();
      PosVert = TopWidth;
      }

    PosVert += pCanvas->TextHeight(String);
    }
 
if(PosVert >= (Prn->PageHeight-BottomWidth)){
 Prn->NewPage();
 PosVert = TopWidth;
 }
PosVert += pCanvas->TextHeight(String)*2;
...


doro 29.10.2005 16:34

kot_, твоё сообщение добило почти окончательно мою тупость.
Но остатки остались. :)

Вот код:
Код:

AnsiString VD = "", VM = "", VY = "", StartD="", StartM="", StartY="", EndD="", EndM="", EndY="", ChisloD="", ChisloM="", ChisloY="";

DateTimeToString(VD, "dd" ,DateTimePicker1->Date);
DateTimeToString(VM, "mm" ,DateTimePicker1->Date);
DateTimeToString(VY, "yyyy" ,DateTimePicker1->Date);

DateTimeToString(StartD, "dd" ,DateTimePicker2->Date);
DateTimeToString(StartM, "mm" ,DateTimePicker2->Date);
DateTimeToString(StartY, "yyyy" ,DateTimePicker2->Date);

DateTimeToString(EndD, "dd" ,DateTimePicker3->Date);
DateTimeToString(EndM, "mm" ,DateTimePicker3->Date);
DateTimeToString(EndY, "yyyy" ,DateTimePicker3->Date);

r=Rect(XCoordinate, YCoorfinate+350, CurPrinter->PageWidth,CurPrinter->PageHeight);

AnsiString TextRaporta=AnsiString("\tАаааа бббббббббббб вввввввв")+VD+" "+Months[VM.ToInt()-1]+" "+VY+AnsiString(" гггг зз жжжжж")+ComboBox1->Text+AnsiString(" и ")+StartD+" "+Months[StartM.ToInt()-1]+StartY+" "+AnsiString(" кккк лл ")+EndD+" "+Months[EndM.ToInt()-1]+" "+EndY+AnsiString(" оооо.");
                DrawText(CurPrinter->Canvas->Handle,
                        TR.c_str(),
                        TR.Length(),
                        &r,
                        DT_EXPANDTABS|DT_WORDBREAK | DT_LEFT);

Количество букв в словах текста соответсвует оригиналу. Так вот если в ComboBox'е длинный текст, то при печати он вылещает за границы листа на 5-7 символов. При короком тесте - всё нормально. Проблемы... :confused:

kot_ 30.10.2005 00:28

Не совсем понял - так а проблема в чем? Проверяй длинну строки перед тем как ее выводить. В приведенном примере - так как объем выводимых данных невелик, и данные жестко вшиты в код, функция автопереноса не выделялись отдельно - то есть я проверяю длину строки прямо в коде, и в принципе это нормально работало:
Код:

String = "Поставщик: " + Form1->stPostav->Caption+"\r\n";
  int j = 1;
  do{
    AnsiString g = String[j];
    if(PosGor >= (Prn->PageWidth-RightWidth)||g=="\r"){
    PosGor = LeftWidth+pCanvas->TextWidth("Поставщик: ");
    if(PosVert >= (Prn->PageHeight-BottomWidth)){
      Prn->NewPage();
      PosVert = TopWidth;
    }

    PosVert += pCanvas->TextHeight(String);
    }
    if(g!="\r"&&g!="\n"){
    pCanvas->TextOutA(PosGor,PosVert,g);
//Выводится каждый отдельный символ - не строка!!!
    PosGor += pCanvas->TextWidth(g);
    }
    j++;
}while(String.Length()>= j);

Но вобще-то бы стоило делать это отдельным потоком - на больших объемах вывода такой код здорово будет тормозить.
То же и у тебя - тебе нужно или проверять всю строку - и выводить ту дельту которая разница между шириной страницы и шириной строки в отдельную строку - используя субстринг - или выводить посимвольно - проверяя не попадает ли символ за пределы страницы.
Тут кстати, че-то я накрутил с фигурными скобками и объявлениями, звиняй, ессественно не нужно в конструкции do{}while объявлять переменную, просто реальный код менее читаем, там используется ряд полей класса и т.д. и объем его гораздо более. Я надеюсь общая идея понятна.

doro 30.10.2005 02:44

Это всё хорошо, но ведь я рисую на канвасе принтера, который получил, использую в DrawText DT_WORDBREAK. Поэтому мне не совсем понятно почему текст вылезает за пределы страницы вообще. :confused:

kot_ 30.10.2005 02:48

Цитата:

Сообщение от doro
Это всё хорошо, но ведь я рисую на канвасе принтера, который получил, использую в DrawText DT_WORDBREAK. Поэтому мне не совсем понятно почему текст вылезает за пределы страницы вообще. :confused:

Хз. Такой вот код работает но не так как надо:
Код:

TRect r = Rect(30,50, this->Width,this->Height);
AnsiString TR=AnsiString("\tАаааа бббббббббббб ввввввввnnnnnnnnnnnnnnnnnnnnnnn nnnnnnnnnnnnnnnnnnnnnnnn nnnnnnnnnnnnnn nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn 1111111111111111111 1111111111111111111 1111111111111111");
DrawText(this->Canvas->Handle,
                        TR.c_str(),
                        TR.Length(),
                        &r,
                        DT_EXPANDTABS|DT_WORDBREAK | DT_LEFT);

т.е. часть символов между пробелами нормально не переносится. Как по мне проще реализовать свою функцию - чем биться разбираясь почему не работает толком библиотечная. А она скорее всего переносит по пробелам, а не так как моя - по символам, может еще что-то. Хотя скорость вывода на экран одинакова.
Угу. удалил пробелы до единиц - результат - строка полезла за границы формы и перенос только на единицах.

doro 10.11.2005 04:13

Что-то ни с того ни с сего заработал у меня DrawText. :confused:


Часовой пояс GMT +4, время: 04:35.

Powered by vBulletin® Version 3.8.5
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.