Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.

TextWidth problem u iscitavanju sirine BOLD teksta

[es] :: C/C++ programiranje :: TextWidth problem u iscitavanju sirine BOLD teksta

[ Pregleda: 2485 | Odgovora: 18 ] > FB > Twit

Postavi temu Odgovori

Autor

Pretraga teme: Traži
Markiranje Štampanje RSS

drugtito
Milovan Djilas

Član broj: 138118
Poruke: 56
*.dynamic.sbb.rs.



+1 Profil

icon TextWidth problem u iscitavanju sirine BOLD teksta04.08.2008. u 02:14 - pre 191 meseci
Pozdrav
Naime primetio sam da
Canvas->TextWidth(nekitekst) metoda vraca
apsolutno iste vrednosti i za regular i za bold varijantu,

pr.:

neki ispis
neki ispis

iako im sirina nije ista, sto je ocigledno.
Ja bih trebao da uklopim u neki rect odredjeni tekst
ali mi se problem javlja kada boldujem tekst jer sama metoda
ocigledno ne vraca pravu sirinu vec uvek meri regular type teksta! :(

Koju metodu koristite za iscitavanje PRAVE sirine nekog teksta.
Pomoc !

Unapred Hvala
 
Odgovor na temu

X Files
Vladimir Stefanovic
Pozarevac

SuperModerator
Član broj: 15100
Poruke: 4902
*.tekostolac.co.yu.

Jabber: xfiles@elitesecurity.org


+638 Profil

icon Re: TextWidth problem u iscitavanju sirine BOLD teksta04.08.2008. u 06:56 - pre 191 meseci
Koji tekst meris? Da li je to TLabel, linija teksta u TMemo ili TRichEdit polju?

Kada je u pitanju TLabel ili TMemo, mozes koristiti TControlCanvas objekat, na primer:
(netestirano)
Code:

// Label1 i Label2 su recimo razlicitog stila, jedan je obican drugi je bold
#include <memory>
void __fastcall TForm1::Button1Click(TObject *Sender)
{
   std::auto_ptr<TControlCanvas>LabelCanvas( new TControlCanvas() );

   LabelCanvas->Control = Label1;
   LabelCanvas->Font = Label1->Font;
   ShowMessage( LabelCanvas->TextWidth( Label1->Caption ) );

   LabelCanvas->Control = Label2;
   LabelCanvas->Font = Label2->Font;
   ShowMessage( LabelCanvas->TextWidth( Label2->Caption ) );
}


... ako se radi o TRichEdit, gde se u jednoj (istoj) liniji moze naci vise velicina fonta i formata, potreban je nesto slozeniji kod:

http://www.elitesecurity.org/t253482-0#1524103
 
Odgovor na temu

drugtito
Milovan Djilas

Član broj: 138118
Poruke: 56
*.dynamic.sbb.rs.



+1 Profil

icon Re: TextWidth problem u iscitavanju sirine BOLD teksta04.08.2008. u 11:15 - pre 191 meseci
Nekoristim ni jednu kontrolu.

Fakticki je title dbgrid-a, implementiram
sort mark pored texta, koji se pozicionira perfektno
dok korisnik ne izabere recimo da title
caption bude bold. E sad ukoliko je malo duzi
caption, sort mark (strelica) se ponekad i ne vidi.

Jednostavno nisam znao sta se desava, izludeh, dok salucajno
nisam primetio da mi iscitava isti
Canvas->TextWidth(Caption), i za regulari za bold, sto mi je
malo da kazem neverovatno ! Suvise je ocigledan (kao bug)
da borland tako nesto pusti da egzistira !
T.j. ne implementira metodu za realni textwidth.

Pomislih da postoji :(

Jedino da ubacim fake TLabel u TDBgrid samo za to...
ne znam , videcu

u svakom slucaju hvala mr. moderator :)
 
Odgovor na temu

nikomak
Nikola Makić
Beograd

Član broj: 177053
Poruke: 65
*.eunet.rs.



+1 Profil

icon Re: TextWidth problem u iscitavanju sirine BOLD teksta04.08.2008. u 15:58 - pre 191 meseci
Pozdrav,

Ovaj problem je i mene mucio (u Delphi-u doduse), mada sam ga resio ovako nekako, koristeci windows api

Code:

int __fastcall TForm1::GetTextWidth(AnsiString Text, TFont *F)
{
    int res = 0;
    HDC Dc;
    HFONT SFont = 0;
    TSize t;
    Dc = GetDC(0);
    __try {
        SFont = SelectObject(Dc, F->Handle);
        if (GetTextExtentPoint32A(Dc, Text.c_str(), Text.Length(), &t)) {
            res = t.cx;
        }
    }
    __finally {
        SelectObject(Dc, SFont);
        ReleaseDC(0, Dc);
    }
    return res;
}



TurboDispatchJumpAddressEnd
----
Knocka Fia
----
And so we meet, again in a different time
 
Odgovor na temu

kiklop74
Darko Miletić
Buenos Aires

Član broj: 78422
Poruke: 569
200.49.157.*

Sajt: ar.linkedin.com/pub/darko..


+13 Profil

icon Re: TextWidth problem u iscitavanju sirine BOLD teksta04.08.2008. u 16:50 - pre 191 meseci
Zasto __try _finally blok?

Nije li bolje koristiti raii npr:

Code:

struct job {
  job() {
   //do code 
 }
 ~job(){
  //on exit
 }
};



Tko leti vrijedi
 
Odgovor na temu

drugtito
Milovan Djilas

Član broj: 138118
Poruke: 56
*.dynamic.sbb.rs.



+1 Profil

icon Re: TextWidth problem u iscitavanju sirine BOLD teksta04.08.2008. u 17:09 - pre 191 meseci
Verovatno stvar ukusa, mirisa i ostalo :)

