블로그 이미지
훅크선장

카테고리

분류 전체보기 (362)
사진이야기 (23)
펭귄컴퓨팅 (121)
컴퓨터보안 (84)
절름발이 프로그래머 (59)
C언어, C++ 과 Visual C+.. (12)
C# .net (1)
Delphi (40)
Python (5)
하드웨어개조 (23)
멀알려줄까 (35)
홈베이킹&홈쿠킹 (2)
잡다한것들 (15)
Total
Today
Yesterday

달력

« » 2024.4
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30

공지사항

태그목록

최근에 올라온 글

http://www.microsoft.com/download/iexplorer/down.php?id=3

위와 같은 URL  즉, 웹 주소가 있는 경우,
여러 프로그래밍 상황에서 각 요소별로 나누어야 되는 상황이 많이 발생합니다.

다시 말해서, URL을 파싱해야 되는 상황이라면,

전 그전까지 AppControls에 있는 acHTTP 모듈에 있는 
ParseURL(EdtDownloadURL.Text, Protocol, HostName, URLPath, Username, Password, ExtraInfo, Port);
함수를 사용했습니다만,

델파이 2009를 사용하면서, (델파이 2009에서 AppControls가 컴파일이 안됩니다.)
위 함수를 대체하기 위해서 다음을 사용하게 되었습니다.

참고한 곳은
입니다.

UnitURLIPv6 라는 모듈입니다.

위 링크에 있는 것을 바로 사용할 수 있는 것이 아니었습니다.
하나의 모듈을 더 찾아서 사용해야하고, 소스중에 필요한 함수 하나를 대체하였습니다.

결국, 수정된 UnitURLIPv6.pas 와 synautil.pas 파일이 있어야만 동작합니다.
두 파일은 각각 다운받을 수 있습니다.

두 소스를 프로젝트에 포함시키고, 다음과 같이 사용합니다.

uses UnitURLIPv6;


var
     errcode : Integer;
     URLInfo : URL;
begin

...
...

// URL을 파싱해서, 각 요소별로 구분한다.
url_parse(EdtURL.Text, errcode, @URLInfo);

...
...

end;

정상적인 URL 파싱이면 errcode가 0으로 리턴됩니다.
에러상황이면 각각의 에러 코드가 errcode에 들어갈 것 같습니다.

URLInfo에 URL의 각 요소가 들어가게 됩니다.

URLInfo.url  -> 원래의 URL 전체
URLInfo.host  -> www.microsoft.com
URLInfo.port  -> 80
URLInfo.path  -> download/iexplorer/down.php
URLInfo.query  -> id=3
URLInfo.dir  -> download/iexplorer
URLInfo.file1  -> down.php

________________________________________________
type
  url = record
    url: string;              // Original URL
    scheme: url_scheme;  // URL scheme

    host: string;              // Extracted hostname
    port: word;                // Port number

    // URL components (URL-quoted).
    path: string;
    params: string;
    query: string;
    fragment: string;

    // Extracted path info (unquoted). */
    dir: string;
    file1: string;

    // Username and password (unquoted). */
    user: string;
    passwd: string;
  end;
Posted by 훅크선장
, |
델파이에서는 기본적으로 TImage 라는 컴포넌트로 이미지를 다루는데,
이것은 그냥 BMP 파일을 다루는 것 같습니다.

델파이 2007에서는 JPG와 GIF 형식을 바로 보여줄 수 있습니다.
델파이 2009에서는 PNG 형식을 추가로 바로 보여줄 수 있게 되었습니다.

PNGImage 라는 오픈소스를 아예 Embarcadero에서 사버렸습니다.
머, GIF쪽은 저자가 직접 기증?한거이지만...

델파이 2009에서 TImage 컴포넌트에 각각의 그래픽 파일을 보여주는 예제는 다음과 같습니다.
각각의 이미지 파일을 처리하기 위해서는 
uses PNGImage, JPEG, GIFImg;

구문을 앞부분에 사용하여야만 합니다.
(클래스 즉 파일명에 일관성이 없네요~~ 쯧쯧~~)

procedure TForm1.Button1Click(Sender: TObject);
var
  Extension : String;
  PNG : TPNGImage;
  JPG : TJPEGImage;
  GIF : TGIFImage;
