OKWAVEのAI「あい」が美容・健康の悩みに最適な回答をご提案!
-PR-
解決
済み

LVM_HITTEST

  • 困ってます
  • 質問No.180648
  • 閲覧数598
  • ありがとう数6
  • 気になる数0
  • 回答数5
  • コメント数0

お礼率 90% (37/41)

マウス位置に存在するエクスプローラ内のアイテムを取得しようと思っております。

エクスプローラの左側のフォルダ一覧(クラス名:SysTreeView32)と右側のファイルとフォルダ名の一覧(クラス名:SysTreeView32)において、そのSysListView32内のマウス位置に存在するアイテムを取得したいのです。

なぜかというと、オリジナルアプリ内のリストビューにFTPサーバのファイル一覧を出力し、リストビューからエクスプローラへの直接ドラッグにより、サーバからローカル\TempにDLして、ドラッグ先にDLしたファイルを移動したいのです。

現状としてはLVM_HITTESTをエクスプローラ内のSysListView32に送っているのですが、こちらが送ったLVHITTESTINFO構造体のXYと、SpyでみたXYの値が違っているのです。結果としてアイテムインデックスを得ることができませんでした。

参考までに、LVM_GETITEMCOUNTはエクスプローラからも取得できました・・・

どのようにしたら、マウス位置のアイテムを取得することができるのでしょうか?


簡単に処理内容を記します。
ドラッグ時に
GetCursorPos:マウス位置を取得
WindowFromPoint:マウス位置のハンドル取得
GetClassName:マウス位置のハンドルよりそのオブジェクトのクラス名を取得
以下は[クラス名=SysListView32]のときのみの処理
ScreenToClient:SysListView32をベースとした座標に変換
SendMessage: TVM_HITTESTと、LVHITTESTINFO構造体を送る

以上です。

本当は・・・
アプリはVBにて製作中なのですが、この手の質問はこちらのCの掲示板の方が回答を望めるかもと思って、こちらに質問させていただきました。Cで答えていただいて結構です。こちらでコンバートしますので。。。


どうぞよろしくお願いいたします。m(__)m
通報する
  • 回答数5
  • 気になる
    質問をブックマークします。
    マイページでまとめて確認できます。

質問者が選んだベストアンサー

  • 回答No.3
レベル8

ベストアンサー率 60% (21/35)

実際に試した訳じゃないのでうまくいくか分かりませんが、
思い付いた事を....

たしか今回のように別のプロセスにあるウィンドウを調べようとした場合、
LVM_GETITEMCOUNTのようにSendMessageの戻り値で取得するのは
問題ないけど、LVM_HITTESTのように構造体のアドレスを渡す場合には
CreateFileMappingとMapViewOfFileを使って、共有メモリから
割り当てなければならなかったと思います。

// 共有メモリをオープン
HANDLE hFileMapping = CreateFileMapping((HANDLE)0xFFFFFFFF, NULL,PAGE_READWRITE, 0, sizeof(LVHITTESTINFO), NULL);
LVHITTESTINFO* pHitTestInfo = (LVHITTESTINFO*)MapViewOfFile(hFileMapping, FILE_MAP_ALL_ACCESS, 0, 0, 0);

//LVHITTESTINFO構造体への値設定
・・・

//HitTest
SendMessage(hSysWnd, LVM_HITTEST, 0, (LPARAM)pHitTestInfo);

// 共有メモリをクローズ
UnmapViewOfFile(pHitTestInfo);
CloseHandle(hFileMapping);
補足コメント
TAGOSAKU7

お礼率 90% (37/41)

現在VBのコードで、HitTestマクロを改良中です。
教えていただいたコードを参考に、このような状況になりました。

わかりずらいかもしれませんが、VBではAPIを呼ぶときに呼びたいAPI関数の宣言を先頭に行います。ですのでポインタで渡さなければならない部分は、きちんとポインタ渡しになっております。

