델파이에서 동적으로 배열 컨트롤을 만들었을 때의 컨트롤 유무 체크 하는 방법

VB에서는 어떤 오브젝트가 생성되었는지 안되었는지 알기위해서는
IsObject라는 함수가 있다.

델파이에서는 배열 컨트롤이 있는지 없는지 체크하기 위해서는
밑의 소스처럼 is를 사용수 있다.


procedure TForm2.Button1Click(Sender: TObject);
begin

  if btnD[3] is TObject then
    btnD[3].Caption := 'ttttt';

end;

Posted by 띠리


시리얼 포트 오픈

시리얼 포트는 파일처럼 다룬다.
시리얼 포트를 오븐 하기위해서는 CreateFile()을 사용한다.

HANDLE CreateFile(
  LPCTSTR lpFileName,         // 포트 이름을 가르키는 버퍼의 포인터
  DWORD dwDesiredAccess,       // 억세스모드(READ, WRITE)
  DWORD dwShareMode,          // 포트의 공유 방법 비정(공유 불가: 0으로 설정)
  LPSECURITY_ATTRIBUTES lpSecurityAttributes, // 시큐리티 속성
  DWORD dwCreationDisposition,  // 포트 여는 방법 지정(OPEN_EXISTING로 기존 파일 지정)
  DWORD dwFlagsAndAttributes,   // 포트의 속성 지정
  HANDLE hTemplateFile          // 템플레이트 파일의 핸들(항상 NULL로 지정)
 );


인수:

lpFileName: COM1이나 COM2등의 시리얼 포트 이름을 지정한다.
(LPT1같은 프린터 포트도 지정할 수 있다.)

dwDesiredAccess: 이하의 읽기 모드를 단독 또는 OR로 지정한다.

의미
0 디바이스의 속성을 묻는다.
GENERIC_READ 읽기 억세스.
읽기 쓰기를 할때는 GENERIC_WRITE를 조합해서 지정
GENERIC_WRITE 쓰기 억세스.
쓰기 쓰기를 할때는 GENERIC_READ를 조합해서 지정

일반적으로 시리얼 포트는 입출력이 가능하기 때문에 GENERIC_READ | GENERIC_WRITE로 설정한다.

dwShareMode : 포트의 공유모드로 이하의 값을 단독이나 OR로 지정한다.
0을 지정하면 공유하지 않는다.
 
 
의미
FILE_SHARE_DELETE Windows NT 일 경우만 : 
후속의 오픈 조작으로 삭제 억세스가 요구될 때, 그 오픈을 허가
FILE_SHARE_READ 후속의 호픈 조작으로 읽기 억세스가 요구될 때 그 오픈을 허가
FILE_SHARE_WRITE 후속의 호픈 조작으로 쓰기 억세스가 요구될 때 그 오픈을 허가

 
 포트는 파일과 달리 공유할수 없기 때문에 0으로 지정한다. 이 경우는 이미 오픈 되어진 포트를 다른 프로세스가 오픈 하려고 하면 CreateFile()은 에러가 된다. 하지만 같은 프로세스의 복수 스레드는 CraeteFile()로 반환된 핸들을 공유할 수 있다.

lpSecurityAttributes : 시큐리티 속성으로 SECURITY_ATTRIBUTES 구조체의 포인터이다.
NULL을 설정하면 핸들은 자식 프로세스에 계승되어지지않는다.

dwCreationDisposition : 파일이 존재할 때 또는 존재하지 않을 때, 각각의 동작을 지정한다.
시리얼 포트는 기존 파일 이외에 있을 수 없기 때문에 OPEN_EXISTING을 지정한다.

dwFlagsAndAttributes : 파일의 속성 및 플래그를 지정한다.
시리얼 포트에서 사용할만한 플래그는 FILE_FLAG_OVERLAPPED 뿐이다.