begin

  // 저장된 파일의 확장자명을 추출한다.
  Extension := ExtractFileExt(OutputFilePath);
  Extension := LowerCase(Extension);

  // GIF 파일 형식인 경우,
  if Extension = '.gif' then
  begin
    GIF := TGIFImage.Create;
    try
      GIF.LoadFromFile(OutputFilePath);
      Image1.Picture.Assign(GIF);
      Image1.Stretch := True;
      Image1.Visible := True;
    finally
      GIF.Free;
    end;


  end
  // JPG 파일 형식인 경우,
  else if Extension = '.jpg' then
  begin
    JPG := TJPEGImage.Create;
    try
      JPG.LoadFromFile(OutputFilePath);
      Image1.Picture.Assign(JPG);
      Image1.Stretch := True;
      Image1.Visible := True;
    finally
      JPG.Free;
    end;
  end
  // PNG 파일 형식인 경우,
  else if Extension = '.png' then
  begin
    PNG := TPngImage.Create;
    try
      PNG.LoadFromFile(OutputFilePath);
      Image1.Picture.Assign(PNG);
      Image1.Stretch := True;
      Image1.Visible := True;
    finally
      PNG.Free;
    end;
  end;
end;

Posted by 훅크선장
, |
C언어에서는 당연하고 되는 것이지만,
델파이 즉, 오브젝티브 파스칼을 쓸 때는 한번쯤 생각해보게 되는 방법이다.

C언어에서는  타입 캐스팅으로 되는 것을
델파이에서는 다음과 같이 해야된다.

tmpbuffer: array[0..1023] of Byte;
ptr : ^aRecord;

    // 파일에서 데이터를 읽어온다.
    ZeroMemory(@tmpbuffer[0], sizeof(tmpbuffer));
    BlockRead(File, tmpbuffer, datasize, readbytes);
    ptr := @tmpbuffer; // 버퍼 내용을 레코드 형식으로 해석한다.

    ptr.a
이런 식으로 버퍼의 데이터를 레코드형식으로 받아서 사용할 수 있다.

Posted by 훅크선장
, |
http://delphi.about.com/od/windowsshellapi/a/executeprogram.htm
를 참고하였습니다.

델파이에서 별도의 프로그램, 즉 exe를 실행시키고 종료를 확인할 수 있습니다.
ShellExecuteEx 를 사용하는데, 
먼저 uses ShellApi; 를 포함합니다.

그리고,
procedure TForm1.Button2Click(Sender: TObject);
var
   SEInfo: TShellExecuteInfo;
   ExitCode: DWORD;
   ExecuteFile, ParamString, StartInString: string;
begin
   ExecuteFile:='C:\Windows\Notepad.exe'; // 실행하려는 프로그램의 경로 및 파일명 지정
   ParamString := 'C:\autoexec.bat'; // 프로그램 실행시 인자값을 문자열로 지정

   FillChar(SEInfo, SizeOf(SEInfo), 0) ;
   SEInfo.cbSize := SizeOf(TShellExecuteInfo) ;
   with SEInfo do begin
     fMask := SEE_MASK_NOCLOSEPROCESS;
     Wnd := Application.Handle;
     lpFile := PChar(ExecuteFile) ;
     lpParameters := PChar(ParamString) ;
 // lpDirectory := PChar(StartInString) ; // StartInString 문자열에 실행되고자 하는 디렉토리를 지정할 수 있음. 지정하지 않으면 현재 프로그램 실행 디렉토리가 디폴트로 사용됨
     nShow := SW_SHOWNORMAL; // 프로그램이 실행되는 윈도우 형태를 지정할 수 있습니다. ACTIVE, 최대화, 최소화 등등...
   end;
   if ShellExecuteEx(@SEInfo) then begin
     repeat
       Application.ProcessMessages;
       GetExitCodeProcess(SEInfo.hProcess, ExitCode) ;
     until (ExitCode <> STILL_ACTIVE) or
Application.Terminated;
     ShowMessage('프로그램이 종료되었습니다.') ;
   end
   else ShowMessage('프로그램을 실행하지 못했습니다.') ;
