ページ 11

「このプログラムは応答していません」と表示されてしまいます

Posted: 2006年7月28日(金) 23:37
by Anti MS
以下のようなプログラムで、D:\test1フォルダーを監視して、pdfが投げ込まれたらd:\test2フォルダーへmoveさせようとしています。監視してMoveすること自体は正常に動作してくれていますが、メインウィンドウで"閉じる"をクリックすると、「このプログラムは応答していません」と表示されてしまいます。
無限ループの組み方が悪いのではないかと思いますが、どなたかアドバイスを戴けけないでしょうか?
よろしくお願い致します。

------------------------------------------------------------------------------------
' ここから下は、イベントプロシージャを記述するための領域になります。

Sub MainWnd_Destroy()
test_DestroyObjects()
PostQuitMessage(0)
End Sub

Sub MainWnd_Create(ByRef CreateStruct As CREATESTRUCT)
SetTimer(hMainWnd,1,1,AddressOf(fff) As DWord) 'タイマーの設定
End Sub

Sub fff()
Dim File1 As String
File1="D:\test1\*.pdf" 'pdf検索用
dim File2 as string
dim File3 as string
Dim wfd1 As WIN32_FIND_DATA '構造体: WIN32_FIND_DATA
Dim hFind As VoidPtr
dim drv[2] As Byte
dim path[255] As Byte
dim fname[255] As Byte
dim ext[63] As Byte

dim i as long
i=1
dim filepath_F as string
Dim Ret As Long
KillTimer(hMainWnd,1)

While i=1
hFind = FindFirstFile(File1,wfd1)
If hFind=INVALID_HANDLE_VALUE Then
' MessageBox(hMainWnd,File1+"が見つからない","",MB_OK)
Else
File2=wfd1.cFileName '構造体: WIN32_FIND_DATAから検索結果を取得
File2="D:\test1\"+File2 '検索結果:フルパス
_splitpath(StrPtr(File2),drv,path,fname,ext)
File3=fname '単体ファイル名
' MessageBox(hMainWnd,File2,"フルパス",MB_OK)
' MessageBox(hMainWnd,fname,"ファイル名単体",MB_OK)
filepath_F="D:\test2\"+File3+".pdf"
Ret=MoveFile(File2, filepath_F)
FindClose(hFind)
End If

Sleep(1000)
Wend

End sub

Re:「このプログラムは応答していません」と表示され

Posted: 2006年7月29日(土) 12:18
by Anti MS
2005年6月、”あおぞら”さんの同じような質問で、
"「オフィシャルユーザーズガイド」の「マルチスレッド」の真似で、落ち着きました。"
との記述を見つけました。

でも、私には”あおぞら”さんのように、”マルチスレッドの真似”なんて到底できそうもありません...^^;

While~Wendの無限ループが悪そうな感じがするのですが、いろいろとトライはしてみても
、今のところなかなかうまい方法が見つかりません。

Posted: 2006年7月29日(土) 21:27
by konisi

コード: 全て選択

' ここから下は、イベントプロシージャを記述するための領域になります。

Sub MainWnd_Destroy()
    test_DestroyObjects()
    PostQuitMessage(0)
End Sub

Sub MainWnd_Create(ByRef CreateStruct As CREATESTRUCT)
	SimpleCreateThread(AddressOf(fff))
End Sub

Sub fff()
	Dim File1 As String
	File1="D:\test1\*.pdf"					'pdf検索用
	Dim File2 As String
	Dim File3 As String
	Dim wfd1 As WIN32_FIND_DATA				'構造体: WIN32_FIND_DATA
	Dim hFind As VoidPtr 
	Dim drv[2]  As Byte
	Dim path[255] As Byte
	Dim fname[255] As Byte
	Dim ext[63] As Byte

	Dim i=1 As long
	Dim filepath_F As string

	While i=1
	    hFind=FindFirstFile(File1,wfd1)
	    If hFind=INVALID_HANDLE_VALUE Then
	'		MessageBox(hMainWnd,File1+"が見つからない","",MB_OK)
	    Else
			File2=wfd1.cFileName			'構造体: WIN32_FIND_DATAから検索結果を取得
			File2="D:\test1\"+File2			'検索結果:フルパス
			_splitpath(StrPtr(File2),drv,path,fname,ext)
			File3=fname						'単体ファイル名
	'		MessageBox(hMainWnd,File2,"フルパス",MB_OK)
	'		MessageBox(hMainWnd,fname,"ファイル名単体",MB_OK)
			filepath_F="D:\test2\"+File3+".pdf"
			MoveFile(File2, filepath_F)
			FindClose(hFind)
		End If

		Sleep(1000) 
	Wend
