DragDropだと成功、通常起動だと失敗

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
ざこ

DragDropだと成功、通常起動だと失敗

#1

投稿記事 by ざこ » 16年前

自分なりに考えた結果・・InitDialogクラスにコマンドライン引数__argv[1]を使ってファイル移動のプログラム全部ぶちこみました。
BOOL CDragDrop6Dlg::OnInitDialog()
{
	CDialog::OnInitDialog();

	// "バージョン情報..." メニュー項目をシステム メニューへ追加します。

	// IDM_ABOUTBOX はコマンド メニューの範囲でなければなりません。
	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);

	CMenu* pSysMenu = GetSystemMenu(FALSE);
	if (pSysMenu != NULL)
	{
		CString strAboutMenu;
		strAboutMenu.LoadString(IDS_ABOUTBOX);
		if (!strAboutMenu.IsEmpty())
		{
			pSysMenu->AppendMenu(MF_SEPARATOR);
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
		}
	}

	// このダイアログ用のアイコンを設定します。フレームワークはアプリケーションのメイン
	// ウィンドウがダイアログでない時は自動的に設定しません。
	SetIcon(m_hIcon, TRUE);			// 大きいアイコンを設定
	SetIcon(m_hIcon, FALSE);		// 小さいアイコンを設定
	
	// TODO: 特別な初期化を行う時はこの場所に追加してください。
		
	registry=0;
	m_listC.InsertColumn(0,"拡張子",LVCFMT_CENTER,100);//リストボックスの初期設定
	m_listC.InsertColumn(1,"移動先",LVCFMT_CENTER,360);
	m_listC.InsertColumn(2,"チェックボタン",LVCFMT_CENTER,100);
	DragAcceptFiles(TRUE);
	reg_Number();
	
		CString expand,movement;
		CKodomo1Dlg dlg;
		dlg.m_chk1=&chk;
		CString CHK;
	
	ReadReg(0, "Reg_Drop1","CHKBUTTON1");//レジストリ読み込み
	ReadReg(1, "Reg_Drop2","CHKBUTTON2");
	ReadReg(2, "Reg_Drop3","CHKBUTTON3");
	ReadReg(3, "Reg_Drop4","CHKBUTTON4");
	ReadReg(4, "Reg_Drop5","CHKBUTTON5");
	ReadReg(5, "Reg_Drop6","CHKBUTTON6");
	ReadReg(6, "Reg_Drop7","CHKBUTTON7");
	CString Cname=getFileName(__argv[1]);
	int index=-1;
CString	kaku=strchr(__argv[1],'.');
	CFileStatus FSts;

	while((index=m_listC.GetNextItem(index,LVNI_ALL))!=-1){
					CString str_index=m_listC.GetItemText(index,0);
				
				CString	str_index2=m_listC.GetItemText(index,1);
				CString  Rname=str_index2+"\\"+Cname;
				CString r_chk=m_listC.GetItemText(index,2);
					if(kaku=="."+str_index){
					//	n=index;
						if(atoi(r_chk)==1){
								
								MessageBox("上書きされます");
								MoveFileEx(__argv[1],str_index2,MOVEFILE_REPLACE_EXISTING);
								MoveFileEx(__argv[1],str_index2+"\\",MOVEFILE_REPLACE_EXISTING);
								MoveFileEx(__argv[1],Rname,MOVEFILE_REPLACE_EXISTING);

							}
							else{
								if(CFile::GetStatus(Rname,FSts)){
							
									MoveFile(__argv[1],str_index2);
									MoveFile(__argv[1],str_index2+"\\");
									MoveFile(__argv[1],Rname);

							

								}
								else{
									MoveFile(__argv[1],str_index2);
									MoveFile(__argv[1],str_index2+"\\");
									MoveFile(__argv[1],Rname);
									
								}
							}
					}
	}


このようにした結果exeアイコンへのドラッグ&ドロップは成功しました。
しかし通常起動(ビルド→実行 or アイコンをダブルクリック)すると"問題が発生しました。プログラムを
終了します"とでます。原因はどうやら