end;
같이 코드를 작성하면 됩니다.
Posted by 훅크선장
, |
ipAddresses 라는 TStringList에 IP 주소 문자열이 있다고 가정할 때,
동일한 IP주소가 몇 개나 있는지 찾고, 그 결과를 출력하는 예제입니다.
꼭 IP 주소가 아닌, 일반 문자열이나 단어등에도 적용해 볼 수 있습니다.

AddObject로 문자열의 개수를 추가하는 방식이라서, 간단하게 결과를 볼 수 있습니다.
아래 펌글에 좀 더 빠른 방법이 제안되어 있습니다만, 대용량이 아니라면 이것만 가지고도 충분히 빠른 결과를 볼 수 있습니다.

procedure TForm1.Button1Click(Sender: TObject);
var
  ls : TStringList;
  ip : string;
  ipAddresses : TStringList;
  n : integer;
  I: Integer;
begin
  memo1.Lines.Clear;
  memo2.Lines.Clear;

  ipAddresses := TStringList.Create;
  ipAddresses.Add('192.168.10.1');
  ipAddresses.Add('192.168.1.10');
  ipAddresses.Add('192.168.1.1');
  ipAddresses.Add('192.168.10.1');
  ipAddresses.Add('192.168.1.1');
  ipAddresses.Add('192.168.1.10');
  ipAddresses.Add('192.168.1.1');
  ipAddresses.Add('192.168.1.10');

  ls := TStringList.Create;
  ls.Sorted := true;
  for ip in ipAddresses do begin
    n := ls.IndexOf(ip);
    if n = -1 then
      ls.AddObject(ip, TObject(1))
    else
      ls.Objects[n] := TObject(Integer(ls.Objects[n]) + 1);
  end;

  memo1.Lines := ls;
  for I := 0 to ls.Count - 1 do
  begin
    memo2.Lines.Add(IntToStr(Integer(ls.Objects[I])));
  end;

end;
Posted by 훅크선장
, |
http://www.matsgefvert.se/blog/archives/651
에서 가져온 글입니다.

StringList상에 있는 동일한 문자열 개수 세기 샘플 코드와
StringList의 검색속도를 증가시키는 방법이 나와있습니다.
----------------------------------------------------------------------------------

Speeding Up Delphi’s TStringList.IndexOf
1 June 2009, 15:33 ? Music, Software Development
Delphi’s TStringList is one of the objects I love the most. If it’s sorted (StringList.Sorted := true) then you can use it to parse huge chunks of data quickly.

For instance, looping through an enormous amount of IP addresses and keeping count of how many times they appeared, is easily done using the following code (not compiled or checked for syntax errors):

ls := TStringList.Create;
ls.Sorted := true;
for ip in ipAddresses do begin
  n := ls.IndexOf(ip);
  if n = -1 then
    ls.AddObject(ip, TObject(1))
  else
    ls.Objects[n] := TObject(Integer(ls.Objects[n]) + 1);
end;
It’s very efficient. Since TStringList.IndexOf always does a binary search, it operates in log2(n) time, and using Objects as integers allows us to keep track of count without messing with the string data.

But there are things we can do to speed it up. For instance, TStringList.IndexOf relies on TStringList.Find, which itself uses AnsiCompareStr, which is a slow Windows call, taking locale and its mother into consideration. Overriding this with our own method should be worthwhile. (The code below is adapted straight from the Classes unit.)

type
  TStringListEx = class(TStringList)
  public
    function Find(const S: string; var Index: Integer): Boolean; override;
  end;

function TStringListEx.Find(const S: string; var Index: Integer): Boolean;
var
  L, H, I, C: Integer;
begin
  Result := False;
  L := 0;
  H := Count - 1;
  while L <= H do
  begin
    I := (L + H) shr 1;
    C := CompareStr(Get(I), S);
    if C < 0 then L := I + 1 else
    begin
      H := I - 1;
      if C = 0 then
      begin
        Result := True;
        if Duplicates <> dupAccept then L := I;
      end;
    end;
  end;
  Index := L;
end;
We’ve replaced AnsiCompareStr with Delphi’s own CompareStr, which is a highly optimized FastCode routine. There are some drawbacks ? things will always be sorted in byte order and no case-sensitivity is done. But we don’t care about this ? it can always be done afterwards; right now, speed is the main importance.