End Sub

Sub SimpleCreateThread(Address As VoidPtr)
	Dim A As DWord
	CreateThread(ByVal NULL,0,Address,0,0,VarPtr(A))
End Sub
とすればスレッド作成して監視するモードになります。

また、統一性が取れていないと気に食わないので勝手にdimをDimに書き換えましたが、特に問題はないと思います。

;ところで、これを一般に公開するときはD:\test1ディレクトリおよびD:\test2ディレクトリが存在するかどうか調べる必要も出てくると思います。

Posted: 2006年7月29日(土) 22:27
by OverTaker
普通にタイマーイベントを使えばループやマルチスレッドは必要ないと思います。
KillTimer()とWhileループを削除し、タイマーの時間を適当に調整してみたらどうでしょう?

Re:「このプログラムは応答していません」と表示され

Posted: 2006年7月30日(日) 00:26
by Anti MS
konisiさん。大変ありがとうございます。
メインウィンドウが軽やかに動くようになり、きれいさっぱりと終了させることができました。

良くは理解できてはいないのですが、「無限ループから抜け切れていないのにメインのスレッドを終了させようとしていた。そのため、OSは何処の何をどうして良いのかわからなかった。これをサブスレッドを出汁(ダシ)に使ってきちんと終了できた」というように考える事に致しました...^^;


OverTakerさん。深夜にもかかわらずアドバイスありがとうございました。

タイマーイベントについてHELPを読んだりWebで調べてみたり致しました。
この方法ですと、私でも何とかやれそうな気がいたしましたのでこれから試してみたいと思います。

 お二方に感謝いたします。ありがとうございました。

Posted: 2006年7月30日(日) 01:10
by konisi
前に似たような問題に直面したことがありましてね、そのときも今回言ったのと同じCreateThread関数による非同期化をして何とかなったんですよ。

そのときはとある計算プログラムを作成していたんですが、計算開始ボタンを押すとプログラムが固まっちゃって、何とかならんものかといろいろ調べたものです。なんせ人に分らない事を聞くのはあまり好きではないのでね。ここで質問をしたのは2005年07月25日が最初で2回目の2005年07月27日が最後ですかね?よく覚えていませんが。

;雑談化失礼。

追記:調べなおしたら、2005年10月30日、2005年12月04日、2006年03月22日にもプログラムに関して質問をしていました。

Re:「このプログラムは応答していません」と表示され

Posted: 2006年7月30日(日) 21:24
by Anti MS
 OverTakerさん。アドバイスありがとうございました。お陰様で、アドバイス通りにコーディングしたらきれいに動くようになりました。ただ、文法が良くわかっていないので、四苦八苦してやっと下の記述にたどり着きましたが...

Sub MainWnd_Create(ByRef CreateStruct As CREATESTRUCT)
SetTimer(hMainWnd,1,1000,AddressOf(fff_timer_) As DWord) 'タイマーの設定
' SimpleCreateThread(AddressOf(fff))
End Sub

Sub fff_timer_()
--------------------------------------------------------------------------------------
 konisiさんも過去に質問されていたのですね。Googleで検索していましたが、konisiさんのご質問には辿り着いていませんでした。もっと良く考えてキーワードを指定していれば、皆さんにご迷惑をお掛けしなかったかも知れませんでした。
 それから、今回いろいろ調べていたら、良く目にする「過去スレ」の「スレ」ってスレッドの事だったんだなあ、と改めて感心もしました。

 私の小さな小さな水溜まりが少し大きくなったような気もしました。

みなさんどうもありがとうございました。