23. juni 2003 - 23:50Der er
20 kommentarer og 2 løsninger
Forkortelse af path
Jeg har et listview hvori der er en kolonne kaldet file. Denne raekke indeholder stier til filer.
Nogen gange saa er stien laengere end der er plads til i selve kolonnen, og jeg har set at MS kommer udenom dette ved at cutte noget af kolonnen af. F.eks. hvis man nu har denne sti:
c:\Documents and settings\User name\Desktop\bla\bla saa kunne denne f.eks blive cuttet ned til: c:\Documents and settings\...\Desktop\bla\bla eller mindre: c:\Documents and ...\bla\bla
Hvordan laver man denne funktionalitet?
Jeg regner med at man som parametre til det der beregner dette, skal vaere font'en, stringen, og maks bredden.
Uden at give dig selve koden vil mit forslag være:
Stiens navn er vel en String. Så du kan tage at checke længden af denne string, hvis den er over 25 tegn, så exploder du den og tager de første 12 tegn + ... + de sidste 10 tegn og imploder dette og gemmer det under det gamle stringnavn. Hvis du skal bruge strengen senere til at kalde filen, så skal du nok lave noget med at beholde den oprindelige streng og lave en ny til brug i tabellen.
Dette vil ikke være svært at lave i C++, jeg er dog ikke så godt hjemme i syntaksen, så derfor har jeg ikke lavet noget kode.
laengden af strengen er ikke godt nok, eftersom jeg ikke ved hvor stor fonten er. Jeg maa skulle bruge stoerrelsen paa strengen naar den bliver skrevet med en bestemt type font.
Faktisk troede jeg at denne funktion var saa esential, saa at koden var et sted paa nettet.
Tror ikke du skal regne med at finde koden nogen steder på nettet - og hvis du gør, vil det være lavet som petter78 skriver, da funktionen i de fleste programmer er implementeret på netop den måde.
Eller... på den anden side, så ville petter78's løsning være rimelig ubrugelig... hvem siger at filnavnet ikke er længere end 12 tegn? Hvis det er det, vil man ikke kunne se hele filnavnet, hvilket nok ikke ville være særlig smart.
Jeg har derfor lavet en anden løsning, hvor man altid kan se hele filnavnet, og så skærer den stien ned. Det giver følgende output:
- Hvis den fulde sti er mindre end den ønskede længde, returneres hele strengen.
- Uanset om der er plads til stien eller ej, vises hele filnavnet, med drevangivelse først. Eksempel med ønsket længde 15: c:\...\filnavn.txt
- I sidste tilfælde vises hele filnavnet og den del af stien som der er plads til indenfor den ønskede længde. Eksempel med ønsket længde 30: c:\windows\syste...\system.dll
Og her kommer koden:
public string MakeFit(string filename, int length) { if (filename.Length <= length) return filename;
Hvis du i stedet for ønsker at lave den så længden altid passer med fonten, bliver du nødt til at lave det så den fjerner et stykke af strengen, tjekker længden, fjerner et stykke af strengen, tjekker længden osv. Det vil altså blive en meget langsommere funktion, end ovenstående som har konstant udførselstid. Jeg ville derfor benytte ovenstående, hvis der er mange stier der skal kortes ned...
nielslbeck>> Jeg har ikke oplevet hastighedsproblemer med at kalde unmanaged dll. API-funktionen PathAddBackslash er heller ikke implementeret i Path klassen. Jeg har prøvet med to implementeringer af den (en, hvor jeg selv tester på sidste tegn, og en, hvor jeg kalder direkte til PathAddBackslash i API). Der var ikke forskel at mærke på trods af *mange* kald til rutinen (i en opbygning af biblioteksstruktur i et TreeView).
Jeg kan ikke se hvordan jeg kan faaet taget hoejde for at min font stoerrelse er kaempe stor f.eks.
nielslbeck>>
En endnu smartere maade ville vaere:
1) Jeg kender den font jeg arbejder med. Derfra ved jeg font hoejden i pixels(emsize). Det er nu bredden jeg er efter, men den findes let ved foelgende simple formel: emsize * 3(bredde) / 4(hoejde). Dvs. at jeg nu ved bredden paa min font. Lad os sige at her er den 6. 2) Jeg ved ogsaa hvor plads jeg har ialt. F.eks. er det en label, saa er det bredden(- evt. offsets). Lad os sige at den er 200 her. 3) Nu kan jeg saa beregne hvor mange tegn der kan vaere maksimalt i min label: makstegn = Floor(200 / 6) 4) kald din funktion Dette ville ogsaa have en konstant eksekveringstid.
gooky>> Ja, det ville være smartere... men det kan bare ikke bruges, da alle tegn ikke er lige brede! Der er f.eks. forskel på hvor meget "H" og "i" fylder i bredden - i hvert fald ved de fleste skrifttyper...
yes, det har du ret i, men efter meget hurtig soegning, ser det ud til at det er maksimum bredden(forholdet er maks 3/4). Jeg har kun undersoegt det ved at gaa ind i Character Map, saa det kan godt vaere at det ikke er sandheden. Jeg bruger maks settings, hvilket kun betyder at det i hvert fald aldrig kommer ud over bredden.
Det er så rigtigt nok... Så hvis man kan leve med, at stierne kan komme til at fylde mindre end den maksimale bredde, vil det være kanon at regne ud hvor meget plads man har, og så bruge ovenstående metode til at korte stien ned...
men den maa jo tage en font stoerrelse som standard naar den beregner... Men hvilken font er det. Hvis man viste det, saa kunne man tage forholdet mellem bredderne paa den font og den font man nu bruger.
Det kan man jo så ikke... Der er jo ikke nogen der siger, at fordi et "i" har en bredde i en font og en anden i en anden font, er forholdet mellem dem det samme som forholdet mellem "H" i de to fonte...
hDC [in] Handle to the device context used for font metrics. lpszPath [in, out] Pointer to a null-terminated string of length MAX_PATH that contains the path to be modified. On return, this buffer will contain the modified string. dx [in] Width, in pixels, within which the string will be forced to fit. Return Value
Returns TRUE if the path was successfully compacted to the specified width. Returns FALSE on failure, or if the base portion of the path would not fit the specified width.
Remarks
This function uses the font currently selected in hDC to calculate the width of the text. This function will not compact the path beyond the base file name preceded by ellipses.
det var ogsaa mit allerfoerste logiske bud, men da jeg proevede, gav det ikke det resultat. Det kan vaere at jeg har lavet lort i den, jeg proever lige igen.
Her bliver strengen meget kortere end selve kontrollen hvori denne onpaint er overriden(jeg har bare gjort det i formen). Proever man derimod at aendre paa fonten(som jeg har udkommenteret her), saa bliver strengen stoerrere end selve formen. Den bruger vist ikke DEN font som intern parameter i hdc'en. Har du en kommentar til det benny
Erklaering i PathEx: [System.Runtime.InteropServices.DllImport("gdi32.dll", CharSet=System.Runtime.InteropServices.CharSet.Auto)] public extern static long SelectObject(System.IntPtr hdc, System.IntPtr hObject);
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.