2013年11月15日金曜日

C# フォームアプリケーションで複数ウィンドウ

フォームアプリケーションをやっていたら、
フォームBで選択されたデータをフォームAに反映したいという状況になった。
フォームBがモーダルダイアログならShowDialogで問題ないんだけど、
フォームAと常に一緒に表示されているウィンドウなので、親子関係を構築する。



親子関係の構築の仕方は簡単。子ウィンドウのShowメソッド呼び出し時に親を渡す。

/*---------------------------------------------------------------------------*/
public FormA() {
        this.Shown += delegate(object sender, EventArgs e) {
        Form formB = new Form();
        formB.Show(this);
        };
}
/*---------------------------------------------------------------------------*/

上記の例では、コンストラクタでShownイベントハンドラを設定し、
イベントハンドラ内でフォームBを生成、親として自分自身を渡している。
コンストラクタ内で直接やると、親のインスタンスが生成されておらず、
期待通りの結果にならないので注意。

表示位置もこちらで自由に指定したいのなら、
StartPositionプロパティをFormStartPosition.Manualに設定して Location を弄る。

常にその配置に固定したいならMoveやResizeにイベントハンドラを設定。

2013年11月14日木曜日

C# FileDialogとカレントディレクトリ

C#のフォームアプリケーションではファイル操作を行うときにファイルダイアログを使うと、
専用のダイアログを開いてファイルを選択できる。

このファイルダイアログ、適当に生成して使うと、
たまげたことにアプリケーションのカレントディレクトリを変更しやがる。
相対アドレスを直接指定して画像ファイルを読み込みとかしていると、
当然のごとく読めなくなった。

こういうときは、RestorDirectoryプロパティをtrueにしてやるといい。

/*---------------------------------------------------------------------------*/
OpenFileDialog dialog = new OpenFileDialog()
{
   RestoreDirectory = true,
};
DialogResult result = dialog.ShowDialog();
/*---------------------------------------------------------------------------*/

上記のコードではOpenFileDialogで行っているが、SaveFileDialogでも同様。

ところで、newしたあとに{}で囲むとプロパティを操作できるのね。
機能名がわからんから詳しく調べられてないんだけど、なんなんだこりゃ?

2013年11月13日水曜日

C# Formあれこれ

ツール作成にはC#が便利だ! というのをどこかで聞いたような聞いていないような。
C#のフォームアプリケーションを試してみたので、メモを残しておく。



まずは単純にフォームを表示するだけ

  1. VisualStudio or VisualC#を立ち上げる。
  2. 「ファイル」→「新しいプロジェクト」→「Windowsフォームアプリケーション」
完成! あらやだ簡単。なにもないフォームを表示するだけだけど。
ここから色々いじくっていくのだ。

フォームデザイナを使う


C#にはフォームデザイナという機能があって、
メニューやテキストボックスなどのコントロールをグラフィカルに追加できる。
試しに使う方法と使わない方法を試してみたけど、使ったほうが圧倒的に楽。
デザインを変更するときもぽちぽちするだけですむのはありがたい。

  1. デザイナを開いた状態で右側の「ツールボックス」へマウスオン
  2. 使いたいコントロールをデザイナ上の好きな場所へドラッグオンドロップ

イベントハンドラを追加する


フォームアプリケーションは
ボタンを押す、指定時間経過などのイベントにしたがって処理を行う「イベント駆動方式」。
ちゃんと意味を理解したのはいまさらだったりする。我ながらひでえ。
そんなわけで、ユーザーのアクションに対して適切な処理を行うためには、
イベントを追加してやらにゃなりません。
デザイナを使用していると、これも簡単に行える。(クリック系の処理に限る)

  1. 追加したコントロールをダブルクリック。
  2. ソースコードにイベントハンドラ定義用の関数が追加され、ついでにそこが開く。
  3. 処理を書き込む。



とりあえず基本中の基本をやってみたのをまとめてみた。
これだけでも簡単なツールは作れると思う。
イベントもほしいイベントは大抵用意されているので、ちょっと調べればすぐ出てくる、はず。

