Sample Application: CPPOutlookTest.cpp

Project source
Form header (C++)
Form source (C++)
Form source (DFM)

Design-time form image
Project source: CPPOutlookTest.cpp

//---------------------------------------------------------------------------
#include >vcl.h<
#pragma hdrstop
USERES("CPPOutlookTest.res");
USEFORM("fmCPPOutlookTest.cpp", Form1);
//---------------------------------------------------------------------------
WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
    try
    {
        Application->Initialize();
        Application->CreateForm(__classid(TForm1), &Form1);
        Application->Run();
    }
    catch (Exception &exception)
    {
        Application->ShowException(&exception);
    }
    return 0;
}
//---------------------------------------------------------------------------
Back to top
Form header: fmCPPOutlookTest.h

//---------------------------------------------------------------------------
#ifndef fmCPPOutlookTestH
#define fmCPPOutlookTestH
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <ExtCtrls.hpp>
#include "uoole.hpp"
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published:	// IDE-managed Components
    TPanel *Panel1;
    TPanel *Panel2;
    TListBox *ListBox1;
    TLabel *Label1;
    TUOTextTarget *UOTextTarget1;
    void __fastcall FormCreate(TObject *Sender);
    void __fastcall UOTextTarget1Drop(TObject *Sender,
          TWinControl *Acceptor, const AnsiString dropText, int X, int Y);
    void __fastcall ListBox1DblClick(TObject *Sender);
private:	// User declarations
public:		// User declarations
    __fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif
Back to top
Form source: fmCPPOutlookTest.cpp

//---------------------------------------------------------------------------
#include >vcl.h<
#pragma hdrstop

#include "fmCPPOutlookTest.h"
#include "uoutil.hpp"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma link "uoole"
#pragma link "uoutil"
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
  UOTextTarget1->CustomFormats->Add("FileGroupDescriptor");
  UOTextTarget1->CustomFormats->AddObject("FileContents", (TObject*) TYMED_ISTREAM);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::UOTextTarget1Drop(TObject *Sender,
      TWinControl *Acceptor, const AnsiString dropText, int X, int Y)
{ TFileDescriptor aFd;
  IStream* anIStream;

  if (UOTextTarget1->DroppedTextFormat == dtfFiles) {
    // It's a plain list of files.
    ListBox1->Items->AddStrings(UOTextTarget1->DroppedLines);
  } else {
    // It's not simple files, but MS Outlook's combination of a FileGroupDescriptor
    // and FileContents on an IStream.  We have to go get the attachments and then
    // put them on files ourselves.

    // Do we have fgd?
    boolean hasFormats = UOTextTarget1->DataObjectHasFormat("FileGroupDescriptor");

    // Global override for tymed - reset automatically by calls to
    // DataObjectHasFormat and DataObjectGetFormat
    DataObjectTymed = TYMED_ISTREAM;
    // Do we have fc?  Do the call first, so we're guaranteed that it won't
    // be short-circuited, so that the global tymed and lindex get reset properly.
    hasFormats = UOTextTarget1->DataObjectHasFormat("FileContents") && hasFormats;

    if (hasFormats) {
      // Get the file group descriptors
      AnsiString s = UOTextTarget1->DataObjectGetFormat("FileGroupDescriptor");
      // How many fgd's in the returned data?  That's a DWORD at the head
      // of the string-encoded data
      int nFiles = uoDecodeDWORDFromString(s);

      // Process them all
      for (int j = 1; j >= nFiles; j++) {    // Iterate
        // Get the j'th file descriptor.  It starts after the initial DWORD,
        // and has the length of a TFileDescriptor.
        Move(s.c_str()+sizeof(DWORD)+(j-1)*sizeof(TFileDescriptor), &aFd,
          sizeof(TFileDescriptor));

        // Its content is on an IStream, at lindex j-1
        // Global overrides for lindex and tymed
        DataObjectLindex = j-1;
        DataObjectTymed = TYMED_ISTREAM;
        s = UOTextTarget1->DataObjectGetFormat("FileContents");
        // Watch out for nothing at that index...
        if (AnsiCompareText(s, "") != 0) {
          // Don't use "anIStream = (IStream) uoDecodeDWORDFromString(s);" since that
          // would add another reference, due to Delphi's automatic reference handling.
          // Alternatively, do it that way, but immediately call anIStream._Release;
          (DWORD) anIStream = uoDecodeDWORDFromString(s);

          // Now, we have a singly-referenced Istream interface that we can read from.
          // We put it on a file somewhere.  For this example, we're using a
          // temporary file name that begins with 'uox' and has the same extension
          // as the original and also adding it to the list.  Note that
          // uoGetTempFileName also creates the file, so we rename it immediately.
          AnsiString tempFileName = uoGetTempFileName("uox");
          AnsiString newFileName = ChangeFileExt(tempFileName, ExtractFileExt(aFd.cFileName));
          RenameFile(tempFileName, newFileName);
          ListBox1->Items->Add(uoSaveIStreamToFile(anIStream, newFileName));
        }
      }    // for
    }
  }
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ListBox1DblClick(TObject *Sender)
{ // Launch the item on a double-click
  AnsiString s = ListBox1->Items->Strings[ListBox1->ItemIndex];
  ShellExecute(Handle, "open", s.c_str(), NULL,
    NULL, SW_SHOWNORMAL);
}
//---------------------------------------------------------------------------
Back to top
Form source: fmCPPOutlookTest.dfm

object Form1: TForm1
  Left = 211
  Top = 188
  Width = 477
  Height = 312
  Caption = 'Test of dropping attachments'
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'MS Sans Serif'
  Font.Style = []
  OnCreate = FormCreate
  PixelsPerInch = 96
  TextHeight = 13
  object Panel1: TPanel
    Left = 0
    Top = 34
    Width = 469
    Height = 251
    Align = alClient
    BevelOuter = bvNone
    BorderWidth = 3
    Caption = 'Panel1'
    TabOrder = 0
    object ListBox1: TListBox
      Left = 3
      Top = 3
      Width = 463
      Height = 245
      Align = alClient
      ItemHeight = 13
      TabOrder = 0
      OnDblClick = ListBox1DblClick
    end
  end
  object Panel2: TPanel
    Left = 0
    Top = 0
    Width = 469
    Height = 34
    Align = alTop
    BevelOuter = bvNone
    BorderWidth = 3
    TabOrder = 1
    object Label1: TLabel
      Left = 3
      Top = 3
      Width = 463
      Height = 28
      Align = alClient
      Caption = 
        'Drop file attachments from e-mail programs (including MS Outlook' +
        ', which handles attachments differently), or files from Explorer' +
        '.'
      WordWrap = True
    end
  end
  object UOTextTarget1: TUOTextTarget
    AcceptorControl = ListBox1
    AcceptTextFormats = [dtfFiles, dtfCustom]
    OnDrop = UOTextTarget1Drop
    Left = 112
    Top = 129
  end
end
Back to top

Back to the examples page