マンガでよめる痔のこと・薬のこと

いつもお世話になっております。
今回はドラッグドロップについてお聞きしたいことがあります。

ダイアログに読取専用エディットボックスとリストボックスをつけて
フォルダをドロップするとエディットにはフォルダのフルパス、
リストにはフォルダ内のファイルが列挙されるというソフトを
作っております。

現状、リストへフォルダをドロップした場合は以上の動作をしますが
エディットへドロップしても何の反応も起きません。
今回はエディットとリストどちらにドロップしても同様の動作をしたく、
ResourceViewで両方ドラッグドロップ許可にしていますが、
リストのほうはドロップするとアイコンには+がでて、
ドロップ可能のようになっていますが実際にはWM_DROPFILESすら
捕まえることができません。

読み取り専用がよくない等いろいろ試しては見ましたが
できませんでした。
リストのほうをドロップ不可(エディットのほうのみ可能)にした場合も
何もおきなかったのですが、そもそもエディットボックスではドロップは
不可能なのでしょうか?

以上の点をご教授願いたいです。
よろしくお願いします。

開発環境は VC++6.0 Professional SP2
OSは WindowsXP です。

このQ&Aに関連する最新のQ&A

A 回答 (1件)

ダイアログの『ドラッグアンドドロップを許可』を指定したほうが簡単なように思います



開発の環境は何でしょう? SDKでしょうか MFCでしょうか

確かに Editコントロールに WS_EX_ACCEPTFILESを付加すればドラッグした場合 カーソルに『+』ついたドロップ可能アイコンに変わります

しかし WM_DROPFILESまでメッセージが来ないようです

MFCで開発ならCDialogクラスの PreTranslateMessageで

if ( pMsg->message == WM_DROPFILES ) {
  // メンバー変数 m_ctlEditにEditコントロールが設定されているなら
  // 設定されていないなら GetDlgItemなどで取得しましょう
  if ( pMsg->hWnd == m_ctlEdit.m_hWnd ) {
    this->PostMessage( pMsg->mesage, pMsg->wParam );
    return TRUE;
  }
}

この回答への補足

ご回答ありがとうございます。

今回は、というか当方まだVCを始めたばかりでMFCについての知識がないため
SDKでやっております。
MFCを用いるといろいろ楽にできるけど最初はSDKをやってからでないと
理解できないということでしたのでまずはSDKをとやっています。

今回のものをSDKのみで実現することは可能なのでしょうか?

補足日時:2008/02/21 21:35
    • good
    • 0

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

QMFCのドラッグ&ドロップについて

閲覧して頂きありがとうございます。

現在、WindowsXPでvc++6.0のMFC(ダイアログベース)を利用してダイアログを作り
エディットボックスに入力されたファイルパスを利用して指定のファイルを
開く簡単なアプリを作ろうとしています。

そこでダイアログのエディットボックスの部分にファイルをドラッグ&ドロップすると
エディットボックスにドロップされたファイルのパスを表示させようとしていますが、中々できません。

状況としては、グループボックスの中にエディットボックスを作成し、
グループボックスを右クリック→プロパティ→ドラッグドロップを許可
をすることによりグループボックスにドロップの許可を与えることはできていますが
ドロップのイベントを拾うことができておりません。

※参考サイトなどをみると「WM_DROPFILES」というハンドラがあるみたいなのですが
 どこにも見当たらないです。。。

何か不明な点などあれば補足させて頂きますので、よろしくお願いします。

Aベストアンサー

すみません 先の回答はDialogクラスで処理する場合でした
EditコントロールでD&Dを処理したいのであれば CEditを継承した独自クラスが必要になります

クラスビューまたはメニューの挿入から『クラスの新規作成』
クラスの種類を『MFCクラス』
クラス名を 作成するクラス名 たとえば『CMyEdit』など
基本クラスを 『CEdit』
として OKをクリック

クラスビューでCMyEditクラスを選択して 右クリック > Windowsメッセージハンドラの追加を実行
左側の『Windowsメッセージ/イベント新規作成(N)』で『WM_DROPFILES』を選択
『追加と編集(D)』または『ハンドラの追加(A)』をクリックしてスケルトンを生成

