MFCのスレッド実行中のコマンド処理 – プログラミング – Home

MFCのスレッド実行中のコマンド処理
 
通知
すべてクリア

[解決済] MFCのスレッド実行中のコマンド処理


猫柳
 猫柳
(@猫柳)
ゲスト
結合: 18年前
投稿: 11
Topic starter  

今勉強中の初心者の者です。
Visual Studio2005(MFC)でダイアログベースのスレッドを使ったfile copyのプログラム
を作成しています。
サイズの大きなファイルをcopyしながらプログラスバーを更新していきます。
スレッドを起動してcopyのプログラムを実行します。そしてコピー状況をプログレスバ
ーに表示するプログラムです。

基本的なプログラムの動作は問題なく、コピー状況にあわせてプログレスバーが更新さ
れますが、
メッセージが処理できないようです。途中でwindowを移動したり、最小化することがで
きません。なぜでしょうか?

void CnewoneDlg:: copyfile()
{
//省略
while(k > 0){256バイトづつコピーループ
ReadFile (hf1, buff, sizeof(buff), &nRead, NULL);
WriteFile(hf2, buff, nRead, &nWriten, NULL) ;
// k、counter 変数の更新計算
}
//hf1, hf2クローズ、スレッド終了処理。
}
UINT CnewoneDlg::CopyThread( LPVOID pParam )
{ //threadからcopyプログラムを呼び出し
// copyfile()の呼び出し
}

void CnewoneDlg::OnBnClickedButton1()
{//ボタンコマンド

// スレッド開始
m_pCopythread = AfxBeginThread( CopyThread, this );//
LPMSG Msg = NULL;

while(mProgress.SetPos(counter) <100){ //100% コピーするまで
if(PeekMessage(Msg,NULL,0,0,PM_REMOVE) != 0)
DispatchMessage(Msg);
}//
}


引用未解決
トピックタグ
ぬふや
 ぬふや
(@ぬふや)
ゲスト
結合: 18年前
投稿: 34
 

while(mProgress.SetPos(counter) <100){ //100% コピーするまで
if(PeekMessage(Msg,NULL,0,0,PM_REMOVE) != 0)
DispatchMessage(Msg);
}//
ここが問題で、消して良い。
ここでわざわざメッセージループする必要は無いし、ループの仕方も間違ってい
る。
メッセージループはMFCが用意しているし、アクセラレータ用の処理もあるから特
に必要が無ければ自分では書かないほうが良い。
そして、PeekMessageをSleepその他無しで回したら、CPU負荷が100%になって
ファイルコピースレッドにも悪影響が出る。

ついでに、「LPMSG Msg = NULL;」は駄目。
PeekMessageは構造体を確保してくれるAPIではないし、もしそうなら引数は
LPMSGへのポインタになる。
PeekMessageは構造体は自分で用意する必要があります。

そして、「while(mProgress.SetPos(counter) <100)」はスレッドを分けた意味
を完全に無くしています。

正しく動作させたいなら、
void CnewoneDlg:: copyfile(){//省略
while(k > 0){
ReadFile (hf1, buff, sizeof(buff), &nRead, NULL);
WriteFile(hf2, buff, nRead, &nWriten, NULL) ;
// k、counter 変数の更新計算

}//hf1, hf2クローズ、スレッド終了処理。
}
void CnewoneDlg::OnBnClickedButton1(){
m_pCopythread = AfxBeginThread( CopyThread, this );
}


返信引用
ぬふや
 ぬふや
(@ぬふや)
ゲスト
結合: 18年前
投稿: 34
 

while(mProgress.SetPos(counter) <100){ //100% コピーするまで
if(PeekMessage(Msg,NULL,0,0,PM_REMOVE) != 0)
DispatchMessage(Msg);
}//
ここが問題で、消して良い。
ここでわざわざメッセージループする必要は無いし、ループの仕方も間違ってい
る。
メッセージループはMFCが用意しているし、アクセラレータ用の処理もあるから特
に必要が無ければ自分では書かないほうが良い。
そして、PeekMessageをSleepその他無しで回したら、CPU負荷が100%になって
ファイルコピースレッドにも悪影響が出る。

ついでに、「LPMSG Msg = NULL;」は駄目。
PeekMessageは構造体を確保してくれるAPIではないし、もしそうなら引数は
LPMSGへのポインタになる。
PeekMessageは構造体は自分で用意する必要があります。

そして、「while(mProgress.SetPos(counter) <100)」はスレッドを分けた意味
を完全に無くしています。

正しく動作させたいなら、
void CnewoneDlg:: copyfile(){//省略
while(k > 0){
ReadFile (hf1, buff, sizeof(buff), &nRead, NULL);
WriteFile(hf2, buff, nRead, &nWriten, NULL) ;
// k、counter 変数の更新計算

}//hf1, hf2クローズ、スレッド終了処理。
}
void CnewoneDlg::OnBnClickedButton1(){
m_pCopythread = AfxBeginThread( CopyThread, this );
}


返信引用
ぬふや
 ぬふや
(@ぬふや)
ゲスト
結合: 18年前
投稿: 34
 

投稿失敗。

正しく動作させたいなら、
void CnewoneDlg:: copyfile(){//省略
while(k > 0){
ReadFile (hf1, buff, sizeof(buff), &nRead, NULL);
WriteFile(hf2, buff, nRead, &nWriten, NULL) ;
// k、counter 変数の更新計算
    mProgress.SetPos(counter);
}//hf1, hf2クローズ
//スレッド終了処理。
}
void CnewoneDlg::OnBnClickedButton1(){
m_pCopythread = AfxBeginThread( CopyThread, this );
//ボタン連打を回避する場合はm_pCopythreadが有効か調べた上でスレッ
ドを開始して、ボタンを無効にする。

}


返信引用
ぬふや
 ぬふや
(@ぬふや)
ゲスト
結合: 18年前
投稿: 34
 

投稿失敗。

正しく動作させたいなら、
void CnewoneDlg:: copyfile(){//省略
while(k > 0){
ReadFile (hf1, buff, sizeof(buff), &nRead, NULL);
WriteFile(hf2, buff, nRead, &nWriten, NULL) ;
// k、counter 変数の更新計算
    mProgress.SetPos(counter);
}//hf1, hf2クローズ
//スレッド終了処理。
}
void CnewoneDlg::OnBnClickedButton1(){
m_pCopythread = AfxBeginThread( CopyThread, this );
//ボタン連打を回避する場合はm_pCopythreadが有効か調べた上でスレッ
ドを開始して、ボタンを無効にする。

}


返信引用
猫柳
 猫柳
(@猫柳)
ゲスト
結合: 18年前
投稿: 11
Topic starter  

いろいろありがとうございます。
うまくいきました。
まだまだスレッドの使い方が慣れていないようですね。

・・・・・
if(PeekMessage(Msg,NULL,0,0,PM_REMOVE) != 0)
DispatchMessage(Msg);
この部分は最初はなくて、うまくいかなくて付け加えていましたが、
更に深みにはまっていたわけですね。
・・・・

スレッドに対する本がAPIに関する本しかなかったので、直してる間にいつの間にかこう
なってしまったようです。


返信引用

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました