Delphi Tips
>> Index
● 03/04 ブレークポイントで停止したときに IDE がアクティブにならない
● 09/24 Delphi7 のコンボボックスの空文字列でエラー
● 06/27 システムアイコンをリフレッシュする
● 06/25 ActiveX でショートカットキーが使えない
● 06/25 DLL にブレークポイントが設定できない
● 04/05 Oracle の Number 型で入力値が化ける
● 08/12 Dual CPU 機でフォームのフォントに不具合
● 05/26 DLLの初期化・終了処理
● 04/06 Currency型の小数演算結果が不正
● 09/21 Delphi4 で TBitmap を pf1bit で使うときの注意点(不具合回避)
● 09/19 Sqr()の結果が負になる!?
● 09/09 Metafile が Draw で1ピクセル小さく描画される
● 08/28 データコントロールのDataLinkオブジェクトを取得する方法(ReadOnlyプロパティのバグの解決法)
● 08/14 Delphi2/3.x における Cardinal 型の妙な定義
● 08/14 MS-Word 97 で作成した rtf ファイルがヘルプコンパイラでエラーを起こす
● 02/11 IniFile に書き込みを行った後にはバッファのクリアが必要
● 02/11 Delphi2 以上で Form の枠を黒線一本にするには
● 02/11 TSplitter をドラッグ中にヒント文字列が表示された時の不具合
● 02/08 Glyphに張ったビットマップの背景がおかしくなる
● 02/08 TBitmap の Width/Height に 0 を代入すると例外が発生する
● 02/08 OpenDialogでたくさんファイルを選択するとエラー
● 02/08 TDDEClientConvで最初の行しか実行されない?
● 02/08 TUpDown の不具合
● 02/08 Delphi1/2で状況依存型のコンポーネントヘルプを作るときの注意
● 02/08 TPageControl を TabPosition=tpBottom にすると不具合
● 02/08 アプリケーションアイコンの変更が反映されない
● 02/08 BCB3 のバージョン情報でキー名が日本語だと不具合
● 02/08 NT のタスクマネージャにアプリケーションのアイコンが表示されない
● 02/08 DLL のロード・アンロードでメモリリーク?
● 02/08 アイコン状態で起動するアプリ
● 02/08 TLabelのFontがイタリックだと、AutoSize=Trueで右端が切れる
● 02/08 Delphi1.0のDirectoryListBoxが全角英文字のディレクトリ名で動作不良
● 02/08 Delphi3 の TStringList.CommaText の不具合
● 02/08 TIniFileにクオートを含む文字列を与えるときの注意点
● 02/08 フォームの印刷時にComboBoxの内容が印刷されない
● 02/08 COMCTL32.DLLのバージョンについて
● 02/08 Delphi3.1でオブジェクトインスペクタの表示がおかしい
● 02/08 DelphiのバグをBorlandに報告する
● 02/08 TDriveComboBoxの内容の更新
● 02/08 Delphi3.0でDLLにバージョン情報が入らない
最終更新: 7375 日前
0146 D1 D2 D3 D4 D5 D6 D7 3.1 95 98 作成: 1999/02/11 osamu rev 1.4 B1 B3 B4 B5 B6 B7 NT3 NT4 2K XP 更新: 2004/03/04 osamu 編集
ブレークポイントで停止したときに IDE がアクティブにならない
Windows98 に移行してから、ブレークポイントで停止したときの挙動が変わりました。
フォーカスがDelphi IDE に移らず、デバッグ中のプログラムに残ったままなのです。
これを改善するためのエキスパート focusmgr.zip が、Delphian World
http://www.delphianworld.com/ で入手可能です。
(別件)
win.ini ファイルを編集することでも対応できます。
このファイルの[Compatibility95] セクションに(なければ追加し)、
DELPHI32=0x00000002
と記述するだけです。
こちらについての詳細は、以下をご覧ください。
Microsoft のサポート技術情報
W98:メッセージボックスがデスクトップの背後に隠れる
文書番号: J044951
参照: [Delphi-ML:24961] [Delphi-ML:25050] <開発環境>
0344 D1D2D3D4D5D6D7 3.195 98 作成: 2003/07/03 osamu rev 1.4 B1B3B4B5B6 B7 NT3 NT4 2K XP 更新: 2003/09/24 osamu 編集
Delphi7 のコンボボックスの空文字列でエラー
Delphi7 では、コンボボックスに空文字列を入れておくと、
ComboBox1.Items.Add('');
この Item を Items[0] などとして参照した時にアクセスバイオレーションエラーが発生してしまいます。
これは、以前の Delphi が Item 保持領域として 4096 などの固定値を使っていたのに対して、Delphi7 からは CB_GETLBTEXTLEN を使ってバッファを動的に確保するようになったためで、それ自体は正しいことなのですが、Item の長さが 0 の時に正しくバッファが確保されないためにエラーが発生してしまいます。
エラーの詳しい内容は、[Delphi-ML:77352][Delphi-ML:77360][Delphi-ML:77366]を見てみてください。回避方法としては、Amaito さんの [Delphi-ML:77357] のように、
StdCtrls.pasをプロジェクトと同じフォルダにコピーして、2325行を
//if Len <> CB_ERR then
if Len > 0 then
とするのが良いようです。(CB_ERR は負の値なので、Len > 0 で Len=0 と Len=CB_ERR との両方の場合に対応しています)
#[Delphi-ML:72969] でもすでに同じ問題が報告されていました。
## 実は編集後のコードにもちょっとした仕様バグが含まれています。
## TListBox.Items などと動作を合わせるのであれば、CB_ERR
## の場合には空文字列を返すのではなく例外を投げるべきだと
## 思います。
参照: [Delphi-ML:72969] [Delphi-ML:77352] [Delphi-ML:77357] [Delphi-ML:77360] [Delphi-ML:77366] <Standard> <コンポーネント >
0175 D1 D2 D3 D4 D5 D6 D7 3.1 95 98 作成: 1999/03/08 osamu rev 1.2 B1 B3 B4 B5 B6 B7 NT3 NT4 2K XP 更新: 2003/06/27 osamu 編集
システムアイコンをリフレッシュする
フォルダのアイコンなど、システムで使われるアイコンを変更した後は、ちょっとしたトリックを使わないと画面に反映されません。
具体的には、一旦アイコンの大きさを変更してまた元に戻すのだそうです。ひきさんのページでサンプルコードを見ることができます。
[Delphi壁の穴]-[その二:システムを覗く]
http://hp.vector.co.jp/authors/VA009712/take/delphi/kabesys.htm#refreshsysicon
参照: <Windows> <アイコン>
0334 D1 D2 D3 D4 D5 D6 D7 3.1 95 98 作成: 2003/06/25 osamu rev 1.1 B1 B3 B4 B5 B6 B7 NT3 NT4 2K XP 更新: 2003/06/25 osamu 編集
ActiveX でショートカットキーが使えない
ActiveXをd3・d4で取り込むと ActiveX に組み込まれているショートカットキーが使えないものがあります。
どうも、TOLEControlの親であるTWinControlでショートカットのメッセージが止まっていて、activeXに渡されてないようなのです。
ちょっとうまい対処の方法が思いつかないのですが、とりあえずApplication.OnMessage をつかってOleInPlaceActiveObject.TranslateAccelerator(Msg); で、activeXに直接伝えれば、症状を回避できるようです。
由木尾@蛸薬師倶楽部さんが具体的なコードを [Delphi-ML:32242] に示してくださっています。
参照: [Delphi-ML:32242] <その他Windows関連> <Windows>
0332 D1 D2 D3 D4 D5 D6 D7 3.1 95 98 作成: 2003/06/25 osamu rev 1.1 B1 B3 B4 B5 B6 B7 NT3 NT4 2K XP 更新: 2003/06/25 osamu 編集
DLL にブレークポイントが設定できない
今までWin2000 + Del5Entの環境で開発していました。OSをWinXPに変えたところ、DLLのデバッグができなくて困っています。
D5 + WinXP では DLL のデバッグができないようです。
D7 では正常に動作するとの報告があります。
参照: [Delphi-ML:72312] [Delphi-ML:73399] <開発環境> <デバッグ> <DLL>
0202 D1 D2 D3 D4 D5 D6 D7 3.1 95 98 作成: 1999/08/13 osamu rev 1.2 B1 B3 B4 B5 B6 B7 NT3 NT4 2K XP 更新: 2001/04/05 濱野 編集
Oracle の Number 型で入力値が化ける
BDE の 5.01 よりも前のバージョンで、Oracle 8.0.4 のテーブルのNUMBER型で桁数が7,2の項目に 99.999 と入力すると 10.00 になってしまいます。これは、BDE のバグです。
http://www.borland.co.jp/download/other.html
で BDE を 5.01 以上にバージョンアップすることで回避されます。詳しくは [Delphi-ML:41554] から始まるスレッドを参照してください。
参照: [Delphi-ML:41554] <データベース>
0300 D1D2 D3 D4 D5 D6 D7 3.19598作成: 2000/04/06 osamu rev 1.2 B1 B3 B4 B5 B6 B7 NT3NT4 2K XP 更新: 2000/08/12 ITO, Sakuya 編集
Dual CPU 機でフォームのフォントに不具合
開発環境がNT4 + Dual CPUだと、IDEで Code Explorer を表示させていると、 Object Inspector や作ったフォームなどのフォントが勝手に変わるというおぞましい現象がでます。Delphi 4で経験し、Delphi 5でも解消していませんでした。ちょっと使用に耐えなかったので、泣く泣く1個 CPU を外しました。
Delphi 5 Update Pack #1 では治っているそうです。
//追記 2000-08-12
日本語版 Delphi 5 は Update Pack #1 で修正されますが、US版では UP1 をあてても解消されません。
参照: [Delphi-ML:47436]
0301 D1 D2 D3 D4 D5 D6 D7 3.1 95 98 作成: 2000/05/26 osamu rev 1.1 B1 B3 B4 B5 B6 B7 NT3 NT4 2K XP 更新: 2000/05/26 osamu 編集
DLLの初期化・終了処理
D3 のヘルプでは DLL の終了処理に ExitProc を使うように書かれていますが、ExitProc のヘルプには ExitProc が下位互換性のためだけに残してあるものである旨の記述があります。実際(?)、ExitProc はパッケージの使用時に正常に動作しないようです。
このような問題を回避するためには、System ユニットにある DLLProc という変数を使います。
library MyLibrary;
uses Windows, SysUtils;
...
procedure DLLEntry(ul_reason_for_call: DWORD);
begin
case ul_reason_for_call of
// これらの値の意味については、Win32SDK の
// DLLEntryPoint の HELP を参照してください。
DLL_PROCESS_ATTACH:
;
DLL_PROCESS_DETACH:
;
DLL_THREAD_ATTACH:
;
DLL_THREAD_DETACH:
;
end;
end;
begin
DllProc := @DLLEntry;
DLLEntry(DLL_PROCESS_ATTACH);
end.
なお、初期化部分でエラーを発生させて DLL のロードを失敗させたい場合には、
(1) 初期化コードで System.ExitCode を 0以外に設定する。
(2) 初期化コード内で例外を起こす。
のいずれかを行います。
参照: [Delphi-ML:39301] [Delphi-ML:39147] <DLL> <PASCAL>
0299 D1 D2 D3 D4 D5 D6 D7 3.1 95 98 作成: 2000/04/06 osamu rev 1.1 B1 B3 B4 B5 B6 B7 NT3 NT4 2K XP 更新: 2000/04/06 osamu 編集
Currency型の小数演算結果が不正
Currency型で小数点以下の計算をすると、環境によっては結果が期待した値にならない場合があるそうです。
[例]
procedure TForm1.Button1Click(Sender: TObject);
var
num1, num2: Currency;
ret: string;
begin
num1 := StrToCurr('888888888888888.8888');
num2 := StrToCurr('0.8888');
ret := FormatCurr('#,##0.0000', num1 - num2);
ShowMessage(ret);
end;
この結果が『888888888888888.0128』になります。
この問題を解決するには、Currency や Extended 型の演算を行う前に、Set8087CW(Default8087CW); なるおまじないを入れておけばよいらしい。プロジェクトソースの一行目にでも書いておきましょう。
未確認ながら Delphi4 では治っていると言う報告があります。
[例]
begin
Set8087CW(Default8087CW);
num1 := StrToCurr('888888888888888.8888');
参照: [Delphi-ML:47431] <PASCAL>
0270 D1D2 D3 D4 D5 D6 D7 3.195 98 作成: 1999/09/21 osamu rev 1.1 B1 B3 B4 B5 B6 B7 NT3 NT4 2K XP 更新: 1999/09/21 osamu 編集
Delphi4 で TBitmap を pf1bit で使うときの注意点(不具合回避)
TBitmap は pf1bit で Width/Height が共に 0 以上になると 1bpp DIB を作成しますが、2色のカラーテーブルを初期化していません。
さらに、Width/Height が 0 以上の TBitmap を PixelFormat で pf1bit へ形式変換する場合
DDB -> 1bpp DIB 変換なら 黒白2色のカラーテーブルが作られます。 -> OK
DIB -> 1bpp DIB 変換なら 古いカラーテーブルが引き継がれます。 -> バグ
となります。
結局、PixelFormat := pf1bit; がまともに動くのは、古い PixelFormat の値が pfDevice で Width > 0, Height > 0 の場合だけです。たとえば,以下のようなコードで問題が発生します。
Bitmap1 := TBitmap.Create; // スクリーン互換 DDB を作成
Bitmap1.PixelFormat := pf1bit; // Size がゼロのまま 1bit DIB に変換
Bitmap1.Width := 1000;
Bitmap1.Height := 1000;
これを、
Bitmap1 := TBitmap.Create; // スクリーン互換 DDB を作成
Bitmap1.Width := 1000;
Bitmap1.Height := 1000;
Bitmap1.PixelFormat := pf1bit; // Size を設定してから 1bit DIB に変換
とすれば、正常に動きます。ただし、一旦ばかでかい DDB ができてしまうので,リソースの消費が問題になります。この場合には、以下のようにするのがベストでしょう。
Bitmap1 := TBitmap.Create; // スクリーン互換 DDB を作成
Bitmap1.Width := 1;
Bitmap1.Height := 1;
Bitmap1.PixelFormat := pf1bit; // 小さな Size を設定してから 1bit DIB に変換
Bitmap1.Width := 1000;
Bitmap1.Height := 1000; // 大きくする
基礎知識:
TBitmap.Monochrome=True; は 1bit DDB
TBitmap.PixelFormat:=pf1bit; は 1bit DIB
を作成します。
この辺は、Delphi Magazine 3/4/5号で中村@NECさんが詳しく説明して下さっています。
参照: [Delphi-ML:42732] <画像>
0024 D1 D2 D3 D4 D5 D6 D7 3.1 95 98 作成: 1999/02/08 osamu rev 1.5 B1 B3 B4 B5 B6 B7 NT3 NT4 2K XP 更新: 1999/09/19 西坂良幸 編集
Sqr()の結果が負になる!?
Sqr()関数は引数にIntegerを渡すと結果にIntegerが返ってきます。
ヘルプで
function Sqr(X: Real): Real;
と書いてあるにもかかわらずです。
Sqr()関数は引数が整数型だと結果は整数型で返り、
引数が実数型だと結果は実数型で返ります。
これが仕様です。
なお、整数型を渡した場合、オーバーフローのチェックは行われません。そのため渡す値によっては
sqr(x)+sqr(y)
の結果が負になる場合があり、これを実行時に検出することはできません。自乗した場合の結果が Integer の制限を越えることが予想できる場合には、引数を実数型にキャストして渡す必要があります。
参照: [Delphi-ML:7250] <計算> <PASCAL>
0248 D1 D2 D3 D4 D5 D6 D7 3.1 95 98 作成: 1999/09/09 osamu rev 1.1 B1 B3 B4 B5 B6 B7 NT3 NT4 2K XP 更新: 1999/09/09 osamu 編集
Metafile が Draw で1ピクセル小さく描画される
>拡張メタファイルを作成するツールを作ろうとしています。
>そこで、メタファイルに編集を加えるたびに以前編集した像が
>1ドット(?)ずつ縮小してしまう問題があるのです。
TMetafile.Draw を見ると
R := Rect;
Dec(R.Right); // Metafile rect includes right and bottom coords
Dec(R.Bottom);
PlayEnhMetaFile(ACanvas.Handle, FImage.FHandle, R);
となっていて、描画先矩形を 1ドット分縮小しているのが原因のようです。
Win32 Programmer's Ref. で PlayEnhMetafile を見ると、
Points along the edges of the rectangle are included in the picture.
なんて微妙なことが書いてあるのですが、実際には Win98 で試してみた限り矩形領域を小さくするのは正しくないようです。Dec をコメントにすると完全に同じ大きさの図形が得られます。
対処としては graphics.pas を修正するか、Right, Bottom を一つ大きめに指定して StretchDraw するしかないようです。
ただ、ディスプレイデバイスとメタファイルの参照デバイスが異なると多少の誤差は避けられないようです。この辺を考慮して高精度のメタファイルを作るにはメタファイルを直接編集するしかないと思います。
参照: [Delphi-ML:33593] <画像> <描画>
0222 D1 D2 D3 D4 D5 D6 D7 3.1 95 98 作成: 1999/08/28 西坂良幸 rev 1.2 B1 B3 B4 B5 B6 B7 NT3 NT4 2K XP 更新: 1999/08/28 西坂良幸 編集
データコントロールのDataLinkオブジェクトを取得する方法(ReadOnlyプロパティのバグの解決法)
VCLでは、DataControlのFDataLinkは、プロパティになっていないので、アクセスできませんが、
DataControlにCM_GETDATALINKメッセージを投げる事で取得(参照)できます。[Delphi-ML:41387]田原
多重継承ができないので、こうなっているそうです。
これによって、MLでも多い質問ですが、いわゆる「極東仕様」問題、すなわち、TDBEdit の ReadOnly と継承元の TCustomEdit のReadOnly の同期がとれないバグを解決することができます。[Delphi-ML:41051]藤中
以下は、藤中さんの例示コード(省略部あり)です。
// このデータコントロール(フィールド対応)は編集可能か?
function IsCanModifyFieldDataControl(Control: TControl) : Boolean;
var
DataLink : TFieldDataLink;
begin
// データリンクを取得
DataLink := TFieldDataLink(Control.Perform(CM_GETDATALINK,0,0));
if (DataLink = nil) then
DatabaseError('CM_GETDATALINK は無効', Control);
// データリンクが編集可能かどうか調べる
Result := DataLink.CanModify and
( DataLink.DataSource.AutoEdit or
(DataLink.DataSource.State in [dsInsert, dsEdit]) );
end;
// たとえば、Table1のAfterScrollイベントなどで動的にReadOnlyを変更する
type TCustomEditCracker = class(TCustomEdit);
procedure TForm1.Table1AfterScroll(DataSet: TDataSet);
var
Flg :Boolean;
begin
// 条件
if DataSet.FieldByName('制御フラグ').AsString = '1' then
Flg := True
else
Flg := False;
// 以下でReadOnlyを変更
DBEdit1.ReadOnly := Flg;
if (Flg = False) then
begin
TCustomEditCracker(DBEdit1).ReadOnly :=
not IsCanModifyFieldDataControl(DBEdit1);
end
else begin
TCustomEditCracker(DBEdit1).ReadOnly := True;
end;
end;
参照: [Delphi-ML:41387] [Delphi-ML:17611] [Delphi-ML:41051] <データベース> <コンポーネント > <DataControls>
0089 D1 D2 D3 D4 D5 D6 D7 3.1 95 98 作成: 1999/02/08 osamu rev 1.2 B1 B3 B4 B5 B6 B7 NT3 NT4 2K XP 更新: 1999/08/14 osamu 編集
Delphi2/3.x における Cardinal 型の妙な定義
>Delphi3.1のWindows.pasの中で、
> DWORD = Integer; と定義されていますが、
> DWORD = Cardinal; ではないのでしょうか。
>
>また、ヘルプ及びマニュアルに
> Cardinal 0〜2147483647 符号なし 32 ビットと書かれていますが、
> 0〜4294967295 ではないのでしょうか.。
残念ながらマニュアルの通りです。
また Cardinal 型の変数には マイナス値や 2147483647 を超える定数値を代入することは出来ませんが、「オプション」の「範囲チェックエラー」をオフにしておくと 計算の結果負数を持つことは出来ます。
例えば
var i: Cardinal;
:
:
i := 10;
i := i - 20;
if i >= 0 then ShowMessage('Plus')
else ShowMessage('Minus');
は Minus と表示されます。つまり Integer とほとんど変わりません。
[Delphi-ML:23120]によれば、Delphi4 ではちゃんと Cardinal=(0..2^32-1) になっているようです。
参照: [Delphi-ML:20567] [Delphi-ML:23120] <PASCAL>
0035 D1 D2 D3 D4 D5 D6 D7 3.1 95 98 作成: 1999/02/08 osamu rev 1.2 B1 B3 B4 B5 B6 B7 NT3 NT4 2K XP 更新: 1999/08/14 osamu 編集
MS-Word 97 で作成した rtf ファイルがヘルプコンパイラでエラーを起こす
Delphi付属のヘルプコンパイラではMS-Word97で作成したrtfファイルをコンパイルできません。
http://support.microsoft.com/support/downloads/dp2677.asp
から、Word97対応のヘルプコンパイラがダウンロードできます。
参照: [Delphi-ML:6924] [Delphi-ML:16043] [Delphi-ML:18838] <ヘルプ>
0162 D1 D2 D3 D4 D5 D6 D7 3.1 95 98 作成: 1999/02/11 osamu rev 1.1 B1 B3 B4 B5 B6 B7 NT3 NT4 2K XP 更新: 1999/02/11 osamu 編集
IniFile に書き込みを行った後にはバッファのクリアが必要
Delphi4 になって追加されたメソッドに、TIniFile.UpdateFile というのがあります。
TIniFile.UpdateFile メソッドは,バッファリングされた INI ファイルのデータをディスクにフラッシュします。
function UpdateFile; override;
説明
UpdateFile メソッドを呼び出すと,バッファリングされた,INI ファイルからの読み取りや INI ファイルへの書き込みをディスクにフラッシュできます。UpdateFile は,Windows95 では便利ですが,Windows NT では INI ファイルの読み取りや書き込みをバッファリングしないので、効果がありません。
Delphi3 以前では自分で
WritePrivateProfileString(nil, nil, nil, PChar(FileName));
などとして IniFile のキャッシュを書き込む必要があります。
> Ini := TIniFile.Create(Filename);
> with Ini do begin
> WriteString(aaaa, bbbb, cccc);
> WriteString(dddd, eeee, ffff);
> Free;
> // 以下の処理で、キャッシュをフラッシュ
> WritePrivateProfileString(nil, nil, nil, PChar(Filename));
> end;
参照: [Delphi-ML:31512] <アプリケーション> <Windows>
0154 D1 D2 D3 D4 D5 D6 D7 3.1 95 98 作成: 1999/02/11 osamu rev 1.1 B1 B3 B4 B5 B6 B7 NT3 NT4 2K XP 更新: 1999/02/11 osamu 編集
Delphi2 以上で Form の枠を黒線一本にするには
Form の枠を一本線にするために Ctrl3D = True, BorderStyle = bsSingle としても、望みの結果が得られません。問題は、ControlStyle に csFrame が無いとき CTRL3D := False は無視されてしまうということです。
constructor を再定義して
# constructor TForm1.Create(AOwner: TComponent);
# begin
# inhelited;
# ControlStyle := ControlStyle + [csFramed] ;
# end;
を加えれば望みの結果が得られます。
参照: [Delphi-ML:30137] <フォーム>
0134 D1 D2 D3 D4 D5 D6 D7 3.1 95 98 作成: 1999/02/11 osamu rev 1.1 B1 B3 B4 B5 B6 B7 NT3 NT4 2K XP 更新: 1999/02/11 osamu 編集
TSplitter をドラッグ中にヒント文字列が表示された時の不具合
TSplitter をドラッグ中に他のコントロール上にてヒントボックスを出現させると、TSpliter の境界線がその場に残ってしまいます。
TSplitter のドラッグ中は Application.ShowHint を False にしてしまうという回避方が [Delphi-ML:24019] にて紹介されています。
参照: [Delphi-ML:24019] <Additional> <その他コンポーネント関連> <コンポーネント >
0049 D1 D2 D3 D4 D5 D6 D7 3.1 95 98 作成: 1999/02/08 osamu rev 1.1 B1 B3 B4 B5 B6 B7 NT3 NT4 2K XP 更新: 1999/02/08 osamu 編集
Glyphに張ったビットマップの背景がおかしくなる
Glyphでは、左下隅のピクセルの色を透過色として扱うので、背景となる色をちゃんと表示するには、ビットマップを一回り大きく作って表示したい絵の中に使われていない色で「縁」を作ってやればよいです。
参照: [Delphi-ML:6213] <画像>
0058 D1 D2 D3 D4 D5 D6 D7 3.1 95 98 作成: 1999/02/08 osamu rev 1.1 B1 B3 B4 B5 B6 B7 NT3 NT4 2K XP 更新: 1999/02/08 osamu 編集
TBitmap の Width/Height に 0 を代入すると例外が発生する
TBitmap のバグか仕様か以下のようなコードで例外が発生する。
void __fastcall TClass1::Method1( void )
{
Graphics::TBitmap *Bmp;
Bmp = new Graphics::TBitmap();
Bmp->LoadFromFile( "BMPファイル名" );
Bmp->Width = 0; // <-ここでEOutOfResource例外が発生
delete Bmp;
}
このコードは BCB1 では問題なかったが BCB3 では例外が発生する。
内部ビットマップ形式が DDB から DIB に変わったことが関連している。
Bmp->Width = 0;
の前に、
Bmp->ReleaseHandle();
とすることで回避が可能。
参照: [builder:4889] <画像>
0070 D1 D2 D3 D4 D5 D6 D7 3.1 95 98 作成: 1999/02/08 osamu rev 1.1 B1 B3 B4 B5 B6 B7 NT3 NT4 2K XP 更新: 1999/02/08 osamu 編集
OpenDialogでたくさんファイルを選択するとエラー
ファイル名を保存するバッファが 8KB 固定のために起こります。
VCL に手を入れるか、自分で GetOpenFileName API を呼ぶしか回避できません。
参照: [builder:5117] <ダイアログ> <ファイル>
0084 D1 D2 D3 D4 D5 D6 D7 3.1 95 98 作成: 1999/02/08 osamu rev 1.1 B1 B3 B4 B5 B6 B7 NT3 NT4 2K XP 更新: 1999/02/08 osamu 編集
TDDEClientConvで最初の行しか実行されない?
TDDEClientConv を使って、ステップ実行を行うとちゃんとマクロは実行されるのですが、そのまま実行すると、最初のコマンドのみ実行してその後が実行されません。
これは2.0からのバグです。3.0/3.1用のパッチを当てると直ると思います。
http://www.dataweb.nl/~r.p.sterkenburg/bugsall.htmが詳しいです。
日本語版でも通用する個所が多いです。参考にしてみて下さい。
1)必要なったらTDDEClientConvをCreate
2)マクロを実行
3)用が済んだらFree
で逃げられます。
参照: [Delphi-ML:19657] <その他Windows関連> <System> <ShellApi> <Windows> <コンポーネント >
0085 D1 D2 D3 D4 D5 D6 D7 3.1 95 98 作成: 1999/02/08 osamu rev 1.1 B1 B3 B4 B5 B6 B7 NT3 NT4 2K XP 更新: 1999/02/08 osamu 編集
TUpDown の不具合
TUpDown コントロールは OnChange/OnClick イベントがらみで、様々な問題を抱えているようです。
詳しくは、まとめとして投げられた、[Delphi-ML:20127]からたどれるスレッドを参照してください。
参照: [Delphi-ML:20127] <Win95> <コンポーネント >
0087 D1 D2 D3 D4 D5 D6 D7 3.1 95 98 作成: 1999/02/08 osamu rev 1.1 B1 B3 B4 B5 B6 B7 NT3 NT4 2K XP 更新: 1999/02/08 osamu 編集
Delphi1/2で状況依存型のコンポーネントヘルプを作るときの注意
[delphi-cw 127]より。
マニュアルによれば、ヘルプトピックに、決められた形式の B 脚注を入れれば良いことになっているのですが、この時、脚注の書式に気を付けないといけません。
#{\footnote hlp_TNkDIB}
${\footnote TNkDIB}
K{\footnote TNkDIB;NkDIB;DIB}
B{\footnote class_TNkDIB}
などとする変わりに、
#{\footnote # hlp_TNkDIB}
${\footnote $ TNkDIB}
K{\footnote K TNkDIB;NkDIB;DIB}
B{\footnote B class_TNkDIB}
のようにしないと、kwgen.exe がキーワードの読み取りに失敗してしまいます。
参照: <開発環境> <コンポーネント開発> <ヘルプ>
0091 D1 D2 D3 D4 D5 D6 D7 3.1 95 98 作成: 1999/02/08 osamu rev 1.1 B1 B3 B4 B5 B6 B7 NT3 NT4 2K XP 更新: 1999/02/08 osamu 編集
TPageControl を TabPosition=tpBottom にすると不具合
Windowsのバージョンによって、tpBottom での利用に制限がある場合があるようです。[Delphi-ML:20099]からのスレッドに、いくつか報告例があるので、参考にしてください。
参照: [Delphi-ML:20099] <Win95> <コンポーネント >
0093 D1 D2 D3 D4 D5 D6 D7 3.1 95 98 作成: 1999/02/08 osamu rev 1.1 B1 B3 B4 B5 B6 B7 NT3 NT4 2K XP 更新: 1999/02/08 osamu 編集
アプリケーションアイコンの変更が反映されない
IDEでアプリケーションアイコンを変更しても、95のエクスプローラからプロパティで見たときのアイコンを変更することができず、はまることがあります。
これは、Windows 95 のアイコンキャッシュのせいです。何故か、Windows 95 環境では、再起動しようがどうしようが変わってくれない事があります。ファイルをリネームすると変わるので、Windows 95 のバグみたいです。
TWEAK UI に含まれるツールに、アイコンのキャッシュを飛ばすツールが有るらしいので、それを使って見てはいかがでしょうか。
普段、Windows NT 4.0 を使っているのですが、こちらでは普通起こりません。希に起こっても、再起動で必ず解消します。
参照: [builder:5426] <開発環境>
0096 D1 D2 D3 D4 D5 D6 D7 3.1 95 98 作成: 1999/02/08 osamu rev 1.1 B1 B3 B4 B5 B6 B7 NT3 NT4 2K XP 更新: 1999/02/08 osamu 編集
BCB3 のバージョン情報でキー名が日本語だと不具合
BCB3は標準でバージョン情報が表示できるようになりましたが、キーの名前がが2バイト文字で終わるとバグるみたいです。(標準のキー名(会社、製品名など)は大丈夫)
とりあえず終わりに「.」を打つことで対処しています。
参照: [builder:4937] <開発環境>
0103 D1 D2 D3 D4 D5 D6 D7 3.1 95 98 作成: 1999/02/08 osamu rev 1.1 B1 B3 B4 B5 B6 B7 NT3 NT4 2K XP 更新: 1999/02/08 osamu 編集
NT のタスクマネージャにアプリケーションのアイコンが表示されない
Delphi で作られるソフトすべてでこの問題が発生します。ちなみに、Delphi 自身も同じ問題を抱えています。
アプリケーションのクラスアイコンをセットしたら表示されるようになると思います。
プロジェクトソースかメインフォームの OnCreate イベントで、
SetClassLong(Application.Handle,
GCL_HICON,
Application.Icon.Handle);
を実行して下さい。
参照: [Delphi-ML:21168] <その他Windows関連> <アプリケーション> <Windows> <アイコン>
0106 D1 D2 D3 D4 D5 D6 D7 3.1 95 98 作成: 1999/02/08 osamu rev 1.1 B1 B3 B4 B5 B6 B7 NT3 NT4 2K XP 更新: 1999/02/08 osamu 編集
DLL のロード・アンロードでメモリリーク?
プログラム中でDLLの呼び出し、開放を何度も行っていると、システムモニターの「アロケート済みメモリ」がどんどん増えていきます。
簡単なDLL呼出しプログラムを作って試しましたが、呼出・開放を2018回繰り返すとプログラムがとまります。DLLの内容には関係ありません。
また、NT4/BCB3を使っても同様の現象が発生します。
以下の方法で回避できます。
・インポートライブラリを使ってDLLをリンクする
または
・DLLを作成するときにVCLをリンクしない(DLLでVCLを使っていない場合のみ)
参照: [builder:5705] <DLL> <メモリ>
0027 D1 D2 D3 D4 D5 D6 D7 3.1 95 98 作成: 1999/02/08 osamu rev 1.1 B1 B3 B4 B5 B6 B7 NT3 NT4 2K XP 更新: 1999/02/08 osamu 編集
アイコン状態で起動するアプリ
参照: [Delphi-ML:13173] [Delphi-ML:13185] <フォーム>
0031 D1 D2 D3 D4 D5 D6 D7 3.1 95 98 作成: 1999/02/08 osamu rev 1.1 B1 B3 B4 B5 B6 B7 NT3 NT4 2K XP 更新: 1999/02/08 osamu 編集
TLabelのFontがイタリックだと、AutoSize=Trueで右端が切れる
困ったもんですね。
コードを見るとDelphiのせいではなく、WinAPI側の問題のようですが。。。
とりあえず、Captionの後ろにダミーの空白文字を入れておけばちゃんと表示されます。
Caption:=Caption+' ';
参照: [Delphi-ML:18567]
0032 D1 D2 D3 D4 D5 D6 D7 3.1 95 98 作成: 1999/02/08 osamu rev 1.1 B1 B3 B4 B5 B6 B7 NT3 NT4 2K XP 更新: 1999/02/08 osamu 編集
Delphi1.0のDirectoryListBoxが全角英文字のディレクトリ名で動作不良
参照: [Delphi-ML:11616]
0033 D1 D2 D3 D4 D5 D6 D7 3.1 95 98 作成: 1999/02/08 osamu rev 1.1 B1 B3 B4 B5 B6 B7 NT3 NT4 2K XP 更新: 1999/02/08 osamu 編集
Delphi3 の TStringList.CommaText の不具合
個々のアイテムが空白などを含む場合にのみダブルクオートで括るはずが、必要の無いときまでダブルクオートが使われる。
[対応策]
class.pas の 2253 行目から4行だけ示します。"" で包む必要があるなら
包む処理をする部分です。
S := Get(I);
P := PChar(S);
while not (P^ in [#0..' ','"',',']) do P := CharNext(P);
if (P <> #0) then S := AnsiQuotedStr(S, '"');
// ^^ ここ正しくは P^ 。
// ポインタと文字を比べるんじゃなーい!!
参照: [Delphi-ML:8468] <文字列> <PASCAL>
0034 D1 D2 D3 D4 D5 D6 D7 3.1 95 98 作成: 1999/02/08 osamu rev 1.1 B1 B3 B4 B5 B6 B7 NT3 NT4 2K XP 更新: 1999/02/08 osamu 編集
TIniFileにクオートを含む文字列を与えるときの注意点
APIのGetPrivateProfileStringの仕様として、値文字列の両端がクォート( " or ' )で囲まれていると、これを外してから返すことになっています。
これは、次のような問題を引き起こしかねません。
[Iniファイルの内容]
SomeItem="a bd","de fg","h ijk"
これをTIniFileを使って読み出すと、結果は、
Result='a bd","de fg","h ijk';
となって、両端のクォートだけが取り払われ、おかしなことになってしまいます。
これは、特に、TStringList.CommaTextをTInifileを使って読み書きするときに注意すべき点です。
これを防ぐには、クォートで括られた文字列群をさらに一段、クォートで囲ってしまいます。
[Iniファイルの内容]
SomeItem=""a bd","de fg","h ijk""
これをTIniFileを使って読み出すと、結果は、
Result='"a bd","de fg","h ijk"';
となって、OKです。
コード的には、
IniFile.WriteString('TEST', 'ZZZ', TmpLst.CommaText);
を
IniFile.WriteString('TEST', 'ZZZ', '"'+TmpLst.CommaText+'"');
とします。
ちなみに、TRegIniFileを使う場合には、このようなことは起こりません。
参照: [Delphi-ML:8412] [Delphi-ML:8417] <アプリケーション>
0040 D1 D2 D3 D4 D5 D6 D7 3.1 95 98 作成: 1999/02/08 osamu rev 1.1 B1 B3 B4 B5 B6 B7 NT3 NT4 2K XP 更新: 1999/02/08 osamu 編集
フォームの印刷時にComboBoxの内容が印刷されない
Delphi3 になって、フォームの印刷時に TComboBox の内容(テキスト)が印刷表示されなくなりました。
Delphi2 ではちゃんと印刷されます。
kohiroさんが[Delphi-ML:19070]で解法を示してくださっています。
参照: [Delphi-ML:19070] <印刷> <フォーム> <Standard> <コンポーネント >
0042 D1 D2 D3 D4 D5 D6 D7 3.1 95 98 作成: 1999/02/08 osamu rev 1.1 B1 B3 B4 B5 B6 B7 NT3 NT4 2K XP 更新: 1999/02/08 osamu 編集
COMCTL32.DLLのバージョンについて
Delphi3のクールバーなどは、Windows の comctl32.dll のバージョンによって動作したりしなかったりします。
このため、Delphi3.1 では comctl32.dll のバージョンを手軽にチェックするための関数が Comctrls.pas に追加されています。
この関数はヘルプには載っていません。
使い方は、
if (GetComCtlVersion >= ComCtlVersionIE4) then
などとします。
ComCtlVersionIE3 なども定義されています。
参照: [Delphi-ML:19113]
0045 D1 D2 D3 D4 D5 D6 D7 3.1 95 98 作成: 1999/02/08 osamu rev 1.1 B1 B3 B4 B5 B6 B7 NT3 NT4 2K XP 更新: 1999/02/08 osamu 編集
Delphi3.1でオブジェクトインスペクタの表示がおかしい
PCにインストールされているグラフィックカードによって、この現象が起こることがあるようです。
コントロールパネルの[システム]-[パフォーマンス]のグラフィックスのハードウェアアクセラレータを1つ2つ下げてやることで改善されることが多いようです。
参照: [Delphi-ML:19277] <開発環境>
0047 D1 D2 D3 D4 D5 D6 D7 3.1 95 98 作成: 1999/02/08 osamu rev 1.1 B1 B3 B4 B5 B6 B7 NT3 NT4 2K XP 更新: 1999/02/08 osamu 編集
DelphiのバグをBorlandに報告する
Borlandへのバグ報告は質問扱いにはならず、この場合のインシデントの消費は無いそうです。
電子メールmailto:user@borland.co.jpでも受け付けるそうです。
参照: [Delphi-ML:11475]
0017 D1 D2 D3 D4 D5 D6 D7 3.1 95 98 作成: 1999/02/08 osamu rev 1.1 B1 B3 B4 B5 B6 B7 NT3 NT4 2K XP 更新: 1999/02/08 osamu 編集
TDriveComboBoxの内容の更新
ネットワークドライブの割当てをした後、TDriveComboBoxにて割当てたドライブを反映させたいのですが、方法が解りません。
DriveComboBox1.TextCase:=DriveComboBox1.TextCase;
たぶんこれが一番楽な方法だと思います。
非常に裏わざ臭いですが。。。
参照: [Delphi-ML:7162] <System> <コンポーネント > <ファイル>
0007 D1 D2 D3 D4 D5 D6 D7 3.1 95 98 作成: 1999/02/08 osamu rev 1.1 B1 B3 B4 B5 B6 B7 NT3 NT4 2K XP 更新: 1999/02/08 osamu 編集
Delphi3.0でDLLにバージョン情報が入らない
Delphi3.0で、「新規作成」から DLL を作ると、「バージョン情報を含める」のオプションを指定しても、効果が無い。
これは、.dpr ファイルに {$R*.RES} の一文が入らないために、リソースファイルはできるのに、リンクされないためだ。
uses節の後ろに手動で{$R*.RES} を書いてやればよい。
参照: [Delphi-ML:19012] <その他Windows関連> <アプリケーション> <開発環境> <Windows> <DLL>
[新規作成] [最新の情報に更新]
How To
Lounge
KeyWords
Osamu Takeuchi osamu@big.or.jp
Tips
Delphi
Home