[MFC] Windowsアプリで引数を受け取る

GUIベース(Windowsフォームを提供)するアプリケーションを作成しているのだけど、ここにいてバッチ処理をしたいとかいう風に言われた。今まで苦労してGUIの機能を作ってきたのは何だったのだろう?

と、いうことでコマンドライン引数を受け取った場合にフォームを生成せずに処理できるように作り直すことになりましたとさ。

コマンドライン引数の受け取り

WindowsアプリケーションのInitInstance()の中に以下のコードを書けばいいらしい。

//VC2005, 文字コード: Unicode 

// コマンドライン引数を格納する配列
CStringArray cmdParams;

{ // コマンドライン引数の取得
 CString cmdParam( m_lpCmdLine );
 cmdParam.Trim();

 // パラメータの取得
 int curPos = 0;
 CString param = cmdParam.Tokenize( _T("/"), curPos );
  while( param != "" ){
  cmdParams.Add( param.Trim() );
	param = cmdParam.Tokenize( _T("/"), curPos );
 }
}

上記の例だと example.exe /test1 /test2とコマンドライン引数を与えると
 cmdParams[0]: test1
 cmdParams[1]: test2
となる。

コマンドライン引数取得の改良 2007/11/07

パラメータを半角スペースで区切る。ただし、"(ダブルクォーテーション)で括われていた場合、その中は半角スペースを含むことができるようにする。

// コマンドライン引数の取得
CString cmdParam( m_lpCmdLine );
cmdParam.Trim();
CStringArray cmdParams; // 引数を格納する動的配列

CString param;
int curPos;

// パラメータの分解
cmdParam.Trim();
do{
 if( cmdParam.GetLength() >= curPos && cmdParam.GetAt( curPos ) == '\"' ){
  // "で括われた引数
  ++curPos;
  param = cmdParam.Tokenize( _T("\""), curPos );
 } else {
  // 引数を半角スペースで分解
  param = cmdParam.Tokenize( _T(" "), curPos );
 }
 cmdParams.Add( param.Trim() );
}while( param != "" );
// 最後に空の文字列が追加されてしまうので取り除く
cmdParams.Remove( cmdParams.GetCount() );

処理の切り分け

引数が与えられていなければcmdParamsは空のはずなのでこれを使ってやればいい。

if( cmdParams.GetSize() > 0 ){
 // フォームを生成しない場合
 // 引数の値のエラートラップ、処理ルーチンの呼び出し
}else{
 // フォームを生成するコード
}

参考にしたサイト

コマンドプロンプトで、~.exe *** の *** を判定するには?

2007/09/29(土)どうしろっていうんだ

XPを導入しているサブPCですが、W2Kを導入しているメインマシンよりもマシンパワーがあります。
普段はW2Kのメインマシンしか利用しませんが、iTunesのエンコードのようなマシンパワーが求められる作業にはサブPCの方が適しています。このため、W2KマシンからリモートデスクトップでサブPCを操作するということを行っているのですが、突然リモートのXPが応答しなくなりました。

何事かと思い、サブPCを直接モニタに展開してみると以下のような感じで表示されていました。
[album:PC:xp.jpg:large]
ログインが出来ない状態になっていて、どうしようもないので左下のアイコンから再起動をかけようとしても反応しません。

Alt-Ctrl-Delを試してみると以下のような感じでログイン?ダイアログが表示されますが、全く判りません。
[album:PC:xp2.jpg:large]
Admin権限でログインを試みるとなにやらダイアログが表示されるのですが、やっぱり何が表示されているかも判らないのでへたにボタンも押せません。

結局、電源長押しで落とすしかありませんでした。

2007/09/28(金)日記: 07/09/28

本日のプログラム

とあるライブラリを利用して開発を行っていますが、このライブラリで提供されている関数内でエラーが発生した場合、エラーコードを返却します。と、まあここまではいいのですが、このエラーコードの内容によってエラーの深刻度が以下のように仕様で定義されています。

  • Fatal Error: 致命的なエラー。プログラム内での修正・復帰不可能。処理を中断しなければならない。
  • Error: エラー。ライブラリ関数内での修正不可能。処理を中断することを推奨するが、呼び出し側で修正可能。
  • Warning: 警告。ライブラリ関数内で修正される。処理を継続しても良い。
  • Information: 情報。処理を行う際の様々な情報。処理を継続。

このように決められているのはいいのですが、帰ってきたエラーコードからはこのエラーの深刻度がわからないのです。と、いうことで本日の作成プログラムはエラーコードからエラーの深刻度を求めるというもの。

enum ErrorLv {
 FatalError = 1,
 Error,
 Warning,
 Information,
 Unknown
};

int getErrorLv( int errorCode ){

 int level;
 switch( errorCode ){
  case 1:
  case 15:
  case 32:
   level = FatalError;
   break;
  case 3:
  case 20:
  case 45:
   level = Error;
   break;
  case 2:
  case 8:
  case 60:
   level = Warning;
   break;
  case 9:
  case 38:
   level = Information;
   break;
  default:
   level = Unknown;
 }
 return level;
}

