/***************************************************************************** fontti.c PROGRAM : fontti (win 16 & 32) AUTHOR : Mika Haverila 16.11.1994 Muutoksia Vesa Lappalainen 26.8.1995 USAGE : Aliohjelmakirjasto fontin vaihtoon. - Fontin vaihto aktiivisena olevaan ikkunaan tai jos ikkuna kuuluu ryhmään kaikkiin ryhmään kuuluviin ikkunoihin. KÄYTTÖ YKISTTÄISEN TextOut-fontin vaihtamiseksi: ================================================ 1. Liitä projektiin ALI\fontti.c, ALI\mjonot.c 2. Lisää ohjelmaan : #include "fontti.h" static tOneFont MyFont 3. a) Ikkunan alustukseen: alusta_fontti(".\\myini.ini","FONT",&MyFont); 1 2 3 1 = .INI -tiedoston nimi, josta fontin vanha arvo haetaan, jos NULL, ei käytetä .INI-tiedostoa 2 = TOPIC-nimi vanhalle fontille .INI -tiedostossa, jos NULL, ei käytetä .INI-tiedostoa 3 = oman fonttimuuttujan osoite b) Ikkunan hävitessä: poista_fontti(".\\font3.ini","FONT",&MyFont); c) Kun fontti halutaan vaihtaa: vaihda_fontti(msg->hWnd,&MyFont,TRUE); 1. 2. 3. 1 = ikkuna joka omistaa fontinvaihtodialogin ja johon mahd. uudelleenpiirto kohdistuu 2 = oman fonttimuuttujan osoite 3 = piirretäänkö hWnd uudestaan fontin vaihdon jälkeen d) Kun fonttia tarvitaan (esim. WM_PAINT -viesti): valitse_fontti(msg->hDC,&MyFont); TextOut(msg->hDC, 10, 10, "Hello World!",12); palauta_fontti(msg->hDC,&MyFont); e) Jos on käytössä monta fonttia yhtäaikaa (ks. seuraava osa), voidaan kutsulla tOneFont *EtsiYksiFontti(tFontChange *fc,int id) etsiä tiettyä ID:tä vastaava yksi fontti esim valitse fonttia varten. KÄYTTÖ DIALOGIN IKKUNOIDEN FONTTIEN VAIHTAMISKESI: ================================================== 1. Liitä projektiin ALI\fontti.c, ALI\mjonot.c 2. Lisää ohjelmaan : #include "fontti.h" #define ININAME ".\\INITIED.INI" int wIDs[] = { ID_IKKUNA1,ID_IKKUNA2,0, ID_IKKUNA3,0, ID_IKKUNA4,0, ID_IKKUNA5,0, 0 }; static tFontChange Fontin_vaihto = {"MunIkkuna",wIDs,NULL}; ^ ^ ^ a)Ikkunan tunniste INI-tiedostossa ----| | | b)Oman ID-lista alkuosoite -----------------------| | c)Tähän fontti.c laittaa omaa sisäistä tietoa,ÄLÄ MUUTA - mutta alusta aina ennen 1. kertaa NULLiksi ÄLÄ MUUTA wIDS osoitetta enää 1. kutsun jälkeen ellet ole tehnyt välillä poista_fontit-kutsua! ID_IKKUNA1 jne. ovat lapsi-ikkunoiden (kontrollien) tunnisteita. Halutessa saman fontin vaikuttavan useampaan ikkunaan (=ryhmä) laita tunnisteet peräkkäin esim. ID_IKKUNA1,ID_IKKUNA2,0 . Ryhmät ovat toisistaan 0-merkillä erotettuja ja koko taulukko lopetetaan 0-merkkiin. Jos tarvitse fontin vaihtoa usealle eri ikkunalle tai dialogille, niin tee useita ID-taulukoita ja vastaavia tFontChange-tietueita. 3. Aliohjelmien käyttö : a) Ikkunan tai dialogin alustuksessa jos edellisen kerran fontit käyttöön: alusta_fontit(hWnd,ININAME,Fontin_vaihto); b) Haluttaessa vaihtaa fonttia aktiivisen ikkunan mukaan: vaihda_fontit(hWnd,Fontin_vaihto); tai jos haluttua ikkunaa ei voida tehdä aktiiviseksi, niin vaihda_fontit_id(hWnd,Fontin_vaihto,id); missä id jokin halutun ikkunasarjan tunnisteista. c) Ohjelman lopetuksessa (jos hWnd == NULL, niin koko ikkunan pitää jo olla hävinnyt. Eli jos tämä kutsu on ohjelman lopussa, niin hWnd = NULL, mutta jos esim WM_DESTROY -viestissä, niin silloin ao hWnd): poista_fontit(hWnd,ININAME,Fontin_vaihto); HUOM! Tämä täyty tehdä, muuten systeemiresurreja jää varatuksi. Selityksiä: ----------- Jos wIDs taulukkoon halutaan jatkuva väli tunnuksia, niin tällöin välin eteen laitetaan FONT_ID_RANGE -vakio. Esim. joukko 1,2,3,4,8,12,13,14,15,16,0 voidaan laittaa myös FONT_ID_RANGE,1,4,8,FONT_ID_RANGE,12,16,0 ------------------------------------------------------------------------------ Muutoksia: 26.8.1995/vl: + vaihda_fontti_id vaihda_fontti etsii nykyisen focuksen omistavan ikkunan perusteella ikunan ryhmää vaihda_fontti_id:lle voidaan viedä parametrina minkä ikkunan ryhmää etsitään. + jos samassa ohjelmassa on useita ikkunoita, niin tämä voidaan toteuttaa käyttämällä useata tFontChange -tietuetta. + pitäisi voida nyt totetuttaa myös DLL:nä ja WIN32:ssa + FONT_ID_RANGE 3.9.1995/vl + TextOut -fontin vaihto 23.9.1995/vl + EtsiYksiFontti ------------------------------------------------------------------------------ Suunnitelmia/vl: - jos ryhmää ei löydy, muutetaan pelkästään id:n mukainen ikkuna. - vastaava aliohjelmakirjasto ikkunan paikoille ja väreille ******************************************************************************/ #include #include #include #include #include #include "fontti.h" #include "mjonot.h" #define TOPIC_MAX_PIT 40 #define fontID "FONT-" /*****************************************************************************/ #define INT_INI_TIEDOSTOON(ininame,topic,arvo,item) WritePrivateProfileString(topic,item,itoa(arvo,s,10),ininame) #define HEX_INI_TIEDOSTOON(ininame,topic,arvo,item,koko) {sprintf(s,"%0*lx",koko,arvo); WritePrivateProfileString(topic,item,s,ininame); } #define INT_INI_TIEDOSTOSTA(ininame,topic,arvo,item) arvo=GetPrivateProfileInt(topic,item,arvo,ininame) #define BYTE_INI_TIEDOSTOSTA(ininame,topic,arvo,item) arvo=(BYTE)GetPrivateProfileInt(topic,item,arvo,ininame) #define STRING_INI_TIEDOSTOON(ininame,topic,arvo,item) WritePrivateProfileString(topic,item,arvo,ininame) #define STRING_INI_TIEDOSTOSTA(ininame,topic,arvo,item) GetPrivateProfileString(topic,item,arvo,arvo,sizeof(arvo),ininame) #define HEX_INI_TIEDOSTOSTA(ininame,topic,arvo,item) {GetPrivateProfileString(topic,item,"0",s,sizeof(s),ininame); sscanf(s,"%lx",&arvo); } /*****************************************************************************/ #define H(id) GetDlgItem(msg->hWnd,id) /*****************************************************************************/ static int *etsi_ryhma_nro(const tFontChange *fc,int ryhma) { int *ids = fc->FontIDTables; int ed,i,r=-1; for (i=0,ed=0; ids[i] || ids[i+1]; ed=ids[i++] ) { if ( ids[i] != 0 && ed == 0 ) r++; if ( r == ryhma ) return ids+i; } return NULL; } /*****************************************************************************/ static int laske_ryhmat(const tFontChange *fc) { int *ids = fc->FontIDTables; int ed,i,ryhmia=0; for (i=0,ed=0; ids[i] || ids[i+1]; ed=ids[i++] ) { if ( ids[i] != 0 && ed == 0) ryhmia++; } return ryhmia; } /*****************************************************************************/ typedef struct {/* Tietue yhden ryhmän id-numeroiden läpikäymiseksi */ int *ids; /* Ryhmän alku */ int ok; /* onko ryhmästä otettu alkio 1 = OK, 0 = ei */ int i; /* indeksi ryhmän sisällä */ int id; /* jos völi, niin menossa oleva välin osa */ } ryhma_iter; /*****************************************************************************/ static int ryhma_ok(ryhma_iter *ri) { return ri->ok; } /*****************************************************************************/ static int ryhman_seuraava(ryhma_iter *ri) { int id; int i; if ( ri->ok == 0 ) return 0; if ( ri->ids == NULL ) { ri->ok = 0; return 0; } if ( ri->id ) { /* Jos välin läpikäynti kesken */ ri->id++; if ( ri->id <= ri->ids[ri->i+2] ) return ri->id; ri->id = 0; ri->i += 2; } i = ++ri->i; ri->ok = 0; id = ri->ids[i]; if ( id == 0 ) return 0; if ( id == FONT_ID_RANGE ) { /* Alkaako uusi väli */ if ( ri->ids[i+1] == 0 || ri->ids[i+2] == 0 ) return 0; ri->id = ri->ids[i+1]; ri->ok = 1; return ri->id; } ri->ok = 1; return id; } /*****************************************************************************/ static int ryhman_alku(const tFontChange *fc, int ryhma, ryhma_iter *ri) { ri->ids = etsi_ryhma_nro(fc,ryhma); ri->i = -1; ri->ok = 1; ri->id = 0; return ryhman_seuraava(ri); } #define FOR_EACH_ID(i,fc,r) {ryhma_iter ri; \ for ( i=ryhman_alku(fc,r,&ri); ryhma_ok(&ri); i=ryhman_seuraava(&ri) ) { #define NEXT_ID(i) }} /*****************************************************************************/ static int etsi_indeksi_id(const tFontChange *fc, int id) { int i,ryhma,ryhmia = laske_ryhmat(fc); for (ryhma=0; ryhmalf.lfHeight, "lfHeight"); INT_INI_TIEDOSTOON(ini,topic,f->lf.lfWidth, "lfWidth"); INT_INI_TIEDOSTOON(ini,topic,f->lf.lfEscapement, "lfEscapement"); INT_INI_TIEDOSTOON(ini,topic,f->lf.lfOrientation, "lfOrientation"); INT_INI_TIEDOSTOON(ini,topic,f->lf.lfWeight, "lfWeight"); INT_INI_TIEDOSTOON(ini,topic,f->lf.lfItalic, "lfItalic"); INT_INI_TIEDOSTOON(ini,topic,f->lf.lfUnderline, "lfUnderline"); INT_INI_TIEDOSTOON(ini,topic,f->lf.lfStrikeOut, "lfStrikeOut"); INT_INI_TIEDOSTOON(ini,topic,f->lf.lfCharSet, "lfCharSet"); INT_INI_TIEDOSTOON(ini,topic,f->lf.lfOutPrecision, "lfOutPrecision"); INT_INI_TIEDOSTOON(ini,topic,f->lf.lfClipPrecision, "lfClipPrecision"); INT_INI_TIEDOSTOON(ini,topic,f->lf.lfQuality, "lfQuality"); INT_INI_TIEDOSTOON(ini,topic,f->lf.lfPitchAndFamily, "lfPitchAndFamily"); STRING_INI_TIEDOSTOON(ini,topic,f->lf.lfFaceName, "lfFaceName"); HEX_INI_TIEDOSTOON(ini,topic,f->clr, "rgbColors",6); return 0; } /*****************************************************************************/ int lue_fontti_inista(const char *ini,const char *topic,tOneFont *f) { char s[200]; /* makro tarttee */ if ( ini == NULL || *ini == 0 || topic == NULL || *topic == 0 ) return 1; INT_INI_TIEDOSTOSTA(ini,topic,f->lf.lfHeight, "lfHeight"); INT_INI_TIEDOSTOSTA(ini,topic,f->lf.lfWidth, "lfWidth"); INT_INI_TIEDOSTOSTA(ini,topic,f->lf.lfEscapement, "lfEscapement"); INT_INI_TIEDOSTOSTA(ini,topic,f->lf.lfOrientation, "lfOrientation"); INT_INI_TIEDOSTOSTA(ini,topic,f->lf.lfWeight, "lfWeight"); BYTE_INI_TIEDOSTOSTA(ini,topic,f->lf.lfItalic, "lfItalic"); BYTE_INI_TIEDOSTOSTA(ini,topic,f->lf.lfUnderline, "lfUnderline"); BYTE_INI_TIEDOSTOSTA(ini,topic,f->lf.lfStrikeOut, "lfStrikeOut"); BYTE_INI_TIEDOSTOSTA(ini,topic,f->lf.lfCharSet, "lfCharSet"); BYTE_INI_TIEDOSTOSTA(ini,topic,f->lf.lfOutPrecision, "lfOutPrecision"); BYTE_INI_TIEDOSTOSTA(ini,topic,f->lf.lfClipPrecision, "lfClipPrecision"); BYTE_INI_TIEDOSTOSTA(ini,topic,f->lf.lfQuality, "lfQuality"); BYTE_INI_TIEDOSTOSTA(ini,topic,f->lf.lfPitchAndFamily, "lfPitchAndFamily"); STRING_INI_TIEDOSTOSTA(ini,topic,f->lf.lfFaceName, "lfFaceName"); HEX_INI_TIEDOSTOSTA(ini,topic,f->clr, "rgbColors"); return 0; } /*****************************************************************************/ static int muuta_fontti_ikkunaan(HWND hWnd,int id,HFONT hfont) { HWND hCwnd = GetDlgItem(hWnd,id); if ( hCwnd == NULL ) return -1; SetWindowFont(hCwnd,hfont,TRUE); return 0; } /*****************************************************************************/ static int vaihda_yksi_fontti(tOneFont *f,HFONT hf) { if ( f->hfont ) DeleteObject(f->hfont); f->hfont = hf; return 0; } /*****************************************************************************/ static int muuta_fontit_ryhma(HWND hWnd,tFontChange *fc,HFONT hf,int ryhma) { int id; if ( hWnd ) { FOR_EACH_ID(id,fc,ryhma) muuta_fontti_ikkunaan(hWnd,id,hf); NEXT_ID(id); } return vaihda_yksi_fontti(&fc->Fonts[ryhma],hf); } /*****************************************************************************/ static int poista_vanha_fontti_ryhma(HWND hWnd,tFontChange *fc,int ryhma) { muuta_fontit_ryhma(hWnd,fc,NULL,ryhma); return 0; } /*****************************************************************************/ static int tarkista_tai_luo_fontit(tFontChange *fc) { int ryhmia = laske_ryhmat(fc); if ( ryhmia <= 0 ) return -1; if ( fc->Fonts ) return ryhmia; fc->Fonts = calloc(ryhmia,sizeof(fc->Fonts[0])); if ( fc->Fonts == NULL ) return -1; return ryhmia; } /*****************************************************************************/ static HFONT kysy_fontti(HWND hWnd,tOneFont *f) { HFONT hf; CHOOSEFONT cf; cf.lStructSize = sizeof(CHOOSEFONT); cf.hwndOwner = hWnd; cf.lpLogFont = &f->lf; cf.Flags = CF_INITTOLOGFONTSTRUCT | CF_SCREENFONTS | CF_EFFECTS; cf.rgbColors = f->clr; /* Oletusväri */ /* FD */ if ( ChooseFont(&cf) == 0 ) return NULL; f->clr = cf.rgbColors; /* Käyttöväri */ /* FD */ hf = CreateFontIndirect(&f->lf); return hf; } /*****************************************************************************/ static int vaihda_fontit_ryhma(HWND hWnd,tFontChange *fc,int ryhma) { HFONT hf; if ( tarkista_tai_luo_fontit(fc) <= 0 ) return -1; hf = kysy_fontti(hWnd,&fc->Fonts[ryhma]); if ( hf == NULL ) return 1; muuta_fontit_ryhma(hWnd,fc,hf,ryhma); return 0; } /*****************************************************************************/ int vaihda_fontti(HWND hWnd,tOneFont *f,int redraw) { HFONT hf; if ( f->hfont == NULL ) alusta_fontti(NULL,NULL,f); hf = kysy_fontti(hWnd,f); if ( hf == NULL ) return 1; vaihda_yksi_fontti(f,hf); if ( redraw ) InvalidateRect(hWnd, NULL, TRUE); return 0; } /*****************************************************************************/ int alusta_fontti(const char *ini,const char *topic,tOneFont *f) { HFONT hf; GetObject(GetStockObject(SYSTEM_FONT),sizeof(LOGFONT),&f->lf); f->clr = RGB(0, 0, 0); /* oletus mustaksi */ lue_fontti_inista(ini,topic,f); hf = CreateFontIndirect(&f->lf); vaihda_yksi_fontti(f,hf); return 0; } /*****************************************************************************/ int alusta_fontit(HWND hWnd,const char *ini,tFontChange *fc) { int i; HFONT hf; char topic[TOPIC_MAX_PIT]; int ryhmia; if ( ( ryhmia = tarkista_tai_luo_fontit(fc) ) <= 0 ) return -1; for(i=0; iWindowName,i); GetObject(GetStockObject(SYSTEM_FONT),sizeof(LOGFONT),&fc->Fonts[i].lf); fc->Fonts[i].clr = RGB(0, 0, 0); /* oletus mustaksi */ lue_fontti_inista(ini,topic,&fc->Fonts[i]); hf = CreateFontIndirect(&fc->Fonts[i].lf); if ( hf ) muuta_fontit_ryhma(hWnd,fc,hf,i); } return 0; } /*****************************************************************************/ int poista_fontti(const char *ini,const char *topic,tOneFont *f) { if ( f->hfont == NULL ) return 0; talleta_fontti_iniin(ini,topic,f); return vaihda_yksi_fontti(f,NULL); } /*****************************************************************************/ int poista_fontit(HWND hWnd,const char *ini,tFontChange *fc) { int i; char topic[TOPIC_MAX_PIT]; int ryhmia = laske_ryhmat(fc); if ( fc->Fonts == NULL ) return 0; for(i=0; iFonts[i].hfont ) { tee_fontID(N_S(topic),fc->WindowName,i); talleta_fontti_iniin(ini,topic,&fc->Fonts[i]); poista_vanha_fontti_ryhma(hWnd,fc,i); } } free(fc->Fonts); fc->Fonts = NULL; return 0; } /*****************************************************************************/ int vaihda_fontit(HWND hWnd,tFontChange *fc) { int ryhma = etsi_indeksi_focus(fc); if ( ryhma < 0 ) return 1; /* Jos ei löydy tunnusta */ return vaihda_fontit_ryhma(hWnd,fc,ryhma); } /*****************************************************************************/ int vaihda_fontit_id(HWND hWnd,tFontChange *fc,int id) { int ryhma = etsi_indeksi_id(fc,id); if ( ryhma < 0 ) return 1; /* Jos ei löydy tunnusta */ return vaihda_fontit_ryhma(hWnd,fc,ryhma); } /*****************************************************************************/ /*****************************************************************************/ int valitse_fontti(HDC hDC,tOneFont *f) { f->ohfont = SelectObject(hDC,f->hfont); /* Fontti */ /* FD */ f->oclr = SetTextColor(hDC,f->clr); /* Väri */ /* CD */ return 0; } /*****************************************************************************/ int palauta_fontti(HDC hDC,tOneFont *f) { SetTextColor(hDC,f->oclr); /* Palautus */ /* CD */ SelectObject(hDC,f->ohfont); /* Palautus */ /* FD */ return 0; } /*****************************************************************************/ tOneFont *EtsiYksiFontti(tFontChange *fc,int id) { int ryhma = etsi_indeksi_id(fc,id); if ( ryhma < 0 ) return NULL; /* Jos ei löydy tunnusta */ return &fc->Fonts[ryhma]; }