トップページ > 記事閲覧
中よせ文字
名前:にこよん 日時: 2017/04/22 17:09

こんにちわ。 いつもお世話になっています。 DrawFormatStringToHandleのような関数で文字の真ん中の座標を指定するような関数はありますでしょうか? もしなければ追加することは可能ですか? 普段文字を描画する時に画面の真ん中に描画することがよくあるのですが、文字を書き換えるたびに ちょっとずつ座標をずらしていくのが大変なのでこのような関数がほしいと思いました。 それと、 SetMouseDispFlag(TRUE) ↑この関数はどれぐらい重たいのでしょうか? というのは、フルスクリーンやスクリーンモードを切り替えるたびにマウスが消えてしまうので、 ループでずっとSetMouseDispFlag(TRUE)関数をよんでいるのですが、少し重くなった気がします。 この関数を呼ぶことで内部で行われている処理が mouse_flag=引数 程度なら重くなることはないと思うので問題ないと思うのですが... SetMouseDispFlag(TRUE)関数を呼び続けているのはあまりよくないのなら30ループに1回など対策はとれるので教えていただきたいです。
メンテ

Page: 1 |

Re: 中よせ文字 ( No.1 )
名前:yumetodo 日時:2017/04/22 18:19

横から。 > DrawFormatStringToHandleのような関数で文字の真ん中の座標を指定するような関数はありますでしょうか? GetDrawStringWidthで一回描画サイズを取得して、画面サイズから計算すればDrawFormatStringToHandleに渡すべき座標は決定できます。 画面サイズは御存知の通りかんたんに取得できるか、下手すれば固定値でコンパイル時に定まるので、ライブラリ側で計算しないで自分で書いてしまうべきでしょう。 割り算と引き算だけですし。
メンテ
Re: 中よせ文字 ( No.2 )
名前:にこよん 日時:2017/04/22 18:05

なるほどそういう使い方ができるんですか、中央描画の関数ばかり探していました。 ありがとうございます。 そんな感じで関数を作ってみます。
メンテ
Re: 中よせ文字 ( No.3 )
名前:yumetodo 日時:2017/04/22 18:20

> SetMouseDispFlag(TRUE) 内部的には ``` // マウスの表示フラグのセット extern int NS_SetMouseDispFlag( int DispFlag ) { int DispState ; // マウスの表示フラグをセットしてメッセージを生成する if( DispFlag != -1 ) { WinData.MouseDispFlag = DispFlag ; } // マウスを表示するかどうかを取得 DispState = WinData.MouseDispFlag == TRUE || GetDisplayMenuState() == TRUE ; // マウスの表示状態が今までと同じ場合は何もしない if( DispFlag != -1 && DispState == WinData.MouseDispState ) return 0 ; // マウスの表示状態をセット { if( DispState == FALSE ) { while( ShowCursor( FALSE ) > -1 ){} ; } else { while( ShowCursor( TRUE ) < 0 ){} ; } } // マウスのセット信号を出す PostMessageW( WinData.MainWindow, WM_SETCURSOR, ( WPARAM )WinData.MainWindow, 0 ) ; // マウスの表示状態を保存する WinData.MouseDispState = DispState ; // 終了 return 0 ; } ``` ShowCursor https://msdn.microsoft.com/ja-jp/library/cc364876.aspx というWIN32APIの関数を呼んでいるのですが、ShowCursorが内部的に持っているカウントを直接いじらせてくれず、 ループを回すというよくわからないコードが出現しています。なんでや。 多分それが重いんじゃないかなぁ(推測)。一応キャッシュコードがあるので延々と重いということはないはずですが(Win32API側のマウス描画コストは知らず)。
メンテ
Re: 中よせ文字 ( No.4 )
名前:yumetodo 日時:2017/04/22 18:19

