이거 설치한다고 3일 걸렸다. T.T

너무 짜증이 나서 적어둔다.
나중에 또 잊어버리고 버벅거릴까봐서.

1) 먼저 2010용 ZEOS를 다운로드 받는다.
    http://sourceforge.net/projects/zeoslib/files/Zeos%20Database%20Objects/
    위 사이트에서 zeosdbo-7.0.0-alpha를 다운받는다.
    2010에서 ZEOS를 쓰려면 알파버전이지만 이것을 쓰는 방법밖에는 없는 것같다.

2) 압축을 풀고 압축을 푼 데이터를 아래 폴더에 복사한다.
    C:\Program Files\Embarcadero\RAD Studio\7.0\lib\ZeosLib
     (당연한 이야기지만 위 폴더는 사용자 마다 틀릴 수 있다.)

3) packages 폴더의 delphi14에 들어가
    ZeosDbo.groupproj 파일을 연다.

4) 델파이의 프로젝트 메니저의 ZeosDbo 그룹명에서 오른쪽 클릭을 하여
    Compile All을 한다.

5) 다시 ZeosDbo 그룹명에서 오른쪽 클릭을 하여
    Build All을 한다.

6) Delphi menu의 Tools > Options...를 선택하면 아래의 창이 표시된다.

Environment Options > Delphi Options > Library - Win32에서 Library를 선택하면
오른쪽에 Directories가 표시된다.

거기서 Library path 아래의 path를 입력한다.

    $(BDS)\Lib\ZeosLib\packages\delphi14\build
     (당연한 이야기지만 위 폴더는 사용자 마다 틀릴 수 있다.)

7) ZComponentDesign140.bpl에서 오른쪽을 클릭하여 Install을 해서 문제가 없으면 끝

그런데 여기서 문제없이 끝나주면 아주 행복한데
여기서 에러가 뜨기 시작해서 부터 이틀이 흘렀다.

보통 에러가 bpl을 찾을 수 없다고 한다.
그런데 웃기는 것은 에러 메세지 창의 표시된 폴더에는 bpl이 있다.
그럼 왜 이 문제가 생기는 것일까?

그것은 아래 그림의 빨강 테두리의 버튼을 눌러보면 알 수 있다.


버튼을 누르면 아래의 창이 뜬다.


저 빨강 테두리의 폴더 안에 작성한 BPL이 들어가 있어야지만 ZComponentDesign140.bpl을 인스톨 할 수 있다.


위 문제만 금방 해결되었으면 예전보다 ZeosLib 설치하는 것이 편해진 것같다.

-------------------------------------------

우리나라 홈페이지에서 이 정보를 열심히 찾아도 델마당에만 힌트가 조금 적혀있었다.
결국 이 수순은 유럽 말로 적혀있는 홈페이지를 보고 대략적인 수순을 이해하고

http://www.delphiaccess.com/forum/delphi/logre-instalar-zeos-7-en-delphi-2010/

그리고 에러가 나는 문제는 일본어로 적어둔 내용을 보고 알게되었다.

http://www.freeml.com/delphi-users/1163/latest

혹시 나처럼 고민하는 한국사람이 있을 것 같아서 적어본다.

이런 것을 설치하는데 걸리는 시간이 가장 아깝다.

Posted by 떡잎

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ShellApi, Menus;

const
  WM_NOTIFYICON = WM_USER + 333;

type
  TForm1 = class(TForm)
    PopMenu: TPopupMenu;
    Show1: TMenuItem;
    EXit1: TMenuItem;
    procedure EXit1Click(Sender: TObject);
    procedure Show1Click(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
    NotifyIcnData : TNotifyIconData;
    hMainIcon : HICON;

    procedure ClickTrayIcon(var msg: TMessage); message WM_NOTIFYICON;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;


implementation

{$R *.dfm}

// System Tray에 Icon의 Event 수신
procedure TForm1.ClickTrayIcon(var msg: TMessage);
var
    pt: TPoint;
begin
  case msg.lparam of
    WM_LBUTTONDBLCLK : Show;
    WM_RBUTTONDOWN :
      begin
        GetCursorPos(pt);
        PopMenu.Popup(pt.x, pt.y);
      end;
  end;
end;

procedure TForm1.EXit1Click(Sender: TObject);
begin
  Application.Terminate;
end;

// Form Close 했을 때
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  Action := caNone;
  Hide; // Form 숨기기
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  // System Tray에 Icon 표시
  hMainIcon := LoadIcon(MainInstance, 'MAINICON');

  Shell_NotifyIcon(NIM_DELETE, @NotifyIcnData);

  with NotifyIcnData do
  begin
    cbSize            := sizeof(TNotifyIconData);
    Wnd               := handle;
    uID               := 11111;
    uFlags            := NIF_MESSAGE or NIF_ICON or NIF_TIP;
    uCallbackMessage  := WM_NOTIFYICON;
    hIcon             := HMainIcon;
    szTip             := 'System Tray Test';
  end;

  Shell_NotifyIcon(NIM_ADD, @NotifyIcnData);
end;

procedure TForm1.Show1Click(Sender: TObject);
begin
  Show;
end;

end.




Posted by 띠리

// GetFileList : Sub Folder안의 File까지 검색하는 함수
//      slFileList : 반환하는 File List
//      sPath : 검색한 Root Folder
//      sMask : File 검색 Mask 설정
//              예) '*.txt', '*.exe'
//      bSubDir : SubFolder 검색 유무
procedure GetFileList(slFileList: TStringList;
                      sPath, sMask: string; bSubDir: boolean);
var
  i, iFindRst : integer;
  SrchRec : TSearchRec;
  slFolder : TStringList;
begin
  if sPath[length(sPath)] <> '\' then
    sPath := sPath + '\';

  // 지정 Foldr 안의 지정 Mask의 Full File path 수집
  iFindRst := FindFirst(sPath + sMask, faAnyFile - faDirectory, SrchRec);
  while iFindRst = 0 do
  begin
    slFileList.Add(sPath + SrchRec.Name);
    iFindRst := FindNext(SrchRec);
  end;
  FindClose(SrchRec);

  // Sub Folder List 수집
  slFolder := TStringList.Create;
  iFindRst := FindFirst(sPath + '*.*', faAnyFile, SrchRec);
  while iFindRst = 0 do begin
    if ((SrchRec.Attr and faDirectory) <> 0) and (SrchRec.Name[1] <> '.') then
      slFolder.Add(sPath + SrchRec.Name);
    iFindRst := FindNext(SrchRec);
  end;
  FindClose(SrchRec);

  // Sub Folder안 File 검색
  for i := 0 to slFolder.Count - 1 do
    GetFileList(slFileList, slFolder[i], sMask, bSubDir);

  slFolder.Free;
end;




procedure TForm1.Button1Click(Sender: TObject);
var
  slFiles : TStringList;
begin
  slFiles := TStringList.Create;
  GetFileList(slFiles, 'c:\data\', '*.txt', true); //

  memo1.Clear;
  memo1.Lines := slFiles;

  slFiles.Free;
end;

Posted by 띠리
DBGrid의 자료를 다시 표시할 때 코딩을 잘못하면 DBGrid가 깜박거리는 현상이 발생한다.

TDBGrid에 연결된 DataSource의 연결된 DataSet에 SQL이 바뀔 때 아래와 같이 하면
문제가 해결되었다.


  ZQuery1.DisableControls;
  ZQuery1.close;
  ZQuery1.SQL.Text := edit1.Text;
  ZQuery1.Open;
  ZQuery1.EnableControls;


개발환경
   Delphi2006
   ZeosLib 6.6.6
Posted by 떡잎
 Delphi에서 Firebird를 사용하기위한 무료 Component인 ZoesLib 설치하기
(ZoesLib는 Firebird 뿐 아니라 여러 다른 database도 지원한다.)

ZoesLib가 지원하는 databse들

• MySQL 3.20 - 5.0
• PostgreSQL 6.5 - 8.1
• Firebird 1.0 - 2.0
• Interbase 5.0 - 7.5
• Microsoft SQL Server 7, 2000
• Sybase ASE 12.0, 12.5
• Oracle 9i
• SQLite 2.8, 3.5

설치 SW version
  • Delphi 2006
  • Firebird 2.5
  • ZeosLib 6.6.6
1. ZeosLib 설치 순서

1) ZeosLib 사이트에서 ZeosLib를 Download한다.
http://sourceforge.net/projects/zeoslib/

2) Download한 파일의 압축을 푼다.
압축을 풀면 아래의 네개의 Folder가 만들어진다.
    - doc
    - examples
    - packages
    - src
