Translate

2013/06/14

ClientDataSet上使用GROUP BY篩選

ClientDataSet對已經收到的資料集是不能再下SQL語法篩選的。

不過,把GROUP BY的邏輯想通應該也可以如法泡製。

直接把結果轉出來吧!

2013/06/13

Delphi繼承的寫法

底下的連結提供了相當多的解法,有時需要改裝一下TCustomForm時可以來參考使用。

資料來源:Delphi/pascal: overloading a constructor with a different prototype

Delphi 2009 raises Exception in DBX: Unknown Driver XXX

在Design Mode下使用TSQLConnection,設定完成後也可以正常連線,可是在Runtime硬是出現「Unknown Driver: MSSQL」。

其實這只要在uses區手動加入「DBXDynalink」,就可以用了。

資料來源:Delphi 2009 raises Exception "Unknown Driver: Devart..."

2013/06/10

EAccessViolation in function CreateProcess in Delphi 2009

很有趣的,我也遇到了這件事情,明明 CreateProcess 這函式在Delphi 7時就正常,到了Delphi 2009就出怪手了。

原因就是出在Unicode……解法轉貼如下:

2013/06/06

DBGrid scrolling (滾動條事件) 生成

C++ Builder的DBGrid比較麻煩,可以的話還是從Delphi建一個後再使用帶入使用吧。
/* JDBGrid.h文件内容 */
//-------------------------------------------------------------------------
#ifndef JDBGridH
#define JDBGridH
//-------------------------------------------------------------------------
#include 
#include 
#include 
#include 
#include 
//-------------------------------------------------------------------------
class PACKAGE TJDBGrid : public TDBGrid
{
  enum TDBGridOption{ dgEditing, dgAlwaysShowEditor,
                      dgTitles, dgIndicator, dgColumnResize,
                      dgColLines, dgRowLines, dgTabs,
                      dgRowSelect, dgAlwaysShowSelection,
                      dgConfirmDelete, dgCancelOnExit,
                      dgMultiSelect ,dgThumbTracking,dgMouseWheel};
typedef Set  TDBGridOptions;
  private:
    TDBGridOptions FOptions;
  protected:
    TWndMethod DBGridProc;
    TWndMethod DBInplaceEditProc;
    virtual void __fastcall JDBInplaceEditProc(Messages::TMessage &Message);
    virtual void __fastcall JDBGridProc(Messages::TMessage& Message);
    virtual Grids::TInplaceEdit* __fastcall CreateEditor(void);
    void __fastcall SetOptions(TDBGridOptions Value);
  public:
    __fastcall TJDBGrid(TComponent* Owner);
    __published:
    __property TDBGridOptions Options = {read=FOptions, write=SetOptions,default=27901};
};
//-------------------------------------------------------------------------
#endif

/* JDBGrid.cpp文件内容 */
//-------------------------------------------------------------------------
#include 
#pragma hdrstop
#include "JDBGrid.h"
#pragma package(smart_init)
//-------------------------------------------------------------------------
static inline void ValidCtrCheck(TJDBGrid *)
{
  new TJDBGrid(NULL);
}
//-------------------------------------------------------------------------
fastcall TJDBGrid::TJDBGrid(TComponent* Owner):TDBGrid(Owner)
{
  short *shortTmp;
  Dbgrids::TDBGridOptions optionsTmp;
  (void*)shortTmp=(void*)&FOptions;
  *shortTmp=27901;
  (void*)shortTmp=(void*)&optionsTmp;
  *shortTmp=3325;
  TDBGrid::Options=optionsTmp;
  DBGridProc=WindowProc;
  WindowProc=JDBGridProc;
}
//-------------------------------------------------------------------------
void __fastcall TJDBGrid::SetOptions(TDBGridOptions Value)
{
   short *pValue,*pOp,*pFOp,saveValue;
   Dbgrids::TDBGridOptions DBGridOptions;
   (void*)pValue=(void*)&Value;
   (void*)pOp=(void*)&DBGridOptions;
   (void*)pFOp=(void*)&FOptions;
   *pOp=*pValue & 0x1fff;
   TDBGrid::Options=DBGridOptions;
   DBGridOptions=TDBGrid::Options;
   *pFOp=*pOp | (*pValue & 0x6000);
}

