初版作成 2004.07.21
最終更新 2024.04.01
プロジェクトを新規作成して、「プロジェクトに名前を付けて保存」 した後、コンパイルすると [リンカ 致命的エラー] Fatal: ファイル名が必要 : というエラーが出ることがある。ディレクトリの深さが深すぎると、 エラーが出るように思われる。以下のように対処する。 **.dpr ファイルをエディタで開くと、 <INCLUDEPATH value=""C:\Program Files\Borland\CBuilder6\Projects";[この部分];$(BCB)\include;$(BCB)\include\vcl"/> <LIBPATH value=""C:\Program Files\Borland\CBuilder6\Projects";[この部分];$(BCB)\lib\obj;$(BCB)\lib"/> の [この部分] にプロジェクトを保存したフォルダが絶対パスで入っている。 LIBPATH に含まれている [この部分] を削除するとエラーは出なくなる。謎である。 ネットワークドライブを使用したときも同様のエラーがでる。この時にも 上記の対処法が有効か否かは未確認である。
1.「ファイル」→「新規作成」→「アプリケーション」で新規アプリケーションを作成し、 「ファイル」→「プロジェクトに名前を付けて保存」でフォルダに保存する。 2.「プロジェクト」→「プロジェクトから削除」で、全てのフォーム、リソースを削除する。 3. 移行元のプロジェクトのフォルダから、cpp, h, dfm, res ファイルをコピーしてくる。 新規アプリケーション作成時に自動生成された Unit1.* などは不要なので削除する。 4. 「プロジェクト」→「プロジェクトに追加」で cpp, res ファイルを追加する。
バージョン 1.0 のプロジェクトファイルを 5.0 用に移行する方法 1.「ファイル」→「プロジェクトを開く」→「ファイルの種類」を 「C++Builder 1.0 のプロジェクト(mak)」でプロジェクトファイル ◯◯.mak を開く。 2. ソースファイルのうち、#include <stdio.h> を記述していない ファイルは記述する。 3. 「ファイル」→「全て保存」で ◯◯.dpr ファイルを作成する。 4. ◯◯.dpr をエディタで開き、LIBRARIES と SPARELIBS の項目の部分を 以下のように直す。 <LIBRARIES value="vcl50.lib"> <SPARELIBS value="vcl50.lib"> 5.「ファイル」→「全て閉じる」のあと、「ファイル」→「プロジェクトを開く」 で修正した ◯◯.dpr ファイルを開き直す。 6. 「プロジェクト」→「◯◯を再構築」でコンパイル〜リンクをやり直す。
C++Builder 1.0 ではデフォルトでランタイムライブラリ不要の exe ファイル を作成していたが、C++Builder 5.0 ではデフォルトでランタイムライブラリが 必要な exe ファイルを作成する。C++Builder 5.0 でランタイムライブラリ 不要の exe ファイルを作成する方法は以下の通り。 「プロジェクト」→「オプション」のウィンドウにおいて > 「パッケージ」で「実行時パッケージを使って構築」のチェックを外す > 「リンカ」で「共有 RTL DLL を使う」のチェックを外す
SelectDirectory という関数を使えばよい。 使い方はヘルプの「例」を参照。SelectDirectory を使うには #include <FileCtrl.hpp> が必要であるが、このインクルード文は *.cpp に書いてはいけない。 *.h の中に書く必要がある。 *.cpp の中に書き、かつ「実行時パッケージを使って構築」の チェックを外した場合、「外部参照が未解決です」というリンクエラーが発生する。
Form1.Scaled = false : 起動するディスプレイの解像度によらず 固定サイズのウィンドウを開く Form1.Posision = poDefaultPosOnly : サイズは設計時のままで、 位置は Windows が規定する位置にウィンドウを開く Form1.BorderIcons.biMaximize = false : 最大化できなくする
情報源 http://tokyo.cool.ne.jp/purasupurasu/bcb.html#n9 フォーム生成時に、ボタンの属性を Windows の API を使って変更する。 Button1->Caption = "ab............\n............"; long bsp; // Window の情報を取得する API。ボタンもウィンドウの一種 GWL_STYLE はスタイルを取得する bsp = GetWindowLong(Button1->Handle, GWL_STYLE); // Window の属性を定義する。ウィンドウハンドル, 属性, 新しい値 SetWindowLong(Button1->Handle, GWL_STYLE, bsp | BS_MULTILINE);
RadioGroup1->Items->Strings[0] = "abc"; RadioGroup1->Items->Add("abc"); RadioGroup1->Items->Delete("abc"); index = RadioGroup1->Items->Indexof("abc"); RadioGroup1->Items->Count;
「ファイル」→「新規作成」→「その他」→「スレッドオブジェクト」 でスレッド用のユニットが作成される。 スレッド用ユニットが Unit2.cpp でメインフォームのコードが Unit1.cpp だと すると、お互いに #include "Unit1.h" のようにインクルードしあうことが 必要である。 TThread を継承して新しいスレッドクラスが作成される。 名前を TMyThread とすると __fastcall TMyThread::TMyThread(bool CreateSuspended) : TThread(CreateSuspended) { } となり、コンストラクタの引数である bool 型変数を TThread の コンストラクタに渡す。 false にすると new の瞬間に開始する。 true にすると Resume() メソッドで明示的に開始する。 false にするとコンストラクタが終了する前に Execute が開始するので、 true を推奨するとヘルプに書いてある。 私は以下のようにしている。 コンストラクタの引数を変更したときは、Unit2.h も書き換えることを 忘れないように。 __fastcall TMyThread::TMyThread( 初期化用の引数 ) : TThread(true) { 初期化処理 } コンストラクタは以下のようになる。 TMyThread *thread; thread = new TMyThread( 初期化用の引数 ); thread->Resume(); スレッド本体を関数 Execute() の中に記述する。 しかし、Execute() は呼ぶことが出来ない。Resume() で開始させる。 Terminate() メソッドを呼ぶと、デフォルトで用意されている 変数 Terminated が true となる。 Execute の中で無限ループを組む場合は、以下の処理を入れる。 if ( Terminated == true ) return; Execute() から return すると、スレッドのインスタンスは消滅するようだ。 もう一度、Resume() しても Execute() は実行されない。 一時停止させるには Suspend() メソッドを呼ぶ。 以下のことは大変重要である。 ボタンを押して呼ばれるコールバック関数の中で、 スレッドを new して Resume() したとき、そのコールバック関数 から return するまで、スレッドは開始しない。例えば、 以下のような場合、thread->Execute() が 開始するのは Sleep(1000) の後である。 void __fastcall TForm1::Button1Click(TObject *Sender) { thread = new TestThread(Memo1); thread->Resume(); Sleep(1000); } スレッドからメインフォームのメソッドを呼ぶとき、 Symchronize メソッドを使わないと、効かないことがある。 以下のように記述する。 -------- Unit2.h ---------- protected: void __fastcall Execute(); void __fastcall Form_Hide(); -------- Unit2.cpp --------- void __fastcall TMyThread::Form_Hide() { Form1->Hide(); } void __fastcall TMyThread::Execute() { // TODO : スレッドとして実行したいコードを以下に記述 */ Synchronize(Form_Hide); ----------- ここまで -----------
Unit1.cpp とUnit2.cpp で共通の変数を使うとき、 Unit1.h の中で int abc; と 宣言して Unit1.cpp と Unit2.cpp において #include "Unit1.h" とするのは ダメである。別々の変数と見なされる。