의미
FILE_FLAG_OVERLAPPED 시간이 걸리는 처리에 있어서 ERROR_IO_PENDING을 반환하도록 한다. 처리가 끝나면 이벤트가 시그널 상태로 설정된다.
이 플래그를 지정했을 때는 ReadFile 함수나 WriteFile 함수로 OVERLAPPED 구조체를 지정해야만 된다.


hTemplateFile : 시리얼 포트에 관계없기 때문에 NULL을 지정한다.


시리얼 포트 클로즈

클로즈는 CreateFile()이 반환하는 핸들을 인수로 하여 CloseHandle을 호출한다.

BOOL CloseHandle( HANDLE hObject );


반환값 : 성공하면 0 이외의 값, 실패하면 0을 반환한다.

시리얼 포트 상태 정보 얻기

자신의 컴퓨터에 시리얼 포트는 어느 정도의 성능인지 등 보통은 신경쓰지않지만 디바이스 드라이버를 포함한 시리얼 포트의 성능을 앎으로 서포트 하지않는 보레이트를 잘못해서 설정했을 때의 부정한 설정을 막아준다.

시리얼 포트에 관한 정보는 GetCommProperties()의 호출로 COMPROC 구조체 변수를 읽어온다.

BOOL GetCommProperties (HANDLE hFile, LPCOMMPROP lpCommProp );


인수 :

hFile : 통신 디바이스의 핸들
CreateFile함수가 반환하는 핸들

lpCommProp : 통신 특성 정보가 반환되어 COMPROC 구조체의 포인터

반환값 : 함수가 성공하면 0 이외의 값, 실패하면 0을 반환한다.

LPCOMMPROP 구조체는 이하의 구성의 시리얼 포트 정보를 가진다.

typedef struct _COMMPROP{
  WORD wPacketLength;     // 구조체 사이즈
  WORD wPacketVersion;    // 구조체 버젼
  DWORD dwServiceMask;    // 실행된 서비스
  DWORD dwReserved1;      // 예약
  DWORD dwMaxTxQueue;    // 바이트 단위의 최대 송신 버퍼 사이즈
  DWORD dwMaxRxQueue;    // 바이트 단위의 최대 수신 버퍼 사이즈
  DWORD dwMaxBaud;      // 보레이트 최대값
  DWORD dwProvSubType;       // 특정 프로바이더 타입
  DWORD dwProvCapabilities;     // 서포트된 함수
  DWORD dwSettableParams;      // 변경 가능 파라미터
  DWORD dwSettableBaud;     // 허가된 보레이트
  WORD wSettableData;        // 허가된 바이트 사이즈
  WORD wSettableStopParity;      // 스탑 비트 / 패리티 허가
  DWORD dwCurrentTxQueue;     // Tx 버퍼 사이즈
  DWORD dwCurrentRxQueue;     // Rx 버퍼 사이즈
  DWORD dwProvSpec1;       // 프로바이더 특정 데이터
  DWORD dwProvSpec2;       // 프로바이더 특정 데이터
  WCHAR wcProvChar[1];       // 프로바이더 특정 데이터
}COMMPROP;

dwServiceMask : 시링러 포트의 경우는 항상 SP_SERIALCOMM이다.
dwReserved1 : 미사용
dwMaxTxQueue : 출력 버퍼의 최대값(바이트), 0을 설정하면 무제한
dwMaxRxQueue : 입력 버퍼의 최대값(바이트), 0을 설정하면 무제한
dwMaxBaud : 이하의 상수로 설장 가능한 보레이트의 최대값

의미
BAUD_075 75 bps
BAUD_110 110 bps
BAUD_134_5 134.5 bps
BAUD_150 150 bps
BAUD_300 300 bps
BAUD_600 600 bps
BAUD_1200 1200 bps
BAUD_1800 1800 bps
BAUD_2400 2400 bps
BAUD_4800 4800 bps
BAUD_7200 7200 bps
BAUD_9600 9600 bps
BAUD_14400 14400 bps
BAUD_19200 19200 bps
BAUD_38400 38400 bps
BAUD_56K 56K bps
BAUD_57600 57600 bps
BAUD_115200 115200 bps
BAUD_128K 128K bps
BAUD_USER 유저 설정

