Delphi - 투명 윈도우 만들기

Programming/Delphi 2008.03.23 01:55 Posted by 파란크리스마스

출처
http://kurapa.com/content-a411_%25ED%2588%25AC%25EB%25AA%2585%25EC%259C%2588%25EB%258F%2584%25EC%259A%25B0

http://careerblog.scout.co.kr/home/?pSeq=665762&blogURL=http://neodreamer.tistory.com/39
http://careerblog.scout.co.kr/search/?searchtype=4&searchtext=CodeGear

// 투명 윈도우 만들기
procedure TfmMain.Button1Click(Sender: TObject);
begin
  SetWindowLong(handle, GWL_EXSTYLE, GetWindowLong(handle, GWL_EXSTYLE) or WS_EX_LAYERED);
  SetLayeredWindowAttributes(handle, 0, Round((255 * 70 ) / 100), LWA_ALPHA);
end;

// 투명 윈도우 만들기 + 최상위 윈도우 + 이벤트 활성화
procedure TfmMain.Button2Click(Sender: TObject);
begin
   Self.Color := RGB(1, 1, 1);
   SetWindowLong(handle, GWL_EXSTYLE, GetWindowLong(handle, GWL_EXSTYLE) or WS_EX_LAYERED);
   SetLayeredWindowAttributes( handle, RGB(1, 1, 1), 127, LWA_COLORKEY or LWA_ALPHA);
  Self.FormStyle := fsStayOnTop;
end;

신고

Delphi Tip - 파일이름 관련 함수

Programming/Delphi 2008.03.04 17:27 Posted by 파란크리스마스
Delphi Tip - 파일이름 관련 함수

출처 : http://delphi.borlandforum.com/impboard/impboard.dll?action=read&db=del_tip&no=179
http://www.swissdelphicenter.ch/torry/showcode.php?id=144
http://www.delphibasics.co.uk/RTL.asp?Name=StringReplace

// 델파이
function ExtractFileDir(const FileName: string): string;
function ExtractFileDrive(const FileName: string): string;
function ExtractFileName(const FileName: string): string;
function ExtractFilePath(const FileName: string): string;

예)