javascript でtrim

ちょくちょくjavascriptを使う機会が出てきたような、そうでもないような。
環境に依存するところもあるけど、いろんな環境でサポートされているので、
覚えておくと後々便利そうだと思った。



意外なことにjavascriptにはtrim関数がないので、
replaceを使ってそれっぽい処理を実装する必要がある。

参考サイト
Javascript で trim するには

上記サイトより
/*---------------------------------------------------------------------------*/
String.prototype.trim = function() {
    return this.replace(/^\s+|\s+$/g, "");
}
String.prototype.ltrim = function() {
    return this.replace(/^\s+/, "");
}
String.prototype.rtrim = function() {
    return this.replace(/\s+$/, "");
}
/*---------------------------------------------------------------------------*/

リテラルの最後の/の後にgを入れると条件に該当する全ての要素に対して
処理をしてくれるもの、と思われる。調べた感じ。

正規表現を使って、行頭・行末の文字を検索している。
できればスペース以外のやつもtrimで排除できるといいな、
と思ったんだけども予想以上に面倒そう。
その場合は素直にreplaceを呼んだほうが早いかもしれない。




2013年11月5日火曜日

CakePHP2.x フォルダのファイルを全て削除する

とりあえずwebroot以下にあるhogeフォルダのテキストファイルを削除する。

/*---------------------------------------------------------------------------*/
    App::uses( "Folder", "Utility" ); 
$dir = new Folder( WWW_ROOT."hoge".DS );
$files = $dir->find( '.*\.txt' );
foreach( $files as $file ) {
$file = new File( $dir->pwd().DS.$file );
$file->delete();
}
/*---------------------------------------------------------------------------*/

webroot以下のファイルは基本リソースになるので
プログラムで消す機会はそうそうないとは思うけども。

2013年11月4日月曜日

android-ndk インストールからテストまで

久しぶりにandroidをいじろうと思ってeclipceを立ち上げたら、アプリケーションの実行時に以下のエラーが出て動かなくなった。

 /*---------------------------------------------------------------------------*/
    failed to initialize monitor thread: unable to establish loopback connection
/*---------------------------------------------------------------------------*/

ネットで軽く調べても原因がわからんかったので、いっそのこと最初から入れなおしてやる! と奮起した。
その際に悪戦苦闘したのでメモを残しておく。

AndroidSDKインストール(ついでに日本語化も)


参考サイト
Androidアプリケーション開発環境の構築(ADTバンドル版SDK編)
Android開発をJava 7で行う
  1. AndroidSDKをダウンロードして適当なフォルダに解凍
  2. Java SE Development Kit (JDK)をダウンロード。インストール。
  3. Pleiadesをインストールして解凍
  4. 解凍したフォルダのfeaturesとpluginsのフォルダをeclipce内の同名フォルダに上書き
以上。今のSDKはeclipceが同梱されているバージョンが配布されており、昔に比べて余計な設定の必要がなくてとても楽になった。
JDKは推奨バージョンじゃない場合は「設定」からjreを追加してコンパイラ準拠レベルを推奨バージョンに変更する必要があるらしい。

AndroidNDKインストール



参考サイト
Android NDKを使った開発環境の構築
  1. AndroidNDKをダウンロードして適当なフォルダに解凍。
  2. 「設定」「Android」「NDK」からNDK Locationを解凍したフォルダに設定する
おしまい。

AndroidSDKのサンプルを実行してみる


新しい環境も整えたところで、もうようわからんエラーは出ないだろう、と意気揚々と適当なサンプルを実行。
はい、また同じエラー出ました!

 /*---------------------------------------------------------------------------*/
    failed to initialize monitor thread: unable to establish loopback connection
/*---------------------------------------------------------------------------*/

ええい! なんなのだ貴様は! と本腰入れて調査を開始。
で、仕方ないから全然読めない英語を雰囲気から読み取りつつ見つけた情報を試す。
eclipce.iniの末尾に以下の設定を追加。

/*---------------------------------------------------------------------------*/
    -Djava.net.preferIPv4Stack=true
/*---------------------------------------------------------------------------*/