dwProvSubType : 이하의 상수로 CreateFile()에 의해 작성된 통신 디바이스가 무엇을 서포트하는지를 알려준다. 시리얼 포트의 경우는 PST_RS232가 된다.

의미
PST_FAX 팩스
PST_LAT LAT 프로토콜
PST_MODEM 모뎁
PST_NETWORK_BRIDGE 미정의 네트워크 브릿지
PST_PARALLELPORT 패럴렐 포트
PST_RS232 RS-232 시리얼 포트
PST_RS422 RS-422 포트
PST_RS423 RS-423 포트
PST_RS449 RS-449 포트
PST_SCANNER 스캐너
PST_TCPIP_TELNET TCP/IP TelnetR 프로토콜
PST_UNSPECIFIED 미정의
PST_X25 X.25 스탠다드


dwProvCapabilities : 이하의 상수로 시리얼 포트가 서포트 하는 기능을 보여준다.
통산의 리리얼 포트 드라이버는 PCF_16BITMODE와 PCF_SPECIALCHARS 이외는 대체적으로 서포트한다.

의미
PCF_16BITMODE 특별한 16비트 모드를 서포트
PCF_DTRDSR DTR/DSR 서포트
PCF_INTTIMEOUTS 인터벌 타임아웃을 서포트
PCF_PARITY_CHECK 패리티 체크 서포트
PCF_RLSD RLSD(CD) 서포트
PCF_RTSCTS RTS/CTS 서포트
PCF_SETXCHAR 설정 가능한 XON/XOFF 서포트
PCF_SPECIALCHARS 설정 가능한 특수문자 서포트
PCF_TOTALTIMEOUTS 토탈 타임아웃 서포트
PCF_XONXOFF XON/XOFF 플로 제어 서포트

dwSettableParams : 이하의 상수로 설정 변경 가능한 파라미터를 나타낸다.

의미
SP_BAUD 보레이트
SP_DATABITS 1케릭터의 비트수
SP_HANDSHAKING 핸드 쉐이크 방식(플로 제어)
SP_PARITY 패리티 비트 수
SP_PARITY_CHECK 패리티 체크의 유무
SP_RLSD RLSD(CD)
SP_STOPBITS 스톱 비트 수

dwSettableBaud : 설정 가능한 모든 보레이트의 종류를 dwMaxBaud의 항목으로 정의된 상수값으로 OR한 값을 나타낸다.

wSettableData : 이하의 상수의 OR로 설정 가능한 1 케릭터의 비트 수를 나타낸다.
시리얼 포트에서는 5~8이 서포트 된다.

의미
DATABITS_5 5 data bits
DATABITS_6 6 data bits
DATABITS_7 7 data bits
DATABITS_8 8 data bits
DATABITS_16 16 data bits
DATABITS_16X 시리얼 회선을 사용한 특수한 와이드 버스

wSettableStopParity : 이항의 상수의 OR로 설정 가능한 스톱 비트 수와 패리티를 나타낸다.

의미
STOPBITS_10 1  스톱 비트
STOPBITS_15 1.5 스톱 비트
STOPBITS_20 2 스톱 비트
PARITY_NONE 패리티 없음
PARITY_ODD 홀수 패리티
PARITY_EVEN 짝수 패리티
PARITY_MARK 마크  패리티
PARITY_SPACE         스페이스 패리티


dwCurrentTxQueue : 현재 송신 버퍼 사이즈를 나타낸다.

dwCurrentRxQueue : 현재 수신 버퍼 사이즈를 나타낸다.

시리얼 포트의 상태를 얻기 예제

COMMPROP구조체의 주요 내용을 표시하는 프로퍼티 시트 예제

