#define STRICT #define XVT_INCL_NATIVE #include #include #include #include #include #include #include #include #include #include #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 /////////////////////////////////////////////////////////// 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; } }