[RadPHP]ListViewやDBGridの行に色やフォントを設定する

RadPHP XEでListViewやDBGridの行に色やフォントを設定する方法を紹介します。

ListViewやDBGridの行に色やフォントを設定するには、qx.ui.table.DefaultDataRowRendererを使用します。

var renderer = new qx.ui.table.DefaultDataRowRenderer();

行の色情報を設定するには、setRowColors()メソッドを使用します。

var rowColors1 = {  //行の色設定
  colNormal:'blue',  //標準の文字色
  colSelected: 'red', //選択行の文字色
  bgcolEven: '#FFC6E2', //奇数行の背景色
  bgcolOdd: '#E2FFc6',  //偶数行の背景色
  bgcolFocusedSelected: '#000000',     //行にフォーカスあり グリッドにフォーカスあり 行選択
  bgcolFocusedSelectedBlur: '#555555', //行にフォーカスあり グリッドにフォーカスなし 行選択
  bgcolFocused: '#FFFFFF',             //行にフォーカスあり グリッドにフォーカスあり 行未選択
  bgcolFocusedBlur: '#000000',         //行にフォーカスあり グリッドにフォーカスなし 行未選択
  bgcolSelected: '#00FF00',            //行にフォーカスなし グリッドにフォーカスあり 行選択
  bgcolSelectedBlur: '#009900',        //行にフォーカスなし グリッドにフォーカスなし 行選択
};
renderer.setRowColors(rowColors1);

フォント名を設定するには、setFontFamilyメソッドを使用します。

renderer.setFontFamily("'MS 明朝', 'sans-serif'");  //フォント名

フォントサイズを設定するには、setFontSize()メソッドを使用します。

renderer.setFontSize('14px'); //フォントサイズ

DefaultDataRowRendererの設定ができたら、ListViewのsetDataRowRendererメソッドで登録します。

ListView1.setDataRowRenderer(renderer);

次のコードはListView(ListView1)の行に色を設定するコードです。

フォームにListViewを配置します。

フォームのEncodingを「Unicode (UTF-8)」にします。

ListViewのColumnsプロパティを設定します。

製品名
配布形態
金額

フォームのJavaScriptのOnLoadイベントに以下のコードを記述します。

function Unit1JSLoad($sender, $params)
{
    ?>
    //begin js
//行データの登録
var rowData = [['RAD Studio XE Professional (ライセンス+メディア)', 'DVD', 168000],
               ['RAD Studio XE Professional ESD バージョンアップ (ライセンスのみ)', 'ESD(ライセンスのみ)', 84000],
               ['Delphi XE Professional (ライセンス+メディア)', 'DVD', 98000],
               ['Delphi XE Professional ESD バージョンアップ (ライセンスのみ)', 'ESD(ライセンスのみ)', 52000],
               ['Delphi XE Starter ESD(ライセンスのみ) アップグレード版', 'ESD(ライセンスのみ', 14000],
               ['C++Builder XE Professional (ライセンス+メディア)', 'DVD', 98000],
               ['C++Builder XE Professional ESD バージョンアップ (ライセンスのみ)', 'ESD(ライセンスのみ)', 52000],
               ['C++Builder XE Starter ESD(ライセンスのみ) アップグレード版', 'ESD(ライセンスのみ)', 14000],
               ['RadPHP XE (ライセンス+メディア)', 'DVD', 36000],
               ['RadPHP XE ESD (ライセンスのみ) バージョンアップ', 'ESD(ライセンスのみ)', 20000]];
ListView1.getTableModel().addRows(rowData);

//列幅の調整
var tcm = ListView1.getTableColumnModel();
tcm.setColumnWidth(0, 300);
tcm.setColumnWidth(1, 140);
tcm.setColumnWidth(2, 100);

//行の色の設定
var renderer = new qx.ui.table.DefaultDataRowRenderer();
var rowColors1 = {  //行の色設定
  colNormal:'blue',  //標準の文字色
  colSelected: 'red', //選択行の文字色
  bgcolEven: '#FFC6E2', //奇数行の背景色
  bgcolOdd: '#E2FFc6',  //偶数行の背景色
  bgcolFocusedSelected: '#000000',     //行にフォーカスあり グリッドにフォーカスあり 行選択
  bgcolFocusedSelectedBlur: '#555555', //行にフォーカスあり グリッドにフォーカスなし 行選択
  bgcolFocused: '#FFFFFF',             //行にフォーカスあり グリッドにフォーカスあり 行未選択
  bgcolFocusedBlur: '#000000',         //行にフォーカスあり グリッドにフォーカスなし 行未選択
  bgcolSelected: '#00FF00',            //行にフォーカスなし グリッドにフォーカスあり 行選択
  bgcolSelectedBlur: '#009900',        //行にフォーカスなし グリッドにフォーカスなし 行選択
};
renderer.setRowColors(rowColors1);
renderer.setFontFamily("'MS 明朝', 'sans-serif'");  //フォント名
renderer.setFontSize('14px'); //フォントサイズ
ListView1.setRowHeight(20);  //行の高さ
ListView1.setDataRowRenderer(renderer);
    //end
    <?php
}

MySQL ODBCデータソースを削除しようとすると”Invalid attribute string”になるときの対処法

MySQL ODBCデータソースを削除しようとすると”Invalid attribute string”になるときの対処法について。

“Invalid attribute string”はmysql-connector-odbc-5.1.7-win32の不具合のようですね。