動いたー! とりあえず原因までは調べてないけど動くようになったので先に進む。
あとで調べようとは思っているけど、誰か理由がわかる人がいたらよければ教えてください。

AndroidNDKサンプルを実行する


SDKも動いたところで、NDKも大丈夫だろうととりあえずGLES使っているサンプルを実行。
この時にエミュレータの「ホストGPUを使用する」の設定にチェックを入れとかないと
動かないので気をつけよう。
それから、Nexus7を使うとなぜかエミュレータが動かなくなる。別のマシンなら問題なし。なぜ?

で、この一連の作業してる時に知ったんだけど、
今のeclipceってcygwinがなくてもNDKのビルドできるのね。
プロジェクトを右クリックして「Androidツール」のサブメニューから「Add Native Support」を選択。
で、表示されたダイアログをOK。名前は変えても変えなくてもいい。
命名規則に従う形にするのが無難かな?
これだけでNDKのビルドができるようになる。

そしてついに実行。そしてさすがというべきかやはりというべきか、エラー。というか落ちた。
こういう時こそデバッガの出番だぜ! と思って起動したらこっちもエラー。なんじゃそりゃ。

/*---------------------------------------------------------------------------*/
   Unable to detect application ABI's
/*---------------------------------------------------------------------------*/

こんな感じのエラーが出てきまして。
他にもずらずら出てる大量のエラーを読み解く。

どうもAndroidManifest.xmlの設定がよろしくないっぽい。
APP_PLATFORMのバージョンとminSdkVersionが違うよ、と怒られているんだと思う。
実際minSdkVersionをAPP_PLATFORMに合わせたらこのエラーは出なくなった。

でも別のエラーで怒られた。
NDK_DEBUG=1がどうこうというメッセージが出ていたので、
プロジェクトのプロパティからビルドオプションにNDK_DEBUG=1を付けたしてやると動いた。
ちなみに後でもう一回試してみたら、オプションを付加しなくても怒られない不思議。


中途半端だけどいろいろ限界なので一回ここでやめる。
続きはまた気が向いたときに追記か新しい記事で。




/** 11/19 追記 **/

結局サンプルは動かせなかったけれど、
適当に作ったndkのプロジェクトが動くところまでは行った。
メモメモ。

参考サイト
Windows で Android NDK を使ってみる

結局デバッグはこれでもうまくいかなかった。
その原因は、なんてこったい。パスの通し忘れだった。
環境変数PATHを設定する。

/*---------------------------------------------------------------------------*/
 C:\android\android-ndk
/*---------------------------------------------------------------------------*/

実際には自分の環境のNDKを解凍したフォルダにパスを通す。
ついでにSDK周りのPATHもチェックしたらこっちは大丈夫だった。
これをやったらデバッグはできるようになった。
でも、相変わらずglesを使ったプロジェクトは落ちるし、サンプルは動かない。

どこのサイトで見たのかは忘れたけど、
エミュレータだとglesのプロジェクトが動かない、というのがあったような気がする。
GPUだかハードウェアだかがどうだか。
実機でテストしようと思ったら、持ってる端末がくそ過ぎてPCにデバイスがダウンロードできない。
glesはまたの機会に持ち越しだ! 諦めたわけじゃないよ!

んで、サンプルのほうは、どうもバージョンによる違いが出てるみたい。
サンプルによってはそもそもビルドすら通らないこともざらにある。
なので、もういっそのこと新規プロジェクトを作ってみたら、普通に動いた。
公式サンプルが信用できないってどうなのよ?

以上。
一応インストールから空のプロジェクトの実行まで。
glesは諦めたわけじゃない。諦めたわけじゃ、ないんだ。

2013年11月1日金曜日

cakephp2.x 他のコントローラのビューを使用する

ひとつのコントローラから別のコントローラのビューを使用したいときはこうする。

/*---------------------------------------------------------------------------*/
    $this->render( "../controller/view" );
/*---------------------------------------------------------------------------*/

コントローラごとに機能を分けるのが理想であって、極力使わないほうがいいんだろうけど。