controls.cpp Implementati 'outline' alcuni metodi inline controls.h Eliminato include <xi.h> ed aggiunto include <xvt_type.h> execp.cpp Tolti due include inutili <string.h> e <ctypes.h> golem.cpp Sostituita xi_invalidate_rect con xvt_dwin_invalidate_rect msksheet.cpp Sostituito <xi.h> con <xinclude.h> progind.cpp Eliminata dipendenza da <xi.h> sheet.cpp Aggiunto include <xinclude.h> viswin.cpp Sostituito XI_FU_MULTIPLE con 8 (Distanza dei bottoni dal fondo) window.cpp Sostituito <xi.h> con <xinclude.h> xinclude.h Includitore automagico di <xi.h> con relative #define git-svn-id: svn://10.65.10.50/trunk@5807 c028cbd2-c16b-5b4b-a496-9718f37d4682
		
			
				
	
	
		
			1046 lines
		
	
	
		
			27 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			1046 lines
		
	
	
		
			27 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;
 | 
						|
  
 | 
						|
  // Non so se questo debba rimanere
 | 
						|
  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(".msg");
 | 
						|
  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 edit_url(const char* url)
 | 
						|
{
 | 
						|
  bool retflag = FALSE;
 | 
						|
  
 | 
						|
  HINSTANCE hinst = ShellExecute(NULL, "edit", url, NULL, NULL, SW_SHOWNORMAL);
 | 
						|
  DWORD winst = DWORD((DWORD*)hinst);
 | 
						|
  UINT error = UINT(winst);  // Tutto 'sto giro per evitare un warning
 | 
						|
  if (error <= 32)
 | 
						|
  {                   
 | 
						|
    TFilename app;
 | 
						|
    if (fexist(url) && file2app(".wri", app))
 | 
						|
    {
 | 
						|
      app << ' ' << url;
 | 
						|
      error = WinExec(app, SW_SHOWNORMAL);
 | 
						|
      if (error > 32)
 | 
						|
        retflag = TRUE;
 | 
						|
    }
 | 
						|
    else
 | 
						|
      retflag = goto_url(url);
 | 
						|
  }
 | 
						|
  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);
 | 
						|
  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 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(), '\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);
 | 
						|
      }
 | 
						|
    }
 | 
						|
    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;
 | 
						|
  }
 | 
						|
}
 | 
						|
 |