>GetDrawStringWidthで一回描画サイズを取得して、画面サイズから計算すればDrawFormatStringToHandleに渡すべき座標は決定できます。 ああ、ただし、描画サイズがスクリーンのサイズを超えた場合の折り返し処理は GetDrawStringCharInfoToHandle関数を呼び出して、一文字ずつの幅を取得して計算する必要があるので、もしその可能性があるなら 描画範囲に収まった文字数を返してくれるDrawFormatStringToHandle関数みたいなのを追加することをお願いするのはありかもしれないです。 ref: dxlib.o.oo7.jp/cgi/patiobbs/patio.cgi?mode=view&no=3778
メンテ
Re: 中よせ文字 ( No.5 )
名前:にこよん (一応解決) 日時:2017/04/24 20:01

返信遅くなってしまって申し訳ないです。 マウスの処理の中知ってるなんてすごいですね( `ー´)ノ 一応マウスのフラグをセットする頻度を 20/1 に下げました。 軽くなった...のかな?軽くなったかどうかはちょっとわからないです。 >ああ、ただし、描画サイズがスクリーンのサイズを超えた場合の折り返し処理は >GetDrawStringCharInfoToHandle関数を呼び出して、一文字ずつの幅を取得して計算する必要があるので、もしその可能性があるなら >描画範囲に収まった文字数を返してくれるDrawFormatStringToHandle関数みたいなのを追加することをお願いするのはありかもしれないです。 確かに折り返すこともありますが、それぐらいは自分で調節します。 一応真ん中の座標を求める関数はできたのですが、真ん中の座標を指定して代わりに描画してもらえる関数は作れませんでした。 void draw_nakamozi(int x, int y, char mozi, ...){ } ↑的な感じで...にすればたくさん引数が指定できることははわかったのですがそれをどうすれば受け取れるのかわからず。。。 とりあえずありがとうございました。 もし簡単なやり方があるのなら教えてくださいm(__)m
メンテ
Re: 中よせ文字 ( No.6 )
名前:yumetodo 日時:2017/04/27 19:29

>マウスの処理の中知ってるなんてすごいですね( `ー´)ノ ソースコードは公開されているので誰でも見れますよー >一応マウスのフラグをセットする頻度を 20/1 に下げました。 前述のような実装なので、多分意味ないです。せいぜい関数呼び出しのcall命令とpush命令が消える程度だからnano sec.オーダーの改善かと。 >↑的な感じで...にすればたくさん引数が指定できることははわかったのですがそれをどうすれば受け取れるのかわからず。。。 とりあえずありがとうございました。 ん?なんで可変長引数が必要なんでしょう? とりあえず、折り返し対応版の中寄せ文字列描画関数を作ってみました。改行対応は面倒なのでやってません。 というかDrawStringToHandleは改行対応しているのにDrawStringFToHandleが対応していない時点でモチベがなくなりました。 ttps://bitbucket.org/yumetodo/dxlib_n4092/src/9540438840e9d5b225060e889fa606c2b6c9841b/dxlib_n4092/main.cpp draw_string_center関数がそれです。第1〜4引数に描画可能領域を渡してあげるかんじです。 改行したい場合は戻り値で描画済みの文字列領域の底辺のy座標を返すようにしてるのでそこから座標計算してください。 --- 折り返しで次の行に描画するときのy座標をDxLibでどうやって決定しているのかなと思ったら、 GetFontLineSpaceToHandle関数が返すのと同じ値を使っているんですね。ちょっと探すのに手間取った。
メンテ
Re: 中よせ文字 ( No.7 )
名前:yumetodo 日時:2017/04/27 19:50

>GetDrawStringWidthで一回描画サイズを取得して、画面サイズから計算すればDrawFormatStringToHandleに渡すべき座標は決定できます。 って書きましたが、一応訂正、使うべきはGetDrawStringWidthToHandleですね、上記のでは使わなかったけど。
メンテ
Re: 中よせ文字 ( No.8 )
名前:yumetodo 日時:2017/04/27 21:25

DxLibで中寄せで文字列を描画するのはどのくらい大変なんだろうか? - Qiita ttp://qiita.com/yumetodo/items/8180d48b6fca18d78a90 せっかくなのでこれをネタに記事を書かせて頂きました。
メンテ
Re: 中よせ文字 ( No.9 )
名前:にこよん 日時:2017/05/01 19:33

