« 2014年11月 | トップページ | 2015年2月 »

2015年1月

2015年1月31日 (土)

キーボードコントロールを実装しました その5

最後まで残っていた「特殊キー」のイベント取得についてですがプラットフォームのネイティブイベントをフックするAbstractNativeEventFilterインタフェースを継承して、QApplication::installNativeEventFiler()を利用して登録すればWindowsのメッセージ(MSG)をフックできるという仕組みを利用することにしました。

この仕組はQt5.0で実装されたものらしいので、それより前のQtだとQApplication::winEventFilter()という関数を再実装することでWindowsだけならば可能らしいですが、Qt5でより多くのプラットフォームに対応した感じですね。

具体的にはbool nativeEventFilter()というメンバー関数を実装することになります。ここで必要なのはキーイベント(WM_KEYUP/WM_KEYDOWN)の特定のキーに関するイベントのみなので以下の様な感じになります。その他のメッセージはスルーします。


bool MainWindow::nativeEventFilter(const QByteArray &eventType, void *message, long *result)
{
  if (eventType == "windows_generic_MSG"){
	MSG *msg = static_cast<MSG *>(message);
	if (msg->message == WM_KEYUP ||
		msg->message == WM_KEYDOWN){
	  switch(msg->wParam){
	  case VK_OEM_AUTO:		// 全角/半角キー
	  case VK_OEM_ENLW:		// 全角/半角キー
	  case VK_CONVERT:		// 変換キー
	  case VK_NONCONVERT:	// 無変換キー
	  case VK_OEM_ATTN:		// カナ/ひらキー
		// 上記の4つのキーの押下に関してのみフックする
		// .. 処理 ..
		return true;
		break;
	  default:
		// その他のキーはスルー
		return false;
		break;
	  }
	}
  }
  return false;
}



この仕組み自体はWindowsでのみ必要なので、Linuxなどのプラットフォームでは通常のKeyPressイベントなどで対応可能だと思います。

2015年1月29日 (木)

Qt Brynhildr(仮称) の その後のこと

雑用が忙しく、「サウンドがうまく再生できない」、といったまま2ヶ月放置していましたが、思いつく限りの修正を行っても、改善しなかったので…Qtの機能のみを使うという方針を諦めました…

具体的には、Qtのネットワークの仕組みに関して、です。

Brynhildrのパブリックモードでは3つのソケットを使って、それぞれキーボード/マウスの制御情報、グラフィックス情報、サウンド情報を通信します。Qtのネットワーク通信機構では、QTcpSocketというクラスを利用してやりとりを行うのですが、このクラスを用いた通信の仕組み自体がどうやらマルチスレッドに対応していないそうです。マルチスレッドで実装すると正しいデータが受信できません(;ω;)

シングルスレッド内でsignal/slotを用いた3つの通信を同時に行うとやはり通信スピードが間に合いませんでした。サウンドの再生バッファを常に満たせるほどのスピードがでないのです…結果プチノイズがヒドイのです。

最終決断として、ネットワーク通信だけネイティブな機能(WindowsではWinSock)を使うことにしました。
3つの処理はそれぞれQtのスレッド(QThread)を継承して別々に実装します。その中での通信は直接WinSockを利用します。ネットワーク処理は1つのクラスに閉じ込めたので、Linuxのような他のプラットフォームの場合はここだけを変更すれば大丈夫だと思います。

綺麗に音が鳴ると気持ち良いですね…遅延もzeroshikikaiのレベルにはなっていると思います。

Windows 8.1 update 版 Qt Brynhildr (音出るよ、キーボード、マウスもO.K.版) テスト動画

細かい未実装処理の実装とソースコード整理をしないと…

Windows版パッケージを作って公開、その後ソースコード公開でしょうかね…いつになるのだろう…

« 2014年11月 | トップページ | 2015年2月 »