ダイアログでのドロップ処理の仕方について

[戻る]
2004/01/28(水) 10:08:40
win Me VC++ Ver6.0    過去ログ
「ダイアログでのドロップ処理」を見せて頂きましたが初心者で十分解らない所が有りますので
よろしくお願いします。

ダイヤログベースのスケルトンを作り(MFC Appwizard(exe)を使用)EditBoxを貼り付けて
 ここにドラッグ ドロップ を実現したいのです。(ファイル名を表示)プロジェクト名を
 Drag_Drop とします。
 1.EditBox の拡張スタイルのドラックドロップにチェックを入れればDragAcceptFilesは
  使わなくてもいいのでしょうか?
 2.Windows.hをインクルーズするのをソースファイルのどこに書くのでしょうか?
  Drag_Drop.cpp?  Drag_DropDlg.ccp?
  3.最後に肝心の
  //ダイアログのプロシージャ
  LRESULT CALLBACK DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
  { 
   .....
  }
    関数をコーディングする場合メンバー関数の追加を使うのでしょうか?また、そのクラス
  は?

ひろぴー 2004/01/28(水) 10:43:55
> 1.EditBox の拡張スタイルのドラックドロップにチェックを入れればDragAcceptFilesは
>  使わなくてもいいのでしょうか?
はい

>  2.Windows.hをインクルーズするのをソースファイルのどこに書くのでしょうか?
しなくてよいです。

> 3.最後に肝心の
Appwizardで作成した場合はMFC使用ですので、PreTranslateMessage()内でWM_DROPFILESを
処理するとよいです。
ダイアログプロシージャはCDialogクラスを使用せずにDialogBoxマクロを使用してダイアログ
を作成する場合に実装します。

2004/01/28(水) 11:05:18
早速のご教示有難う御座いました。あちこち探しましたが PreTranslateMessage() が見つ
かりませんが? すみません!

2004/01/28(水) 11:14:11
見つかりました。か゜、CwinApp,CWndなど 使い方がいまいちですが?

ひろぴー 2004/01/28(水) 12:05:28
> 使い方がいまいちですが?
どういう事でしょう?

2004/01/28(水) 12:28:09
CWndとかの関数をオーバーライド?して使えばいいのでしょうか? また、VBの様に
PeekMessage も使えますか? ナントカ ヤッテミマス。出来上がったらお知らせします。
有難う御座いました。

ひろぴー 2004/01/28(水) 14:19:56
VBは知らないのでPeekMessageはわかりませんが、下記のようにすれば処理出来ると思います。
BOOL CxxDlg::PreTranslateMessage( MSG* pMsg ) 
{
    switch ( pMsg->message )
    {
    case WM_DROPFILES:
        // エディットボックスか判断
        if ( pMsg->hwnd == m_edit.GetSafeHwnd() )
        {
            // ファイル名を取得する処理
        }
        break;
    }
    return CDialog::PreTranslateMessage(pMsg);
}

ココでのm_editは目的のEditBoxの事を指します。

2004/01/28(水) 15:43:05
とりあえずテストのためのコーディングをしました。
BOOL CDrag_DropDlg::PreTranslateMessage(MSG *pMsg)
{
switch ( pMsg->message )
    {
    case WM_DROPFILES:
         {
         // ファイル名を取得する処理
         char  FileName[MAX_PATH+1]; // ドロップされたファイルの名前
         UINT  Count;   // ドロップされたファイルの数
         HDROP hDrop;    //ハンドル
         
         //ドロップされたファイルの数を取得する
    Count = DragQueryFile( hDrop, 0xFFFFFFFF, NULL, 0 ); 
         DragQueryFile( hDrop, 0, FileName, MAX_PATH );    
    AfxMessageBox(FileName);
        }
        break;
    }
    return CDialog::PreTranslateMessage(pMsg);
}
コンパイルは出来ますが実行するとバンドルされていない例外はDrag_Drop.exe(SHELL32.DLL)
にあるというエラーが出るのですが?

2004/01/28(水) 16:10:36
>コンパイルは出来ますが実行するとバンドルされていない例外はDrag_Drop.exe
>(SHELL32.DLL)にあるというエラーが出るのですが?

