こんばんは。
時間(タイマー)の管理をしたく、ヘルプなどでsettimerにたどり着きました。
SetTimer(
HWND hWnd, // ウィンドウのハンドル
UINT_PTR nIDEvent, // タイマの識別子
UINT uElapse, // タイムアウト値
TIMERPROC lpTimerFunc // タイマのプロシージャ
);
私の実力不足で、いまいち使い方がわかりません。
やりたいことは、Form1_Shownの5秒後にMessageBoxを立ち上げたいのですが、ハンドル、識別子、プロシージャが何を意味しているのかわかりません。。申し訳ありませんが、教えていただけますでしょうか。
よろしくお願いいたします。
環境は何でしょうか?
> Form1_Shown
ってことは、C++/CLI?(VS2005?)
SetTimerはネイティブなAPIですけど。
環境はVS2005です。
う〜ん、プロジェクトの種類が何なのかを聞けばよかったですね。
2005では、いろいろな方法でアプリケーション作れますからね。
それによって、書き方もいろいろあるわけです。
まぁ、Windows フォームアプリケーションとして一応回答してみる。
SetTimer APIを使わなくても、 Timerコントロールを使うとお手軽にできます。
1)ツールボックス→コンポーネント→TimerをFormにドロップ
2)timer1のプロパティの Enabled を True、Interval を 5000(ms) に設定
3)プロパティウィンドウのカミナリマークを選択し、
Tickイベントを追加する(timer1_Tick)
4)timer1_Tickイベント
timer1->Enabled = false;
とMessageBox::Showの記述を入れる。
訂正)
> 2)timer1のプロパティの Enabled を True、Interval を 5000(ms) に設定
Enabled は False のままで、
Form1_Loadイベントで、
timer1->Start(); // または timer1->Enabled = True;
のほうが適切でした。
ついでに
> timer1->Enabled = false;
は timer1->Stop(); のほうが(意味合い的にも)わかりやすいかも。
参考)C# Timerコントロール
http://vbdotnet.fc2web.com/csharp/control/TimerMenu.htm
ブルー様 ありがとうございます。目的は教えていただいた方法で解決できました。私の自己学習のために、settimerの方法を教えていただけませんでしょうか。わがままで申し訳ないのですが。。。
> settimerの方法を教えていただけませんでしょうか
このまま、Windows Formアプリケーションで開発を続ける上で、
ほんとうに必要ない方法ですが、それでも教えてほしいでしょうか?
SetTimerはWindows Formアプリケーション以外のやり方であって、
無理をして使うことない方法です。
(やってできないこともないという方法)
しかも、これを使うとなると、メッセージループ等のウィンドウズアプリの
基本的な動きが理解できていないといけません。
とりあえず、ソースだけ。(説明たるい)
private: literal unsigned int nTimerID = 1;
private: System::Void Form1_Load(System::Object^ sender, System::EventArgs^ e) {
::SetTimer( ( HWND )this->Handle.ToPointer(), this->nTimerID, 5000, NULL );
}
protected: virtual void WndProc(System::Windows::Forms::Message% m) override {
switch ( m.Msg ){
case WM_TIMER:
if ( m.WParam.ToInt32() == this->nTimerID ){
::KillTimer( ( HWND )this->Handle.ToPointer(), this->nTimerID );
MessageBox::Show( L"TEST" );
}
break;
}
Form::WndProc( m );
}
参考)Win32 アプリケーションにおける SetTimer の使い方
http://wisdom.sakura.ne.jp/system/winapi/win32/win47.html
ついでに、Win32 API を使うには
・#include <windows.h> を適当なところに記述する
・プロジェクトのプロパティから
リンカ→入力→追加の依存ファイル に適切な lib を追加する
(基本的に「親またはプロジェクトの規定値からの継承」をチェックすればOK)
※ #pragam comment( lib, "〜〜〜.lib" ) でもOK
をしないといけません。
TimerProcを使う方法(あっている自身はない)
using namespace System::Runtime::InteropServices;
private:
UINT_PTR nTimerID;
GCHandle gch;
delegate VOID TimerProcDelegate( HWND, UINT, UINT_PTR, DWORD );
static VOID TimerProc( HWND hwnd, UINT uMsg, UINT_PTR uIDEvent, DWORD dwTime )
{
::KillTimer( hwnd, uIDEvent );
MessageBox::Show( L"TEST" );
}
System::Void Form1_Load( System::Object^ sender, System::EventArgs^ e )
{
TimerProcDelegate^ timerProcDelegate = gcnew TimerProcDelegate( Form1::TimerProc );
this->gch = GCHandle::Alloc( timerProcDelegate );
IntPtr deletegatePointer = Marshal::GetFunctionPointerForDelegate( timerProcDelegate );
TIMERPROC timerProc = static_cast< TIMERPROC >( deletegatePointer.ToPointer() );
HWND hWnd = static_cast< HWND >( this->Handle.ToPointer() );
this->nTimerID = 1;
//GC::Collect();
this->nTimerID = ::SetTimer( hWnd, this->nTimerID, 5000, timerProc );
if ( this->nTimerID == 0 )
{
this->gch.Free();
MessageBox::Show( L"タイマーのセットに失敗しました。" );
}
}
System::Void Form1_FormClosed( System::Object^ sender, System::Windows::Forms::FormClosedEventArgs^ e )
{
if ( this->gch.IsAllocated )
{
this->gch.Free();
}
}
参考
http://msdn2.microsoft.com/ja-jp/library/367eeye0.aspx
ツイート | ![]() |