/**************/ /* morfo.c */ /**************************************************************************** LIBRARY: MORFO.C PURPOSE: Malli DDE-asiakkaasta. Tarkistetaan sanojen oikeinkirjoitusta. Editor: Vesa Lappalainen 19.8.1993 Kari Heikkilä 18.11.1992 ( DDE osat ) USAGE: 1) Lisätään omaan ohjelmaan sopivaan alustuskohtaan (joko WM_CREATE- viestiin tai ennen ikkunan luomista: virhe = alusta_morfo(hInstance); Jos tulee virhe, niin tällöin tarkistus ei toimi, mutta sitä voidaan silti kutsua. 2) Kutsutaan tarvittaessa: virhe = tarkista_sana(sana); 0 = sana oikein 1 = sana väärin -1 = DDE ei ole käynnissä -2 = DDE:n datakahvan muodostus epäonnistui -3 = Morfo ei vastaa 3) Lopuksi joko WM_DESTROY-viestissä tai ikkunan hävittämisen jälkeen kutsutaan lopeta_morfo(); Kun ohjelma on käynnissä, pitää DDEMORFO.EXE olla käynnissä jotta oikoluku olisi mahdollista. Tämän liittämiseksi projektissa pitää olla ainakin oma.c morfo.c (tai .LIB jossa morfo.obj on mukana) ****************************************************************************/ #include #include #include #include "morfo.h" /***************************************************************************/ /* DDE:n tarvitsemat muuttujat */ typedef struct { DWORD idInst; HCONV hConv; FARPROC lpDdeProc; HSZ hszService; HSZ hszTopic; HSZ hszItem; } DDE_struct; /***************************************************************************/ static DDE_struct DDE = {0,NULL,NULL}; /***************************************************************************/ HDDEDATA EXPENTRY DDECallback ( WORD wType, WORD wFmt, HCONV hConvX, HSZ hsz1,HSZ hsz2, HDDEDATA hData, DWORD dwData1,DWORD dwData2 ) #pragma argsused { switch ( wType ) { case XTYP_DISCONNECT: DDE.hConv = NULL; break; case XTYP_ERROR: break; case XTYP_XACT_COMPLETE: /* compare transaction identifier, indicate transaction complete */ break; } return NULL; } /***************************************************************************/ int tarkista_sana(const char *sana) /* Tarkistetaan morfon avulla onko sana kirjoitettu oikein. ** Palautus: 0 = oikein ** 1 = väärin ** <0 = virhe (koodit ks. koodi alla) */ { HDDEDATA hData; DWORD dwResult; char tulos[40]; /* Laitetaan DDEmorfolle kyselyitä vain jos se on käynnissä */ if ( !DDE.hConv ) return -1;/* "DDE ei ole käynnissä */ /* luodaan tarkistettavasta sanasta datakahva */ hData = DdeCreateDataHandle(DDE.idInst, sana,strlen(sana)+1, 0L,DDE.hszItem, CF_TEXT, 0 ); if ( !hData ) return -2; /* "DDE:n datakahvan muodostus epäonnistui" */ /* lähetään sana Morfolle tutkittavaksi */ hData = DdeClientTransaction( (LPBYTE)hData, -1,DDE.hConv, DDE.hszItem, CF_TEXT, XTYP_POKE, 1000, &dwResult ); /* pyydetään Morfolta vastaus */ hData = DdeClientTransaction( (LPBYTE) NULL, 0, DDE.hConv, DDE.hszItem, CF_TEXT, XTYP_REQUEST, 5000, &dwResult ); if ( !hData ) return -3; /* "Morfo ei vastaa" */ /* Mofro lähetti dataa */ DdeGetData(hData, (LPBYTE)tulos,sizeof(tulos), 0L ); if ( strncmp("",tulos,sizeof(tulos)) != 0 ) return 1; return 0; } /***************************************************************************/ int alusta_Morfo(HINSTANCE hInst) /* Palautetaan 0 jos Morfon alustus onnistuu ja ** negatiivinen arvo virheestä. ** Epäonnistunutta alustusta ei tarvitse lopettaa, muuten pitää ** lopuksi kutsua lopeta_Morfo */ { /* luodaan esiintymä DDE-funktiosta */ DDE.lpDdeProc = MakeProcInstance( (FARPROC) DDECallback, hInst ); /* alustetetaan DDE */ if ( DdeInitialize( (LPDWORD)&DDE.idInst, (PFNCALLBACK)DDE.lpDdeProc, APPCMD_CLIENTONLY, 0L ) ) return -1; /* luodaan DDE:n merkkijonokahvat */ DDE.hszService = DdeCreateStringHandle(DDE.idInst, "DDEMorfo", CP_WINANSI ); DDE.hszTopic = DdeCreateStringHandle(DDE.idInst, "oikoluku", CP_WINANSI ); DDE.hszItem = DdeCreateStringHandle(DDE.idInst, "oikoluku", CP_WINANSI ); /* alustetaan yhteys Morfoon */ DDE.hConv = DdeConnect(DDE.idInst, DDE.hszService, DDE.hszTopic,NULL ); if ( DDE.hConv ) return 0; lopeta_Morfo(); return -2; } /***************************************************************************/ void lopeta_Morfo(void) { if ( DDE.idInst ) { if ( DDE.hConv ) DdeDisconnect(DDE.hConv); DDE.hConv = NULL; DdeFreeStringHandle(DDE.idInst, DDE.hszService ); DdeFreeStringHandle(DDE.idInst, DDE.hszTopic ); DdeFreeStringHandle(DDE.idInst, DDE.hszItem ); } if ( DDE.lpDdeProc ) FreeProcInstance(DDE.lpDdeProc); DDE.lpDdeProc = NULL; DDE.idInst = 0; }