カテゴリー「CBuilder」の6件の記事

2012-02-01

TCanvas::CopyRectでのソースはビットマップだけ?

TImage (Image1)のPictureにJPEGイメージをセットします。

TRect src (0,0,Image1->Width,Image1->Height);
TRect dst (0,0,Image2->Width,Image1->Height);
Image2->Canvas->CopyRect (dst, Image1->Canvas, src);

とすると、以下の例外が発生する
image

Image1->Picture->Bitmapに何かをセットしてやるとコピーできる。

| | コメント (0) | トラックバック (0)

2012-01-25

dbExpressでMySQLに接続 RAD Studio 2010

今回、サーバはLinuxサーバなので、MySQLのインストールはしないので、mysql-noinstall-5.1.61-win32.zipをダウンロードしてlibmySQL.dllをパスの通ったディレクトリにコピー

どうも、5.0系では動かないっぽいので、5.1系を使わないとならないっぽい。

TSQLConnectionのDriverにMySQLを選択する。多分これだけで、ほとんどの設定を自動に選択してくれる。

Paramsパラメータにデータベース固有の情報を書く

  • HostName
    データベースサーバ
  • Database
    データベース名
  • User_Name
    ユーザー名
  • Password
    パスワード
  • ServerCharSet
    サーバーのデータの文字コード (sjis, ujis, utf8とか?)

これで、接続できるんじゃないのかな?

SET NAMES とかやっても、文字化けしちゃうからちょっと焦った。

| | コメント (0) | トラックバック (0)

2011-10-06

VCL TDrawGrid, TStringGridにComboBoxを使う

通常の、goEditingでは、TInplaceEditが使われますが、これをTInplaceEditListに代えてやればOK。

あとは、TCustomGridのGetEditStyle関数が、戻すTEditStyleによって、エディタの挙動が変わります。esSimpleが普通の状態、esPickListでコンボボックス、esEllipsisで参照ボタンのような点が3つ描かれたボタンが表示されます。

TEditStyle __fastcall GetEditStyle (int ACol, int ARow);

TInplaceEditListクラスには、OnGetPickListitems、OnEditButtonClickというイベントハンドラプロパティが用意されていて、OnGetPickListitemは、内部エディタがPickListの要素を要求した時に発生するので、ここで任意の要素を設定すれば、セルの座標に応じたリストを表示する事ができる。OnEditButtonClickはesEllipsisの時に表示されるボタンのクリックに対応する。普通に考えるとOpenDialogを表示して、ファイル名をセルに描画するという感じになると思う。

TInplaceEditをTInplaceEditListに変えるには、TCustomGrid::CreateEditor関数でTInplaceEdit*を返す。TInplaceEditListは、TInplaceEditの派生クラスなので、TInplaceEditListを生成して返してやれば良いのだが、上記2つのイベントハンドラの設定が必要になる。

TInplaceEdit * __fastcall CreateEditor ();

で、簡単にこれらをグリッドで管理してしまおうと思う。ついでに、GetEditStyleをフォームなどから操作できるように、コールバック化する。

typedef void __fastcall (__closure* TOnGetEditStyle) (int ACol, int ARow, TEditStyle& AStyle);

