[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 *** の *** を判定するには?

[MFC] 10進RGB値を16進RGB値に変換

RGB値を3つのint型変数で持っている時、このRGB値を16進表記にし、1つの文字列として表したい場合に何かいい方法って無いものでしょうか?
この手のものはよく使いそうなのでライブラリにありそうですが、探し方が悪かったのか見つけられませんでした。で、10進RGB値を受け取って16進RGB値の文字列を返す関数を作ってみた。

処理系はVisual C++ 2005 (VC8.0)です。

struct RGB{
 int red;
 int green;
 int blue;
};

CString convToHexRGB( RGB* rgb ){

 // 入力値チェック
 if( red >= 0 && red <= 255 && green >= 0 && green <= 255 &&
  blue >= 0 && blue <= 255 ){
   return CString::Format( "#%02X%02X%02X", rgb->red, rgb->green, rgb->blue );
 }

 // 入力値が不正な場合
 return "";
}

実際はRGBのそれぞれの値はunsigned char型で格納すれば0~255までの値しか入らないので入力値チェックも必要なくなるのだろうけど、とある制限によりint型でRGBの各値が格納されている為上記のような実装となりました。

以下はunsigned char型で実装した場合

struct RGB{
 unsigned char red;
 unsigned char green;
 unsigned char blue;
};

CString convToHexRGB( RGB* rgb ){
 return CString::Format( "#%02X%02X%02X", rgb->red, rgb->green, rgb->blue );
}

何でRGB値しか入らないのに、しかも仕様書で0~255までの値となっているにもかかわらずint型で入れなければならないんだろう…。
処理系固定なのに…。

2007/06/25(月)[C#/Java] 例外処理

研修も佳境に入ってきてグループで大きめの課題に取り組むことになりました。
で、それぞれ個別に機能を作成するのですが、考え方の違いに悩まされています。

JavaやC#ではtry-catchステートメントで例外処理をするけど、定義メソッドの開始から終了までをtryで括ってすべてのExceptionをcatchするのってどうなんでしょ?
Javaだとソースはこんな感じ。

public void method(){
  try{
    処理1
    ...
    例外が発生する可能性のある処理
    ...
    処理n
  }catch(Exception e){
    例外処理
  }
}

例外の取りこぼしはなくなって安全だろうけど自分はやりたくない。