CString Cname=getFileName(__argv[1]);
のgetFileName(フルパスからファイル名を取り出すプログラム)の中にあるみたいで
char *CDragDrop6Dlg::getFileName(char *lpszPath)//全パスからファイル名を取り出す関数
{
    char    *lpszPtr=lpszPath;

    while(*lpszPtr != '\0')//////////ここから先進みません。
    {
        //2バイト文字の先頭はスキップ
        if(IsDBCSLeadByte(*lpszPtr) == 0)
        {
            //[\],[[/url],[:]を見つけたら現在地+1のポインタを保存
            if((*lpszPtr == '\\') || (*lpszPtr == '/') || (*lpszPtr == ':'))
            {
                lpszPath=lpszPtr+1;
            }
        }
        //次の文字へ
        lpszPtr=CharNext(lpszPtr);
    }
    return lpszPath;
}
	
	
	
	
	
	return TRUE;  // TRUE を返すとコントロールに設定したフォーカスは失われません。
}
コメントの位置で止まります。どうして通常起動のときだけなるのか、何が悪いのかなど教えて下さい。

Blue

Re:DragDropだと成功、通常起動だと失敗

#2

投稿記事 by Blue » 16年前

__argcの値を確認していますか?
__argv[1]が常にあるとは限りません。

ざこ

Re:DragDropだと成功、通常起動だと失敗

#3

投稿記事 by ざこ » 16年前

なるほどそれが原因かな・・デバッグで調べ様にもハンドルがないと言われるしMessageBoxで調べたら空でした。
おそらくドロップしてきた場合はargvに値入ってますが総でない場合は入ってない のでしょうか。

ざこ

Re:DragDropだと成功、通常起動だと失敗

#4

投稿記事 by ざこ » 16年前

やはりその通りでした。argv[1]!=NULLという条件を加えれば落ちなくなりました。
ところで、この場合ドラッグ&ドロップすると移動(プログラム目的)された後実行ファイルが起動します。
Mistさんにも仰られたように起動自体はせず実行だけしたいんですが、最初のダイアログを表示している所は
InitInstanceでしょうか?同様に__argv[1]の有無でドラッグ&ドロップか通常起動か、分けてるんですがそこでやってみた結果移動しませんでした。

Mist

Re:DragDropだと成功、通常起動だと失敗

#5

投稿記事 by Mist » 16年前

argvとargcについて勉強しました?
argcにはコマンドライン引数の個数が入っています。
argvには引数の文字列が入っています。

通常起動時
argc=1
argv[0]=アプリケーションファイル名(~.exe)

ドロップ時
argc=1+ドロップされたファイルの数
argv[0]=アプリケーションファイル名(~.exe)
argv[1]=ファイル名1
argv[2]=ファイル名1



というか、OK Waveでせっかくもらえた回答は無視ですか?

Blue

Re:DragDropだと成功、通常起動だと失敗

#6

投稿記事 by Blue » 16年前

> 起動自体はせず実行だけしたい
なら今の作りをカナリ変えないとダメでしょう。

画面は必要な情報を集めるためのユーザインタフェース

だけにして、それに対して処理をする部分を切り分ける。


あとからあとから仕様を変えていくからムリヤリな感じになってしまうんでしょうね。
作り始める前に必要な機能を整理しておくべきでしたね。

ざこ

Re:DragDropだと成功、通常起動だと失敗

#7

投稿記事 by ざこ » 16年前

