17Th
Developer Camp

【B4】 Delphi/C++Builderテクニカルワークショップ「Delphi / C++Builder 旧バージョンアプリケーションの移行」

エンバカデロ・テクノロジーズ
サポートチーム with 高橋智宏

1

17Th
Developer Camp

Delphi Q1

2

midas.dll
Q. 別々のバージョンで作成したデータベースアプリケーションがあります。
その場合 midas.dllは .exeと同じディレクトリに配置すれば問題ありませんか？

A. midas.dll はインプロセスサーバーとして動作します。そのため通常の dllのよ
うに .exeと同じディレクトリ上にある midas.dllが優先して使われるのではなく、インプロセスサーバーとして登録してある midas.dllがあるかどうかを確認し、あればそれを使用し、無ければ .exeと同じディレクトリ上にある midas.dll等が使用されます。XE3で作ったアプリケーションが 2007の midas.dll を使用して文字化けが等が発生することがあります。

midas.dll は配布するのではなく uses に含めるのがベター( uses MidasLib; )3

17Th
Developer Camp

Delphi Q2

4

背景色
Q. 以前のバージョンで作成したアプリケーションを XE3 でビルドして実行したらTCheckBox の背景色が表示されなくなりました。TPageControl も白くなります。

A. プロジェクトのランタイムテーマがONの時の正しい動作です。
[プロジェクト|オプション|アプリケーション]のランタイムテーマのON/OFFを確認する
5

17Th
Developer Camp

Delphi Q3

6

プロジェクトオプション
Q. 移行プロジェクトごとに使用しているコンポーネントパッケージなどが異なるのですが、-[ツール|オプション…|環境オプション|Delphiオプション]-[コンポーネント|パッケージのインストール…]で設定しなければなりませんか？
A. プロジェクトファイル毎に、使用するパッケージや、コンパイラの検索パス等を設定し、保持することができます。

7

17Th
Developer Camp

Delphi Q48

エラーメッセージ
Q. データベースアクセス時のエラーメッセージをカスタマイズしたいのですが…

A. 例えばキーの重複などで発生するエラーの場合、OnPostError でif (E is EDBClient) and (E.Message = 'Key violation.') thenraise Exception.Create('キー重複エラーです。');のように記述することが可能です。
ただし、あちこちに散らばっていると、作業箇所が複数になり工数もかかってしまいます。

データモジュールを活用しよう（データベースアクセス部分のパッケージ化）
9

17Th
Developer Camp

C++Builder Q1

10

アクセス違反
Q. C++Builder6からC++Builder 2007へプロジェクトを移行しています。
sscanf関数を呼び出した以降のコード近辺で例外が発生するようになりました。
コンパイラの最適化オプション等を変更すると起きなくなる場合もあるようです…

「Project1.exeが例外により実行を停止しました。
‘accessviolation at 0x2013c52f:read of address
0x00120000‘再開するにはステップ実行または実行を選択してください。」
11

原因と解決策
A. そもそも、sscanf関数のフォーマット形式 %d で受け取る変数は int型(32bit整数)を要求します。sscanf関数の引数として渡しているshowlocの型は USHORT(16bit整数) です。sscanf関数は32bit幅で書き込み、はみ出た16bit分の領域がメモリを壊します。
案1. showloc変数の型を、USHORTからintやUINT等に変更する

案2. sscanf関数に渡すフォーマット形式を %d から %hd に変更する

1217Th
Developer Camp

C++Builder Q2

13

BCC32致命的エラー
Q. 旧バージョンのC++Builderプロジェクトを、最近のバージョンのC++Builder移行しようとしています。あるプロジェクトをビルドすると、以下のようなエラーが表示されてコンパイルすることができません。開発マシンは、64bit版OSで、メモリも8GB積んでいるのですが...

[BCC32 致命的エラー] xxxxxx.cpp(行番号): F1008 メモリ不足

