campo-sirio/include/golem.cpp
guy 42bddb770f array.h Tolta riga vuota
assoc.h     Aggiunta macro di iterazione sugli elementi
golem.h     Aggiunta gestione della posta
golem.cpp   Suvvia c'e' la postaa, la posta eletrronicaaa
mailbox.h   Aggiunto vitrtual davanti al distruttore dei TMessage
msksheet.h  Aggiunte macro di iterazione sulle righe
regexp.h    Tolta #define di NULL
strings.cpp Aggiunti metodi a TFilename:
            is_absolute_path, is_relative_path e make_absolute_path
strings.h   Tolta #include <regexp.h> (-1K nel file .mak)


git-svn-id: svn://10.65.10.50/trunk@5626 c028cbd2-c16b-5b4b-a496-9718f37d4682
1997-11-17 10:28:04 +00:00

1030 lines
26 KiB
C++
Executable File

#define STRICT
#define XVT_INCL_NATIVE
#include <controls.h>
#include <execp.h>
#include <golem.h>
#include <msksheet.h>
#include <prefix.h>
#include <relation.h>
#include <urldefid.h>
#include <utility.h>
#include <mapi.h>
#include <shellapi.h>
#include "bagn006.h"
///////////////////////////////////////////////////////////////////////////////
// GotoURL
// Liberamente tradotto da Windows Developer Journal August 1997
///////////////////////////////////////////////////////////////////////////////
HIDDEN long get_reg_key(HKEY key, const char* subkey, TString& retdata)
{
HKEY hkey;
long retval = RegOpenKey(key, subkey, &hkey);
if (retval == ERROR_SUCCESS)
{
long datasize = retdata.size();
RegQueryValue(hkey, NULL, retdata.get_buffer(), &datasize);
RegCloseKey(hkey);
}
return retval;
}
HIDDEN bool file2app(const char* filename, TString& app)
{
bool ok = FALSE;
if (*filename != '.')
{
HINSTANCE hinst = FindExecutable(filename, ".", app.get_buffer());
DWORD* pinst = (DWORD*)hinst;
UINT err = LOWORD(pinst);
ok = err > 32;
}
if (!ok)
{
TString ext(_MAX_EXT);
if (*filename == '.')
ext = filename;
else
_splitpath(filename, NULL, NULL, NULL, ext.get_buffer());
ext.lower();
TFilename key;
if (get_reg_key(HKEY_CLASSES_ROOT, ext, key) == ERROR_SUCCESS)
{
key << "\\shell\\open\\command";
if (get_reg_key(HKEY_CLASSES_ROOT, key, key) == ERROR_SUCCESS)
{
key.strip("\"");
int pos = key.find("%1");
if (pos > 0)
key.cut(pos);
key.trim();
app = key;
ok = TRUE;
}
}
}
return ok;
}
HIDDEN bool internet_address(const char* filename)
{
const TFilename url(filename);
if (url.find("://") > 0)
return TRUE;
if (url.find("www.") >= 0)
return TRUE;
const char* extensions[] = { "com","edu","gov","it","mil","net","org", NULL };
const char* ext = url.ext();
for (int e = 0; extensions[e]; e++)
if (stricmp(ext, extensions[e]) == 0)
return TRUE;
return FALSE;
}
HIDDEN word file2icon(const char* filename)
{
TFilename key;
word icon = 0;
int icon_number = 0;
TString ext(_MAX_EXT);
if (*filename == '.' && strlen(filename) < _MAX_EXT)
ext = filename;
else
{
if (internet_address(filename))
ext = ".htm";
else
_splitpath(filename, NULL, NULL, NULL, ext.get_buffer());
}
ext.lower();
if (ext != ".exe")
{
if (get_reg_key(HKEY_CLASSES_ROOT, ext, key) == ERROR_SUCCESS)
{
key << "\\DefaultIcon";
if (get_reg_key(HKEY_CLASSES_ROOT, key, key) == ERROR_SUCCESS) // Windows 95 only
{
const int comma = key.find(',');
if (comma > 0)
{
icon_number = atoi(key.mid(comma+1));
key.cut(comma);
}
}
else
{
if (!file2app(filename, key))
file2app(".htm", key);
}
}
}
else
key = filename;
// Toglie eventuali parametri sulla riga si comando
const int space_pos = key.find(' ');
if (space_pos > 0) key.cut(space_pos);
HINSTANCE hInst = (HINSTANCE)xvt_vobj_get_attr(NULL_WIN, ATTR_WIN_INSTANCE);
HICON hicon = ExtractIcon(hInst, key, icon_number);
if (hicon == NULL && icon_number != 0)
hicon = ExtractIcon(hInst, key, 0);
if (hicon != NULL)
{
DWORD dwicon = DWORD((DWORD*)hicon);
icon = LOWORD(dwicon);
}
return icon;
}
HIDDEN word mail2icon()
{
word icon = 0;
TFilename key;
if (get_reg_key(HKEY_CLASSES_ROOT, "msgfile\\shell\\open\\command", key) == ERROR_SUCCESS)
{
const int space = key.find(' ');
if (space) key.cut(space);
icon = file2icon(key);
}
if (icon == 0)
icon = file2icon(".mmf");
return icon;
}
bool goto_url(const char* url)
{
TFilename app(url);
app.lower();
const TString ext(app.ext());
TConfig link(CONFIG_USER, "Link");
app = link.get(ext);
if (app.not_empty())
{
app << ' ' << url;
UINT error = WinExec(app, SW_SHOWNORMAL);
if (error > 32)
return TRUE;
else
link.set(ext, "");
}
bool retflag = FALSE;
HINSTANCE hinst = ShellExecute(NULL, "open", url, NULL, NULL, SW_SHOWNORMAL);
DWORD winst = DWORD((DWORD*)hinst);
UINT error = UINT(winst); // Tutto 'sto giro per evitare un warning
if (error <= 32)
{
if (file2app(".htm", app))
{
app << ' ' << url;
error = WinExec(app, SW_SHOWNORMAL);
if (error > 32)
retflag = TRUE;
}
}
else
retflag = TRUE;
return retflag;
}
bool print_url(const char* url)
{
HINSTANCE hinst = ShellExecute(NULL, "print", url, NULL, NULL, SW_SHOWNORMAL);
DWORD winst = DWORD((DWORD*)hinst);
UINT error = UINT(winst); // Tutto 'sto giro per evitare un warning
return error >= 32;
}
///////////////////////////////////////////////////////////
// Maschera GOLEM
///////////////////////////////////////////////////////////
class TGolem_mask : public TMask
{
protected:
static bool file_handler(TMask_field& f, KEY k);
static bool link_handler(TMask_field& f, KEY k);
static bool main_link_handler(TMask_field& f, KEY k);
static bool ole_handler(TMask_field& f, KEY k);
public:
TGolem_mask();
virtual ~TGolem_mask() { }
};
bool TGolem_mask::file_handler(TMask_field& f, KEY k)
{
TMask& m = f.mask();
if (k == K_F9)
{
FILE_SPEC fs;
xvt_fsys_convert_str_to_dir(".", &fs.dir);
strcpy(fs.type, "");
strcpy(fs.name, "*.*");
strcpy(fs.creator, "GOLEM");
DIRECTORY dir; xvt_fsys_get_dir(&dir);
FL_STATUS ok = xvt_dm_post_file_open(&fs, "Selezionare il file ...");
xvt_fsys_set_dir(&dir);
if (ok == FL_OK)
{
TFilename file;
xvt_fsys_convert_dir_to_str(&fs.dir, file.get_buffer(), file.size());
file.add(fs.name);
m.set(S_FILE, file);
k = K_TAB;
}
}
if (k == K_TAB && f.focusdirty())
{
TFilename file = m.get(S_FILE);
if (fexist(file))
{
char ext[_MAX_EXT];
char name[_MAX_FNAME];
_splitpath(file, NULL, NULL, name, ext);
file = name; file.ext(ext);
m.enable(S_LINK);
m.disable(F_NEWREC);
m.enable(F_LINK);
m.enable(F_PRINT);
}
else
{
const bool full = file.not_empty();
m.set(S_LINK, full ? "X" : "");
m.disable(S_LINK);
m.enable(F_NEWREC, full);
m.enable(F_LINK, full);
m.disable(F_PRINT);
file.cut(0);
}
m.set(S_ALIAS, file);
}
return TRUE;
}
bool TGolem_mask::link_handler(TMask_field& f, KEY k)
{
if (k == K_SPACE)
{
TMask& m = f.mask();
TFilename url = m.get(S_FILE);
short id = f.dlg();
if (id == F_NEWREC && url.not_empty())
{
if (!fexist(url))
{
TFilename name;
char ext[_MAX_EXT];
_splitpath(url, NULL, NULL, name.get_buffer(), ext);
if (name.not_empty() && *ext)
{
name.ext(ext);
url.tempdir();
url.add(name);
ofstream out(url); // Crea un file vuoto
}
else
url.cut(0);
m.set(S_FILE, url, TRUE); // ... memorizza il suo nome ...
m.reset(S_LINK); // Non puo' essere un collegamento
}
else
id = F_LINK;
}
if (url.not_empty())
{
bool open = TRUE;
if (id == DLG_PRINT)
open = !print_url(url);
if (open)
goto_url(url);
}
}
return TRUE;
}
bool TGolem_mask::main_link_handler(TMask_field& f, KEY k)
{
if (k == K_SPACE)
{
TSheet_field& sheet = f.mask().sfield(F_SHEET);
if (sheet.items() > 0)
{
sheet.check_row(sheet.selected());
TMask& sm = sheet.sheet_mask();
TMask_field& link = sm.field(f.dlg());
link_handler(link, K_SPACE);
}
}
return TRUE;
}
bool TGolem_mask::ole_handler(TMask_field& f, KEY k)
{
if (k == K_SPACE)
{
TSheet_field& sheet = f.mask().sfield(F_SHEET);
TMask& sm = sheet.sheet_mask();
int selected = sheet.selected();
if (sheet.items() == 0 || !sm.field(S_FILE).empty())
{
sheet.row(-1);
selected = sheet.items()-1;
}
sheet.check_row(selected);
TString16 ext = f.prompt();
if (ext == "mailto")
{
TMail_message msg("");
msg.send();
}
else
{
TFilename file;
file.temp(NULL, ext);
sm.set(S_FILE, file);
ofstream out(file);
sheet.row(selected) = file;
sheet.force_update();
TFilename app; file2app(ext, app);
app << ' ' << file;
WinExec(app, SW_SHOWNORMAL);
}
}
return TRUE;
}
TGolem_mask::TGolem_mask()
: TMask("bagn006")
{
TSheet_field& sheet = sfield(F_SHEET);
set_handler(F_NEWREC, main_link_handler);
set_handler(F_LINK, main_link_handler);
set_handler(F_PRINT, main_link_handler);
TMask& sm = sheet.sheet_mask();
sm.set_handler(S_FILE, file_handler);
sm.set_handler(F_NEWREC, link_handler);
sm.set_handler(F_LINK, link_handler);
sm.set_handler(F_PRINT, link_handler);
TConfig ini(CONFIG_USER, "Link");
TString_array list;
ini.list_variables(list);
// Elimina la posta se c'e'
const int mmf_pos = list.find("mailto");
if (mmf_pos >= 0) list.destroy(mmf_pos);
// Ordina alfabeticamente
list.sort();
const int ITEMS_PER_ROW = 15;
const int MAX_ITEMS = ITEMS_PER_ROW * 2;
// Aggiungi la posta se attiva
if (GetProfileInt("Mail", "MAPI", 0))
{
const int items = list.items();
const int mmf_pos = (items >= MAX_ITEMS) ? MAX_ITEMS-1 : -1;
list.add("mailto", mmf_pos);
}
int i = 0;
FOR_EACH_ARRAY_ROW(list, r, row)
{
TString16 ext = *row;
word icon;
if (ext == "mailto")
{
icon = mail2icon();
}
else
{
ext.insert(".", 0);
icon = file2icon(ext);
}
if (icon)
{
const int x = (i < ITEMS_PER_ROW ? i*5 : (i-ITEMS_PER_ROW)*5) + 1;
const int y = i < ITEMS_PER_ROW ? 0 : 2;
TButton_field& btn = add_button(301+i, 0, ext, x, y, 3, 2);
btn.set_handler(ole_handler);
btn.set_icon(icon);
i++;
if (i > MAX_ITEMS)
break;
}
}
}
///////////////////////////////////////////////////////////
// Campi GOLEM
///////////////////////////////////////////////////////////
TString& TGolem_field::get_window_data()
{
return _str;
}
void TGolem_field::set_window_data(const char* data)
{
WORD icon = 0;
char* pipe = strchr(data, '|');
if (pipe)
{
*pipe = '\0'; // Poor man TToken_string
icon = file2icon(data);
*pipe = '|';
}
TPushbutton_control* btn = (TPushbutton_control*)_ctl;
if (icon)
btn->set_icon(icon);
else
btn->set_bmp(BMP_OLE, 0);
RCT rct; btn->get_rect(rct);
xi_invalidate_rect(btn->parent(), &rct);
}
bool TGolem_field::is_editable() const
{ return FALSE; }
void TGolem_field::parse_head(TScanner& scanner)
{
_ctl_data._width = scanner.integer();
if (_ctl_data._width <= 0) _ctl_data._width = 10;
_ctl_data._height = scanner.integer(); // Height
if (_ctl_data._height <= 0) _ctl_data._height = 1;
_ctl_data._bmp_up = BMP_OLE;
}
void TGolem_field::create(WINDOW parent)
{
_ctl = new TPushbutton_control(parent, _ctl_data._dlg,
_ctl_data._x, _ctl_data._y,
_ctl_data._width+2, _ctl_data._height,
_ctl_data._flags, _ctl_data._prompt,
_ctl_data._bmp_up, _ctl_data._bmp_dn);
}
bool TGolem_field::autoload(const TRelation& r)
{
const bool ok = TEditable_field::autoload(r);
if (ok)
_old_value = get();
else
_old_value.cut(0);
return ok;
}
bool TGolem_field::autosave(TRelation& r)
{
if (field() != NULL)
{
TToken_string new_value(get(), '\n');
if (new_value != _old_value)
{
TDir dir;
const int logicnum = r.lfile().num();
dir.get(logicnum, _nolock, _nordir, _sysdirop);
const long ditta = dir.is_com() ? 0 : prefix().get_codditta();
TFilename golem_path;
golem_path = firm2dir(ditta);
golem_path.add("golem");
if (!fexist(golem_path))
make_dir(golem_path);
const int old_items = _old_value.items();
const int new_items = new_value.items();
const int items = new_items > old_items ? new_items : old_items;
TToken_string old_row, new_row;
TFilename old_file, new_file;
for (int i = 0; i < items; i++)
{
old_row = _old_value.get(i); // Devo usare l'indice ogni volta ...
new_row = new_value.get(i); // ... perche' le TToken_string cambiano!
old_file = old_row.get(0);
new_file = new_row.get(0);
if (old_file != new_file)
{
const was_stored = old_row.get_char(2) <= ' ' &&
golem_path.compare(old_file, golem_path.len(), TRUE) == 0;
const tobe_stored = new_row.get_char(2) <= ' ';
if (was_stored && fexist(old_file))
::remove(old_file);
if (tobe_stored && !new_file.blank())
{
char ext[_MAX_EXT];
_splitpath(new_file, NULL, NULL, NULL, ext);
old_file.temp(golem_path, ext);
fcopy(new_file, old_file);
new_row.add(old_file, 0);
new_value.add(new_row, i);
// Cancella il file originale se temporaneo
TFilename tmp; tmp.tempdir();
if (tmp.compare(new_file, tmp.len(), TRUE) == 0)
::remove(new_file);
}
}
}
set(_old_value = new_value);
}
}
return TEditable_field::autosave(r);
}
bool TGolem_field::on_key(KEY key)
{
bool ok = TRUE;
if (key == K_SPACE)
{
TMask* msk = new TGolem_mask;
TSheet_field& sheet = msk->sfield(F_SHEET);
TToken_string tmp = get();
if (roman())
{
tmp.separator('\n');
// for (const char* row = tmp.get(0); row; row = tmp.get())
FOR_EACH_TOKEN(tmp, row)
{
if (*row > ' ')
sheet.row(-1) = row;
}
if (msk->run() == K_ENTER)
{
tmp.cut(0);
// for (int r = 0; r < sheet.items(); r++)
FOR_EACH_SHEET_ROW(sheet, r, row)
{
// TToken_string& row = sheet.row(r);
if ((*row)[0] > ' ')
tmp.add(*row);
}
set(tmp);
}
}
else
{
TMask& sm = sheet.sheet_mask();
for (int i = 0; i < 3; i++)
sm.set(S_FILE+i, tmp.get());
if (sm.run() == K_ENTER)
{
tmp.cut(0);
for (int i = 0; i < 3; i++)
tmp.add(sm.get(S_FILE+i));
set(tmp);
}
}
delete msk;
}
return ok;
}
TGolem_field::TGolem_field(TMask* m)
: TEditable_field(m), _old_value(80, '\n')
{ }
TGolem_field::~TGolem_field()
{ }
///////////////////////////////////////////////////////////
// Mail message
///////////////////////////////////////////////////////////
#ifdef _WIN32
const char* const szMAPIDLL = "MAPI32.DLL";
#else
const char* const szMAPIDLL = "MAPI.DLL";
#endif
static HINSTANCE _hlibMAPI = NULL;
LPMAPILOGON lpfnMAPILogon = NULL;
LPMAPILOGOFF lpfnMAPILogoff = NULL;
LPMAPISENDMAIL lpfnMAPISendMail = NULL;
LPMAPISENDDOCUMENTS lpfnMAPISendDocuments = NULL;
LPMAPIFINDNEXT lpfnMAPIFindNext = NULL;
LPMAPIREADMAIL lpfnMAPIReadMail = NULL;
LPMAPISAVEMAIL lpfnMAPISaveMail = NULL;
LPMAPIDELETEMAIL lpfnMAPIDeleteMail = NULL;
LPMAPIFREEBUFFER lpfnMAPIFreeBuffer = NULL;
LPMAPIADDRESS lpfnMAPIAddress = NULL;
LPMAPIDETAILS lpfnMAPIDetails = NULL;
LPMAPIRESOLVENAME lpfnMAPIResolveName = NULL;
bool TMail_message::load_mapi(void)
{
if (_hlibMAPI) // Check in already loaded
return TRUE;
// Check if MAPI is installed on the system
BOOL MAPI_installed = GetProfileInt("Mail", "MAPI", 0);
if(!MAPI_installed)
return FALSE;
UINT fuError = SetErrorMode(SEM_NOOPENFILEERRORBOX);
_hlibMAPI = LoadLibrary(szMAPIDLL);
SetErrorMode(fuError);
DWORD* err = (DWORD*)_hlibMAPI;
if ((DWORD)err < 32)
return FALSE;
if (!(lpfnMAPILogon = (LPMAPILOGON) GetProcAddress (_hlibMAPI, "MAPILogon")))
return FALSE;
if (!(lpfnMAPILogoff = (LPMAPILOGOFF) GetProcAddress (_hlibMAPI, "MAPILogoff")))
return FALSE;
if (!(lpfnMAPISendMail = (LPMAPISENDMAIL) GetProcAddress (_hlibMAPI, "MAPISendMail")))
return FALSE;
if (!(lpfnMAPISendDocuments = (LPMAPISENDDOCUMENTS) GetProcAddress (_hlibMAPI, "MAPISendDocuments")))
return FALSE;
if (!(lpfnMAPIFindNext = (LPMAPIFINDNEXT) GetProcAddress (_hlibMAPI, "MAPIFindNext")))
return FALSE;
if (!(lpfnMAPIReadMail = (LPMAPIREADMAIL) GetProcAddress (_hlibMAPI, "MAPIReadMail")))
return FALSE;
if (!(lpfnMAPISaveMail = (LPMAPISAVEMAIL) GetProcAddress (_hlibMAPI, "MAPISaveMail")))
return FALSE;
if (!(lpfnMAPIDeleteMail = (LPMAPIDELETEMAIL) GetProcAddress (_hlibMAPI, "MAPIDeleteMail")))
return FALSE;
if (!(lpfnMAPIFreeBuffer = (LPMAPIFREEBUFFER) GetProcAddress (_hlibMAPI, "MAPIFreeBuffer")))
return FALSE;
if (!(lpfnMAPIAddress = (LPMAPIADDRESS) GetProcAddress (_hlibMAPI, "MAPIAddress")))
return FALSE;
if (!(lpfnMAPIDetails = (LPMAPIDETAILS) GetProcAddress (_hlibMAPI, "MAPIDetails")))
return FALSE;
if (!(lpfnMAPIResolveName = (LPMAPIRESOLVENAME) GetProcAddress (_hlibMAPI, "MAPIResolveName")))
return FALSE;
return TRUE;
}
void TMail_message::unload_mapi()
{
if (_hlibMAPI)
{
FreeLibrary(_hlibMAPI);
_hlibMAPI = NULL;
}
}
bool TMail_message::send()
{
TWait_cursor hourglass;
bool ok = load_mapi();
if (!ok)
return error_box("Impossibile inizializzare MAPI");
LHANDLE lhSession = 0;
ULONG err = lpfnMAPILogon(0L, "", "",
MAPI_LOGON_UI | MAPI_USE_DEFAULT,
0L, &lhSession);
if (err == SUCCESS_SUCCESS)
{
const int MAX_RECIPIENTS = _recipients.items() + _copy_recipients.items() + 1;
MapiRecipDesc* msgRecipient = new MapiRecipDesc[MAX_RECIPIENTS];
memset(msgRecipient, 0, MAX_RECIPIENTS*sizeof(MapiRecipDesc));
int nr = 0;
if (_sender.not_empty())
{
msgRecipient[nr].ulRecipClass = MAPI_ORIG;
msgRecipient[nr++].lpszName = _sender.get_buffer();
}
FOR_EACH_ARRAY_ROW(_recipients, rec, recipient)
{
msgRecipient[nr].ulRecipClass = MAPI_TO;
msgRecipient[nr++].lpszName = recipient->get_buffer();
}
FOR_EACH_ARRAY_ROW(_copy_recipients, cc_rec, cc_recipient)
{
msgRecipient[nr].ulRecipClass = MAPI_CC;
msgRecipient[nr++].lpszName = cc_recipient->get_buffer();
}
const int MAX_ATTACHMENTS = _attachments.items() + 1;
MapiFileDesc* msgAttachment = new MapiFileDesc[MAX_ATTACHMENTS];
memset(msgAttachment, 0, MAX_ATTACHMENTS*sizeof(MapiFileDesc));
int na = 0;
FOR_EACH_ARRAY_ROW(_attachments, att, attachment)
{
TString80 tmp; tmp.spaces(32);
*this << '\n' << tmp;
msgAttachment[na].nPosition = len()-1;
msgAttachment[na++].lpszPathName = attachment->get_buffer();
}
MapiMessage msgSend;
memset(&msgSend, 0, sizeof(MapiMessage));
msgSend.lpszNoteText = get_buffer();
msgSend.lpszSubject = _subject.get_buffer();
msgSend.nRecipCount = nr;
msgSend.lpRecips = msgRecipient;
msgSend.nFileCount = na;
msgSend.lpFiles = msgAttachment;
err = lpfnMAPISendMail(lhSession, 0, &msgSend, MAPI_DIALOG, 0L);
delete msgRecipient;
delete msgAttachment;
err = lpfnMAPILogoff(lhSession, 0L, 0L, 0L);
}
else
ok = error_box("Impossibile collegarsi a MAPI");
unload_mapi();
return ok;
}
bool TMail_message::add_recipient_ex(const char* recipient, int type)
{
TFilename rec(recipient);
rec.trim();
bool ok = rec.not_empty();
if (ok) switch(type)
{
case 1:
_copy_recipients.add(rec);
break;
case 2:
if (rec.is_relative_path())
rec.make_absolute_path();
ok = fexist(rec);
if (ok)
_attachments.add(rec);
break;
default:
_recipients.add(rec);
break;
}
return ok;
}
TMail_message::TMail_message(const char* recipient, const char* subject,
const char* text, const char* sender)
: TString(text), _subject(subject), _sender(sender)
{
add_recipient(recipient);
}
///////////////////////////////////////////////////////////
// Obsolete DDE management
///////////////////////////////////////////////////////////
#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())
FOR_EACH_TOKEN(topics, topo)
{
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;
}
}