반응형

unit Unit1;

interface

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

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

var
  Form1: TForm1;

implementation

{$R *.dfm}

function IsDigit(ch: Char): Boolean;
begin
  Result := ch in ['0'..'9'];
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  s1, s2: String;
  i: integer;
begin
  s1 := Edit1.text;

  for i:=1 to length(s1) do
  begin
    s2 := '';

    if IsCharAlphaNumeric(s1[i]) then
    begin
      s2 := s2 + '<영문 or 숫자>';

      if IsDigit(s1[i]) then
        s2 := s2 + '<숫자>'
      else if IsCharAlpha(s1[i]) then
      begin
        s2 := s2 + '<영문>';
        if IsCharLower(s1[i]) then
          s2 := s2 + '<소문자>'
        else if IsCharUpper(s1[i]) then
          s2 := s2 + '<대문자>'
      end;
    end
    else if IsDBCSLeadByte(Byte(s1[i])) then
    begin
      // IsDBCSLeadByte()는 double byte character set(DBCS) 의 lead byte인지 검사합니다
      s2 := s2 + '<한글 or 한문>';
    end;
    
    Memo1.Lines.Add(s1[i]+' = '+s2);
  end;  
end;

end.

반응형
반응형

해당사이트의 referer 차단으로 인해 403 forbidden 에러나 기타 사용자가 지정한 에러로 막혀서


밤새 고민 했는데


의외로 idhttp나 httpcli 자체에 reference 기능이 있어서 허탈했다.


property에 가보면 reference에 해당 사이트의 주소를 입력하면 이미지나 기타 파일들을 잘 가져오는 것을 볼 수 있다.



반응형
반응형

Where is this error coming from? In the example we are using DataSnap TCP/IP connectivity, which is internally implemented using Indy framework. The Indy implementation has changed between XE and XE3 versions, so there are little changes needed. On the server it is necessary to add "IPPeerServer" to the interface "uses" clause in the "ServerContainerUnit1" and on client we need to add "IPPeerClient" to the interface "uses" clause in the "ClientModuleUnit1". In fact the IDE can add these entries automatically. Just put the cursor somewhere in the "uses" clause of these two files and when you press "Enter" correct entries will be added for You! Cool:-)

I have also added a project group file "SimpleCalcGrp" and updated forms’ captions to "XE3".



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

델파이 XE의 멀티티어 서버 예제를 XE3에서 실행하면 다음과  같은 에러를 확인 할 수 있다.


uses절에 IPPeerServer를 추가하면 해결.




반응형
반응형

말씀하신대로 dbExpress 데이터셋의 경우 unidirectional이라고 해서 단방향 진행만 가능합니다.
다른 부분에는 문제가 없지만, 데이터셋에서 전진 뿐 아니라 역방향으로 진행해야 한다면 말씀하신 것처럼 예외가 발생합니다.
대표적인 경우가 TDBGrid와 같은 그리드에 연결하거나, 말씀하신 경우와 같은 레포트 컴포넌트와 연결할 경우입니다.

이런 경우엔 중간에 클라이언트데이터셋(TClientDataSet)을 끼워 넣어서 한단계 더 거치도록 하면 됩니다.
dbExpress 데이터셋(TSQLDataSet 이라고 가정하죠)을 그리드(혹은 레포트)에 직접 연결하지 말고 TClientDataSet을
거쳐서 연결하는거죠. 그리고 원래의 TSQLDataSet과 TClientDataSet을 연결하기 위해 다시 TDataSetProvider을 중간에
추가합니다.

따라서 이전에 컴포넌트들 사이의 연결 상태가 다음과 같았던 경우,
TSQLConnection – TSQLDataSet – TDataSource – 그리드/레포트
다음과 같이 됩니다.
TSQLConnection – TSQLDataSet – TDataSetProvider – TClientDataSet – TDataSource – 그리드/레포트

여기서 TClientDataSet – TDataSource간의 연결은 일반적인 데이터셋 연결의 경우처럼 TDataSource의 DataSet 속성을
통해 연결합니다. 그리고 TDataSetProvider – TClientDataSet간의 연결은 TClientDataSet의 ProviderName 속성으로
연결하고요. TSQLDataSet – TDataSetProvider간의 연결은 TDataSetProvider 컴포넌트의 DataSet 속성을 이용합니다.

