델파이에서 동적으로 배열 컨트롤을 만들었을 때의 컨트롤 유무 체크 하는 방법
VB에서는 어떤 오브젝트가 생성되었는지 안되었는지 알기위해서는
IsObject라는 함수가 있다.
델파이에서는 배열 컨트롤이 있는지 없는지 체크하기 위해서는
밑의 소스처럼 is를 사용수 있다.
begin
if btnD[3] is TObject then
btnD[3].Caption := 'ttttt';
end;
델파이에서 동적으로 배열 컨트롤을 만들었을 때의 컨트롤 유무 체크 하는 방법
VB에서는 어떤 오브젝트가 생성되었는지 안되었는지 알기위해서는
IsObject라는 함수가 있다.
델파이에서는 배열 컨트롤이 있는지 없는지 체크하기 위해서는
밑의 소스처럼 is를 사용수 있다.
■ 시리얼 포트 오픈
시리얼 포트는 파일처럼 다룬다.
시리얼 포트를 오븐 하기위해서는 CreateFile()을 사용한다.
인수:
lpFileName: COM1이나 COM2등의 시리얼 포트 이름을 지정한다.
(LPT1같은 프린터 포트도 지정할 수 있다.)
dwDesiredAccess: 이하의 읽기 모드를 단독 또는 OR로 지정한다.
| 값 | 의미 |
| 0 | 디바이스의 속성을 묻는다. |
| GENERIC_READ | 읽기 억세스. 읽기 쓰기를 할때는 GENERIC_WRITE를 조합해서 지정 |
| GENERIC_WRITE | 쓰기 억세스. 쓰기 쓰기를 할때는 GENERIC_READ를 조합해서 지정 |
| 값 | 의미 |
| FILE_SHARE_DELETE | Windows NT 일 경우만 : 후속의 오픈 조작으로 삭제 억세스가 요구될 때, 그 오픈을 허가 |
| FILE_SHARE_READ | 후속의 호픈 조작으로 읽기 억세스가 요구될 때 그 오픈을 허가 |
| FILE_SHARE_WRITE | 후속의 호픈 조작으로 쓰기 억세스가 요구될 때 그 오픈을 허가 |
| 값 | 의미 |
| FILE_FLAG_OVERLAPPED | 시간이 걸리는 처리에 있어서 ERROR_IO_PENDING을 반환하도록 한다. 처리가 끝나면 이벤트가 시그널 상태로 설정된다. 이 플래그를 지정했을 때는 ReadFile 함수나 WriteFile 함수로 OVERLAPPED 구조체를 지정해야만 된다. |
반환값 : 성공하면 0 이외의 값, 실패하면 0을 반환한다.
■ 시리얼 포트 상태 정보 얻기
자신의 컴퓨터에 시리얼 포트는 어느 정도의 성능인지 등 보통은 신경쓰지않지만 디바이스 드라이버를 포함한 시리얼 포트의 성능을 앎으로 서포트 하지않는 보레이트를 잘못해서 설정했을 때의 부정한 설정을 막아준다.
시리얼 포트에 관한 정보는 GetCommProperties()의 호출로 COMPROC 구조체 변수를 읽어온다.
인수 :
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 | 유저 설정 |
| 값 | 의미 |
| 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 스탠다드 |
| 값 | 의미 |
| 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 플로 제어 서포트 |
| 값 | 의미 |
| SP_BAUD | 보레이트 |
| SP_DATABITS | 1케릭터의 비트수 |
| SP_HANDSHAKING | 핸드 쉐이크 방식(플로 제어) |
| SP_PARITY | 패리티 비트 수 |
| SP_PARITY_CHECK | 패리티 체크의 유무 |
| SP_RLSD | RLSD(CD) |
| SP_STOPBITS | 스톱 비트 수 |
| 값 | 의미 |
| 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 | 시리얼 회선을 사용한 특수한 와이드 버스 |
| 값 | 의미 |
| STOPBITS_10 | 1 스톱 비트 |
| STOPBITS_15 | 1.5 스톱 비트 |
| STOPBITS_20 | 2 스톱 비트 |
| PARITY_NONE | 패리티 없음 |
| PARITY_ODD | 홀수 패리티 |
| PARITY_EVEN | 짝수 패리티 |
| PARITY_MARK | 마크 패리티 |
| PARITY_SPACE | 스페이스 패리티 |
CommProp.zipVS 2005
델파이에서 동적으로 컨트롤 만드는 두가지 방법
밑의 소스의 ①과 ②를 보면 컨트롤을 동적으로 만드는 법이 두가지가 있다.
①처럼 바로 컨트롤을 만드는 방법과
②처럼 기존에 동적 배열 컨트롤을 정의해 두고
배열의 크기를 설정해서 컨트롤을 만드는 방법이 있다.
이 프로그램을 실행시켜서 컨트롤 키를 누르고 마우스를 클릭하거나
컨트롤 키를 누르지 않고 마우스를 클릭하면 동적으로 컨트롤들이 폼에 생성되어진다.
그리고 그렇게 생성되어진 컨트롤을 클릭하면 각 컨트롤의 캡션이 폼의 캡션에 표시되어진다.
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
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
Inc(Count1);
end
// 컨트롤 키를 안눌렀을때
else
begin
SetLength(btnD, Count2);
// 버튼을 동적 배열로 생성②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.
CreateCtrls.zipBDS 2006
델파이 XML Data Binding으로 xml 파일 조작하기
소스를 열어둔 상태에서 Tool Palette를 보면 Delphi Projects | XML이 있다.
그 밑에 XML Data Binding이 있다.
그것을 클릭한다.
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.zipBDS 2006
프로젝트 소스와 xml 파일
델파이에서 프로그램이 있는 패스(디렉토리) 얻기
델파이에서 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 소스
델파이에서 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 파일 읽기
// 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 컴포넌트를
쓰는것이 더 깔끔하게 프로그램을 만들 수 있을 것같다.
델파이에서 엑셀 파일에 선그리기
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를 열어서
소스에서 오른 쪽 클릭하면 "개체 찾아보기"가 나온다.
그것을 선택하면 개체 찾아보기 창이 뜨고 거기서
찾고자 하는 상수를 입력하면 상수값을 알 수 있다.
델파이에서 엑셀로 데이터 출력하는 간단한 예제
맨 위의 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 소스

|