ダイアログエディタで親ダイアログを表示
テキストボックスを選択して クラスウィザードを実行 > メンバ変数タブを選択
ID_EDIT1などクラスを変更するIDを選択して 変数の追加 をクリック
メンバー変数 を設定
カテゴリーを『コントロール』
変数のタイプを新規で作ったクラスに変更 上の例なら『CMyEdit』に
OKをクリック

新規に作ったクラスを ダイアログクラスで使えない旨のメッセージボックスが表示されるが OKクリックして ClassWizardを終了する

ダイアログクラスのヘッダーファイルの冒頭に
#include "MyEdit.h"
を追加する
場所は ダイアログクラス定義の直前がいいと思います
// この辺りに追加
/////////////////////////////////////////////////////////////////////////////
// CMFCTestDlg ダイアログ
Class CMFCTestDlg : public CDialog

といった具合で

すみません 先の回答はDialogクラスで処理する場合でした
EditコントロールでD&Dを処理したいのであれば CEditを継承した独自クラスが必要になります

クラスビューまたはメニューの挿入から『クラスの新規作成』
クラスの種類を『MFCクラス』
クラス名を 作成するクラス名 たとえば『CMyEdit』など
基本クラスを 『CEdit』
として OKをクリック

クラスビューでCMyEditクラスを選択して 右クリック > Windowsメッセージハンドラの追加を実行
左側の『Windowsメッセージ/イベント新規作成(N)』で『WM_DROPFILES』...続きを読む

Qドラッグ&ドロップで読み込むことは・・・

exeファイルにファイルを直接ドラッグ&ドロップをして、
ファイルを読み込むことっていうのはできるのでしょうか?
できるのであれば、どのような方法を用いればよいか教えてください。

Aベストアンサー

#2さんの例はGUIアプリですね。
コマンドラインプログラムの場合は、

int main(int argc,char **argv)
{ if(argc>1) printf("filename of drag&drop is [%s]\n",argv[1]);
}

読み込むなら argv[1] をfopenすればいいでしょう。

Qファイルやディレクトリの存在確認を行う方法

ファイルをオープンするのはfopenでOKですが、ファイルやディレクトリの存在確認を行う方法が知りたいです。

何か組み合わせて作るものなのでしょうか?
perlとか便利な演算子があるのですが、C/C++って器用ではないですね。
これは処理系?依存の内容ですか?

私の環境は VC6, VC2005 Windows2000です。

Aベストアンサー

int access(const char* path, int mode);
int stat(const char* path, struct stat* sb);

かな?
MSDN を引くと _access_s() を使えとか書いてあるけど。

Q【Windowsアプリ】ファイルのドラッグ&ドロップについて

C言語でのWindowsアプリの勉強をしています。(始めたばかりです)
***.exeにファイルをD&Dした際、
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
上記の"lpCmdLine"にファイルパスが入るのはわかったのですが、別のファイルパスの取得方法として、
1.***.exeを実行
2.ウィンドウ表示
3.ウィンドウ内にファイルをD&D
4.ファイルパスを取得
の方法がわかりません。
DragAcceptFiles()や、DragQueryFile()を使うと思うのですが、WinAPIの使い方がいまいち良くわかっていない状況です。
自分で勉強するべきというのは承知の上でのお願いしたいのですが、どなたか出来ればサンプルソースなど教えて頂けるとうれしいです。

環境はテキストエディタでソースを作成→Borland C++ Compiler 5.5でコンパイルしています。

C言語でのWindowsアプリの勉強をしています。(始めたばかりです)
***.exeにファイルをD&Dした際、
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
上記の"lpCmdLine"にファイルパスが入るのはわかったのですが、別のファイルパスの取得方法として、
1.***.exeを実行
2.ウィンドウ表示
3.ウィンドウ内にファイルをD&D
4.ファイルパスを取得
の方法がわかりません。
DragAcceptFiles()や、DragQueryFile()を使うと思うのですが、WinAPIの使...続きを読む

Aベストアンサー

 こんばんは。

 ウィンドウの拡張スタイルにWS_EX_ACCEPTFILESを指定して、WM_DROPFILESで受け取ります。以下参考程度に。

