トップページ > 記事閲覧
タッチ操作について
名前:たろう 日時: 2015/01/16 22:50

いつもお世話になっております。 またアドバイスを頂きたく失礼致します。 RegisterTouchWindow(GetMainWindowHandle() , TWF_WANTPALM)で タッチウィンドウとしてメインウィンドウを登録した上で SetHookWinProc( WndProc )を使ってWM_TOUCHメッセージを受けとり、下記の様な処理をして、 ウィンドウズのタブレットで画面上の十字キーとボタンで操作出来るゲームを作っています LRESULT CALLBACK WndProc( HWND WindowHandle, UINT Message, WPARAM wParam, LPARAM lParam ) { switch( Message ) { case WM_TOUCH: { unsigned int numInputs = (unsigned int) wParam; TOUCHINPUT* TNB = new TOUCHINPUT[numInputs]; if(GetTouchInpuTNBnfo((HTOUCHINPUT)lParam, numInputs, TNB, sizeof(TOUCHINPUT))) { for(unsigned int i=0; i< numInputs; ++i) { if(TNB[i].dwFlags & TOUCHEVENTF_DOWN) { 処理用関数( TNB[i].dwID , TNB[i].x ,TNB[i].y , 1); } else if((TNB[i].dwFlags & TOUCHEVENTF_MOVE)) { 処理用関数( TNB[i].dwID , TNB[i].x ,TNB[i].y , 2); } else if(TNB[i].dwFlags & TOUCHEVENTF_UP) { 処理用関数( TNB[i].dwID , TNB[i].x ,TNB[i].y , 0); } } } CloseTouchInputHandle((HTOUCHINPUT)lParam); delete [] TNB; } break; default: return CallWindowProc((WNDPROC)dxWndProc, WindowHandle, Message, wParam, lParam); } return CallWindowProc((WNDPROC)dxWndProc, WindowHandle, Message, wParam, lParam); } しばらくはタッチ操作も快調で問題なく動くのですが、十分ほど遊ぶと タッチすると画面がカクつくようになります。 画面に一つ目の指を置いて、2つ目の指を動かした時に 一つ目の指の下にプレスアンドホールドの時に表示される白い四角が 激しく点滅するので、恐らくはウィンドウズ側のWM_TOUCHの情報やその処理が重すぎて、 処理が蓄積していってしまうように感じます。 WM_TOUCHだけ受け取る回数を減らすなど出来ないかと方法を探しても見つからず、、 その上、知識(知能?)が足りないため、それもまったく見当外れのなのかもしれません^^; ウィンドウをもう一つ作る方法なども試しましたが、そのウィンドウもメインウィンドウと同時に 更新されてしまうようで、そのウィンドウだけ回数を減らしてPeekMessageするなども出来ませんでした。 (※それも知識不足が原因かもしれません) 是非ウィンドウズタブレットでの操作が可能なソフトを作りたいのですが よろしければアドバイスをいただけますでしょうか。 もしくはウィンドウズのタッチ操作に正式対応していただけると 大変嬉しいのですが・・・勝手な願望です^^; よろしくお願いいたしますm(__)m
メンテ

Page: 1 |

Re: タッチ操作について ( No.1 )
名前:管理人 日時:2015/01/17 00:34

プログラムの全体を拝見しないと何とも言えませんが、 載せて頂いたプログラムの中の「処理用関数」の中で描画処理を行っていますでしょうか? もし描画処理を行っているとしますと、それを行わないようにすることで症状が改善するかもしれません ( WM_TOUCH の情報を何か構造体の配列などに記憶しておいて、メインループ内のどこかでその構造体配列の  情報を元に処理を行うようにする ) > 一つ目の指の下にプレスアンドホールドの時に表示される白い四角が > 激しく点滅するので 「白い四角」はDXライブラリの DrawBox 関数で描画しているものでしょうか? > もしくはウィンドウズのタッチ操作に正式対応していただけると > 大変嬉しいのですが・・・勝手な願望です^^; タッチに対応したPCを所持していないので直ぐには無理です・・・ よろしければたろうさんがお使いのPCを教えて頂けないでしょうか? タッチ対応PCを購入するかどうかは分かりませんが参考にさせて頂ければと思います m(_ _)m
メンテ
Re: タッチ操作について ( No.2 )
名前:たろう 日時:2015/01/17 07:13

