settimer


みあき  2006-06-27 08:10:25  No: 62328

こんばんは。
時間(タイマー)の管理をしたく、ヘルプなどでsettimerにたどり着きました。
SetTimer(
  HWND hWnd,              // ウィンドウのハンドル
  UINT_PTR nIDEvent,      // タイマの識別子
  UINT uElapse,           // タイムアウト値
  TIMERPROC lpTimerFunc   // タイマのプロシージャ
);
私の実力不足で、いまいち使い方がわかりません。

やりたいことは、Form1_Shownの5秒後にMessageBoxを立ち上げたいのですが、ハンドル、識別子、プロシージャが何を意味しているのかわかりません。。申し訳ありませんが、教えていただけますでしょうか。
よろしくお願いいたします。


Blue  2006-06-27 08:12:44  No: 62329

環境は何でしょうか?
> Form1_Shown
ってことは、C++/CLI?(VS2005?)

SetTimerはネイティブなAPIですけど。


みあき  2006-06-27 08:20:37  No: 62330

環境はVS2005です。


Blue  2006-06-27 08:52:40  No: 62331

う〜ん、プロジェクトの種類が何なのかを聞けばよかったですね。
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の記述を入れる。


Blue  2006-06-27 08:59:41  No: 62332

訂正)
> 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


みあき  2006-06-27 10:30:27  No: 62333

ブルー様  ありがとうございます。目的は教えていただいた方法で解決できました。私の自己学習のために、settimerの方法を教えていただけませんでしょうか。わがままで申し訳ないのですが。。。


Blue  2006-06-27 11:45:33  No: 62334

> settimerの方法を教えていただけませんでしょうか
このまま、Windows Formアプリケーションで開発を続ける上で、
ほんとうに必要ない方法ですが、それでも教えてほしいでしょうか?

SetTimerはWindows Formアプリケーション以外のやり方であって、
無理をして使うことない方法です。
(やってできないこともないという方法)
しかも、これを使うとなると、メッセージループ等のウィンドウズアプリの
基本的な動きが理解できていないといけません。


Blue  2006-06-27 11:52:32  No: 62335

とりあえず、ソースだけ。(説明たるい)

    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


Blue  2006-06-27 12:03:18  No: 62336

ついでに、Win32 API を使うには

・#include <windows.h> を適当なところに記述する
・プロジェクトのプロパティから
  リンカ→入力→追加の依存ファイル に適切な lib を追加する
  (基本的に「親またはプロジェクトの規定値からの継承」をチェックすればOK)
  ※ #pragam comment( lib, "〜〜〜.lib" ) でもOK

をしないといけません。


Blue  2006-06-28 08:30:47  No: 62337

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


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加