お知らせ

電子会議

ライブラリ

FDelphi サイト全文検索

Delphi FAQ一覧

サンプル蔵



FDelphi FAQ
15番会議室「FAQ編纂委員会」に寄せられた「よくある質問の答え」

[Q]
>[FAQ][D2]FileListBox等のI/Oエラー回避 のDelphi1.0J版はどうなりますか? 同じようなコーディングでは、Win3.1 ではうまく行きませんが。

[A]
Win3.1で、
>[FAQ][D2]FileListBox等のI/Oエラー回避、の(I)の操作でのエラーに相当す
るものは、

「システムエラー、読み出せません:ドライブ〜」と、
「不正なファイル名です」
というエラーメッセージが、元のフロッピーを戻してそのドライブを指定し
ない限り、出続ける、というものです。

 ほぼ同じ方法で対処できましたが、かなりの修正が必要でした。

 最初、1.0Jの場合には、破棄を先にしないとダメと思っていたのですが、
FileListBox にしても、DirectoryListBox にしても、ドライブとの関連を
DirectoryListBox.FileList:=nil などで取っているのになぜ読みに行くの
かと思い直し、パラメータ設定順序など変えてみたら、うまく行きました。
つまり、生成を先、破棄をあとにして、フォーム上から消えてしまう(の
が目に付くの)を防ぎます。

 DriveComboBoxの更新が必要な場合があったのですが、これが、2.0Jと比
べて、異常に長時間を必要とします。
[例]
>[FAQ][D2]FileListBox等のI/Oエラー回避

でのコーディングとの異同を記しています。

{----- ここから Form1 ユニット:
       DriveComboBox1 を配置
       DirectoryListBox[1]、[2] および ------------------------------
       FileListBox[1]、[2] は動的に生成配置
}
unit Drvfilu;

  (...略...)
type
  TArrDirectoryListBox=array[1..2] of TDirectoryListBox;
  TArrFileListBox=array[1..2] of TFileListBox;

  TForm1 = class(TForm)
  (...略...)
  private
    { Private 宣言 }
  (変数宣言は [FAQ][D2]FileListBox等のI/Oエラー回避、に同じ)
  (メンバー関数の宣言...略...)
  end;

var
  Form1: TForm1;
  uOldMode: integer;           {エラーモード}

function DriveState(cDrive: char): boolean;
変更点:
  SetErrorMode(SEM_FAILCRITICALERRORS)->SetErrorMode(1);

function GetNearHD(iDrive: integer): char;
変更点:
>      cDrive:=chr(k+ord('A')-1);
>      j:=GetDriveType(PChar(cDrive+':\'));
---
      j:=GetDriveType(k-1);
      cDrive:=chr(k+ord('A')-1);
      if (j=DRIVE_FIXED) then
        if not DriveState(cDrive) then j:=1; {MO の場合}
---

function OtherBox(iBox: integer): integer;
{同じ}

procedure TForm1.FormCreate(Sender: TObject);
{同じ}

procedure TForm1.UpdateDrive(
          okDrive: Char; var badDrive: Char);
begin
  DriveComboBox1.Drive:=okDrive;
  DriveComboBox1.TextCase:=FileCtrl.tcLowerCase; (注*1)
  badDrive:=okDrive;
end; {UpdateDrive}

procedure TForm1.RenewFileListBox(
          okDrive: Char; var badDrive: Char);
{使いません}

procedure TForm1.RenewDirFileBox(
          okDrive: Char; var badDrive: Char);
var
  jDBox,jFBox: integer;
begin
  jDBox:=OtherBox(gDBox);
  jFBox:=OtherBox(gFBox);
  DriveComboBox1.DirList:=nil;
  DirectoryListBox[gDBox].FileList:=nil;
  ChDir(okDrive+':');
  CreateFileListBox(jFBox); {新規のFileListBox作成}
  CreateDirectoryListBox(jDBox);

  DriveComboBox1.Drive:=okDrive;
  DriveComboBox1.DirList:=DirectoryListBox[jDBox];
  DirectoryListBox[jDBox].Update;
  FileListBox[jFBox].Update;

  DirectoryListBox[gDBox].Free; {使えなくなった古いのは廃棄}
  FileListBox[gFBox].Free;

  gDBox:=jDBox; gFBox:=jFBox;

  badDrive:=okDrive;
end; {RenewDirFileBox}

procedure TForm1.CreateFileListBox(iBox: integer);
例:SetBounds(180,20,145,157);

procedure TForm1.CreateDirectoryListBox(iBox: integer);
例:SetBounds(20,20,145,157);

procedure TForm1.AppExcept(Sender: TObject; E: Exception);
begin
  if E is EInOutError then begin
    if EInOutError(E).ErrorCode in
      [3]   {不正なファイル名です}
      then begin
      if (UpCase(fDrive)=UpCase(gDrive)) or
        (DriveState(gDrive) and
        (not DriveState(fDrive))) then begin
        RenewDirFileBox(gDrive,fDrive);
      end;
    end;
  end;
end; {AppExcept}

procedure TForm1.DriveComboBox1Click(Sender: TObject);
var
  aDrive: char;
begin
  fDrive:=DriveComboBox1.Drive;
  gDrive:=(DriveComboBox1.Items[DriveComboBox1.ItemIndex])[1];
  if (UpCase(fDrive)=UpCase(gDrive)) and DriveState(gDrive)
    then begin
    DirectoryListBox[gDBox].Update;
    FileListBox[gFBox].Update;
  end else if (not DriveState(fDrive)) and
    (not DriveState(gDrive)) then begin
    {FDにはもはやアクセスできない}
    aDrive:=gDrive;
    gDrive:=GetNearHD(ord(UpCase(aDrive))-ord('A')+1);
    ShowMessage(UpCase(fDrive)+':ドライブ、'+UpCase(aDrive)+
      ':ドライブには'#13+'アクセスできませんので'#13+
      gDrive+':ドライブを表示します。');
    RenewDirFileBox(gDrive,fDrive);
  end else if DriveState(fDrive) and
    (not DriveState(gDrive)) then begin
    ErrMes:=gDrive+':ドライブの準備ができていません';
    ShowMessage(ErrMes);
    UpdateDrive(fDrive,gDrive); {OK}
  end else if DriveState(gDrive) and
    (not DriveState(fDrive)) then begin
    RenewDirFileBox(gDrive,fDrive);
  end
end;

procedure TForm1.FormDestroy(Sender: TObject);
{同じ}

end.
{----- ここまで ----------------------------------------------------}

 (注*1):
>SBORLAND/旧9/10963 水無月紗羅さん、Re*2:DriveComboBoxのホ゛リューム名取得タイミンク゛
>(96/05/06)

>SBORLAND/旧9/18204 tac さん、      RE^5:DriveComboBox の更新方法は?
>( 9)   96/09/11


ここにあるドキュメントは NIFTY SERVEの Delphi Users' Forum FDELPHIに寄せられる質問の中から、よくある質問への回答を FDELPHIのメンバーがまとめたものです。 したがって、これらの回答はボーランド株式会社がサポートする公式のものではなく、掲示されている内容についての問い合わせは受けられない場合があります。

Copyright 1996-1998 Delphi Users' ForumFAQ編纂委員会