filename := ExtractFileName(  StringReplace(url, '/', '\', [rfReplaceAll, rfIgnoreCase]) );
신고

Delphi - File Download

Programming/Delphi 2008.03.04 12:58 Posted by 파란크리스마스

Delphi Tip - File Download

출처 : http://delphi.about.com/od/internetintranet/a/get_file_net.htm

uses WinInet;

function GetInetFile (const fileURL, FileName: String): boolean;
const
  BufferSize = 1024;
var
  hSession, hURL: HInternet;
  Buffer: array[1..BufferSize] of Byte;
  BufferLen: DWORD;
  f: File;
  sAppName: string;
begin
  result := false;
  sAppName := ExtractFileName(Application.ExeName);
  hSession := InternetOpen(PChar(sAppName), INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0) ;
  try
    hURL := InternetOpenURL(hSession, PChar(fileURL), nil, 0, 0, 0) ;
    try
      AssignFile(f, FileName);
      Rewrite(f,1) ;
      repeat
        InternetReadFile(hURL, @Buffer, SizeOf(Buffer), BufferLen);
        BlockWrite(f, Buffer, BufferLen);
      until BufferLen = 0;
      CloseFile(f) ;
      result := True;
    finally
      InternetCloseHandle(hURL);
    end
  finally
    InternetCloseHandle(hSession);
  end;
end;

// 윈도우즈의 임시폴더 명을 반환한다.
function SysTempPath(): String;
var
  Buffer: array[0..1023] of Char;
begin
  SetString(Result, Buffer, GetTempPath(Sizeof(Buffer)-1, Buffer));
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  internetFile,
  localFileName: string;
begin
 internetFile := 'http://localhost:8080/Sample.jmd';
 localFileName := SysTempPath() + 'test.xml';

 if GetInetFile(internetFile, localFileName) then
   ShowMessage(SysTempPath() + 'Sample.jmd' + ' / Download successful.')
 else
   ShowMessage('Error in file download.') ;
end;

신고

초간단 java2delphi

Programming/Delphi 2007.08.23 15:42 Posted by 파란크리스마스

java 소스를 Delphi로 변환 프로그램을 간단하게 만들어 보았습니다.

원래 필요로 했던 것은 사칙연산이나 제어문 정도라서 일주일 투자해서 간단하게 만들어 보았습니다.

JavaCC을 이용했으며, jj 파일을 제외하고 Java 소스를 첨부합니다.

 

사용법:

java -jar java2delphi.jar Formatter.java

 

위와 같이 명령을 하시면 Formatter.pas의 결과물을 얻을 수 있습니다.

아래에 일부 변환된 예를 입니다.

  public int sum(int s1, int s2) {
    return s1 + s2;
  }
  function TFormatter.sum(s1 : integer; s2 : integer): int;
  begin
   result := s1+s2;
  end;
------------------------------------------------------------------
  public boolean checkSELECT(String s1) {
    if (s1.equalsIgnoreCase("select")) {
      return true;
    } else {
      return false;
    }
  }
  function TFormatter.checkSELECT(s1 : String): boolean;
  begin
    if ((UpperCase(s1)='SELECT')) then
    begin
      result := true;
    end else begin
      result := false;
    end;
  end;
------------------------------------------------------------------
  public static int testFor() {
    int sum = 0;
    for (int i=0; i<100; i++)
      sum = sum + 1;
  }
  function TFormatter.testFor(): int;
  var
    i : integer;
    sum : integer;
  begin
    sum:=0;
    i:=0;
    while (i<100) do begin
      sum:=sum+1;
      inc(i);
    end;
  end;
------------------------------------------------------------------
  private void doEscape2Space() {
    for (aD = 1; aD <= queryTokenCount; aD++) {
      if (isTokenQuoteLiterals[aD])
        continue;
      if (queryToken[aD].equals("\t")
          || queryToken[aD].equals("\f")
          || queryToken[aD].equals("\r")
          || queryToken[aD].equals("\b"))
        queryToken[aD] = " ";
      if (queryToken[aD].equals("\r"))
        queryToken[aD] = "\\n";
    }
  }
  procedure TFormatter.doEscape2Space();
  begin
    aD:=1;
    while (aD<=queryTokenCount) do begin
      if (isTokenQuoteLiterals[aD]) then
      begin
        continue;
      end;
      if ((queryToken[aD]=#9)
        or  (queryToken[aD]=#12)
        or  (queryToken[aD]=#13)
        or  (queryToken[aD]=#8)) then
      begin
        queryToken[aD]:=' ';
      end;
      if ((queryToken[aD]=#13)) then
      begin
        queryToken[aD]:='\\n';
      end;
      inc(aD);
    end;
  end;  
                                    
신고

[SOAP강좌] Java 서버 - Delphi 클라이언트

Programming/Delphi 2007.08.17 01:09 Posted by 파란크리스마스

▶ SOAP

SOAP(Simple Object Access Protocol)에 대한 설명은 다른 사이트에 잘 나와 있으니 찾아 보세요.
여기에서는 Java로 SOAP 서버를 만들고, Tomcat으로 Web 서비스 하여, 클라이언트는 Delphi로 만들어 보겠습니다.
이와 같은 예가 외국 사이트를 찾아 보아도 별로 없더군요. 그래서 허접한 설명이지만 도움이 될까 해서 올립니다.
(기회가 되면 배열이나, Dataset도 구현 하고 싶지만 시간이 없어서...)

일부 소스와 내용은 에어콘 출판사의 차세대 자바 SOAP AXUS을 참조 했습니다.

▶ 준비물

JDK 1.4.x 이상 (http://java.sun.com)
Tomcat 4.1.36 (http://tomcat.apache.org/)
AXIS 1.4 (http://ws.apache.org/axis/)
Delphi 7 (http://www.borland.com)

▶ SOAP Web 서비스 설치

여기에서 JDK, Tomcat의 설치는 따로 하지 않겠습니다. 이것도 다른 사이트를 참조하세요.

1. axis-bin-1_4.zip 압축 풀기

Apache에서 받은 axis-bin-1_4.zip을 압축을 특정 폴더에 풀어 주세요. 저는 C:\SOAP\axis-1_4 에 풀었습니다.
앞으로 설명은 C:\SOAP\axis-1_4 으로 하겠습니다.

2. %tomcat_home%\conf\server.xml

아래 내용을 추가해서 AXIS 가상 경로를 추가 Tomcat을 다시 실행 시켜주세요.

<!-- Tomcat SOAP Context -->
<Context path="/axis" docBase="C:\SOAP\axis-1_4\webapps\axis" debug="0"
         reloadable="true" crossContext="true">
</Context>

▶ Java로 SOAP 서버 만들기

아래와 내용과 같이 HelloWorld.java을 만들고, 이 파일을 C:\SOAP\axis-1_4\webapps\axis 디렉토리에 확장자가 .jws로 수정 HelloWorld.jws을 C:\SOAP\axis-1_4\webapps\axis 복사해주세요.

HelloWorld.java 파일

public class HelloWorld {

  public HelloWorld() {
  }
 
  public String getHelloWorldMessage(String name) {
    return "Hello World to " + name;
  }
}

확인하기

지금까지 잘 하셨다면 브라우저에서 http://localhost:8080/axis/HelloWorld.jws 주소로 보시면 아래와 같이 나올 것입니다.

사용자 삽입 이미지















▶ WSDL 파일 만들기


SOAP의 WSDL 파일이 어떤 일을 하는지도 다른 사이트에 자세히 나와 있으니 이것도 다른 사이트에서 찾아보세요.
여기에서는 WSDL 파일을 AXIS을 이용해서 만들고, Delphi로 사용하는 방법만 설명하겠습니다.

브라우저에서 http://localhost:8080/axis/HelloWorld.jws 페이지를 열어서 Click to see the WSDL을 선택하시면 아래와 같이 나올 것입니다.

사용자 삽입 이미지


























이 내용을 복사해서 메모장에 붙여 넣은 후 HelloWorld.wsdl로 저장합니다.

▶ Delphi 로 Client 만들기

1. 새로운 프로젝트을 만들어 주세요.

2  File > New > Other... 선택 WebServices 창에서 WSDL Importer 아이콘을 더블 클릭

사용자 삽입 이미지




















3. HelloWorld.wsdl 선택하고, [Next] 버튼 선택

사용자 삽입 이미지
























4. [Finish] 버튼 선택

사용자 삽입 이미지
























지금까지 하셨으면 HelloWorld1.pas 파일이 만들어 졌을 것입니다.

5. Unit1.pas을 열어서 Button 과 Edit Box을 추가 해주세요

6. Unit1.pas 아래와 같이 코딩 해주세요. 추가된 코드는 파란색으로 표시 해두었습니다.

unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    Button1: TButton;
    Edit1: TEdit;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
    FHelloWorld : HelloWorld;
  public
    { Public declarations }
    function GetHelloWorldService(): HelloWorld;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

function TForm1.GetHelloWorldService(): HelloWorld;
begin
  if FHelloWorld = nil then begin
    FHelloWorld := GetHelloWorld();
  end;
  Result := FHelloWorld;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  Edit1.Text := GetHelloWorld().getHelloWorldMessage('AXIS');
end;


end.

▶ 실행 결과

사용자 삽입 이미지

신고
TAG AXIS, Delphi, SOAP, wsdl

Lex&Yacc으로 SQL 파서를 만들어 보자

Programming/Delphi 2007.08.17 01:04 Posted by 파란크리스마스

정규표현식이나, Lex&Yacc을 델파이만 개발 하신 분이라면 처음 들어 보신 분들도 계실 것이라고 생각됩니다.
저도 6년 넘게 개발하면서 최근에 알게 되었고, 그 활용 범위가 무궁무진 하다는 것도 알게 되었죠.
이 글을 있는 개발자 분들도 이 글을 계기로 Lex&Yacc에 대해서 관심을 가졌으면 합니다.

Lex&Yacc은 컴파일러를 만들기 위한 도구로 GCC나 대부분의 컴파일러가 Lex&Yacc을 사용하고 있습니다.
Lex&Yacc의 활용 범위는 소스를 분석하거나, 소스에서 주석만 제거하거나, 간단한 스크립트 언어를 만들 수도 있습니다.

C언어나 JAVA의 경우 많은 Lex&Yacc 도구가 많이 있지만 Delphi의 경우 2개 정도 있는 것 같고,
제가 사용하고 있는 Delphi Lex&Yacc은 Tuber Pascal로 만들어 진 것을 델파이용으로 수정한 것으로 버전은 1.3을 사용했습니다.

아래의 예제는 데이터베이스에서 SQL을 파싱하는 아주 간단한 Sample을 만들어 보았습니다.

select aa, bb from tab;
select aa, bb, cc from tab1, tab2;

위의 SQL 문장에서 컬럼과 테이블 명을 구하는 Lex&Yacc 소스입니다.
위의 SQL 문장의 컬럼과 테이블 명을 구하는 것을 Lex&Yacc을 사용하지 않고도 쉽게 얻어 낼 수 있겠지만, 굉장히 긴 문장의 SQL문장에서 컬럼, 테이블, 함수, 문자열을 분리하는 것을 어려울 것입니다. 이와 같은 SQL문 처리를 위해서 여러분들이 Lex&Yacc문장을 추가 하시기 바랍니다. (인터넷에 SQL grammar 찾아서 추가하면 될 듯......)

▶ Delphi Lex & Yccc Download

http://www.grendelproject.nl/dyacclex/

▶ Lex 파일

- sqllex.l 파일

%start

%%
 
[F|f][R|r][O|o][M|m] begin return(FROM); end;
[S|s][E|e][L|l][E|e][C|c][T|t] begin return(SELECT); end;

[A-Za-z][A-Za-z0-9_]* begin
yylval.yyString := yytext;
return (NAME);  end;

[ \t\n] ;

. |
\n returnc(yytext[1]);

- sqllex.pas 만들기

C:\Delphi\dyacclex-1.3\test\sql>dlex.exe sqllex.l
Delphi Lex - Copyright (c) 2003,2004 by Michiel Rook
Based on Turbo Pascal Lex 4.1, Copyright (c) 1990-2000 Albert Graef
parse ... DFA construction ... code generation ... DONE
15 lines, 6 rules, 27/1200 p, 29/600 s, 58/1200 t.

▶ Yacc 파일

- sqlparser.y 파일

%{
program sqlpser;
{$APPTYPE CONSOLE}


uses
SysUtils,
dlib,
yacclib,
lexlib;

var x : array [1..26] of Real;

%}

%token NAME
%token FROM SELECT /* illegal token */

%%

query_spec:
SELECT selection table_exp ';'
;

table_exp:
from_clause
;

from_clause:
FROM table_ref_commalist
;

table_ref_commalist:
table_ref
| table_ref_commalist ',' table_ref
;

table_ref:
table
| table range_variable
;

range_variable: NAME
;

table:
NAME { writeln('Table : ', $1); }
| NAME '.' NAME
;

selection:
scalar_exp_commalist
| '*'
;

scalar_exp_commalist:
scalar_exp
| scalar_exp_commalist ',' scalar_exp
;

scalar_exp:
column_ref
;

column_ref:
NAME { writeln('Column : ', $1); }
| NAME '.' NAME /* needs semantics */
| NAME '.' NAME '.' NAME
;

%%

{$I sqllex.pas}

var
lexer : TLexer;
parser : TParser;
i : Integer;

begin
for i := 1 to 26 do
x[i] := 0.0;

lexer := TLexer.Create();
  
parser := TParser.Create();
parser.lexer := lexer;
parser.parse();
end.

- sqlparser.dpr 만들기

C:\Delphi\dyacclex-1.3\test\sql>dyacc.exe sqlparser.y sqlparser.dpr
Delphi Yacc - Copyright (c) 2003,2004 by Michiel Rook
Based on Turbo Pascal Yacc 4.1, Copyright (c) 1990-2000 Albert Graef
parse ... sort ... closures ... first sets ... LR0 set ... lookaheads ...
code generation ... DONE
89 lines, 18/900 rules, 29/1200 s, 41/9600 i, 33/9600 t, 19/1200 r.

▶ 컴파일, 실행

- 컴파일

위의 lex, yacc 절차를 따르셨다면 sqlparser.dpr, sqllex.pas 파일이 생겼을 것입니다.
sqlparser.dpr, sqllex.pas 한 폴더에 두고 델파이에서 sqlparser.dpr을 열어서 컴파일 하고 sqlparser.exe 실행 하면 됩니다.

C:\Delphi\dyacclex-1.3\test\sql>sqlparser
select aa, bb from tab;
Column : aa
Column : bb
Table : tab
신고

TInterfaceList 사용하기

Programming/Delphi 2007.08.17 00:57 Posted by 파란크리스마스
델파이의 경우도 JAVA와 같이 객체의 상속은 하나만 되고, Interface의 상속은 다중으로 되고 있습니다. 객체의 어떠한 성격을 Interface로 만들고 그 것을 Collection 객체에 담아 두었다가 다시 사용할 수 있는 것은 OOP 프로그램을 하면서 유용하게 사용할 수 있을 것입니다. 최근에 TInterfaceList 가 있는 것을 알게 되었네요. 그래서 여기 Tip에 올립니다.

type
  IDatabase = interface
    function GetDatabaseName() : String;
  end;

  TDatabase = class(TInterfacedObject, IDatabase)
  private
    FDtabaseName : String;
  public
    procedure SetDatabaseName(ADatabaseName : String);
    function GetDatabaseName() : String;
  end;

{ TDatabase }

procedure TDatabase.SetDatabaseName(ADatabaseName : String);
begin
  Self.FDtabaseName := ADatabaseName;
end;

function TDatabase.GetDatabaseName() : String;
begin
  Result := Self.FDtabaseName;
end;

{ TForm1 }

procedure TForm1.Button1Click(Sender: TObject);
var
  DatabaseList : TInterfaceList;
  ADatabase : TDatabase;
  InterfaceDatabase : IDatabase;
  i : integer;
begin
  DatabaseList := TInterfaceList.Create;

  ADatabase := TDatabase.Create;
  ADatabase.SetDatabaseName('Oracle');
  InterfaceDatabase := ADatabase;
  DatabaseList.Add(InterfaceDatabase);

  ADatabase := TDatabase.Create;
  ADatabase.SetDatabaseName('MsSQL');
  InterfaceDatabase := ADatabase;
  DatabaseList.Add(InterfaceDatabase);

  for i :=0 to DatabaseList.Count-1 do begin
    Memo1.Lines.Add(IDatabase(DatabaseList[i]).GetDatabaseName());
  end;
end;

신고

TCollection 사용하기

Programming/Delphi 2007.08.17 00:54 Posted by 파란크리스마스

type
  TDatabase = class (TCollectionItem)
  private
    FDatabaseName: String;
  published
    property DatabaseName: String read FDatabaseName write FDatabaseName;
  end;

  TDatabaseList = class (TCollection)
  private
    function GetItem(Index: Integer): TDatabase;
  public
    function Add: TDatabase;
    property Item[Index: Integer]: TDatabase read GetItem;
  end;
 
{ TDatabaseList }

function TDatabaseList.Add: TDatabase;
begin
  result := inherited Add as TDatabase;
end;

function TDatabaseList.GetItem(Index: Integer): TDatabase;
begin
  result := inherited Items[Index] as TDatabase;
end;

{ TForm1 }

procedure TForm1.Button1Click(Sender: TObject);
var
  DatabaseList : TDatabaseList;
  aDatabase : TDatabase;
  i : Integer;
begin
  DatabaseList := TDatabaseList.Create(TDatabase);

  aDatabase := DatabaseList.Add;  // create one hair
  aDatabase.DatabaseName := 'Oracle';

  aDatabase := DatabaseList.Add;  // create another hair
  aDatabase.DatabaseName := 'MsSQL';

  for i :=0 to DatabaseList.Count-1 do begin
    Memo1.Lines.Add(DatabaseList.Item[i].DatabaseName);
  end
end;

신고


 

티스토리 툴바