/****************/ /* laskurm3.cpp */ /****************/ // Esimerkki Autolaskurista. // Projektiin // laskurm3.cpp // laskurm3.rc // ALI\clipboar.c // Kopioi hakemistoon ..\kuvat tiedosto laskurir.ico // Lisäksi tarvitaan ALI\owl\intlabel.h // // Ohjelma on esimerkki seuraavista: // INI-tiedoston käsittely // Leikekirjan käyttö // Document/View = dokumentin ja näytön käsittely erotettu toisistaan // // DocManger Dokumentti Näyttö // ----------------------------------------------------------------- // FileNew |-> Open -----------> VnRevert // +<--GetData <-------- uusi näyttö // Revert to saved ----> |<--Revert // // FileSave ------------> Commit ----------> Commit // tallet.<----OK--- // FileOpen ------------> Close ----------> uusi näyttö (SDIssä) // // HUOM! FileOpen ei kutsu dokumentin Open-metodia, vaan tämä on tehtävä // itse esim. seuraavassa WM_PAINTissä tai kun dataa tarvitaan. // Open-kutsu voidaan piilottaa esim. GetData-metodiin! // // Tehtäviä: // 1) Muuta ohjelma sellaiseksi, ettei laskureiden lisäyksessä // tarvitse tehdä muuta kuin muuttaa .RC ja .RH -tiedotoja // #if __BORLANDC__ >= 0x460 #define OWL5 // Määrittele tämä sen mukaan kumpaa käytät #endif #include #include #include #include #include #ifdef OWL5 #include #endif #include #include "laskurm3.rh" #include "owl\intlabel.h" #include "clipboar.h" #define LASKUREITA 2 #define INIFILE ".\\Laskuri.ini" //------------------------------------------------------------------------------ // Dokumenttiluokka joka huolehtii pelkästään dokumentista //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ class TLaskuriDocument : public TFileDocument { //------------------------------------------------------------------------------ int laskurit[LASKUREITA]; int OK(int i) { return 0 <= i && i < LASKUREITA; } int dataOK; public: TLaskuriDocument(TDocument* parent = 0); // implement virtual methods of TDocument bool Open(int mode, const char far* path=0); bool Close() { dataOK = 0; return true; } bool IsOpen() { return dataOK; } bool Commit(bool force = false); bool Revert(bool clear = false); void set(int index,int i) { if ( OK(index) ) { laskurit[index] = i; SetDirty(true); } } int GetData(int index) { // HUOM!!! Tätä on itse kutsuttava jostakin!!! if ( !dataOK && !Open(ofRead) ) return 0; if ( OK(index) ) return laskurit[index]; else return 0; } bool Refresh() { return TFileDocument::Revert(false); } friend istream &operator>>(istream &is, TLaskuriDocument &doc); friend ostream &operator<<(ostream &os, const TLaskuriDocument &doc); const char *AsText() const; int FromText(const char *s) { istrstream is((char *)s); is >> *this; return 0;} int ToClipboard(HWND hWnd) const { return TextToClipboard(hWnd,AsText()); } int FromClipboard(HWND hWnd) { return FromText(TextClipboard(hWnd)); } }; TLaskuriDocument::TLaskuriDocument(TDocument* parent) : TFileDocument(parent) { for (int i=0; i>(istream &is, TLaskuriDocument &doc) { for (int i=0; i> doc.laskurit[i]; doc.SetDirty(true); doc.Refresh(); return is; } ostream &operator<<(ostream &os, const TLaskuriDocument &doc) { for (int i=0; i> *this; delete is; } SetDirty(false); dataOK = 1; return true; } //------------------------------------------------------------------------------ class TIntLaskuri : public TIntLabel { // Laskuri, joka ilmoittaa muutoksen //------------------------------------------------------------------------------ TLaskuriDocument &doc; int index; public: TIntLaskuri(TLaskuriDocument &d,int ind,TWindow* parent, int resourceId, uint textLimit = 0, TModule* module = 0) : doc(d), index(ind), TIntLabel(parent,resourceId, textLimit, module) {} virtual int set(int i) { if ( int(*this) == i ) return i; if ( &doc != NULL ) { doc.set(index,i); } return TIntLabel::set(i); } virtual int get() const { if ( &doc != NULL ) return doc.GetData(index); return 0; } int operator=(int i) { return set(i); } }; //------------------------------------------------------------------------------ class TLaskuriDialog : public TDialog, public TView { //------------------------------------------------------------------------------ TIntLaskuri *hal; TIntLaskuri *kal; TLaskuriDocument &Docu; // Valmiiksi oikean tyyppinen synonyymi Doc:ille int suunta; public: TLaskuriDialog(TLaskuriDocument& doc, TWindow* parent = 0) : TView(doc), Docu(doc), TDialog(parent, "LASKURI") { hal = new TIntLaskuri(doc,0,this, HAL); kal = new TIntLaskuri(doc,1,this, KAL); suunta = 1; char s[50]; GetPrivateProfileString("LASKURI","LASKURI","",s,sizeof(s),INIFILE); Docu.FromText(s); Docu.SetDirty(false); } virtual ~TLaskuriDialog() { WritePrivateProfileString("LASKURI","LASKURI",Docu.AsText(),INIFILE); delete kal; delete hal; } void SetupWindow() { TDialog::SetupWindow(); VnRevert(false); // Tämän jekun ansiosta lukee!!! } // Seuraavat virtuaaliset metodit pitää tehdä jotta View ikkuna toimisi static const char far* StaticName() {return "Laskuri View";} // put in resource const char far* GetViewName() { return StaticName(); } TWindow* GetWindow() { return (TWindow*)this; } bool SetDocTitle(const char far* docname, int index) { return TWindow::SetDocTitle(docname, index); } bool VnIsWindow(HWND hWnd) { return ((HWindow == hWnd) || IsChild(hWnd)); } int TeeTyhja() { *hal = 0; *kal=0; return 0; } void BNHAClicked() { *hal += suunta; } void BNKAClicked() { *kal += suunta; } void BNNollaaClicked() { TeeTyhja(); } void BNExitClicked() { CloseWindow(); } bool CanClose() { return TWindow::CanClose() && Doc->CanClose(); } void CmCut() { Docu.ToClipboard(*this); TeeTyhja(); } void CmCopy() { Docu.ToClipboard(*this); } void CmPaste() { Docu.FromClipboard(*this); } void CmDec() { TMenu menu(*Parent); suunta = -1; menu.CheckMenuItem(IDM_OPTIONS_DEC, MF_CHECKED); menu.CheckMenuItem(IDM_OPTIONS_INC, MF_UNCHECKED); } void CmInc() { TMenu menu(*Parent); suunta = 1; menu.CheckMenuItem(IDM_OPTIONS_DEC, MF_UNCHECKED); menu.CheckMenuItem(IDM_OPTIONS_INC, MF_CHECKED); } bool VnRevert(bool clear); bool VnCommit(bool force); DECLARE_RESPONSE_TABLE(TLaskuriDialog); }; DEFINE_RESPONSE_TABLE2(TLaskuriDialog, TDialog, TView) EV_BN_CLICKED(HA ,BNHAClicked), EV_BN_CLICKED(KA ,BNKAClicked), EV_BN_CLICKED(NOLLAA ,BNNollaaClicked), EV_BN_CLICKED(EXIT ,BNExitClicked), EV_BN_CLICKED(IDCANCEL,BNExitClicked), // Tämä, niin ESCillä ei vahingossa EV_COMMAND(IDM_EDIT_CUT, CmCut ), EV_COMMAND(IDM_EDIT_COPY, CmCopy ), EV_COMMAND(IDM_EDIT_PASTE, CmPaste ), EV_COMMAND(IDM_OPTIONS_DEC ,CmDec ), EV_COMMAND(IDM_OPTIONS_INC ,CmInc ), EV_VN_REVERT, // Lue näytön tiedot dokusta EV_VN_COMMIT, // Onko näytössä muutoksia jotka pitäisi antaa dokulle EV_VN_ISWINDOW, // Jos tämä puuttuu, menuun ei tule Save -valintaa!!! END_RESPONSE_TABLE; bool TLaskuriDialog::VnRevert(bool /*clear*/) { hal->update(); kal->update(); return true; } bool TLaskuriDialog::VnCommit(bool /*force*/) { // nothing to do here, no data held in view ??? return true; } //------------------------------------------------------------------------------ // Luodaan dokumentin käsittelijä ja annetaan sille käsiteltävä tiedostotyyppi DEFINE_DOC_TEMPLATE_CLASS(TLaskuriDocument, TLaskuriDialog, tLaskuriDocTPL); tLaskuriDocTPL LaskuriDoc( // "Laskuri (*.las)|*.las|Teksti (*.txt)|*.txt|All Files (*.*)|*.*||", "*.*", "Laskuri", "*.las", 0, "las", dtAutoDelete | dtUpdateDir ); //------------------------------------------------------------------------------ class TLaskuriApp : public TApplication #ifdef OWL5 , public TRecentFiles #endif { public: TLaskuriApp(const char *title) : TApplication(title) #ifdef OWL5 ,TRecentFiles(INIFILE, 4) #endif {} void InitMainWindow() { TDecoratedFrame *fw = new TDecoratedFrame(0, Name,0); fw->SetIcon(this, "IKONI"); #ifdef OWL5 fw->SetIconSm(this, "IKONI"); #endif fw->Attr.AccelTable = "PIKA"; SetMainWindow(fw); // Laitetaan menu, jossa EI ole File-menua fw->SetMenuDescr(TMenuDescr("Paamenu",1,0,0,0,0,1)); // Asennetaan dokumentin käsittelijä SetDocManager(new TDocManager(dmSDI | dmMenu ,this)); GetMainWindow()->SetFlag(wfShrinkToClient); } void InitInstance() { TApplication::InitInstance(); GetDocManager()->CreateAnyDoc(0, dtNewDoc); // Tämän ansiosta tyhjä aluksi GetMainWindow()->SetFlag(wfShrinkToClient); } protected: void EvNewView(TView& view); void EvCloseView(TView& view); void EvOwlDocument(TDocument& doc); int32 CmFileSelected(uint wp, int32 lp); // void CmHelpAbout(); DECLARE_RESPONSE_TABLE(TLaskuriApp); }; #ifdef OWL5 DEFINE_RESPONSE_TABLE2(TLaskuriApp, TApplication, TRecentFiles ) #else DEFINE_RESPONSE_TABLE1(TLaskuriApp, TApplication ) #endif EV_OWLVIEW(dnCreate, EvNewView), EV_OWLVIEW(dnClose, EvCloseView), #ifdef OWL5 EV_OWLDOCUMENT(dnCreate, EvOwlDocument), EV_OWLDOCUMENT(dnRename, EvOwlDocument), EV_REGISTERED(MruFileMessage, CmFileSelected), #endif // EV_COMMAND(CM_HELPABOUT, CmHelpAbout), END_RESPONSE_TABLE; void TLaskuriApp::EvNewView(TView& view) { // Koko ei tule 1. kerralla ihan oikein??? GetMainWindow()->SetFlag(wfShrinkToClient); GetMainWindow()->SetClientWindow(view.GetWindow()); if ( !view.IsOK() ) GetMainWindow()->SetClientWindow(0); else if ( view.GetViewMenu() ) // Jos View:llä oma menu GetMainWindow()->MergeMenu(*view.GetViewMenu()); } void TLaskuriApp::EvCloseView(TView&) { GetMainWindow()->ClearFlag(wfShrinkToClient); GetMainWindow()->SetClientWindow(0); GetMainWindow()->SetCaption("Laskurm3"); } #ifdef OWL5 // Nämä on viimeksikäytettyjen tiedostojen listan (MRU) takia void TLaskuriApp::EvOwlDocument(TDocument& doc) { if (doc.GetDocPath()) SaveMenuChoice(doc.GetDocPath()); } int32 TLaskuriApp::CmFileSelected(uint wp, int32) { TAPointer text = new char[_MAX_PATH]; GetMenuText(wp, text, _MAX_PATH); TDocTemplate* tpl = GetDocManager()->MatchTemplate(text); if ( tpl ) GetDocManager()->CreateDoc(tpl, text); return 0; } #endif /********************* Pääohjelma *********************************************/ int OwlMain(int ,char far * []) { return TLaskuriApp("Autolaskuri").Run(); }