And it turns out that using the above code, in pure examples, can slash execution time with up to about 80%. Dramatic savings, indeed. In my own example, where I analyze ftp log data, I managed to cut execution time on 122 MB of data down from 7 seconds down to 3.1 seconds.

Best of all, since TStringList.Find is declared virtual, we don’t need to change any types anywhere, just do a TStringListEx.Create instead of a TStringList.Create and you’re good to go.




Posted by 훅크선장
, |
http://www.delmadang.com/
델마당의 “강좌, 팁, 정보” 게시판에서 가져온 글입니다.

대웅
(klol)
2009-01-12 오후 11:39:47

이 쓰신 글입니다.
----------------------------------------------------------------------------------

DBGrid자료를 엑셀로 보내는 함수입니다.

uses
      dbgrids, ComObj, Excel2000, Clipbrd;
.....

procedure ToExcle(vDBGrid: TDBGrid);
var
  XL: Variant;
  i,k: integer;
  sData: string;
begin
  try
    XL := CreateOLEObject('Excel.Application');
  except on E: Exception do
  begin
    ShowMessage('Excel OLE object를 오픈할 수 없습니다.'+E.Message);
    Exit;
  end; end;
  try
    XL.WorkBooks.Add; //새로운 페이지 생성
    XL.Visible := False;
    XL.Workbooks[XL.Workbooks.Count].WorkSheets[1].Name := 'Sheet1';
    sData := '';
    for i := 0 to vDBGrid.Columns.Count - 1 do
    begin
      sData := sData+vDBGrid.Columns[i].Title.Caption+#9;
      if vDBGrid.Columns[i].Field.DataType in [ftString,ftMemo,ftWideString] then
      begin
        XL.Workbooks[XL.Workbooks.Count].WorkSheets['Sheet1'].Columns[i+1].Select;
        XL.Selection.NumberFormatLocal := '@';
      end;
    end;
    sData := sData+#$D#$A;

    with vDBGrid do
    begin
      k := 0;
      DataSource.DataSet.First;
      while not DataSource.DataSet.Eof do
      begin
        inc(k);
        for i := 0 to Columns.Count - 1 do
          sData := sData+Columns[i].Field.AsString+#9;
        sData := sData+#$D#$A;
        DataSource.DataSet.Next;
      end;
    end;

    Clipboard.SetTextBuf(PChar(sData));
    XL.Cells[1,1].Pastespecial;
    XL.Range['A1', Chr(64+vDBGrid.Columns.Count)+IntToStr(k)].select;
    XL.Selection.Columns.AutoFit;
    XL.Range['A1', 'A1'].select;
    XL.Visible := True;
  except on E: Exception do
  begin
    ShowMessage('Excel로 자료를 보내는 중 오류가 발생했습니다.'+E.Message);
    XL.Visible := True;
    Exit;
  end; end;
end;

테스트결과 아주 잘 되는군요.

Posted by 훅크선장
, |
http://topopen.egloos.com/3211897 에서 가져왔습니다.

StringGrid를 아직 안 써봤지만, 앞으로 쓸 일이 있을 것 같습니다.

[Delphi] 델파이 excel export 소스

아래는 델마당 소스 발췌한 내용입니다.
---------------------------------------------------------------------
스트링그리드이 내용을 excel로 저장하는 델파이 소스입니다..

그런데, 제가 델은 잘 몰라서....변환을 할 수가 없군요..

소스는 한델에서 얻었구요... 빌더로 변환해 주세요..^^

소스는 아래와 같습니다..

1. StringGrid 예제
Uses절 ComObj 포함..

procedure TshGridX.run_excel;
var
  XL, XArr: Variant;
  i, j: Integer;
