• ベストアンサー

LVM_HITTEST

マウス位置に存在するエクスプローラ内のアイテムを取得しようと思っております。 エクスプローラの左側のフォルダ一覧(クラス名: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

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

  • ベストアンサー
  • akinori_s
  • ベストアンサー率60% (21/35)
回答No.3

実際に試した訳じゃないのでうまくいくか分かりませんが、 思い付いた事を.... たしか今回のように別のプロセスにあるウィンドウを調べようとした場合、 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
質問者

お礼

VB仕様かな?と思って、同様の処理をCでも作成して検証しました。 LVM_HITTESTを行うと、やはりメモリの違反が発生します。 海外サイトでも、別プロセスへのHITTESTのサンプルが存在しないのは、根本的に無理だから? とりあえず、別方法を考えます。

TAGOSAKU7
質問者

補足

現在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オンリーにしたいのです。。。 何はともあれもう一度チャレンジ!

全文を見る
すると、全ての回答が全文表示されます。

その他の回答 (4)

  • todo36
  • ベストアンサー率58% (728/1234)
回答No.5

VBのサンプルです。 OleDrag&Dropで出来そうですね。

参考URL:
http://homepage2.nifty.com/inform/vbmania/source/drop2explorer.htm
TAGOSAKU7
質問者

お礼

何とか別方法で取得ができました。 共有メモリを確保して、ウィンドウズ側が発するメッセージを横取りしました。

TAGOSAKU7
質問者

補足

ありがとうございます。ファイルのコピーはそれで確かにできますね。 しかし、ファイルはローカルには存在していない状態から行う処理をするのです。 FTPソフトなので、ドラッグが始まるたびにDLして、セットしていては無駄な処理が多くなります。ですので、ドラッグが終わったときにドラッグ先のパスを取得し、同名ファイルの有無を取得した後DLするかどうかの問い合わせを行って、その後にローカル¥TempにDLを行います。DLが終了したら、指定のパスにファイルを移動します。 VBのOLEStartDragはドラッグスタート時に発生するイベントです。 VBの内部で行われている処理は、StreamにCF_HDROP(VBのvbCFFiles)型のデータをセットしてしまい、受け側がその型をサポートしている場合は受け側でそれを読み取るという処理を行っていると勝手に思ってますが・・・ 現在行いたいのは、ファイルのコピーや移動ではなく、そのドラッグ先のパス取得です。 ※現段階の調査結果の報告 1.エクスプローラ内のリスビューに、リストビューメッセージを渡すだけの処理は可能。 2.共有メモリを使用しても、エクスプローラ内のリスビューに、パラメータに値を返すリストビューメッセージを渡すとメモリエラー発生。 2について・・・ エクスプローラはメモリの共有参照不可にしているようです。これはVBでもCでも検証しました。(技術不足?)#3の発言を元に作成したもの以外に、GlobalAllocでメモリ確保して、コールバック関数でDrag処理をさせてもリストビューのアイテムを取得しようとすると、同じ状況になります。 ※今後の検証予定 Shellエクステンション系の操作を試みようと思います。 今は、どのエクスプローラが、どのフォルダを開いているかが取得可能になりました。しかしエクスプローラ内リストビューの中にサブフォルダが存在していて、そのサブフォルダの上にドラッグされたときの判断ができないので、その部分の処理を調査したいと思っています。

全文を見る
すると、全ての回答が全文表示されます。
  • akinori_s
  • ベストアンサー率60% (21/35)
回答No.4

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

参考URL:
http://support.microsoft.com/default.aspx?scid=kb;EN-US;q139067
TAGOSAKU7
質問者

お礼

ちょっとプロジェクトが大きめで、デバッグに時間がかかってしまいました。 現在作成中のアプリは、完成したら書物にしようと思っております。 VBでも一応プロセス監視などができるのですが、できるだけ使用したくない気持ちもあるのです。 参考コードをVBにコンバートしきれるかどうかがちょっと不安ですが。。。 もう少しやってみます。

TAGOSAKU7
質問者

補足

ありがとうございます。 現在デバッグ中につき、報告はちょっと待ってください。

全文を見る
すると、全ての回答が全文表示されます。
  • todo36
  • ベストアンサー率58% (728/1234)
回答No.2

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

TAGOSAKU7
質問者

補足

LHUTではないですが、類似ソフトでの調査済みなので報告します。 受け側のエクスプローラ内のSysListView32内ではLVM_HITTESTは発生しているのですが、これはエクスプローラ本体が送っているメッセージ、あるいはWINDOWSそのものが送っているメッセージであって、アプリ側からLVM_HITTESTを送っているようには見えませんでした。 知り合いに相談した結果、「おそらくファイル名ではなく、"FileContents"でStreamを渡し・・・云々」というのですが、さっぱりです。 何か手は無いものでしょうか?

全文を見る
すると、全ての回答が全文表示されます。
  • todo36
  • ベストアンサー率58% (728/1234)
回答No.1

↓に該当しませんか?

参考URL:
http://support.microsoft.com/default.aspx?scid=kb;EN-US;q135786
TAGOSAKU7
質問者

お礼

お礼ではなくさらに補足です。 デスクトップのクリック検出って、グローバルフックを使用しますよね? だから、もしかしてフックしなくてはいけないのかな? うーむ、行き詰まってます・・・

TAGOSAKU7
質問者

補足

英語が苦手なのでよく理解していませんが・・・ これはListViewのHITTESTですよね。 現在の方法で、ListViewのHITTESTは可能なのですが・・・ どうやらSysListView32へのHITTESTはちょっと違うようです。 フラグをセットする以前に、メッセージで送った構造体の各値と、受けている状態をスパイでデバッグした各値が違うのです。 最初に述べたように英語が苦手なので、意味不明な返答でしたらごめんなさい。 もし、参考URLが解決策を書いているのであれば、どのような内容か教えてください。 お願いいたします。

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • CTreeCtrlのHitTestメソッドについて

    環境:WinXP VS2005 MFC使用 CTreeCtrlに階層のあるアイテムを複数個設定しています。 ノード開閉時にカーソル位置にあるアイテムをGetCorsorPos()+HitTest()関数を使用し、取得していました。これは正しいアイテムのハンドルが返ってきています。 ところが、ある程度ノードを開いていき、表示しきれなくなるとスクロールが表示されますが、一番下までスクロールしている状態だとアイテムがうまく取得できていないようです。 おそらく、GetCursorPosが画面上の相対座標を取得するのに対し、HitTestで設定するのはツリーコントロール自体の相対座標なので、スクロールしている分だけずれてしまっているのではないかと思っているのですが、スクロールしているサイズを取得する方法がわかりませんでした。ご存じの方いましたらご教授をお願いします。 ※ソース抜粋 void CTestTreeCtrl::OnTvnItemexpanded(NMHDR *pNMHDR, LRESULT *pResult) { CPoint point; GetCursorPos(&point); ScreenToClient(&point); // マウスカーソルの位置からアイテムのハンドルを取得する HTREEITEM hItem = HitTest(point);           ・           ・           ・

  • MFCを使わずファイルをドラッグアンドドロップ

    エクスプローラーなどからドラッグしてきたファイルのパス一覧を MFCを使わず取得したいのですが、 どうすればいいのでしょうか?

  • ツリービューでのドラッグイメージの作成方法

    VC++でエクスプローラもどきを作成しています。 ListViewからTreeViewへ、ファイルをドラッグする際、 マウスカーソルにファイルイメージを追従させようとしています。 ListView内でのドラッグは作成できたのですが、 TreeViewへ移った際に、CreateDragImageでドラッグを作成するためには HTREEITEMを渡さなくてはいけません。 TreeViewで表示させているのは、フォルダアイコンのみなので、 ファイルをドラッグした際に、該当するようなitemがありません。 TreeViewへitemをinsertして表示させるわけにはいかないのですが、 このような場合、どのようにして、 ドラッグイメージを作成すべきなのでしょうか?

  • ListViewで複数項目のドラッグ&ドロップ

    やりたいことは、エクスプローラのようなアイテムのドラッグ&ドロップです。 VB付属のリストビューをそのまま使うと、大きいアイコンで表示した時、複数選択してドラッグしても動くアイテムは、1つとなってしまいます。 複数アイテムを動かす方法を知っている方がいましたら教えてほしいのですが。 環境は、 Windows2000SP3 VisualBasic6SP5 です。

  • ツリービューを使って、エクスプローラのようなものを作りたい。

    タイトルの通りです。VBで、Windowsのエクスプローラのような物を作り、それでファイルを選択したいのですがその作り方が分かりません。 任意の場所から、その最下層までのファイル名やフォルダ名を取得し、それをツリービューに表示させてエクスプローラのようなものを作りたいのです。 どなたか分かる方がおりましたら、お教えください。

  • ウインドウの取得

    かんたんYouTubeプレーヤーというソフトのウインドウハンドルを取得し、プレーヤーウインドウのサイズや位置を変更するプログラムをVB2008で作成しようとしました。このプレーヤーはリストウインドウとプレーヤーウインドウの二つがあるのですが、窓ちぇき!というソフトでタイトルとクラス名を調べたら二つとも同じタイトルとクラス名になっていました。これだとFindWindow関数でウインドウハンドルを取得できません。どうすればよいでしょうか。

  • リストビューのハンドルについて

    リストビューコントロールのハンドルについて疑問に思う事がありまして、ご教授よろしくおねがいします。 通常リストビューをCreateWindow()で作成した時に戻り値として受け取るウィンドウハンドルに対してSetWindowFont()を行うとリストビュー全体のフォントが変更されます。 リストビュー関数にはListView_GetHeader( リストビューハンドル );という関数が用意されていてリストビューのカラム部分のハンドルを取得できます。 このハンドルに対してSetWindowFont()を行うとカラム部分だけのフォントが変更されます。 という事はアイテム部分だけのハンドルを取得し、SetWindowFont()でフォントを変更する事はできるのでしょうか? ご教授よろしくお願いいたします。

  • w10 エクスプローラーでファイル名が表示される

    ある日、いつものようにw10でエクスプローラーのスクロールバーをマウスでドラッグしてスクロールした所、エクスプローラーの左側に表示されているファイルのファイル名が表示される現象が起きるようになってました。 自分で設定を変えた覚えはなく、なぜ突然表示されるようになってしまったのかも分かりませんが、とにかく今までのようにマウスでスクロールバーを動かしてもファイル名が表示されないようにしたいです。 どなたかこの原因不明の現象の原因とその直し方が分かる方、居られましたら、お教え下さいましたら大変助かります。 現象の画像を添付いたします。

  • ListViewにSETしたファイル名からファイルパス取得方法

    今、ファイル名変換プログラムを作成しています。 そこで、ドラッグ&ドロップまたはフォルダ参照ダイアログから、 ファイルステータスをリストビューにセットしました。 (ファイル名)EX) XXXX.txt #その時、ファイルパスは取得できています。 その後、実行する時にリストビューから ファイル名は、GetItemTextで取得できました。 しかし、ファイルパスは取得できません。 ファイル名だけから、ファイルパスを取得するには、 どのようにしたら良いのでしょうか?? ファイル名の変更は、CFileDialog::Renameで考えているので、。。 それとも、他に良い方法はございますでしょうか? また、構造体かなんか定義して、 リストビューへSETする時に構造体にパスを保存し、 実行時に参照して処理すべきでしょうか? ただ、リストビューで選択し「DEL」ボタンで、 削除できるようしてあるので、 この方法は、効率が悪いように思えて・・・ 環境は、Win2000、VC++6.0、MFCで作成しています。 以上、ご教授ください!

  • w10 エクスプローラーでファイル名が勝手に表示

    ある日、いつものようにw10でエクスプローラーのスクロールバーをマウスでドラッグしてスクロールした所、今まで表示されてなかったはずの、エクスプローラーの左側に表示されているファイルのファイル名が勝手に表示される現象が起きるようになってしまってました。 自分で設定を変えた覚えはなく、なぜ突然勝手に挙動が変わったのかも分かりませんが、とにかく今までのようにマウスでスクロールバーを動かしても勝手にファイル名が表示されないようにしたいです。 どなたかこの原因不明の現象の原因とその直し方が分かる方、居られましたら、お教え下さいましたら大変助かります。

このQ&Aのポイント
  • 攻撃的な人とは、メンタルの弱さや言い訳をすることがあり、学生時代に逃げてきた人のことを指します。しかし、現在はパートで働きながら人間関係や仕事を上手にやっていることから、環境が重要な要素だと考えられます。同じような経験を持つ同期の話を聞くと、彼らも理不尽な扱いを受けていたようで、困った女性による que のような文句を言われることもあったそうです。少数でも、賢くて出世できるタイプや、天然でタフな人もうまくやっている可能性もあるようです。
  • 他の人も同じような経験をしていることを知り、自身の行動を反省しました。ズル賢いタイプは成功できると思われますが、根っからの天然でタフなタイプもうまくやれるか疑問に思います。自身がこれらのタイプのどちらになるかもわかりませんし、なぜそう思うのかも理解ができません。戦うのが疲れると感じる場合、距離を取ることや対策を立てることもできますが、それでも不安です。明日の初出勤で嫌な人に出会ったらどうしようと不安になっていますが、割合的には嫌な人は1人くらいいるかもしれません。
回答を見る

専門家に質問してみよう