質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Win32 API

Win32 APIはMicrosoft Windowsの32bitプロセッサのOSで動作するAPIです。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

1回答

2697閲覧

C/C++でのsetInterval ( GUI 用 )

BeatStar

総合スコア4958

Win32 API

Win32 APIはMicrosoft Windowsの32bitプロセッサのOSで動作するAPIです。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2016/11/08 02:00

自作関数 setInterval と WM_TIMER について。

C/C++ ( WindowsAPI 実装 ) でやっています。

JavaScriptでいう setInterval関数 のようなものってないでしょうか。

"Stack Overflow" というサイトでは、

C++11 の thread を使う方法が掲載されています。

CUIで試したところ、うまくいったのですが、

GUI で試したところ、クラッシュしてうまくいきませんでした。

C++

1typedef bool (*INTERVALTHREAD)(); 2 3 4void setInterval(INTERVALTHREAD function,int interval) { 5 thread th([&]() { 6 while(true) { 7 std::this_thread::sleep_for(std::chrono::milliseconds(interval)); 8 if( function() != true ) break; 9 } 10 }); 11 th.detach(); 12} 13 14// グローバル変数。 別のスレッド ( ウィンドウプロシージャ等 ) から "終了命令" を下すため。 15int a; 16 17bool func(){ 18 a++; 19 if( a <= 4 ){ 20 printf( "OK\n" ); 21 return true; 22 }else{ 23 return false; 24 } 25} 26 27

を GUI に埋めこんでみましたが、クラッシュしました。

WindowsAPI の SetTimer関数 と WM_TIMER で処理するのはいいのですが、

「Win32 API入門」(http://wisdom.sakura.ne.jp/system/winapi/)
->「標準 Windows API」の
->「タイマー」

には、

『さらに、タイマーは 1000 ミリ秒に設定したからといって
必ず1秒後に WM_TIMER が実行されるとは限りません
WM_TIMER が発生した時、他のメッセージが処理中であれば
その間 WM_TIMER はキューの中で実行を待つことになります

また、コールバック関数を使って指定関数を呼び出すことも可能です
この場合は、指定時間が経過するとWindowsが関数を呼び出します...』

とあります。

他のサイト ( どこだったか忘れましたが。 ) でも

ウィンドウプロシージャにキューされるが、(その他の)処理内容が多い場合、指定間隔よりも長くなる可能性がある。

といった感じの文がありました。

今のところ (その他の)処理が多い プログラムが思いつかないのですが、
(他の)処理のために指定間隔がずれるのを防ぐ方法はないのでしょうか。

WinAPI の SetTimer関数 で指定する コールバック関数を 定義すれば回避できるのでしょうか。

それとも他にやり方があるのでしょうか。

[環境等]
言語 : C/C++ ( WinAPI 実装 )
コンパイラ: MinGW

宜しくお願い致します。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

こんにちは。

GUI で試したところ、クラッシュしてうまくいきませんでした。

CUIでできるならGUIでクラッシュする理由はないです。
GUIへ移植する際に単純な移植ミスをしているのでは?
もし、少ない回数ではうまくいくけど、長期間やっていると落ちるなら排他制御ミスでしょう。

(他の)処理のために指定間隔がずれるのを防ぐ方法はないのでしょうか。

方法は多数ありますが、どの程度の精度を必要とするのか?によりやり方が異なります。
JavaScriptの置き換えならばそれ程精度は必要としないはずですので普通にWM_TIMERで十分ではないでしょうか?

WinAPI の SetTimer関数 で指定する コールバック関数を 定義すれば回避できるのでしょうか。

残念ながらできません。ウィンドウ・プロシージャとコールバックは、両方ともメイン・スレッドで実行されますのでメイン・スレッドで何か他の処理をしていたら、どちらともその処理が終わるのを待たされます。

それとも他にやり方があるのでしょうか。

既に試みられているサブ・スレッドを用いる方法で可能です。
でも、排他制御等頭の痛い問題も発生しますので、「今のところ (その他の)処理が多い プログラムが思いつかないのです」と言う状況なら、あまりお勧めしません。

JavaScriptのsetInterval関数は知りませんが、お手軽に使えるものであればサブ・スレッドで実装されているとは思えませんので、WM_TIMERでも精度は大差無い筈です。

投稿2016/11/08 02:56

Chironian

総合スコア23272

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問