Windows7でDelphi7のプログラムを動かす時の注意点
今週は急遽Windows7でDelphi7で開発しているプログラムが動くか確認する必要が出たので色々確認していたのですが、そこで幾つかはまった事があるのでメモ的に。
ます、DeveloperExpressのcxGrid等を使用しているのでcxLocalizerを使って日本語化をしているんですが下記のロケールを設定する所でエラーが起こってました。
cxLocalizer1.Locale := 1041;
調べて見ると、最終的にTLanguages.Createが呼び出されていてその中でエラーが発生してました。
これは、cxLocalizer1.LanguageIndexに値を直接設定することで回避しました。
LanguageIndexは、翻訳ファイル内に一つの言語しか入れてない場合は0を指定しておけば良いみたい。
もう一つは、文字列を全角文字にする処理をLCMapStringを使用して作ってたんですが、これが変換に失敗してしまうように成ってました。
これは、互換モードの指定でLCMapStringの動作が変わってしまっていたのが原因でした。
互換モードを指定してない場合は、LCMapStringの引数のcchDestに0を指定した場合、ANSI版の場合ちゃんと必要なバイト数が返ってきます。
ところが互換モードを指定してあると、上図のようにどうやら文字数が返ってきます。この返り値を元にバッファを確保して変換しようとすると失敗してしまいます。
これは、UNICODE化されたDelphi2009以降には影響ないと思います。ただDelphi2007とかだと確認してないですが影響あると思います。
確認用のコード載せるの忘れてたので追記
procedure TForm1.Button1Click(Sender: TObject); const CSConvStr = 'ABCあいう'; var CnvStr: PChar; CnvLngth: Longint; begin // 変換に必要なバッファのサイズの取得 CnvLngth := LCMapString( MAKELCID(MAKELANGID(LANG_JAPANESE,SUBLANG_NEUTRAL),SORT_JAPANESE_XJIS) , LCMAP_FULLWIDTH, PChar(CSConvStr), Length(CSConvStr), Nil, 0); Label1.Caption := Format('変換文字列: %s', [CSConvStr]); Label1.Caption := Label1.Caption + #13#10 + Format('要求バイト数: %d', [CnvLngth]); // 変換処理 if CnvLngth > 0 then begin CnvStr := AllocMem(CnvLngth + 1); try CnvLngth := LCMapString( MAKELCID(MAKELANGID(LANG_JAPANESE,SUBLANG_NEUTRAL),SORT_JAPANESE_XJIS) , LCMAP_FULLWIDTH, PChar(CSConvStr) , Length(CSConvStr), CnvStr, CnvLngth); if CnvLngth <> 0 then begin Label1.Caption := Label1.Caption + #13#10 + Format('変換後: %s', [CnvStr]); Label1.Caption := Label1.Caption + #13#10 + Format('変換バイト数: %d', [CnvLngth]); end else begin Label1.Caption := Label1.Caption + #13#10 + '変換後:'; Label1.Caption := Label1.Caption + #13#10 + Format('変換バイト数: %d', [CnvLngth]); end; finally FreeMem(CnvStr); end; end; end;