以下の手順で、Infobright.org Forumで公開されているmyodbc5S.dllを差し替えることで、正しく動作するようになります。

  1. Infobright.org Forumからmyodbc5S.zipをダウンロードする。
  2. ダウンロードしたmyodbc5S.zipを展開する。
  3. myodbc5S.dllをC:\Program Files\MySQL\Connector ODBC 5.1\myodbc5S.dllと差し替える。

最新版のConnector/ODBC 5.1.8にバージョンアップしてもいいかもしれません。

[C++Builder]リストボックスの複数選択(複数選択と拡張選択)

リストボックスには、複数選択と拡張選択の二種類の複数選択の方法があります。

  • 複数選択
    ユーザーが項目をクリックするだけで複数の項目を選択できる。
  • 拡張選択
    [Shift]キーや[Ctrl]キーを使いながら連続する項目や連続しない項目を選択できる。

選択方法は、TListBoxのExtendedSelectプロパティで設定します。
ExtendedSelectプロパティの値がtrueのときは拡張選択、falseのときは複数選択になります。
ExtendedSelectプロパティの初期値はtrueです。

当然のことですが、複数の項目を選択可能にするにはMultiSelectプロパティがtrueである必要があります。

選択されている項目の数を取得するにはSelCountプロパティ、項目が選択されているかどうかを調べるにはSelectedプロパティを使用します。

[C++Builder] TMultiReadExclusiveWriteSynchronizerでRead-Write Lockパターン

TMultiReadExclusiveWriteSynchronizerを使用すると、保護されたメモリから複数のスレッドが同時に読み出すことを可能とし、かつメモリに書き込むスレッドは排他的にアクセスできます。

TMultiReadExclusiveWriteSynchronizerを使うには、まずグローバルインスタンスを作成します。

std::unique_ptr<TMultiReadExclusiveWriteSynchronizer> ReadWriteLock(new TMultiReadExclusiveWriteSynchronizer());

読み取りを行うスレッドでは、読み込む時はBeginReadメソッド、読み取りが終わったらEndReadメソッドを読み出します。

ReadWriteLock->BeginRead();
//ここで読み取り処理
ReadWriteLock->EndRead();

書き込みを行うスレッドでは、書き込む時はBeginWriteメソッド、書き込みが終わったらEndWriteを読み出します。

ReadWriteLock->BeginWrite();
//ここで書き込み処理
ReadWriteLock->EndWrite();

以前に書いた「Read-Write Lockパターン」もTMultiReadExclusiveWriteSynchronizerを使うと、ずっと簡単に書くことができました。

#include <tchar.h>
#include <iostream>
#include <memory>
#include <string>

//スレッドセーフな出力
std::unique_ptr<TCriticalSection> CriticalSection(new TCriticalSection);
void Print(const std::string& S)
{
  CriticalSection->Acquire();
  std::cout << S << std::endl;
  CriticalSection->Release();
}

//TDataクラス
//ゆっくりと読み書きを行う
class TData
{
public:
  TData(int Count) : FBuffer(std::string(Count, '*')) {}
  std::string Read() {
    Sleep(50);
    return FBuffer;
  };
  void Write(char C) {
    for (std::string::size_type i = 0; i < FBuffer.size(); ++i)
    {
      FBuffer[i] = C;
      Sleep(50);
    }
  }
private:
  std::string FBuffer;
};

//グローバルインスタンスを作成します。
std::unique_ptr<TMultiReadExclusiveWriteSynchronizer> ReadWriteLock(new TMultiReadExclusiveWriteSynchronizer());

//読み出しスレッド
class TReaderThread : public TThread {
public:
  __fastcall TReaderThread(std::string Name, TData* Data) : TThread(false), FName(Name), FData(Data) {}
protected:
  void __fastcall Execute() {
    while (true) {
      ReadWriteLock->BeginRead(); //読み取り前
      std::string readbuf = FData->Read();
      ReadWriteLock->EndRead(); //読み取り終了
      Print(FName + " reads " + readbuf);
    }
  }
private:
  const std::string FName;
  TData* FData;
};
//書き込みスレッド
class TWriterThread : public TThread {
public:
  __fastcall TWriterThread(TData* Data, std::string Filter)
       : TThread(false), FData(Data), FFilter(Filter), FIndex(0) {}
protected:
  void __fastcall Execute() {
    while (true) {
      ReadWriteLock->BeginWrite(); //書き込み前
      FData->Write(NextChar());
      ReadWriteLock->EndWrite(); //書き込み終了
      Sleep(random(3000));
    }
  };
private:
  TData* FData;
  const std::string FFilter;
  unsigned int FIndex;
  char NextChar() {
    char c = FFilter[FIndex];
    FIndex++;
    if (FIndex >= FFilter.size()) FIndex = 0;
    return c;
  };
};
int _tmain(int argc, _TCHAR* argv[])
{
  TData* data = new TData(10);
  new TReaderThread("TReaderThread-1", data);
  new TReaderThread("TReaderThread-2", data);
  new TReaderThread("TReaderThread-3", data);
  new TReaderThread("TReaderThread-4", data);
  new TReaderThread("TReaderThread-5", data);
  new TReaderThread("TReaderThread-6", data);
  new TWriterThread(data, "ABCDEFGHIJKLMNOPQRSTUVWXYZ");
  new TWriterThread(data, "abcdefghijklmnopqrstuvwxyz");

  Sleep(INFINITE);
  return 0;
}