よろしくお願いします。
<環境>WIN98 VC++6.0 MFCにて
有名な”猫でも~”の下記サイトで行っているマルチスレッドを、MFCにて実現しようとしてお
りますがいろいろ調べても分かりません。
http://www.kumei.ne.jp/c_lang/sdk/sdk_87.htm
MDIにて2つのウィンドウが開いているとき、一方のウィンドウに1、2、3・・・
他方のウインドウにあ、い、う・・・のようにそれぞれのウィンドウに同時に別々の処理を行う
にはどのようにすれば良いのでしょうか?
ご教授のほど、よろしくおねがいします。
マルチスレッドにする方法なら、googleで
AfxBeginThread
などで検索してみてください。詳しく解説されているページが
たくさん引っかかると思いますよ。
<Wandererさん>
いつも回答ありがとうございます。
>マルチスレッドにする方法なら、googleでAfxBeginThread
>などで検索してみてください。詳しく解説されているページが
>たくさん引っかかると思いますよ。
残念ながら今の私の実力では、ネット上で見つかるレベルの解説では出来ません。
<NEG(ねぐ)さん>
いつも回答ありがとうございます。
もちろんNEGさんのHPはいつも参考にしております。
が、残念なことに今の私の力では分かりません。
<以下雑談>
マルチスレッドとはそんなに難しいものなのか?
ネット上でも良い例は見つけられないし、本にも載っていない。
質問もなかなかレスがつかないし。(質問の仕方が悪いと言われそうだが)
VC++付属のサンプルのコードをそっくり真似しようとしたが、いろいろ有って挫折。
SDKよりMFCのほうがアプリを作る作業は簡単だとすると、”猫でも~”の例は容易に出来
そうなのに。誰か教えてくれ~~~~~~~。
簡単そうなのに、自分で出来ないのが悲しい。ぐすん;
> MDIにて2つのウィンドウが開いているとき、一方のウィンドウに1、2、3・・・
> 他方のウインドウにあ、い、う・・・のようにそれぞれのウィンドウに同時に別々の処理を行
う
> にはどのようにすれば良いのでしょうか?
とりあえず、やりたいことをもう少し分かりやすく説明してみては?
「1、2、3・・・」「あ、い、う・・・」と言われても・・・
マルチスレッドを使わなくても済む問題かもしれないし。
> マルチスレッドとはそんなに難しいものなのか?
ワーカースレッドを起こすだけならさほど難しくはないです。
ただ、同期とか排他制御の問題が絡んでくるとややこしいです。
KAB-studio ( http://www.kab-studio.com/) から、
http://www.kab-studio.com/Programing/Codian/MFCTips/11.html
ワーカースレッド(ユーザーインターフェースの不要なスレッド)を
動かすだけなら記述のポイントは2つです。
1つ目
UINT func(LPVOID pParam)
{
・
・
・
return (UINT型の値);
}
のような関数を定義します。これは静的関数の必要があるので、グロ
ーバルに定義してください。(クラスの外ということ)
2つ目
この関数をサブスレッドで動かしたい場所で、
AfxBeginThread(func, (LPVOID)0);
と記述してください。(第2引数は、funcの引数に渡されるものなの
でこれを利用して、funcに値を渡すことができます)
これでfuncがサブスレッドで動き出します。funcの処理が最後に来た
時点でサブスレッドは終了して勝手になくなります。
以上です。
この例は、スレッドを作って放ったらかしています。実際にはきちん
と管理を行う必要がありますが、とりあえず慣れないとなかなか理解
できないかもしれません。funcの中にいろいろ書いて同時に動いてい
ることを試してみてください。慣れてきたら、検索したページ等を見
れば書いている内容もだんだんと理解できるようになると思います。
kazumaさん 回答ありがとうございます。
>とりあえず、やりたいことをもう少し分かりやすく説明してみては?
>「1、2、3・・・」「あ、い、う・・・」と言われても・・・
やりたいことは、最初に書いたように”猫でも~”をMFCで再現することです。
1,2,3、・・・あ、い、う・・・は当然たとえで、四角、丸ことです。
>マルチスレッドを使わなくても済む問題かもしれないし。
マルチスレッドの使うことそのものが目的です。すみません。
>ワーカースレッドを起こすだけならさほど難しくはないです。
>ただ、同期とか排他制御の問題が絡んでくるとややこしいです。
そのようなことが本にも書いてありました。
とりあえず”猫でも~”を再現したいだけなのですが、同期等の問題が発生するのでしょうか?
”猫でも~”を再現することは、私が思っている程甘くないと言うのであれば今回は諦めます。
>KAB-studio ( http://www.kab-studio.com/) から、
> http://www.kab-studio.com/Programing/Codian/MFCTips/11.html
今の私の実力ではピンときません。
1.MDIのスケルトンを作れ(バカヤロ~)
2.どこそこに○○関数を追加しろ(これくらい自分で勉強しろよな。ぼけ)
3.
・
・
・
というように教えていただける方いませんか?(ずうずうしいのは百も承知です)
どうかよろしくお願いいたします。
とりあえずこんなので出来ます。(スレッドの終了処理など、かなり手抜き)
UINT ThreadProc( LPVOID pParam )
{
CWnd *pWnd = CWnd::FromHandle((HWND)pParam);
CClientDC dc(pWnd);
while (::IsWindow(pWnd->GetSafeHwnd())) {
CRect rect(0,0,50,50);
rect.OffsetRect(rand()%640, rand()%480);
dc.Ellipse(rect);
Sleep(0);
}
return 0;
}
int CHogeView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CView::OnCreate(lpCreateStruct) == -1)
return -1;
AfxBeginThread(ThreadProc, m_hWnd);
return 0;
}
kazumaさ~~~ん 本当に有難う御座います。
何度も申しますが、今の私の実力では、
1.こうしろ
2.ああしろ
3.・・・
4.・・・
と言う風にご指導頂かないと、うまく実行することが出来ません。
しかしながら、int CHogeView::OnCreate(LPCREATESTRUCT lpCreateStruct) がウィザード
が生成したコードの中に無かったので自分で追加し実行したところ、
うぉぉぉぉ~~~感激です。円が書けているではないですか。
あと、別ウィンドウで四角を書くにはどうすれば良いのですか?
お願いします。教えてください。
>別ウィンドウで四角を書くにはどうすれば良いのですか?
コレは
1.別ウィンドウで描く、
2.四角を書く、
に、分割できます。
さらに、1.は
・『別ウィンドウ』というものの出し方、
・そこへの他スレッドからの描画
に分割でき、さらにそこにはCWndがスレッドセーフではない、という問題があり、
ウィンドウハンドル、およびデバイスコンテキストについて
理解する必要があります。
これらを理解いただけないなら、一つ一つ指導するより、
すべてのソースを示してしまったほうがラクなのですが・・・これが何を意味するかわかります
か?
あなたの言うように
>マルチスレッドの使うことそのものが目的
で、かつ、
>と言う風にご指導頂かないと、うまく実行することが出来ません。
ならば、次にすべきことは示されたコードを理解することで、
別機能を追加していくことではないと思うのですが、いかがでしょうか?
PAIさん お名前は良く拝見しております。ご意見有難う御座います。
物事を本当に理解するということは非常に難しいことです。
今回の件は確かに基礎の理解をサボって、回答そのものを求めています。
この考えは、批判が出ても仕方がないと覚悟の上で一連の質問をしています。
VC++のアプローチとして基礎を固めて進んでいく方法と、自分の気に入ったアプリが実現でき
た喜びを感じながら、このコードはどのように書かれているんだ理解していく方法があると思い
ます。当然普通は両方が混在して進んでいくと思いますが。
本題に入ります。
>コレは
> 1.別ウィンドウで描く、
> 2.四角を書く、
>に、分割できます。
別ウィンドウは最近教えていただいた、以下にて実現できました。
1つ目のウィンドウと同じように丸が書かれていました。
CxxApp::InitInstance()の最後で、
pMainFrame->PostMessage(WM_COMMAND, ID_FILE_NEW);
を追加。
>さらに、1.は
> ・『別ウィンドウ』というものの出し方、
> ・
> ・
>ならば、次にすべきことは示されたコードを理解することで、
>別機能を追加していくことではないと思うのですが、いかがでしょうか?
当然その努力はしています。その結果として、上記に書いたように2つ目のウィンドウが出来ま
した。
>これらを理解いただけないなら、一つ一つ指導するより、
>すべてのソースを示してしまったほうがラクなのですが・・・これが何を意味するかわかりま
>すか?
冒頭に書いたような考えで、今回はソースを示して頂いて、そこから理解していくスタイルをと
れたらと言うのが、私の希望です。
ダメならそのように明言頂いて結構です。
只、あまりにも素人の私が独学で理解するには難解で、時間が足りなさすぎます。
初心者の方、あるいは初心者を卒業できた方でも初心者の頃を思い出せば、私の考えが理解でき
ると思うのですが・・・???
なるほど、骨はしっかりしてそうですね(w
ちゃんとほかのスレッドでの話題も(ただの要求ではなく)
自分がどこまで理解しているかは理解されてるみたいですね。
// みんながこうであってくれれば日本のソフトウェア産業も安泰なのだが、とか
失礼なことを言ってしまったようで、すみません。
// でも、みんながすべてのスレッドを読んでるわけではないので、
// 『どこまでできてるのか』の説明は一応簡単にでも入れておきましょう。
で、
ID_FILE_NEW して、OnCreateでスレッドを作ると、
『ドキュメントを2作って、それぞれのドキュメントにViewとスレッドが割り当てられてい
る』
という状態になってるわけですね。(なんかカッコイイなぁコレ)
なにも考えずに、
1個目に起動したスレッドは丸を描いて、
2個目に起動したスレッドは四角を描く、
とするのが、要求を満たすための、今の状態からの一番お手軽な方法でしょうか。
// ですけど、コレだとそれだけなら問題ないけど、ほかの事しようとした時かなり困りそうで
すが。
// コレで一応はいけると思いますけど、
// いい方法じゃないです。真似しないほうがいいかと、
UINT ThreadProc( LPVOID pParam )
{
static int st_count = 0; // 起動されたスレッドの数
int count = st_count; // このスレッド自体が何番目に起動されたものか。
st_count++;
CWnd *pWnd = CWnd::FromHandle((HWND)pParam);
CClientDC dc(pWnd);
while (::IsWindow(pWnd->GetSafeHwnd())) {
CRect rect(0,0,50,50);
rect.OffsetRect(rand()%640, rand()%480);
if( count ){
dc.Ellipse(rect);
}else{
dc.Rectangle( rect );
}
Sleep(0);
}
return 0;
}
> なにも考えずに、
> 1個目に起動したスレッドは丸を描いて、
> 2個目に起動したスレッドは四角を描く、
> if( count ){
> dc.Ellipse(rect);
> }else{
> dc.Rectangle( rect );
> }
あ、逆だ。// 問題ないですよね、コレは・・・
で、pParam にはkazumaさんのやってくださっているように、
ウィンドウハンドルを渡してやってください。
PAIさん おはよう御座います。
出来ました~~。とうとう出来ました~~~よ。(当たり前か全部教えてもらってるんだから)
コードをみて皆さんが教えてくれない理由がわかりました。
「これくらい自分で考えろよ!」っていう内容でした。(でも実際には自分では出来ない)
もっと別のものをイメージしてたから。
今回は覚悟をきめて、諦めずに質問して良かったです。
ようやく、気持ちや思いが伝わったようです。
VC++を愛するがあまり(魔物に取り付かれてしまったように、本当はいい加減開放されたい
のに・・・)、去年の11月からほかのことが何も出来ないほど時間を割いています。本当は簡
単なVBのほうで良いのですが、車好きならやはりF-1に乗りたい??。と同じでどうしても
VC++をマスターしたいのです。
また地道に基本の理解に戻ります。今回いろいろ教えてくださった皆さん有難う御座いました。
<雑談>
VC++をやる前は、VBAをやっていました。結局、会社の仕事でみんながエクセルを使って
いるためVBAが一番役に立つからです。
VBAのQ&Aサイトでは、一応回答者側に立つことも出来ました。
質問者の中には、今の私のように1から10まで教えてくれと言う質問をする人がいます。えぇ
~~、教えるのは簡単なんだけど、5と6が分からないと言う風に言ってくれないとこっちもそ
んなに時間ないし、第一、1を知らない人に10を教えてもこの場限りで発展性なんて無いし、
そもそも俺はアプリ製作請負人じゃないぞ。と思っていました。
と言うことで今回の件、回答していただいた人の気持ちは良く分かっているつもりです。ここま
でお付き合い頂き有難う御座いました。
間違いでしたらごめんなさい。この質問って、OK-webで見かけたやつ
と同一でしょうか? とするとマルチポストなんですが...
もしそうでしたら、あちら(OK-Web)の後始末をお願いします。