//-------------------------------------------------------------------------
void __fastcall TJDBGrid::JDBInplaceEditProc(Messages::TMessage &Message)
{
   switch (Message.Msg)
   {
      case WM_MOUSEWHEEL:
         if(Options.Contains(dgMouseWheel))
         {
            if (DataLink->Active)
            {
               if (Message.WParam<0)
               {
                if (DataLink->DataSet->RecNoDataSet->RecordCount)
                DataLink->DataSet->RecNo++;
               }
               else
               {
                  if (DataLink->DataSet->RecNo>1)
                     DataLink->DataSet->RecNo--;
               }
            }
            if (!Options.Contains(dgAlwaysShowEditor))
               EditorMode=false;
            return;
         }
      break;
   }
   DBInplaceEditProc(Message);
}
//-------------------------------------------------------------------------
Grids::TInplaceEdit* __fastcall TJDBGrid::CreateEditor(void)
{
   TInplaceEdit *tmp;
   tmp=TDBGrid::CreateEditor();
   DBInplaceEditProc=tmp->WindowProc;
   tmp->WindowProc=JDBInplaceEditProc;
   return tmp;
}
//-------------------------------------------------------------------------
void __fastcall TJDBGrid::JDBGridProc(Messages::TMessage& Message)
{
   switch (Message.Msg)
   {
      case WM_VSCROLL:
      case WM_HSCROLL:
         if (Options.Contains(dgThumbTracking))
            if (Message.WParamLo==5)
            {
               DBGridProc(Message);
               Message.WParamLo=4;
               DBGridProc(Message);
               Message.WParam=8;
            }
         break;
      case WM_MOUSEWHEEL:
         if(Options.Contains(dgMouseWheel))
         {
            DBGridProc(Message);
            if (DataLink->Active)
            {
               if (Message.WParam<0)
               {
                 if (DataLink->DataSet->RecNoDataSet->RecordCount)
                   DataLink->DataSet->RecNo++;
               }
               else
               {
                 if (DataLink->DataSet->RecNo>1)
                   DataLink->DataSet->RecNo--;
               }
            }
            if (!Options.Contains(dgAlwaysShowEditor))
              EditorMode=false;
            return;
         }
      break;
   }
   DBGridProc(Message);
}
//-------------------------------------------------------------------------
namespace Jdbgrid
{
        void __fastcall PACKAGE Register()
        {
                 TComponentClass classes[1] = {__classid(TJDBGrid)};
                 RegisterComponents("Samples", classes, 0);
        }
}
//-------------------------------------------------------------------------


/* 技巧三,行列不同颜色时,交叉部位颜色的设置。
   如图:在交叉部位使用行列颜色的alpha混合。
   响应TDBGrid的OnDrawColumnCell事件如下:*/
void __fastcall TForm1::JDBGrid1DrawColumnCell(TObject *Sender,
      const TRect &Rect, int DataCol, TColumn *Column,
      TGridDrawState State)
{
  int recordNo,tmpInt;
  if (JDBGrid1->DataSource->DataSet->Active)
  {
    recordNo=DataCol=JDBGrid1->DataSource->DataSet->RecNo % 10;
    if (recordNo ==0 || recordNo>5 )
       JDBGrid1->Canvas->Brush->Color=0xb0b0ff;
    else
       JDBGrid1->Canvas->Brush->Color=0xffe0e0;
    tmpInt=Column->Color;
    if (tmpInt!=clWindow)
    {
        int R1,G1,B1,R2,G2,B2,rgbTmp;
        int alpha=60;
        rgbTmp=JDBGrid1->Canvas->Brush->Color;
        R1=tmpInt & 0xff;
        G1=(tmpInt & 0xff00)>>8;
        B1=(tmpInt & 0xff0000)>>16;
        R2=rgbTmp & 0xff;
        G2=(rgbTmp & 0xff00)>>8;
        B2=(rgbTmp & 0xff0000)>>16;
        R1=(R1*alpha+R2*(256-alpha))>>8;
        G1=(G1*alpha+G2*(256-alpha))>>8;
        B1=(B1*alpha+B2*(256-alpha))>>8;
        JDBGrid1->Canvas->Brush->Color=(TColor)(R1+(G1<<8)+(B1<<16));
    }
    JDBGrid1->Canvas->FillRect(Rect);
  }
  JDBGrid1->DefaultDrawColumnCell(Rect,DataCol,Column,State);
}


Delphi就相當簡單,直接繼承就可以用了。
uses Message;
type
  TDBGrid = class(DBGrids.TDBGrid)
  private
    procedure WmVScroll(var Message: TWMVScroll); message WM_VSCROLL;
  end;

  TForm1 = class(TForm)
    DBGrid1: TDBGrid;
    ..

implementation

procedure TDBGrid.WmVScroll(var Message: TWMVScroll);
begin
  if Message.ScrollCode = SB_THUMBTRACK then
    Message.ScrollCode := SB_THUMBPOSITION;
  inherited;
end;


如此一來,DBGrid的滾動條在拉動的過程中,DataSet的RecNo也會跟著一起調整,十分好用的小技巧。

參考來源:
TDBGRID一些小技巧
Delphi dbgrid continuous scrolling
Winapi.Messages.TWMVScroll

DBX framework 初探

DBX 框架在官方手冊裡有句話引起我的注意: Currently, using a TDBXValue is the fastest way to pass a parameter, because these are the internal objects used...