忍者ブログ

マインのブログ

マインが何かを気まぐれに書く日記です。

[PR]

カテゴリー:

2017/06/29(Thu)04:01

×

[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。

No.|CommentTrackback

6連休が始まる

カテゴリー:プログラムとか

2009/09/18(Fri)00:20

明日から6連休です。
やほーい。
・・・、連休明けはきつそうだな・・・。

今日も仕事。
でも、そんなに作業はしてない。
仕事で使うソフトの使い方を書いてたり、テストプログラムを作ってたりした。
JavaのSwingを使っているんですけど、結構難しい。
Eclipseではどうやってるんでしょうかね。
今日はチェックボックスリストに挑戦。
Eclipseで実行する時にファイルの更新を保存しますかの
ダイアログのリストみたいなのを作ろうとしてました。
結論から言えばできましたが、これをどうやったら汎用化できるのだろうか・・・。

JListにチェックボックスを入れるのは以外に簡単です。
JCheckBoxを拡張し、ListCellRendererを実現してやって、
格納するデータにフラグを持たせてやればいいです。
或いは、JCheckBoxをリストに格納してやればいいです。
有効無効の切り替えは、JListにMouseListenerを登録して、
クリックした時にマウスカーソルの場所からリストのインデックスを取得、
そのインデックスのデータのフラグを変更するなり、
チェックボックスのチェックをつけたりはずしたりするなりすればいいです。

ただ、この方法だとチェックボックスの四角だけでなく、
文字列をクリックしてもチェックの有効/無効が切り替わります。
Eclipseの保存確認ダイアログをいじると分かると思いますが、
文字列のところをクリックしても有効/無効は切り替わりません。
なので、ちょっと変更。

始めはリストセルのチェックボックスの四角のところにマウスカーソルがあるとき、
みたいな判定をつけようとしたのですが、ちょっと別なことをやってみました。
今回やってみたのは、データを登録する際にチェックボックスとラベルを持つ
パネルをリストに入れる、という方法です。
ListModelとListCellRendererを改造したものを使えば出来ます。
マウスのあるインデックスのデータ(パネル)を取り出して、
そのパネルのチェックボックスの有効/無効を切り替えることが出来ます。
もちろん、チェックボックスの上にマウスカーソルがあるとき、という条件が必要ですが。
この方法だと、Eclipseみたいに、チェックボックスの右にアイコンがあって、
その右に文字列を表示、みたいなことも比較的簡単に出来ます。

最初に書いたとおり、汎用化できるのかとかまだ検証してません。
テストもそんなにしてないので実際は使えない可能性も。
これが出来なかったらJTableにチェックボックスを入れるヤツに変更ですかね。
これならてんぷらにサンプルがあるし。

と、こんなことをやってたら定時になりました。
きりがよかったのでさっさと帰ってきました。
帰ってきてメールをチェック。
まだポケモンの支払いは来てませんでした。
アマゾンを見てみると、ゴールドの値段が6000円になっていた。
どうも、昨日オレが申し込んだ後にアマゾンが確保していた分が埋まったみたいです。
なかなか際どいタイミングだったようです。
昨日のメールを見て、ちゃんと定価以下の値段であることも確認しました。
後は待つだけか。

夕食後、DQ9をやってました。
うえー、金稼ぎだリー・・・。
ダンジョンに1階潜って5000ちょっとか・・・。
もう少し稼げるといいんだが・・・。
やっぱレベルか?レベルなのか??

そのあとmixiアプリで遊んでました。
サンシャイン牧場とアルヴィオンを登録してみました。
牧場のほうはバグか何かでブラウザが3回ほど落ちました・・・。
マイミク関連の操作はしないようにしよう・・・。
平日とかふつーに操作できないから作物が全滅しそうだな・・・。
アルヴィオンは戦闘が自動で進むのである程度運が必要。
まだ最初のクエストすらクリアできない・・・。
もう1つくらい攻撃魔法カード入れてみるか?

日記を書いてたらもうこんな時間。
牧場を一回覗いてから寝ますかね。

拍手[0回]

PR

No.1811|Comment(0)Trackback(0)

断食

カテゴリー:プログラムとか

2009/09/15(Tue)00:05

明日は健康診断です。
なので、21時ごろから断食を強制されています。
まあ、もともと夜に何かを食べるほうじゃないので。
最近は。

今日も朝から作業です。
大分共通部分が見つけられてきたかな、と言うところ。
クラスが多くなってきて何がなんだか・・・。
コメント書きながらやってます。
今日はちょっとテストプログラムを作ってました。
作ったのはポップアップメニューにスクロール可能なメニューを入れるというもの。
いわゆる、ScrollableMenuと呼ばれるもので、
スクロールバーありのメニューを格納するといったもので、
IEのスクロールメニューとは違うもの。
また、てんぷらさんで紹介されているものより少し汎用性のあるものにしました。
Office2007のリボンメニューみたいなことが出来ます。

てんぷらさんで紹介されているものはBasicComboPopupを継承して
新たなポップアップメニューを作成していますが、
これではネストしたメニューには対応できません。
JMenuの中にJMenuを入れて、その中にスクロール可能メニューを入れるといったことが出来ないのです。
(もしかしたらできるのかもしれませんが、オレにはできませんでした)
なので、コンポーネントにMenuElementを継承してそれをメニューに追加できるようにしました。
参考サイトを見つけたので意外に早く終わりました。
ただ、JScrollPaneにMenuElementをインプリメントさせてその中にJListを入れても
ちゃんとポップアップメニューになるようにするのに苦労しましたね。
結局MouseListenerを使って強引にアクションを送るようにしました。
さらに、てんぷらさんの「マウスがあるところを強調するリスト」のアイデアで
マウスがあるところを選択状態になるようにするとOffice2007のリボンメニューのようになりました。
ソースとかは、そういう気分になったときにでも、
前のComponentTitledBorderと一緒に公開したいな、と思ったり。
いつになるか分かりませんけどね・・・。

そんなことをやって、クラス図を作ってたら定時になりました。
明日が健診なので早めに帰りました。
ジャンプと親に頼まれていたものを買って帰宅。
それからテレビを見ながら夕食。

NHKのクローズアップ現代で、「希望学」について放映されていました。
学歴、収入などに恵まれている人には希望がある人が多いと言う統計の一方、
恵まれている環境にいながら希望があるとは答えなかった人もいる、といったもの。
全部は見れなかったのですが、困難にぶつかっても前向きに生きること、
そして思いもよらない関係が問題の打開策となり、それが希望につながる、
と言ってたような気がします。
まあ、これを見ててしゅごキャラのことが一番に思い浮かんだオレはクソダメ人間だと思いました。
×たまは絶望・無気力などのマイナス感情の象徴。
この×を取れるアム(亜夢?字知らん)は最高のカウンセラーになれると思いました。
・・・、クソダメ人間の思考なのでまともな人は無視してください・・・。

と、こんなこと書いているうちに日が変わってしまった。
そろそろ寝ないとな。
・・・、ジャンプを少し読んでからにするか。<ダメ人間

拍手[0回]

No.1808|Comment(0)Trackback(0)

またー

カテゴリー:プログラムとか

2009/09/03(Thu)23:13

もう、また仕事で使ってるPCの調子が悪くなった。
再起動に20分以上かかる・・・。
イベントビュアーを見るとPrint Spooler起動の前にReadFileがタイムアウトしている。
うーん、なんだろ・・・。

朝、会社に着いてPCの電源を入れたらなんか起動が遅かった。
ま、まさか・・・。
と思って何回か再起動してみた。
またあれです、再起動に20分以上かかるあの症状です。
何が原因かまったく分かりません。
エラーが発生しているので、先輩の助言でダンプを出さないようにしてみました。
あとは明日PCを起動したときにどうなるか・・・。
ダメだったら再セットアップだな・・・。
特に何もいじってないのに・・・。

気合でPCを動かし、仕事は出来ました。
で、昨日の続き。
ComponentTitledBorderに階層構成のコンポーネントを配置した場合の処理。
これがめっちゃタフかった・・・。
Container.validate()だけじゃぜんぜん解決しなかった。
やったことは、まず、SwingUtilities.paintComponent()の前に、
タイトルコンポーネントのdoLayout()を呼ぶ。
そのあと、Container内部の全てのコンポーネントに対して
setBounds()でコンポーネントの位置と大きさを確定させる。
内部のコンポーネントは、Container.getComponents()で取れます。
予めdoLayout()を呼んでいるので、
いったんタイトルコンポーネント内部を描画したことと同じになっている(と思うんだけど)ので、
getPreferredSize()やgetBounds()とかでなんとかなります。
(なぜか、setBoundsをやらないとウィンドウ再描画とかでおかしくなる・・・)

次にdispatchEvent()のところ。
これは上に比べて簡単で、タイトルコンポーネントとその内部のコンポーネントすべてに対して
Component.dispatchEvent()を呼んであげればいいだけ。
どうせ、JPanelの中にJCheckBoxがあってもJPanelをタイトルコンポーネントとしているのなら、
タイトルコンポーネント内の全てのコンポーネントのサイズは
タイトルコンポーネントのサイズでいいじゃないか、ということでそのままにしてます。
うーん、でも、やっぱりちゃんと計算した方がいいのかな・・・。
そうすると計算が・・・。
FlowLayoutのパネルにパネルを入れると一計算がうまくいかないんよね・・・。
どうやるんだろ。
まあ、タイトルコンポーネントにMouseListenerでも入れておいてくださいよ。

なんとかうまく動いているっぽいのでここでコーディングは終了。
ぐはー、疲れた・・・。
Javaで予めこういうの用意してくれればいいのに・・・。
今あるTitledBorderなんて、ComponentTitledBorderのタイトルコンポーネントを
Stringを描画するJLabelにしちゃえばいいじゃんかよ。
なんでTitledBorderに表示するタイトルをStringで保持してるんだよ。

このあとはクラス図を書いてました。
まだ画面構成が出来てないのに画面のクラス図ですよ。
まずは必要なコンポーネントを置いてみる。
別の画面でも使いそうなコンポーネントは共通コンポーネントとしてみる。
書いていると、「ああ、この画面はこうした方がいいな」といったところが出てくる。
明日は画面の構成を考えるか。
PCがちゃんと動けばな!

今日は今月から入ってきた人の歓迎会。
いつもの中華料理店。
おしゃべりしてきました。
なんだかんだで3時間も居座ってました。
最後の方はぐだぐだでした。
あれで2次会行くとかどんだけ元気なんですかね・・・。
明日も仕事あるのに。

帰ってきてからすぐにBleachのエンコード。
それから風呂に入って、すこしゆっくりしてから見ました。
はい、次ー。

この2日ほど、DQ9をやりながら腹筋をした。
は、腹がいてー・・・。
筋力落ちすぎ。
仰向けになって足を紙一重で浮かせるのが一番きつい。
背筋もやってみようかな。

さて、そろそろDQ9をやってそれから寝るかね。
PCが怖い・・・。

拍手[0回]

No.1802|Comment(0)Trackback(0)

疲れた・・・

カテゴリー:プログラムとか

2009/09/02(Wed)22:58

今日はものすごい疲れた・・・。
Swingよく分からない・・・。

今日も仕事です。
仕事ではJavaを使うことになっています。
GUI部分についてはSwingを使います。
で、GUIのところに、TitledBorderのタイトル部分にComponentを配置する、
というのをやることになりそうだと言うことで、以下のサイトを参考に色々いじってました。
http://terai.xrea.jp/Swing/ComponentTitledBorder.html
http://www.jroller.com/santhosh/entry/component_titled_border
試しに上のサイトのサンプルを動かしてみるとバグが・・・。

実際に動かしてみると分かりますが、タイトルに配置したコンポーネントの挙動が
普通にコンポーネント配置した場合と違います。
ボタンを置くと分かりやすいかな?
まず(1)マウスをコンポーネントからどかすとロールオーバーが解除されない。
そして、(2)ボタンを押したままマウスをボタンの外に移動して離すとボタンが押されたままになる。
これを解決するため、自分なりにソースをいじってみました。

最初は1番の問題。(以下、Santhoshさんのソースを基に書いてます)
これは51行目でタイトルに配置したコンポーネント(27行目、comp)内にマウスがあるときのみ、
comp.dispatchEvent()(55行目)を呼んでいるため。
なので、タイトルのコンポーネントを出てもdispatchEventを呼べるように直します。
51行目のif分の条件式を二つに分けて
if (rect != null) {
    if (rect.contains(me.getPoint()) {  //Santhoshさんのと変えてます
        //マウスがcomp内のときの処理もdispatchEvent
    }
    else {
        //マウスがcomp外のときの処理もdispathEvent
    }
}
みたいにして、うまくcomp.dispatchに渡すMouseEventを渡してやればいいと思います。
しかし、comp外のときの処理によっては別の問題が発生します。
ボーダーを適用するコンポーネント(container、28行目)にマウスが入ったら
タイトルコンポーネントがロールオーバーされます。

これを回避するため、containerにはMouseMotionListenerを登録し、
mouseDragged()とmouseMoved()にはdispatchEvent()を呼ぶように実装します。
そして、mouseEntered()(78行目)のdispatchEvent()は消します。
さらに、マウスがタイトルコンポーネント(containerではない)に入ったかの判定フラグを用意します。
そして、
マウスがcomp内、かつフラグがfalseなら、フラグをtrueにしてMOUSE_ENTEREDのMouseEventを、
マウスがcomp内、かつフラグがtrueなら、53行から58行の内容のMouseEventを、
マウスがcomp外、かつフラグがtrueなら、フラグをfalseにしてMOUSE_EXITEDWのMouseEventを、
マウスがcomp外、かつフラグがfalseなら、53行から58行の内容のMouseEventを、
comp.dispatchEvent()に渡してやればいい・・・と思います。(うろ覚え)
これで、マウスをcomp外で放したときにも対応できるので2番の問題も解決します。

上で説明したないように、FocusListenerを付加させてフォーカスにも対応したのが、
Santoshさんのページの下のほうにある投稿です。
インデントされてないので見にくいですが・・・。

で、実際に実行してみると、TitledBorderのタイトルの配置と違うことに気付きました。
TitledBorderのタイトルは、ボーダーのインセットの中央に配置されます。
一方、ComponentTitledBorderはボーダー上部にくっつくように配置されます。
また、x座標も違います。
new ComponentTitledBorder(checkBox, panel, BorderFactory.createLineBorder(Color.RED, 50));
とかにすると分かりやすいと思います。
これはSantoshさんのソースの49行目のRectangleの引数を調整してやればいいです。

int rectx = borderInsets.x + offset;  //ボーダーの厚みプラスオフセット分だけ右にずらす
int recty = (borderInsets.height-size.height)/2;  //コンポーネントをボーダーインセットの真ん中に
if (recty < 0) recty = 0;  //ボーダーの厚みがコンポーネントの高さより小さい場合は0にする
rect = new Rectangle(rectx, recty, size.width, size.height);

こんな感じですかね。
こうすると、マウスとタイトルコンポーネントの当たり判定がずれるので、
53行目も変更します。
pt.translate(-rect.x, -rect.y);

と、こんなんで動くと思う。
会社で書いたソースを見てこのブログ書けたら楽なんだけど、
うちのところ、外部アクセスにうるさくて個人ブログすらまともに見れないので、
自分の頭にあるものをピックアップして書きました。
また作るのも面倒なんで・・・。

大体うまくいってますが(うまく言って欲しい)まだ問題があります。
まあ、使い方によりますがね、タイトルコンポーネントに
階層になっているコンポーネントを入れるとうまくいきません。
具体的には、
JPanel contentPanel = new JPanel();
JPanel panel = new JPanel();
panel.add(new JCheckBox("checkbox"));
panel.setBorder(
    new ComponentTitledBorder(panel,
                                    contentPanel,
                                    BorderFactory.createLineBorder(Color.RED))
);
みたいにすると、タイトルには空のパネルだけが表示されます。
これを解決するためにはコンテナー内部を階層的に表示、dispatchEventするしか・・・。
Container.revalidate()で解決するといいなー。

と、こんなことやってたら1時間も残業してしまいました。
頭いてー。
階層表示はまたあとで・・・。

帰ってきてから夕食を食べてメイドガイ。
くくく、が口癖になりそうで怖いわ。
大分空気を読めないメイドガイだが、
ご主人も空気の読めなさではいい勝負をしていると思います。
残り2話というところで今日は終了。

久しぶりにまともなブログを書いたから疲れた。
ダメ人間だね。
さて、DQ9をやって寝ますかね。

拍手[1回]

No.1801|Comment(0)Trackback(0)

本番でした

カテゴリー:プログラムとか

2007/12/21(Fri)23:45

今日はプレゼンの本番でした。
先生からの修正はなし。
別に原稿が完璧だったわけではなく、単純に先生が忙しかったからです。
で、プレゼンはぐだぐだもいいところ。
あーあーあー。

今日は昼ちょっと前に学校へ。
昼食を食べたあと研究室に行ってプログラム。
昨日付けられなかったJCanvas3Dの実装をしてました。
で、色々調べてみたところ、それっぽいサンプルを発見。
さっそく自分のコードにいれてみたのですが、なんかうまく動かない。
ここかー!それともここかー!といいながらごちゃごちゃやってました。
そしたらなんかうまくいった。
でも5ピクセルy座標がずれる・・・。

最初の構造はこんな感じ。
ContentPane
       |
      +--MainPanel
               |
              +--toppanel
                      |
                     +--JCanvas3D
これだとパネルの座標がずれるのでtoppanelを消して、
JCanvas3Dを直接MainPanelに追加してみました。
そしたら別ウィンドウが出てきてそこに3DUniverseが・・・。
しかも3Dの初期化が行われない・・・。
その後もごちゃごちゃやってたらこんな構造になりました。
ContentPane
       |
      +--MainPanel              toppanel
               |                               |
              +----JCanvas3D------+
なんかこうやったらうまくいった・・・。
よく分からん・・・。
Javaのバグですかねー。

そのあとオブジェクトを回転させようと思ったのですが、動かず。
JCanvas3D.getOffscreenCanvas3D()で、Canvas3Dを取得してこれに
普通のJava3DみたいにUniverseに登録します。
このUniverseにBranchGroupを追加してそのグループをBehaviorでぐりぐり動かすようにすると
ただ単にJCanvas3Dを有効にしただけではCanvas3Dには反映されません。
しかし、JCanvas3D.processMouseEvent(MouseEvent e)なるprotectedなメソッドがあります。
protectedなので直接さわれませんが、JCanvas3DにMouseListenerやMouseMotionListener、
MouseWheelListener、KeyListener等を登録してやると自動的にprocessEvent系が働き、
JCanvas3Dに対するアクションがCanvas3Dに反映されます。
まあ、BehaviorをJCanvas3Dで反映させたかったらリスナーを登録しろということです。
はい。

これでSwingと一緒に動くようになりました。
なのでエクスポータを作ることに。
まず手始めにDirectXのXファイルから。
形式を読んでがんばって記述。
ふー、ようやくできた、さて実行実行。

・・・、何じゃこりゃ?
なんか変なふうにメッシュができてる・・・。
色々調べてみた結果、GeometryInfoをStripifierで最適化したときに
メッシュの情報が変わってしまい(最適化してるから当たり前だけど)
その情報がうまく取り出せないことに原因があるようでした。
うーん、なんか頂点インデックスが取れんのよねー。
GeometryInfo.getCoordinateIndeces()の返り値がnullになるんよ。
でも、最適化直後ではnullになってなかったような・・・。
Shape3Dに登録した時になくなるのかね?
まあ、もし登録した時にけるのであればどっかにインデックスを保存しとけばいいんですけどねー。

しかし、これじゃプレゼンで見せられないのでStripifierを使わないことにしました。
そしたらうまくいったー。
よっしゃー。
この2日でずいぶん進展があったものだ。
我ながらすごいね。

そのあと夕食を食べて、また研究室に戻ってプレゼンの準備。
で、程なくしてプレゼン本番。
・・・、えー、もう何も聞かないでください・・・。
ぐだぐだもいいところ。
かみまくり。
ああ・・・。
テキトーにプレゼンしてテキトーに質問に答えてました。
あんなんで分かりましたかね?
一応、全ての質問に質問した人の意図に合った答えを返しておきました。
これもぐだぐだでしたけどねー。
文法とか知るかよ。

最後に先生に、それじゃつまらないよね、もっとやろうね、と言われました。
くはー。
ま、確かにこれじゃただのパフォーマンスの改善でしかないですからねー。
研究じゃないですよねー。
でも、処理スピードは平均10倍以上、ものによっては50倍速くなり、
メモリ使用量も10分の1以下にしたのでオレのノートでも動くようになりました。
今までのプログラムはオレのノートでは動かなかったですからねー。
ま、まだ前のプログラムほどきれいにできてないのでがんばらないといけないんですけど。
冬休みの宿題だね、こりゃ。

今日は3人プレゼンをやったので結構時間がいっぱいいっぱいになりました。
急いで部室に行き、ゲームの提出。
今回はなんかゲームの集まりが悪くて、オレのを急遽出すことにしました。
さすがに⇒くんとかは今まで何回も出してたのでやめました。
今回出したのはボタンdeげ~む。
前出した時にあったポケモン現象を直したバージョンです。
改善があったので出すことにしました。
今回のゲーム数はどれくらいになるんだろうなー。
みんながんばってるけどやってることがエディターだったり下準備だったりであまり出せなさそうです。
明後日の焼き日にどれだけ集まってるか見てみますかね。
ついでにデバックと称して遊んでるか。

で、帰宅。
いつも通りアニメ収集。
もやしもんが終わりましたなー。
二宮くんも終わったようで。
まだちゃんとしたソースのじゃないけど。
もう今年も終わりますからね。
どんどん終わっていくわけです。
あと3週間もすれば新しいアニメが始まるので忙しくなりそう。
オレのHDはもつのか?

今からアニメ。
もうプレゼンが終わったからウハウハだぜ。
実家に帰るまでにできるだけ多く見てDVDに焼かないとな。
忙しい忙しい。

拍手[0回]

No.1216|Comment(0)Trackback(0)

LNK2005のエラー回避法

カテゴリー:プログラムとか

2007/08/15(Wed)15:43

えー、クイズゲームをVC6で作ってます。
リリースする際に構成をReleaseにするのですが、
なぜかLNK2005エラーが出てリンクできません。

リリース直前にこれは困った。
調べる時間もないのでDebugのまま出してしまいました・・・。

このままでは気持ちが悪いので調べてみることに。
結構色々あるようです。
インクルードをする順番とか使用するライブラリのところに書く順番とか。

色んなサイトを見ていてこのサイトに辿り着きました。
http://www.nwhite.info/mt/show_entry.php?id=3294
これによるとライブラリを使用する際に「ライブラリが作られたときの設定」と「ライブラリを使うときの設定」
が違うとLNK2005が発生するようです。
なので上のサイトを参考に設定をいじってみてください。

以下、身内向けのPDライブラリを使用してLNK2005が出る場合の対処法。
VC6の場合のみ。VC2005は知らんよ。
メニューバーの「プロジェクト」→「設定」
「C/C++」タブの「カテゴリ」のプルダウンボックスから「コード生成」
「使用するランタイムライブラリ」のプルダウンボックスから「マルチスレッド」を選択
「OK」ボタンを押して終了。

それともう一つ覚書。
PDライブラリをVC2005で使うとPDFontが使えなくなりますが、
これは
#undef UNICODE
をwindows.hをインクルードする前とかにいれてやれば動きます。
原因はフォント描画にライブラリ内の定義ではマルチバイト文字列、
VC2005ではワイド文字列が定義されているためです。
#undef UNICODEをしてやるとフォント描画にマルチバイト文字列に統一できます。
(これは今後改善されるかも)

以上。

拍手[0回]

No.1076|Comment(0)Trackback(0)

ワイド文字とかめんどい

カテゴリー:プログラムとか

2007/04/18(Wed)23:07

えー、今日はデータベースの授業でした。
が、何でしょうね、あのハンドアウト。
スライドの順番がおかしい。
ちょっと早めに学校に着いたのでそれをがんばってやろうと思ってましたが、無理でした。
もうちょっと調べないとなー。
てか、元のデータをくれ。
そしたら俺がやってやるよ!
それにあれ分かりにくいしなー。
明日は演習だが、大丈夫だろうか??

と、授業の愚痴はこの辺にして昨日言ってたワイド文字を使ったプログラムに関して。
まあ、ここに書いてあるとおりにしても動かないなんてことはよくあることなので、それは気にしない方向で。
ちなみにVC6.0かVC2005のコンソールです。

まず、ワイド文字の型ですが、wchar_tというのを使います。
stdio.hに入ってるはずですが、もしあれならwchar.hをインクルードしちゃってください。
あとはcharと同じように使えます。
つまりワイド文字列なら
wchar_t *wstr;
みたいになるわけです。
しかし、これを実際に使うとなるとマルチバイト文字列で使ったようにstrlenとかstrcmpとかが使えません。
よく使う物の対応を書いておきます。
strlen -> wcslen
strcmp -> wcscmp
strcpy -> wcscpy
atoi -> _wtoi
まあ、見て分かるとおり、strが付くものはstrをwcsにすれば大丈夫です。
もちろん、マルチバイト文字列と同じでstring.hをインクルードしないとダメですけどね。
atoiだけが違いますね。
見難いとは思いますが、(アンダーバー)wtoiです。

では、ちょっとしたサンプルを。

-----ここからソース-------
#include <stdio.h>
#include <string.h>

int main()
{
      wchar_t  *wstr = L"テスト";
      wchar_t  wstr2[20];
      wchar_t  *wstr3 = L"test";

      wcscpy(wstr2, wstr);
      // VC2005を使いwarningを消したければ
      // wcscpy_s(wstr2, 20, wstr);

      wprintf(L"%s\n", wstr);
      wprintf(L"%s\n", wstr2);
      wprintf(L"%s\n", wstr3);

      return 0;
}
------ソースここまで----------
""で囲った文字列をワイド文字列として扱う場合はL""とします。
小数を明示的にfloatであるとするときの1.0fと似たようなものと覚えてもらえればいいかと。
ワイド文字列を出力するときはwprintf(const wchar_t *Format, ...)を使います。
これも引数がwchar_t*なので
wprintf(L"...", ...);
というようにします。
さて、結果は
-----output-----
テスト
テスト
test
-----to here----
となればいいのですが、実際は
-----output-----
???
???
test
-----to here----
となってしまいます。
これはワイド文字の日本語が日本語として認識されてないことが原因らしいです。

これを解決するためにはlocale.hをインクルードし、main()の最初に
setlocale(LC_ALL, "");
を入れるとちゃんと日本語が表示されるようになります。
この命令の意味ですが、
「これ以降に出てくる関数で扱う言語をPC環境の標準言語(日本語)にする」
というような意味だったかと。
よく覚えてません。
まあ、この辺は調べればすぐ出てくるかと。

さて、ゲームを作る上でワイド文字を使うときは外部から読み込むことのほうが多いと思います。
マルチバイト文字であればgetcやscanf(あまり使わないかな?)を使うと思います。
これらもワイド文字用の関数があります。
getc -> getwc
scanf -> wscanf
sprintf -> swprintf
wscanfやswprintfはwprintfのように引数としてwchar_t*を使うのでLを忘れないようにしましょう。

では、またサンプルを。
読み込みに使う外部データは
-------- test.txt ------
テスト
てすと
test
--------to here------
とします。
これを1文字ずつ読み込んでそれを出力するというプログラムを作ります。
まあ、これを見てる人の大半はwhileを使ってEOFまでループさせて
getwcで読み込んだ文字をwprintfで出力すればいいとすぐに分かると思いますが、
それだけではうまくいきません。
それはなぜか?
実際に自分でプログラムを組んでみてから下のサンプルを見てください。
違いがすぐに分かると思います。
-----------ここからソース----------
#include <stdio.h>
#include <stdlib.h>
#include <locale.h>

int main()
{
      setlocale(LC_ALL, "");

      FILE *file;
      file = _wfopen(L"test.txt", L"r");
      // VC2005を使っていてwarningを出したくなければ
      // _wfopen_s(&file, L"test.txt", L"r");

      // ファイルオープンに失敗
      if (file == NULL) exit(10);

      wchar_t ch;
      while ( (ch = getwc(file)) != WEOF) wprintf(L"%c", ch);

      fclose(file);

      return 0;
}
---------ソースここまで--------------
この出力は
-----output-------
テスト
てすと
test
-----to here-------
となります。
ちょっと説明するとテキストをワイド文字として読み取る場合には_wfopenを使い、
これから読み上げる文字はワイド文字であるということを明確にする必要があります。
またワイド文字のEOFはWEOFです。
間違えると無限ループになったりとひどいことになると思います。

さてさて、大分長くなってきましたが、もう1ステップ行ってみますか。
今度はSTLのstringです。
これはマルチバイト文字列ですが、ワイド文字のストリングはどうすればいいのか?
自分で作ってください、なんてことはひどいことはさすがに言われません。
ちゃんとwstringというワイド文字列型が用意されています。
これはSTLのstringと同様に
#include <string>

using namespace std;
を適所に入れれば使えます。
あとはlength()やc_str()などstringと同じように使えます。
もちろん出力にはwprintfや文字加算はwchar_tを使いますが。

まあ、こういうわけで、ワイド文字を扱うのはかなり大変です。
ああ、なんか間違えがあっても気にしないでくださいね。
プログラムをやってる人なら自分で直せるはずです。
勝手に直すなり俺に文句を言うなりしてください。
てか、なげーな、この記事。
ここまで読んだ方、本当にお疲れ様でした。
ちなみにここに書いたことは少し調べればゴロゴロ出てきます。
そっちのほうが詳しくていいかも。
さて、今日の終わりにバグが出てしまったからちょっとやるかな。
明日が1限だから夜更かしできないのがイヤだな。

拍手[0回]

No.930|Comment(0)Trackback(0)

久しぶりにHP更新

カテゴリー:プログラムとか

2007/04/07(Sat)22:54

・・・してません。
そのための準備中です。
前からあるFFTAのデータの整理をしてました。

以前友達にも協力してもらいExcelにまとめてあるデータをそのまま手打ちでHTMLにしてもいいんですが、
かなり面倒なのでちょっとプログラムに通して作ることにしました。
まあ、Excelは下のような感じです。
excel.jpg
をcsvファイルにします。
csv.jpg
こんな感じになります。

これをちょっとしたデータベース(エセ)プログラムに取り込みます。
そして、それを元にHTMLに出力しようという考えです。
ソースはこんな感じ。
source.jpg
えー、このソース、まだバグがあります。
バグというより不具合といったほうがいいかな。
なんか思ったとおりにHTML出力してくれないんですよ。
ああ、これかなー。
もうちょっといじってみるかなー。

そして出力されたHTMLの一部はこんな感じになります。
html.jpg
まあ、これだけ見ると手打ちでも問題なさそうですが、FFTAのクエストは図鑑に載るだけでも300あり、
乗らないものが数個あります。
手打ちしたらいやでしょ?
それに装備品、ジョブデータもあるので手で打ちたくないんですよ。
プログラムなら読み込んで後はループ回すだけですからね。

さて、早いところ不具合を消してリンクを張るようにしないとな。
ある程度進んだらHPにアップするので暇な人は見てみてくださいな。
てか、いまさらFFTAのデータをアップしてもね・・・。

拍手[0回]

No.917|Comment(0)Trackback(0)

久しぶりに

カテゴリー:プログラムとか

2007/02/24(Sat)20:29

なんかこのタイトル多いな。
周りを見るとみんな結構就活はいい感じだそうです。
いいことです。

今日は昨日のことをビミョーに引きずって始まりました。
うーん、もう就活は諦め気味だな。
まあ、これからが本命なので、がんば・・・れるのか??
でも、あれはへこんだな・・・。
で、3回も痛い目にあったので昨日マイナビに登録して、いまさらSPIの勉強を始めてみました。
そしたら、出てきましたよ、一昨日出たのと同じ問題が。
しかし、これを予めやっていたからといって解けたとは思えません。
なぜなら、一昨日やったやつは一般常識と時事は選択ではなく筆記でしたから。
選択なら解けたんだろうなー。

それで今日は起きてからは親の買い物の手伝いをしてました。
そのあとは久しぶりにバイトのプログラムをいじってました。
やったのは今のプロジェクトのリリースのための実行ファイルのダイエットです。
これが意外と手間なんですよね。
今回はプログラム内の整理によりファイル容量を減らしました。
無駄な変数は使わないとかメソッドを減らすとかexceptionは上に投げるとか。
これにより試験プログラムで約9%のダイエットに成功。
9%て微妙だと思うでしょうけど、この9%で結構文字入るんですよ。
まあ、初回起動時にデータはダウンロードする方式にすると思うのでそんなにやる必要はないんですけどね。

しかし、まだ容量を減らすことが出来ます。
まずデータのパッキング。
画像とかばらばらのままだとjarファイルの圧縮方式では全体で見るとそんなに圧縮されないそうです。
しかし全てを1つのファイルにバイナリでまとめてしまうと、ばらばらのままより容量が減ります。
それから難読化ツールの使用と7z形式圧縮にすることです。
難読化ツールとはjavaではクラスファイルから比較的容易にソースを再現することが出来るそうです。
それを難しくするためのツールが難読化ツールなのですが、そのプロセスにより変数名等が変更され、
結果的には実行ファイルの容量の削減につながります。
それから7z形式圧縮のほうですが、これはjar形式とちょっと違う圧縮方式で、jar形式より圧縮率がいいです。
プログラムによりますが、どちらも数%ほど容量を減らせます。
一応俺が試した機種で700以上の携帯では実行可能でした。
なぜか505では何もしなくても動かないので7z、難読化ツールが適用可能なのか分かりません。

今日はプログラムの整理だけでしたが、今度はパッキングに手をつけようかと思ってます。
その次はデータのダウンロードかな。
パッキングはどうやったら効率的にデータを取得できるかな。
それからパッキングついでにスクリプトの整理も出来たらプログラムももう少し改良できるかも。

拍手[0回]

No.860|Comment(0)Trackback(0)

amemboで転送できないファイルがある件について

カテゴリー:プログラムとか

2007/01/16(Tue)01:21


こんな長いタイトルは初めてかな。

まあ、タイトルの通りです。
俺の持ってるファイルでいくつか転送できないものがあります。
原因はドイツ語でした。
aの上に点々がついてたりするのがあるじゃないですか。
あれがファイル名に入ってると転送できないんですね。

で、ちょっとプログラマっぽいことをしてました。
今日は1限からで昨日はあまり寝てないのに。
解決策はunicodeを使うこと。
ただこれだけです、はい。
導入方法はよくあるファイル検索のコードを使います。
  WIN32_FIND_DATA fd;

  WIN32_FIND_DATAW fd;
にするだけ。
これでunicodeでファイル名を取得できます。
(なんかdefineしただけで明示的にunicodeを使うことが出来るのがあった気がするけど忘れた)
もちろん、これを使う場合(たとえばファイルを開く)場合はワイド文字列用関数を使います。
fopen()なら_wfopen()みたいにです。
これでマルチバイト文字列の場合とワイド文字列の場合とでファイルを開いてみました。
そしたらワイド文字列で読み込めガチャンとドイツ語が入ってても読み込めました。
(_wfopen()の戻り値がNULLではなかったため読み込めたと思う)

しかし、コンソールではワイド文字列が表示できなかったので、
ワイド文字列をマルチバイト文字列にするのをがんばってました。
逆は前やったんですけどね。
まず、さくっと調べるとWideCharToMultiByte()が見つかりました。
それでその通りにやるとなぜかファイル名が切れる・・・。
中身を見てみるとワイド文字って2バイト文字でも1文字とカウントするんですね・・・。
つまり「あ」はマルチバイト文字では2文字ですが、ワイド文字では1文字。
これでは2バイト文字と1バイト文字が混同してる場合、
マルチバイト文字列をどれだけメモリ確保すれば良いの分かりません。

それであっちこっち調べてみるとwctomb()なる関数が。
ワイド文字をマルチバイト文字にする関数だそうです。
で、変換できないときは-1を、出来るときは1を返します。
これを利用して下のようにしてみました。
int len = 0;
for (int i = 0; i < wcslen(fileName); i++) {
    char ch;
    int def = wctomb(&ch, fileName[i]);
    if (def == -1) len += 2;
    else if (def == 1) len++;
}
これでようやく文字列長が分かるようになったわけです。
あとは求めた文字列長だけメモリ確保して・・・、
とやりたかったのですが、なぜか4文字分多く確保される・・・。
なぜだ・・・。
まあ、-4すればいいだけなんですけどね。
なんかキモイ。

と、まあ、こんな何も役に立たないプログラムを作ってました。
なんかほかにもまともなやり方があるんでしょうけど、俺にはこれが限界でした。
ああ、眠い。
amemboの制作者さんには後日連絡しよう。
もう風呂に入って寝ます・・・。

拍手[0回]

No.534|Comment(0)Trackback(0)