Delphi Tips
>> Index
● 01/02 TField.EditMask の y2k 回避
● 09/09 DLL 内で TDBCtrlGrid を使うときの注意事項
● 08/28 データコントロールのDataLinkオブジェクトを取得する方法(ReadOnlyプロパティのバグの解決法)
● 02/11 DBGrid のスクロールバーを非表示に
● 02/08 StringGrid/DBGrid でのセル編集の動作を細かく指定する
最終更新: 9090 日前
0296 D1D2D3D4 D5 D6 D7 3.195 98 作成: 2000/01/02 osamu rev 1.3 B1 B3 B4 B5 B6 B7 NT3 NT4 2K XP 更新: 2000/01/02 osamu 編集
TField.EditMask の y2k 回避
> DBEditで日付入力させるのですが、関連付けているTTable側の
> 日付フィールドのTFieldのEditMaskプロパティで
>
> !99/99/00;1;_
>
> ・・とマスクをかけています。
> すると、西暦を下2桁で打つマスクが有効になるのですが
> 2000/05/05 の意で 00/05/05 とか打つと、期待した
> 2000/05/05にならずに、1900/05/05と表示されてしまいます。
OnCreate イベントハンドラ内で
TwoDigitYearCenturyWindow := 50;
ShortDateFormat := 'yyyy/mm/dd';
の設定を行うと,現在の年が1999年のとき,1999年の前後50年である
1949/1/1 から 2048/12/31 の100年を変換の対象として扱います.
ただし D4 からの機能のようです。
詳しくはヘルプか以下のサイトをご覧になられるとよいと思います.
http://www.inprise.com/devsupport/y2000/
【追記】
Delphi 5 になってから TwoDigitYearCenturyWindow グローバル変数の初期値が「0」から「50」に変更されました。UI 簡略化等で西暦2桁年を使っているような場合、TwoDigitYearCenturyWindow 変数を設定しないまま日付型に変換しているような処理では、処理結果がD4以前と変わる場合があります。
ヘルプの記述(初期値は0)は誤っていますので、ご注意ください。
参照: [Delphi-ML:37908] [Delphi-ML:43093] <データベース> <コンポーネント >
0246 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 編集
DLL 内で TDBCtrlGrid を使うときの注意事項
>DLL化したアプリのフォームにDBCtrlGrid,DBCheckBoxを置いてローカルDB
>の内容を表示させているのですが、DLL化した途端にカレントレコードしか
>表示されなくなってしまいました。
この現象は以下の理由で発生します。
1.DLLの中では、何もしなければApplication.Handle=0です。
2.DBCtrlGridに配置されるコンポーネントの一部(DBCheckBoxを含む)はカレントレコード以外へ複製表示を行うために、Application.Handleを利用しています。
具体的にはDBCtrls.pasのTPaintControl.GetHandleで、次のようなコードで表示用の別ウインドウを生成しています。
with Params do
FHandle := CreateWindowEx(ExStyle, PChar(FClassName),
PChar(TWinControlAccess(FOwner).Text), Style or WS_VISIBLE,
X, Y, Width, Height, Application.Handle, 0, HInstance, nil);
Application.Handle=0 だと CreateWindowEXは失敗し、FHandle=0となるので複製表示が正常に行われないのです。
対処方法としては、Delphiヘルプの TApplication.Handle に書いてありますが、EXE ホストのメインウィンドウのウィンドウハンドルを DLL の Application.Handleに割り当てます。
別の方法としては、上記の TPaintControl.GetHandle の Application.Handle を FOwner.Handle に書き換えてもいいでしょう。
このスレッドではさらに、TApplication.MainForm.Handle を渡すべきか、TApplication.Handle を渡すべきか。また、TApplication.Handle を渡す際には、DLL 側の uses から Forms を削除しなければ、など、使い方に関する細かい注意点が議論されています。
参照: [Delphi-ML:33636] [Delphi-ML:33791] <データベース> <コンポーネント >
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] <データベース> <バグ> <コンポーネント >
0165 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 編集
DBGrid のスクロールバーを非表示に
この DBGrid のスクロールバーを力で消す方法,大変参考になりました。じっと見ているとちらりと映りますが,言われなければたぶん誰も気づかないでしょう(^^)
> private
> { Private 宣言 }
> FCellBottom : Integer;
>
> procedure TForm1.DBGrid1DrawColumnCell
> (Sender: TObject; const Rect: TRect;
> DataCol: Integer; Column: TColumn; State: TGridDrawState);
> begin
> if (FCellBottom < Rect.bottom) then FCellBottom := Rect.bottom;
> end;
>
> procedure TForm1.Query1BeforeInsert(DataSet: TDataSet);
> begin
> Abort;
> end;
>
> procedure TForm1.Query1AfterScroll(DataSet: TDataSet);
> begin
> ShowScrollBar(DBGrid1.Handle, SB_VERT, False);
> end;
>
> procedure TForm1.Button1Click(Sender: TObject);
> begin
> DBGrid1.Height := FCellBottom - DBGrid1.Top + 6;
> end;
参照: [Delphi-ML:31864] <データベース> <コンポーネント >
0009 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 編集
StringGrid/DBGrid でのセル編集の動作を細かく指定する
下のような関数を使って、TCustomGridで定義されているインプレースエディタを取得すれば、
GetGridEditor(StringGrid1).SelStart:=0;
などとできます。
function GetGridEditor(Grid: TCustomGrid): TCustomEdit;
var i: Integer;
begin
Result:=nil;
for i:=0 to Grid.ControlCount-1 do
if Grid.Controls[i] is TCustomEdit then begin
Result:=TCustomEdit(Grid.Controls[i]);
Exit;
end;
end;
参照: [Delphi-ML:18726] <データベース> <Additional> <コンポーネント >
[新規作成] [最新の情報に更新]
How To
Lounge
KeyWords
Osamu Takeuchi osamu@big.or.jp
Tips
Delphi
Home