課題に追われてしばらくパソコンが触れてなかったのですっかりこのスレッドのことを忘れていました。 すみません。 >ん?なんで可変長引数が必要なんでしょう? %dとか%sとかですね。 中央座標と文字や色、フォントを渡して描画してもらう関数を作りたかったのですが %dみたいな変数の受け取り方がわからなかったです。 今は端っこの座標から中央の座標を求める関数で何とかしています。
メンテ
Re: 中よせ文字 ( No.10 )
名前:管理人 日時:2017/05/02 21:55

可変長引数は stdarg.h に定義されている va_start, va_arg, va_end を使用すると値を取得することができます 書式文字列 + 可変長引数を通常の文字列に変換するのは関数 vsprintf_s を使用することで実現できます DrawFormatString の引数 x を文字列の中心 x 座標とする関数を組んでみましたので、よろしければご覧ください m(_ _)m #include <stdarg.h> #include <string.h> int DrawFormatString_Centering_X( int x, int y, unsigned int Color, const char *FormatString, ... ) { va_list VaList ; char String[ 2048 ] ; // 変換後の文字列を格納する配列 int Width ; // va_list の準備( 第二引数は引数『...』の直前の引数を記述します ) va_start( VaList, FormatString ) ; // 書式文字列 + 可変長引数リストから書式文字列に従って文字配列に変換 vsprintf_s( String, sizeof( String ), FormatString, VaList ) ; // va_list の後始末 va_end( VaList ) ; // 文字列描画時の幅を取得 Width = GetDrawStringWidth( String, strlen( String ) ) ; // 指定されたx座標を文字列の中心x座標として描画 return DrawString( x - Width / 2, y, String, Color ) ; }
メンテ
Re: 中よせ文字 ( No.11 )
名前:yumetodo 日時:2017/05/06 23:35

もしくはC++なのでC++11の可変長引数を使って template<typename ...Rest> float draw_string_center_format( float draw_area_x_left, float draw_area_x_right, float draw_area_y_top, float draw_area_y_bottom, unsigned int color, int font_handle, unsigned int edge_color = 0, const std::basic_string<TCHAR>& format, Rest&& ...rest ){ return draw_string_center( draw_area_x_left, draw_area_x_right, draw_area_y_top, draw_area_y_bottom, fmt::format(format, std::forward<Rest>(rest)...), color, handle, color ); } とかすることもできます(fmt::formatはttps://github.com/fmtlib/fmt、C++11の可変長引数と組み合わせることで型安全に)
メンテ
Re: 中よせ文字 ( No.12 )
名前:にこよん (解決) 日時:2017/05/03 04:37

yumetodo様、管理人様ありがとうございましたm(__)m 思った通りのことができたのでこのスレッドは解決にします。 本来なら処理はC++のyumetodoさんのソースのほうがいいのかもしれませんが、私はC++は全く分かりません。 全く分からないコードを使うのはちょっともやもやするので 今回は管理人さんのソースを参考にさせていただきました。 DrawString関数ではなくフォント付き文字で使いたかったので少し改造させていただきました。 int drawstr_xx(int x, int y, int Color, int font, const char *FormatString, ...) { va_list VaList; char String[2048]; //変換後の文字列を格納する配列 int Width; va_start(VaList, FormatString); //va_list の準備( 第二引数は引数『...』の直前の引数を記述します ) vsprintf_s(String, sizeof(String), FormatString, VaList); //書式文字列 + 可変長引数リストから書式文字列に従って文字配列に変換 va_end(VaList); //va_list の後始末 Width = GetDrawStringWidthToHandle(String, strlen(String), getfont(font)); //文字列描画時の幅を取得 return DrawFormatStringToHandle(x - Width / 2, y, Color, getfont(font), String); //指定されたx座標を文字列の中心x座標として描画 } いつも初心者でもわかりやすいサンプルコードを書いていただきありがとうございます。
メンテ

Page: 1 |

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

   クッキー保存