Uglavnom, @nikomak
bukvalno sam prepisao, ubacio i sve radi ki singerica!

thx mano

P.S. i dalje ne mogu da verujem da borland magovi to nisu ispravili ?
 
Odgovor na temu

savkic
Igor Savkić

Član broj: 92186
Poruke: 2739



+92 Profil

icon Re: TextWidth problem u iscitavanju sirine BOLD teksta04.08.2008. u 19:17 - pre 191 meseci
> if (GetTextExtentPoint32A(Dc, Text.c_str(), Text.Length(), &t)) {
> Uglavnom, @nikomak
> bukvalno sam prepisao, ubacio i sve radi ki singerica!
> P.S. i dalje ne mogu da verujem da borland magovi to nisu ispravili ?

VCL TextWidth funkcija (barem u Delphiu, nemam Builder instaliran da pogledam) se na kraju svede na GetTextExtentPoint32 API funkciju, dakle ne verujem da je tu problem. Mislim da treba gledati u pravcu HDC/TCanvasa, verovatno si koristio pogrešan. Spominješ DBGrid i njegov title, mislim da DBGrid nema odvojene canvase za nazive kolona i sadržaj što verovatno znači da si u oba slučaja koristio glavni Canvas odnosno font grida a ne titlefont.
 
Odgovor na temu

deerbeer
Beograd

Član broj: 174418
Poruke: 1189
*.adsl-1.sezampro.yu.



+395 Profil

icon Re: TextWidth problem u iscitavanju sirine BOLD teksta04.08.2008. u 19:52 - pre 191 meseci
Mozes i sa funkcijom DrawText pa da prosledis flag DT_CALCRECT i da u RECT strukturi dobijes dimenzije fonta :
http://msdn.microsoft.com/en-us/library/ms533909(VS.85).aspx
Ova funkcija sa ovim flagom ne ispisuje nikakav text iako se tako zove .

Citat:
@kiklop
Zasto __try _finally blok?

Da nema potrebe tj.beskorisno je koristiti try/catch/finally blokove u pozivima api funkcija ...


Viva lollapalooza
 
Odgovor na temu

nikomak
Nikola Makić
Beograd

Član broj: 177053
Poruke: 65
*.eunet.rs.



+1 Profil

icon Re: TextWidth problem u iscitavanju sirine BOLD teksta04.08.2008. u 23:10 - pre 191 meseci
Citat:
deerbeer
Da nema potrebe tj.beskorisno je koristiti try/catch/finally blokove u pozivima api funkcija ...


Ne razumem ? Kako je beskorisno ? Da je kojim slucajem u gornjem primeru TFont nevazeci ptr vcl bi bacio exception i ReleaseDC se nikada i ne bi izvrsio. Mozda je nestandardno, ali mislim da i Microsoft-ov kompajler podrzava (__try/__finally), dok kod Borland kompajlera nije ni potrebno navoditi __ ispred try ako se dobro secam.

Na primer, kako moze biti "beskorisno" u sledecem primeru, u nekom visenitnom programu, a i ovo su sve api funkcije

Code:

CRITICAL_SECTION cs;
EnterCriticalSection(&cs);
__try {
    /// neki kod koji moze da baci exception     
}
__finally {
 /// cleanup
 LeaveCriticalSection(&cs);
}


Elaborate, please :)
TurboDispatchJumpAddressEnd
----
Knocka Fia
----
And so we meet, again in a different time
 
