メニュー

「メニュー」の編集履歴(バックアップ)一覧はこちら

メニュー」(2016/04/15 (金) 17:01:43) の最新版変更点

追加された行は緑色になります。

削除された行は赤色になります。

**メニュー -[[トップページ]] -[[プラグイン紹介>プラグイン]] -[[メニュー]] -[[メニュー2]] -[[Indy10]] -[[new reslult tool]] -[[TidTCP sample]] -[[リンク名>http://www30.atwiki.jp/marchaya/pages/16.html]] [[ServerSupportTEST]] [[cintanotesバックアップ]] [[TEST]] [[PingThread]] [[PingThread完成]] [[PingThread完成2]] [[PingThread完成3]] [[threadまとめ]] [[TCPServer]] ---- TIPS //パス名が必ず区切り文字で終わるようにする IncludeTrailingPathDelimiter(path); C:\test → C:\test\ C:\test\ → C:\test\ //最初から区切り文字で終わっていたら何もしない //codepage 1252でASCII文字列を使用してバイナリ相当を表現する IdTCPClient1.IOHandler.WriteDirect(StrToBytes(str,1252)); //処理にかかった時間を計測する ms:cardinal; ms := GetTickCount; 何らかの処理 ShowMessage(IntToStr(GetTickCount - ms)); //簡易メモリリーク機能を有効にする FormのCreateあたりに下記を追加 ReportMemoryLeaksOnShutdown := True //文字列の置換 usesにSystem.SysUtilsを追加 replacedValue := StringReplace(ragetValue, '/','-',[rfReplaceAll]); //'/'を'-'へ変換 //TStringListにソート属性を与える Sl.Sorted := true; ->この後これを乱すような、挿入、移動操作がエラーにる。追加・削除は可能。 しかも追加の場合、ソートされて適切な位置に納まる。 Sl.Sorted=false の状態でも、項目を Sl.Sort;にできるが、この後追加しても Sl1.Sorted=false なので追加項目は末端につく。 文字を16進数に変換 IntToHex(Ord(moji),2); Delete(Src,7,5); 7文字目から5文字分削除する ---- Delete('ABCDEF',3,2) = 'ABEF' //3文字目から2文字消す ---- str := 'Hakata'; Delete(str,Length(str)-2,3);//後ろから3文字消す => 'Hak' AnsiLeftStr(str,2); //左端から2文字抜き取る AnsiRightStr(str,2); AnsiMidStr(str,2); AnsiPos('C','ABCDE'); -> 3 AnsiPos('DE','ABCDE'); -> 4 AnsiPos('SGU','ABCDE'); -> 0 AnsiReplace(str,before,after); uses SysUtils CreateDirectory //最下層のディレクトリのみ生成 ForceDirectory //必要に応じて親ディレクトリも生成 MkDir ExtractFilePath(Application.ExeName) = C:\...\...\ 最後は\になる ディレクトリが存在しない場合は作成する。すでに存在している場合にMkDirを実行するとエラーが発生する If not DirectoryExists(ExtractFilePath(Application.ExeName) + 'NewFolder\' then //If文丈では最後に\をつける MkDir('New Folder') // '\New Folder' でも 'New Folder\'でもない AnsiCompareText(比較文字列A、比較文字列B) = +(A>B), 0(A=B), -(A<B); 文字をASCIIコードにする(10進数) Byte(s); Ord(s); <-> chr(c) IntToHex(Ord(s),1); IdUDPClient.BoundPort にて自分の送信元ポートを指定することができる。 デザイナ時のポート番号の指定は何を示しているのかは・・・?? フォルダ指定のダイアログボックスを表示する procedure TForm1.Button3Click(Sender: TObject); var RootFolder : String; SelectFolder : String; begin RootFolder := ''; SelectFolder := ''; if SelectDirectory('フォルダの指定', RootFolder, SelectFolder, [sdNewUI, sdNewFolder, sdShowEdit], Self) then begin MessageBox(Handle, PChar(SelectFolder), '選択フォルダ', MB_ICONINFORMATION); end; end; ----------------- FindFirstChangeNotification API関数は、指定したディレクトリまたは、その配下に対してファイルが作成・更新・削除されると、変更されたことを通知する。どのファイルが変更されたかは通知されない。 ただし、このAPIで通知されるのは「変更の有無」だけであり、どのファイルが変更されたかは通知されない。 変更されたファイルを知り、ファイルの変更をイベントとして扱えるようにするには、上記の変更通知だけでは対応できない。 また、変更通知は、変更があった時点で通知される。いつ、変更が完了したのかは通知からはわからない。 そのため、一定時間待って変化がなくなったときが完了したものとみなす、などの処置が必要になる。 (ログファイル等、ファイルによっては開かれっぱなしのものもあるであろうから、このあたりの判定方法はアプリケーション次第といえる。) WindowsNT系且つUNICODEビルドである場合にのみ使える方法として、ReadDirectoryChangeW関数がある。 このAPIの利点としては、変更の有無だけでなく、変更されたファイルが通知される、という点にある。 ちょっと注意しなければならないかな、と思う点は、フォルダが削除された場合、当然、フォルダ削除は通知されるが、フォルダの中にいた子も削除されたことは通知されない、という点である。 フォルダが消された場合に、それが保持していた子供も消えたことを認識させるには、やはり事前に一度はスキャンしていなければならない、ということになるだろう。 変更があった時点で通知され、いつ変更が完了したかはわからない、というのはFindFirstChangeNotificationで説明したものと同じであり、検出方法も、同様な方法をとる必要があるものと思われる。 また、MacのSMB共有でファイル通知がうまくされないところをみても、やはりファイル監視系APIではネットワークでの監視、とくに非Windowsマシンへの監視は当てにはできなさそう、という点はFindFirstChangeNotificationのケースと同じであろうことが予想される。 結論として、ReadDirectoryChangeW関数を使ったとしてもFindFirstChangeNotificationを使った場合よりロジックが劇的に簡略化されることはなく、ほぼ同等な処理が必要であり、若干の最適化のメリットがある程度と考えられる。 (ただし監視ファイル数が多い場合は、この最適化が大きなパフォーマンス上の利点を生む可能性はある。) ----------------- セキュリティ面の強化を前提に、リムーバルドライブなどの外部装置へのファイル転送を監視したいと考えています。 プログラムは常駐型で、FPDドライブにアクセスがあった際、コピーや削除などの操作をログとして取得していきたいのですが、可能でしょうか? システム操作なので、Delphiが機能的に一番サポート出来ているのでは?と思っています。 インターネットでも、該当するコーティング事例を探しましたが、見付けられませんでした。 スタテツ 2004/06/29(火) 21:40:00 概略ですが 1.WM_DEVICECHANGEでドライブの挿入検知 2.GetLogicalDrivesで使用可能なドライブを探す 3.FindFirstChangeNotificationでファイルの移動検知 でどうでしょうか? 全てサンプルはネットで入手可能かと思います。 とほほ 2004/07/01(木) 16:05:16 スタテツさん、ありがとうございます。 常駐型の大まかな雛形は出来上がったので、機能的なロジックを始めたのですが、WM_DEVICECHANGEでドライブの挿入検出を実施したところ、CD-ROMの検出は可能ですが、FPDドライブの検出確認は出来ませんでした。(エクスプローラでアクセスしても反応がありませんでした。) PFDドライブのデバイスから発生するメッセージは、取得が出来ないのでしょうか? スタテツ 2004/07/01(木) 18:14:26 PFDドライブってUSB接続のメモリースティック等ですよね? 私の方では検出します… 環境はWindowsXP sp1 + Delphi7pro up1です。 ソース unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 = class(TForm) ListBox1: TListBox; private { Private 宣言 } public { Public 宣言 } procedure WmDevChange(var Mess: TMessage); message WM_DEVICECHANGE; end; var Form1: TForm1; implementation {$R *.dfm} { TForm1 } procedure TForm1.WmDevChange(var Mess: TMessage); begin ListBox1.Items.Add(inttostr(Mess.WParam)); end; end. とほほ 2004/07/02(金) 10:42:39 すいません、FPDドライブのタイプミスでした。 CD-ROMデバイス、リムーバルデバイス(MO)は検出できたのですが、内蔵タイプのFPD(USB接続ではありません)はエクスプローラからのアクセスでは検出できませんでした。 環境はWindowsNT(WS) SP6a + Delphi6.0 up1(Personal版)です。 提供していただいたソースを実行してみましたが、結果は同じでした。 CD-ROMやMOなどは、媒体挿入時に読み込みされますが、FPDは挿入しただけでは読み込みされないため、そういった制御の違いから、WM_DEVICECHANGEでの検出はできないものなのかと手詰まりです。 スタテツ 2004/07/02(金) 12:17:36 お役に立てず申し訳ないです。 フロッピーディスクアクセスについて色々調べてみましたが、 解決策には至りませんでした。相当難しそうです。 回避としては 1.デバイスマネージャでFDのデバイスを使用不可にしてしまう 2.アプリケーション起動時にFDを挿入しておいてFindFirstChangeNotificationを実行してしまう。 両方穴はありますが… とほほ 2004/07/02(金) 13:08:27 スタテツさん、色々ありがとうございました。 私も調べてみましたが、こんなに難しいとは思いませんでした。市販の監視ソフトで、FPD監視が出来ない旨がありましたので、それなら作ってやれ!と活き込んだまでは良かったのですが…。 FPDドライブが全く使えないとゆう利便が悪いのもネックになってしまうので…良い運用がないか検討してみます。 スタテツ 2004/07/02(金) 16:12:17 やっと分かりました。 以下のソースをタイマーとかスレッドでまわしてあげれば可能です。 フロッピーディスクが入っているかチェック procedure TForm1.Button1Click(Sender: TObject); var EMode: Word; begin EMode := SetErrorMode(SEM_FAILCRITICALERRORS); try if DiskSize(Ord('A')-$40) <> -1 then ShowMessage('Disk in drive A: !') else ShowMessage('No disk in drive A: !'); finally SetErrorMode(EMode); end; end; その他色々 http://delphi.about.com/library/weekly/aa070699.htm とほほ 2004/07/02(金) 18:07:11 すごいですね、ありがとうございます。 SetErrorModeでFPDアクセス時のコントロールが取得出来れば、検出やアクセスタイミングが図れそうですね。試してみます。ご連絡まで。 PageTop ---- **リンク -[[@wiki>>http://atwiki.jp]] -[[@wikiご利用ガイド>>http://atwiki.jp/guide/]] // リンクを張るには "[" 2つで文字列を括ります。 // ">" の左側に文字、右側にURLを記述するとリンクになります //**更新履歴 //#recent(20) &link_editmenu(text=ここを編集)
**メニュー -[[トップページ]] -[[プラグイン紹介>プラグイン]] -[[メニュー]] -[[メニュー2]] -[[Indy10]] -[[new reslult tool]] -[[TidTCP sample]] -[[リンク名>http://www30.atwiki.jp/marchaya/pages/16.html]] [[ServerSupportTEST]] [[cintanotesバックアップ]] [[TEST]] [[PingThread]] [[PingThread完成]] [[PingThread完成2]] [[PingThread完成3]] [[threadまとめ]] [[TCPServer]] [[TCPクライアント・サーバー例]] ---- TIPS //パス名が必ず区切り文字で終わるようにする IncludeTrailingPathDelimiter(path); C:\test → C:\test\ C:\test\ → C:\test\ //最初から区切り文字で終わっていたら何もしない //codepage 1252でASCII文字列を使用してバイナリ相当を表現する IdTCPClient1.IOHandler.WriteDirect(StrToBytes(str,1252)); //処理にかかった時間を計測する ms:cardinal; ms := GetTickCount; 何らかの処理 ShowMessage(IntToStr(GetTickCount - ms)); //簡易メモリリーク機能を有効にする FormのCreateあたりに下記を追加 ReportMemoryLeaksOnShutdown := True //文字列の置換 usesにSystem.SysUtilsを追加 replacedValue := StringReplace(ragetValue, '/','-',[rfReplaceAll]); //'/'を'-'へ変換 //TStringListにソート属性を与える Sl.Sorted := true; ->この後これを乱すような、挿入、移動操作がエラーにる。追加・削除は可能。 しかも追加の場合、ソートされて適切な位置に納まる。 Sl.Sorted=false の状態でも、項目を Sl.Sort;にできるが、この後追加しても Sl1.Sorted=false なので追加項目は末端につく。 文字を16進数に変換 IntToHex(Ord(moji),2); Delete(Src,7,5); 7文字目から5文字分削除する ---- Delete('ABCDEF',3,2) = 'ABEF' //3文字目から2文字消す ---- str := 'Hakata'; Delete(str,Length(str)-2,3);//後ろから3文字消す => 'Hak' AnsiLeftStr(str,2); //左端から2文字抜き取る AnsiRightStr(str,2); AnsiMidStr(str,2); AnsiPos('C','ABCDE'); -> 3 AnsiPos('DE','ABCDE'); -> 4 AnsiPos('SGU','ABCDE'); -> 0 AnsiReplace(str,before,after); uses SysUtils CreateDirectory //最下層のディレクトリのみ生成 ForceDirectory //必要に応じて親ディレクトリも生成 MkDir ExtractFilePath(Application.ExeName) = C:\...\...\ 最後は\になる ディレクトリが存在しない場合は作成する。すでに存在している場合にMkDirを実行するとエラーが発生する If not DirectoryExists(ExtractFilePath(Application.ExeName) + 'NewFolder\' then //If文丈では最後に\をつける MkDir('New Folder') // '\New Folder' でも 'New Folder\'でもない AnsiCompareText(比較文字列A、比較文字列B) = +(A>B), 0(A=B), -(A<B); 文字をASCIIコードにする(10進数) Byte(s); Ord(s); <-> chr(c) IntToHex(Ord(s),1); IdUDPClient.BoundPort にて自分の送信元ポートを指定することができる。 デザイナ時のポート番号の指定は何を示しているのかは・・・?? フォルダ指定のダイアログボックスを表示する procedure TForm1.Button3Click(Sender: TObject); var RootFolder : String; SelectFolder : String; begin RootFolder := ''; SelectFolder := ''; if SelectDirectory('フォルダの指定', RootFolder, SelectFolder, [sdNewUI, sdNewFolder, sdShowEdit], Self) then begin MessageBox(Handle, PChar(SelectFolder), '選択フォルダ', MB_ICONINFORMATION); end; end; ----------------- FindFirstChangeNotification API関数は、指定したディレクトリまたは、その配下に対してファイルが作成・更新・削除されると、変更されたことを通知する。どのファイルが変更されたかは通知されない。 ただし、このAPIで通知されるのは「変更の有無」だけであり、どのファイルが変更されたかは通知されない。 変更されたファイルを知り、ファイルの変更をイベントとして扱えるようにするには、上記の変更通知だけでは対応できない。 また、変更通知は、変更があった時点で通知される。いつ、変更が完了したのかは通知からはわからない。 そのため、一定時間待って変化がなくなったときが完了したものとみなす、などの処置が必要になる。 (ログファイル等、ファイルによっては開かれっぱなしのものもあるであろうから、このあたりの判定方法はアプリケーション次第といえる。) WindowsNT系且つUNICODEビルドである場合にのみ使える方法として、ReadDirectoryChangeW関数がある。 このAPIの利点としては、変更の有無だけでなく、変更されたファイルが通知される、という点にある。 ちょっと注意しなければならないかな、と思う点は、フォルダが削除された場合、当然、フォルダ削除は通知されるが、フォルダの中にいた子も削除されたことは通知されない、という点である。 フォルダが消された場合に、それが保持していた子供も消えたことを認識させるには、やはり事前に一度はスキャンしていなければならない、ということになるだろう。 変更があった時点で通知され、いつ変更が完了したかはわからない、というのはFindFirstChangeNotificationで説明したものと同じであり、検出方法も、同様な方法をとる必要があるものと思われる。 また、MacのSMB共有でファイル通知がうまくされないところをみても、やはりファイル監視系APIではネットワークでの監視、とくに非Windowsマシンへの監視は当てにはできなさそう、という点はFindFirstChangeNotificationのケースと同じであろうことが予想される。 結論として、ReadDirectoryChangeW関数を使ったとしてもFindFirstChangeNotificationを使った場合よりロジックが劇的に簡略化されることはなく、ほぼ同等な処理が必要であり、若干の最適化のメリットがある程度と考えられる。 (ただし監視ファイル数が多い場合は、この最適化が大きなパフォーマンス上の利点を生む可能性はある。) ----------------- セキュリティ面の強化を前提に、リムーバルドライブなどの外部装置へのファイル転送を監視したいと考えています。 プログラムは常駐型で、FPDドライブにアクセスがあった際、コピーや削除などの操作をログとして取得していきたいのですが、可能でしょうか? システム操作なので、Delphiが機能的に一番サポート出来ているのでは?と思っています。 インターネットでも、該当するコーティング事例を探しましたが、見付けられませんでした。 スタテツ 2004/06/29(火) 21:40:00 概略ですが 1.WM_DEVICECHANGEでドライブの挿入検知 2.GetLogicalDrivesで使用可能なドライブを探す 3.FindFirstChangeNotificationでファイルの移動検知 でどうでしょうか? 全てサンプルはネットで入手可能かと思います。 とほほ 2004/07/01(木) 16:05:16 スタテツさん、ありがとうございます。 常駐型の大まかな雛形は出来上がったので、機能的なロジックを始めたのですが、WM_DEVICECHANGEでドライブの挿入検出を実施したところ、CD-ROMの検出は可能ですが、FPDドライブの検出確認は出来ませんでした。(エクスプローラでアクセスしても反応がありませんでした。) PFDドライブのデバイスから発生するメッセージは、取得が出来ないのでしょうか? スタテツ 2004/07/01(木) 18:14:26 PFDドライブってUSB接続のメモリースティック等ですよね? 私の方では検出します… 環境はWindowsXP sp1 + Delphi7pro up1です。 ソース unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 = class(TForm) ListBox1: TListBox; private { Private 宣言 } public { Public 宣言 } procedure WmDevChange(var Mess: TMessage); message WM_DEVICECHANGE; end; var Form1: TForm1; implementation {$R *.dfm} { TForm1 } procedure TForm1.WmDevChange(var Mess: TMessage); begin ListBox1.Items.Add(inttostr(Mess.WParam)); end; end. とほほ 2004/07/02(金) 10:42:39 すいません、FPDドライブのタイプミスでした。 CD-ROMデバイス、リムーバルデバイス(MO)は検出できたのですが、内蔵タイプのFPD(USB接続ではありません)はエクスプローラからのアクセスでは検出できませんでした。 環境はWindowsNT(WS) SP6a + Delphi6.0 up1(Personal版)です。 提供していただいたソースを実行してみましたが、結果は同じでした。 CD-ROMやMOなどは、媒体挿入時に読み込みされますが、FPDは挿入しただけでは読み込みされないため、そういった制御の違いから、WM_DEVICECHANGEでの検出はできないものなのかと手詰まりです。 スタテツ 2004/07/02(金) 12:17:36 お役に立てず申し訳ないです。 フロッピーディスクアクセスについて色々調べてみましたが、 解決策には至りませんでした。相当難しそうです。 回避としては 1.デバイスマネージャでFDのデバイスを使用不可にしてしまう 2.アプリケーション起動時にFDを挿入しておいてFindFirstChangeNotificationを実行してしまう。 両方穴はありますが… とほほ 2004/07/02(金) 13:08:27 スタテツさん、色々ありがとうございました。 私も調べてみましたが、こんなに難しいとは思いませんでした。市販の監視ソフトで、FPD監視が出来ない旨がありましたので、それなら作ってやれ!と活き込んだまでは良かったのですが…。 FPDドライブが全く使えないとゆう利便が悪いのもネックになってしまうので…良い運用がないか検討してみます。 スタテツ 2004/07/02(金) 16:12:17 やっと分かりました。 以下のソースをタイマーとかスレッドでまわしてあげれば可能です。 フロッピーディスクが入っているかチェック procedure TForm1.Button1Click(Sender: TObject); var EMode: Word; begin EMode := SetErrorMode(SEM_FAILCRITICALERRORS); try if DiskSize(Ord('A')-$40) <> -1 then ShowMessage('Disk in drive A: !') else ShowMessage('No disk in drive A: !'); finally SetErrorMode(EMode); end; end; その他色々 http://delphi.about.com/library/weekly/aa070699.htm とほほ 2004/07/02(金) 18:07:11 すごいですね、ありがとうございます。 SetErrorModeでFPDアクセス時のコントロールが取得出来れば、検出やアクセスタイミングが図れそうですね。試してみます。ご連絡まで。 PageTop ---- **リンク -[[@wiki>>http://atwiki.jp]] -[[@wikiご利用ガイド>>http://atwiki.jp/guide/]] // リンクを張るには "[" 2つで文字列を括ります。 // ">" の左側に文字、右側にURLを記述するとリンクになります //**更新履歴 //#recent(20) &link_editmenu(text=ここを編集)

表示オプション

横に並べて表示:
変化行の前後のみ表示: