◀ PREV : [1] : [2] : [3] : [4] : [5] : ... [21] : NEXT ▶

TIdFTP로 FTP 클라이언트를 만드는데 여러번 삽질을 했다.
자료가 많이 있거나 샘플이 어디 있는지 알면 좋았겠지만
내 검색 능력으로는 잘 검색되지 않아서 나름 고생했다.


FTP 서버 접속

  // ftpCt: TIdFTP; 폼에서 선언
  ftpCt.Host := edtHost.Text;  
  // 기본 FTP 포트를 사용하는 경우, 설정 안해도 됨
  ftpCt.Port := StrToInt(edtPort.Text);
  // Anonymous(익명)로 접속하는 경우 아래와 같이 설정
  ftpCt.Username := 'anonymous';//edtId.Text;
  // 익명 접속일 경우 패스워드 설정할 필요 없음
  //ftpCt.Password := edtPass.Text;
  // FTP 서버에 접속
  ftpCt.Connect;

FTP 서버에서 파일 리스트 가져오기

파일 리스트를 가져오는 방법은 두가지가 있다.
파일명이나 폴더명을 가져오는 방법과
파일명의 속성같은 정보를 한번에 가져오는 방법이 있다.

물론 파일 리스트를 가져오기전에 FTP를 접속해야된다.

  * 파일명만 가져오는 방법

  slFile := TStringList.Create;
  try
    // FTP 폴더를 바꾸는 방법
    ftpCt.ChangeDir('/');

    // 파일명만 가져오기
    //   선택된 폴더의 파일 리스트를 TStringList파일에 저장한다.
    ftpCt.List(slFile, '', false);

    // 저장된 리스트를 리스트 박스에 추가
    for i := 0 to slFile.Count - 1 do
      lstFolder.Items.Add(slFile.Strings[i]);

  finally
    slFile.Free;
    ftpCt.Quit;
  end;
  ftpCt.Disconnect;


  * 파일속성까지 가져오는 방법

  try
    ftpCt.ChangeDir('/');
    // 선택된 폴더의 파일 리스트(속성 포함)를
    //  DirectoryListing에 자료를 저장
    ftpCt.List(nil);

    // 리스트에 저장한 값 리스트박스에 추가
    for i := 0 to ftpCt.DirectoryListing.Count -1 do
    begin
      // 디렉토리(ditDirectory )인지 파일(ditFile)인지 구분
      if ftpCt.DirectoryListing.Items[i].ItemType = ditDirectory then
        sFile := ftpCt.DirectoryListing.Items[i].FileName ;  // 파일이름
      // 리스트박스에 추가
      lstAtt.Items.Add(sFile);
    end;
  finally
    ftpCt.Quit;
  end;
  ftpCt.Disconnect;


★여기서 중요한 것이 있다.
FTP서버가 윈도우즈 계열인 경우, 파일 속성까지 가져오려해도(ftpCt.List(nil))
리스트를 제대로 가져오지 못한다.
FTP서버가 윈도우즈 계열인 경우에는 uses에서 IdFTPListParseWindowsNT
추가해주어야지만 제대로 리스트를 가져올 수 있다.
이것을 몰라서 하루종일 해맸다.

FTP 서버에서 지정한 파일 가져오기

FTP에서 파일을 클라이언트로 카피하기

  // FTP가 연결되어있는가
  if ftpCt.Connected then
  begin
    try
      // 파일이 있는 폴더 설정
      sFolder := '/'+ lstFolder.Items.Strings[lstFolder.ItemIndex];
      // FTP 서버에 있는 파일명
      sSrcFile := lstFile.Items.Strings[lstFile.ItemIndex];
      // 클라이언트 컴퓨터에 카피할 파일명
      sTrgFile := 'c:\' + lstFile.Items.Strings[lstFile.ItemIndex];

      ftpCt.TransferType := ftASCII;
      // 폴더 바꾸기
      ftpCt.ChangeDir(sFolder);
      // FTP 서버에서 파일 가져오기
      ftpCt.Get(sSrcFile, sTrgFile, true);
    finally
      ftpCt.Quit;
    end;

참고사항

위 소스를 돌리기 위해서는 밑의 클래스들을
uses에 추가해야된다.

uses
 IdFTP, IdFTPCommon, IdFTPListParseWindowsNT, IdFTPList;


이올린에 북마크하기(0) 이올린에 추천하기(0)
Posted by 띠리

[델파이]Edit에 수치값만 입력 가능하게(소수, 음수입력 가능) 자리수 제한

Edit컨트롤에 정수, 소수, 음수만을 입력할 수 있게 한다.
숫자의 자릿수를 설정하여 자릿수만큼만 입력할 수 있게 한다.



procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char);
var
  iKey : Integer;
  iPos : Integer;
  iLen : integer;
  iSel : integer;
  iAfterPointDigit :integer;
  iBeforePointDigit :integer;
  sText : string;
begin
  sText := Edit1.text;
  iKey := ord(Key);
  iLen := Length(trim(sText));
  iSel := Edit1.SelStart;
  iAfterPointDigit := 3;
  iBeforePointDigit := 3;

  if iKey = $08 then exit;  // Back space

  // 수치와 소숫점과 마이너스만 입력 가능하게
  if not(iKey in [$2E, $2D, $30..$39]) then begin Key := #0; exit; end;

  iPos :=  Pos('-', sText);
  // 마이너스가 두개 입력되지 않게
  if (iPos > 0) and (iKey = $2D) then begin Key := #0; exit; end
  else if (iPos = 0) and (iKey = $2D) and (iSel > 0) then
    begin Key := #0; exit; end;

  iPos :=  Pos('.', sText);
  // 소숫점 두개 안들어가게
  if (iPos <> 0) and (iKey = $2E) then begin Key := #0; exit;  end
  // 숫자가 입력되지 않았을 때, 소수점 입력 안되게
  else if (iPos = 0) and (iKey = $2E) and (iLen = 0) then
    begin Key := #0; exit; end;

  // 소수점 있을 때 소수점 앞의 자릿수 제한
  if (iPos > 0 ) then
  begin
    if ((iLen - iPos - 1) > (iBeforePointDigit - 1)) then
      begin Key := #0; exit; end;
  end
  // 소수점 없을 때 소수점 앞의 자릿수 제한
  else
  begin
    if (iLen > iBeforePointDigit - 1) and (iKey <> $2E) then
      begin Key := #0; exit; end;
  end;

  // 소숫점 뒤의 자리수 제한
  if (iPos > 0 ) and ((iPos + iAfterPointDigit - 1) < iLen) then
    if iSel > iPos then begin Key := #0; exit; end;
end;

이올린에 북마크하기(0) 이올린에 추천하기(0)
Posted by 띠리

StringGrid의 셀에 색칠하기 예제

StringGrid의 1열은 녹색으로 표시하고
2행은 적색으로 표시하고 StringGrid의 1열과 2행 외의
다른 셀을 클릭하였을 때, 클릭한 셀을 청색으로 표시한다.


procedure TForm1.StringGrid1Click(Sender: TObject);
var
  pntCurPos :TPoint;
  iCol      :integer;
  iRow      :integer;
begin

  with StringGrid1 do
  begin
    pntCurPos := ScreenToClient(Mouse.CursorPos);

    // 마우스가 위치가 어느 셀위에 있는지 정보얻기
    MouseToCell(pntCurPos.x, pntCurPos.y, iCol, iRow);

    // 셀 별 오브젝트가 설정되었는지 확인
    // 오브젝트가 설정되어 있지 않을 경우 색을 오브젝트로 설정
    if Assigned(Objects[iCol, iRow]) then
      Objects[iCol, iRow] := nil
    else
      Objects[iCol, iRow] := TObject(clBlue);

  end;
end;

procedure TForm1.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
  Rect: TRect; State: TGridDrawState);
begin
  with StringGrid1 do
  begin

    // 셀 별 어브젝트가 설정되었는지 확인
    if Assigned(Objects[ACol, ARow]) then
    begin
      // 색을 셀에 채우기
      Canvas.Brush.Color := TColor(Objects[ACol, ARow]);
      Canvas.FillRect(Rect);
    end;

    // 1열 녹색 채우기
    if ACol  = 1 then
    begin
      Canvas.Brush.Color := TColor(clGreen);
      Canvas.FillRect(Rect);
    end;

    // 2행 적색 채우기
    if ARow  = 2 then
    begin
      Canvas.Brush.Color := TColor(clRed);
      Canvas.FillRect(Rect);
    end;

    // 글자 표시
    Canvas.TextOut(Rect.Left + 2, Rect.Top + 2, Cells[ACol, ARow]);
  end;
end;


 

이올린에 북마크하기(0) 이올린에 추천하기(0)
Posted by 띠리

[델파이]StringGrid에서 오른쪽 정렬과 가운데 정렬하기 예제

오른쪽 정렬하고자하는 StringGrid의 DrawCell 이벤트에
밑의 소스를 카피해서 정렬을 하고자 하는 열이나 행을 설정한다.

StringGrid는 기본적으로 왼쪽 정렬
 


procedure TForm1.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
  Rect: TRect; State: TGridDrawState);
var
  hdcTemp       : HDC;
  crdOrgAlign   : Cardinal;
begin

  with Sender as TStringGrid do
  begin

    hdcTemp := Canvas.Handle;
    if ARow = 0 then
      Canvas.Font.Style := Canvas.Font.Style + [fsBold];

    // 오른쪽 정렬
    if ((ACol = 2) or (ACol = 0)) and (ARow <> 0) then
    begin
      crdOrgAlign := SetTextAlign(hdcTemp, TA_RIGHT);
      Canvas.TextRect(Rect,
                      Rect.Right - 2,
                      Rect.Top + 2,
                      Cells[ACol, ARow]);
      SetTextAlign(hdcTemp, crdOrgAlign);
    end
    // 가운데 정렬
    else if (ACol = 3) and (ARow <> 0) then
    begin
      crdOrgAlign := SetTextAlign(hdcTemp, TA_CENTER);
      Canvas.TextRect(Rect,
                      (Rect.Left + Rect.Right) DIV 2,
                      Rect.Top + 2,
                      Cells[ACol, ARow]);
      SetTextAlign(hdcTemp, crdOrgAlign);
    end
    // 맨 윗줄 가운데 정렬
    else if (ARow = 0) then
    begin
      crdOrgAlign := SetTextAlign(hdcTemp, TA_CENTER);
      Canvas.TextRect(Rect,
                      (Rect.Left + Rect.Right) DIV 2,
                      Rect.Top + 2,
                      Cells[ACol, ARow]);
      SetTextAlign(hdcTemp, crdOrgAlign);
    end
  end;
end;



 

이올린에 북마크하기(0) 이올린에 추천하기(0)
Posted by 띠리
VB에서는 문자열 값이 수치값인지 확인하는 IsNumeric이라는 함수가 있다.
이런 것을 델파이에서 쓰려면 아래의 함수를 사용하면 간단하게
문자열이 수치값인지 확인할 수 있다.


function IsNum(sStr : string) : boolean;
var
  nErr : integer;
  nRet : integer;
begin
  Val(sStr, nRet, nErr);
  Result := (nErr = 0);
end;


이올린에 북마크하기(0) 이올린에 추천하기(0)
Posted by 띠리

선택한 폴더의 들어있는 파일을 리스트 박스에 표시하는 예제


function TfrmMain.GetFileList(sFolder: string): integer;
var
  SrcRec  : TSearchRec;
  nCnt    : integer;
begin
  if DirectoryExists(sFolder) then
  begin
    nCnt := 0;

    // '\'가 없으면 붙임
    sFolder := IncludeTrailingPathDelimiter(sFolder);

    // 폴더의 모든 파일 표시
    if FindFirst(sFolder + '*.*', faAnyFile, SrcRec) = 0 then
    try
      repeat
         // 폴더, 현 폴더, 상위 폴더 제외
         if not((SrcRec.Attr and faDirectory > 0)) and
               (SrcRec.Name <> '.') and (SrcRec.Name <> '..') then
           begin
             Inc(nCnt);
             // 파일명 추가
             lstLog.Items.Add(SrcRec.Name);
           end;
       until (FindNext(SrcRec) <> 0);
       Result := nCnt;
    finally
      FindClose(SrcRec);
    end;
  end;
end;


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

풀 패스에서 파일명이나 확장자나 패스만을 얻는 것은 델파이에서는 쉽게 할 수 있다.
하기야 만들어 짜면 되기야하지만 공부 삼아 만들어 보는 것도 나쁘지 않겠지만
이젠 공부삼아 만드는 것도 귀찮다. ^^;;

파일명 얻기
function ExtractFileName(const FileName: string): string;

확장자 얻기
function ExtractFileExt(const FileName: string): string;

패스 얻기
function ExtractFilePath(const FileName: string): string;

 

이올린에 북마크하기(0) 이올린에 추천하기(0)
Posted by 띠리

파일 유무 체크를 하는데 있어서
네트워크 경유로 파일을 체크할 경우에는
체크하려는 네트워크가 검색이 안 될 경우에는
프로그램이 먹통이 된 것처럼 잠시 멈쳐 버린다 그런 것을 해결하기 위해서
스레드로 이 처리를 하면 지정한 시간만 기다리고 응답이 없으면
다음 처리로 넘어가게 할 수 있다.

네트워크가 아닌 경우에는 FileExists는 폴더나 파일이 없으면
바로 다음 행으로 넘어간다.


  // 네트워크 파일 유뮤 체크 스레드
  TCheckFileThread = class(TThread)
  private
    FFileName : String;
    FResult   : Integer;
  protected
    procedure Execute;override;
  published
    property FileName : String read FFilename write FFilename;
    property Result : Integer read FResult write FResult;
  end;

// 스레드 본체 : 파일 유무 체크
procedure TCheckFileThread.Execute;
begin
    Result := -1;
    // 파일 유무 체크
    if FileExists(FileName) = True then
      // 파일 유
      Result := 0
    else
      // 파일 무
      Result := 1;
    Terminate;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
    CheckFile : TCheckFileThread;
    tick : Cardinal;
begin

    // 파일 유무 체크 스레드 기동
    CheckFile := TCheckFileThread.Create(True);
    CheckFile.Result := -2;
    CheckFile.FreeOnTerminate := False;
    // wwwi가 검색하려는 컴퓨터명(ip어드레스를 입력해도 됨)
    CheckFile.FileName := '\\wwwi\haha.txt';
    CheckFile.Resume;

    tick := GetTickCount;
    // 지정한 시간 만큼 대기하고 응답이 없으면 다음으로 넘어가기
    while (CheckFile.Terminated = False) and (GetTickCount - tick < 1000) do
    begin
      Application.ProcessMessages;
    end;

    case CheckFile.Result of
     -1:// Timeout
      begin
        // 타임아웃으로 끝났을 경우 스레드 종료
        TerminateThread(CheckFile.Handle, 0);
        Button1.Caption := 'Timeout';
      end;
      0:// Ok
      begin
        Button1.Caption := 'Ok';
      end;
      1:// no file
      begin
        Button1.Caption := 'no file';
      end;
    end;
    CheckFile.Free;
end;


 

이올린에 북마크하기(0) 이올린에 추천하기(0)
Posted by 띠리

명령 프롬프트에서 net file을 치면 누가 내 컴퓨터의 어떤 파일을 억세스 하고 있는지 알 수 있다.
 

C:\>net file

ID         경로                                    사용자 이름            잠금

-------------------------------------------------------------------------------
224        D:                                      RARARA                0
289        D:TEST FILE1234.xls                     RARARA                3
315        D:                                      HAHAHA                0
443        D:\TEST-SYSTEM-소개-V2.ppt              HAHAHA                0
명령을 잘 실행했습니다.


C:\>net file > net.txt


프로그램 짤 때 이것을 참조하려면 빨간 글씨로 씌여진 것 처럼 하면
위의 내용을 텍스트 파일로 자신이 원하는 곳에 출력할 수 있다.
출력된 파일을 읽어들이면 어떤 유저가 어떤 파일을 억세스하는지 알 수 있다.
 

이올린에 북마크하기(0) 이올린에 추천하기(0)
Posted by 띠리

함수의 고무줄 파리미터 초간단 예제


#include <stdio.h>
#include <stdarg.h>

void testit ( int i, ...)
{
    va_list argptr;
    int  n;

    // 가변 인수 수의 초기화
    va_start(argptr, i);

    if ( i == 5 ) {
     
        for(int j = 0; j < i; j++)
        {
            // 다음 인수 얻기
            n = va_arg( argptr, int );
            printf( "%d\n", n );
        }
    } else {
        char *s = va_arg( argptr, char* );
        printf( "%s\n", s);
    }
    // 가변 인수 수의 리셋
    va_end(argptr);
}

int main()
{
    testit( 5, 12, 34, 56, 78, 90 );
    testit( 1, "TEST" );     

    return 0;
}




 

이올린에 북마크하기(0) 이올린에 추천하기(0)
Posted by 띠리

델파이에서 날짜 더하고 빼기 예제


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


procedure TForm1.Button1Click(Sender: TObject);
var
  dtNow : TDateTime;
  dtThen : TDateTime;

begin
  // IncDay    한날을 더한 날짜 반환
  // IncMonth  한달을 더한 날짜 반환
  // IncYear   한년을 더한 날짜 반환

  // 오늘 날짜 표시
  Label1.Caption := DateToStr(Now());

  // 오늘 날에서 지정한 날짜 가감산
  Label2.Caption := DateToStr(IncDay(Now(), -30));

  // 오늘에서 한달 더하기
  Label3.Caption := DateToStr(IncMonth(Now()));

  dtNow := Now();

  // TDateTime형에 데이터 입력
  dtThen := EncodeDateTime(2008, 9, 9, 12, 12, 12, 0);

  // DaysBetween
  //  : TDateTime 값의 차를 하루(24) 단위로 반환
  Label4.Caption := FloatToStr(DaysBetween(dtNow, dtThen));

  // DaySpan
  //  : TDateTime 값의 차의 그래도 반환
  Label5.Caption := FloatToStr(DaySpan(dtNow, dtThen));
end;



 

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

공지사항

카테고리

분류 전체보기 (201)
Win32 SDK 초보 (27)
통신관련 (11)
MFC TIP (20)
C/C++ TIP (10)
개발기타 (9)
링크 (2)
견물생심 (24)
이것저것 (7)
용어메모 (3)
데이터베이스 (13)
비주얼 베이직 (10)
하드웨어 (1)
델파이 (46)
홈페이지 (4)
낙서 (5)
기타 (3)
Total : 116,931
Today : 8 Yesterday : 157