이같은 과정이 지나치게 복잡하게 느껴진다면 몇개의 컴포넌트가 조합된 편의용 컴포넌트를 사용할 수 있습니다.
델파이 6의 dbExpress 탭에 TSQLClientDataSet이라는 컴포넌트가 있는데, TSQLDataSet, TDataSetProvider,
TClientDataSet의 세가지 컴포넌트가 조합된 컴포넌트입니다. ConnectionName 속성으로 SQLConnection과 연결하고,
TDataSource에서 DataSet 속성으로 직접 가리켜질 수 있습니다.

델파이 7에서는 이 컴포넌트가 없어지고 대신 TSimpleDataSet라는 컴포넌트가 도입되었습니다.
두 컴포넌트는 비슷하기는 하지만 다른 부분도 적지 않습니다. (델파이 6의 TSQLClientDataSet 컴포넌트의 문제점 때문에
새로 도입된 것입니다)

그럼…

interBeginner 님이 쓰신 글 :
: dbExpress 를 사용해서 레포트를 출력하는데
: Group Band 에서 계속 operation not allowed on a unidirectional dataset 이란 오류가 뜹니다.
: dbExpress 콤포는 unidirectional 만 가능한 걸로 알고 있는데
: 퀵에서 커서가 back 이 안되서 오류가 나는것 같은데
: 혹시 이런 경우를 해결하신 분 있으면 도움 부탁드립니다.

 

반응형
반응형
클래스 메서드는 메서드를 정의할 때, class 예약어를 추가한 메서드를 말합니다.
클 래스 메서드는 특정 객체에 종속되지 않는 메서드 입니다. 이 말은 Self 레퍼런스가 존재하지 않는다는 것이며, 달리 말하면 멤버 필드 값을 참조할 수 없다는 것입니다. 다음 소스 파일을 컴파일 하면 클래스 메서드인 ClassMethod 내에서는 멤버 필드 값 참조 코드가 모두 에러로 처리됨을 알 수 있습니다.

unit Unit2;

interface

type
  TTestClass = class(TObject)
  private
    FOne: Integer;
    FTwo: string;
  public
    class procedure ClassMethod;
    procedure NormalMethod;
  end;

implementation

class procedure TTestClass.ClassMethod;
begin
  FOne := 10;       // Compile Error
  FTwo :='abcdef';  // Compile Error
end;

procedure TTestClass.NormalMethod;
begin
  FOne := 10;
  FTwo :='abcdef';
end;

end.

멤 버 필드를 참조하지 못한다는 점으로만 판단하면, 클래스 메서드는 별로 사용가치가 없어 보이나, 사실 그렇지 않습니다. 일반 메서드는 반드시 객체를 생성하고 초기화한후에야만 호출할 수 있지만, 클래스 메서드는 객체 생성을 하지 않아도 일반 전역 함수처럼 호출 할 수 있습니다. 다음 코드가 이를 설명합니다.

procedure CallTest;
var
  obj : TTestClass;
begin
  // 클래스 메서드는 클래스명을 참조하여 직접 호출 가능함
  TTestClass.ClassMethod;
  // 클래스 메서드는 생성되지 않는, 즉 초기화하지 않은 객체를 통해서도 호출 가능
  obj.ClassMethod;

  // 일반 메서드는 객체 생성후에야만 호출 가능
  obj := TTestClass.Create;
  obj.NormalMethod;

  // 클래스 메서드는 생성된 객체를 통해서도 호출 가능
  obj.ClassMethod;
  
  obj.Free;

end;


클 래스 메서드를 대체 어떤 경우 사용해야 할까요? 객체 지향 이론에 의하면, 전역 함수는 프로그램 유지 보수를 어렵게 만들기 때문에, 전역함수 대신,  메서드를 사용하라고 권합니다. 이 이론을 따라서, 전역함수를 특정 클래스의 일반 메서드로 정의했다면, 그 메서드를 호출하려면, 앞의 예제에서 봤듯이 항상 객체 생성/파괴와 관련된 코드가 수반되어야 합니다.

반면에 클래스 메서드는 객체 생성과 파괴 없이도 호출할 수 있기 때문에 전역적 함수 역할을 충분히 대신할 수 있다는 이야기 입니다.