管理人様、ご返信いただき有難う御座います。 ちょっと変なプログラムなので恥ずかしいのですが 処理用関数は以下の様なもので、タッチを押して離すまで識別して 座標を格納する構造体(指)に入れるだけです。描画はありません。 int 処理用関数(int IDn,int x,int y,int オン) { int nb=20; for(int i=0;i<10;i++){if(IDn==指[i].id)nb=i;} if(nb==20){ for(int i=9;i>=0;i--){if(IDBOX[i].オン==0)nb=i;} } 指[nb].id =IDn; POINT pos; if(g最大化>0)//擬似フルスクリーンの場合 { 指[nb].x = (int)(TOUCH_COORD_TO_PIXEL(x)*gDeskWin比率x); 指[nb].y = (int)(TOUCH_COORD_TO_PIXEL(y)*gDeskWin比率y); } else//通常ウィンドウの場合 { pos.x= TOUCH_COORD_TO_PIXEL(x); pos.y= TOUCH_COORD_TO_PIXEL(y); ScreenToClient(GetMainWindowHandle(), &pos); 指[nb].x = pos.x; 指[nb].y = pos.y; } if(オン<=1)IDBOX[nb].オン=オン; return 0; } 使っているタブレットPCは、ARROWS Tab WQ1/Mです dellの、latitude10でも同じ症状が出ました。 白い四角についてですがDrawBoxで描いたものではなく、 ウィンドウズタブレットは、画面をタッチしてそのまま一秒ほどキープすると マウスの右クリックと同じようになるプレスアンドホールドというのがあるのですが 「右クリックされました」というのを分かりやすくするためでしょうか、 ウィンドウズ側が勝手に出すタッチ操作に反応する合図のようなものです。 これがどういうわけかタッチした一本目の指の下に表示されて激しく点滅します 二本目の指を激しく動かすほど激しく点滅します。三本にするとさらに激しくなります いかにも処理が追いついてないというような異常な感じなのですが DXライブラリのメッセージ処理とは別にタッチの処理だけpeekmessageする回数を減らせれば なんとかなる様な気がするのですが、そのような方法はありませんでしょうか? すみません知識が足りず変な事を言っているかもしれません^^; よろしくお願いいたします。
メンテ
Re: タッチ操作について ( No.3 )
名前:管理人 日時:2015/01/18 00:38

処理内容のご解説ありがとうございます あと、ご使用のタブレットを教えて頂きありがとうございます 最近のタブレットPCは DirectX11 に対応しているんですね・・・ ( 考えてみたら DirectX11 が登場してから既に5年が経過!?(・・; ) メッセージの処理が間に合っていないのだとしても、それはPCの性能が足りないのではなく プログラム側で行っているメッセージ処理数が少ないだけの可能性があります DXライブラリでは ProcessMessage でウインドウメッセージを処理しているのですが、 一回の ProcessMessage で5個のメッセージしか処理しないようになっています 昔のPCでは来たメッセージを全て処理すると、メッセージが短時間に大量に来たときに処理落ちが 発生してしまうことがあったので、その対策として一度に処理する数を5個に制限したのですが、 今回の件では逆にそれが不具合の原因になってしまっている可能性があります なので、試しに ProcessMessage の回数を増やしてみて頂けないでしょうか? 例えばメインループが while( PrcessMessage() == 0 ) { // メインループの処理 } このようになっていたとしましたら while( PrcessMessage() == 0 ) { int i ; for( i = 0 ; i < 10 ; i ++ ) { if( ProcessMessage() != 0 ) { break ; } } if( i != 10 ) { break ; } // メインループの処理 } このようにして、メインループ1回で実行する ProcessMessage の回数を増やしてみてください
メンテ
Re: タッチ操作について ( No.4 )
名前:たろう 日時:2015/01/18 06:17

管理人様、ご返信有難う御座います。 早速以下のようにして試してみましたが 全く変化が無いようです。 while(!ProcessMessage() && !ClearDrawScreen() && !GetHitKeyStateAll( Key )) { int i ; for( i = 0 ; i < 10 ; i ++ ) { if( ProcessMessage() != 0 ) { break ; } } if( i != 10 ) { break ; } //ゲームの処理 //・ //・ //・ ScreenFlip(); } さらに100回にして試しましたが、点滅も、しばらくしてからのカクつきもそのままです。 さらに思い切ってProcessMessage()を以下のように削除して実行してみたのですが 不思議なことにProcessMessage()が完全に無いにもかかわらず特に変わりなく起動して、 点滅やカクつきの症状もそのままで、良くも悪くもなりませんでした^^; while(!ClearDrawScreen() && !GetHitKeyStateAll( Key )) { //ゲームの処理 //・ //・ //・ ScreenFlip(); } そもそもウィンドウズストアアプリ以外でタッチ操作に対応した ウィンドウズのゲームを見たことが無いので、ちょっと無理があるような気もしてきました。 とりあえず別ソフトとして十字キーとボタンのコントローラーを作ってソフトと同時に起動して、 ソフトの終了と同時にコントローラーのウィンドウにWM_CLOSEを送って閉じる というのを最後に試してみようかと思います。 お忙しいところお手数をお掛けしてしまい申し訳ございませんでしたm(_ _)m
メンテ
Re: タッチ操作について ( No.5 )
名前:管理人 日時:2015/01/18 11:39

ProcessMessage は関係ありませんでしたか・・・ 最後に幾つかご質問させてください 1.その点滅現象はDXライブラリを使用したアプリのウインドウの上でのみ発生するのでしょうか? 2.一応のご確認ですが SetDrawScreen( DX_SCREEN_BACK ) ; を実行して、描画先を裏画面にされていますでしょうか?   ( 稀に DxLib_Init の前で SetDrawScreen を使用してしまっていたり、ChangeWindowMode や    SetGraphMode の後に使用していなかったりということがあります ) 3.DxLib_Init 呼び出しの前に SetWaitVSyncFlag( FALSE ) ; を記述して、VSYNC待ちを   しないようにした場合も同様の現象が発生してしまうでしょうか? 4.「画面がカクつく」とのことですが、単に白い四角が点滅するだけではなく   ゲームの進行が遅くなる「処理落ち」が発生してしまうのでしょうか?
メンテ
Re: タッチ操作について ( No.6 )
名前:たろう 日時:2015/01/18 17:40

管理人様、ご返信有難う御座います。 1の点滅についてですがウィンドウズストアアプリ以外で ジェスチャーではないタッチに対応しているソフト自体が 少ないのであまり試せてはいないのですが、 私の作ったソフト以外では点滅が起こったことはありません。 例えばベクターにあるVirtualPadというウィンドウズタッチパネル用の 擬似コントローラーでは発生しませんでした 2につきましては以下の様な順番で その後ChangeWindowModeやSetGraphModeの使用はありません ChangeWindowMode( TRUE ) ; SetHookWinProc( WndProc ) ; SetGraphMode(横幅,縦幅,16); SetAlwaysRunFlag(TRUE); SetOutApplicationLogValidFlag(FALSE); if(DxLib_Init() == -1) return -1; SetMouseDispFlag( TRUE ) ; SetDrawScreen( DX_SCREEN_BACK ) ; RegisterTouchWindow(GetMainWindowHandle() , TWF_WANTPALM); 3ですがSetWaitVSyncFlag( FALSE ) ;を上記の if(DxLib_Init() == -1) return -1;の直前に差し入れて試してみましたが 全く変化無しです。 4ですが、まず一本目の指を置いて何もしなければ何も出ません。 その指を離さずに二本目の指を置くとその時にまず一瞬四角が 一本目の下に表示され、その後両方の指を離さずにグリグリ動かしていると たまに四角が表示されます。タイミングが不定なのでなぜ表示されるのか わからないのですが、しばらくはこの表示だけで動きはスムーズです。 この状態で十分ほど遊んでいると偶にピクピクとゲームが瞬間的に止まって カクカクします。使っているうちにどんどんこれが悪化していって、 最後は指をおいただけでゲームの進行が半分くらいの速度にモッサリします。 (※この最悪の状態になるまで一時間位かかりますが、左手で一本指をおいて 右手の全指でバタバタすると初めからすごい勢いの点滅になって、一分ほどで 最悪の状態になることが分かりました) ここで一旦ゲームを閉じて、しばらくして再度立ち上げても はじめのスムーズな状態には戻らずに、指をおいただけで速度の落ちる 最悪の状態からはじまるので、ウィンドウズのタッチ機能の方で処理がパンクして 問題が出ているように感じます。 はじめのスムーズな状態にはパソコンを再起動しないと戻りません。 おそらくDXライブラリに問題があるわけでは無いと思いますので、 少々申し訳なく感じております。 お手数をお掛けしてしまい申し訳ございませんm(_ _)m 追記します: その後色々試しすぎたせいか、 なんとパソコンを再起動しても元に戻らなくなりました。 その上今までは最悪の状態になってもタッチしなければ スムーズに動いていたのですが 起動直後からタッチをしなくてもカクカクするようになっています^^; こういう場合はOSを再インストールしないと治らないでしょうか^^; 追記します: 上の追記はテストで入れたSetWaitVSyncFlag( FALSE ) ;の削除を 忘れているのが原因でした。バカですすみませんm(_ _)m
メンテ
Re: タッチ操作について ( No.7 )
名前:管理人 日時:2015/01/18 17:52

ご返答ありがとうございます 一度カクカク状態になるとパソコンを再起動するまで直らないんですか Σ(・・ それは少し根が深そうですね・・・ こちらの富士通のドライバダウンロードのページで http://www.fmworld.net/cgi-bin/driversearch/drvindex.cgi?COLOR=1 「検索方法2」の部分に「WQ1/M」と入力して検索をすると WQ1/Mが検出され、更に「検索開始」のボタンを押すとARROWS Tab WQ1/M用の ファイルが一覧で表示されます BIOSやディスプレイドライバなど、去年の中ごろまで更新されていますので、 もしかしたらこれらを適用すれば症状が改善するかもしれません ともあれ、お力になれず申し訳ありません 私もなるべく早く現象が確認できる環境を揃えようと思います > 追記 直った様で何よりです
メンテ
Re: タッチ操作について ( No.8 )
名前:たろう 日時:2015/01/18 19:13

管理人様、ご返信有難う御座います。 先程biosとディスプレイドライバを更新してみましたが やはり変わりなく、同じようにカクついてパソコンを再起動するまで 治らない状態です。 とりあえず別ソフトで擬似コントローラーを作ってソフトと同時起動して ソフト終了とともにそのソフトも閉じるというやつを作ってみようと思います 何度もお手数をお掛けして申し訳ございませんでした。 失礼致します。
メンテ
Re: タッチ操作について ( No.9 )
名前:たろう() 日時:2015/01/28 06:51

お世話になっております。その後、解決策が見つかりましたので報告させていただきます。 上記の怪しい点滅症状につきましては、RegisterTouchWindowを入れるだけで WM_TOUCHなどのメッセージ処理を一切書かなくても起こることがわかりました。 それでREGISTER〜を必要としないWM_POINTERDOWNなどに変更することで 点滅も、しばらくしてからのカクカクも発生しなくなりました。 WM_POINTERDOWNの使用はwindows8以降に限定されますが windows10は無料でwin7以降からアップデート出来るそうですから win7で使えなくなる点も大きな問題ではないと思われます。 同じ問題でお悩みの方は、よろしければご参考になさって下さい。 失礼しましたm(_ _)m
メンテ
Re: タッチ操作について ( No.10 )
名前:管理人 日時:2015/01/29 02:50

ご情報ありがとうございます タブレット等に対応する際は参考にさせて頂きます
メンテ

Page: 1 |

題名
名前
コメント
パスワード (記事メンテ時に使用)

   クッキー保存