이 예제는 컴포트1에서 4까지를 고정으로 오픈한다.
(요즘 기본적으로 컴포트가 없는 컴퓨터가 많아서 USB를 쓰는 사람은
컴포트를 1에서 읽는 것을 좀 수정할 필요가 있다.
USB 컴포트가 3이나 4로 잡히면 그냥 실행시켜도 문제없다.)

컴포트 1에서 4를 열어 각 포트의 시리얼 포트 상태와
각 포트에 설정 가능값을 표시한다.


Posted by 띠리

델파이에서 동적으로 컨트롤 만드는 두가지 방법

밑의 소스의 ①과 ②를 보면 컨트롤을 동적으로 만드는 법이 두가지가 있다.
①처럼 바로 컨트롤을 만드는 방법과
②처럼 기존에 동적 배열 컨트롤을 정의해 두고
배열의 크기를 설정해서 컨트롤을 만드는 방법이 있다.

이 프로그램을 실행시켜서 컨트롤 키를 누르고 마우스를 클릭하거나
컨트롤 키를 누르지 않고 마우스를 클릭하면 동적으로 컨트롤들이 폼에 생성되어진다.

그리고 그렇게 생성되어진 컨트롤을 클릭하면 각 컨트롤의 캡션이 폼의 캡션에 표시되어진다.

unit Unit2;

interface

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

type
  TForm2 = class(TForm)
    procedure FormMouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
  private
    procedure GetCtrlName(Sender: TObject);
  public

    btnD : Array of TButton;

  end;

var
  Form2: TForm2;

implementation

{$R *.dfm}

var
  Count1 :integer = 1;
  Count2 :integer = 1;
  sParent : string;

// 컨트롤 키를 눌렀는지 알려줌
function CtrlDown : Boolean;
var
  State : TKeyboardState;
begin
  GetKeyboardState(State);
  Result := ((State[vk_Control] And 128) <> 0);
end;

procedure TForm2.FormMouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  if Button = mbRight then Exit;


  // 컨트롤 키를 눌렀을때
  if CtrlDown then
  begin

    // 버튼을 동적으로 생성①
    with TButton.Create(Self) do begin
      Parent := Self;
      Height := 30;
      Width := width + Count1*2;
      Left := X - Width div 2;
      Top := Y - Height div 2;
      Name := Format('D1Button%d',[Count1]);
      Caption := 'OOO' + IntToStr(Count1);
      OnClick := GetCtrlName;
    end;

    Inc(Count1);

  end
  // 컨트롤 키를 안눌렀을때
  else
  begin

    SetLength(btnD, Count2);

    // 버튼을 동적 배열로 생성②
    btnD[Count2] := TButton.Create(nil);
    with btnD[Count2] do
    begin
      Parent := Self;
      Height := 30;
      Width := width + Count1*2;
      Left := X - Width div 2;
      Top := Y - Height div 2;
      Caption := 'XXX' + IntToStr(Count1);
      Name := Format('D2Button%d',[Count1]);
      OnClick := GetCtrlName;
    end;

   Inc(Count2);

  end;


end;

// 동적으로 만들어진 컨트롤을 클릭했을 때 실행
procedure TForm2.GetCtrlName(Sender: TObject);
begin
  Form2.Caption  := (Sender as TButton).Caption;
  //Form2.Caption  := (Sender as TButton).name;

  if ((Sender as TButton).Left + (Sender as TButton).Width + 50) > Form2.Width  then
    (Sender as TButton).Left := 0
  else
    (Sender as TButton).Left :=  (Sender as TButton).Left + 50;
end;

end.



소스 파일
Posted by 띠리

델파이 XML Data Binding으로 xml 파일 조작하기

소스를 열어둔 상태에서 Tool Palette를 보면 Delphi Projects | XML이 있다.
그 밑에 XML Data Binding이 있다.
그것을 클릭한다.

사용자 삽입 이미지

그러면 아래 윈도우가 표시되어지고
조작할  XML 파일을 선택하고 "Next" 버튼을 누른다.

사용자 삽입 이미지

