「えーと●●●って選択肢のあるRadioGroupはどのフォームだったっけ」とか探したくなることがたまにある。
C++Builderでは(Delphiも)フォーム情報がテキスト形式(DFM)で保存されているので、ソースのあるフォルダでgrepかければ一発、のはずなのだが、英数・記号以外の文字は数値変換されているので、見つからないことがままある。
たとえば変な例だが「叱るButtonAtype」みたいなCaptionはdfmファイルに
Caption = #21489#12427'Button'#65313'type'
と保存される。(”A”も全角なので数値変換されている)
たぶん
・半角英数・記号はそのまま(シングルクオーテーション囲み)
・それ以外は文字コード番号の10進数表記(個々の先頭に”#”)
・さらにサロゲートペアは分割して変換(例の「叱(U+20B9F)」は「#21489#12427」)
というルールっぽい。
というわけで、変換関数を作った。
以下、コード。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
String StringToDfmStyle( String OrgStr ) { if( OrgStr.IsEmpty() ) return OrgStr; String RetStr; // 返値 bool IsBeforeAlpha = false; // 英数・記号の前後にシングルクオーテーションを付けるためのフラグ while( !OrgStr.IsEmpty() ) { // 半角の英数・記号の場合、そのまま出力 if( OrgStr[1] <= L'~' ) { if( !IsBeforeAlpha ) // 半角英数・記号の始まりにシングルクオーテーション RetStr += L"'"; // 1文字目をそのまま追加 RetStr += OrgStr.SubString( 1,1 ); // 文字列の先頭1文字を削除 OrgStr = OrgStr.SubString( 2, OrgStr.Length() - 1 ); IsBeforeAlpha = true; // フラグ } // その他の場合 else { if( IsBeforeAlpha ) // 前の英数記号の末尾にシングルクオーテーション RetStr += L"'"; // 記号(#)と文字コードの10進 RetStr += String( L"#" ) + IntToStr( OrgStr[1] ); // サロゲートペアの場合 if( System::Character::IsSurrogate( OrgStr, 1 ) ) { // サロゲートペア後半部も同様処理 RetStr += String( L"#" ) + IntToStr( OrgStr[2] ); // 文字の先頭2文字分を削除 OrgStr = OrgStr.SubString( 3, OrgStr.Length() - 2 ); } else { // 文字の先頭削除 OrgStr = OrgStr.SubString( 2, OrgStr.Length() - 1 ); } IsBeforeAlpha = false; } } if( IsBeforeAlpha ) // 末尾が半角英数・記号の場合、シングルクオーテーション付加 RetStr += L"'"; return RetStr; } |