いつもお世話になっております。
1)CWnd::OnTimerのスレッドハンドルを取得したいのですが、CreateThread又はAfxBeginThreadで取得できますか?
2)普通、CreateThreadやAfxBeginTHreadでハンドルを取得できるようですが、なぜ作る関数が取得する機能を果たすのか疑問です。
3)CWnd::OnTimerの中身を見たいのですが、どのようにすれば見ることができますか?

知っている方がいましたら教えて下さい。

このQ&Aに関連する最新のQ&A

A 回答 (3件)

1)MFCらしくは扱えませんが、コールバックが呼ばれるときに作成されるスレッドもGetCurrentThreadで取得する擬似ハンドルでアクセスできると思います。

このハンドルは自分自身のスレッドを指す特殊な定数なので、他のスレッドから参照する必要があるのならDuplicateHandleで複製してやる必要があります。でも、コールバックに対して、そのような事はしたことがないので無理かもしれません。

3)デフォルトの動作が必要ない種類のものだから、無いと思います。
    • good
    • 0
この回答へのお礼

ありがとうございます。
新しい発想を知ることができて、とても勉強になりました。
お忙しい中、本当にありがとうございました。

お礼日時:2001/09/26 12:53

1について



 CWnd::OnTimerはWin32ネイティブでは::SetTimer()で起動され、WM_TIMERメッセージのハンドラとしてキャッチされます。
 ::SetTimer()ではTimerProc関数のポインタを指定できますが、ここに指定したとしても、実際にはメッセージキュー経由で起動されるため、結局の所CWnd::OnTimerfハンドラでは新たなスレッドは起動されていません(ウィンドウプロシージャ内で時間のかかる処理を実行してその時間より短い間隔でTimerイベントを発生させるようにしていれば確認できます)。
 なのでCWnd::OnTimerのスレッドハンドルはウィンドウプロシージャのスレッドハンドルそのものです。よってそれを知る事が出来ればスレッドを捕まえる事も出来るでしょう(多分PSAPI(NT/2000)やToolhelp32(9x/Me/2000)を使う事で取得できるかもしれません)。

