campo-sirio/include/golem.cpp
guy 4759abb8f4 applicat.cpp Aggiunto metodo pre_create per inizializzazioni di basso livello
golem.cpp     Migliorata gestione degli hook agli handler di finestra
msksheet.cpp  Eliminati molti sfarfallamenti duante cambio focus
relapp.cpp    Corretta gestione messaggio ED
sheet.cpp     Corretto posizionamento iniziale su righe disabilitate
xvtility.cpp  Migliorata gestione dell'event hook.


git-svn-id: svn://10.65.10.50/trunk@3328 c028cbd2-c16b-5b4b-a496-9718f37d4682
1996-08-05 09:43:06 +00:00

420 lines
9.7 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_NT
#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_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