喫茶XRAYトップページ

[スレッド全体
]

[1540] TWebBrowserでローカルPCのフォルダ内表示返信 削除
2008/2/9 (土) 23:00:49 Mr.XRAY
▼ 宮さん

今日,というより,今やっていました.それは,

> (#なぜSysListView32なのかは解りません)

これに早く注目すべきでした.
この情報がなかったら永遠に気づかなかったでしょう.

TWebBroswerにローカルのフォルダを指定してNavigateすると,エクスプローラの
アイコン表示のListViewをOleコンテナにするようです.
で,とりあえず,表示しているファイル名が取得できるハズですのでやってみました.
次は,フォーカスのあるファイル名の取得です.
しばらくお持ちくださいませ.
これならなんとかいけるかも知れません(あまり自信はないですが).

なんと言っても,この方面にはほとんどといっていいぐらい興味がないものです
から.フックだったら興味あるんですが.フックのコードもUPしましょうか?
リストビューのメソッド類は以下を参照
http://mtbeta.msdn.microsoft.com/ja-jp/library/aa923178.aspx?altlang=ja-jp

uses  CommCtrl,WinSearch;

{$R *.dfm}

//=============================================================================
//  確実動作のため,最初から表示しない
//=============================================================================
procedure TForm1.FormShow(Sender: TObject);
begin
     Edit1.Text := 'D:\デジカメ画像\20060929大阪';
     Memo1.ScrollBars := ssVertical;
end;
//=============================================================================
//  つまりボタンクリックで表示開始
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
begin
     WebBrowser1.Navigate(Edit1.Text);
end;
//=============================================================================
//  表示ファイル名のリストを表示
//=============================================================================
procedure TForm1.Button2Click(Sender: TObject);
var
     hListView : HWND;
     ItemCount : Integer;
     i         : Integer;
     pszText   : array[0..255] of AnsiChar;
     Str       : String;
begin
     Memo1.Lines.Clear;
     Memo1.Lines.BeginUpdate;

     //Explorerで使用しているListViewのハンドルを取得
     //FindChildOfClassはHalbow資料館のWinSearch.pasを利用した...
     hListView := FindChildOfClass(Handle,'SysListView32');

     //アイテム数を取得
     ItemCount := ListView_GetItemCount(hListView);

     //アイテムの文字列(ファイル名)を順番に取得してメモに表示
     for i:=0 to ItemCount-1 do begin
       ListView_GetItemText(hListView,i,0,pszText,SizeOf(pszText));
       Str := pszText;
       Memo1.Lines.Add(Str);
     end;
     Memo1.Lines.EndUpdate;
end;


[1541] Re:TWebBrowserでローカルPCのフォルダ内表示返信 削除
2008/2/10 (日) 00:25:29 Mr.XRAY
▼ 宮さん

後何を調べればいいでししょうか?

(1)選択している,あるいはフォーカスのあるItemを取得する
(2)マウスクリックで,そのクリック位置のItemを取得する

ただし,(2)の場合には,コンテキストメニューとの兼ね合いがあるので,
これをどういった仕様にするかということになりますが.


[1542] Re2:TWebBrowserでローカルPCのフォルダ内表示返信 削除
2008/2/10 (日) 11:14:15 Mr.XRAY
一応やってみました.

(1)Button1クリックでフォルダ内のファイルをアイコン表示
   アイコン表示しかできないようです.
(2)SpeedButtonクリックで選択ファイルのファイル名をMemo1に表示
(3)ファイル上のマウス右クリックで,選択ファイルをMemo1に表示

後は適当に....
動作確認環境 WindowsXP(SP2) + Delphi7 Pro

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, OleCtrls, SHDocVw, ExtCtrls, Buttons;

type
  TForm1 = class(TForm)
    Panel1: TPanel;
    WebBrowser1: TWebBrowser;
    Panel3: TPanel;
    Button1: TButton;
    Edit1: TEdit;
    SpeedButton1: TSpeedButton;
    Panel2: TPanel;
    Splitter1: TSplitter;
    Memo1: TMemo;
    procedure FormShow(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure SpeedButton1Click(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure WebBrowser1NavigateComplete2(Sender: TObject;
      const pDisp: IDispatch; var URL: OleVariant);
  private
    { Private 宣言 }
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;

implementation

// WinSearch.pasはHalbow資料館のもの
uses  CommCtrl,WinSearch;

var
     hListView : HWND;
     ItemCount : Integer;
     HookID    : THandle;
const
    LV_name = 'SysListView32';

{$R *.dfm}

//=============================================================================
//  マウスフック関数
//  右ボタンのみ検出
//  [参考]
//  ポップアップメニューを非表示にするにはResultにHC_SKIPを返す
//=============================================================================
function MouseProc(nCode: Integer; wParam, lParam: Longint): Longint; stdcall;
var
    szClassName : array[0..255] of Char;
begin
     if (nCode < 0) then begin
       Result := CallNextHookEx(HookID, nCode, wParam, lParam);
       exit;
     end;
 
     if (wParam = WM_RBUTTONUP) then begin
       GetClassName(PMOUSEHOOKSTRUCT(lParam)^.HWND,szClassName,SizeOf(szClassName));
       if lstrcmp(@szClassName[0], @LV_name[1]) = 0 then begin
         Form1.SpeedButton1Click(nil);
       end;
     end;
     Result := CallNextHookEx(HookID, nCode, wParam, lParam);
end;
//=============================================================================
//  確実動作のため,最初から表示しない
//=============================================================================
procedure TForm1.FormShow(Sender: TObject);
begin
     Edit1.Text := 'D:\デジカメ画像\20060929大阪';
     Memo1.ScrollBars := ssVertical;
     Memo1.Lines.Clear;

     //フック開始
     HookID := SetWindowsHookEx(WH_MOUSE, MouseProc, 0, GetCurrentThreadId());
end;
//=============================================================================
//  フック終了
//=============================================================================
procedure TForm1.FormDestroy(Sender: TObject);
begin
    if HookID <> 0 then UnHookWindowsHookEx(HookID);
end;
//=============================================================================
//  ボタンクリックで表示開始
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
begin
     WebBrowser1.Navigate(Edit1.Text);
end;
//=============================================================================
//  表示終了したら
//  ListViewのハンドルとItem数(ファイル数)を取得しておく
//=============================================================================
procedure TForm1.WebBrowser1NavigateComplete2(Sender: TObject;
  const pDisp: IDispatch; var URL: OleVariant);
begin
     //TWebBrowserで使用しているListViewのハンドルを取得
     //FindChildOfClassはHalbow資料館のWinSearch.pasを利用した...
     hListView := FindChildOfClass(Handle,LV_Name);

     //アイテム(ファイル)数を取得
     ItemCount := ListView_GetItemCount(hListView);
end;
//=============================================================================
//  ListViewのメソッド類については以下を参照
//  http://mtbeta.msdn.microsoft.com/ja-jp/library/aa923178.aspx?altlang=ja-jp
//  FindItemというのがあるので,そちらの方がいいかも知れない
//  選択やフォーカス状態が見やすい様にスピードボタンで
//=============================================================================
procedure TForm1.SpeedButton1Click(Sender: TObject);
var
     iState  : Integer;
     i       : Integer;
     mask    : Integer;
     pszText : array[0..255] of AnsiChar;
     Str     : String;
begin
     //フォーカス状態も検出するのであれば mask := LVIS_SELECTED or LVIS_FOCUSED;
     mask := LVIS_SELECTED;
     for i:=0 to ItemCount-1 do begin
       iState := ListView_GetItemState(hListView,i,mask);

       //選択中の時(反転表示)
       if (iState and LVIS_SELECTED)<>0 then begin
         ListView_GetItemText(hListView,i,0,pszText,SizeOf(pszText));
         Str := pszText;
         Memo1.Lines.Add(Str+' 選択');
       end;
     end;
end;

end.

ソースコード付けました.ダウンロードできます.
■添付ファイル webbrowser_test0.zip

[1550] Re3:TWebBrowserでローカルPCのフォルダ内表示返信 削除
2008/2/14 (木) 15:29:28 宮 〔HomePage
▼ Mr.XRAYさん
> 一応やってみました.
>
> (1)Button1クリックでフォルダ内のファイルをアイコン表示
>    アイコン表示しかできないようです.
> (2)SpeedButtonクリックで選択ファイルのファイル名をMemo1に表示
> (3)ファイル上のマウス右クリックで,選択ファイルをMemo1に表示



Mr_XRAYさん、皆さんありがとうございました。
亀レスですみません。
本当に、難しいとはココに限ります。DelphiQ&Aではとてもココまで
追求は出来なかったでしょう。
感謝します。

アイコンをコンテキストメニューの代わりに右クリックで
ファイルバスを取得して、自分の指定したビューワーに表示したいですから
番号でいえば(3)になると思います。

ぼ〜っとしていたわけではありませんで、自分の知識レベルでは
途中経過では、ついて行けないので、傍観させて頂いていました。

それと、私の既存のプログラムにファイルコピー、削除、移動
コンポーネントにSHFILEOPSTRUCTを使っていましたが、
CPU負荷が大きいのとリソースを食うので、
使いやすい?ようにしたShfOperationコンポーネントに切り替えていましたが、
このコンポーネントのバグ(仕様かも)
を発見しまして、大変だと、その再現テストと修正、検証を夢中でやっていました。

長文になりますが、かいつまんで書きますと、
コピー先に同じファイル名で更新日が新しいファイルがあった場合
コピー元ファイルが同じ名前で更新日が古い場合、
ファイル名に日付文字列を付けて名前変更してコピーするとき

ShfOperationは、名前を変更できないでコピー〜を勝手に付けてコピーするが、
SHFILEOPSTRUCTは、正常に名前を変えてくれてコピーできる。
例とコード(略)

FromFile         D:\マイ ドキュメント\Temp\aaa.txt (2005/10/01/ 12:35)
ToFile(コピー先)D:\pppppp\aaa.txt(更新日 2008/02/14/ 20:15)
ファイル名を変更する。
  //SearchRec.Timeは検出した aaa.txtの 更新日2005/10/01 12:35.
 yyyymmdd:= FormatDateTime('yyyymmddhhnnss', FileDateToDateTime(SearchRec.Time));
 ToFile2:=D:\pppppp\aaa.txt; ←最初予定したコピー先ファイル名,これを変更する
 LastDelim := LastDelimiter('.', ToFile2);
 Insert( '['+yyyymmddhhnnss+']', ToFile2, LastDelim);
 ToFile:=ToFile2;
 
 ShowMessage(ToFile);→(D:\pppppp\aaa[200510011235].txt)

        ForceDirectories(ExtractFilePath( ToFile));

        ShfOperation1.OperationF:=foCOPY;
        ShfOperation1.Options.RENAMEONCOLLISION:=true;
        ShfOperation1.Options.NOCONFIRMMKDIR:=true;
 
        ShfOperation1.FromFFList.Clear;
        ShfOperation1.FromFFList.Add(FromFile);
        ShfOperation1.ToFolder:= ExtractFilePath( ToFile);
        ShfOperation1.ToFiles.Add(ToFile);
        ShfOperation1.Execute;
コピー 〜aaa.txtになる。




[1553] Re4:TWebBrowserでローカルPCのフォルダ内表示返信 削除
2008/2/14 (木) 23:38:13 Mr.XRAY
▼ 宮さん

お疲れさまです.

> 本当に、難しいとはココに限ります。DelphiQ&Aではとてもココまで
> 追求は出来なかったでしょう。


そんなことないと思いますけど.
ただ,ここは雑談系なので,レスする私も,特に解決レスでなくとも,取り敢えず
レスする,という軽い気持ちで反応できますから.
一方Q & Aの方ですと,やはり構えてしまいます.
Q & Aでの質問では,こちらも質問という状態で読みますから,環境とか状況説明
に不足があると,
「もっとわかりやすく書けないのかよ?」
と思ってしまいますが,ここでの質問の場合,別にそういう精神状態にはなら
ないから不思議です.やりとりしながら聞いていけばいいやと.

もちろん,Q & Aも個人の方が運営されているわけですが,多くの人が訪れている
ことから,公的な要素があるようにも思います.

情報の有効利用という意味では,ここよりも Q & AとかDelphi談話室,
あるいはMLの方が,プログラミング関係はいいのでしょうけど.
それに,知識がある方が閲覧している可能性がはるかにあります.

まっ,でも堅いこと言わずに...
ここでダメだったら,他で質問しなおすとか...
解決をお急ぎの方の質問は,ここはでは無理があるでしょう.多分.
寒村の片隅の小さな,さびれた喫茶店でごさいますよ.ここは.(^_^;)

# そう言えば,プリンタの質問のところでDEKOさんが怒っているみたい.
# (^O^) (不謹慎!?)

[▼次のスレッド]
INCM/CMT
Cyclamen v3.82