0e6df8119c
git-svn-id: svn://10.65.10.50/trunk@4485 c028cbd2-c16b-5b4b-a496-9718f37d4682
425 lines
9.8 KiB
C++
Executable File
425 lines
9.8 KiB
C++
Executable File
#define STRICT
|
|
#define XVT_INCL_NATIVE
|
|
#include <applicat.h>
|
|
#include <config.h>
|
|
#include <execp.h>
|
|
#include <golem.h>
|
|
#include <mask.h>
|
|
#include <prefix.h>
|
|
#include <relation.h>
|
|
#include <urldefid.h>
|
|
#include <utility.h>
|
|
|
|
#include <bagn006.h>
|
|
|
|
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_WIN32
|
|
|
|
#include <dde.h>
|
|
|
|
///////////////////////////////////////////////////////////
|
|
// 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_DATA:
|
|
{
|
|
ATOM i = HIWORD(lparam); if (i) GlobalDeleteAtom(i);
|
|
}
|
|
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(-1)
|
|
{
|
|
CHECK(CUR_DDE == NULL, "Double DDE");
|
|
CUR_DDE = this;
|
|
_hwnd = (word)xvt_vobj_get_attr(TASK_WIN, ATTR_NATIVE_WINDOW);
|
|
}
|
|
|
|
TDDE::~TDDE()
|
|
{
|
|
do_events(); // Flush degli venti in coda prima di sganciare tutto
|
|
terminate();
|
|
_hwnd = 0;
|
|
CUR_DDE = NULL;
|
|
}
|
|
|
|
bool TDDE::initiate(const char* app, const char* topic)
|
|
{
|
|
if (_old_hook == -1)
|
|
{
|
|
_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 == -1)
|
|
{
|
|
_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 != -1)
|
|
{
|
|
xvt_vobj_set_attr(NULL_WIN, ATTR_EVENT_HOOK, _old_hook);
|
|
_old_hook = -1;
|
|
PostMessage((HWND)_server, (WPARAM)_hwnd, WM_DDE_TERMINATE, (LPARAM)0);
|
|
_server = 0;
|
|
}
|
|
}
|
|
|
|
#endif
|