• ベストアンサー

システムボタンなどがクリックされている間、処理が止まらないようにしたい

VisualC++2005でWindows用のゲームを作成しています。 ウィンドウのメッセージループで、メッセージが無い間は メインの処理を行うという方法で作成しているのですが、 以下の条件で、処理が停止してしまい、処理に不都合が発生してしまい困っています。 ・タイトルバーがクリックされている間 ・タイトルバーの右クリックでメニューが表示されている間 ・タイトルバーのアイコン部分のクリックでメニューが表示されている間 ・「最小化ボタン」をクリックしている間 ・「閉じるボタン」をクリックしている間 ・タスクバーの実行アプリケーション部分の右クリックでメニューが表示されている間 上記の条件で、処理が停止してしまい「タイマーに依存している制御」「MIDI再生に依存している制御」で不都合が出てしまいます。 不都合部分を手直しすることで対応するのは、難しいと判断しています。 理由としては、上記の条件について、 一部ウィンドウメッセージで「発生の瞬間」を取得して 「処理が止まっている間の分だけ、タイマーの経過時間を差し引く」「音楽を止める」 などの対応が可能なのですが、 ウィンドウメッセージで取得できないものもあり、それについては対処できない状態です。 上記の条件において「処理を止めないようにする」という対応方法は存在しますでしょうか。 どなたかご教授よろしくお願いいたします。

質問者が選んだベストアンサー

  • ベストアンサー
  • BLK314
  • ベストアンサー率55% (84/152)
回答No.1

ワーカー・スレッドを作成し、 優先度を高めて(THREAD_PRIORITY_ABOVE_NORMAL以上) おけば良いと思います。 特に、THREAD_PRIORITY_TIME_CRITICALにすれば、 Windowsのどんな処理よりも最優先で実行されます。 (CTRL + ALT + DELよりも優先されるので、 CTRL + ALT + DELでも処理は止まりません) その代償として、 スレッドで重い処理をするとメニュー等の応答が非常に鈍くなります。 最悪、ハングアップ状態になる可能性もあります。 特にTHREAD_PRIORITY_TIME_CRITICALスレッドがハングアップした場合 reset以外打つ手がなくなります。 「処理を止めないようにする」 ことにどの程度の重きを置くのか (CTRL + ALT + DELでも止まってはいけないのかetc) 慎重に判断して使ってください。

motch_cpp
質問者

お礼

ご回答ありがとうございます。 ワーカースレッドを作成するということは、 ウィンドウのメッセージループとは別にメイン処理を行うスレッドを作成するということでしょうか。 現在、そのような仕組みになっていませんので、 一度スレッドを分けた上で、優先度変更の実験を行ってみたいと思います。 ありがとうございました。

その他の回答 (1)

回答No.2

市販ゲームを参考にしましょう。リアルタイム性が要求される、多人数参加型(MMO)RPGオンラインゲームが良いです。 >以下の条件で、処理が停止してしまい、処理に不都合が発生してしまい困っています。 以下のようにすると、ほぼ99%以上は対処出来る筈です。MMO RPGオンラインゲームでも似たような事をして、ゲームの進行停止を防いでいます。 ・ESCキーなどで、いつでも自由に「ポーズ」出来るようにする。ポーズ中はタイマーも音楽も一時停止して、ポーズ解除したらタイマーも音楽も再開するようにする ・マウスの移動範囲をクライアント領域(ゲーム表示画面)のみにキャプチャして、マウスが外に出れないようにする ・ウィンドゥがフォーカスを失ったら強制的にポーズに入る。ESCキーでポーズしたのと同じ状態なのでタイマーも音楽も止まる。もちろん、フォーカスを取り戻した場合はポーズ解除すればゲームを再開できる ・フォーカス喪失を監視するタイマーを用意し、そこで「ウィンドゥにフォーカスがあるか?」を調べ、フォーカスを失っていたら強制的にポーズに入る。 ・その他、悪さをしそうなキー(PrintScreenキーなど)は、メインのメッセージループで捨ててしまう こうすると、少なくとも ・マウスでタイトルバーやタスクバーに移動できないので、システムボタンをクリックできないし、タスクバーの右ボタンメニューも出せない。つまり、処理が止まるような事を起こせない ・Ctrl+Alt+Delキー、Alt+Tabキー、Windowsキー、Windows+Tabキーなど、メッセージで検知出来ない事が起きても、必ずフォーカスを失う事になるので強制的にポーズしてゲームが止まる と言う状態になり「処理が止まるような変な事は起きない」ですし「処理が止まる前にポーズモードに入る筈」です。 要は「処理が止まっちゃうような場所にはマウスを移動させない。処理が止まらないようには出来ないので止まっちゃう前に自分で止めちゃえ」って事です。 蛇足ですが、MMO RPGのオンラインゲームの多くは、ゲーム中にデバッガを起動してメモリを書き換えてアイテムを不正入手するなどのハッキングを防止する為「ゲーム画面がフォーカスを失ったら、有無を言わせず強制終了」するようになっています。 当然ですが、他のプレーヤーが困るので「ポーズ」はありません。 多くの人がネット上で同時にリアルタイムでゲームを進行させる必要があるので、上記で説明したような方法を使って、質問者さんが悩んでいるような事が起きないようになっています。

motch_cpp
質問者

お礼

ご回答ありがとうございます。 確かに、オンラインゲームなどのリアルタイム性が問われるものでしたら、 フォーカスの監視、マウスの移動範囲の制限、 望まないショートカットキーなどの排除などで 不都合が起こらないようにする対応はやむを得ない感じがします。 ですが、私が作成しているものは、 「リアルタイム性」がそれ程重視されるものではなく、 そこまで制限をかけてしまうと、不自然さを感じてしまう印象です。 ですが、オンラインゲームでは、教えていただいたような制限があるものもあるということを始めて知りました。 参考になりました。