3) Delphi가 설치된 곳의 Lib folder에 ZeosLib folder를 만들고 위의 네 folder를 복사해서 붙인다.
C:\Program Files\Borland\BDS\4.0\lib\ZeosLib

4) Packages folder의 delphi11 folder에서 groupproj를 열고 싶었지만 Delphi 2006에서는 열 수 없어서 아래의 dpk file들을 delphi에서 하나씩 열었다.
• ZCore.dpk
• ZParseSql.dpk
• ZPlain.dpk
• ZDbc.dpk
• ZComponent.dpk
그리고 위의 순서대로 아래의 그림과 같이 각 project에서 오른쪽 click을 하여 compile을 한다.


5) 위 compile을 마친 후 ZComponentDesign.dpk를 열어서 Compile한 후 Install을 한다.
그러면 아래와 같이 Form에 붙여서 사용할 수 있는 Component가 표시된다.


6) Delphi menu의 Tools > Options...를 선택하면 아래의 창이 표시된다.

Environment Options > Delphi Options > Library - Win32에서 Library를 선택하면
오른쪽에 Directories가 표시된다.

거기서 Library path, Borwsing Path, Debug DCU path에 아래의 path를 입력한다.

    ;C:\Program Files\Borland\BDS\4.0\lib\ZeosLib\src\component
    ;C:\Program Files\Borland\BDS\4.0\lib\ZeosLib\src\core
    ;C:\Program Files\Borland\BDS\4.0\lib\ZeosLib\src\dbc
    ;C:\Program Files\Borland\BDS\4.0\lib\ZeosLib\src\parsesql
    ;C:\Program Files\Borland\BDS\4.0\lib\ZeosLib\src\plain

(주의 : ZeosLib를 어느 folder에 복사했는지에 따라 위 path는 변경된다.)



7) Windows folder의 system folder에 사용하고자 하는 database의 client dll을 복사해서 붙여넣어야 된다.

Firebird의 경우 : Firebird가 설치된 folder의 bin folder에 fbclient.dll를 Windows의 system folder에 복사하여 붙여넣는다.
(default path에 설치한 경우 : C:\Program Files\Firebird\Firebird_2_5\bin)

2. ZeosLib 간단 사용법

1) Form에 먼저 Zeos Access에서 TZConnection을 붙여넣는다.


Database : Firebird Database file path를 입력한다.
Password : SYSDBA의 password를 변경하지 않았을 경우 masterkey를 입력한다.
Protocol : firebird-2.1을 선택한다.(2.5도 지원은 되는 것 같음)
User : Firebird의 기본 User 명을 변경하지 않았으면 SYSDBA를 입력한다.
Connected : true로 설정한다.

2) Form에 Zeos Access에서 TZQuery를 붙여넣는다.


Connection : 1)에서 설정한 TZConnection의 name을 선택한다.
SQL : SQL문을 입력한다. (예: select * from table명 )
Active : true로 설정한다.

3) Form에 Data Access에서 TDataSource를 붙여넣는다.


DataSet : 2)에서 설정한 TZQuery의 name을 선택한다.

4) Form에 Data Controls에서 TDBGrid를 붙여넣는다.


DataSource : 4)에서 설정한 TDataSource의 name을 선택한다.



5) F9를 눌러 Run을 하면 아래와 같이 Table에 있는 내용들이 표시된다.