XML Data Binding Wizard 화면에서도 특별히 고치지 않고 "Next" 버튼을 누른다.

사용자 삽입 이미지

그러면 아래와 같이 새로운 pas파일이 생성되면서 조금전에 선택한 XML 파일의 조작하기 쉽게 xml 파일이 바인딩된다.

사용자 삽입 이미지

그리고 이 바인딩된 xml 파일을 사용하고자 하는 곳에
추가된 unit명과 xmldom, XMLIntf, XMLDoc을 uses에 추가해야 된다.

xml Data Binding을 쓰면 간단하게 xml 파일에 노드를 추가하고
삭제하고 검색하고 변경하는 것이 가능하지만 좀 자유도(?)가 많이 떨어지게 된다.

자세한 내용은 첨부한 소스를 참조하는 것이 좋을 것같다.

unit uMain;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, stdctrls, extctrls
  ,CarList, xmldom, XMLIntf, XMLDoc;

type
  TForm1 = class(TForm)
    ListBox1: TListBox;
    ListBox2: TListBox;
    Button1: TButton;
    procedure ListBox1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }

    ixList : IXMLItemListType;
    ixDetail :Array of IXMLItemType;

  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
  iListCount : integer;
  i : integer;
  sTest : string;
begin

  iListCount := ixList.Count;
  setLength(ixDetail, iListCount);

  ListBox1.Clear;

  // xml 파일에서 아이템 가져오기
  for i := 0 to iListCount - 1 do
  begin
    ixDetail[i] := ixList.Get_Item(i);
    ListBox1.Items.Add(ixDetail[i].Name)
  end;

end;

procedure TForm1.FormCreate(Sender: TObject);
var
  CurrentPath : array [0..256] of char;
begin

  // 어플리케이션이 위치하는 디렉토리 얻기
  GetCurrentDirectory(sizeof(CurrentPath),CurrentPath);

  // xml을 읽어서 아이템 리스트 로드
  ixList := LoadItemList(CurrentPath + '\CarList.xml');
  Application.GetNamePath

end;

procedure TForm1.ListBox1Click(Sender: TObject);
var
  i: integer;
begin
  i := ListBox1.ItemIndex;

  ListBox2.Clear;
  // 선택한 아이템의 상세 정보 표시
  //ListBox2.Items.Add(ixDetail[i].Sec);
  ListBox2.Items.Add('Color = ' + ixDetail[i].Color);
  ListBox2.Items.Add('Maker = ' + ixDetail[i].Maker);
end;

end.



XmlBind.zip

BDS 2006

프로젝트 소스와 xml 파일

Posted by 띠리

델파이에서 프로그램이 있는 패스(디렉토리) 얻기

procedure TForm1.FormCreate(Sender: TObject);
var
  CurrentPath : array [0..256] of char;
begin
  // 프로그램이 있는 현재의 디렉토리 정보 얻기
  GetCurrentDirectory(sizeof(CurrentPath), CurrentPath);
  Form1.Caption := CurrentPath;

end;
Posted by 띠리

델파이에서 XMLDocument 컴포넌트를 사용해서
XML 파일 불러 TreeView에 표시하는 소스

XML 파일 불러오기

// XML 파일 읽어오기
procedure TForm1.Button2Click(Sender: TObject);
Var
  xdSoft : TXMLDocument;
begin

  OpenDialog1.Filter := 'Xml file|*.xml';

  if OpenDialog1.Execute then
  begin

    // XML Document 만들기
    xdSoft := TXMLDocument.Create(Application);

    // XML Document 불러오기
    xdSoft.LoadFromFile(OpenDialog1.FileName);
    xdSoft.Active := True;

    // TreeView 기존 데이터 삭제
    TreeView1.Items.Clear;

    // XML 구조를 읽어서 TreeView에 표시
    MakeTree(nil, xdSoft.DocumentElement);

    // TreeView 다 펴서 보여주기
    TreeView1.FullExpand;

    xdSoft.Free;

  end;

end;


XML 파일을 트리뷰에 표시

// XML 구조를 읽어서 TreeView에 표시
procedure TForm1.MakeTree(TreeNode : TTreeNode; XMLNode : IXMLNode);
var
  Node: TTreeNode;
  i: integer;
  sNode : string;
begin

  sNode := '';

  // 노드 밑에 노드가 없을 때
  if (XMLNode.NodeType = ntText) then
  begin

    // 노드에 Attribute가 있을 때
    if XMLNode.AttributeNodes.Count > 0  then
    begin
      sNode := ' |';
      For i :=0 To XMLNode.AttributeNodes.Count - 1 Do
      begin
        sNode := sNode +
        XMLNode.AttributeNodes.Get(i).NodeName + ' : ' +
        XMLNode.AttributeNodes.Get(i).NodeValue + '|';
      end;
    end;

    // 트리뷰에 노드 추가
    Node := TreeView1.Items.AddChild(TreeNode, XMLNode.NodeValue + sNode);

  end

  // 노드 밑에 노드가 있을 때
  else
  begin

    // 노드에 Attribute가 있을 때
    if XMLNode.AttributeNodes.Count > 0  then
    begin
      sNode := ' |';
      For i :=0 To XMLNode.AttributeNodes.Count - 1 Do
      begin
        sNode := sNode +
        XMLNode.AttributeNodes.Get(i).NodeName + ' : ' +
        XMLNode.AttributeNodes.Get(i).NodeValue + '|';
      end;
    end;

    // 트리뷰에 노드 추가
    Node := TreeView1.Items.AddChild(TreeNode, XMLNode.NodeName + sNode);

  end;

  // 노드 밑에 노드가 있을 경우
  for i :=  0 to  XMLNode.ChildNodes.Count - 1 do
    // XML 구조를 읽어서 TreeView에 표시
    MakeTree(Node, XMLNode.ChildNodes.Nodes[i]);

end;

XML 파일의 모든 노드와 속성을 표시하는 소스

 

XmlToTreeView.zip

델파이 2006 소스

델파이 2006 소스
Posted by 띠리

델파이에서 XMLDocument 컴포넌트로 XML파일을 읽고 쓰는 방법은
말로 설명하기는 좀 어렵고 그냥 소스를 보는 것이 알기 쉬울 것같다.

먼저 uses에  XMLDoc, XMLIntf을 추가한다.

XML 파일 쓰기

// XML 파일 만들고 쓰기
procedure TForm1.Button1Click(Sender: TObject);
Var
  xdSoft : TXMLDocument;
  xnRoot  : IXMLNode;
  xnChild : IXMLNode;
  xnGrandchild : IXMLNode;
begin

  // XML Document 만들기
  xdSoft := TXMLDocument.Create(Application);
  xdSoft.Active := True;
  xdSoft.Encoding:= 'euc-kr';

  // 루트 노드 만들기
  xnRoot := xdSoft.AddChild('SoftList');
  // 노드에 속성 설정
  xnRoot.Attributes['LatestUpdate'] := FormatDateTime('YYYY/MM/DD', Now);


  // 테스트 데이터 추가