즉 클래스 메서드는, 관련된 전역함수들끼리 특정 클래스에 모아두고, 메서드를 전역 함수 처럼 사용할 수 있게 하는 것입니다.

클래스 메서드 사용예로서, 로그인을 처리하는 다음과 같은 클래스를 만들었다고 가정합시다

unit Unit3;

interface.

type
  TLogin = class(TObject)
  public
    class procedure Login;
    class procedure Logout;
  end;

implementation

var
  // 요 파일에서만 참조 가능하도록 implementation 영역에서 변수 정의
  LoginCnt : integer = 0;
  LoginId, Password : String;

class procedure TLogin.Login;
begin
  // Login Process Code
  // Get Id
  // Get Password

  inc(LoginCnt);
  if LoginCnt > 4 then
  begin
    ShowMessage('Max log count limit. Program shut down');
  end;
end;

class procedure TLogin.Logout;
begin
  // Log out
end;

이제 로그인 작업을 처리하려면 다음과 같이 하면 될 것 입니다.

procedure SomeJob;
begin
  TLogin.Login;
end;

유감스럽게도 델파이에는 클래스 메서드는 있으나 클래스 필드는 없습니다. 즉 다음과 같이 코딩할 수는 없습니다.

TLogin = class(TObject)
  private
    class ID : string;      // 클래스 필드는 지원하지 않음. 컴파일 에러
    class Password : string; // 클래스 필드는 지원하지 않음. 컴파일 에러
  public  
    class procedure Login;
    class procedure Logout;
  end;

이 때문에 TLogin 클래스와 밀접한 관계가 있는  LoginCnt, LoginId, Password 등을 멤버 필드로 정의하지 못하고, 유닛 전역적 변수인 implementation 영역에서 정의했습니다. 이 변수들을 멤버 필드로 정의해 버리면 클래스 메서드인 Login은 이 값을 참조할 수가 없기 때문입니다.

결론적으로 이야기해서, 클래스 정의가 어떤 변수와 그 변수를 사용하는 함수들간에 문법적 결합을 설정하는 것처럼, 클래스 메서드란 관련성 있는 전역 함수들 간에 문법적 결합을 설정하는 것입니다.
 


반응형
반응형

var
  aaa : Integer;
begin
  aaa :=  StrToIntDef('a',-1);

  edt_1.Text := FormatFloat('#,',aaa);


세자리수 마다 끊어서 , 출력

반응형
반응형

녕하세요.

 

StringGrid 내용을 자동으로 스크롤 시키는 팁이 있어서 소개해 드립니다.

 

 

 

 

StringGrid의 데이터 영역에서 마우스를 클릭한 상태로 상하좌우로 이동하면

데이터 영역이 자동으로 스크롤 됩니다.

 

루틴은 아래와 같이 간단 합니다.

 

procedure TForm1.StringGrid1MouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
var
  px,py: Integer;
begin
  if not flag then Exit;
  //if not(ssCtrl in Shift) then Exit;

  px := GetScrollPos(StringGrid1.Handle, SB_HORZ);
  py := GetScrollPos(StringGrid1.Handle, SB_VERT);
  px := px - (X - x1);
  py := py - (Y - y1);

  StringGrid1.Perform(WM_HSCROLL, px shl 16 or SB_THUMBPOSITION, 0);
  StringGrid1.Perform(WM_VSCROLL, py shl 16 or SB_THUMBPOSITION, 0);

  x1 := X;
  y1 := Y;
end;

 

여러가지로 응용이 가능 할 것 같은데요...

 

반응형
반응형

팁은 담비님(천리안 FREKBS)님이 99년 4월 1일에 천리안 프로그래머포럼에 올리신 것입니다.
담비님으로부터는 전제하여 올리는 데 대해 허락을 받았습니다.
좋은 정보를 공유하도록 허락해주신 담비님께 감사드립니다.

-----------------------------------------------------------------------
안녕하세요! 담비입니다.

출처 : http://www.inprise.co.jp/tips/cbuilder/cb010/index.html

메모 콤포넌트는 윈도우 클래스의 "EDIT"를 사용하고있지만, 모든 메세지를 커버
하는것은 아니다. 메모 콤포넌트가 제공하고 있지 않는 주요한 메세지들에 관하여
소개한다.