いえいえ恥ずかしながら私がargc argvのことをしったのはあそこが初です。
失礼ながら私の現段階ではあの文章は 理解できなかったというのは少し違ってあのプログラムは
回答を導く為の補佐するものと思いました。回答をいただいて色んな人の意見(あれで十分とけるなど)をいただいても今の私にできるのはここまで。何時間もargv argc コマンドライン引数に調べてこの程度です。まぁ
あの回答でできます と言われた程度でできるなら見た瞬間わかりますけどね。始めてみたときには丁寧な説明と感じました。しかし意味がちんぷんかんぷんでした。調べた結果語句などは理解できました。
ココの掲示板でバグさんやtoyoさんにあれを理解すればできる といわれてから何時間もにらめっこしていますが、
なんとなく、わかる程度です。argvやargcに何が書いてあるのかわかったのでそれを使って自分なりに回答を導こうとしているだけです。 そうすれば多分回答者様のアドバイス内容もわかると思います。

Mistさんが今書かれたことは存じています。
せっかく回答していただいた意見を無視したことなど【一度も】 ありません。

ざこ

Re:DragDropだと成功、通常起動だと失敗

#8

投稿記事 by ざこ » 16年前

やはり大幅に変えないといけませんか。もう少し自分でも調べた方がいいのでしょうが
何をキーワードに検索すればいいのかもさっぱりです。

SooA

Re:DragDropだと成功、通常起動だと失敗

#9

投稿記事 by SooA » 16年前

http://www.play21.jp/board/formz.cgi?ac ... &rln=29497
↑の書き込みの時点で argc *argv[/url] に関して書いてくれています。

この時点で argc *argv[/url] について調べ、
渡された値を表示するようなテストプログラムを作っていれば、
その特性はすぐに理解できたものと思われます。

よく理解できていない命令を直接プログラムに
組み込むと混乱とバグの原因にもなるので
テスト用のプロジェクトを作成してテストを行い、
十分に内容を理解してから組み込むようにしましょう。

ざこ

Re:DragDropだと成功、通常起動だと失敗

#10

投稿記事 by ざこ » 16年前

あのときは少し勘違いをしていて、起動させてからドロップさせてもいいんじゃないか?と思ってたんですよ。
かなり後の方に起動させずに っと言われまして、そのスレッドは使わずに他の問題点に頭ひねらせていました。

OKWAVEの方でも簡単な表示するプログラムをご紹介していただいているので、多分そのときに
調べていても多分今とそれほどかわらなかったとおもいますよ。あーしかしこのスレッド完全に忘失していましたね。
ここでも同じ問題起こしています。以後気をつけます

argcとargvについては大体といってもMistさんに書いていただいた内容程度ですが理解できてると思います。
ブルーさんに意見をいただいた後にすぐ原因わかりましたし。

toyo

Re:DragDropだと成功、通常起動だと失敗

#11

投稿記事 by toyo » 16年前

ドラッグされたときにはダイアログを出さないようにしたいわけですね
CDragDrop6App::InitInstance()

int nResponse = dlg.DoModal();
という箇所があると思いますがこのDoModalの前に処理を終わらせてreturn FALSE;すればいいと思います。
DoModal()でダイアログが表示されてしまいます。
BOOL CDragDrop6App::InitInstance()
{
//略
	if (__argc > 1)
	{
		//処理を行う
		return FALSE;
	}
	CDragDrop6Dlg dlg;
	m_pMainWnd = &dlg;
	int nResponse = dlg.DoModal();
	if (nResponse == IDOK)
	{
		// TODO: ダイアログが <OK> で消された時のコードを
		//       記述してください。
	}
	else if (nResponse == IDCANCEL)
	{
		// TODO: ダイアログが <キャンセル> で消された時のコードを
		//       記述してください。
	}

	// ダイアログが閉じられてからアプリケーションのメッセージ ポンプを開始するよりは、
	// アプリケーションを終了するために FALSE を返してください。
	return FALSE;
}

ざこ

Re:DragDropだと成功、通常起動だと失敗

#12

投稿記事 by ざこ » 16年前

なるほど、ずっとそこいじくってましたがうまいこといきませんでした
今試せる環境にないので後日試して見ます。ありがとうございました。

ざこ

Re:DragDropだと成功、通常起動だと失敗

#13

投稿記事 by ざこ » 16年前

