#define STRICT #define WIN32_EXTRA_LEAN #define XVT_INCL_NATIVE #include #include #include #include #include #include #include #include #include #ifdef WIN32 #include #include #endif #include "bagn006.h" /////////////////////////////////////////////////////////////////////////////// // GotoURL // Liberamente tradotto da Windows Developer Journal August 1997 /////////////////////////////////////////////////////////////////////////////// HIDDEN unsigned int mail2icon() { unsigned int icon = xvt_sys_load_icon(".eml"); if (icon == 0) icon = xvt_sys_load_icon(".msg"); if (icon == 0) icon = xvt_sys_load_icon(".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 << '"'; long error = xvt_sys_execute(app, FALSE, FALSE); //verificare if (error > 32) return TRUE; else link.set(ext, ""); } return xvt_sys_goto_url(url, "open") != 0; } bool edit_url(const char* url) { bool ok = xvt_sys_goto_url(url, "edit") != 0; if (!ok) ok = goto_url(url); return ok; } bool print_url(const char* url) { bool ok = xvt_sys_goto_url(url, "print") != 0; if (!ok) ok = goto_url(url); return ok; } /////////////////////////////////////////////////////////// // 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); static bool sheet_notify(TSheet_field& s, int r, 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; if (!f.empty()) { const TFilename n = f.get(); xvt_fsys_convert_str_to_dir((char*)(const char*)n.path(), &fs.dir); } else 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; } f.set_focus(); } if (k == K_TAB && f.focusdirty()) { TFilename file = m.get(S_FILE); if (file.exist()) { char ext[_MAX_EXT]; char name[_MAX_FNAME]; xvt_fsys_parse_pathname(file, NULL, NULL, name, ext, NULL); //verificare 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 (!url.exist()) { TFilename name; char ext[_MAX_EXT]; xvt_fsys_parse_pathname(url, NULL, NULL, name.get_buffer(), ext, NULL); 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::sheet_notify(TSheet_field& s, int r, KEY k) { if (k == K_DEL) { TToken_string row = s.row(r); if (row.get_char(2)<=' ') { xvt_fsys_removefile(row.get(0)); } } 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); out.close(); sheet.row(selected) = file; sheet.force_update(); edit_url(file); } } return TRUE; } TGolem_mask::TGolem_mask() : TMask("bagn006") { TSheet_field& sheet = sfield(F_SHEET); sheet.set_notify(sheet_notify); 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 #ifdef WIN32 // verificare 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); } #else SORRY_BOX(); // verificare #endif int i = 0; FOR_EACH_ARRAY_ROW(list, r, row) { TString16 ext = *row; unsigned int icon; if (ext == "mailto") { icon = mail2icon(); } else { ext.insert(".", 0); icon = xvt_sys_load_icon(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_central_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) { unsigned int icon = 0; char* pipe = strchr(data, '|'); if (pipe) { *pipe = '\0'; // Poor man TToken_string icon = xvt_sys_load_icon(data); *pipe = '|'; } TPushbutton_control* btn = (TPushbutton_control*)_ctl; if (icon) btn->set_central_icon(icon); else btn->set_bmp(BMP_OLE, 0); RCT rct; btn->get_rect(rct); xvt_dwin_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 bool was_stored = old_row.get_char(2) <= ' ' && golem_path.compare(old_file, golem_path.len(), TRUE) == 0; const bool 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]; xvt_fsys_parse_pathname(new_file, NULL, NULL, NULL, ext, NULL); 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(), '\n'); if (roman()) { FOR_EACH_TOKEN(tmp, row) { if (*row > ' ') sheet.row(-1) = row; } if (msk->run() == K_ENTER) { tmp.cut(0); FOR_EACH_SHEET_ROW(sheet, r, row) { if ((*row)[0] > ' ') tmp.add(*row); } set(tmp); _selected = sheet.selected(); do_message(0); } } else { tmp.separator('|'); 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); do_message(0); } } delete msk; } return ok; } TGolem_field::TGolem_field(TMask* m) : TEditable_field(m), _old_value(80, '\n'), _selected(0) { } TGolem_field::~TGolem_field() { } /////////////////////////////////////////////////////////// // TGolem_client_field /////////////////////////////////////////////////////////// class TGolem_window : public TField_window { TFilename _last_file; unsigned long _last_handle; protected: virtual bool on_key(KEY k); virtual void update(); virtual void handler(WINDOW win, EVENT* ep); public: TGolem_field* driver() const { return ((TGolem_client_field&)owner()).driver(); } const TFilename& get_current_file(TFilename& fn) const; TGolem_window(int x, int y, int dx, int dy, WINDOW parent, TGolem_client_field* owner); virtual ~TGolem_window(); }; const TFilename& TGolem_window::get_current_file(TFilename& fn) const { TGolem_field* gf = driver(); if (gf != NULL) { TToken_string list(gf->get(), '\n'); TToken_string tok = list.get(gf->selected()); fn = tok.get(); } else fn.cut(0); return fn; } void TGolem_window::update() { bool drawn = FALSE; TField_window::update(); TFilename file; get_current_file(file); if (file.not_empty() && file.exist()) { const TString16 ext = file.ext(); if (ext.compare("bmp", -1, TRUE) == 0) { TImage img(file); if (img.ok()) { RCT cli; xvt_vobj_get_client_rect(win(), &cli); if (owner().automagic()) { const double ratiox = double(cli.right-cli.left) / img.width(); const double ratioy = double(cli.bottom-cli.top) / img.height(); const double ratio = min(ratiox, ratioy); const int maxx = int(ratio * img.width()); const int maxy = int(ratio * img.height()); RCT dst; xvt_rect_set(&dst, 0, 0, maxx, maxy); img.draw(win(), dst); } else { long sx = img.width() - (cli.right-cli.left); if (sx < 0) sx = 0; long sy = img.height() - (cli.bottom-cli.top); if (sy < 0) sy = 0; set_scroll_max(sx, sy); // Setta le scroll bar const TPoint orig = origin(); img.draw(win(), -int(orig.x), -int(orig.y)); } drawn = TRUE; } } } if (!drawn) { set_scroll_max(0, 0); // Toglie le scroll bar RCT cli; xvt_vobj_get_client_rect(win(), &cli); set_pen(COLOR_RED, 5); line(cli.right/4, cli.bottom/4, 3*cli.right/4, 3*cli.bottom/4); line(cli.right/4, 3*cli.bottom/4, 3*cli.right/4, cli.bottom/4); } } bool TGolem_window::on_key(KEY k) { if (k == K_SPACE) { TFilename file; get_current_file(file); if (file != _last_file) { #ifdef WIN32 // verificare if (_last_handle) { if (IsWindow(HWND(_last_handle))) ::SendMessage(HWND(_last_handle), WM_CLOSE, 0, 0); _last_handle = NULL; } #endif _last_file = file; if (!file.blank() && file.exist()) { const TString16 ext = file.ext(); if (ext != "BMP") { TFilename cmd; const char* good_ext[] = { "BAT", "COM", "DLL", "DOC", "EXE", "INI", "TXT", "WRI", "XLS", NULL }; for (int i = 0; good_ext[i]; i++) { if (ext == good_ext[i]) { #ifdef WIN32 // verificare ::GetSystemDirectory(cmd.get_buffer(), cmd.size()); cmd.add("viewers"); cmd.add("quikview.exe"); #endif break; } } if (!cmd.exist()) xvt_sys_find_editor(file, cmd.get_buffer()); if (cmd.not_empty()) { cmd << ' ' << file; _last_handle = xvt_sys_execute_in_window(cmd, win()); } } } force_update(); } } return TField_window::on_key(k); } void TGolem_window::handler(WINDOW win, EVENT* ep) { switch (ep->type) { case E_USER: switch (ep->v.user.id) { case E_DROP_FILES: if (driver()) { #ifdef WIN32 // verificare HDROP hdrop = (HDROP)(DWORD)ep->v.user.ptr; const int num_files = DragQueryFile(hdrop, -1, NULL, 0); // Numero totale di files TToken_string file_list(driver()->get(), '\n'); TFilename fname; // File corrente for (int i = 0; i < num_files; i++) { DragQueryFile(hdrop, i, (char*)(const char*)fname, fname.size()); fname << '|' << fname.name() << "|X"; if (driver()->roman()) { file_list.add(fname); } else { file_list = fname; break; } } DragFinish(hdrop); driver()->set(file_list); #endif on_key(K_SPACE); } break; default: break; } break; case E_MOUSE_DBL: on_key(K_SPACE); break; default: break; } TField_window::handler(win, ep); } TGolem_window::TGolem_window(int x, int y, int dx, int dy, WINDOW parent, TGolem_client_field* owner) : TField_window(x, y, dx, dy, parent, owner), _last_handle(0) { _pixmap = TRUE; #ifdef WIN32 // verificare HWND nat = (HWND)xvt_vobj_get_attr(win(), ATTR_NATIVE_WINDOW); DragAcceptFiles(nat, TRUE); #endif } TGolem_window::~TGolem_window() { #ifdef WIN32 // verificare if (_last_handle) PostMessage(HWND(_last_handle), WM_CLOSE, 0, 0); HWND nat = (HWND)xvt_vobj_get_attr(win(), ATTR_NATIVE_WINDOW); DragAcceptFiles(nat, FALSE); #endif } word TGolem_client_field::class_id() const { return CLASS_GOLEM_CLIENT_FIELD; } bool TGolem_client_field::is_kind_of(word cid) const { return cid == CLASS_GOLEM_CLIENT_FIELD || TWindowed_field::is_kind_of(cid); } TField_window* TGolem_client_field::create_window(int x, int y, int dx, int dy, WINDOW parent) { return new TGolem_window(x, y, dx, dy, parent, this); } bool TGolem_client_field::parse_item(TScanner& scan) { if (scan.key() == "DR") { TMask& m = mask(); const short driver = atodlg(scan.pop()); const int pos = m.id2pos(driver); if (pos >= 0) { _driver = (TGolem_field*)&m.fld(pos); TString16 msg; msg.format("PUSH,%d", dlg()); _driver->message(0, TRUE)->add(msg); } else yesnofatal_box("Non esiste il campo driver %d", driver); return TRUE; } return TWindowed_field::parse_item(scan); } bool TGolem_client_field::on_hit() { dispatch_e_char(win().win(), K_SPACE); return TWindowed_field::on_hit(); } TGolem_client_field::TGolem_client_field(TMask* m) : TWindowed_field(m), _driver(NULL) { } TGolem_client_field::~TGolem_client_field() { } #ifdef WIN32 // verificare /////////////////////////////////////////////////////////// // MAPI session /////////////////////////////////////////////////////////// class TMAPI_session : public TObject { HINSTANCE _hlibMAPI; LHANDLE _hSession; LONG _hWnd; TFilename m_strBaseDir; // Directory iniziale protected: bool load_mapi(); void unload_mapi(); public: operator LHANDLE() const { return _hSession; } LONG hWnd() const { return _hWnd; } bool open(); bool send(MapiMessage& msg, FLAGS flags = MAPI_DIALOG); bool remove(const TString& id); void close(); virtual bool ok() const { return _hlibMAPI != NULL && _hSession != NULL; } TMAPI_session(); virtual ~TMAPI_session(); }; const char* const szMAPIDLL = "MAPI32.DLL"; const int MAPI_USE_DEFAULT = 0; 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 TMAPI_session::load_mapi() { 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 error_box("MAPI non attivato nel file win.ini"); UINT fuError = SetErrorMode(SEM_NOOPENFILEERRORBOX); _hlibMAPI = LoadLibrary(szMAPIDLL); SetErrorMode(fuError); if (_hlibMAPI < (HINSTANCE)HINSTANCE_ERROR) { DWORD err = *((DWORD*)_hlibMAPI) & 0xFFFF; _hlibMAPI = NULL; return error_box("Errore di caricamento di %s: %lu", szMAPIDLL, err); } 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 TMAPI_session::unload_mapi() { if (_hlibMAPI) { FreeLibrary(_hlibMAPI); _hlibMAPI = NULL; } } bool TMAPI_session::open() { if (_hSession == NULL) { TWait_cursor hourglass; if (!load_mapi()) return error_box("Impossibile inizializzare MAPI"); FLAGS flags = MAPI_USE_DEFAULT | MAPI_LOGON_UI; ULONG err = lpfnMAPILogon(_hWnd, NULL, NULL, flags, 0L, &_hSession); if (err != SUCCESS_SUCCESS) return error_box("Impossibile collegarsi a MAPI: %lu", err); _hWnd = xvt_vobj_get_attr(cur_win(), ATTR_NATIVE_WINDOW); } return TRUE; } void TMAPI_session::close() { if (_hlibMAPI) { if (_hSession) { lpfnMAPILogoff(_hSession, _hWnd, 0L, 0L); _hSession = NULL; } unload_mapi(); } } bool TMAPI_session::send(MapiMessage& msg, FLAGS flags) { bool ok = FALSE; if (open()) { LONG err = lpfnMAPISendMail(_hSession, _hWnd, &msg, flags, 0L); if (err == SUCCESS_SUCCESS) ok = TRUE; else error_box("Can't send mail message: %ld", err); } return ok; } bool TMAPI_session::remove(const TString& id) { bool ok = FALSE; if (open()) { LONG err = lpfnMAPIDeleteMail(_hSession, _hWnd, (char*)(const char*)id, 0L, 0L); if (err == SUCCESS_SUCCESS) ok = TRUE; else error_box("Can't delete mail message: %ld", err); } return ok; } TMAPI_session::TMAPI_session() : _hlibMAPI(NULL), _hSession(NULL), _hWnd(NULL) { // Memorizza directory base GetCurrentDirectory(_MAX_PATH, m_strBaseDir.get_buffer(_MAX_PATH)); } TMAPI_session::~TMAPI_session() { close(); // Ripristina directory base SetCurrentDirectory(m_strBaseDir); } #endif /////////////////////////////////////////////////////////// // TMail_message /////////////////////////////////////////////////////////// int TMail_message::add_line(const char* s) { const long len = (s && *s) ? strlen(s) : 0; int n = items() - 1; if (n < 0 || (long(row(n).len()) + len) > 30000L) n = TString_array::add(""); TString & line = row(n); line << s; if (line.right(1) != "\n") line << '\n'; return n; } bool TMail_message::send(TMAPI_session& lhSession, bool hide_ui) { #ifdef WIN32 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(); nr++; } FOR_EACH_ARRAY_ROW(_copy_recipients, cc_rec, cc_recipient) { msgRecipient[nr].ulRecipClass = MAPI_CC; msgRecipient[nr].lpszName = cc_recipient->get_buffer(); nr++; } 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-> row(0) << tmp; msgAttachment[na].nPosition = row(0).len()-1; msgAttachment[na].lpszPathName = attachment->get_buffer(); na++; } MapiMessage msgSend; memset(&msgSend, 0, sizeof(MapiMessage)); long tot = 0; for (int i = 0; i < items(); i++) tot += row(i).len(); char * buffer = new char[tot + 1]; long b = 0; for (i = 0; i < items(); i++) { strcpy(&buffer[b], row(i)); b += row(i).len(); } buffer[b] = '\0'; msgSend.lpszNoteText = buffer; msgSend.lpszSubject = _subject.empty() ? NULL : _subject.get_buffer(); msgSend.nRecipCount = nr; msgSend.lpRecips = nr == 0 ? NULL : msgRecipient; msgSend.nFileCount = na; msgSend.lpFiles = na == 0 ? NULL : msgAttachment; bool ok = lhSession.send(msgSend, hide_ui ? 0 : MAPI_DIALOG); delete buffer; delete msgRecipient; delete msgAttachment; return ok; #else return TRUE; #endif } bool TMail_message::send(bool hide_ui) { #ifdef WIN32 //verificare TMAPI_session lhSession; // Open MAPI session return send(lhSession, hide_ui); #else return TRUE; #endif } bool TMail_message::remove(TMAPI_session& lhSession) { #ifdef WIN32 //verificare bool ok = _id.not_empty() && lhSession.remove(_id); return ok; #else return TRUE; #endif } bool TMail_message::remove() { #ifdef WIN32 //verificare TMAPI_session lhSession; // Open MAPI session return remove(lhSession); #else return TRUE; #endif } 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; } // Certified 99% void TMail_message::set_date_time(const char* str) { if (str == NULL) str = ""; int anno, mese, giorno; int ora = 12, minuto = 0, secondo = 0; const int num = sscanf(str, "%d/%d/%d %d:%d:%d", &anno, &mese, &giorno, &ora, &minuto, &secondo); if (num >= 3) { _date = TDate(giorno, mese, anno); _hms = ora*10000L + minuto*100L + secondo; } else { _date = TODAY; _hms = 0; } } // Certified 100% const TString& TMail_message::recipient(int n) const { if (n >= 0 && n < recipients()) return _recipients.row(n); return EMPTY_STRING; } TMail_message::TMail_message(const char* recipient, const char* subject, const char* text, const char* sender) : _subject(subject), _sender(sender), _hms(0) { add_recipient(recipient); if (text && *text) add(text); } /////////////////////////////////////////////////////////// // TMail_messages /////////////////////////////////////////////////////////// TMail_messages::TMail_messages() { } int TMail_messages::get(const char* senderFilter, const char* subjectFilter, const char* bodyFilter, bool attach, bool mark) { #ifdef WIN32 //verificare TMAPI_session lhSession; destroy(); if (!lhSession.open()) return 0; TString str_msg_id(512); // Accept MAPI_LONG_MSGID char* msg_id = str_msg_id.get_buffer(); TString str_msg_next(512); // Next MAPI message LONG err = lpfnMAPIFindNext(lhSession, lhSession.hWnd(), NULL, NULL, MAPI_GUARANTEE_FIFO | MAPI_LONG_MSGID, 0, msg_id); FLAGS flags = 0; if (!mark) flags |= MAPI_PEEK; if (!attach) flags |= MAPI_SUPPRESS_ATTACH; while (err == SUCCESS_SUCCESS) { MapiMessage FAR* pMessage = NULL; err = lpfnMAPIReadMail(lhSession, lhSession.hWnd(), msg_id, flags, 0, &pMessage); if (err == SUCCESS_SUCCESS) { const char* id = NULL; const char* sender = NULL; const char* subject = NULL; const char* body = NULL; const char* recipient = NULL; bool should_add = TRUE; if (should_add) { const MapiRecipDesc* pSender = pMessage->lpOriginator; sender = pSender->lpszName; if (senderFilter && *senderFilter) should_add = stricmp(senderFilter, sender) == 0; } if (should_add) { subject = pMessage->lpszSubject; if (subjectFilter && *subjectFilter) { const unsigned lenFilter = strlen(subjectFilter); should_add = strncmp(subject, subjectFilter, lenFilter) == 0; } } if (should_add) { body = pMessage->lpszNoteText; if (bodyFilter && *bodyFilter) should_add = strstr(body, bodyFilter) != NULL; // Toglie eventuale = finale derivante da cattiva traduzione quoted-printable char* tail = pMessage->lpszNoteText + strlen(body)-2; if (tail[0] == '\n' && tail[1] == '=') *tail = '\0'; } if (should_add) { TMail_message* msg = new TMail_message(recipient, subject, body, sender); msg->set_date_time(pMessage->lpszDateReceived); msg->set_id(msg_id); add(msg); } lpfnMAPIFreeBuffer(pMessage); } err = lpfnMAPIFindNext(lhSession, lhSession.hWnd(), NULL, msg_id, MAPI_LONG_MSGID, 0, str_msg_next.get_buffer()); str_msg_id = str_msg_next; } return items(); #else return 0; #endif } bool TMail_messages::send(bool hide_ui) { #ifdef WIN32 //verificare TMAPI_session lhSession; bool ok = TRUE; for (int i = 0; i < items(); i++) ok &= msg(i).send(lhSession, hide_ui); return ok; #else return TRUE; #endif } bool TMail_messages::remove() { #ifdef WIN32 //verificare TMAPI_session lhSession; bool ok = TRUE; for (int i = 0; ok && i < items(); i++) ok &= msg(i).remove(lhSession); return ok; #else return TRUE; #endif }