もし、Count = DragQueryFile() でエラーが起きているのなら、hDrop には何を指定
しなければならないのか調べてください(msdn ライブラリーで DropQueryFile について
調べれば判ると思います。判らなければ google などで検索して調べて下さい)
そうでないのなら、どこでエラーが起きているか確かめて知らせて下さい

更に、実行するとだけでなく、何をしたらそのエラーがおきたのか判るように示して下さい

ところで、デバッグバージョンで実行してみたのですか、リリースバージョンで実行して
みたのですか?
エラーが出たことはどこに何が出たのでわかったのですか?

2004/01/28(水) 19:11:43
島さん ひろぴー お手数をおかけします。 
コードの AfxMessageBox(FileName); をコメントアウトしてコンパイルすると
「warning C4700: 値が割り当てられていないローカルな変数 'hDrop' に対して参照が行われまし
た。」が出るので hDrop の使い方が間違っているようですがこれより先は解りません。すみ
ません。

とおり 2004/01/29(木) 01:24:37
Windowsうんぬんの前にC言語の基礎を勉強した方がよいかと。

>「warning C4700: 値が割り当てられていないローカルな変数 'hDrop' に対して参照が行わ
れました。」

そのままなのですが… CやC++では、変数を定義しただけでは、正しい値は入ってません。
だから、代入なり何なりして正しい値にしてやってから使わないとまずいんじゃないの?
とコンパイラが親切に教えてくれているのです。

wood 2004/01/29(木) 07:27:37
>薫 2004/01/28(水) 15:43:05>   case WM_DROPFILES:
>         ・
>         ・
>         HDROP hDrop;    //ハンドル

>         //ドロップされたファイルの数を取得する
>    Count = DragQueryFile( hDrop, 0xFFFFFFFF, NULL, 0 ); 

の
DragQueryFile( hDrop, 0xFFFFFFFF, NULL, 0 )
に対する警告ですね 
>AfxMessageBox(FileName);
は関係ないよ 

>hDrop の使い方が間違っているようですがこれより先は解りません。
MSDNは読んだの?

引数の解説にhDrop 
「ドロップされた複数のファイルの名前を保持している、1 個の内部構造体のハンドル
を指定します。」
とあるじゃない

DragQueryFile関数を使用するまでの間に「保持」をどうやって行っているの何もしてい
ないじゃない
いわゆる値の代入は「どうなっちゃたんですか?」と言うことです
初期化されていない、ハンドル「hDrop」が1つ存在しているだけでしょ

CやC++では変数(ハンドル含む)宣言はその後利用しようと思うのなら
初期化(実態化「メモリ領域の確保」)と言う作業が必ず必要です
やらないと実行時にゼロアドレス参照c00005(アクセスバイオレーション)
ページ違反・アクセス侵害の原因になります
これを防ぐ意味での警告エラーですので警告と侮らず、回避しましょう

2004/01/29(木) 10:40:34
すみません
「HDROP hDrop;」の部分の初期化が良く解りません。
下記のようなメッセージが10数行出るし 
 'C:\WINDOWS\SYSTEM\COMCTL32.DLL' をロードしました、合致するシンボル情報は見つかりませ
  んでした。
  ・・・・・
  ・・・・・・
実行すると「バンドルされていない例外はDrag_Drop.exe(SHELL32.DLL)・・」が出ます。

ひろぴー 2004/01/29(木) 10:57:09
HDROPという構造体はメモリ上に確保しましたが、中身が空っぽという事です。
ココでいう初期化とは、中身を入れろという事ですね。

みなさんが教えて下さっている事が理解できていればhDropにドロップされたファイルのハンド
ルが定義されていないという事が分かると思います。
何をhDropに設定すればよいかというと、MSDNでWM_DROPFILESを検索してみて下さい。
その定義するものがドコにあるのか分からない場合はMSG構造体を検索して下さい。
何をするにもMSG構造体しか渡されていないのですから、その中身でどうにかするしかない訳で
すね。