起動はできなくなりましたが実行もできなくなりました。どこか全体のプログラムをまとめている関数みたいなものはないのでしょうか?後そこをいじくるぐらいしか思いつかないです。切り分けしか方法はないのかな.

Mist

Re:DragDropだと成功、通常起動だと失敗

#14

投稿記事 by Mist » 16年前

> そういう訳で、メインプログラムの最初で「__argcは幾つか?」を調べ、実行時引数があるなら(__argcが2以上だったら)「__targv[1]~__targv[__argc - 1]」の内容を「ドロップされたファイル名として処理する」って事になります。

この部分無視していなければ、最初のプログラムにはならないよね。

ざこ

Re:DragDropだと成功、通常起動だと失敗

#15

投稿記事 by ざこ » 16年前

何度も言いますが、貴方のように大方 わかるわけじゃありません。理解しずらい表現も、語句も、色々あるわけですよ。調べまくりましたが理解しずらい所もあります。無視?理解しずらかっただけですよ。プログラムは勉強だけじゃなく実際に打ち込んで学ぶものと聞きます。曖昧な所は打ち込んで理解する。そうなると完璧なプログラムは最初からはできません。教えてもらってる立場で非常に恐縮ですが無視 無視といわれるとどうも・・
上級者から見るとそう見えるのかもしれませんね。

ざこ

Re:DragDropだと成功、通常起動だと失敗

#16

投稿記事 by ざこ » 16年前

うーんしかし今も__argv[1]が空かどうかでドロップか通常起動か判断していますが、
argcの方が何かと使い勝手がいいのかもしれませんね。

SCI

Re:DragDropだと成功、通常起動だと失敗

#17

投稿記事 by SCI » 16年前

MFCでなければならない理由があるのですか?

>プログラムは勉強だけじゃなく実際に打ち込んで学ぶものと聞きます。曖昧な所は打ち込んで理解する。そうなると完璧なプログラムは最初からはできません。
この部分に私も大賛成なのですが、だからこそ、まずはコンソールや非MFCなWin32Appで作ってみることが大切なのではないでしょうか。
もう既にいくつもテストプログラムを作っているのでしたら的外れな指摘になりますが、まずはここで得た知識をもとにコンソールで作ってみては如何でしょう?

バグ

Re:DragDropだと成功、通常起動だと失敗

#18

投稿記事 by バグ » 16年前

一度、やりたい事を整理して仕様をキッチリ固めた方がよいかもしれませんね。
アプリの動作を細かく箇条書きにしていき、1つ1つ実装していく。
その過程で分からないところが出てきたならば、箇条書きにした文章を全て掲載して、この部分でつまづいています。というのを質問する…という風にすれば、自分自身にも回答者にも分かりやすくなると思います。

ざこ

Re:DragDropだと成功、通常起動だと失敗

#19

投稿記事 by ざこ » 16年前

理由ですか、あくまでMFCの勉強の為だからかな・・ というのも仕事でMFC使うみたいですのでそれの研修(勉強)中なのです。

Mist

Re:DragDropだと成功、通常起動だと失敗

#20

投稿記事 by Mist » 16年前

上級者であるかどうかなんか関係なくて

問題が発生する

質問する

回答もらう

さらに問題発生する

★今まで貰った回答を見直す

ということしていないじゃないですか?
最初に問題にぶつかったときに、OK Waveから引用した部分について(その他についても)対処できているかどうかを見直されましたか?
回答するほうは、今ある問題だけでなくその対応をした場合に(今回のような)よくやりそうな二次的なミスについても言及している場合があります。

ざこ

Re:DragDropだと成功、通常起動だと失敗

#21

投稿記事 by ざこ » 16年前

成る程私の質問は回答者様には若干理解しずらいような雰囲気が感じられますので理解しやすくなるように
工夫していきたいですね。自分自身も整理できてない部分もありますね

ざこ

Re:DragDropだと成功、通常起動だと失敗

#22

投稿記事 by ざこ » 16年前

