/**************/ /* printw.h */ /**************************************************************************** PROGRAM: printw.c PURPOSE: Helpottaa tekstin tulostamista näyttöön (lähinnä yhteen ikkunaan) AUTHOR: Vesa Lappalainen 17.6.1994 USAGE: Projektiin lisättävä printw.c Tulostamiseksi 1) Tulostamisen aluksi kutsutaan teksin paikan alustamista: SetTextStart(hDC,10,10); y-koordinaatista tulee \r ja \n varten samalla vasen reuna. Oletuksena alkupaikalle on (0,0). 2) Tulostetaan halutut tekstit kutsulla printw(HDC,"tekstiä\nmonelle\nriville"); Tulostusta voidaan saman ikkunan sisällä jatkaa siitä mihin edellinen tulostus loppui suoraan uudella printw-kutsulla. Funktio palauttaa tulostuksen suurimman x-koordinaatin. On myös mahdollista käyttää formatoitua tulostusta: printfw(hDC,"Olen %d vuotta vanha\n",ika) Lisätoimintoja: =============== 3) Jos tulostuksen alkupaikkaa halutaan siirtää muuttamatta vasenta reunaa, voidaan käyttää kutsua: MoveToEx(hDC,x,y,NULL); 4) Tabulaattorit (\t) osataan. Jos niiden paikkaa halutaan muuttaa, käytetään kutsua (oletuksena paikat on 8M-kirjaimen välein): set_tabpos(hDC,i,paikka); missä i on tabulaattroin numero ja paikka koordinaatti pisteinä tai jos paikka on negatiivinen, niin paikka m-kirjaimen levyksinä. 5) Jos tarvitsee tietää seuraava tabulointikohta (esim. kuvien piirtämiseksi alekkain), niin käytetään kutsua: ux = find_nexttab(hDC,x); 6) Jos halutaan alleviivattua tekstiä, käytetään kutsua printwu(hDC,"Alleviivattuna\n"); HUOM! Jos halutaan tulostaa eri ikkunoihin ja hDC:t välillä hävitetään, pitää kunkin tulostuksen paikka tallettaa kutsulla static POINT p; GetCurrentPositionEx(hDC,&p); ja uuden tulostuksen (kun hDC jälleen luotu) aluksi siirtää kutsulla: MoveToEx(hDC,p.x,p.y,NULL); *****************************************************************************/ #include #include #include #include /* ... käsittely */ #include "printw.h" #define TABS 50 static POINT pw_textstart = {0,0}; static POINT pw_textpos = {0,0}; static int pw_tabpos[50]={-1}; /****************************************************************************/ int set_tabpos(HDC hDC,int i,int tp) { SIZE ms; if ( i >= TABS ) return 1; if ( tp >= 0 ) pw_tabpos[i]=tp; else { /* Neg. tp tarkoittaa kokoa M-kirjaimen kokoina */ GetTextExtentPoint(hDC,"M",1,&ms); /* M-kirjaimen koko selville */ pw_tabpos[i]=-tp*ms.cx; } return 0; } /****************************************************************************/ int find_nexttab(HDC hDC,int x) { int i; int x0=pw_textstart.x,dx,px,m1=0,m2=0; if ( pw_tabpos[0] < 0 ) set_tabpos(hDC,0,-8); for (i=0; i x ) return px + x0; /* Löytyi suurempi. */ if ( px > m2 ) { m1 = m2; m2 = px; } /* Pidetään yllä kahta suurinta */ else if ( px > m1 ) m1 = px; } dx = m2 - m1; /* Kahden suurimman erotus jos valmista kohtaa ei löydy */ if ( dx <= 0 ) return x; for ( px = m2; px + x0 <= x; px += dx); /* Toistetaan viim. väliä kun.löyt*/ return px + x0; } /****************************************************************************/ int SetTextStart(HDC hDC,int x, int y) { pw_textstart.x = x; pw_textstart.y = y; pw_textpos = pw_textstart; MoveToEx(hDC,x,y,NULL); return 0; } /****************************************************************************/ int printw(HDC hDC,const char *s) /* Tulostetaan teksti rivinvaihdot huomioiden edellisestä paikasta alkaen. ** Tulostettava teksti jaetaan osiin \r, \n ja \t merkkien kohdalta ja ** tulostetaan aina niitä edeltävä osa ja sitten siirrytään tarvittavalla ** tavalla eteenpäin. ** ** Palautetaan suurin x-koordinaatti tulostuksen aikana. */ { POINT p; SIZE ss,ms; const char *b,*e; int n,max_x=0; if ( GetCurrentPositionEx(hDC,&p) ) p = pw_textpos; b = s; while ( b && *b) { /* Jono tulostetaan erik. merkkeihin saakka */ e = strpbrk(b,"\r\n\t"); /* Etsitään eka CR, LF tai TAB */ if ( e ) n = (int)(e-b); /* Tulostus vain ed. löyt. saakka*/ else n = strlen(b); /* tai jollei löydy, niin kaikki */ GetTextExtentPoint(hDC,"M",1,&ms); /* M-kirjaimen koko selville */ if ( n == 0 ) { /* Jollei tulosteta mitään */ ss = ms; ss.cx = 0; /* niin korkeus M:stä ja lev=0 */ } else { GetTextExtentPoint(hDC,b,n,&ss); /* Tekstin koko selville */ TextOut(hDC,p.x,p.y,b,n); } p.x += ss.cx; if ( p.x > max_x ) max_x = p.x; switch ( b[n] ) { /* Löytyneen mekrin mukaan siirto*/ case '\n': p.y += ss.cy + 1; /* Rivinvaihto ja telan palautus */ case '\r': p.x = pw_textstart.x; break;/*Telanpalautus */ case '\t': p.x = find_nexttab(hDC,p.x);/* Tabulaattori */ break; } if ( p.x > max_x ) max_x = p.x; b = e; /* Jatketaan edellisen perästä */ if ( b ) b++; /* ja ohitetaan \n tai \r */ } MoveToEx(hDC,p.x,p.y,NULL); /* Siirrytään tekstin loppupaik. */ pw_textpos = p; return max_x; } /****************************************************************************/ static int is_last_n(const char *s) /* Tutkitaan onko jonon viimeinen merkki rivinvaihto */ { int n = strlen(s); if ( n == 0 ) return 0; return s[n-1] == '\n'; } /****************************************************************************/ int printwu(HDC hDC,const char *s) /* Alleviivataan tulostus */ { POINT p1,p2; SIZE ms; int x,y; if ( GetCurrentPositionEx(hDC,&p1) ) p1 = pw_textpos; x = printw(hDC,s); p2 = pw_textpos; GetTextExtentPoint(hDC,"M",1,&ms); if ( is_last_n(s) ) y = p2.y -1; else y = p2.y + ms.cy; MoveToEx(hDC,p1.x,y,NULL); LineTo(hDC,x,y); MoveToEx(hDC,p2.x,p2.y,NULL); return x; } /****************************************************************************/ static char buffer[2000]; /****************************************************************************/ int printfw(HDC hDC,const char *fmt, ...) { int x; va_list ap ; va_start(ap,fmt); vsprintf(buffer,fmt,ap); x = printw(hDC,buffer); va_end(ap); return x; }