메모 콤포넌트와 메세지
----------------------

Memo Component는 복수행에 걸쳐 문자열을 편집할 수 있는 기본적인 component이다.
이것은, Windows가 제공하는 Window Class인 "EDIT"를 사용하여 실현하고 있다.
Memo Component는, "EDIT" 클래스가 메세지에 의해 제공하고 있는 기능을 많은
method나 property를 사용해 이용할 수 있도록 하고 있다. 그러나, 그다지 사용되지
않는 일부의 메세지에는 대응하는 property와 method가 존재하지 않는다. 아래는,
Memo Component를 사용하여 제공되지 않는 주요한 메세지와 그 사용 예를
나타낸것이다. 다시말하자면 , 콤포넌트에 메세지를 보내기위해 Perform method를
사용할 수 있다. Perform의 첫번째 인수에는 메세지를 두번째 인수에는
WParam(int형), 세번째 인수에는 LParam(int형)을 건네준다. WParam과 LParam은
메세지마다의 역할이 다르다. 이들 인수가 사용되지 않는 경우에는 0을 건네준다.

EM_GETRECT, EM_SETRECT, EM_SETRECTNP
──────────────────
Memo 컴포넌트중에서 편지영역으로 사용할 영역을 취득, 설정한다.
Perform의 LParam에는, 지정하는 범위를 나타내는 RECT형 변수의 주소를 건내준다.
예를 들자면, 다음의 프로그램은, Memo1 컴포넌트의 편집 영역을 Memo1 전체로부터
10 dot 이내로 한다. EM_SETRECTNP는, 메모 컴포넌트의 내용을 다시 그리지는
않는다는 점을 제외하고, EM_SETRECT와 동일하다.

    RECT R := Memo1->ClientRect;
    InflateRect(&R, -10, -10);
    Memo1->Perform(EM_SETRECT, 0, (int)&R);

다음의 프로그램은, Memo1 컴포넌트에 실제로 표시되어지는 행수를 계산한다.
    RECT R;
    Memo1->Perform(EM_GETRECT, 0, (int)&R);
    int N = (R.bottom - R.top) / Canvas->TextHeight("H");


EM_SCROLL
─────
Memo 컴포넌트의 내용을 상하 스크롤시키는 메세지이다. WParam에는 4종류의
스크롤 방법을 지정할수 있다.

SB_LINEDOWN     1줄 아래로 스크롤
SB_LINEUP       1줄 위로 스크롤
SB_PAGEDOWN     1페이지 아래로 스크롤
SB_PAGEUP       1페이지 위로 스크롤

다음의 프로그램은, Memo1의 내용을 1줄 아래로 보이게(전체를 1줄 위로하여)
스크롤 한다.
    Memo1->Perform(EM_SCROLL, SB_LINEDOWN, 0);

EM_LINESCROLL
───────
Memo 컴포넌트의 내용을 상하좌우로 스크롤하는 메세지이다.
WParam에는 수평방향의 문자수를, LParam에는 수직방향의 행수를 건제준다.
스크롤되어지는 의미가 없는 경우는 무효이다. 예를들자면, WordWrap property가
true인 때는 수평스크롤은 할수없다.
다음의 프로그램은 Memo1의 내용을 2문자와 2행의 좌상으로 스크롤한다.
    Memo1->Perform(EM_LINESCROLL, 2, 2);


EM_CANUNDO, EM_UNDO, EM_EMPTYUNDOBUFFER
────────────────────

편집 조작을 취소시키기 위한 메세지이다. Memo 컴포넌트는 상에서 Ctrl-Z을 누르면
현재 텍스트메뉴에서 [취소 (U)]를 실행한것과 동일한 처리를, 프로그램으로부터
실행할수 있다. EM_CANUNDO는, 원래대로 되돌릴 편집조작이 있는가를 판단하기
위한것이다. 예를 들자면, EM_CANUNDO의 결과가 false에 있는 경우 [취소 (U)]이라는
조작을 금지시킬수 있다. 또, EM_EMPTYUNDOBUFFER은 원래대로 되돌릴 조작을 위한
버퍼를 클리어한다. EM_EMPTYUNDOBUFFER 메세지가 보내진 후에는, EM_CANUNDO는
false를 되돌린다. 이들 메세지는 어느것도 Wparam, Lparam을 사용하지 않는다.

