[BlueLeaf1336]> PROBLEMS> ClickThereItIs!>
| history | TOP |
2004/02/01:作成
| とりあえず動く奴 | TOP |
2004/02/01
CAUTION!! ALPHA VERSION!! AT YOUR OWN LISK!!
とりあえずEXEとソース。20040131ClickHereItIs.zip(10,562bytes)
警告!! 開発版です!! 保証できません!!
動作確認は、Windows2000sp4 + IE6 + Full Windows-Updateで行っています。
さて、ちょっとだけ使い方を説明しておきます。何をしているのかはこれまでのページとこのページで一部を説明します。
まずダウンロードしたファイルを解凍するといくつかのファイルが入っていますが、実行に必要なのは
だけです。で、(当然ですが)EXEをダブルクリックすると次のようなヘナチョコな画面が開きます。
特に気にする必要はありません。ただ、常に最前面に居座るので邪魔です。適当に端っこに移動しておいて下さい。
次に、エディタを開きます。別にエディタでなくてもかまわないのですが、「ファイルを開く」あるいは「ファイルを保存」するダイアログが次の図のような奴でないと駄目です。
OKOKOKOKOKOKOKOKOKOKOKOKOKOKOKOKOKOKOKOKOKOKOK
OKOKOKOKOKOKOKOKOKOKOKOKOKOKOKOKOKOKOKOKOKOKOK
つまり、左側に便利なボタンのついているダイアログには対応できていません。次のような奴は駄目です。
NGNGNGNGNGNGNGNGNGNGNGNGNGNGNGNGNGNGNGNGNGNGNGNGNGNGNGNG
NGNGNGNGNGNGNGNGNGNGNGNGNGNGNGNGNGNGNGNGNGNGNGNGNGNGNGNG
で、「ファイルを開く」ダイアログあるいは「ファイルを保存する」ダイアログを開いて、
のいずれかをクリックしてみてください。今はエディタ(等の対象プログラム)が非アクティブになってしまいますが、それでもダイアログの示している場所が変化していることが確認できると思います。ただ、なんか変更反映タイミングがもうひとつです。やってもらえれば分かると思います。確かにクリックしているのに変更されない場合は、いろんなフォルダをクリックしたり、一旦エディタをアクティブにしたりしてみてください。特にタスクバーでアクティブにしたフォルダなんかはテキメンに反映されません。
でもまあ、先が見えてきました。
| Open/SaveAsダイアログかどうか | TOP |
2004/02/01
現在次のコードで、CBTフックから飛んできた全種類ダイアログから「ファイルを開く」「ファイルを保存する」ダイアログを見分けています。多分だめだめですが、とりあえず動いているようです。
uses
dlgs;
(*
===========================================================================
Open/SaveAsダイアログかどうか(だいたい)
---------------------------------------------------------------------------
http://www1.harenet.ne.jp/cgi-bin/cgiwrap/unaap/chtml/chtml.cgi?key=comdlg1
===========================================================================
*)
function IsOpenSaveAsDialog(WH: HWND): Boolean;
var
Check: HWND;
begin
Result := false;
// 以下に上げる標準と思われるコントロールを持ってればOK
Check := GetDlgItem(WH, stc2); // ファイルの種類(&T)
if (Check = 0) then Exit;
Check := GetDlgItem(WH, stc3); // ファイル名(&N)
if (Check = 0) then Exit;
Check := GetDlgItem(WH, stc4); // ファイルの場所(&I)
if (Check = 0) then Exit;
Check := GetDlgItem(WH, cmb2); // ファイルの場所選択コンボ
if (Check = 0) then Exit;
Check := GetDlgItem(WH, lst1); // リストビュー
if (Check = 0) then Exit;
Check := GetDlgItem(WH, chx1); // 読取専用ファイルとして開く(&R)チェック
if (Check = 0) then Exit;
Check := GetDlgItem(WH, cmb1); // ファイルの種類選択コンボ
if (Check = 0) then Exit;
Check := GetDlgItem(WH, edt1); // ファイル名入力エディット
if (Check = 0) then Exit;
Check := GetDlgItem(WH, IDOK); // 開く(&O)ボタン
if (Check = 0) then Exit;
Check := GetDlgItem(WH, IDCANCEL); // キャンセルボタン
if (Check = 0) then Exit;
Result := true;
end;
| クリックされた位置のパスを求める | TOP |
2004/02/01
次に、現在次のコードで、「マウスクリックされた場所のフォルダパスの取得」を行っています。
uses
ShlObj, ActiveX;
(*
===========================================================================
デスクトップパスを取得する
---------------------------------------------------------------------------
http://homepage1.nifty.com/MADIA/delphi/Win32API/ShFolder.htm
http://homepage2.nifty.com/Mr_XRAY/Delphi/plFileDialog/B_BrowseFolder.htm
===========================================================================
*)
function GetDeskTopPath():string;
var
Root : PItemIDList;
Buffer: PChar;
Memory: IMalloc;
begin
SHGetMalloc(Memory);
Buffer := Memory.Alloc(MAX_PATH);
// 特殊フォルダの位置を取得する
SHGetSpecialFolderLocation(Application.MainForm.Handle, CSIDL_DESKTOP, Root);
// ItemIDList構造体からパス名を取り出す
SHGetPathFromIDList(Root, Buffer);
Result := Buffer;
// メモリの解放
Memory.Free(Root);
Memory.Free(Buffer);
end;
(*
===========================================================================
マウスがデスクトップにある場合にデスクトップへのパスを返す
マウスがフォルダ内にある場合にそのフォルダへのパスを返す
マウスがエクスプローラにある場合にそのフォルダへのパスを返す
マウスがよく分からない場所にある場合には空文字を返す
---------------------------------------------------------------------------
http://hp.vector.co.jp/authors/VA020801/lnkpg/sample/getexp.txt
http://hp.vector.co.jp/authors/VA009712/take/delphi/kabeapp.htm
===========================================================================
*)
function GetFullPathOfMouse(): string;
var
WndClassName: string;
Buf: array[0..255] of Char;
WH: HWND;
begin
Result := '';
// マウス直下のウィンドウの一番天辺の親ウィンドウのハンドル
WH := GetMostTopLevelWindow(WindowFromPoint(Mouse.CursorPos));
// そのウィンドウのクラス名
WndClassName := GetClassNameStr(WH);
// デバッグ
Application.MainForm.Caption := WndClassName;
// フォルダかエクスプローラ
if (WndClassName = 'CabinetWClass') or (WndClassName = 'ExploreWClass') then
begin
// WorkerW ウィンドウ検索
WH := FindWindowEx(WH, 0, 'WorkerW', nil);
if (WH <> 0) then
begin
// ReBarWindow32 ウィンドウ検索
WH := FindWindowEx(WH, 0, 'ReBarWindow32', nil);
if (WH <> 0) then
begin
// ComboBoxEx32 ウィンドウ検索
WH := FindWindowEx(WH, 0, 'ComboBoxEx32', nil);
if (WH <> 0) then
begin
// そいつのテキストを取得
FillChar(Buf, SizeOf(Buf), #0);
SendMessage(WH, WM_GETTEXT, SizeOf(Buf), Integer(@Buf));
Result := Buf;
end;
end;
end;
end
else
// デスクトップ
if (WndClassName = 'Progman') then
begin
Result := GetDeskTopPath();
end;
end;
いくつか登場しているクラス名が何なのか?については、コード中の参考URLを見てもらったり次の図を見てもらったりして判断してください。まず、適当なフォルダを開いた状態でそのフォルダウィンドウのウィンドウ階層図を取り出したものです。で、上記の見たこともないようなクラスは「アドレス(&D)」に辿り着くための階層だったわけです。
それからデスクトップを構成しているウィンドウの階層図です。「Progman」が天辺にあればデスクトップだろう...と。で、デスクトップならば、アドレスもくそもなく別の手段でデスクトップのフォルダパスを取得してやろうということです。
ただし、この方法で取得したデスクトップには「マイコンピュータ」や「マイネットワーク」が現れません。ご愁傷様です。
| ターゲットのダイアログの表示中のパスを書き換える | TOP |
2004/02/01
で、悩みに悩んでネットで見つけて「なるほどー」と納得したダイアログの表示パスの書き換えコードです。
(*
===========================================================================
指定のダイアログにパス変更させてみる
---------------------------------------------------------------------------
http://www.kumei.ne.jp/c_lang/sdk4/sdk_301.htm
http://forum.nifty.com/fdelphi/samples/00908.html
===========================================================================
*)
procedure SetDialogPath(WH: HWND; Path: string);
var
EditWH, OkWH: HWND;
Buf: array[0..255] of Char;
PreText: string;
begin
// Editコントロール検索
EditWH := GetDlgItem(WH, edt1);
// 今の文字列をバックアップしておく
FillChar(Buf, SizeOf(Buf), #0);
SendMessage(EditWH, WM_GETTEXT, SizeOf(Buf), Integer(@Buf));
PreText := Buf;
// 書き込む
SendMessage(EditWH, WM_SETTEXT, 0, Longint(PChar(Path)));
// OKボタン検索
OkWH := GetDlgItem(WH, IDOK);
// OKボタン押す
SendMessage(OkWH, BM_CLICK, 0, 0);
// 元に戻す
SendMessage(EditWH, WM_SETTEXT, 0, Longint(PChar(PreText)));
end;
この関数を呼ぶ前に、そのウィンドウが確かに本物の「ファイルを開く」「ファイルを保存する」ダイアログであることは確認しておけよ。というスタンスです。
| フック | TOP |
2004/02/01
で、一番重要で動作が妙だと感じるフックですが、CBTフックを使用しています。で、ウィンドウが作られる瞬間とウィンドウが破棄される瞬間とアクティブなウィンドウが切り替わる瞬間に本体プログラムに対してメッセージを投げています。作成タイミングと破棄タイミングは完璧に予想通りの動作をしていると思いますが、アクティブなウィンドウが切り替わるタイミングが微妙で動作が妙だと感じる原因になっています。
道半ばです。
前ページで、6ページぐらいかも、と予想してましたが一気に進んだのでアレは嘘です。
| EOF | TOP |