class TMyGrid : public TStringGrid
{
private:
TOnGetEditStyle FOnGetEditStyle;
TOnGetPickListItems FOnGetPickListItems;
TNotifyEvent FOnEditButtonClick;
protected:
DYNAMIC TEditStyle __fastcall GetEditStyle (int ACol, int ARow)
{
TEditStyle style = esSimple;

if (NULL != FOnGetEditStyle)
{
FOnGetEditStyle (ACol, ARow, style);
}

return style;
}

TInplaceEdit* __fastcall CreateEditor ()
{
TInplaceEditList* editor = new TInplaceEditList (this);

editor->OnGetPickListitems = FOnGetPickListItems;
editor->OnEditButtonClick = FOnEditButtonClick;

return editor;
}

virtual void __fastcall SetOnGetPickListItems (TOnGetPickListItems event)
{
FOnGetPickListItems = event;

TInplaceEditList* editor =
dynamic_cast <TInplaceEditList*> (InplaceEditor);

if (NULL != editor)
{
editor->OnGetPickListitems = FOnGetPickListItems;
}
}

virtual void __fastcall SetOnEditButtonClick (TNotifyEvent event)
{
FOnEditButtonClick = event;

TInplaceEditList* editor =
dynamic_cast <TInplaceEditList*> (InplaceEditor);

if (NULL != editor)
{
editor->OnEditButtonClick = FOnEditButtonClick;
}
}

public:
__fastcall TMyGrid (TComponent* Owner)
: TStringGrid (Owner),
FOnGetEditStyle (NULL),
FOnGetPickListItems (NULL),
FOnEditButtonClick (NULL)
{
}

virtual __fastcall ~TMyGrid ()
{
}

__published:
__property TOnGetEditStyle OnGetEditStyle =
{ read = FOnGetEditStyle, write = FOnGetEditStyle };

__property TOnGetPickListItems OnGetPickListItems =
{ read = FOnGetPickListItems, write = SetOnGetPickListItems };

__property TNotifyEvent OnEditButtonClick =
{ read = FOnEditButtonClick, write = SetOnEditButtonClick };
};

あとは、このグリッドをフォームのメンバにして、フォーム側でOnGetPickListItems、OnEditButtonClick, OnGetEditStyleを実装してから、グリッドのプロパティにセットしてやる。

OnEditButtonClickでオープンダイアログを表示するために、フォームにはOpenDialogを置いておく。

class TForm1 : public TForm
{
__published:
TOpenDialog* OpenDialog1;
private:
TStringList* FStringList1;
TStringList* FStringList2;
public:
TMyGrid* MyGrid;

__fastcall TForm1 (TComponent *Owner)
: TForm (Owner),
MyGrid (new TMyGrid (this)),
FStringList1 (new TStringList),
FStringList2 (new TStringList)
{
MyGrid->Parent = this;
MyGrid->Options += TGridOptions () << goEditing << goColSizing;
MyGrid->Align = alClient;
MyGrid->FixedRows = 1;
MyGrid->FixedCols = 1;
MyGrid->RowCount = 5;
MyGrid->ColCount = 5;

MyGrid->OnGetEditStyle = MyGridGetEditStyle;
MyGrid->OnGetPickListItems = MyGridGetPickListItems;
MyGrid->OnEditButtonClick = MyGridEditButtonClick;

FStringList1->Append (L”リスト1-1”);
FStringList1->Append (L”リスト1-2”);
FStringList1->Append (L”リスト1-3”);

FStringList2->Append (L”リスト2-1”);
FStringList2->Append (L”リスト2-2”);
FStringList2->Append (L”リスト2-3”);
}

virtual __fastcall ~TForm1 ()
{
delete MyGrid;
delete FStringList1;
delete FStringList2;
}

void __fastcall MyGridGetEditStyle (int ACol, int ARow, TEditStyle& AStyle)
{
switch (ACol)
{
case 1:
case 2:
AStyle = esPickList;
break;

case 3:
AStyle = esEllipsis;
break;

default:
AStyle = esSimple;
}
}

void __fastcall MyGridGetPickListItems (int ACol, int ARow, TStrings* Items)
{
switch (ACol)
{
case 1:
Items->Assign (FStringList1);
break;

case 2:
Items->Assign (FStringList2);
break;
}
}

void __fastcall MyGridEditButtonClick (TObject *Sender)
{
if (OpenDialog1->Execute ())
{
MyGrid->Cells [MyGrid->Col][MyGrid->Row] =
OpenDialog1->FileName;
}
}
};

image

image

image

コンポーネントにしておけば、普段から簡単に使えるんじゃないかと思う。コンパイルには#include <Grids.hpp>が必要

| | コメント (0) | トラックバック (0)

2010-04-20

F1004 コンパイラの内部エラー (BCB6 + boost 1.33.1)

boostを使っていると、時々発生するようだ。

どうやら、インライン関数のオプションが関連しているらしい。

インライン展開しないようにするとなおるというサイトを見つけたが、インライン展開しないようにチェックがついていてもエラーが出る。

そこで、インライン展開させてみたらコンパイルが通った。

| | コメント (0) | トラックバック (0)

2010-02-13

子コントロールを持つコンポーネント

