忙しい現代人の腰&肩のお悩み対策!

同じエディットボックスへの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

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

A 回答 (3件)

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); //追加
    • good
    • 0
この回答へのお礼

goo39さん、
ご回答いただきありがとうございます。
ご回答のとおり、やりましたらうまくいきました!
RevokeでDropリストからはずし、
Drag&Dropの後、Registerでリストに再追加するのですね。
1ヶ月以上悩んでいたので、感激です!
本当にありがとうございました。

お礼日時:2010/01/27 10:13

例えば、


VOID CDropTarget::SetDropSrc( CWnd *pWnd )
{
m_pWndSrc = pWnd;
}

のようなメソッドを作り、

m_DropTarget.SetDropSrc( this );
DROPEFFECT DropEffect = OleDataSrc.DoDragDrop(DROPEFFECT_COPY); //DROPEFFECT_SCROLL

としてやれば良い、と思っていましたが、実際にやってみると、DoDragDrop の後で、
m_DropTarget.SetDropSrc( NULL );
としてやらなければ、次にドロップしようとしたときにドロップ不可の状態のままになってしまいました・・・。

#1 の方の方法の方が簡潔で良さそうですね。
    • good
    • 0
この回答へのお礼

tsukasa-12rさん、
再度、ご回答ありがとうございました。

上記のコードとCDropTarget::OnDropに
if(this->m_pWndSrc == pWnd) return FALSE;
を追加したら、うまく動きました!

確かに今回はgoo39さんの方が簡潔でしたので
そちらを採用したいと思います。
しかしながら、ドラッグ元をとる方法がわかり、
今後大いに役にたちそうな気がします。

本当にありがとうございました!

お礼日時:2010/01/28 18:45

COleDropTargetの派生クラスの


OnDragEnter()、および OnDrag() で、ドロップ先がドラッグ元と同じなら
DROPEFFECT_NONE
を返すようにして、ドラッグ元にはドロップできないようにしてはどうでしょうか。

この回答への補足

tsukasa-12rさん、
ご回答ありがとうございます。

私も以前この方法でどうにかならないか考えていたのですが、
ドロップ先がOnDragEnter()、および OnDrag()の引数CWnd* pWndで取れるとして、
ドラッグ元のとり方がよくわからず断念したしだいです。

よろしければ
このドラッグ元のとり方も教えていただけないでしょうか。
よろしくお願いいたします。

補足日時:2010/01/27 10:20
    • good
    • 0

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

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

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

QVC++でドラッグドロップ

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

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

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

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

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

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

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

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

現状、リストへフォルダをドロップした場合は以上の動作をしますが
エディットへドロップしても何の反応も起きません。
今回はエディットとリストどちらにドロップしても同様の動作をしたく、
...続きを読む

Aベストアンサー

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

開発の環境は何でしょう? 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;
  }
}

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() を使えとか書いてあるけど。

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』...続きを読む

QCString から LPCTSTRの型に変換

visual studio 2013 VC++を使用していますが、WINDOWSの関数に渡すためにCString からLPCTSTRに変換する必要があります。実際にどのようにするのかわかりません。
例えば、以下のサンプルは他の質問コーナーの回答をアレンジしたものです

CString str = _T("ABC");
int siz = str.GetLength()+1;
LPCTSTR pszFName = new TCHAR[siz];
_tcscpy_s( pszFName, siz, str );

で変換するのですが
LPCTSTRからwchar_t*へ変換できませんとエラーがでます
_tcscpy_s()は使用できないのでしょうか

Aベストアンサー

>APIはCStdioFile の Open()でファイル名を与えるところ

APIではないようですが……。

http://msdn.microsoft.com/ja-jp/library/ee247566.aspx
ならば、そのままCStringの変数渡せば、よろしく処理してくれると思いますけど。

QcharからLPTSTRへの変換方法

リストコントロールにchar型の変数の値を数値として表示させたいのですが、charからLPTSTRへの洗練された変換方法がよくわからないです。

char tempChar;
CString tempString;
tempString.Format("%s", tempChar);
LPTSTR lpsz = new TCHAR[tempString.GetLength()+1];
_tcscpy(lpsz, tempString);

こんなプログラムを考えてみたのですが、汚いような気がします。もっと簡単で洗練された変換方法はないのでしょうか?

Aベストアンサー

wsprintfを使ってはどうでしょうか?

char tmpChar = 100;//表示する数値
TCHAR buf[5];
wsprintf(buf, "%d", tempChar);

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→クラスメンバで確認してください。

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すればいいでしょう。

QCFileDialogの最初のディレクトリ設定

Visual C++のMFCです。

CFileDialogを使ってファイルを指定して開くと、カレントディレクトリの位置が変化して、次回、CFileDialogで開くときは、その変化したあとの最新のディレクトリが開きますね。
このカレントディレクトリは、GetCurrentDirectory で、調べることができました。

しかし、特定のディレクトリ(フォルダ)をCFileDialogで開きたいとき、SetCurrentDirectory で設定しようとしても、これでは、CFileDialogで開くフォルダ位置を変更できません。

CFileDialogで開きたいフォルダ位置を変更するコマンドを教えてください。

DoModal()をする以前に設定したいので、CFileDialogクラスとは別の関数、できれば、SDKの関数等であれば、いいです。

Aベストアンサー

CFileDialog のメンバにm_ofnというOPENFILENAME構造体があります
その中にさらにlpstrInitialDir というメンバ変数がありこれでイニシャルディレクトリが指定できます
----sample-----
CFileDialog fileDlg(TRUE);
fileDlg.m_ofn.lpstrInitialDir = TEXT("C:\\");
if (fileDlg.DoModal() == IDOK)
{
MessageBox(fileDlg.m_ofn.lpstrFile);;
}

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リストビュー内でのドラッグ&ドロップ

MFCのCListView内の表示されるアイテムのドラッグ&ドロップを許容させるにはどうすればいいのでしょうか?

外からのドロップはMainFrameでキャッチできたのですが、CListView内でのドラッグ&ドロップがどうしてもできないので、お分かりになる方がいましたら、教えていただけないでしょうか?

Aベストアンサー

つまりLVN_BEGINDRAGのメッセージハンドラを追加しても呼び出されない、という状況ですね。

VisualC++.NET 2003 MFC使用 SDI CListViewのモードはreport という環境で試してみました。
LVN_BEGINDRAGのメッセージハンドラを追加した後、
リストビューのアイテムをドラッグしようとすると、このハンドラが呼び出されました。
reportモードにした他はスタイルを変更していません。


人気Q&Aランキング