いやしていますけど理解できなかった所が ☆の時点でですか、急にはわかるようにはならないんですね。
質問すればいいんですけど、回答者様の意見をじっと待つってのも少々都合が悪いでしょう。ただ今回の場合
argv[1]が空とかじゃなくてargcを使っていれば最初の文にはならない ということだと思います。
最初に思いついたのが私のやり方で(argcでやるという方法も考慮には入ってましたが)それでうまくいかなかったので質問、→ブルーさんにargv[1]は中身入っているとも限らない。

あ、そういえばそんなことOKWAVEの方でもあったね(見落としですが) となってargv[1]!=0を思いつきました。
それでargcの方はわかってたんですがtargv[1]~というのが何の事か理解できたんです。
そういう順序もありなのではないでしょうか。

ざこ

Re:DragDropだと成功、通常起動だと失敗

#23

投稿記事 by ざこ » 16年前

まぁたしかにちゃんとしっかり見直していれば質問の必要もない というのは納得です。見落としのせいでしたから・・ ただ日本語の問題でしょうけども●●について理解できていないと直接言っていただいて構いません。
回答者様の意見を無視している、というのは見向きもしないで調べもしないでいる と受け取ってちょっと熱くなってしまいました。

Blue

Re:DragDropだと成功、通常起動だと失敗

#24

投稿記事 by Blue » 16年前

argv[1] != NULL
というようなコードより
argc >= 2
という風にしたほうが良いです。

C言語の規格では
argv[argc]はNULLでないといけないとなっていますが、
たとえば、argv[2]を使わないといけないときにはargcが1未満であるとき問題が出てしまいます。
こんなのは問題です。
if (argv[1] != NULL) {
	printf("%s", argv[1]);
}
if (argv[2] != NULL) {
	printf("%s", argv[2]);
}
こちらなら問題ありません。
if (argc >= 2) {
	printf("%s", argv[1]);
}
if (argc >= 3) {
	printf("%s", argv[2]);
}

ざこ

Re:DragDropだと成功、通常起動だと失敗

#25

投稿記事 by ざこ » 16年前

なるほど、それは知りませんでした。argcを使うようにします。

toyo

Re:DragDropだと成功、通常起動だと失敗

#26

投稿記事 by toyo » 16年前

実行できませんでしたか
やりたいことはファイル移動ですよね
移動元のファイル名は__targv[ ]で取得できますが移動先ファイル名はどうやって決めるのでしょうか
[url]#30470[/url]の
//処理を行う
の部分に
MoveFileEx(__targv[1],TEXT("移動先ファイル名"),MOVEFILE_REPLACE_EXISTING);
とするだけだと思うのですが
それとMoveFileExの戻り値はチェックしたほうがいいでしょう
特にVistaでは書き込めないフォルダがありますので

ざこ

Re:DragDropだと成功、通常起動だと失敗

#27

投稿記事 by ざこ » 16年前

ああ・・//処理を行うとはそういう意味でしたか。勘違いでした。少し試してみますね。

ざこ

Re:DragDropだと成功、通常起動だと失敗

#28

投稿記事 by ざこ » 16年前

うーん移動先ファイル名ですがプログラムではリストボックスから文字列取り出してるのですが
AppクラスにDragDro6Dlgクラスからとってこれるものでしょうか?
InitInstanceとInitDialogの関係がいまいちよくわかってないのかもしれません。

toyo

Re:DragDropだと成功、通常起動だと失敗

#29

投稿記事 by toyo » 16年前

プログラムの流れとしては
InitInstance( )

DoModal( )→InitDialog( )→ダイアログ表示
になります
ダイアログ表示前(DoModal実行前)にダイアログクラスからデータを得る方法は思いつきません

ざこ

Re:DragDropだと成功、通常起動だと失敗

#30

投稿記事 by ざこ » 16年前

そうでしたか、それだとつくりを作り変えなければ私の望むプログラムは作れない ということになりますね。
親切にありがとうございました。

閉鎖

“C言語何でも質問掲示板” へ戻る