###################################################################### //

  // 노드 밑에 노드 만들기
  xnChild := xnRoot.AddChild('Soft');
  xnChild.Attributes['Soft_name'] := 'PhotoSharp';

  xnGrandchild := xnChild.AddChild('Detail');
  xnGrandchild.Attributes['maker'] := 'Adove';
  xnGrandchild.Attributes['section']  := 'Drawing tool';
  xnGrandchild.Attributes['Price']  := 5000;

  xnGrandchild := xnChild.AddChild('Extra');
  xnGrandchild.Attributes['name'] := 'toy';
  xnGrandchild.Attributes['note']  := 'for child';

  xnGrandchild := xnChild.AddChild('Stock');
  // 노드 값 설정
  xnGrandchild.NodeValue := 100;

  // ---------------------------------------------------------------------- //

  xnChild := xnRoot.AddChild('Soft');
  xnChild.Attributes['Soft_name'] := 'OverOffice';

  xnGrandchild := xnChild.AddChild('Detail');
  xnGrandchild.Attributes['maker'] := 'OverSoft';
  xnGrandchild.Attributes['section']  := 'office tool';
  xnGrandchild.Attributes['Price']  := 2000;

  xnGrandchild := xnChild.AddChild('Extra');
  xnGrandchild.Attributes['name'] := 'notebook';
  xnGrandchild.Attributes['note']  := 'no comment';

  xnGrandchild := xnChild.AddChild('Stock');
  xnGrandchild.NodeValue := 50;

  // ###################################################################### //

  // XML Document 저장하기
  xdSoft.SaveToFile('C:\Test.Xml');
  xdSoft.Free;

end;

만들어진 XML 파일

<?xml version="1.0" encoding="euc-kr" ?>
<SoftList LatestUpdate="2007-10-12">
  <Soft Soft_name="PhotoSharp">
    <Detail maker="Adove" section="Drawing tool" Price="5000" />
    <Extra name="toy" note="for child" />
    <Stock>100</Stock>
  </Soft>
  <Soft Soft_name="OverOffice">
    <Detail maker="OverSoft" section="office tool" Price="2000" />
    <Extra name="notebook" note="no comment" />
    <Stock>50</Stock>
  </Soft>
</SoftList>

XML 파일 읽기

// XML 파일 읽어오기
procedure TForm1.Button2Click(Sender: TObject);
Var
  xdSoft : TXMLDocument;
  xnChild : IXMLNode;
  xnGrandchild : IXMLNode;
  i : Integer;
  j : Integer;
  k : Integer;
  sMsg : string;
  sTest : string;
begin

  // XML Document 만들기
  xdSoft := TXMLDocument.Create(Application);

  // XML Document 불러오기
  xdSoft.LoadFromFile('C:\Test.Xml');
  xdSoft.Active := True;

  // 루트 노드가 없을 경우 종료
  if xdSoft.ChildNodes.First = nil then Begin
    Exit;
  End;

  // 루트에 딸려있는 노드 분
  For i := 0 To xdSoft.DocumentElement.ChildNodes.count - 1 Do
  Begin
    sMsg := '';
    sTest := '';

    xnChild := xdSoft.DocumentElement.ChildNodes[i];
    xnGrandchild := xnChild.ChildNodes[0];

    // Soft 노드의 첫번째 노드의 속한 attribute 분
    For j :=0 To xnGrandchild.AttributeNodes.Count - 1 Do
    begin

    sMsg := sMsg +
      '    ' + xnGrandchild.AttributeNodes.Get(j).NodeName + ' : ' +
      xnGrandchild.AttributeNodes.Get(j).NodeValue + #13

    end;
    sTest := sTest + xnChild.NodeName + ' : ';
    sTest := sTest + xnChild.AttributeNodes.Get(0).NodeValue + #13;

    xnGrandchild := xnChild.ChildNodes[2];

    ShowMessage(
      sTest + #13 +
      sMsg + '    ----------' + #13 +
      '    ' + xnGrandchild.NodeName + ' : ' +
      xnGrandchild.NodeValue
    );

  End;

  xdSoft.Free;

end;

개인적으로 생각하기에는 XML Data Binding보다 XML Documnet 컴포넌트를
쓰는것이 더 깔끔하게 프로그램을 만들 수 있을 것같다.






 

Posted by 띠리

델파이에서 엑셀 파일에 선그리기



procedure TForm1.Button1Click(Sender: TObject);
var
  Excel: OleVariant;
  WorkBook: OleVariant;
  WorkSheet: OleVariant;

  i : integer;

Const
  xlNone = -4142;
  xlDiagonalDown = 5;
  xlDiagonalUp = 6;
  xlEdgeLeft = 7;
  xlEdgeTop = 8;
  xlEdgeBottom = 9;
  xlEdgeRight = 10;
  xlContinuous = 1;

  xlThin = 2;
  xlThick = 4;

  xlAutomatic = -4105;