瀬戸っぷ [E-Mail] 2004/01/29(木) 12:00:23
hDropの設定の仕方はひろぴーさんのレスで判るとして…
答えを書くのは簡単ですが、MSDNで調べればいいだけです。
「MSDNで調べる」というコトを覚えて下さい。

>下記のようなメッセージが10数行出るし 
> 'C:\WINDOWS\SYSTEM\COMCTL32.DLL' をロードしました、合致するシンボル情報は見つか
りませ
>  んでした。
は気にしなくても問題ないです。
皆の環境でふつ〜に表示されるメッセージですから。
もちろん、私のところでも表示されます。

2004/01/29(木) 12:02:06
MSDNを見ていますが 解りません。それから下記の行を生かすとエラーが出ます。
メンバー変数 m_edit は int型でいいのでしょうか?

 if ( pMsg->hwnd == m_edit.GetSafeHwnd() )

ひろぴー 2004/01/29(木) 12:09:14
> MSDNを見ていますが 解りません。
何がわからないか明確にしないと、誰も答えられないと思います。

m_editはWM_DROPFILESメッセージが送られたコントロールを判別する為に使用しています。
GetSafeHwnd()を調べればint型ではない事がわかると思います。

sugar 2004/01/29(木) 12:19:14
薫さん、ウィンドウメッセージ(WM_***)は、WPARAM、LPARAMという
2つのパラメータを携えているというのをご存知でしょうか?
これらは、メッセージによって内容は様々で、
何メッセージにはどんな情報がセットされているかはMSDNをみれば解説されてます。

そして、WM_DROPFILESというメッセージのパラメータには、
どんな情報がセットされているでしょうか??

2004/01/29(木) 13:20:26
m_editは解りました。WM_DROPFILESにはwParamだと解りましたが?この後どうコーディングす
るかが解らないのです。よろしくお願いします。

ひろぴー 2004/01/29(木) 14:05:21
> WM_DROPFILESにはwParamだと解りましたが
正確にはWM_DROPFILES時にDragQueryFile関数を使用するにはhDropにはwParamです。
省略して書かれていると思うのですが、これでこの後どうコーディングすればよいか解ったでし
ょうか?

これで解らないと、答えをズバリ書くしかないんですが....。

因みに、みなさん意地悪で教えないのではなくて、薫さんに調べて理解して貰いたいのです。
今、動作すれば良いという考えでは、いつまでもスキルアップしないですから。

sugar 2004/01/29(木) 14:15:55
薫さん、WPARAMをキャストすればいいんですよ、キャスト。

2004/01/29(木) 14:21:32
すみません!答えをずばりお願いします。

ひろぴー 2004/01/29(木) 15:16:40
> すみません!答えをずばりお願いします。
sugarさんの書き込みがズバリな答えなのですが...(ToT)

出来れば、いまの段階でのソースの提示をお願いします。
ドコでキャストすればよいかとか、言えますので。

2004/01/29(木) 15:27:16
薫 2004/01/28(水) 15:43:05 の ページで書かせて頂いたとおりですが宜しく願いします。

ひろぴー 2004/01/29(木) 16:12:06
エディットの判定は?2004/01/29(木) 12:02:06で、エラーが出ていて、そのあとわかったと
の事ですが。

DragQueryFile関数の第1引数が初期化されていない。
WM_DROPFILESにはwParamだと解った。
wParamはキャストして使う。

これで2004/01/28(水) 15:43:05から1ステップも進めないという事は解っていないという事
だと思います。

何が解ってなくて1ステップもコーディング出来ないのでしょうか?

2004/01/29(木) 17:42:48
以前にした質問に答えて戴けていませんが、出来ればお答え戴けないでしょうか
(勿論、答えたくないならそれでいいのですが、答えたく無いとだけでもお知らせ下さい)
----どの程度デバッガーの使い方がお判りなのかが知りたいだけなのです----
>>更に、実行するとだけでなく、何をしたらそのエラーがおきたのか判るように示して下さい
>>
>>ところで、デバッグバージョンで実行してみたのですか、リリースバージョンで実行して
>>みたのですか?
>>エラーが出たことはどこに何が出たのでわかったのですか?