Coding 없이 property 설정만으로 이렇게 Database 내용을 볼 수 있다.

----------------------

오늘 하루 종일 Firebird 설치하고 사용방법 정리하다가 하루가 다가는군
몇 일지나면 바로 잊어버려서 우선 설치 방법과 사용방법을 정리


Delphi 2010인 경우는 아래 link 참조

윈도7 델파이 2010에서 Zeos 빌드하기


Posted by 떡잎




 

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Contnrs;

type

  // ObjectList에 추가할  Object
  TMyObj = class(TObject)
  private
    FiState : integer;
    FsId : string;
    FiTemp : integer;
  public
    function Cal(iTemp: integer): integer;
  published
    property State : integer read FiState write FiState;
    property ID : string read FsId write FsId;
  end;

  TForm1 = class(TForm)
    btnCreate: TButton;
    btnAdd: TButton;
    Edit1: TEdit;
    Memo1: TMemo;
    btnObjList: TButton;
    procedure btnObjListClick(Sender: TObject);
    procedure btnAddClick(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure btnCreateClick(Sender: TObject);
  private
    { Private declarations }
    ol : TObjectList;  // ObjectList 정의
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

{ TPjObj }

function TMyObj.Cal(iTemp: integer): integer;
begin
  result := iTemp * 2;
end;

procedure TForm1.btnCreateClick(Sender: TObject);
begin
  // ObjectList 생성
  ol := TObjectList.Create(true);
end;

procedure TForm1.btnObjListClick(Sender: TObject);
var
  i : integer;
begin
  // Object List에 추가한 Object의 Property 표시
  for i := 0 to ol.Count - 1 do
    memo1.Lines.Add((ol.Items[i]as TMyObj).ID);
end;

procedure TForm1.btnAddClick(Sender: TObject);
var
  po : TMyObj;
begin
  // Object List에 추가할 Object 생성
  po := TMyObj.Create;
  po.ID := edit1.Text;
  // Object List에 Object 추가
  ol.Add(po);
  //po.Free;  <- Free하면 안됨
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  // Object List 개방
  ol.Free;
end;

end.


Object List를 사용하려면 Contnrs를 uses에 추가해야 됨
Object List에 추가할 Object를 생성한 후 소멸시키지 않아도 되고
생성한 후 소멸시켜서도 안된다. ^^;;

프로그램이 죽을 때 Object List를 Free해 주면
추가한 모든 Object가 자동으로 소멸되어진다.

ObjectList에 추가한 Object의 Property나 Method를 사용할 때는
위 소스의 TMyObject로 예를들면 아래와 같이 쓸 수 있다.

    (ol.Items[i] as TMyObj).ID
    TMyObj(ol.Items[i]).ID
 
 

Posted by 떡잎



unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Button3: TButton;
    Edit1: TEdit;
    procedure Button3Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }

    procedure WMRecvData(var Msg: TWMCopyData); message WM_USER + 100;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button3Click(Sender: TObject);
var
  sMsg : string;
  cds : TCopyDataStruct;
begin
  sMsg := edit1.Text;

  cds.dwData := 0; // Identify the message contents
  cds.cbData := 1 + Length(sMsg);
  cds.lpData := PChar(sMsg);

  SendMessage(Handle, WM_USER + 100, 0, Integer(@cds));
end;



 

procedure TForm1.WMRecvData(var Msg: TWMCopyData);
var
  sMsg : string;
begin
  sMsg := PChar(Msg.CopyDataStruct.lpData);

  self.Caption := sMsg;
end;

end.


-----------------------

이젠 귀찮으니까 이렇게 올리네 -.-;;
그래도 나중 되면 잊어버리니까 이렇게라도 써두면
잊어버리면 이거보면 생각나겠지.
아마도...

Posted by 떡잎
델파이에서 외부 OCX를 사용하는 방법을 몰라 이틀 동안 해맸다.

델파이에서 외부 OCX를 사용하려면 OCX를 등록해야된다.
(지금 생각하면 당연한 것인데 왜 몇일 전에는 그리도 해맨걸까?)

