///////////////////////////////////////////////////////////////////////// // // #include "stdafx.h" #include "textfrmt.h" #define END_OF_LINE '\n' // charsinwidth returns the number of characters that will fit within a certain width. int Charsinwidth(CDC &mydc,LPCSTR strtocalc,int width ) { // width is the width in logical units of the maximum output width TEXTMETRIC metric; // structure used to get font information LPCSTR stemp; // temp string SIZE ssize; if(!*strtocalc) return FALSE; mydc.GetTextMetrics( &metric); // get the font information ssize.cx=0; if(*strtocalc==END_OF_LINE) return 1; stemp=strtocalc; // Start at first word if(!*stemp) return FALSE; // first make an educated guess... { int guess = width/metric.tmAveCharWidth; // how many chars we think are in here... int loop; for(loop=0;loop<guess;loop++) { if(!*(stemp+loop) || *(stemp+loop)==END_OF_LINE) break; } stemp+=loop; } // keep advancing word by word untill we're at least 1 word too long // we could already be much further if the educated guess was way off... while(ssize.cx<width && *stemp && *stemp!=END_OF_LINE) { // while we're shorter than the width that they want, but not at end of string or a C/R // keep going to the next word while(*stemp!=32 && *stemp && *stemp!=END_OF_LINE)// advance a char at a time stemp++; // up to next word break ssize=mydc.GetTabbedTextExtent(strtocalc,stemp-strtocalc,0,0); // now, find out how wide this string is if(!*stemp || *stemp==END_OF_LINE) break; stemp++;// if we're short, we want to skip over this space for next loop iteration :) } // now we're too long, so back up a word at a time untill we are right. while(ssize.cx>width && stemp>strtocalc) // don't back up to before where we started! { stemp--;// decrement one more time so next time we aren't at the // same stupid space. we can over-run the beginning of the string this // way, but that won't matter cause we'll catch it in the next // section of code. while(*stemp!=32 && *stemp!='\t' && stemp>strtocalc) stemp--; // back up untill we hit a space ssize=mydc.GetTabbedTextExtent(strtocalc,stemp-strtocalc,0,0) ; } // is there only one word on the line? if(stemp<=strtocalc) { stemp=strtocalc+1; // if so, advance one character at a time. while(*stemp!=END_OF_LINE && *stemp) // to do this just advance up one character at a time untill { // we dont fit within the margin... then back up one char, and // return that as the width. // slow and painfull, but there's no other way ssize=mydc.GetTabbedTextExtent(strtocalc,stemp-strtocalc,0,0); if(ssize.cx>width) { stemp--; break; } stemp++; } } // add trailing spaces to this thing. while(*stemp==' ') { stemp++; } if(stemp==strtocalc) // did we not get rid of any characters? stemp++; // we have to get rid of at least one character in this routine. return(stemp-strtocalc); // return number of characters that will fit } int CharsInColumns(LPCSTR str, BOOL bWordWrap,int columns) { int charat=0; LPCSTR strstart=str; while(*str && *str!=END_OF_LINE && charat < columns) { str++; charat++; } if(bWordWrap && charat>79) // wrapping by words? { LPCSTR strstartwrap=str; while(*str!=' ' && *str+1!=' ' && str>strstart && *str!=END_OF_LINE && *str) str--; if(str<=strstart) str=strstartwrap; } // kill the leading space off of the next line. if(*str==' ') str++; return (str-strstart); } int MyAnsiNext(LPCSTR pStr) { if(!*pStr) { TRACE("\nError, calling MyAnsiNext with pointer to null."); return 0; } LPCSTR pAbort = pStr; if(*pStr!=27) return 1; pStr++; if(strchr("c78ABCDFGHIJKMZ=>12<",*pStr)) return 2; if(*pStr=='#' && *(pStr+1)>'2' && *(pStr+1)<'9') return 3; if( (*pStr=='(' || *pStr==')')&& strchr("AB012",*(pStr+1))) return 3; if(*pStr!='[') goto abort; pStr++; if(strchr("KJm",*pStr)) return 3; do{ if(*pStr==';') pStr++; // move off of '[' or ';' // get first digit if(isdigit(*pStr)) pStr++; else goto abort; // get second digit if(isdigit(*pStr)) pStr++; } while(*pStr==';'); if(strchr("rmABCDRnHfsuJkKycqg",*pStr)) return (pStr-pAbort)+1; abort: TRACE("\nInvalid ansi sequence."); return 1; } int AnsiChars(LPCSTR str, int columns /* = 80 */) { int charat=0; LPCSTR strstart=str; while(*str && *str!=END_OF_LINE && charat < columns) { int num=MyAnsiNext(str); str+= num; if(num==1) charat++; } // kill the leading space off of the next line. if(*str==' ') str++; return (str-strstart); } int Ansimemcpy(LPSTR pDest,LPCSTR pSrc,int iFirstChar,int iLength) { if(iFirstChar) pSrc+=AnsiChars(pSrc,iFirstChar); int charat=0; while(*pSrc && charat < iLength) { int num=MyAnsiNext(pSrc); if(num==1) { *pDest=*pSrc; charat++; pDest++; } pSrc+= num; } *pDest=0; return charat; }