unit FMAddress;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  GradForm, ShellApi, ClipBrd,ComObj,
  Menus, ComCtrls, FMEditAdr, ExtCtrls, Buttons, ParserSup, PXStuff,
  ImgList, StdCtrls, ComboBoxEx, FMSelBook, EnhListView, ExtListView, Registry,
  FMSearch, IniFiles, TB97Tlbr, TB97Ctls, TB97, ActnList, WabDefs, WabApi, WabIab,ToolWin;

type
  TAddressForm = class(TdfsGradientForm)
    MainMenu1: TMainMenu;
    menAddress: TMenuItem;
    menNew: TMenuItem;
    Delete1: TMenuItem;
    N1: TMenuItem;
    Edit1: TMenuItem;
    PopupMenu1: TPopupMenu;
    PopMenDeleteAddress: TMenuItem;
    StatusBar1: TStatusBar;
    N3: TMenuItem;
    N4: TMenuItem;
    ImageList1: TImageList;
    Search1: TMenuItem;
    N5: TMenuItem;
    Book1: TMenuItem;
    New2: TMenuItem;
    Delete2: TMenuItem;
    SelectAllAddresses1: TMenuItem;
    Rename1: TMenuItem;
    Movetoanotherbook1: TMenuItem;
    N6: TMenuItem;
    AdrBookListView: TdfsExtListView;
    imlToolbar: TImageList;
    ActionList1: TActionList;
    actFileClose: TAction;
    actAddressNew: TAction;
    actAddressDelete: TAction;
    actAddressWriteTo: TAction;
    actAddressSelectAll: TAction;
    actAddressMoveTo: TAction;
    actAddressSearch: TAction;
    actAddressEdit: TAction;
    actBookNew: TAction;
    actBookDelete: TAction;
    actBookRename: TAction;
    actHelpContents: TAction;
    actUpdateStatusbar: TAction;
    actBookClose: TAction;
    Hilfe1: TMenuItem;
    Contents1: TMenuItem;
    N9: TMenuItem;
    OpenDialog1: TOpenDialog;
    SaveDialog1: TSaveDialog;
    Speichernunter1: TMenuItem;
    SaveDialog2: TSaveDialog;
    N10: TMenuItem;
    N11: TMenuItem;
    InfoszudieserVersion1: TMenuItem;
    actAddressCopyTo: TAction;
    InanderesAdressbuchkopieren1: TMenuItem;
    Extras1: TMenuItem;
    FindToday: TMenuItem;
    N12: TMenuItem;
    Markierungumkehren1: TMenuItem;
    N13: TMenuItem;
    Adressbuchschlieen1: TMenuItem;
    N15: TMenuItem;
    berPhoenixMail1: TMenuItem;
    PopMenAdressebearbeiten: TMenuItem;
    actVNEcopy: TAction;
    N16: TMenuItem;
    VNEcopy: TMenuItem;
    VNPcopy: TMenuItem;
    actVNPcopy: TAction;
    PMListPrint: TMenuItem;
    actBookPhoenix: TAction;
    ToolBar1: TToolBar;
    ToolbarButton972: TToolButton;
    ToolbarButton971: TToolButton;
    btnDelete: TToolButton;
    ImageListEnable: TImageList;
    ComboBox1: TPMComboBoxEx;
    ImageListDisable: TImageList;
    TreeView1: TTreeView;
    Splitter1: TSplitter;
    ImageList2: TImageList;
    menNewGroup: TMenuItem;
    menProperty: TMenuItem;
    menDelete: TMenuItem;
    menExport: TMenuItem;
    menImport: TMenuItem;
    N7: TMenuItem;
    menExit: TMenuItem;
    menEdit: TMenuItem;
    menCopy: TMenuItem;
    P1: TMenuItem;
    N8: TMenuItem;
    menSelectAll: TMenuItem;
    N14: TMenuItem;
    memFind: TMenuItem;
    ToolButton1: TToolButton;
    ToolButton2: TToolButton;
    ToolButton3: TToolButton;
    PopMen: TPopupMenu;
    C1: TMenuItem;
    F1: TMenuItem;
    popMemNew: TMenuItem;
    PopMenConnect: TMenuItem;
    PopMenNewFold: TMenuItem;
    N17: TMenuItem;
    P2: TMenuItem;
    F2: TMenuItem;
    WAB1: TMenuItem;
    OpenDialog: TOpenDialog;
    N2: TMenuItem;
    procedure FormShow(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure ComboBox1Change(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure AdrBookListViewDrawHeader(Control: TWinControl;
      var ACanvas: TCanvas; Index: Integer; var ARect: TRect;
      Selected: Boolean; var DefaultDrawing: Boolean);
    procedure actFileCloseExecute(Sender: TObject);
    procedure actAddressNewExecute(Sender: TObject);
    procedure actAddressDeleteExecute(Sender: TObject);
    procedure actAddressEditExecute(Sender: TObject);
    procedure actAddressSearchExecute(Sender: TObject);
    procedure actAddressMoveToExecute(Sender: TObject);
    procedure actAddressWriteToExecute(Sender: TObject);
    procedure actHelpContentsExecute(Sender: TObject);
    procedure actAddressSelectAllExecute(Sender: TObject);
    procedure actAddressDeleteUpdate(Sender: TObject);
    procedure actAddressWriteToUpdate(Sender: TObject);
    procedure actAddressMoveToUpdate(Sender: TObject);
    procedure actAddressEditUpdate(Sender: TObject);
    procedure actUpdateStatusbarUpdate(Sender: TObject);
    procedure actBookNewExecute(Sender: TObject);
    procedure actBookDeleteExecute(Sender: TObject);
    procedure actBookRenameExecute(Sender: TObject);
    procedure actBookDeleteUpdate(Sender: TObject);
    procedure actBookRenameUpdate(Sender: TObject);
    procedure AdrBookListViewKeyUp(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    procedure actBookCloseExecute(Sender: TObject);
    procedure Importieren1Click(Sender: TObject);
    procedure Exportieren1Click(Sender: TObject);
    procedure Speichernunter1Click(Sender: TObject);
    procedure InfoszudieserVersion1Click(Sender: TObject);
    procedure actAddressCopyToExecute(Sender: TObject);
    procedure actAddressCopyToUpdate(Sender: TObject);
    procedure FindTodayClick(Sender: TObject);
    procedure SelectOneType(TheType: Integer);
    procedure SelectPrivateClick(Sender: TObject);
    procedure SelectBizzClick(Sender: TObject);
    procedure SelectOrgClick(Sender: TObject);
    procedure SelectFriendsClick(Sender: TObject);
    procedure SelectLoveClick(Sender: TObject);
    procedure Markierungumkehren1Click(Sender: TObject);
    procedure berPhoenixMail1Click(Sender: TObject);
    procedure actVNEcopyUpdate(Sender: TObject);
    procedure actVNEcopyExecute(Sender: TObject);
    procedure actVNPcopyUpdate(Sender: TObject);
    procedure actVNPcopyExecute(Sender: TObject);
    procedure PMListPrintClick(Sender: TObject);
    procedure actBookPhoenixExecute(Sender: TObject);
    procedure TreeView1Click(Sender: TObject);
    procedure menDeleteClick(Sender: TObject);
    procedure menImportClick(Sender: TObject);
    procedure menExportClick(Sender: TObject);
    procedure menExitClick(Sender: TObject);
    procedure TreeView1Change(Sender: TObject; Node: TTreeNode);
    procedure btnDeleteClick(Sender: TObject);
    procedure AdrBookListViewExit(Sender: TObject);
    procedure AdrBookListViewClick(Sender: TObject);
    procedure AdrBookListViewChange(Sender: TObject; Item: TListItem;
      Change: TItemChange);
    procedure WAB1Click(Sender: TObject);
    procedure N2Click(Sender: TObject);
  private
    { Private declarations }
    MailOK: Boolean;
    Filename: string;

    FFileName: TFileName;
    FLastDetails: PSPropsArray;
    FLastDetailsCount: Integer;
    FLastDetailID: PSBinary;
    AddrBook: IAddrBook;
    WabObject: IWabObject;


    function ToAddressFormat(AddressLst: TstringList):string;
    function ToOldAddressFormat(I1: Integer; S1, S2, S3, S4, S5, S6: string):
      string;
    procedure LoadAddressBook;
    function ImportOldAdressBook(OldFileName: string): Integer;
    function ImportOutlookBook(OutFileName: string): Integer;
    procedure SaveAddressBook;
    procedure ExportNewAdressBook;
    function MakeClipBoardString(wie: word): string;
  public
    { Public declarations }
    RootNode,Node:TTreeNode;
    function GetSelAddresses: string;
    function SetAddress(S: string): Boolean;
    function SetAddressSilent(S: string): boolean;
    function IsUniqueAddress(S: string): boolean;
    procedure MoveCopyAddress(bMoveAddress : boolean);
    procedure UpdateTreeview;

    ///////////////////import address from wab  /////////////////////
    procedure ClearLastDetails;
    procedure CloseWabFile;
    procedure CreateNewEntry(ulObjectType: ULONG);
    procedure DeleteEntry(EntryIDData: PSBinary);
    procedure FreeSBinary(var P: PSBinary);
    procedure FreeSRowSet(var P: PSRowSet);
    function HrGetWABTemplateID(ulObjectType: ULONG; var lpcbEID: ULONG;
      var lppEID: PEntryId): HResult;
    procedure LoadItems(RememberSelected: Boolean);
    procedure OpenCopyOfFileName(const FileName: TFileName; CreateCopy: Boolean);
    procedure OpenWabFile(const FileName: TFileName);
    procedure ReadDetails(EntryIDData: PSBinary);
    function SetCurrentPropValue: Boolean;
    ///////////////////import address from wab  /////////////////////

  end;
var
  AddressForm: TAddressForm;

implementation

{$R *.DFM}

uses
   ELVSup, WabTags, WabCode;

var
  F: Text;

const
  pabmodified: Boolean = false;



function SPropValueToStr(PropValue: TSPropValue): string;
var
  LT: TFileTime;
  ST: TSystemTime;
begin
  with PropValue do
    case PROP_TYPE(ulPropTag) of
      PT_TSTRING:
        Result := Value.lpszA;
      PT_BINARY:
        if Value.bin.cb = 4 then
          Result := Format('[Binary - Size: %d bytes] (%.8x)', [Value.bin.cb, PDWORD(Value.bin.lpb)^])
        else
          Result := Format('[Binary - Size: %d bytes]', [Value.bin.cb]);
      PT_I2:
        Result := IntToStr(Value.i);
      PT_LONG:
        Result := IntToStr(Value.l);
      PT_R4:
        Result := FloatToStr(Value.flt);
      PT_DOUBLE:
        Result := FloatToStr(Value.dbl);
      PT_BOOLEAN:
        Result := IntToStr(Value.b);
      PT_SYSTIME:
        begin
          FileTimeToLocalFileTime(Value.ft, LT);
          FileTimeToSystemTime(LT, ST);
          Result := DateTimeToStr(SystemTimeToDateTime(ST));
        end;
      PT_ERROR:
        Result := '';
    else
      Result := Format('[Unknown type %x]', [PROP_TYPE(ulPropTag)]);
    end;
end;


procedure TAddressForm.MoveCopyAddress(bMoveAddress : boolean);
var
  S: string;
  I, E: Integer;
begin
{  SelBookForm := TSelBookForm.Create(Self);
  if Assigned(LangHolder) then
  begin
    if LangHolder.Language <> '' then
      LangHolder.Translate([SelBookForm]);
  end;

  // AH08
  if bMoveAddress then SelBookForm.LabelAction.Caption := GetMessageString(101) else
    SelBookForm.LabelAction.Caption := GetMessageString(102);
  if SelBookForm.ShowModal = mrOK then begin
    pabmodified := true;

    //S := FileName;
    S := SelBookForm.Combobox1.Values[SelBookForm.ComboBox1.ItemIndex];
    AssignFile(F, S);
    Append(F);
    E := AdrBookListView.Items.Count - 1;
    I := 0;
    while I <= E do begin
      with AdrBookListView.Items[I] do begin
        if Selected then begin
          S := ToAddressFormat(ImageIndex,
            SubItems[0], SubItems[1],
            SubItems[3], SubItems[6],
            SubItems[4], SubItems[5], SubItems[2]);
          WriteLn(F, S);
          if bMoveAddress then
          begin
            Delete;
            Dec(E);
            Dec(I);
          end;
        end;
      end;
      Inc(I);
    end;
    CloseFile(F);
  end;
  SelBookForm.Free;}
end;

function TAddressForm.ToAddressFormat(AddressLst: TstringList):string;
var
  sTemp:string;
  i:integer;
begin
  sTemp:=trim(AddressLst.Strings[0]);
  sTemp:=sTemp+chr(30)+Trim(AddressLst[31]);
  for i:=2 to i-2 do
  begin
    sTemp:=sTemp+chr(30)+Trim(AddressLst[i]);
  end;
  Result := sTemp;
end;

function TAddressForm.ToOldAddressFormat(I1: Integer; S1, S2, S3, S4, S5, S6:
  string): string;
var sName: string;
  itype: Integer;
begin
  //Type,Description,Name,E-Mail,Phone,Address
  iType := I1;
  if not iType in [0..4] then iType := 0;
  sName := TrimLeft(S1 + #32 + S2);
  Result := IntToStr(iType) + ',' + sName + ',' + S3 + ',' + S4 + ',' + S5
    + ',' + S6;
end;


function TAddressForm.SetAddress(S: string): Boolean;
var
  MailName: string;
  p: integer;
begin
  if AdrBookListView.Items.Count = 0 then
    LoadAddressBook;
  EditAdrForm := TEditAdrForm.Create(Self);
  with EditAdrForm do begin
    try
      CheckUnique := True;
      Caption := GetMessageString(40);
//      ComboboxEx1.ItemIndex := 0;
//      ComboBox1.ItemIndex := Self.Combobox1.ItemIndex;
      MailName := ExtractEMailName(S);
      p := Pos(' ', MailName);
      if p > 0 then begin
//        EditVorname.Text := Copy(MailName, 1, p - 1);
//        EditName.Text := Copy(MailName, p + 1, Length(MailName) - p);
      end
      else
//        EditVorname.Text := MailName;
//      EditEMail.Text := ExtractEMailAddress(S);
      if ShowModal = mrOK then begin
        pabmodified := true;
        SaveAddressBook;
        AssignFile(F, Combobox1.Values[Combobox1.ItemIndex]);
        Append(F);

{        S := ToAddressFormat(ComboboxEx1.ItemIndex,
          EditVorname.Text, EditName.Text, EditEMail.Text,
          EditPost.Text, EditTel.Text, EditDatum.Text, EditBemerkung.Text);   }
        WriteLn(F, S);
        CloseFile(F);
        LoadAddressBook;
      end;
    finally
      Free;
    end;
  end;
  Result := True;
end;

function TAddressForm.SetAddressSilent(S: string): Boolean;
var
  EName, EAddress, FirstName, LastName: string;
  p: integer;
begin
{  Result := False;
  if Combobox1.Items.Count = 0 then begin
    MessageDlg(GetMessageString(39), mtwarning, [mbOK], 0);
    Exit;
  end;

  if AdrBookListView.Items.Count = 0 then
    LoadAddressBook;

  EName := ExtractEMailName(S);
  EAddress := ExtractEMailAddress(S);
  if not IsUniqueAddress(EAddress) then
    Exit;
  p := Pos(' ', EName);
  if p > 0 then begin
    FirstName := Copy(EName, 1, p - 1);
    LastName := Copy(EName, p + 1, Length(EName) - p);
  end
  else
    FirstName := EName;
  pabmodified := true;
  SaveAddressBook;
  AssignFile(F, Combobox1.Values[Combobox1.ItemIndex]);
  Append(F);
  S := ToAddressFormat(0, FirstName, LastName, EAddress, '', '', '', '');
  WriteLn(F, S);
  CloseFile(F);
  LoadAddressBook;
  Result := true;}
end;

function TAddressForm.IsUniqueAddress(S: string): boolean;
var
  i: integer;
begin
  Result := true;
  with AdrBookListView do begin
    for I := 0 to Items.Count - 1 do
      if CompareText(Items[I].SubItems[3], S) = 0 then begin
        Result := false;
        Exit;
      end;
  end;
end;

function TAddressForm.GetSelAddresses: string;
var
  SL: TStringList;
  I: Integer;
begin
  SL := TStringList.Create;
  with AdrBookListView do
  begin
    for I := 0 to Items.Count - 1 do
      if Items[I].Selected then
        SL.Add(Trim(Items[I].SubItems[0] + ' ' +
         Items[I].SubItems[1]) + ' <' + Items[I].SubItems[3] + '>');
  end;
  Result := StringListToCommataString(SL, False);
  SL.Free;
end;

procedure TAddressForm.LoadAddressBook;
var
  Item: TListItem;
  i,j: Integer;
  s,tempStr:string;
begin
  if Filename = '' then
    Exit;
  if FileExists(Filename) = False then
  begin
    AdrBookListView.Items.Clear;
    Exit;
  end;
  AdrBookListView.BeginUpdate;
  AdrBookListView.Items.Clear;
  AssignFile(F, Filename);
  Reset(F);
  ReadLn(F, S);
  while not EoF(F) do begin
    ReadLn(F, S);
    if S <> '' then
    begin
      AddressInfo.Clear;
      FromAddressFormat(S, AddressInfo);
      Item := AdrBookListView.Items.Add;

      j:=Pos(',',AddressInfo.Strings[1]);
      if j>0 then tempStr:=copy(AddressInfo.Strings[1],1,j-1) else tempStr:=AddressInfo.Strings[1];
      with Item.SubItems do begin
        for i:=0 to AddressInfo.Count-1 do
        begin
          if i=1 then Add(tempStr) else
          Add(AddressInfo.Strings[i]);
        end;
        Add(AddressInfo.Strings[1]);
      end;
    end;
  end;
  CloseFile(F);
  AdrBookListView.Resort;
  AdrBookListView.EndUpdate;
end;

function TAddressForm.ImportOldAdressBook(OldFileName: string): Integer;
var
  Item: TListItem;
  S, S1, S2, S3, S4, S5: string;
  count0, count1, I1: Integer;
begin
  Result := 0;
  if Filename = '' then
    Exit;
  if FileExists(OldFilename) = False then
    Exit;
  Count0 := AdrBookListView.Items.Count - 1;
  AdrBookListView.BeginUpdate;
  AssignFile(F, OldFilename);
  Reset(F);
  ReadLn(F, S);
  S := uppercase(s);
  if pos('SMAIL', s) = 0 then
  begin
    Result := 0;
    CloseFile(F);
    exit;
  end;
  ReadLn(F, S); //two empty lines
  while not EoF(F) do begin
    ReadLn(F, S);
//  FirstName,LastName,E-Mail,Address,Phone,Description
//  Description,Name,E-Mail,Phone,Address
    if S <> '' then
    begin
      FromOldAddressFormat(S, I1, S1, S2, S3, S4, S5);
      Item := AdrBookListView.Items.Add;
      Item.ImageIndex := I1;
      with Item.SubItems do
      begin
        Add(''); //S1 Name
        Add(S1); //Name
        Add(S2); //E-Mail
        Add(S3); //Address
        Add(S4); //Phone
        Add('');
        Add(S5); //Desc.
      end;
    end;
  end;
  CloseFile(F);
  AdrBookListView.Resort;
  AdrBookListView.EndUpdate;
  Count1 := AdrBookListView.Items.Count - 1;
  Result := Count1 - Count0;
end;

function TAddressForm.ImportOutlookBook(OutFileName: string): Integer;
var
  Item: TListItem;
  S: string;
  count0, count1, I1: Integer;
begin
{  Result := 0;
  if Filename = '' then
    Exit;
  if FileExists(OutFilename) = False then
    Exit;
  Count0 := AdrBookListView.Items.Count - 1;
  AdrBookListView.BeginUpdate;
  AssignFile(F, OutFilename);
  Reset(F);
  ReadLn(F, S); //one header line
  while not EoF(F) do begin
    ReadLn(F, S);
//  FirstName,LastName,E-Mail,Address,Phone,Description
//  Description,Name,E-Mail,Phone,Address
    if S <> '' then
    begin
      S := '0;' + S;
      FromAddressFormat(S, I1, V1, N2, E3, P4, T5, D6, B7);
      Item := AdrBookListView.Items.Add;
      Item.ImageIndex := I1;
      with Item.SubItems do begin
        Add(V1); //Vorname1         Vorname S1
        Add(N2); //Name2            Name S2
        Add(B7); //Beschreibung3    E-Mail S3
        Add(E3); //E-Mail4          Post S4
        Add(T5); //Telefon5         Telefon S5
        Add(D6); //                 Datum
        Add(P4); //Post6            Beschreibung S6
      end;
    end;
  end;
  CloseFile(F);
  AdrBookListView.Resort;
  AdrBookListView.EndUpdate;
  Count1 := AdrBookListView.Items.Count - 1;
  Result := Count1 - Count0;}
end;



procedure TAddressForm.SaveAddressBook;
var
  I,J: Integer;
  S: string;
begin
  if Filename = '' then
    Exit;
  if not pabmodified then exit;
  AssignFile(F, Filename);
  Rewrite(F);

  WriteLn(F, 'EdtName;LstBoxEmail;EdtPhoOne2;EdtPhoOne;EdtPhone;EdtP;EdtSicq;EdtIcq;CmbBoxSex;DateTimePicker1;MemoFond'+
  ';EdtHttp;EdtCountry;EdtProvince;EdtCity;EdtPost;EdtPhoTwo;EdtFax;EdtRoad;EdtCorp;EdtCountry2;EdtProvince2;EdtCity2;EdtPost2'+
  ';EdtJob;EdtDepartment;EdtPhoTwo2;EdtFax2;EdtRoad2;EdtHttp2;MemoAttach');  //30
  for I := 0 to AdrBookListView.Items.Count - 1 do begin
    AddressInfo.Clear;
    with AdrBookListView.Items[I] do begin
      for J:=0 to SubItems.Count-1 do begin
        AddressInfo.Add(SubItems[j]);
      end;
      S := ToAddressFormat(AddressInfo);
    end;
    WriteLn(F, S);
  end;
  CloseFile(F);
  pabmodified := false;
end;

procedure TAddressForm.ExportNewAdressBook;
var
  I: Integer;
  S: string;
begin
  if Filename = '' then
    Exit;
  if not SaveDialog1.Execute then exit;

  AssignFile(F, SaveDialog1.Filename);
  Rewrite(F);
  WriteLn(F, 'Smail - Copyright 2003');
  WriteLn(F, 'Type,Description,Name,E-Mail,Phone,Address');
  for I := 0 to AdrBookListView.Items.Count - 1 do begin
    with AdrBookListView.Items[I] do begin
      S := ToOldAddressFormat(ImageIndex,
        SubItems[0], SubItems[1],
        SubItems[2], SubItems[3],
        SubItems[4], SubItems[6]);
    end;
    WriteLn(F, S);
  end;
  CloseFile(F);

  s := Format(GetMessageString(98), [IntToStr(AdrBookListView.Items.Count)]);
  MessageBox(Handle, PChar(s), 'Exportieren', mb_IconInformation);
end;

procedure TAddressForm.FormShow(Sender: TObject);
var
  I: Integer;
begin
  SetWindowLong(Handle, GWL_ExStyle, WS_Ex_AppWindow); //Icon in Taskbar
  pabmodified := false;
  if bFlatStyle then
    AdrBookListView.ExtendedStyles := AdrBookListView.ExtendedStyles + [lvxFlatScrollbar] else
    AdrBookListView.ExtendedStyles := AdrBookListView.ExtendedStyles - [lvxFlatScrollbar];

  if AdrBookListView.Items.Count = 0 then
    LoadAddressBook;
  AdrBookListView.Selected := nil;
  for I := 0 to AdrBookListView.Items.Count - 1 do
    AdrBookListView.Items[I].Selected := False;
  MailOK := False;
  Application.ProcessMessages;
  if Neuer_Kontakt then actAddressNewExecute(self);
  if bSearchName then actAddressSearchExecute(self);
  if bSearchDate then actAddressSearchExecute(self);
end;

procedure TAddressForm.FormCreate(Sender: TObject);
var
  i, j, Found, e: Integer;
  SearchRec: TSearchRec;
  IniFile: TIniFile;
  S: string;
  aColumns : array [0..7] of integer;
begin
  if not WabApiLoaded then
    raise Exception.Create('Error loading WAB API');

  ImageList1.ResourceLoad(rtBitmap, 'PX502', clFuchsia);
  Filename := '';

  with TreeView1.Items do
  begin
    RootNode:=add(nil,'地址薄');
    RootNode.ImageIndex:=2;
    RootNode.SelectedIndex:=2;
  end;

  Found := FindFirst(sAddressBookFolder + '*.ssf', faAnyFile, SearchRec);
  while Found = 0 do
  begin
    s := SearchRec.Name;
    SetFileAttr(sAddressBookFolder + SearchRec.Name, False, True, False, False);
    Delete(s, Length(s) - 3, 4);
    with TreeView1.Items do
    begin
      Node:=AddChild(RootNode,s);
      Node.ImageIndex:=1;
      Node.SelectedIndex:=0;
    end;
    Found := FindNext(SearchRec);
  end;
  FindClose(SearchRec);
end;

procedure TAddressForm.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  SaveAddressBook;
  if menSearchForm <> nil then menSearchForm.Close;
  if MailOK then
    ModalResult := mrOK
  else
    ModalResult := mrCancel;
end;

procedure TAddressForm.ComboBox1Change(Sender: TObject);
begin
  if ComboBox1.ItemIndex = -1 then begin
    Filename := '';
    Exit;
  end;
  SaveAddressBook;
  Filename := ComboBox1.Values[ComboBox1.ItemIndex];
  LoadAddressBook;
end;

procedure TAddressForm.FormDestroy(Sender: TObject);
var
  IniFile: TIniFile;
  aColumns : array[0..7] of Integer;
  x : integer;
  s : string;
begin
  CloseWabFile;
{  IniFile := TIniFile.Create(sSettingsFile);
  AdrBookListView.GetColumnOrder(8, aColumns);
    for x := Low(aColumns) to High(aColumns) do
        begin
        s := s + IntToStr(aColumns[x]) + ',';
        end;
  SetLength(s, Length(s)-1);
  IniFile.WriteString('AddressList','ColumnOrder' , s);
  ELVWriteSettingsToIniFile(AdrBookListView, 'AddressList', IniFile);
  // Form Position
  if ComboBox1.Items.Count > 0 then
    IniFile.WriteInteger('Address', 'CurBook', ComboBox1.ItemIndex);
  if WindowState = wsNormal then
  begin
    IniFile.WriteInteger('Position', 'AddressState', 1);
    IniFile.WriteInteger('Position', 'AddressWidth', Width);
    IniFile.WriteInteger('Position', 'AddressHeight', Height);
    IniFile.WriteInteger('Position', 'AddressTop', Top);
    IniFile.WriteInteger('Position', 'AddressLeft', Left);
  end;
  if WindowState = wsMaximized then
    IniFile.WriteInteger('Position', 'AddressState', 2);
  IniFile.Free;}
end;

procedure TAddressForm.AdrBookListViewDrawHeader(Control: TWinControl;
  var ACanvas: TCanvas; Index: Integer; var ARect: TRect;
  Selected: Boolean; var DefaultDrawing: Boolean);
begin
  {if Index = 0 then begin
    DefaultDrawing := False;
    ACanvas.BrushCopy(Rect(ARect.Left + 2, ARect.Top, ARect.Left + 18, ARect.Top
      + 16), Image1.Picture.Bitmap, Rect(0, 0, 16, 16), clFuchsia);
  end
  else
    DefaultDrawing := True;}
    DefaultDrawing := True;
end;

procedure TAddressForm.actFileCloseExecute(Sender: TObject);
begin
  Close;
end;

procedure TAddressForm.actAddressNewExecute(Sender: TObject);
var
  S,tempStr,temp: string;
  i:integer;
  Item: TListItem;
begin

  if Treeview1.Selected.Level=0 then exit;
  if FileName = '' then
  begin
    actBookNewExecute(self);
    exit;
  end;
  EditAdrForm := TEditAdrForm.Create(Self);

  with EditAdrForm do begin
    try
      CheckUnique := True;
      if ShowModal = mrOK then begin
        pabmodified := true;
 //       SaveAddressBook;
         Item := AdrBookListView.Items.Add;
         AssignFile(F, Filename);
         Append(F);
         temp:=LstBoxEmail.Items.CommaText;
        //////////////
        with  item.SubItems  do begin
        add(EdtName.Text);
        if Pos(',',LstBoxEmail.Items.CommaText)>0 then tempStr:=copy(temp,1,Pos(',',LstBoxEmail.Items.CommaText)-1) else tempStr:='';
        add(tempStr);
        add(EdtPhoOne2.Text);
        add(EdtPhoOne.Text)         ;
        add(EdtPhone.Text)          ;
        add(EdtP.Text)              ;
        add(EdtSicq.Text)           ;
        add(EdtIcq.Text)            ;
        add(CmbBoxSex.Text)         ;
        add(DateTimeToStr(DateTimePicker1.DateTime)) ;//10
        add(MemoFond.Text)    ;
        add(EdtHttp.Text)     ;
        add(EdtCountry.Text)  ;
        add(EdtProvince.Text) ;
        add(EdtCity.Text)     ;
        add(EdtPost.Text)     ;
        add(EdtPhoTwo.Text)   ;
        add(EdtFax.Text)      ;
        add(EdtRoad.Text)     ;
        add(EdtCorp.Text)     ;//20
        add(EdtCountry2.Text) ;
        add(EdtProvince2.Text)  ;
        add(EdtCity2.Text)    ;
        add(EdtPost2.Text)    ;
        add(EdtJob.Text)      ;
        add(EdtDepartment.Text)  ;
        add(EdtPhoTwo2.Text)  ;
        add(EdtFax2.Text)     ;
        add(EdtRoad2.Text)    ;
       add(EdtHttp2.Text)    ;//30
       add(MemoAttach.Text)  ;
       add(temp);
        ////////////
        end;
         for i:=0 to Item.SubItems.Count - 1 do
        begin
          AddressInfo.Add(Item.SubItems[i]);
        end;

        S := ToAddressFormat(AddressInfo);
        WriteLn(F, S);
        CloseFile(F);
      end;
    finally
      Free;
      AdrBookListView.Resort;
    end;
  end;


end;

procedure TAddressForm.actAddressDeleteExecute(Sender: TObject);
var
  I: Integer;
label
  Jump1;
begin
  Jump1:
  for I := 0 to AdrBookListView.Items.Count - 1 do
    if AdrBookListView.Items[I].Selected then
      if MessageDlg(Format(GetMessageString(41),
        [Trim(AdrBookListView.Items[I].SubItems[0] + ' ' +
          AdrBookListView.Items[I].SubItems[1])]), mtWarning, [mbYes, mbNo], 0) = mrYes
      then begin
        AdrBookListView.Items[I].Delete;
        goto Jump1;
      end;
  pabmodified := true;
  SaveAddressBook;
end;

procedure TAddressForm.actAddressEditExecute(Sender: TObject);
var
  Item: TListItem;
  EntryIDData: PSBinary;
  Wnd: ULONG;
  tempStr,tempEmail:string;
  i:integer;
begin

  Item := AdrBookListView.Selected;
  if Item = nil then
    Exit;
  EditAdrForm := TEditAdrForm.Create(Self);
  with EditAdrForm do begin
    try
      CheckUnique := False;
      EdtName.Text:=Item.SubItems[0];

      EdtPhoOne2.Text := Item.SubItems[2];
      EdtPhoOne.Text := Item.SubItems[3];
      EdtPhone.Text := Item.SubItems[4];
      EdtP.Text := Item.SubItems[5];
      EdtSicq.Text := Item.SubItems[6];
      EdtIcq.Text := Item.SubItems[7];
      CmbBoxSex.Text := Item.SubItems[8];
      if  Item.SubItems[9]<>'' then  DateTimePicker1.DateTime := StrToDateTime(Item.SubItems[9]) else
      DateTimePicker1.DateTime:=now;

      MemoFond.Text := Item.SubItems[10];
      EdtHttp.Text := Item.SubItems[11];
      EdtCountry.Text := Item.SubItems[12];
      EdtProvince.Text := Item.SubItems[13];
      EdtCity.Text := Item.SubItems[14];
      EdtPost.Text := Item.SubItems[15];
      EdtPhoTwo.Text := Item.SubItems[16];
      EdtFax.Text := Item.SubItems[17];
      EdtRoad.Text := Item.SubItems[18];
      EdtCorp.Text := Item.SubItems[19];
      EdtCountry2.Text := Item.SubItems[20];
      EdtProvince2.Text := Item.SubItems[21];
      EdtCity2.Text := Item.SubItems[22];
      EdtPost2.Text := Item.SubItems[23];
      EdtJob.Text := Item.SubItems[24];
      EdtDepartment.Text := Item.SubItems[25];
      EdtPhoTwo2.Text := Item.SubItems[26];
      EdtFax2.Text := Item.SubItems[27];
      EdtRoad2.Text := Item.SubItems[28];
      EdtHttp2.Text := Item.SubItems[29];
      MemoAttach.Lines.Add(Item.SubItems[30]);
      LstBoxEmail.Items.CommaText:= Item.SubItems[31];

      Caption:=trim(EdtName.Text)+' 属性';
      if ShowModal = mrOK then begin
        Item.SubItems[0]:=EdtName.Text     ;
        tempEmail:=LstBoxEmail.Items.CommaText;
        i:=Pos(',',tempEmail);
        if i>0 then  tempStr:=copy(tempEmail,1,Pos(',',tempEmail)-1) else tempStr:='';

        Item.SubItems[1]:=tempStr;
        Item.SubItems[2]:=EdtPhoOne2.Text        ;
        Item.SubItems[3]:=EdtPhoOne.Text         ;
        Item.SubItems[4]:=EdtPhone.Text          ;
        Item.SubItems[5]:=EdtP.Text              ;
        Item.SubItems[6]:=EdtSicq.Text           ;
        Item.SubItems[7]:=EdtIcq.Text            ;
        Item.SubItems[8]:=CmbBoxSex.Text         ;
        Item.SubItems[9]   :=DateTimeToStr(DateTimePicker1.DateTime) ;
        Item.SubItems[10]  :=      MemoFond.Text    ;
        Item.SubItems[11]  :=      EdtHttp.Text     ;
        Item.SubItems[12]  :=      EdtCountry.Text  ;
        Item.SubItems[13]  :=      EdtProvince.Text ;
        Item.SubItems[14]  :=      EdtCity.Text     ;
        Item.SubItems[15]  :=      EdtPost.Text     ;
        Item.SubItems[16]  :=      EdtPhoTwo.Text   ;
        Item.SubItems[17]  :=      EdtFax.Text      ;
        Item.SubItems[18]  :=      EdtRoad.Text     ;
        Item.SubItems[19]  :=      EdtCorp.Text     ;
        Item.SubItems[20]  :=      EdtCountry2.Text ;
        Item.SubItems[21]  :=     EdtProvince2.Text  ;
        Item.SubItems[22]  :=      EdtCity2.Text    ;
        Item.SubItems[23]  :=      EdtPost2.Text    ;
        Item.SubItems[24]  :=      EdtJob.Text      ;
        Item.SubItems[25]  :=   EdtDepartment.Text  ;
        Item.SubItems[26]  :=      EdtPhoTwo2.Text  ;
        Item.SubItems[27]  :=      EdtFax2.Text     ;
        Item.SubItems[28]  :=      EdtRoad2.Text    ;
        Item.SubItems[29]  :=      EdtHttp2.Text    ;
        Item.SubItems[30]  :=      MemoAttach.Text  ;
        Item.SubItems[31]  :=      tempEmail        ;//for temp


        pabmodified := true;
        SaveAddressbook;
      end;
    finally
      Free;
    end;
  end;
{begin
  EntryIDData := PSBinary(AdrBookListView.Selected.Data);
  Wnd := Handle;
  with EntryIDData^ do
    AddrBook.Details(Wnd, nil, nil, cb, PEntryID(lpb), nil, nil, nil, 0);
  LoadItems(True);
end;}

end;

procedure TAddressForm.actAddressSearchExecute(Sender: TObject);
begin
  byGlobalSearchMode := smAddress;
  if menSearchForm = nil then
  begin
    menSearchForm := TmenSearchForm.Create(Self);
    if Assigned(LangHolder) then
    begin
      if LangHolder.Language <> '' then
        LangHolder.Translate([menSearchForm]);
    end;
  end;

  with menSearchForm do begin
    SearchMode := smAddress;
    //Caption := GetMessageString(116) + ' ' + GetMessageString(137);
    Caption:='查找地址';
    if bSearchName then
    begin
      menchkFirst.checked := true;
      menchkLast.checked := true;
      menchkEMail.checked := true;
    end;
    if bSearchDate then
    begin
      Caption := GetMessageString(138);
      cboFindText.Text := FormatDateTime('mm"-"dd', now);
      btnFind.enabled := true;
      menchkDate.checked := true;
      menchkDescription.checked := true;
    end;
    Show;
  end;
end;

procedure TAddressForm.actAddressCopyToExecute(Sender: TObject);
begin
  MoveCopyAddress(False);
end;

procedure TAddressForm.actAddressMoveToExecute(Sender: TObject);
begin
  MoveCopyAddress(True);
end;

procedure TAddressForm.actAddressWriteToExecute(Sender: TObject);
begin
  if AdrBookListView.Selected = nil then
    Exit;
  if keypressed(vk_menu) then
  begin
    actAddressEditExecute(Sender);
    exit;
  end;
  MailOK := True;
  Close;
end;

procedure TAddressForm.actHelpContentsExecute(Sender: TObject);
begin
  Application.HelpContext(9);
end;

procedure TAddressForm.actAddressSelectAllExecute(Sender: TObject);
var
  I: Integer;
begin
  AdrBookListView.Items.BeginUpdate;
  for I := 0 to AdrBookListView.Items.Count - 1 do
    AdrBookListView.Items[I].Selected := True;
  AdrBookListView.Items.EndUpdate;
end;

procedure TAddressForm.actAddressDeleteUpdate(Sender: TObject);
begin
  (Sender as TAction).Enabled := (AdrBookListView.Selected <> nil) and (Filename <>
    '');
end;

procedure TAddressForm.actAddressWriteToUpdate(Sender: TObject);
begin
  (Sender as TAction).Enabled := (AdrBookListView.Selected <> nil) and (Filename <>
    '');
end;

procedure TAddressForm.actAddressMoveToUpdate(Sender: TObject);
begin
  (Sender as TAction).Enabled := (AdrBookListView.Selected <> nil) and
    (Filename <> '') and (ComboBox1.Items.Count > 1);
end;

procedure TAddressForm.actAddressEditUpdate(Sender: TObject);
begin
  (Sender as TAction).Enabled := (AdrBookListView.Selected <> nil) and (Filename <>
    '');
end;

procedure TAddressForm.actUpdateStatusbarUpdate(Sender: TObject);
begin
  StatusBar1.Panels[0].Text := Format(GetMessageString(38),
    [IntToStr(AdrBookListView.Items.Count), IntToStr(AdrBookListView.SelCount)]);
end;

procedure TAddressForm.actBookNewExecute(Sender: TObject);
var
  S, oldFilename : string;
  I: Integer;
  TempNode:TtreeNode;
begin
  if InputQuery(GetMessageString(42), GetMessageString(43), S) then begin
    for I := 1 to Length(S) do
      if S[I] in ['\', '/', '<', '>', ':', '?', '*', '"', '|', #19] then
      begin
        MessageDlg(GetMessageString(44), mtError, [mbOK], 0);
        Exit;
      end;
      SaveAddressBook;
      OldFileName := FileName;
      Filename := sAddressBookFolder + S + '.ssf';

    if FileExists(FileName) then
    begin
      Beep;
      Exit;
    end;
    AssignFile(F, Filename);
    Rewrite(F);
    WriteLn(F, 'EdtName;LstBoxEmail;EdtPhoOne2;EdtPhoOne;EdtPhone;EdtP;EdtSicq;EdtIcq;CmbBoxSex;DateTimePicker1;MemoFond'+
    ';EdtHttp;EdtCountry;EdtProvince;EdtCity;EdtPost;EdtPhoTwo;EdtFax;EdtRoad;EdtCorp;EdtCountry2;EdtProvince2;EdtCity2;EdtPost2'+
    ';EdtJob;EdtDepartment;EdtPhoTwo2;EdtFax2;EdtRoad2;EdtHttp2;MemoAttach');

    CloseFile(F);

    with Treeview1.Items do
    begin
      TempNode:=AddChild(RootNode,s);
      TempNode.ImageIndex:=1;
      TempNode.SelectedIndex:=0;
    end;


    FileName := OldFileName;
 //   LoadAddressBook;
  end;
end;

procedure TAddressForm.actBookDeleteExecute(Sender: TObject);
var
  I: Integer;
  iResult:integer;
begin
  if (TreeView1.Selected=nil) or (TreeView1.Selected.Level=0) or (Filename = '') then exit;
  iResult:=application.MessageBox(pchar('确定要删除文件夹 '+TreeView1.Selected.text+'?'), Pchar(Application.Title), MB_YESNO or MB_ICONEXCLAMATION);
  if iResult=6 then
  begin
    DeleteFile(Filename);
    TreeView1.Selected.Delete;
    Filename := '';
    LoadAddressBook;
    Filename:='';
  end;
   ComboBox1.Focused
end;

procedure TAddressForm.actBookRenameExecute(Sender: TObject);
var
  S: string;
  I, E: Integer;
begin
  if TreeView1.Selected=nil then exit;
  SaveAddressBook;
  S := TreeView1.Selected.Text;
  if InputQuery(GetMessageString(47), GetMessageString(43), S) then begin
    for E := 1 to Length(S) do
      if S[E] in ['\', '/', '<', '>', ':', '?', '*', '"', '|', #19] then begin
        MessageDlg(GetMessageString(44), mtError, [mbOK], 0);
        Exit;
      end;
    RenameFile(Filename, sAddressBookFolder + S + '.ssf');
    Filename := sAddressBookFolder + S + '.ssf';
//  UpdateTreeview;
  end;
end;

procedure TAddressForm.actBookDeleteUpdate(Sender: TObject);
begin
  (Sender as TAction).Enabled := ComboBox1.ItemIndex > -1;
end;

procedure TAddressForm.actBookRenameUpdate(Sender: TObject);
begin
  (Sender as TAction).Enabled := ComboBox1.ItemIndex > -1;
end;

procedure TAddressForm.AdrBookListViewKeyUp(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  if Ord(Key) = 46 then
    actAddressDeleteExecute(Self)
  else if Ord(Key) = 13 then
    actAddressWriteToExecute(Self);
end;

procedure TAddressForm.actBookCloseExecute(Sender: TObject);
begin
  Close;
end;

procedure TAddressForm.Importieren1Click(Sender: TObject);
var i: Integer;
  s: string;
begin
  if OpenDialog1.execute then
  begin
    AssignFile(F, OpenDialog1.FileName);
    Reset(F);
    Readln(F, s);
    CloseFile(F);
    s := UpperCase(s);
    if pos('SMAIL', s) <> 0 then i := ImportOldAdressBook(OpenDialog1.FileName) else
      i := ImportOutlookBook(OpenDialog1.FileName);
    if i > 0 then
    begin
      // AH08   s := 'Importing ' + IntToStr(i) + ' addresses';
      s := Format(GetMessageString(103), [IntToStr(i)]);
      MessageBox(Handle, PChar(s), PChar(GetMessageString(105)), mb_IconInformation);
      pabmodified := true;
      SaveAddressBook;
    end;
  end;
end;

procedure TAddressForm.Exportieren1Click(Sender: TObject);
begin
  ExportNewAdressBook;
end;

procedure TAddressForm.Speichernunter1Click(Sender: TObject);
var
  I: Integer;
begin
  if filename = '' then exit;
  if TreeView1.Selected=nil then exit;
  SaveAddressBook;

  SaveDialog2.InitialDir := sAddressBookFolder;
  SaveDialog2.FileName := '';
  if not SaveDialog2.execute then exit;
  FileCopy(nil, FileName, SaveDialog2.FileName);

  if FileExists(SaveDialog2.FileName) then

    MessageBox(Handle, PChar(GetMessageString(104)), Pchar(GetMessageString(105)), mb_Ok or mb_IconInformation or mb_DefButton1)

end;

procedure TAddressForm.InfoszudieserVersion1Click(Sender: TObject);
var s: string;
begin
  s := GetAppPath + 'SMAIL.rtf';
  if FileExists(s) then ShellExecute(Handle, 'open', PChar(s), '', PChar(sTemporaryFolder), SW_SHOWNORMAL)
end;


procedure TAddressForm.actAddressCopyToUpdate(Sender: TObject);
begin
  (Sender as TAction).Enabled := (AdrBookListView.Selected <> nil) and
    (Filename <> '') and (ComboBox1.Items.Count > 1);
end;

procedure TAddressForm.FindTodayClick(Sender: TObject);
begin
  bSearchdate := true;
  actAddressSearchExecute(Sender);
  bSearchdate := false;
end;

procedure TAddressForm.SelectOneType(TheType: Integer);
var
  I: Integer;
begin
  if AdrBookListView.Items.Count = 0 then exit;
  AdrBookListView.Selected := nil;
  AdrBookListView.Items.BeginUpdate;
  for I := 0 to AdrBookListView.Items.Count - 1 do
  begin
    if AdrBookListView.Items[i].ImageIndex = TheType then
      AdrBookListView.Items[I].Selected := True;
  end;
  AdrBookListView.Items.EndUpdate;
end;

procedure TAddressForm.SelectPrivateClick(Sender: TObject);
begin
  SelectOneType(0);
end;

procedure TAddressForm.SelectBizzClick(Sender: TObject);
begin
  SelectOneType(1);
end;

procedure TAddressForm.SelectOrgClick(Sender: TObject);
begin
  SelectOneType(2);
end;

procedure TAddressForm.SelectFriendsClick(Sender: TObject);
begin
  SelectOneType(3);
end;

procedure TAddressForm.SelectLoveClick(Sender: TObject);
begin
  SelectOneType(4);
end;

procedure TAddressForm.Markierungumkehren1Click(Sender: TObject);
var I: Integer;
begin
  if AdrBookListView.Items.Count = 0 then exit;
  AdrBookListView.Items.BeginUpdate;
  for I := 0 to AdrBookListView.Items.Count - 1 do
  begin
    AdrBookListView.Items[I].Selected := not AdrBookListView.Items[I].Selected;
  end;
  AdrBookListView.Items.EndUpdate;
end;

procedure TAddressForm.berPhoenixMail1Click(Sender: TObject);
begin
  ShellAbout(Handle,
    'Windows - SMAIL',
    'SMAIL ' + sInfoVersion
    ,
    Application.Icon.Handle);

end;

procedure TAddressForm.actVNEcopyUpdate(Sender: TObject);
begin
  (Sender as TAction).Enabled := (AdrBookListView.Selected <> nil)
    and (Filename <> '');
end;

function TAddressForm.MakeClipBoardString(wie: word): string;
var
  S, P: string;
  I: Integer;
  wo: Byte;
begin
  S := '';
  if wie = 0 then
  begin
    with AdrBookListView do
    begin
      for I := 0 to Items.Count - 1 do
        if Items[I].Selected then
        begin
          S := S + Items[I].SubItems[0] + ' ' +
            Items[I].SubItems[1] + ', mailto:' +
            Items[I].SubItems[3];
          S := Trim(S);
          S := S + #13#10;
        end;
    end;
  end;

  if wie = 1 then
  begin
    with AdrBookListView do
    begin
      for I := 0 to Items.Count - 1 do
        if Items[I].Selected then
        begin
          S := S + Items[I].SubItems[0] + ' ' +
            Items[I].SubItems[1] + #13#10;
          S := Trim(S);
          S := S + #13#10;
          P := Items[I].SubItems[6];
          wo := Pos('+', P);
          while wo <> 0 do
          begin
            delete(P, wo, 1);
            Insert(#13#10, P, wo);
            wo := Pos('+', P);
          end;
          S := S + P + #13#10#13#10;
        end;
    end;
  end;

  Result := s;
end;

procedure TAddressForm.actVNEcopyExecute(Sender: TObject);
var S: string;
begin
  s := MakeClipBoardString(0);
  ClipBoard.SetTextBuf(PChar(s));
  close;
end;

procedure TAddressForm.actVNPcopyUpdate(Sender: TObject);
begin
  (Sender as TAction).Enabled := (AdrBookListView.Selected <> nil)
    and (Filename <> '');
end;

procedure TAddressForm.actVNPcopyExecute(Sender: TObject);
var S: string;
begin
  s := MakeClipBoardString(1);
  ClipBoard.SetTextBuf(PChar(s));
//  Fehler(Handle,s);
  close;
end;

procedure TAddressForm.PMListPrintClick(Sender: TObject);
var s,f: string;
begin
  s := GetAppPath + 'PMADDON.EXE';
  f := '"'+filename+'"';
  ShellExecute(Handle, 'open', PChar(s), PChar(f), PChar(sTemporaryFolder), SW_SHOW);
end;

procedure TAddressForm.actBookPhoenixExecute(Sender: TObject);
var j: Integer;
begin
  for j := 0 to ComboBox1.Items.Count - 1 do
  begin
    if UpperCase(ComboBox1.Items[j]) = 'SMAIL' then break;
  end;
  ComboBox1.ItemIndex := j;
  SaveAddressBook;
  Filename := ComboBox1.Values[ComboBox1.ItemIndex];
  LoadAddressBook;
end;

procedure TAddressForm.TreeView1Click(Sender: TObject);
begin
  if TreeView1.Selected=nil then exit;
  SaveAddressBook;
  Filename := sAddressBookFolder+TreeView1.Selected.Text+'.ssf';
  LoadAddressBook;
end;

procedure TAddressForm.UpdateTreeview;
var
  i, j, Found, e: Integer;
  SearchRec: TSearchRec;
  IniFile: TIniFile;
  S: string;
  aColumns : array [0..7] of integer; 
begin
  TreeView1.Items.Clear;
  ComboBox1.Clear;
  AdrBookListView.Items.Clear;
  ComboBox1.Sorted := True;

   with TreeView1.Items do                                                  
    begin
      RootNode:=add(nil,'地址薄分类');
      RootNode.ImageIndex:=2;
    end;



  Found := FindFirst(sAddressBookFolder + '*.ssf', faAnyFile, SearchRec);
  while Found = 0 do
  begin
    s := SearchRec.Name; // AH16
    SetFileAttr(sAddressBookFolder + SearchRec.Name, False, True, False, False);
    Delete(s, Length(s) - 3, 4);

    with TreeView1.Items do
    begin
      Node:=addchild(RootNode,s);
      Node.ImageIndex:=1;
      Node.SelectedIndex:=0;
    end;

    Found := FindNext(SearchRec);
  end;
  FindClose(SearchRec);

  IniFile := TIniFile.Create(sSettingsFile);

  s := IniFile.ReadString('AddressList', 'ColumnOrder', '');
  if pos(',', s) <> 0 then
  begin
    for i := 0 to AdrBookListView.Columns.Count-1 do
    begin
      e := Pos(',', s);
      if e = 0 then e := Length(s)+1;
      acolumns[i] := StrToInt(Copy(s, 1, e-1));
      s := copy(s, e+1, length(s));
      if s = '' then break;
    end;
    AdrBookListView.SetColumnOrder(8, aColumns);
  end;
  ELVReadSettingsFromIniFile(AdrBookListView, 'AddressList', IniFile);

  if Combobox1.Items.Count = 0 then //Standard-Adressbuch erzeugen
  begin
    AssignFile(F, sAddressBookFolder + 'SMAIL.ssf');
    Rewrite(F);
    WriteLn(F, 'Art;Vorname;Name;E-Mail;Postanschrift;Telefon;Datum;Bemerkung');
    Writeln(F);
    CloseFile(F);
    ComboBox1.Values.Add(sAddressBookFolder + 'SMAIL.ssf');
    Combobox1.Items.Add('SMAIL');
    ComboBox1.ImgIndexes.Add('5'); //5
  end;

  if Combobox1.Items.Count > 0 then begin
    i := IniFile.ReadInteger('Address', 'CurBook', 0);
    i := abs(i);
    if i <= ComboBox1.Items.Count - 1 then
      ComboBox1.ItemIndex := i else ComboBox1.ItemIndex := 0;
    Filename := ComboBox1.Values[ComboBox1.ItemIndex];
  end;

  if bUsePMBook then
  begin
    j := ComboBox1.Items.IndexOf('SMAIL');
    // AH16...
    if j > -1 then
    begin
      ComboBox1.ItemIndex := j;
      FileName := ComboBox1.Values[ComboBox1.ItemIndex];
    end
    // AH16 ends here...
  end;


  // Form Position
  case IniFile.ReadInteger('Position', 'AddressState', 1) of
    0, 1: begin
        WindowState := wsNormal;
        Width := IniFile.ReadInteger('Position', 'AddressWidth', Width);
        Height := IniFile.ReadInteger('Position', 'AddressHeight', Height);
        Top := IniFile.ReadInteger('Position', 'AddressTop', Top);
        Left := IniFile.ReadInteger('Position', 'AddressLeft', Left);
      end;
    2: begin
        WindowState := wsMaximized;
        Top := 0;
        Left := 0;
        Height := screen.DesktopHeight;
        Width := screen.DesktopWidth;
      end;
  end;
  IniFile.Free;


  S := GetAppPath + 'PMADDON.EXE';
  PMListPrint.visible := FileExists(S); // is in Extras-Menu
  end;
procedure TAddressForm.menDeleteClick(Sender: TObject);
var
  I: Integer;
label
  Jump1;
begin
  Jump1:
  for I := 0 to AdrBookListView.Items.Count - 1 do
    if AdrBookListView.Items[I].Selected then
      if MessageDlg(Format(GetMessageString(41),
        [Trim(AdrBookListView.Items[I].SubItems[0] + ' ' +
          AdrBookListView.Items[I].SubItems[1])]), mtWarning, [mbYes, mbNo], 0) = mrYes
      then begin
        AdrBookListView.Items[I].Delete;
        goto Jump1;
      end;
  pabmodified := true;
  SaveAddressBook;
end;

procedure TAddressForm.menImportClick(Sender: TObject);
var i: Integer;
  s: string;
begin
  if OpenDialog1.execute then
  begin
    AssignFile(F, OpenDialog1.FileName);
    Reset(F);
    Readln(F, s);
    CloseFile(F);
    s := UpperCase(s);
    if pos('SMAIL', s) <> 0 then i := ImportOldAdressBook(OpenDialog1.FileName) else
      i := ImportOutlookBook(OpenDialog1.FileName);
    if i > 0 then
    begin
      // AH08   s := 'Importing ' + IntToStr(i) + ' addresses';
      s := Format(GetMessageString(103), [IntToStr(i)]);
      MessageBox(Handle, PChar(s), PChar(GetMessageString(105)), mb_IconInformation);
      pabmodified := true;
      SaveAddressBook;
    end;
  end;
end;

procedure TAddressForm.menExportClick(Sender: TObject);
begin
  ExportNewAdressBook;
end;

procedure TAddressForm.menExitClick(Sender: TObject);
begin
  close;
end;

procedure TAddressForm.TreeView1Change(Sender: TObject; Node: TTreeNode);
begin
  Filename:=sAddressBookFolder+TreeView1.Selected.Text+'.ssf';
  LoadAddressBook;
end;

procedure TAddressForm.btnDeleteClick(Sender: TObject);
var
  i,iResult:integer;
begin
  if  TreeView1.Focused and (TreeView1.Selected<>nil) and (TreeView1.Selected.Level>0) then
  begin
    iResult:=application.MessageBox(pchar('确定要删除文件夹 '+TreeView1.Selected.text+'?'), Pchar(Application.Title), MB_YESNO or MB_ICONEXCLAMATION);
    if iResult=6 then
    begin
      DeleteFile(Filename);
      TreeView1.Selected.Delete;
      Filename := '';
      LoadAddressBook;
      Filename:='';
    end;
  end;
  if AdrBookListView.Selected<>nil then actAddressDelete.Execute;
end;

procedure TAddressForm.AdrBookListViewExit(Sender: TObject);
begin
  if TreeView1.Focused or (AdrBookListView.Selected<>nil)   then btnDelete.Enabled:=true else btnDelete.Enabled:=false;
  menDelete.Enabled:= btnDelete.Enabled;
  PopMenDeleteAddress.Enabled:= btnDelete.Enabled;
end;

procedure TAddressForm.AdrBookListViewClick(Sender: TObject);
begin
  if TreeView1.Focused or (AdrBookListView.Selected<>nil)   then btnDelete.Enabled:=true else btnDelete.Enabled:=false;
  menDelete.Enabled:= btnDelete.Enabled;
  PopMenDeleteAddress.Enabled:= btnDelete.Enabled;
end;

procedure TAddressForm.AdrBookListViewChange(Sender: TObject; Item: TListItem;
  Change: TItemChange);
begin
  if TreeView1.Focused or (AdrBookListView.Selected<>nil)   then btnDelete.Enabled:=true else btnDelete.Enabled:=false;
  menDelete.Enabled:= btnDelete.Enabled;
  PopMenDeleteAddress.Enabled:= btnDelete.Enabled;

end;

procedure TAddressForm.WAB1Click(Sender: TObject);
begin
  OpenDialog.Filter:='Outlook express(*.wab)|*.wab';
  with OpenDialog do
  begin
    FileName := '';
    if Execute then OpenCopyOfFileName(FileName, ofReadOnly in Options);
  end;
end;

procedure TAddressForm.ClearLastDetails;
begin
  {if FLastDetails <> nil then
  begin
    DetailListView.Items.Count := 0;
    OleCheck(WabObject.FreeBuffer(FLastDetails));
    FreeSBinary(FLastDetailID);
    FLastDetails := nil;
    FLastDetailsCount := 0;
  end; }
end;

procedure TAddressForm.CloseWabFile;
begin
  with AdrBookListView.Items do
  begin
    BeginUpdate;
    Clear;
    EndUpdate;
  end;
  ClearLastDetails;
  AddrBook := nil;
  WabObject := nil;
  Sleep(0);
end;

procedure TAddressForm.CreateNewEntry(ulObjectType: ULONG);
var
  WabEntryID, WabNewEntryID: PEntryID;
  WabEntryIDSize, WabNewEntryIDSize: ULONG;
  Wnd: ULONG;
  Res: HResult;
begin
  OleCheck(HrGetWABTemplateID(ulObjectType, WabEntryIDSize, WabEntryID));
  Wnd := Application.Handle;
  Res := AddrBook.NewEntry(Wnd, 0, 0, nil, WabEntryIDSize, WabEntryID,
    WabNewEntryIDSize, WabNewEntryID);
  if Res <> MAPI_E_USER_CANCEL then OleCheck(Res);
  LoadItems(True);
end;

procedure TAddressForm.DeleteEntry(EntryIDData: PSBinary);
var
  Container: IABContainer;
  WabEntryID: PEntryID;
  WabEntryIDSize, ObjType: ULONG;
  BinArray: TSBinaryArray;
begin
  OleCheck(AddrBook.GetPAB(WabEntryIDSize, WabEntryID));
  OleCheck(AddrBook.OpenEntry(WabEntryIDSize, WabEntryID, nil, 0, ObjType,
    IUnknown(Container)));
  BinArray.cValues := 1;
  BinArray.lpbin := EntryIDData;
  OleCheck(Container.DeleteEntries(PEntryList(@BinArray), 0));
  ClearLastDetails;
  OleCheck(WabObject.FreeBuffer(WabEntryID));
  LoadItems(True);
end;

procedure TAddressForm.FreeSBinary(var P: PSBinary);
begin
  if P = nil then Exit;
  FreeMem(P.lpb);
  Dispose(P);
  P := nil;
end;

procedure TAddressForm.FreeSRowSet(var P: PSRowSet);
var
  I: Integer;
begin
  for I := 0 to P^.cRows - 1 do
    OleCheck(WabObject.FreeBuffer(P^.aRow[I].lpProps));
  OleCheck(WabObject.FreeBuffer(P));
  P := nil;
end;

function TAddressForm.HrGetWABTemplateID(ulObjectType: ULONG;
  var lpcbEID: ULONG; var lppEID: PEntryId): HResult;
begin

end;

procedure TAddressForm.LoadItems(RememberSelected: Boolean);
const
  TableColumns: record // SizedSPropTagArray macro
    Count: ULONG;
    Definition: array[0..4] of ULONG;
  end = (
    Count: 5;
    Definition:
      (PR_DISPLAY_NAME,
       PR_EMAIL_ADDRESS,
       PR_PERSONAL_HOME_PAGE,
       PR_ENTRYID,
       PR_OBJECT_TYPE);
   );
var
  Container: IABContainer;
  EntryID: PEntryID;
  EntryIDSize, ObjType: ULONG;
  Table: IMAPITable;
  TableRow: PSRowSet;
  EntryIDData: PSBinary;
  Item, LastSelectedItem: TListItem;
  i:integer;

  function IsLastDetailItem: Boolean;
  var
    Res: ULONG;
  begin
    Result := (FLastDetailID <> nil) and RememberSelected;
    if not Result then Exit;
    with FLastDetailID^ do
      OleCheck(AddrBook.CompareEntryIDs(EntryIDSize, EntryID, cb, PEntryID(lpb), 0, Res));
    Result := Res <> 0;
  end;

begin
  LastSelectedItem := nil;

  OleCheck(AddrBook.GetPAB(EntryIDSize, EntryID));
  OleCheck(AddrBook.OpenEntry(EntryIDSize, EntryID, nil, 0,
    ObjType, IUnknown(Container)));
  OleCheck(WabObject.FreeBuffer(EntryID));

  OleCheck(Container.GetContentsTable(0, Table));
  OleCheck(Table.SetColumns(@TableColumns, 0));
  OleCheck(Table.SeekRow(BOOKMARK_BEGINNING, 0, nil));

  with AdrBookListView do
  begin
    Items.BeginUpdate;
    try
      Items.Clear;

      repeat
        OleCheck(Table.QueryRows(1, 0, TableRow));
        if TableRow.cRows > 0 then with TableRow^.aRow[0] do
        begin
          if ULONG(lpProps[4].Value.l) in [MAPI_MAILUSER, MAPI_DISTLIST] then
          begin
            EntryID := lpProps[3].Value.bin.lpb;
            EntryIDSize := lpProps[3].Value.bin.cb;

            OleCheck(WabObject.AllocateBuffer(Sizeof(TSBinary), Pointer(EntryIDData)));
            OleCheck(WabObject.AllocateMore(EntryIDSize, EntryIDData, Pointer(EntryIDData.lpb)));
            CopyMemory(EntryIDData.lpb, EntryID, EntryIDSize);
            EntryIDData^.cb := EntryIDSize;

            Item := Items.Add;
            with Item do
            begin
              SubItems.Add(SPropValueToStr(lpProps[0]));
              SubItems.Add(SPropValueToStr(lpProps[1]));

              for i:=1 to 29 do
                SubItems.Add('');
//              SubItems.Add(SPropValueToStr(lpProps[1]));
//              SubItems.Add(SPropValueToStr(lpProps[2]));
              SubItems.Add(SPropValueToStr(lpProps[1]));
              Data := EntryIDData;
              case ULONG(lpProps[4].Value.l) of
                MAPI_MAILUSER:
                  //ImageIndex := imgIndexUser;
                  ImageIndex := 0;
                MAPI_DISTLIST:
                  //ImageIndex := imgIndexDL;
                  ImageIndex := 0;
              end;
            end;
            if IsLastDetailItem then LastSelectedItem := Item;
          end;
          FreeSRowSet(TableRow);
        end else Break;
      until False;

      StatusBar1.Panels[0].Text := Format('%d items', [Items.Count]);
      ClearLastDetails;
      Selected := LastSelectedItem;
      if Selected <> nil then Selected.MakeVisible(False);
    finally
      Items.EndUpdate;
    end;
  end;


end;

procedure TAddressForm.OpenCopyOfFileName(const FileName: TFileName;
  CreateCopy: Boolean);
var
  CopyOfFile: TFileName;
begin
  {if CreateCopy then
  begin
    CopyOfFile := Format('%s\CopyOf%s', [
      ExcludeTrailingBackslash(ExtractFilePath(FileName)), ExtractFileName(FileName)]);
    Win32Check(CopyFile(PChar(FileName), PChar(CopyOfFile), False));
  end else}
  CopyOfFile := FileName;
  OpenWabFile(CopyOfFile);
  LoadItems(False);
  pabmodified:=true;
  SaveAddressBook;;
end;

procedure TAddressForm.OpenWabFile(const FileName: TFileName);
var
  WP: TWabParam;
begin
  CloseWabFile;

  ZeroMemory(@WP, Sizeof(WP));
  WP.cbSize := Sizeof(WP);
  WP.szFileName := PChar(FileName);
  WP.hwnd := Application.Handle;
  OleCheck(WabOpen(AddrBook, WabObject, @WP, 0));

  StatusBar1.Panels[0].Text := FileName;
  FFileName := FileName;
end;

procedure TAddressForm.ReadDetails(EntryIDData: PSBinary);
var
  PropValue: TSPropValue;
  TextValue: string;
  MailUser: IMailUser;
  ObjType: ULONG;
  SPTA: TSPropTagArray;
begin
{  Result := False;
  PropValue := FLastDetails[DetailListView.Selected.Index];
  TextValue := SPropValueToStr(PropValue);
  if InputQuery('Edit value (empty string means delete)', SPropValueToTypeStr(PropValue), TextValue) then
  begin
    with FLastDetailID^ do
      OleCheck(AddrBook.OpenEntry(cb, lpb, nil, MAPI_MODIFY, ObjType, IUnknown(MailUser)));
    SPTA.cValues := 1;
    SPTA.aulPropTag[0] := PropValue.ulPropTag;
    OleCheck(MailUser.DeleteProps(@SPTA, nil));
    TextValue := Trim(TextValue);
    if Length(TextValue) > 0 then
    begin
      StrToSPropValue(TextValue, PropValue);
      OleCheck(MailUser.SetProps(1, @PropValue, nil));
    end;
    OleCheck(MailUser.SaveChanges(0));
    Result := True;
  end;}
end;

function TAddressForm.SetCurrentPropValue: Boolean;
var
  PropValue: TSPropValue;
  TextValue: string;
  MailUser: IMailUser;
  ObjType: ULONG;
  SPTA: TSPropTagArray;
begin
{  Result := False;
  PropValue := FLastDetails[DetailListView.Selected.Index];
  TextValue := SPropValueToStr(PropValue);
  if InputQuery('Edit value (empty string means delete)', SPropValueToTypeStr(PropValue), TextValue) then
  begin
    with FLastDetailID^ do
      OleCheck(AddrBook.OpenEntry(cb, lpb, nil, MAPI_MODIFY, ObjType, IUnknown(MailUser)));
    SPTA.cValues := 1;
    SPTA.aulPropTag[0] := PropValue.ulPropTag;
    OleCheck(MailUser.DeleteProps(@SPTA, nil));
    TextValue := Trim(TextValue);
    if Length(TextValue) > 0 then
    begin
      StrToSPropValue(TextValue, PropValue);
      OleCheck(MailUser.SetProps(1, @PropValue, nil));
    end;
    OleCheck(MailUser.SaveChanges(0));
    Result := True;
  end;}
end;

procedure TAddressForm.N2Click(Sender: TObject);
var i: Integer;
  s: string;
begin
  if OpenDialog1.execute then
  begin
    AssignFile(F, OpenDialog1.FileName);
    Reset(F);
    Readln(F, s);
    CloseFile(F);
    s := UpperCase(s);
    if pos('SMAIL', s) <> 0 then i := ImportOldAdressBook(OpenDialog1.FileName) else
      i := ImportOutlookBook(OpenDialog1.FileName);
    if i > 0 then
    begin
      // AH08   s := 'Importing ' + IntToStr(i) + ' addresses';
      s := Format(GetMessageString(103), [IntToStr(i)]);
      MessageBox(Handle, PChar(s), PChar(GetMessageString(105)), mb_IconInformation);
      pabmodified := true;
      SaveAddressBook;
    end;
  end;
end;

initialization
   PMRegistry.AddCustomClass(TAddressForm, 'TAddressForm');

end.