그런데 등록하는 법이 내가 생각한 것이랑 조금 틀렸다.

Component > Import Componenet ...

Import Component만 하면 되는줄 알았는데
Import Component하면 정상적으로 외부 OCX가 등록되지 않는 것 같다.

외부 OCX를 등록하려면 Package 프로젝트를 만들고
그 프로젝트에서 Import Component를 한 후
Package 프로젝트에서 오른쪽 클릭을 하고
Install을 하면 외부 OCX가 Tool Palette에 등록된다.

자세한 내용은 아래 링크 참조
http://www.ciansoft.com/support/delphi2005install.htm

그냥 그림만 봐도 대충 이해가된다.
Posted by 떡잎

IntToBool, BoolToInt함수가 필요해서 인터넷을 찾아보니 나름 깔끔한 소스가 있었다.


function BoolToInt(const Value: Boolean): Integer;
begin
  Result := Ord(Value);
end;

 

function IntToBool(const Value: Integer): Boolean;
begin
  Result := Value <> 0;
end;

 

*   BOOL in Delphi    Boolean in Delphi 
 original Type LongBool compiler magic
 size in bytes 4 1
false 0 0
true -1 ($FFFFFFFF) 1

Bool하고 Boolean하고 값이 정수로 변형할 때 값이 틀려진다.
Posted by 떡잎
델파이에서 XML에 CRLF를 쓰고 읽으려고 하면
CRLF를 써도 읽어지는 것은 LF만 읽어진다.

인터넷에서 열심히 뒤져 봐도 뾰족한 대안을 못찾았다.

그래서 생각해낸 방법은 LF만 있을 경우 LF를 모두 CRLF로 바꾸면 된다.

먼저 LF만 있는지 확인하는 방법


function CheckOnlyLF(sSrc: string): boolean;
var
  iCrLf, iLf : integer;
begin
  result := false;

  iCrLf := Pos(#13 + #10, sSrc);
  iLf := Pos(#10, sSrc);

  if (iCrLf = 0) and (iLf > 0) then result := true;
end;

이 소스는 LF를 하나만 검색하면 그냥 나와버린다.

그리고 LF를 모두 CRLF로 변경하려면 간단하게 할 수 있다.

function LfToCrLf(sSrc: string): string;
begin
  if CheckOnlyLF(sSrc) = true then
    result := StringReplace(sSrc, #10, #13+#10, [rfReplaceAll, rfIgnoreCase]);
end;

이 함수에도 좀 문제가 있을 수 있다.
문자열에 LF와 CRLF가 섞여있으면
CRCRLF가 되어 버린다. -.-;;
하기야 이렇게 표시에는 문제가 없지만 문자가 하나 더 추가되는 것이 찜찜하면
모든 문자열을 일일히 검색하면서 CRLF인지 LF인지를 검색하는 수 밖에 없다.

이렇게 까지하는 것은 귀찮아서 생략
혹시 그렇게 프로그램을 짜신 분은 트랙백해주세요. ^^;


Posted by 떡잎
BLOG main image
프로그래밍 공부하면서 써가는 개인 노트 (따라서 여기에 씌여있는 소스의 신빙성을 보장 못함 -.-;;) 이 블로그 보면서 틀린 점이 있으면 꼬옥 알려주세요. by 띠리

공지사항

카테고리

분류 전체보기 (323)
Win32 SDK 초보 (27)
통신관련 (11)
MFC TIP (20)
C/C++ TIP (10)
개발기타 (10)
링크 (2)
견물생심 (24)
이것저것 (8)
용어메모 (3)
데이터베이스 (32)
비주얼 베이직 (10)
하드웨어 (3)
C# (42)
Xcode (3)
델파이 (82)
홈페이지 (5)
MindStorm (0)
낙서 (5)
스크래치 (0)
기타 (6)
아두이노 (1)
라즈베리파이 (2)
안드로이드 (6)
파이썬 (0)
WEB (2)
Excel VBA (0)
Total : 1,005,830
Today : 17 Yesterday : 380