Odgovor na temu

drugtito
Milovan Djilas

Član broj: 138118
Poruke: 56
*.dynamic.sbb.rs.



+1 Profil

icon Re: TextWidth problem u iscitavanju sirine BOLD teksta05.08.2008. u 00:27 - pre 191 meseci
@savkic
DBGrid ima odvojene Canvas-e
pogotovu ako pises novu vcl komponentu
izvedenu iz TDBGrid-a.
Konkretno je DrawTitleCell metoda

Code:

class PACKAGE MOJDBGRID: public TDBGrid
{
protected:
   int __fastcall StringWidth(AnsiString text,TFont *fF);
   void __fastcall DrawTitleCell (int ACol, int ARow, const Types::TRect &ARect,          ->za title 
                                         Grids::TGridDrawState AState);
   void __fastcall DrawColumnCell(const TRect &Rect,
                                          int DataCol, TColumn *Column,TGridDrawState State);  ->za nizove kolona
};
//---------------------------------------------------------------------------
void __fastcall MOJDBGRID::DrawTitleCell (int ACol, int ARow, const Types::TRect &ARect, Grids::TGridDrawState AState)
{
   @nikomak bi izgledalo ovako
   int text_length = StringWidth(sText,Columns->Items[nDataCol]->Title->Font);
    .............................
   @X-Files
   isto samo moram da ubacim fake TLabel, new TLabel(this), delete Tlabel etc
   deklarisem parent, poziciju etc...
}//---------------------------------------------------------------------------
int __fastcall MOJDBGRID::StringWidth(AnsiString text,TFont *fF) 
{
   int res = 0;
   HDC Dc;
   HFONT SFont = 0;
   TSize t;
   Dc = GetDC(0);
   __try
   {
      SFont = SelectObject(Dc, fF->Handle);
      if (GetTextExtentPoint32A(Dc, text.c_str(), text.Length(), &t))
         res = t.cx;
   }
   __finally
   {
      SelectObject(Dc, SFont);
      ReleaseDC(0, Dc);
   }
   return res;
}


tako da ni u jednom slucaju nisam koristio pogresne metode
Moze i sa X-Files primerom, generalno, probao sam.
Ali u mom slucaju elegantno je zavrsio posao nikomakov primer.