2について
Win32の設計やMFCの設計がそうだから(^^;
itohhさんと同じく、仕様だからとしか言えませんねぇ(^^;

3について
 ありません。というより実体はWM_TIMERのハンドラですから未定義時は::DefWndProc()に流れるようになっているだけでしょう。
MFCのメッセージハンドラ自体、マクロではなくコンパイラ内で処理されているような感じを受けます。CWnd::OnTimer自体がMFCソース内に無いようですし・・・


# OnTimerのくだり(1について)はたしかProgramming Windowsあたりに載ってたと思います。なんかの書籍からウラを取ったのは確かなんですが、どの書籍かはいまいちはっきりしないので・・・

# CWnd::OnTimerでは新規のスレッドが起きない&メッセージキュー経由なので遅延が発生しやすいので、新規にスレッドを起こしたい場合、timeSetEvent()(マルチメディアAPI)の方を使ってください。こちらの方が精度が高く、メッセージキューを経由せず、独立したスレッドが生成されます。
    • good
    • 0
この回答へのお礼

ありがとうございました。
2については仕様ということで自分に言い聞かせます。
3についてはOnTimer内でハンドルを変数へ渡し、実装しようと考えました。それができれば関数を使わずにハンドル取得ができるのかと思ってみました。
お忙しい中、ご教授感謝しております。

お礼日時:2001/09/26 11:57

こんにちは。

itohhといいます。

ちょっと、質問の意味がわからないのですが。

(1)について。
SetTimer関数で設定された秒数の経過後にOnTimerイベントが呼び出されるというのでは
いけないのでしょうか?

(2)について。
それは、「仕様です。」ではダメ?
newで作成したオブジェクトの戻り値はオブジェクトのアドレス(ハンドル)ですよね?
それと、同様だと思うのですが...

(3)について。
中身を見るってどういう事を意味しているのでしょうか?
OnTimerイベントのときの処理を書きたい、という意味でしょうか?
それならば、クラスウイザードでOnTimerイベントを追加してください。
ソースファイルにOnTimer関数のテンプレートが出来るはずですから、処理を追加
してください。
(注)スレッドには2種類有ります、ワーカースレッドとユーザインターフェース
   スレッドです。
   ユーザインターフェーススレッドでないと、OnTimerイベントは拾えません。
   ワーカースレッドで行いたい場合は、独自のメッセージポンプを実装
   しなければいけません。
    • good
    • 0
この回答へのお礼

いろいろ細かくご教授ありがとうございました。
1つ1つの質問を丁寧に教えていただけたのですが、勉強する時間が長すぎて、不採用になってしまいました。
でも、これから自分なりにゆっくり勉強していきます。
また、その時はよろしくお願いします。
VCを触って早3ヶ月も経つのにわからないことだらけでやになります。愚痴を言ってしまいました。
本当にありがとうございました。

お礼日時:2001/09/26 11:46

このQ&Aに関連する人気のQ&A

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

このQ&Aを見た人はこんなQ&Aも見ています

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

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

QワーカスレッドAfxBeginThreadのスレッド起動を遅延させたい

アラーム情報などをBASP21を用いてE-Mail送信するプログラムを
マルチスレッドにしていました。
自己メールサーバーを立てていた場合は、1秒間に何件でもセッション
張ってもよかったのですが、訳あってOCNのメールサーバーを使うように
したところ、1秒間に複数のセッションを張ると迷惑メール送信
と認識されるため、接続が拒否されていまいます。

そこで、マルチスレッド化しているアラームメールの起動間隔を伸ばす
ためにAfxBeginThreadの後に

Sleep( 5* 1000 );

を入れて1秒間に複数送信しないようにしたつもりなんです
が、何故かSleepが効かな状況です。

エラー内容としては、次のように表示されます。
Too Many Session 421
細かく見ていくと、状況によって次のエラーでした。
http://homepage1.nifty.com/yito/anhttpd/winsock_error.html
10060 WSAETIMEDOUT
10061 WSAECONNREFUSED Connection refused

ログを見てもスリープが効いておらず、間隔なしにアラームメールが
1秒間に10件近く送信されてしまいます。


一応渡されたスレッドの最後に
AfxEndThreadを書いてみたり書かないようにしてみたんですが、
状況は変わらずです。

#include "stdafx.h"
#include "windows.h"

for( i=0;i<ALARM_MAX;i++ ){
m_pThreadCL[i] = AfxBeginThread(ThreadProcCL, (LPVOID)i,THREAD_PRIORITY_NORMAL)
Sleep( 5 * 1000); //::Sleep( 5 * 1000 );の間違い?
}
念の為
スレッド起動をしなければいいのですが、単純にはいかなかった
ため、応急処置としてスレッドの起動間隔を遅延させる方法を
どうにかできないものでしょうか。あくまでも応急処置として、
お願いいたします。

アラーム情報などをBASP21を用いてE-Mail送信するプログラムを
マルチスレッドにしていました。
自己メールサーバーを立てていた場合は、1秒間に何件でもセッション
張ってもよかったのですが、訳あってOCNのメールサーバーを使うように
したところ、1秒間に複数のセッションを張ると迷惑メール送信
と認識されるため、接続が拒否されていまいます。

そこで、マルチスレッド化しているアラームメールの起動間隔を伸ばす
ためにAfxBeginThreadの後に

Sleep( 5* 1000 );

を入れて1秒間に複数送信...続きを読む

Aベストアンサー

AfxBeginThreadの 引数dwCreateにCREATE_SUSPENDEDを指定してスレッドを作成するようにしてみてはいかがでしょう

その後 ResumeThreadメソッドでスレッド起動
WaitForSingleObjectなどを使ってスレッドが終了する毎に次スレッドのResumeThreadを呼んでみてはいかがでしょう ...

for(i=0; i< ALARM_MAX;i++) {
m_pThread[i] = AfxBeginThread( ThreadProcCL,(LPVOID)i,THREAD_PRIORITY_NORMAL,0,CREATE_SUSPENDED);
}

for( i=0; i<ALAM_MAX; i++) {
m_pThread[i]->ResumeThread();
while( WaitForSingleObject( m_pThread[i]->m_hThread, 100 )!= WAIT_OBJECT_0) {
Sleep( 5 * 1000 );
}
}

AfxBeginThreadの 引数dwCreateにCREATE_SUSPENDEDを指定してスレッドを作成するようにしてみてはいかがでしょう

その後 ResumeThreadメソッドでスレッド起動
WaitForSingleObjectなどを使ってスレッドが終了する毎に次スレッドのResumeThreadを呼んでみてはいかがでしょう ...

for(i=0; i< ALARM_MAX;i++) {
m_pThread[i] = AfxBeginThread( ThreadProcCL,(LPVOID)i,THREAD_PRIORITY_NORMAL,0,CREATE_SUSPENDED);
}

for( i=0; i<ALAM_MAX; i++) {
m_pThread[i]->ResumeThread();
while( WaitForS...続きを読む

QCWnd::EnableWindow()の扱い方

 CWnd::EnableWindow()で有効、無効を切り替えるというのはわかりますが、エディットボックスの有効、無効を切り替えるにはどうしたらいいでしょうか?
現在MFCで開発していますが、エディットボックスのメンバ変数にはCStringを使っているので、EnableWindowの使い方がわかりません。
動作環境はWindows2000とNTです。
ツールはVC++6.0を使用しています。

Aベストアンサー

> CEditを使用すると、多くの個所を修正しなくてはならなくなるので、
> 使用することができませんでした。

や、ですから、CString 型の変数は残したまで、
CEdit 型の変数を追加すればよいのです。
ClassWizard の「メンバ変数」-「変数の追加」で、
カテゴリに「コントロール」を選んでください。
(↑方法1)

> ウィンドウハンドルの取得の仕方がわかりません。

ウィンドウハンドルというかポインタの取得方法は、
#1 で episteme さんが書いておられる通りです。
「コントロールID」のところには例えば IDC_EDIT1 などが入ります。
(↑方法2)

QGetStockObjectで取得したGDIオブジェクトハンドルをブラシハンドルにキャストする理由

WINDOWS APIについて質問です。

ウィンドウクラスを登録する際、
winc.hbrBackground= (HBRUSH)GetStockObject(WHITE_BRUSH);
という表現をよく使います。
関数GetStockObject()はHGDIOBJを返します。
HGDIOBJもHBRUSHも実体はvoid*です。
なぜわざわざキャストするのでしょうか。

Aベストアンサー

>HGDIOBJもHBRUSHも実体はvoid*です。
その通りで同値です。
しかしあえてそうすることで「ブラシタイプ」
をソース上、明確にできます。
これは「ソースコードのリーダビリティ」と言う考え方です。
例えば、APIの「GetModuleFileNameEx」などの
「HMODULE」箇所は、他関数の「HINSTANCE」タイプの戻り値を
利用できます。
これは同じハンドルポインタ型だからですし、
設計上、意図されているからです。

QSystem::Drawing::Color::XXXXを変数に代入可能?

連続で質問するのも申し訳ないのですが・・・

VS2005 C++ Expressを使ってWindowsフォームアプリケーションを作っています。(C++/CLI)

ボタンなどのフォームのプロパティに、色を指定するものがあると思いますが、例えばBackColorを白に変更したい場合、
this->button1->BackColor = System::Drawing::Color::White;
のように書けると思います。

この、「System::Drawing::Color::White」の部分を変数のようにして記述したいのですが、どのように宣言した型を使用すればよいのでしょうか?
例えば仮に「System::Drawing::Color::White」がString文字列であれば、
void func1(int choice){
String^ hoge;

  if(!choice){
    hoge = System::Drawing::Color::White;
  } else {
    hoge = System::Drawing::Color::Red;
  }
  this->button1->BackColor = hoge;
}
こんな風にすると、func1(0);と呼ばれるとボタンの背景が白くなり、0以外の引数だと赤くなると思います。
ですが、System::Drawing::Color::XXXはStringではないのでできません。

この場合、hogeをどのような形で定義すればいいのでしょうか?
あるいは別の方法がありますでしょうか?

よろしくお願いします。

連続で質問するのも申し訳ないのですが・・・

VS2005 C++ Expressを使ってWindowsフォームアプリケーションを作っています。(C++/CLI)

ボタンなどのフォームのプロパティに、色を指定するものがあると思いますが、例えばBackColorを白に変更したい場合、
this->button1->BackColor = System::Drawing::Color::White;
のように書けると思います。

この、「System::Drawing::Color::White」の部分を変数のようにして記述したいのですが、どのように宣言した型を使用すればよいのでしょうか?
例えば仮...続きを読む

Aベストアンサー

#1です。
すいません。
System::Drawing::Color^ hoge;
ではなく
System::Drawing::Color hoge;
でした。


void func1(int choice){
System::Drawing::Color hoge;
  if(!choice){
    hoge = System::Drawing::Color::White;
  } else {
    hoge = System::Drawing::Color::Red;
  }
  this->button1->BackColor = hoge;
}

QマルチスレッドでCSocket::Createを呼ぶと落ちる

VC++2008にて、サーバとクライアントPCの相互通信により、
クライアントPC側で、サーバデータを表示する
エクスプローラもどきを作成しています。

サーバ側は、複数台のPCと送受信を行うため、
通信部分をマルチスレッド化しているのですが、
クライアント側は、基本的には、シングルスレッドでOKと考え、
通信部分はマルチスレッド化していませんでした。


クライアントで、ファイルアイコンをクリックしたら、
ファイルデータを受信して、ファイルをオープンし、
クローズすると、サーバへ上書きしに行く部分を、
マルチスレッドにて作成しました。
(ファイルオープンの箇所からマルチスレッド化)

問題が起こっているのは、クローズ後に、
ファイル上書きのために、CSocket派生クラスをCreateすると
落ちてしまうことです。

シングルスレッドでは、Createも正常に通るので、
マルチスレッドから、Createを呼んでることが
原因だとは思うのですが、なぜ原因となっているのか?
また、どのように修正すれば良いかが分かりません。

説明が分かりづらいかもしれませんが、よろしくお願いします。

VC++2008にて、サーバとクライアントPCの相互通信により、
クライアントPC側で、サーバデータを表示する
エクスプローラもどきを作成しています。

サーバ側は、複数台のPCと送受信を行うため、
通信部分をマルチスレッド化しているのですが、
クライアント側は、基本的には、シングルスレッドでOKと考え、
通信部分はマルチスレッド化していませんでした。


クライアントで、ファイルアイコンをクリックしたら、
ファイルデータを受信して、ファイルをオープンし、
クローズすると、サーバへ上書き...続きを読む

Aベストアンサー

こちらを参照してください。
http://www.kt.rim.or.jp/~ksk/wskfaq-ja/articles/csocket.html


このQ&Aを見た人がよく見るQ&A

人気Q&Aランキング

おすすめ情報