2004/01/29(木) 17:55:44
すみません。デバッガーの使い方は殆ど解りません。いちおう、デバッグモードでコンパイルし
ています。ファイルをドラッグドロップするとエラーになります。
>>エラーが出たことはどこに何が出たのでわかったのですか?は
バンドルされていない例外はDrag_Drop.exe(SHELL32.DLL)・・」が出ます。

2004/01/29(木) 18:22:20
どこに出たかについては答えられていないようですが、おそらく(VC++6.0 だとして)
メッセージウィンドー(で合ってたかな?)のデバッグタブが示す領域に出たのでしょう

で、エラーで中断したのでデバッグを終了(中止)したのですか?
ブレークポイントはわかりますか?
ステップ実行はわかりますか?
ステップインは判りますか?
ステップアウトはわかりますか?
コールスタックはわかりますか?

2004/01/29(木) 18:40:51
最初のコーディングのままでコンパイルは出来ます。
エラーはドロップした後にダイアログボックスが出て
混合モードとかの画面が出て最初の行が下記のよう
7FC16DE8   cmp         word ptr [eax],8

>>コールスタックはわかりますか?
はいまいち解りません。

2004/01/29(木) 19:16:46
意地悪く尋ねますが、いまいち判らないという事は幾らか判る、もしくはかなり判ると
解釈していいのかな?
 こういう言葉(文字を用いた)だけが頼りの場では相手にきちんとはっきり伝わる様に
 心がける事が大切だと思います(自戒を込めて言っています)し、あなたがはやる気持ちも
 わかりますが、相手からの問い(質問)にも答えるようにしましょう。それは、あなたの
 困っている問題について判ろうとしているからこそ尋ねているので、あなたを困らせたい
 からではないからだし、問題解決への糸口が見つかる確率が上がる(両者の認識のずれが
 少なくなるから)と思うからです

さて、ブレークポイントについてはお分かりのようなので
switch ( pMsg->message )
か
    Count = DragQueryFile( hDrop, 0xFFFFFFFF, NULL, 0 ); 
かの行にブレークポイントを置いて実行してください
ブレークでとまったらシングルステップで一行づつ実行してみましょう
おそらく
    Count = DragQueryFile( hDrop, 0xFFFFFFFF, NULL, 0 ); 
の行を実行したところでエラーが出るでしょう。ですからこの行の実行をする前に
hDrop の値を確認してみてください(マウスカーソルをこの変数のある位置におく
だけでもいい)。これで何がわかったか教えてください

wood 2004/01/30(金) 07:28:56
>薫 2004/01/29(木) 10:40:34
>「HDROP hDrop;」の部分の初期化が良く解りません。
についてはわかったんですね?

>薫 2004/01/29(木) 12:02:06
で話題変わっているようですけど
もしわかっていないのなら、話を先に進めないほうが良いよ

>島 2004/01/29(木) 18:22:20
>ブレークポイントはわかりますか?
にきちんと答えていないようですが
どのようにわかってますかね、用語または名称を見たことあるけど、
操作を知らないとか
または何のためのものか知らないとか

>薫 2004/01/29(木) 18:40:51
>最初のコーディングのままでコンパイルは出来ます。
はおかしいでしょう?

(「HDROP hDrop;」の部分の初期化)についてきちんと修正できたのなら
再度修正版を提示したほうが良いのではないですか

ここまでで「キャスト」と言う用語出てますけど、どんなことをするのか本当にわかっ
てますか
この手の用語理解できていないのなら厳しいかも知れませんが、
C言語の基礎からやり直ししたほうがいいよ
C++やWindowsアプリの開発なんて論外です
離脱・・・?

2004/01/30(金) 19:31:15
[[解決]]
ひろぴーさん 島さん woodさん とおりさん 瀬戸っぷさん sugarさん
皆さん劣等性のために色々ご教示いただき本当に有難う御座いました。
最初のコーディング 薫 2004/01/28(水) 15:43:05 の 

 ・・・・
 HDROP hDrop;    //ハンドル
 の次に
 hDrop = (HDROP)pMsg->wParam
 の一行を追加してキャストをいたしました。これで無事解決いたしました。

重ねて御礼申し上げます。本当に有難う御座いました。

古いスレッドには追加発言できません。