Jednostavno, zbunjen sam bio, jer mi ni na kraj pameti
nije palo da Canvas->TextWidth(Title->Caption) ne vraca
pravu vrednost. Ta metoda doslovce meri samo Regular Font Style
bez obzira da li ste dinamicki promenili u bold ! :(
 
Odgovor na temu

deerbeer
Beograd

Član broj: 174418
Poruke: 1189
*.adsl-a-1.sezampro.yu.



+395 Profil

icon Re: TextWidth problem u iscitavanju sirine BOLD teksta05.08.2008. u 09:26 - pre 191 meseci
Citat:
nikomak: Ne razumem ? Kako je beskorisno ? Da je kojim slucajem u gornjem primeru TFont nevazeci ptr vcl bi bacio exception i ReleaseDC se nikada i ne bi izvrsio. Mozda je nestandardno, ali mislim da i Microsoft-ov kompajler podrzava (__try/__finally), dok kod Borland kompajlera nije ni potrebno navoditi __ ispred try ako se dobro secam.

Elaborate, please :)


Cisti win api pozivi u tvom slucaju:
Code:
 
 SFont = SelectObject(Dc, fF->Handle);
      if (GetTextExtentPoint32A(Dc, text.c_str(), text.Length(), &t))


se u principu ne stavljaju (ajd nije bas beskorisno ako te je to pogodilo ) u try/catch blokove jer greske proveravas
uglavnom sa povratnim vrednostima funkcije ili testiranjem na NULL pointer ili sa funkcijiom GetLastError (brzi je kod ).
Postoji implementacija za MS compilere structure exception handling na nivou Win32 api ili C koda (__try/__finally), koji nije bas dobro dokumentovan
a handlovati greske u tvom kodu na tom nivou postaje u nekim slucajevima dodatni izvor bug-ova ..
Evo kompletne elaboracije ako si spreman na citanje : http://www.microsoft.com/msj/0197/Exception/Exception.aspx


Viva lollapalooza
 
Odgovor na temu

X Files
Vladimir Stefanovic
Pozarevac

SuperModerator
Član broj: 15100
Poruke: 4902
*.tekostolac.co.yu.

Jabber: xfiles@elitesecurity.org


+638 Profil

icon Re: TextWidth problem u iscitavanju sirine BOLD teksta05.08.2008. u 09:55 - pre 191 meseci
Kljucna rec finally nije deo C++ jezika (vec je u BCB samo ekstenzija preuzeta radi kompatibilnosti sa Delphijem) i kiklop74 je pretpostavljam stoga pomenuo RAII pristup za smestanje clean-up koda, sto je u C++ 100% garantovano ponasanje koda pri destrukciji objekta.

Problem sa ekstenzijama jezika (ako cak zanemarimo pitanje prenosivosti) je sto bas i nemaju obavezu da se pridrzavaju standarda.

Konkretno, try/finally implementacija u BCB ima anomalije.


Primer 1 : Očekivano ponašanje
Code:

void __fastcall TForm1::Button1Click(TObject *Sender)
{
   try
   {
      // prevremeni return ...
      return;
   }
   __finally
   {
      ShowMessage( "Garantovano se izvršava, kao što je i predviđeno strukturom!" );
   }
}



Primer 2 : Neočekivano ponašanje
Code:

void __fastcall TForm1::Button2Click(TObject *Sender)
{
   try
   {
      try
      {
         // Proizvodi izuzetak...
         int x = StrToInt( "abc" );
      }
      catch ( const Exception &e )
      {
         // prevremeni return, ali bez obzira, očekujemo da se prethodno izvrši i finally blok...
         return;
      }
   }
   __finally
   {
      ShowMessage( "Da li je izvršeno, proverite sami..." );
   }
}


U BCB imlementaciji postoji problem sa ugnježdenim try/finally. U principu, ko ovo zna lako je izmeniti kod, ali kad programirate obično se oslanjate na zdrav razum koji ovde očigledno ne pali. Još veći problem bi bio da u nekoj narednoj verziji isprave ovakav bug a vi u međuvremenu već napravili neki Workarround koji će možda proizvesti dvostruko ispaljivanje koda za destrukciju.