EM_LINEFROMCHAR
────────
지정한 문자위치에 있는 행을 되돌린다. 문자의 위치와 행번호는, 각각 0이 시작점
이 된다. 마지막으로, 선두의 문자와 선두의 행은 0의 값에서 나타난다. 문자위치는
WParam에 건네주지만, -1을 건네주면 현재 커서위치의 행번호를 돌려준다. 다음의
프로그램은, Memo1의 OnKeyUp 이벤트를 사용하여, 키입력이 있을때마다의 현재의
행번호를 Caption에 표시한다.
    void __fastcall TForm1::Memo1KeyUp(TObject *Sender, WORD &Key,
          TShiftState Shift)
    {
        Caption = IntToStr(Memo1->Perform(EM_LINEFROMCHAR, -1, 0) + 1);
    }


EM_SETTABSTOPS
───────
Tab Stop의 위치를 지정하는 메세지이다. WParam에는, 지정하는 Tab Stop 배열의
요소수를, LParam은 Tab Stop 배열에 대한 주소값을 건네준다. 그러나, WParam의
값에 따라 LParam의 평가방법이 변하게 된다.           
WParam이 0인 경우, LParam에 관련된 Tab Stop의 위치는 8문자 단위가 되어지다.
WParam이 1인 경우, LParam에 지정하는 배열은 1개의 요소만을 가지지만, Tab Stop은
여기에 지정된 위치가 연속적으로 반복되어진다.
WParma이 2 이상인 경우, LParam이 지정한 배열은 WParam개의 요소를 가지고, 이
범위를 초과한 부분은 Default의 Tab Stop위치를 가지게 된다.
Tab Stop은 DWord형의 배열로 지정하고, 위치는 Dialog 단위로서 나타내진다.
Tab Stop 단위는 문자폭의 평균치의 1/4이 되기때문에, 4문자 단위의 Tab Stop을
지정한 경우에는 16을 지정한다.
다음의 프로그램은, Memo1 컴포넌트의 Tab Stop을 2문자 단위로 한다.
    DWORD TabStops[1] = { 4 * 2 };
    Memo1->Perform(EM_SETTABSTOPS, 1, (int)TabStops);


EM_FIRSTVISIBLELINE
──────────
Memo 컴포넌트상에서, 실제로 눈에 보여지고 있는 최초의 행의 행번호를 되돌려준다.
(최초의 행은 0)

EM_GETMARGINS, EM_SETMARGINS
──────────────
Memo 컴포넌트상에서 좌우의 여백을 설정한다. WParam은 성정한 여백의 종류를
나타내고, LParam은 MAKELONG과 병용하는 여백의 크기를 나타낸다.
다음의 프로그램은, 좌측에 20 dot, 우측에 30 dot의 여백을 설정한다.
    Memo1->Perform(EM_SETMARGINS,
                   EC_LEFTMARGIN : EC_RIGHTMARGIN, MAKELONG(20, 30));


EM_POSFROMCHAR, EM_CHARFROMPOS
───────────────
Memo 컴포넌트상의 좌표와 문자의 위치를 상호 변환시키는 메세지이다.
EM_POSFROMCHAR은, 지정된 문자위치(텍스트의 선두로부터의 바이트 수의 문자의
좌상의 좌표를 되돌려준다. WParam에는, TPoint형의 변수를 사용하는 주소값을
되돌려준다.
EM_CHARFROMPOS에는, 클라이언트 영역의 좌표로부터 그 장소에 있는 문자의 위치
(텍스트의 선두로부터의 위치와 행번을 되돌려준다.
다음의 프로그램은, Memo1의 OnMouseMove 이벤트를 사용하여, 마우스 커서상에
있는 문자의 위치와 행번을 Caption에 표시하는것이다.
    void __fastcall TForm1::Memo1MouseMove(TObject *Sender, TShiftState Shift,
          int X, int Y)  
    {
        DWORD DW = Memo1->Perform(EM_CHARFROMPOS, 0, MAKELONG(X, Y));
        Caption = IntToStr(LOWORD(DW)) + ":" + IntToStr(HIWORD(DW));
    }  


반응형
반응형