begin

  Excel := CreateOleObject('Excel.Application');
  Excel.Visible := True;

  // 워크북 추가
  Excel.WorkBooks.Add;
  WorkBook := Excel.ActiveWorkBook;

  // 워크시트 추가
  Workbook.sheets.add;

  // 작업할  워크시트 선택
  WorkSheet := WorkBook.WorkSheets[1];

  // 선그리기
  WorkSheet.Range['B5:E10'].Borders[xlDiagonalDown].LineStyle := xlNone;
  WorkSheet.Range['B5:E10'].Borders[xlDiagonalUp].LineStyle := xlNone;
  WorkSheet.Range['B5:E10'].Borders[xlEdgeLeft].LineStyle := xlContinuous;
  WorkSheet.Range['B5:E10'].Borders[xlEdgeTop].LineStyle := xlContinuous;
  WorkSheet.Range['B5:E10'].Borders[xlEdgeBottom].LineStyle := xlContinuous;
  WorkSheet.Range['B5:E10'].Borders[xlEdgeBottom].Weight := xlThick;
  WorkSheet.Range['B5:E10'].Borders[xlEdgeBottom].ColorIndex := xlAutomatic;
  WorkSheet.Range['B5:E10'].Borders[xlEdgeRight].LineStyle := xlContinuous;

end;


델파이에서 엑셀에 선그리려면 위에 같이 하면 된다.
각 상수값을 알기 위해서는 엑셀의 메크로의 Visual Basic Editor를 열어서
소스에서 오른 쪽 클릭하면 "개체 찾아보기"가 나온다.
그것을 선택하면 개체 찾아보기 창이 뜨고 거기서
찾고자 하는 상수를 입력하면 상수값을 알 수 있다.
 

Posted by 띠리

델파이에서 엑셀로 데이터 출력하는 간단한 예제

맨 위의 uses에는 "ComObj"를 추가 해야된다.

procedure TForm1.Button1Click(Sender: TObject);
var
  Excel: OleVariant;
  WorkBook: OleVariant;
  WorkSheet: OleVariant;

  i : integer;

begin

  Excel := CreateOleObject('Excel.Application');
  Excel.Visible := True;

  // 워크북 추가
  Excel.WorkBooks.Add;
  WorkBook := Excel.ActiveWorkBook;

  // 워크시트 추가
  Workbook.sheets.add;

  try
    // 작업할  워크시트 선택
    WorkSheet := WorkBook.WorkSheets[1];

    // 셀에 데이터 입력
    for I := 1 to 100 do
    begin
      WorkSheet.Cells[i,1].Value:= IntToStr(i);
      WorkSheet.Cells[i,2].Value:= 'TEST-' + IntToStr(i);;
    end;

    // 워크북 저장
    WorkBook.SaveAs(Filename:='c:\ExcelOutputTest.xls');

  finally
    // 워크북 닫기
    WorkBook.close;
    WorkBook:=unAssigned;
    WorkSheet:=unAssigned;
    // 엑셀 종료
    Excel.Quit;
    Excel:=unAssigned;
  end ;

end;


 

ExcelOutput.zip

델파이 2006 소스


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

공지사항

카테고리

분류 전체보기 (299)
Win32 SDK 초보 (27)
통신관련 (11)
MFC TIP (20)
C/C++ TIP (10)
개발기타 (9)
링크 (2)
견물생심 (24)
이것저것 (7)
용어메모 (3)
데이터베이스 (28)
비주얼 베이직 (10)
하드웨어 (2)
C# (35)
델파이 (82)
Xcode (3)
홈페이지 (5)
MindStorm (0)
스크래치 (0)
낙서 (5)
기타 (6)
아두이노 (1)
라즈베리파이 (0)
Total : 590,889
Today : 53 Yesterday : 153