14原因と解決策
A. コンパイラ自体は32bitプロセスのため、巨大なソースファイルをコンパイルする
場合、コンパイラが十分なメモリを確保できないことがあります。コンパイラが使用するメモリサイズのデフォルトはそんなに大きくありません。

[プロジェクト|オプション...|C++コンパイラ|拡張]の[コンパイラに渡す追加オプション]として以下のパラメータを指定します。なお、指定できるメモリサイズの量は、マシン環境に依存します。

C++Builder XE以前のバージョンの場合-CXxxxC++Builder XE以降のバージョンの場合--savemem=xxx

15

17Th
Developer Camp

C++Builder Q316

Active Template Library(ATL)
Q. 旧バージョンのC++Builderで作成したプロジェクトを、C++Builder XEへ移行しています。しかし、atlbase.h等を利用するプロジェクトをC++Builder XEでビルドすると、以下のエラーが発生します。確かにXEにはatlフォルダはありません...

[BCC32 致命的エラー] atlbase.h(xx): F1003 error 指令:
You must copy ATL files from an earlier version of C++Builder[$(BDS)¥include¥atl¥*.*] to use ATL

17

原因と解決策
A. C++Builder XEから、ActiveXフレームワークは、旧バージョンで採用していたActiveTemplate Library(ATL)ではなく、Delphi ActiveX ライブラリ(DAX)を採用するよう変更されました。DAXは、古くからDelphiに搭載されてきたActiveXフレームワークです。
[docwikiヘルプ : C++Builder は ActiveX と COM に DAX を使用する]
http://docwiki.embarcadero.com/RADStudio/XE3/ja/C%2B%2BBuilder_%E3%81%AF_
ActiveX_%E3%81%A8_COM_%E3%81%AB_DAX_%E3%82%92%E4%BD%BF%E7%94%A
8%E3%81%99%E3%82%8B
案1. C++Builder XEでActiveXプロジェクトを新規作成し直す
ATLプロジェクトが DAX プロジェクトへ適切に変換されます。
(※継続的なサポートが保証される)案2. 旧バージョンのC++Builderから、ATL関連のファイルをコピー...¥include¥windows¥vcl¥vclhew.hpp...¥include¥windows¥sdk¥atlフォルダ全体(※継続的なサポートは保証されない)
18

17Th
Developer Camp

C++Builder Q419ilink32 エラー
Q. 旧バージョンのC++BuilderのプロジェクトをC++Builder XE3へ移行中です。
あるプロジェクトをビルドしたところ、以下のリンクエラーが発生しビルドに失敗します...

20

原因と解決策A. CodeGuardを有効にしている古いプロジェクトを移行すると、以下の条件でリンクエラーが発生します。
C++Builder 2009以降のバージョンでビルドし、且つ、[プロジェクト|オプション...]|[CodeGuardを有効にする]がFalseになっている
案1. 移行先のバージョン(例えば、C++Builder XE3)の[プロジェクト|オプション]の[CodeGuardを有効にする]をTrueに設定する

案2. 移行元のバージョン(例えば、C++Builder6)で先にCodeGuardを無効にしてから、プロジェクトを移行する

21

17Th
Developer Camp

Q&A

22

17Th
Developer Campもう１問 Q5

23

TListBoxのColorプロパティ
Q. Delphi 6からDelphi 2007へプロジェクトを移行中です。TListBoxのColorプロパティを変更するプログラムがあるのですが、Delphi 6とDelphi 2007で挙動が異なります。
Delphi 6ではTListBox全体の色が変更され、Delphi 2007ではItemの色だけが変更されます...

24

原因と解決策
A. この症状は、Delphi 7からDelphi 2009までのVCLに存在する不具合です。
Quality Centralへ報告されており、Delphi XE以降で修正済みです。
http://qc.embarcadero.com/wc/qcmain.aspx?d=9147

Delphi 7からDelphi 2009を利用する方は、Windows APIのInvalidateRect関数を呼び出して、TListBoxの背景色も含めた再描画を要求するコードを追加してください。

Trueが重要25