TBitBtnを二つ配置して、OKボタンとキャンセルボタンを持たせるようなコンポーネントを作成する時に、__property TBitBtn* OkButton = { read = FOkButton }; とかやっておくと、設計時にプロパティエディタでプロパティを設定する事はできるのだが、TBitBtnに関するプロパティは実行時に反映せず、プロパティの値も元に戻ってしまう。

__fastcall TMyPanel::TMyPanel (TComponent* Owner)
     : TPanel (Owner),
      FOkButton (new TBitBtn (this)),
      FCancelButton (new TBitBtn (this))
{
    FOkButton->SetSubComponent (true);
    FCancelButton->SetSubCmponent (true);
}

と子コントロールのSetSubComponenttureを渡してやる事で、設定が可能になる。

| | コメント (0) | トラックバック (0)

2009-12-05

BDEエリアスとTSession

BDEのエリアスからPATHを調べたい。

で、TSessionを使ってエリアスの一覧やエリアスの情報を得られますが、問題はこのTSessionの使い方です。
普通に TSession* session = new TSession (NULL); とかやって、セッション名を自動的につけるようにさせていました。

で、特定のエリアスのパスを返す関数を、実行時ライブラリにして、他のツールと共有しようと思った訳です。

まず、requiresに rtl.bpi, bdertl.bpi あたりが必要だったんですけど、これをコンパイルしたら普通にコンパイルが通って、パッケージライブラリと、インポートライブラリ、それから静的リンク用のライブラリとができあがったんですが、このパッケージライブラリを実行時ライブラリとして利用すると、bdertl.bplでメモリアクセス違反が出る。

で、どうやらTSessionList::AddSessionでTListにTThreadList.LockListを代入している所でエラーが起きてるようだ。
とりあえず、VCLはDelphiで、C++ではないが、こんな感じでbegin直後でエラーが起きるようだ。

DbTables.pas
procedure TSessionList.AddSession(ASession: TSession);
var
  List: TList;
begin
  List := FSessions.LockList;  { ここでエラー発生!! }
  try
    if List.Count = 0 then ASession.FDefault := True;
    List.Add(ASession);
  finally
    FSessions.UnlockList;
  end;
end;


で、調べてみたんですね。
そしたら、スレッドセーフにするため(?)に、Sessions変数のOpenSessionでオブジェクトを取得すればいいみたいですね。
この時、引数にセッション名を渡して、該当するセッションがあれば、そのセッションが返されて、該当セッションが見つからなければ、新しいセッションにその名前をつけて返してくれるらしい。
これが正しい使い方だったのか。

早速、パッケージを修正してから、サンプルプログラムを動かしたら、今度はエラーが出なくなった。
TSessionは基本的にはSessions変数からいただくものだったんですね。

ヤレヤレです。

ついでに見つけたんだが、borland\CBuilder6\source\vcl\Db.hppの1211行目あたりに、Currencyというプロパティがある。
TCurrencyFieldなんだが、TFloatFieldから派生している。
で、派生元クラスのTFloatFieldを見てみると、プロパティはcurrencyだ . . . 。
実際に、borland\cbuilder6\source\include\vcl\db.hppのTCurrencyField には小文字で書かれている。

C++では文字の大小を区別するので、これは別のプロパティとなる。
しかし、TCurrencyFieldでは、 __property Currency  = {default=1}; と型もなく書かれていて、試しにちょっと工夫してこれをコンパイルしてみると、やはりここで、宣言エラーが不正だというエラーが出ますね。
で、先頭のCを小文字のcに変更してみました。
コンパイルも無事通りました。

うぅむ。
なんで、include\vcl\db.hppとsource\vcl\db.hppが違うのかは、勉強不足なのか全然わからん。
同じファイルのコピーじゃダメなんだろうか?
windowsなのでdiff見ないな物の手持ちもないので、比較はしていませんが実際どうなんでしょうね。

この頃はborlandだったもんな。
会社名がよく変わるツールだな。
インプライズになってボーランドに戻って、コードギアになってから、エンバカデロだもんな。
バージョンによってインストールされているディレクトリが全然違うから、戸惑うんだよな。
エンバカデロになってからバージョンアップしてないから、どんなもんだかわからないけど . . . 。




| | コメント (0) | トラックバック (0)