TCHAR szTitle[MAX_PATH] = "drag and drop";
TCHAR szWindowClass[MAX_PATH] = "drag and drop";

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch( message )
{
//ココに飛び込んでくる
case WM_DROPFILES:
{
HDROP hDrop = (HDROP)wParam;
TCHAR tchName[MAX_PATH];
//tchNameにドロップされたファイル名が入っている
::DragQueryFile(hDrop, 0, tchName, sizeof(tchName));

//ココでファイルを開く

//終了
::DragFinish(hDrop);
}
case WM_DESTROY:
PostQuitMessage( 0 );
break;
default:
return DefWindowProc( hWnd, message, wParam, lParam );
}
return 0;
}

ATOM MyRegisterClass( HINSTANCE hInstance )
{
WNDCLASSEX wcex = {sizeof(wcex)};
wcex.style= CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc= (WNDPROC)WndProc;
wcex.cbClsExtra= 0;
wcex.cbWndExtra= 0;
wcex.hInstance= hInstance;
wcex.hIcon= LoadIcon(hInstance, (LPCTSTR)IDI_DDTEAD);
wcex.hCursor= LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground= (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName= (LPCSTR)IDC_DDTEAD;
wcex.lpszClassName= szWindowClass;
wcex.hIconSm= LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);

return RegisterClassEx( &wcex );
}

BOOL InitInstance( HINSTANCE hInstance, int nCmdShow )
{
HWND hWnd = ::CreateWindowEx(WS_EX_ACCEPTFILES, szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);

if( !hWnd )
{
return FALSE;
}

ShowWindow( hWnd, nCmdShow );
UpdateWindow( hWnd );

return TRUE;
}

int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow )
{
MSG msg;
MyRegisterClass( hInstance );
if(!InitInstance( hInstance, nCmdShow ) )
{
return FALSE;
}

while(::GetMessage(&msg, NULL, 0, 0) )
{
::TranslateMessage( &msg );
::DispatchMessage( &msg );
}

return msg.wParam;
}

 こんばんは。

 ウィンドウの拡張スタイルにWS_EX_ACCEPTFILESを指定して、WM_DROPFILESで受け取ります。以下参考程度に。

