#define STRICT #define XVT_INCL_NATIVE #include #include #include #include #include #include #include #include #include #include long TGolem::_count = 0; TFilename* TGolem::_path = NULL; TConfig* TGolem::_config = NULL; TRelation* TGolem::_golem = NULL; TGolem::TGolem(const char* cls, long id) : _class(cls), _id(id) { CHECK(_class.not_empty() && id >= 0, "Invalid Golem creation"); _class.upper(); if (_count == 0) { CHECK(_path == NULL, "Golem construction count error"); _path = new TFilename; _config = new TConfig(CONFIG_GOLEM, _class); _golem = new TRelation(LF_GOLEM); } _count++; } TGolem::~TGolem() { _count--; if (_count == 0) { CHECK(_path != NULL, "Golem destruction count error"); delete _golem; _golem = NULL; delete _config; _config = NULL; delete _path; _path = NULL; } } TConfig& TGolem::config() const { _config->set_paragraph(_class); return *_config; } bool TGolem::ok() const { return _id > 0 && fexist(path()); } const char* TGolem::class_name() const { *_path = "GOLEM_"; *_path << _class << "_CLASS"; return *_path; } word TGolem::class_id() const { return CLASS_GOLEM; } short TGolem::icon() const { const short id = config().get_int("Icon", NULL, -1, DLG_F9); return id; } const char* TGolem::ext() const { return config().get("Extension", NULL, -1, _class.left(3)); } const TFilename& TGolem::path(bool test) const { const char* e = ext(); *_path = firm2dir(-1); // C:\PRASSI\DATI _path->add("golem"); // C:\PRASSI\DATI\GOLEM if (test && !fexist(*_path)) make_dir(*_path); _path->add(_class); // C:\PRASSI\DATI\GOLEM\BITMAP if (test && !fexist(*_path)) make_dir(*_path); if (_id > 0) { _path->add(format("%ld", _id));// C:\PRASSI\DATI\GOLEM\BMP\883 _path->ext(e); // C:\PRASSI\DATI\GOLEM\BMP\883.BMP } return *_path; } int TGolem::compare(const TSortable& s) const { if (s.class_id() != class_id()) return UNDEFINED; const TGolem& g = (const TGolem&)s; return int(_id - g._id); } bool TGolem::edit() { const TFilename& p = path(); bool ok = fexist(p); if (ok) { TFilename e(config().get("Editor")); e << ' ' << p; TExternal_app app(e); ok = app.run(FALSE, FALSE) == 0; } return ok; } long TGolem::new_id() const { long id = 0; TLocalisamfile& gol = _golem->lfile(); gol.zero(); gol.put("CLASSE", _class); gol.put("CHIAVE", "99999999"); const int err = gol.read(_isgteq); switch (err) { case NOERR: id = 0; break; case _isemptyfile: id = 1; break; default: if (gol.get("CLASSE") != _class) gol.prev(); if (gol.get("CLASSE") == _class) id = gol.get_long("CHIAVE")+1; else id = 1; break; } return id; } bool TGolem::import() { FILE_SPEC fs; const char* const e = ext(); xvt_fsys_convert_str_to_dir(".", &fs.dir); strcpy(fs.type, e); sprintf(fs.name, "*.%s", e); strcpy(fs.creator, "GOLEM"); xvt_fsys_save_dir(); FL_STATUS ok = xvt_dm_post_file_open(&fs, "Selezionare il file ..."); xvt_fsys_restore_dir(); if (ok == FL_OK) { TFilename from; xvt_fsys_convert_dir_to_str(&fs.dir, (char*)(const char*)from, 80); from.add(fs.name); from.ext(e); TMask msk("bagn006"); msk.set(F_CLASSE, _class); msk.set(F_CODICE, new_id()); bool correct = msk.run() == K_ENTER; if (correct) { _id = msk.get_long(F_CODICE); correct = fcopy(from, path(TRUE)); if (correct) { msk.autosave(*_golem); int err = _golem->write(); if (err == _isreinsert) err = _golem->rewrite(); if (err != NOERR) { error_box("Errore nell'aggiornamento del file degli oggetti"); ok = FL_BAD; } } else { error_box("Spazio su disco insufficiente per l'oggetto"); ok = FL_BAD; } } else ok = FL_CANCEL; } return ok == FL_OK; } #if XVT_OS == XVT_OS_WIN || XVT_OS == XVT_OS_NT #include /////////////////////////////////////////////////////////// // DDE /////////////////////////////////////////////////////////// static TDDE* CUR_DDE = NULL; HIDDEN BOOLEAN hook(HWND hwnd, UINT msg, UINT wparam, ULONG lparam, long* ret) { CHECK(CUR_DDE, "No DDE available"); bool normal_process = TRUE; if (CUR_DDE->hwnd() == (word)hwnd) switch (msg) { case WM_DDE_INITIATE: if (wparam != CUR_DDE->hwnd()) // Non initiarti da solo! { ATOM app = LOWORD(lparam); ATOM topic = HIWORD(lparam); TString a(256), t(256); if (app) GlobalGetAtomName(app, (char*)(const char*)a, a.size()); if (topic) GlobalGetAtomName(topic, (char*)(const char*)t, t.size()); bool ok = FALSE; const char* an = CUR_DDE->get_app_name(); if (an && *an) ok = a.empty() || a.compare(an, -1, TRUE) == 0; if (ok) // Server name ok { const bool query_topics = t.empty() || t == "*"; TToken_string topics = CUR_DDE->get_topics(); ok = !topics.empty_items(); // No topics? if (ok && !query_topics) { ok = FALSE; for (const char* topo = topics.get(0); topo; topo = topics.get()) { if (t.compare(topo, -1, TRUE) == 0) { ok = TRUE; break; } } } if (ok) // Topic ok { ok = CUR_DDE->do_initiate(wparam, t); if (ok) // Connection ok { if (!query_topics) topics = t; for (t = topics.get(0); t.not_empty(); t = topics.get()) { // E' obbligatorio crearne dei nuovi! Non spostare fuori dal ciclo! app = GlobalAddAtom(CUR_DDE->get_app_name()); topic = GlobalAddAtom(t); SendMessage((HWND)wparam, WM_DDE_ACK, (WPARAM)hwnd, MAKELPARAM(app,topic)); } } } } normal_process = FALSE; } break; case WM_DDE_ACK: { ATOM a = LOWORD(lparam); if (a) GlobalDeleteAtom(a); ATOM t = HIWORD(lparam); if (t) GlobalDeleteAtom(t); CUR_DDE->do_ack(wparam); normal_process = FALSE; } break; case WM_DDE_EXECUTE: { const TString cmd((const char*)lparam); DDEACK ack; memset(&ack, 0, sizeof(ack)); ack.fAck = CUR_DDE->do_execute(wparam, cmd); // Ritorna indietro l'handle globale che verra' distrutto dal chiamante PostMessage((HWND)wparam, WM_DDE_ACK, (WPARAM)hwnd, lparam); normal_process = FALSE; } break; case WM_DDE_TERMINATE: CUR_DDE->do_terminate(wparam); normal_process = FALSE; break; case WM_DROPFILES: if (CUR_DDE->do_custom_message(msg, wparam, lparam)) { *ret = 0; normal_process = FALSE; } break; default: if (msg > (UINT)WM_USER && msg < 0x7FFF) { if (CUR_DDE->do_custom_message(msg, wparam, lparam)) normal_process = FALSE; } break; } return normal_process; } TDDE::TDDE() : _server(0), _old_hook(NULL) { CHECK(CUR_DDE == NULL, "Double DDE"); CUR_DDE = this; _hwnd = (word)xvt_vobj_get_attr(TASK_WIN, ATTR_NATIVE_WINDOW); } TDDE::~TDDE() { terminate(); _hwnd = 0; CUR_DDE = NULL; } bool TDDE::initiate(const char* app, const char* topic) { if (_old_hook == NULL) { _old_hook = xvt_vobj_get_attr(NULL_WIN, ATTR_EVENT_HOOK); xvt_vobj_set_attr(NULL_WIN, ATTR_EVENT_HOOK, (long)hook); } _server = 0; ATOM a_app = GlobalAddAtom(app); ATOM a_topic = GlobalAddAtom(topic); SendMessage(HWND_BROADCAST, WM_DDE_INITIATE, (WPARAM)_hwnd, MAKELPARAM(a_app, a_topic)); GlobalDeleteAtom(a_app); GlobalDeleteAtom(a_topic); return _server != 0; } bool TDDE::execute(const char* cmd) const { HGLOBAL hg = GlobalAlloc(GMEM_DDESHARE, strlen(cmd)+1); char* c = (char*)GlobalLock(hg); strcpy(c, cmd); GlobalUnlock(hg); return PostMessage((HWND)_server, WM_DDE_EXECUTE, (WPARAM)_hwnd, MAKELPARAM(0, hg)); } bool TDDE::execute(const char* app, const char* topic, const char* cmd, const char* filename) { bool running = initiate(app, topic); if (!running) { if (filename == NULL || *filename == '\0') filename = app; TExternal_app server(filename); if (server.run(TRUE) == 0) { for (int failures = 0; !running && failures < 10; failures++) { const clock_t end = clock() + 3*CLOCKS_PER_SEC; while (clock() < end) do_events(); running = initiate(app, topic); } } } if (running) { if (cmd && *cmd) execute(cmd); terminate(); } return running; } bool TDDE::start_server() { if (_old_hook == NULL) { _old_hook = xvt_vobj_get_attr(NULL_WIN, ATTR_EVENT_HOOK); xvt_vobj_set_attr(NULL_WIN, ATTR_EVENT_HOOK, (long)hook); } return TRUE; } void TDDE::terminate() { if (_old_hook) { xvt_vobj_set_attr(NULL_WIN, ATTR_EVENT_HOOK, _old_hook); _old_hook = NULL; PostMessage((HWND)_server, (WPARAM)_hwnd, WM_DDE_TERMINATE, (LPARAM)0); _server = 0; } } #endif