begin
  //데이타 처리변수
  XArr := VarArrayCreate([1, StringGrid1.ColCount], VarVariant);

  try
  //엑셀을 실행
    XL := CreateOLEObject('Excel.Application');
  except
    MessageDlg('Excel이 설치되어 있지 않습니다.', MtWarning, [mbok], 0);
    Exit;
  end;

  XL.WorkBooks.Add; //새로운 페이지 생성
  XL.Visible := True;
  
  for i := 0 to StringGrid1.RowCount - 1 do begin
    for j := 0 to StringGrid1.ColCount - 1 do begin
      XArr[j+1] := StringGrid1.Cells[j,i];
    end;
    //엑셀에 값을 넣는다.
    XL.Range['A' + IntToStr(i+1), CHR(64 + StringGrid1.ColCount) + IntToStr(i+1)].Value := XArr;
  end;

  //셀 크기 조정
  XL.Range['A1', CHR(64 + StringGrid1.ColCount) + IntToStr(i+1)].Select;
  XL.Selection.Columns.AutoFit;
  XL.Range['A1', 'A1'].Select;
end;
Posted by 훅크선장
, |
정상적인 윈도우즈 운영체제에서 Excel 이 깔려있다면,
대부분의 그리드 형태나 리스트뷰 내용을 Excel로 바로 띄워 볼 수 있다.
바로 Excel이 지원하는 형태로 저장할 수 있다는 의미이다.

일단  uses ComObj;  를 추가하여야 엑셀 컴포넌트 기능을 사용할 수 있다.

다음과 같이 한다.

procedure TForm1.BtnExcelViewClick(Sender: TObject);
var
  XL, XArr: Variant;
  i, j: Integer;
begin
  //데이타 처리변수
  XArr := VarArrayCreate([1, ListView1.Columns.Count], VarVariant);

  try
    //엑셀을 실행
    XL := CreateOLEObject('Excel.Application');
  except
    MessageDlg('Excel이 설치되어 있지 않습니다.', MtWarning, [mbok], 0);
    Exit;
  end;

  XL.WorkBooks.Add; //새로운 페이지 생성
  XL.Visible := True;

  // 제목 행 생성
  XArr[1] := '첫번째열';
  XArr[2] := '두번째열';
  XArr[3] := '세번째열';
  XArr[4] := '네번째열';
  XArr[5] := '다섯번째열';
  XL.Range['A1', CHR(64 + ListView1.Columns.Count) +  IntToStr(1)].Value := XArr;

  for i := 0 to ListView1.Items.Count - 1 do begin
    for j := 0 to ListView1.Columns.Count - 1 do begin
      if j = 0 then XArr[j+1] := ListView1.Items.Item[i].Caption
      else XArr[j+1] := ListView1.Items.Item[i].SubItems[j-1];
    end;
    //엑셀에 값을 넣는다.
    XL.Range['A' + IntToStr(i+2), CHR(64 + ListView1.Columns.Count) +  IntToStr(i+2)].Value := XArr;
  end;

  //셀 크기 조정
  XL.Range['A1', CHR(64 + ListView1.Columns.Count) + IntToStr(i+1)].Select;
  XL.Selection.Columns.AutoFit;
  XL.Range['A1', 'A1'].Select;
end;


Posted by 훅크선장
, |
http://tolyn.net/24

Delphi2007(CodeGear RAD Stduio 2007) 을 설치하면 기본적으로 Indy10이 설치된다.
9와 10 중 원하는것을 설치할 수 있던것과는 대조적인데..
Indy10보다는 9쪽을 애용하는 분들이 훨신 많은게 현실이다.
그래서 여기에 Indy9를 사용 하는 방법을 소개한다


 

1. 일단 Component 메뉴에서 Install Packages 를 선택한다

 

그중 붉은 사각형에 있는 Indy10 관련 컴포넌트의 체크를 제거한다.

그 후 ADD버튼을 누르면 아래와 같은 창이 나올텐데

 
dclindy100.bpl 을 골라 설치한다.
이 파일은 RADStudio 설치폴더 \ bin 에 존재한다. 
(기본경로는 C:\Program Files\CodeGear\RAD Studio\5.0\bin)


그 뒤에 옵션창을 열고 

붉은 사각형 안에 있는 Indy10 으로 된 패스를 전부 Indy9로 고쳐주면 된다.


자 이제 우리는 Indy9를 사용 할 수 있다.
맘껏 네트워크 프로그램을 짜 보자 


ps. RAD Studio 2007 에는 현재(07년 4월 23일) Indy9의 최신버젼이 들어있는 것으로 확인되었다
Posted by 훅크선장
, |