Private Function ListView_HitTest(hwndLV As Long, pInfo As LVHITTESTINFO) As Long
  Dim hFileMapping  As Long
  Dim pHitTestInfo  As Long
  
  '共有メモリをオープン
  hFileMapping = CreateFileMapping(&HFFFFFFFF, ByVal 0&, PAGE_READWRITE, 0, LenB(pInfo), ByVal 0&)
  pHitTestInfo = MapViewOfFile(hFileMapping, FILE_MAP_ALL_ACCESS, 0&, 0&, 0&)
  
  'パラメータによって受けた値を、共有メモリ領域にコピー
  Call CopyMemory(ByVal pHitTestInfo, pInfo, Len(pInfo))
  
  'ヒットテスト
  ListView_HitTest = SendMessage(hwndLV, LVM_HITTEST, 0, ByVal pHitTestInfo)
  Call CopyMemory(pInfo, ByVal pHitTestInfo, Len(pInfo))
  
  'それぞれ開放
  Call UnmapViewOfFile(pHitTestInfo)
  Call CloseHandle(hFileMapping)
End Function

で現状としては、自アプリ中のリストビューからリストビューへのHITTESTは求めている結果を得ることができます。エクスプローラ内のリスビューに送ると、エクスプローラが落ちます。共有メモリの取得失敗?

最初に述べているようにVBで作成中です。使用しているリストビューは、VBのコントロールのリストビューです。スパイで監視したところ、ヒットテストのメッセージがそのVBリストビューコントロールで受けてないように見えます。[LVM_HITTEST]が発生していないのです。もしかして、VB仕様?もしそうなら、みなさんに迷惑をかけてしまってすいません。

もういちど、vbコントロールを使用しないで、API関数のみでリストビューを自作して調査してみます。
それでもだめなら、本当はCでDLLを作成するべきなのでしょうが、「VBでのFTPソフト」を目指しているので、できたらVBオンリーにしたいのです。。。


何はともあれもう一度チャレンジ!
投稿日時 - 2001-12-07 07:56:55
お礼コメント
TAGOSAKU7

お礼率 90% (37/41)

VB仕様かな?と思って、同様の処理をCでも作成して検証しました。

LVM_HITTESTを行うと、やはりメモリの違反が発生します。
海外サイトでも、別プロセスへのHITTESTのサンプルが存在しないのは、根本的に無理だから?

とりあえず、別方法を考えます。
投稿日時 - 2001-12-07 17:14:37
-PR-
-PR-

その他の回答 (全4件)

  • 回答No.1
レベル13

ベストアンサー率 59% (729/1235)

↓に該当しませんか? ...続きを読む
↓に該当しませんか?
補足コメント
TAGOSAKU7

お礼率 90% (37/41)

英語が苦手なのでよく理解していませんが・・・

これはListViewのHITTESTですよね。
現在の方法で、ListViewのHITTESTは可能なのですが・・・

どうやらSysListView32へのHITTESTはちょっと違うようです。
フラグをセットする以前に、メッセージで送った構造体の各値と、受けている状態をスパイでデバッグした各値が違うのです。

最初に述べたように英語が苦手なので、意味不明な返答でしたらごめんなさい。
もし、参考URLが解決策を書いているのであれば、どのような内容か教えてください。

お願いいたします。
投稿日時 - 2001-12-06 14:56:20
お礼コメント
TAGOSAKU7

お礼率 90% (37/41)

お礼ではなくさらに補足です。

デスクトップのクリック検出って、グローバルフックを使用しますよね?
だから、もしかしてフックしなくてはいけないのかな?

うーむ、行き詰まってます・・・
投稿日時 - 2001-12-06 17:40:07


  • 回答No.2
レベル13

ベストアンサー率 59% (729/1235)

>うーむ、行き詰まってます・・・ 別の方法があるかもしれません。 反則ぎみなアドバイスをひとつ。 LHUT32というフリーソフトがエクスプローラへファイルをドロップできます。 これをSpyしてみては? ...続きを読む
>うーむ、行き詰まってます・・・

別の方法があるかもしれません。
反則ぎみなアドバイスをひとつ。
LHUT32というフリーソフトがエクスプローラへファイルをドロップできます。
これをSpyしてみては?
補足コメント
TAGOSAKU7

お礼率 90% (37/41)

LHUTではないですが、類似ソフトでの調査済みなので報告します。

受け側のエクスプローラ内のSysListView32内ではLVM_HITTESTは発生しているのですが、これはエクスプローラ本体が送っているメッセージ、あるいはWINDOWSそのものが送っているメッセージであって、アプリ側からLVM_HITTESTを送っているようには見えませんでした。

知り合いに相談した結果、「おそらくファイル名ではなく、"FileContents"でStreamを渡し・・・云々」というのですが、さっぱりです。