Ovo je naravno samo hipotetički, ali i odgovor zašto je dobra praksa držati se standardnih rešenja koje pominje kiklop74.
 
Odgovor na temu

deerbeer
Beograd

Član broj: 174418
Poruke: 1189
*.adsl-a-1.sezampro.yu.



+395 Profil

icon Re: TextWidth problem u iscitavanju sirine BOLD teksta05.08.2008. u 10:23 - pre 191 meseci
Citat:
@XFiles
Ovo je naravno samo hipotetički, ali i odgovor zašto je dobra praksa držati se standardnih rešenja koje pominje kiklop74.


Evo uporednog pregleda Exception handlinga koji opravdava ovu tvrdnju
http://209.85.135.104/search?q...mp;hl=en&ct=clnk&cd=23
Viva lollapalooza
 
Odgovor na temu

savkic
Igor Savkić

Član broj: 92186
Poruke: 2739



+92 Profil

icon Re: TextWidth problem u iscitavanju sirine BOLD teksta05.08.2008. u 12:55 - pre 191 meseci
> DBGrid ima odvojene Canvas-e

Hm, možda ja nešto propuštam ali gledam source i to nigde ne vidim. Za crtanje fixed kolona se koristi regularan Canvas, MeasureTitleHeights funkcija takođe koristi regularan canvas kontrole kao i kod crtanja običnih ćelija. Doduše gledam BDS 2006 i Delphi kod pa je moguće da ima razlike u Builderu.

> Jednostavno, zbunjen sam bio, jer mi ni na kraj pameti
> nije palo da Canvas->TextWidth(Title->Caption) ne vraca
> pravu vrednost. Ta metoda doslovce meri samo Regular Font Style
> bez obzira da li ste dinamicki promenili u bold ! :(

Ako ti nije problem, pošalji primer koda koji nije radio (pogrešno računao širinu). TextWidth se svodi na GetTextExtentPoint32 pa ako postoji bug onda bi to morao biti WinApi ne Builderov.
 
Odgovor na temu

nikomak
Nikola Makić
Beograd

Član broj: 177053
Poruke: 65
*.rcub.bg.ac.yu.



+1 Profil

icon Re: TextWidth problem u iscitavanju sirine BOLD teksta05.08.2008. u 14:04 - pre 191 meseci
Pozdrav,

@deerbeer: postove ne shvatam licno, tako da ne znam sta bi moglo da me pogodi ;-)
Jedino sam zeleo da znam zasto stariji, iskusniji i bolji programeri od mene smatraju da je konstrukcija beskorisna. Hvala tebi X-Files-u i savkicu na dodatnim pojasnjenjima i nadam se da ce drugtito uspeti da resi problem na pravi nacin.

:bye:
TurboDispatchJumpAddressEnd
----
Knocka Fia
----
And so we meet, again in a different time
 
Odgovor na temu

drugtito
Milovan Djilas

Član broj: 138118
Poruke: 56
*.dynamic.sbb.rs.



+1 Profil

icon Re: TextWidth problem u iscitavanju sirine BOLD teksta05.08.2008. u 16:32 - pre 191 meseci
@savkic
Da ne postujem sve bez potrebe

Code:

class PACKAGE MOJDBGRID: public TDBGrid
{
protected:
   void __fastcall DrawTitleCell (       int ACol, int ARow, const Types::TRect &ARect,
                                         Grids::TGridDrawState AState);
   int __fastcall StringWidth(AnsiString text,TFont *fF);
};
//------------------------ implementacija ------------------------------------
//---------------------------------------------------------------------------
void __fastcall MOJDBGRID::DrawTitleCell (int ACol, int ARow, const Types::TRect &ARect, Grids::TGridDrawState AState)
{
   int nDataCol = ACol;
   AnsiString sText = Columns->Items[nDataCol]->Title->Caption;

   int text_length1 = Canvas->TextWidth(sText);                                                // promeni title u bold i videces
   int text_length2 = StringWidth(sText, Columns->Items[nDataCol]->Title->Font);    // da nema veze sa vezom, a zasto nemam pojma
}                                                                                                                // po mom licnom misljenju, sramota je takav propust
//---------------------------------------------------------------------------      // jer nema nikakve logike!
int __fastcall MOJDBGRID::StringWidth(AnsiString text,TFont *fF) 
{
   int res = 0;
   HDC Dc;
   HFONT SFont = 0;
   TSize t;
   Dc = GetDC(0);
   __try
   {
      SFont = SelectObject(Dc, fF->Handle);
      if (GetTextExtentPoint32A(Dc, text.c_str(), text.Length(), &t))
         res = t.cx;
   }
   __finally
   {
      SelectObject(Dc, SFont);
      ReleaseDC(0, Dc);
   }
   return res;
}
//---------------------------------------------------------------------------


Pokreni novu komponentu ancstr od TDBGrid
ubaci ovaj kod , pokreni, proveri kada je regular i bold varijana
teksta u Title->Caption-u, i videces da se u prvom primeru
gde je
Canvas->TextWidth(sText)
iscitava ista vrednost,
a u drugom od nikomaka napokon dobijam realnu.

Malo sam surfovao po netu, i naleteo na postove gde ljudi
to prijavljuju, tako da sam se uverio da problem postoji.
Recimo proveri ovaj post: (Bypass Graphics.MeasureString limitations)

http://www.codeproject.com/KB/...p;sort=Position&view=Quick

Covek je dao zanimljiv primer, mada je limitiran na to, da ukoliko je RightToLeftAlignment
neces dobiti pravuu vrednost. Jer meri pixele razlicite boje sa leva na desno.

pozdrav
 
Odgovor na temu

savkic
Igor Savkić

Član broj: 92186
Poruke: 2739



+92 Profil

icon Re: TextWidth problem u iscitavanju sirine BOLD teksta05.08.2008. u 19:35 - pre 191 meseci


> int text_length1 = Canvas->TextWidth(sText);
> int text_length2 = StringWidth(sText, Columns->Items[nDataCol]->Title->Font);

Pokušaj ovako:

Canvas->Font->Assign(Columns->Items[nDataCol]->Title->Font);
int text_length1 = Canvas->TextWidth(sText);


 
Odgovor na temu

deerbeer
Beograd

Član broj: 174418
Poruke: 1189
*.adsl-3.sezampro.yu.



+395 Profil

icon Re: TextWidth problem u iscitavanju sirine BOLD teksta05.08.2008. u 20:00 - pre 191 meseci
Citat:
savkic
Pokušaj ovako:
Code:

Canvas->Font->Assign(Columns->Items[nDataCol]->Title->Font);


Ovo je ustvari ekvivalentno sa :
Code:
 SFont = SelectObject(Dc, fF->Handle);

Svaki Font objekat treba biti ucitan ili selektovan u HDC tj. Canvas
da bi merenje fonta imalo efekat.


Viva lollapalooza
 
Odgovor na temu

drugtito
Milovan Djilas

Član broj: 138118
Poruke: 56
*.dynamic.sbb.rs.



+1 Profil

icon Re: TextWidth problem u iscitavanju sirine BOLD teksta05.08.2008. u 20:02 - pre 191 meseci
E moj prijatelju,

da si pre 50 godina ovako dokazao
da sam JA nik (drugtito) glup
poslo bih te u gulag.
E sad.... evolucija, sta ces.

Moram ti reci fala :)

Naj-elegantnije resenje. Sto manje koda, to bolje
a i brate ispljuvah borland...
Al ako nek se nadje, ko zna verovatno su negde ipak pogresili !

sve nabolje.
 
Odgovor na temu

[es] :: C/C++ programiranje :: TextWidth problem u iscitavanju sirine BOLD teksta

[ Pregleda: 2485 | Odgovora: 18 ] > FB > Twit

Postavi temu Odgovori

Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.