TCHAR szTitle[MAX_PATH] = "drag and drop";
TCHAR szWindowClass[MAX_PATH] = "drag and drop";

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch( message )
{
//ココに飛び込んでくる
case WM_DROPFILES:
{
HDROP hDrop = (HDROP)wParam;
TCHAR tchName[MAX_PATH];
//tchNameにドロップされたファイル名が入っている
...続きを読む

Q同じエディットボックスへのDrag&Drop(VC++/MFC)

同じエディットボックスへのDrag&Drop(VC++/MFC)

同じエディットボックスへDrag&Dropすると
テキストが消えてしまう現象に悩んでいます。

現在、
下記のサイト
http://www.softist.com/programming/dandd/dandd.htm
のサンプルプログラムを参考に
コントロール間のDrag&Dropの仕方を学習しています。

このサンプルではエディットボックス間で文字列のコピーができるようになっていますが、
私がほしい機能は文字列の移動です。
そこで、サンプルのEditForDD.cppの
DROPEFFECT DropEffect = OleDataSrc.DoDragDrop(DROPEFFECT_COPY);
の下に、
if(DropEffect == DROPEFFECT_COPY) this->SetWindowTextA("");
という一文を加えて、Drag&Dropする際にDrag元のテキストを削除するようにしました。
その結果、異なるエディットボックス間での移動は可能になりましたが、
Drag元のエディットボックスにテキストを戻そうとすると
テキストが消えてしまいまうようになってしまいました。

このように同じエディットボックスにDrag&Dropをしても
テキストが消えないようにする方法をご存じの方はいらっしゃいませんでしょうか?

なお、開発環境は以下の通りです。

開発環境:Visual Studio 2005 Standard Edition
利用言語:VC++/MFC
OS:Windows XP

よろしくお願いいたします。

同じエディットボックスへのDrag&Drop(VC++/MFC)

同じエディットボックスへDrag&Dropすると
テキストが消えてしまう現象に悩んでいます。

現在、
下記のサイト
http://www.softist.com/programming/dandd/dandd.htm
のサンプルプログラムを参考に
コントロール間のDrag&Dropの仕方を学習しています。

このサンプルではエディットボックス間で文字列のコピーができるようになっていますが、
私がほしい機能は文字列の移動です。
そこで、サンプルのEditForDD.cppの
DROPEFFECT DropEffect = OleDa...続きを読む

Aベストアンサー

Revokeをして同じエディットボックスにはDrop出来ないようにし
Drag&Drop後に再びRegisterをしてはどうでしょうか?

m_DropTarget.Revoke(); //追加
DROPEFFECT DropEffect = OleDataSrc.DoDragDrop(DROPEFFECT_COPY); //DROPEFFECT_SCROLL
if(DropEffect == DROPEFFECT_COPY)
this->SetWindowTextA("");
m_DropTarget.Register(this); //追加

QDWORDの実際の型は何でしょうか

VC++.NETの環境です。
DOWRD dw1 = 1;
int i = 2; と定義し
ここで
if ( i > dw1 ){
何かの処理;
}
とコーディングすると
warning C4018: '>' : signed と unsigned の数値を比較しようとしました。
のワーニングがでます。
これは、DWORDがint型でなくunsigned int型のようにも見えます。
ある本によれば(VC++.V.NET逆引き大全500の極意)
DWORD はint型であると記述されています。
もし、int型ならこのワーニングはでないはずなのですが、
なぜでるのでしょうか。又、DWORDの実際の型は何なのでしょうか。ご存じのかたおりましたら、教えていただけませんでしょうか。

Aベストアンサー

型定義が知りたいのならば、宣言ファイルを見れば疑問を挟む余地もありません。
DWORD型はwindef.hで
"typedef unsigned long DWORD;"
と宣言されています。

Visual Studioを使っているのならば、知りたい型の上にマウスポインタを置いて右クリック、ポップアップメニューの「定義へ移動」または「宣言へ移動」で簡単に知ることが出来ます。

QMFC、フォルダの中のファイルパス

ダイアログベースにて、フォルダがドラッグアンドドロップされたら、フォルダの中のファイルのパスを一個ずつ取得したいのですが、どのようにしたらいいでしょうか。

void CDDDlg::OnDropFiles(HDROP hDropInfo)
{
char FileName[100];
int NameSize = sizeof(FileName);
int FileNumber; CString str;
int i;

FileNumber = DragQueryFile(hDropInfo, 0xffffffff, FileName, NameSize);
str.Format("ドロップされたファイルの数 =%d", FileNumber);
AfxMessageBox(str);

for(i=0; i<FileNumber; i++){
DragQueryFile(hDropInfo, i, FileName, NameSize);
str.Format("第 %d 番目のファイル名 = %s", i, FileName);
AfxMessageBox(str);
}
CDialog::OnDropFiles(hDropInfo);
}

のようにすると、フォルダのパスが出力されます。
例えば、testというフォルダの中にtest.txtがあり、testをドラッグアンドドロップしたら、test.txtのパスを取得したのですが・・・。
Visual Studio .NET2003を使用しており、まだ初心者ですがよろしくお願いします。

ダイアログベースにて、フォルダがドラッグアンドドロップされたら、フォルダの中のファイルのパスを一個ずつ取得したいのですが、どのようにしたらいいでしょうか。

void CDDDlg::OnDropFiles(HDROP hDropInfo)
{
char FileName[100];
int NameSize = sizeof(FileName);
int FileNumber; CString str;
int i;

FileNumber = DragQueryFile(hDropInfo, 0xffffffff, FileName, NameSize);
str.Format("ドロップされたファイルの数 =%d", FileNumber);
AfxMessageBox(st...続きを読む

Aベストアンサー

MSDNの CFileFind::IsDirectory にある使用例が参考になります。

http://msdn2.microsoft.com/ja-jp/library/scx99850(VS.80).aspx

要は自分で再帰的に展開すればいいのです。
頑張ってみてくださいね。

QCStringからchar*への型変換について教えてください。

以前の質問に

int型 → CString型/char型

がありましたが、

CString型をchar*型に変換する方法を
教えていただければありがたいです。

MSDNで「LPCTSTRキャスト」が説明されていましたが、
例が載ってないのでよくわかりませんでした。

よろしくお願いします。

Aベストアンサー

目的にもよりますが一時的にchar配列として使いたいならCString::GetBuffer()が利用できます。
char配列としての利用が終わったらCString::ReleaseBuffer()する必要がありますが。

直接CString内の文字列を扱う必要があるならCString::operator LPCTSTRで文字列ポインタが得られます。
ただし、CStringオブジェクトをいじると無効ポインタなる可能性があるので気をつけてください。

MSDNのMicrosoft Foundation Classリファレンス→CString→クラスメンバで確認してください。

QCStringのFindで文字列検索を行いたいのですが

こんにちは。
いつもお世話になっております。

CStringのFindメソッドで文字列検索を行っているのですが、文字列ではなくコードで検索が行われてしまい困っています。
-------------------------------------------------------

CString TargetStr;

TargetStr = "ハヒフヘホ";
if(TargetStr.Find("z", 1) != -1){
return FALSE;
}

-------------------------------------------------------

上記で文字"ホ"のコードが「837A」で"z"が「7A」のため、
文字列が存在するという結果が帰ってきます。
コードではなく文字そのものの検索をするにはどうしたらよいでしょうか?
基本的なことで申し訳ありませんが、ご教示下さい。

<環境>
Windows 2000, VC6.0

Aベストアンサー

CString::Findメソッドは、1バイトごとの検索を行うので、そのような結果になってしまいます。

このような処理を避けるには、CString::Findではなく、_mbsstrを利用します。
詳しくは、MSDNを参照のこと。
http://msdn.microsoft.com/library/ja/default.asp?url=/library/ja/vclib/html/_crt_strstr.2c_.wcsstr.2c_._mbsstr.asp

どちらかといえば、_tcsstrを利用してUnicodeとMBCSの両方に対応できるようにしておいたほうがいいです。
#この場合、_UNICODEもしくは_MBCSのどちらかが設定されていないと正しく動きません。

*注意*
この関数はANSIに互換性がないようですので、Windows以外では利用できない可能性があります。


また、上記のような関数を使わず、自分で実装するなら、以下の参考URLを参考にしてください。

参考URL:シフトJIS文字列の文字検索

参考URL:http://katsura-kotonoha.sakura.ne.jp/prog/c/tip0002d.shtml

CString::Findメソッドは、1バイトごとの検索を行うので、そのような結果になってしまいます。

このような処理を避けるには、CString::Findではなく、_mbsstrを利用します。
詳しくは、MSDNを参照のこと。
http://msdn.microsoft.com/library/ja/default.asp?url=/library/ja/vclib/html/_crt_strstr.2c_.wcsstr.2c_._mbsstr.asp

どちらかといえば、_tcsstrを利用してUnicodeとMBCSの両方に対応できるようにしておいたほうがいいです。
#この場合、_UNICODEもしくは_MBCSのどちらかが設定されていないと...続きを読む

QビジュアルC++でボタンの有効/無効

ビジュアルC++でプログラミングをしているのですが、ツールから貼り付けたボタンの有効/無効を操作したのですが、何度やっても成功しません><、


ネットで検索した結果
CWnd* myWnd = GetDlgItem(IDC_MYEDIT);
myWnd->EnableWindow(TRUE);

でできると書いてあるのですが、どのサイトの物を使用してもビルドできませんでした(;ロ;)

どなたか原因がわかるかた、ご教授くださいm(__)m

Aベストアンサー

みているサンプルは
「Windows フォームアプリケーション」
で作成したプロジェクト用のものではありません。

どのタイミングで有効・無効を切り替えるかわかりませんが、
Enabledプロパティで変更できませんか?

this->button1->Enabled = false; // 無効

Control::Enabled プロパティ
http://msdn.microsoft.com/ja-jp/library/system.windows.forms.control.enabled.aspx


人気Q&Aランキング