何か手は無いものでしょうか?
投稿日時 - 2001-12-06 19:49:27
  • 回答No.4
レベル8

ベストアンサー率 60% (21/35)

エキスプローラーへのドロップという事でしたら OleDrag&Dropを使ったほうが簡単かもしれません。 SAMPLEがあるURLのせておきますので参考にしてください。 ...続きを読む
エキスプローラーへのドロップという事でしたら
OleDrag&Dropを使ったほうが簡単かもしれません。
SAMPLEがあるURLのせておきますので参考にしてください。
補足コメント
TAGOSAKU7

お礼率 90% (37/41)

ありがとうございます。
現在デバッグ中につき、報告はちょっと待ってください。
投稿日時 - 2001-12-07 09:32:54
お礼コメント
TAGOSAKU7

お礼率 90% (37/41)

ちょっとプロジェクトが大きめで、デバッグに時間がかかってしまいました。

現在作成中のアプリは、完成したら書物にしようと思っております。
VBでも一応プロセス監視などができるのですが、できるだけ使用したくない気持ちもあるのです。

参考コードをVBにコンバートしきれるかどうかがちょっと不安ですが。。。
もう少しやってみます。
投稿日時 - 2001-12-07 17:19:04
  • 回答No.5
レベル13

ベストアンサー率 59% (729/1235)

VBのサンプルです。 OleDrag&Dropで出来そうですね。 ...続きを読む
VBのサンプルです。
OleDrag&Dropで出来そうですね。
補足コメント
TAGOSAKU7

お礼率 90% (37/41)

ありがとうございます。ファイルのコピーはそれで確かにできますね。

しかし、ファイルはローカルには存在していない状態から行う処理をするのです。
FTPソフトなので、ドラッグが始まるたびにDLして、セットしていては無駄な処理が多くなります。ですので、ドラッグが終わったときにドラッグ先のパスを取得し、同名ファイルの有無を取得した後DLするかどうかの問い合わせを行って、その後にローカル¥TempにDLを行います。DLが終了したら、指定のパスにファイルを移動します。


VBのOLEStartDragはドラッグスタート時に発生するイベントです。
VBの内部で行われている処理は、StreamにCF_HDROP(VBのvbCFFiles)型のデータをセットしてしまい、受け側がその型をサポートしている場合は受け側でそれを読み取るという処理を行っていると勝手に思ってますが・・・

現在行いたいのは、ファイルのコピーや移動ではなく、そのドラッグ先のパス取得です。


※現段階の調査結果の報告
1.エクスプローラ内のリスビューに、リストビューメッセージを渡すだけの処理は可能。
2.共有メモリを使用しても、エクスプローラ内のリスビューに、パラメータに値を返すリストビューメッセージを渡すとメモリエラー発生。

2について・・・
エクスプローラはメモリの共有参照不可にしているようです。これはVBでもCでも検証しました。(技術不足?)#3の発言を元に作成したもの以外に、GlobalAllocでメモリ確保して、コールバック関数でDrag処理をさせてもリストビューのアイテムを取得しようとすると、同じ状況になります。


※今後の検証予定
Shellエクステンション系の操作を試みようと思います。
今は、どのエクスプローラが、どのフォルダを開いているかが取得可能になりました。しかしエクスプローラ内リストビューの中にサブフォルダが存在していて、そのサブフォルダの上にドラッグされたときの判断ができないので、その部分の処理を調査したいと思っています。
投稿日時 - 2001-12-10 16:09:08
お礼コメント
TAGOSAKU7

お礼率 90% (37/41)

何とか別方法で取得ができました。

共有メモリを確保して、ウィンドウズ側が発するメッセージを横取りしました。
投稿日時 - 2001-12-13 14:11:25
このQ&Aで解決しましたか?
関連するQ&A
-PR-
-PR-
こんな書き方もあるよ!この情報は知ってる?あなたの知識を教えて!
このQ&Aにはまだコメントがありません。
あなたの思ったこと、知っていることをここにコメントしてみましょう。

その他の関連するQ&A、テーマをキーワードで探す

キーワードでQ&A、テーマを検索する
-PR-
-PR-
-PR-

特集


いま みんなが気になるQ&A

関連するQ&A

-PR-

ピックアップ

-PR-
ページ先頭へ