実際はエラーコードの種類が100種類程度あってひたすらcase文が並びます。……なんだかなぁ、せめて1~10000: 致命的エラー、10001~20000: エラーみたいに振ってくれればこんなくだらないプログラムを書かなくても済むのに。

嫌な客

だれがって、いや私です。久しぶりに家電量販店に行っていろいろ見て回ってきたのですが、なぜか行く先々で店員につきまとわれてしまいました。そこでのやりとりを思い返してみると私って店側からすると嫌な客ですね。

@USBメモリ売り場

データの受け渡しやFirefox/Thunderbird Portableなど自分の環境を持ち歩くにはやはりiPod shuffle@512MBでは不便、というかデータ用の領域を大きく割けるほど容量が大きくないというのがネックとなっています。昨今、価格もかなり安くなっているのでUSBメモリの1~2GBくらいのを購入しようかと思い見て回っていたのですが、背後に忍び寄る店員。
店「なにかお探しですか~」
か「1~2GBくらいでVistaのReadyBoost((どうせだったらReadyBoost対応しているのがいいですよね。未だにメインで使用しているのはW2Kですが(笑))に対応しているやつってどれですか」
店「ちょっとそういった細かい対応状況は判りかねます。申し訳ございません」
か「この(USBメモリのパッケージに張られた)Vista対応っていうのはReadyBoostには対応ではなく、単純にVistaでUSBストレージとして使えるものっていうことですか?」
店「……はい」
か「じゃあ、暗号化できるUSBメモリってありますか? PCに暗号化するツールを導入したりするのではなく、USBメモリ単体の機能として暗号化するようなもの*1
店「あいにく、当店では現在在庫として用意しておりません。取り寄せという形となってしまうのですが」
か「じゃあいいです」

@PC売り場

UMPCのFMV LOOX Uが展示されていたのでいじってみる。
う~ん、このキーボードの配列はありえないよなぁ。何なんだ、このかな入力ユーザをバカにしたような配列は! そもそもコレ、かな入力出来るのか?と、おもむろにメモ帳を立ち上げ、Alt + ひらがな(Fn + 半角/全角)でかな入力モードに切り替えて入力を試してみる。……使い物にならないね、これは。
と、かな入力モードにしたまま売り場を去るのでした、まる。

@携帯売り場

Advanced/W-ZERO3の販売価格でも調べるために携帯売り場行くと、待ってましたとばかりに店員が近づいてくる。
店「こちらの機種をご検討ですか」
か「ええ、まぁ」
店「こちらの機種は大変今人気がありまして…(中略)…Officeのファイルが開けるなど非常に高機能となっております」
と、長々と話す店員の解説に心の中で突っ込みを入れながら(笑、おもむろにW-ZERO3[es]を取り出して
か「今、古いW-SIMカードの機種を使っているのですけど、これ(Advanced/W-ZERO3[es])に機種変更すると高速通信に対応した新しいW-SIMカードにも変更して貰えるのですかね?」
店「いや、当店ではそういったことには対応出来ません、ウィルコムの方に行って頂けばそういったことも対応出来ると思われます」
か「じゃあ、これ(W-ZERO3[es])からこれ(Advanced/W-ZERO3[es])に機種変更の場合、FOMAでいうところの買い増しみたいな感じになるんですかね?」
店「はい、現在使われている(W-SIM)カードを新しい機種に差し替えるだけですぐにご利用頂けます」
か「でも、それじゃあ通信速度は遅いままですよね、じゃあいいです」

一言言わせて貰うと

聞きたいことや判らないことがあったら、こっちから聞くから。たかだか1分程度商品見ていたからってまとわりついてくるなー(∵)

*1 : PC側に導入させるようなソフトが必要なものだと結局使わなくなってしまうんですよね。だいたい常駐系だろうし、なにより出先で受け取ったデータの暗号化とかどうなのでしょうか? そう考えると、USBメモリ単体の機能として暗号化できないと使い勝手が悪すぎる気がします

2007/09/26(水)Firefox / Thunderbird Portable 2.0.0.6

Firefox Portableアップグレード

現在使用しているFirefox Portableは2.0.0.0なので2.0.0.6にアップグレードしてみた。

用意するもの

アップグレード手順

  1. Firefox Portableアップグレード
    1. ダウンロードしてきたFirefox Portableを実行し、ファイルを展開
    2. 展開されたファイルを環境構築済みのFirefox Portableフォルダに上書き
    3. Firefox Portableを実行すると拡張機能の互換性チェックが行われる→特に問題がなければアップグレードされているはず
  2. 日本語ロケールのアップグレード
    1. ダウンロードしてきたja.xpiをインストール
    2. Firefox Portableを再起動すれば新しい(2.0.0.6)の言語パックが使用されているはず

Thunderbird Portable 2.0.0.6 新規インストール

用意するもの

Thunderbird Portable 2.0.0.4 日本語化で紹介されている手順に従ってインストール・日本語化が行えます

2007/09/22(土)ひどい

最近は忙しくなってきて、帰る時間も遅くなりがちです。
とっとと帰って眠りたいのにホームに着くと無情にもこんな感じに迎えられます。
[album:2007:passed.jpg:large]

……いくらなんでもひどすぎないか?