레이블이 델파이인 게시물을 표시합니다. 모든 게시물 표시
레이블이 델파이인 게시물을 표시합니다. 모든 게시물 표시

2022년 6월 4일 토요일

Lazarus 2.2.2(2022.5.16) 버전 Mac에 설치 (lldb 디버거 설정 포함)

 최소 macOS 10.12 이상이 필요합니다.  다운로드는 이곳

세 가지 패키지 fpc, fpc-src 및 LazarusIDE를 모두 다운로드하여 설치해야 합니다. 

fpc - 컴파일러, 일부 명령줄 도구, 기본 장치 및 데이터베이스 액세스와 같은 비시각적 구성 요소 

fpc-src - 코드 브라우징에 필요한 fpc 및 패키지의 소스 

LazarusIDE - IDE, 시각적 구성 요소 및 도움말 파일



Step 1: Xcode Command Line Tools (최신버전의 Mac 사용자는 설치가 필요없더군요)

sudo xcode-select --install
sudo xcodebuild -license accept

Step 2: FPC binaries and FPC source code



Step 3: Install the Lazarus IDE



Step 4: Configure the Debugger


4-1. Lazarus를 실행하면 Debuger 설정을 요구합니다. (1) (2) 버튼을 선택합니다.

파인더 창이 나타나면 Shit + Cmd + . (시프트 + 코멘더+ 점)키를 눌러 감추어진 폴더와 파일을 보이게합니다.

4-2. (1)use (2)bin (3)lldv 를 선택하고 (4)Open을 선택합니다.



OK를 확인하고 Start IDE를 선택합니다. 

4-3. 계속하여







* 참고로 Lazarus를 처음 실행하면 창들이 분리되어 있습니다. 하나로 합치려면 아래와 같이 anchordocking, anchordockingdsgn Packages를 설치합니다.



2022년 5월 13일 금요일

Delphi MAC에서 DataBase 연결

1. LiveBinding 나타나게 하기
Tools > Options > Livebinding > Options 에서
Display Livebindings wizard in context Menu 를 체크해준다.

2. 라이브러리 패스 설정은 platform 마다 해주어야한다.


2021년 11월 21일 일요일

델파이 11 버전으로 만들어진 윈도우32비트 실행파일을 윈도우XP에서 실행하기.

아직도 각종 기기를 제어하는 시스템에는 윈도우XP를 상당 사용하고 있습니다. (시스템 프로그램에 굳이 비용과 아이센스측면에서 윈도우7 이상을 사용할 이유는 없는 경우가 많습니다) 

iMac 에서 윈도우프로그램을 델파이로 만들어 실행파일을 돌려볼라치면 부트캠프를 사용하거나, 파라랠즈 같은 가상머신을 돌려서하는 방법이 있습니다. 

그런데 가상머신의 용량이 너무커서 부담이되어 패러럴즈에서 윈도우 XP를 설치하여 실험하면 좋겠다고 생각되어 XP를 설치하였습니다.

윈도우 10은 Lite버전을 설치한 후 델파이11 Alexandria 을 설치하였고,
윈도우 XP는 OS만 설치한후 용량입니다.

델파이11버전으로 윈32실행파일을 생성하여 XP에서 실행하려고 하면 "올바른 Win32응용 프로그램이 아닙니다"(아래)라는 경고창을 볼 수 있습니다.

구굴링해본 결과 델파이 11버전의 업그레이드버전에서는 문제가 해결되었다고 하네요.

업그레이드 이전 버전에서는 (수정. 2021.11 업그레이드 이후에도 아래와 같이 바꾸어주어야함)

 PE Header  부분을 6.0 에서 5.1로 수정하면 되더군요.



또는 프로젝트 소스에서 
program notepad_clone;
{$SETPEOSVERSION 5.1}     // 5.1 로 변경
{$SETPESUBSYSVERSION 5.1} // 5.1 로 변경 

만약 쓰레드를 사용하는 경우에는  Delphi 11 Windows XP compatibility tweak 을 참조하세요.

#delphi11 #windowsxp #windows32 #올바른 Win32 응용 프로그램 #delphi







2021년 11월 15일 월요일

iMac Big Sur 에서 윈도우98 설치하여 Delphi6.0을 설치하여 실행

 iMac Big Sur 에서 윈도우98 설치하여 Delphi6.0을 설치하여 실행하였습니다.

DOSBox-X 를 방문하시면 OS X (iMAC등)에서 윈도우98SE 설치방법을 알 수 있습니다.

참고로 위 홈피에서 언급하지 않은 사항만 알려드립니다.

DosBoox-X를 처음 실행하면 디렉토리를 지정하라고 합니다. 저는 문서폴더에 폴더를 하나만들어 지정하였습니다.(나중에 이미지 생성시 이곳에 생성되고, 델파이 .ISO 파일도 이곳에 둡니다)

도스박스 윈도우98 환경은 

/Users/jglee/Library/Preferences/DOSBox-X 0.83.19 Preferences

에 있으니 위 홈피에 나온 방법으로 수정하시면 됩니다.(반드시 수정하셔야  설치에 실수가 없습니다. 진짜 win98Se 정도의 속도 밖에 안나옴니다. 나중에 cpu 설정을 바꾸면 되겠지요)

DosBox-X를 압축해제 한 후 iMac의 Application 폴더로 복사/붙여넣기하신후 런처에서 실행하시면 됩니다.(런처에서 실행시 Preferences 설정환경으로 실행됩니다. Windows98SE 설치 참조)

DosBox-X 에서

IMGMAKE hdd.img -t hd_2gig
IMGMOUNT C hdd.img
IMGMOUNT D Win98.iso
IMGMOUNT A -bootcd D
BOOT A:

윈도우98 설치중 DosBox-X가 종료되면(실제 PC에서는 종료됩니다) 

아래와 같이 지정하고 재부팅하면 관련드라이버를 자동으로 잡습니다. (2회)

IMGMOUNT C hdd.img
IMGMOUNT D Win98.iso
BOOT C:

델파이6.0을 설치하려면 Borland Delphi 6.0 에서 다운 받은 후 압축해제 후 위에서 언급한 디렉토리에 저장하시면 됩니다.

IMGMOUNT C hdd.img
IMGMOUNT D Delphi60.iso
BOOT C:

2021년 10월 18일 월요일

델파이 소스를 간명하게 하기위한 방법중 하나

델파이 소스를 간명하게 하기위한 방법중 하나입니다.

필드영역에 보면 디자인 이후에 사용되지 않는 컨트롤이 잡다하게 있어 보기 싫을 경우가 있으면 해당 필드를 소스에서만 삭제하면 간명해집니다.  또다른 방법은 해당 콘트롤의 이름 속성을 오브젝트인스펙터에서 지워서 빈칸으로 하면 됩니다.

대신 삭제된 클라스를 ResisterClass()  로 등록해주면 됩니다.

아래 예제 그림 참조!





2021년 9월 17일 금요일

델파이 이전버전의 폼을 불러와 실행하면 스크린에 확대되어 보이는 경우가 있다.

 델파이 이전버전의 폼을 불러와 실행하면 스크린에 확대되어 보이는 경우가 있다.

아마도 아래와 같은 형태일 것이다.

 SnapBuffer = 5

  OnClose = FormClose

  OnCreate = FormCreate

  PixelsPerInch = 192

  DesignSize = (

    2733

    1783)

  TextHeight = 54


에서 처럼 PixelsPerInch = 192 로 되어 있다. 이것을 96으로 바꾸어 주자.

그렇기 위해서는 .DFM 파일을 텍스트로 변환하여야 한다.

델파이에서는 View as Text 가 안된다.

2021년 9월 13일 월요일

Delphi 11에서 RXLIB 2.7.5 사용하기

 Non offcial

다운로드 받은다음

rx.inc 파일 중간을

{$IFDEF VER350} { Embarcadero Delphi 11  }   // 
  {$DEFINE RX_D3}
  {$DEFINE RX_D4}
  {$DEFINE RX_D5}
  {$DEFINE RX_D6}
  {$DEFINE RX_D7}
  {$DEFINE RX_D9}
  {$DEFINE RX_D10}
  {$DEFINE RX_D11}
  {$DEFINE RX_D12}
  {$DEFINE RX_D14}
  {$DEFINE RX_D15}
  {$DEFINE RX_D16}
  {$DEFINE RX_D17}
  {$DEFINE RX_D18}
  {$DEFINE RX_D19}
  {$DEFINE RX_D20}
  {$DEFINE RX_D21}
  {$DEFINE RX_D22}
  {$DEFINE RX_D23}
  {$DEFINE RX_D24}
  {$DEFINE RX_D25}
  {$DEFINE RX_D26}
  {$DEFINE RX_D27} //Sydney specific
  {$DEFINE RX_D28} //Alexandria
{$ENDIF}

로 고치면 됩니다.


2021년 7월 22일 목요일

swift vs delphi: 01

Swift를 공부하면서 Delphi를 재정립하자.

Structure

//Swift
struct Resolution {
var width = 0;
var height = 0;
}
let hd = Resolution(width: 1920, height: 1080)
var someResolution = Resolution(width: 640, height: 480) 

//Delphi
type
  TResolution = record
    width: integer;
    height: integer;
  end;
const
  hd: TResolution = (width: 1920; height: 1080);
var
  someResolution: TResolution = (width: 640; height: 480);

//Swift
  1. @propertyWrapper
  2. struct TwelveOrLess {
  3. private var number = 0
  4. var wrappedValue: Int {
  5. get { return number }
  6. set { number = min(newValue, 12) }
  7. }
  8. }

  9. //Delphi
  10. type TResolution = record private number : integer; function getWappedValue: integer; procedure setWappedValue(const Value: integer); property wrapValue: integer read number write number; property wrappedValue: integer read getWappedValue write setWappedValue; end;

  11. function TResolution.getWappedValue: integer;
  12. begin
  13.   Result:= number;
  14.   // willSet
  15. end;
  16. procedure TResolution.setWappedValue(const Value: integer);
  17. begin
  18.   if Value > 0 then
  19.     number:= Value
  20. else Value := 0;
  21.   // didSet
  22. end;


2021년 7월 21일 수요일

델파이 인터페이스

 델파이 인터페이스를 전혀 이해를 못하다가 Swift의 Protocol을 공부하면서 이해가 되었습니다. 물론 정확한지는 모르지만 제가 이해하는 수준입니다. 

이론적 배경은 구글링을 하시면 어렵게 설명되어 있으니 시스템프로그램하시는 분은 그곳을 참고하시고 저는 사용하는 입장에서만... 

Interface 가 도입된 배경은 Windows 32 시스템에서 COM을 사용하기 위한 것이고 지금은 COM을 사용하는 경우가 별로 없으니 GUID(Shift+Ctrl+G)는 생성할 필요는 없습니다.

먼저 다음과 같이 선언해보십시요.

type
  iCalc = interface
    function calcAdd(adx, bdx: integer): integer;
    function calcMulti(adx, bdx: integer): integer;
  end;
  TiCalc = class(TInterfacedObject, iCalc)
    function calcAdd(adx, bdx: integer): integer;
    function calcMulti(adx, bdx: integer): integer;
  end;
  jCalc = interface
    function calcSub(adx, bdx: integer): integer;
    function calcDivide(adx, bdx: integer): integer;
  end;
  TjCalc = class(TiCalc, iCalc, jCalc)
    function calcSub(adx, bdx: integer): integer;
    function calcDivide(adx, bdx: integer): integer;
  end;

구현은 Interface에서 하지 않고 Class에서 합니다.

TJCalc 가 다중상속되었슴에 주의하시면 되겠습니다. 

사용은 아래그림 및 아래와 같이하고


procedure TForm1.Button1Click(Sender: TObject);
var adx: iCalc;
begin
  adx:= TiCalc.Create;
  Label1.Caption:= adx.calcAdd(2, 3).ToString;
  //adx.free   Not need
end;
procedure TForm1.Button2Click(Sender: TObject);
var adx: jCalc;
begin
  adx:= TjCalc.Create;
  Label1.Caption:= adx.calcDivide(40, 2).ToString;
  //adx.free   Not need
end;
procedure TForm1.Button3Click(Sender: TObject);
var adx: iCalc;
begin
  adx:= TiCalc.Create;
  Label1.Caption:= adx.calcAdd(40, 2).ToString;
  //adx.free   Not need
end;

Button3에서는  TjCalc에서 구현하지 않은 상속받은 calcAdd 메소드를 사용했습에 주의하십시요.

결국 스위시의 프로토콜처럼 어떤 객체에 반드시 구현되어야 할(앞으로 사용 할 것임을 알리는?) 메소드를 먼저 선언한게 아닐까? 사용시에는 이것(Interface)만 보면 되겠지요.

 

2021년 4월 28일 수요일

Delphi 10.4.2 TControlList 이해를 돕기위한 초간단 예제

델파이에서 애플의 테이블뷰를 구현 할 수 있게 되었습니다.

새로운 폼을 하나 만들고 ControlList를 alClient 로 올려놓고

ControlList 의 Item (prototype) 영역에 Label을 하나 올려 놓습니다.

간단하게하기위해 자료 컨테이너는 iMemo: TStringList 로 지정하고

아래 소스처럼 초기값을 넣습니다.

ComtrolList1.ItemHeight := 22;

procedure TForm2.ControlList1BeforeDrawItem(AIndex: Integer; ACanvas: TCanvas;
  ARect: TRect; AState: TOwnerDrawState);
begin
  Label1.Caption:= iMemo[Aindex];
end;
procedure TForm2.FormActivate(Sender: TObject);
begin
  iMemo:= TStringList.Create;
  iMemo.CommaText:= 'Hello, World,1,2,3,4,5,6,7,8,9';
  ControlList1.ItemCount:= iMemo.Count;
end;
procedure TForm2.FormDeactivate(Sender: TObject);
begin
  iMemo.Free;
end;

결과화면



 


2021년 3월 31일 수요일

Delphi 10.4.2 TControlList 예제

RAD스튜디오 10.4.2는 새로운 VCL 컨트롤들을 선보입니다. 그 중 TControlList는 매우 긴 리스트를 효과적으로 제어할 수 있는 컨트롤입니다. 현대식 룩앤필로, 원한다면 UI를 얼마든지 마음대로 설정할 수 있습니다.

파이어몽키의 ListView Item Designer와 닮은 TControlList는 리스트의 각 항목들을 대체해서(가상으로) 나타나는 리스트뷰 아이템의 레이아웃을 원하는 대로 만들 수 있습니다. 

TControlList는 단일 컬럼과 멀티 컬럼 레이아웃이 있는데, 원하는 형태를 선택할 수 있습니다. 완벽하게 가상화되어 있기 때문에 수천 혹은 수백만 개에 달하는 항목들도 얼마든지 제어 가능하며, 굉장히 빠른 스크롤이 가능합니다. 화면에 맞는 항목들만 표시할 수도 있습니다. 

그리고 High-DPI 옵션과 VCL 스타일을 지원할 뿐만 아니라 라이브바인딩(LiveBindings)도 완벽 지원합니다.

2021년 1월 10일 일요일

리스트박스 값으로 소팅하기(ListBox, Value, Sort)

 리스트박스에 key=value 형태로 저장이 되어있을 때 Value 기준으로 소팅하고 싶으면,

문자데이터가 아니고 숫자데이터 일때

procedure TForm2.Button2Click(Sender: TObject);
var
  idx: Integer;
begin
  for idx := 0 to 30 do
    ListBox1.Items.AddPair(idx.ToString, IntToStr(Random(100)));
end;


// function TForm2.TStringsSort(List: TStringList; L, R: integer): integer;
// 이 아님에 주의!
function TStringsSort(List: TStringList; L, R: integer): integer;
begin
  Result:= StrToint(List.ValueFromIndex[L])-StrToInt(List.ValueFromIndex[R]);
end;


procedure TForm2.Button3Click(Sender: TObject);
var
  istrings: TStringList;
begin
  istrings:= TStringList.Create;
  try
    istrings.Assign(Listbox1.Items);
    istrings.CustomSort(@TStringsSort);
    Listbox1.Items.Assign(iStrings);
  finally
    istrings.Free;
  end;

2021년 1월 8일 금요일

Record를 담은 TList를 소팅하는 방법

TArray에서와 같은 방법으로 소팅하면 됩니다.

tBoll = record
    count: integer;
    name: string;
end; 
jTempArr: Tarray<tBoll>;
iList: TList<tBoll>
jBoll: tBoll;
iList := TList<TBoll>.Create;
SetLength(jTempArr, 45);
for idx := 0 to 44 do begin
      jTempArr[idx].Count := 0;
      jTempArr[idx].Name := BollName[idx];
 end;
 for idx := 0 to 44 do begin
        jBoll := jTempArr[idx];
        iList.Add(jBoll);
 end;
 iList.Sort(TComparer<TBoll>.Construct(
        function(const Left, Right: TBoll): integer begin
             Result := Left.Count - Right.Count;
             // Result:= CompareText(Left, Right);
        end));

와 같은 방법으로 하면 됩니다. 그냥 iList.sort 하였더니  숫자의 자리수가 다르거나  음수가 있으면 잘 안되더군요. 0, -99, 99 이렇게 되어있을 경우 0 이 가장적은 수가되버립니다.

잊어먹지 않기위해 정리하였습니다.  참고로 List 소팅도 정리합니다. (XE)

uses
  SysUtils, Generics.Defaults, Generics.Collections;
procedure Sort;
var
  List: TList<String>;
  AComparer: IComparer<string>;
  I: integer;
begin
  Randomize;
  AComparer:= TDelegatedComparer<string>.create(
    function(const Left, Right: String): integer begin
      Result:= StrToInt(Left) - StrToInt(Right);
    end);
  List:= TList<string>.Create(AComparer);
  for i := 0 to 9 do
    List.Add(IntToStr(Random(1000)));
  List.Sort;
  //  List.Sort(TComparer<string>.Construct(function(const left,right: string):integer begin
  //     Result:= StrToInt(Left)-StrToInt(Right); 
  //  end));
  for I := 0 to List.Count-1 do Writeln((List[i]));
  List.Free;
end;

2021년 1월 5일 화요일

레코드 형태의 행렬에서 검색하는 방법(TArray.BinarySearch)

type
  TBoll = record
    count: integer;
    name: string;
  end;
var     iArrayBoll: TArray<TBoll>;
procedure TForm1.Button2Click(Sender: TObject);
begin
  SetLength(iArrayBoll, Memo1.Lines.count);
  for var idx := low(iArrayBoll) to high(iArrayBoll) do begin
    iArrayBoll[idx].count := 25;
    iArrayBoll[idx].name := Memo1.Lines[idx];
  end;
  TArray.Sort<TBoll>(iArrayBoll, TComparer<TBoll>.Construct(
    function(const a, b: TBoll): integer begin
      // Result := StrToint(a.name) - StrToint(b.name); //숫자크기우선 정렬
      Result:= CompareText(a.name, b.name); //스트링 정상 정렬
    end));
  for var idx := low(iArrayBoll) to High(iArrayBoll) do begin
    Memo2.Lines.Add(iArrayBoll[idx].name + '=' + iArrayBoll[idx].count.ToString);
  end;
end;


procedure TForm1.Button4Click(Sender: TObject);
var
  idx: integer;
  iBoll: TBoll;
  Found: boolean;
begin
  if rbLineair.Checked then begin
    for idx := 0 to High(iArrayBoll) do
      if Edit1.Text = iArrayBoll[idx].name then begin
        Caption := intToStr(idx);
        Exit;
      end;
  end else begin
    iBoll.name := Edit1.Text;
    iBoll.count := 250;
    Found := TArray.BinarySearch<TBoll>(iArrayBoll, iBoll, idx, TDelegatedComparer<TBoll>.Construct(
      function(const a, b: TBoll): integer begin
        Result := CompareText(a.name, b.name);
      end));
    if Found then Caption := intToStr(idx) else Caption := 'No';
  end;
end;

사전에 정상 정렬되어 있지 않은 경우 아래처럼 오류가 나온다. BinarySearch 전에 스트링의 경우 정상 정렬(숫자크기우선 정렬이면 안됨)이되어 있어야 한다. 이것 때문에 두어시간 해메었었네요.

레코드 형태의 행렬을 소팅하는 방법(별거아닌데 예제가 귀해서...)

 TArray<integer>나, Tarray<string> 으로 되어 있느 배열은 Tarray.sort<integer>(iArray) 과 같은 방법으로 할수 있습니다.

procedure TForm1.Button1Click(Sender: TObject);
var     iArray: TArray<string>;
begin
  SetLength(iArray, Memo1.Lines.count);
  iArray := Memo1.Lines.ToStringArray;
  TArray.Sort<string>(iArray);
  Memo2.Lines.AddStrings(iArray);
end;

유사한 방법으로 레코드 형태의 배열이며 특정 필드로 소팅한다면

  TBoll = record
    count: integer;
    name: string;
  end;
procedure TForm1.Button2Click(Sender: TObject);
var     iArrayBoll: TArray<TBoll>;
begin
  SetLength(iArrayBoll, Memo1.Lines.count);
  for var idx := low(iArrayBoll) to high(iArrayBoll) do begin
    iArrayBoll[idx].count := 0;
    iArrayBoll[idx].name := Memo1.Lines[idx];
  end;
  TArray.Sort<TBoll>(iArrayBoll, TComparer<TBoll>.Construct(
    function(const a, b: TBoll): integer
    begin
      Result := StrToint(a.name)- StrToInt(b.name); 
     //string 의 경우에는 Result:= CompareText(a.name, b.name);
    end));
  for var idx := low(iArrayBoll) to High(iArrayBoll) do begin
    Memo2.Lines.Add(iArrayBoll[idx].name);
  end;
end;

검색은

procedure TForm1.Button3Click(Sender: TObject);

var
  iStr: string;
  idx: integer;
begin
  iStr := Edit1.Text;
  if Tarray.BinarySearch<string>(iArray, iStr, idx) then Button3.Caption:= intToStr(idx);
end;

2020년 12월 7일 월요일

FastReport 에서 미리보기를 하지 않고 곧바로 PDF로 출력하기

FastReport 에서 미리보기를 하지 않고 곧바로 PDF로 출력하기


당연히 FRXReport 콤포넌트에서 출력 폼을 먼저 생성하여야 하겠지요 (*.fr3) 


procedure TForm1.ExportToPDF(AReport: TfrxReport; AFileName: String);
var
  PDFExport: TfrxPDFExport;
begin
  PDFExport := TfrxPDFExport.Create(nil);
  try
    PDFExport.ShowProgress := True;
    if AFileName <> '' then begin
      PDFExport.ShowDialog := False;
      PDFExport.FileName := AFileName;
    end;
    AReport.PrepareReport(True);
    AReport.Export(PDFExport);
  finally PDFExport.Free;
  end;
end;

사진읽어와 데이터베이스에 저장하기

사진을 정리하여 PDF 파일로 만들어 프린터로 출력하거나 보관하기 위해서 사진을 데이터베이스에 읽어와 일괄작업을 하려고 했더니 

요즈음은 휴대폰의 카메라 성능이 너무 좋아 프린트 출력을 위한 용도로는 파일의 크기가 너무커서 데이터 베이스 작업이 너무 어렵고,

또한 사진의 방향의 제각각으로 읽혀지는 경우가 많습니다.

이곳저곳 기웃기웃하여 좋은 방법을 찾았습니다.

본 예제른 사진의 가로폭을 1280으로 조절하고, 사진의 방향을 맞추어 데이터 베이스에 저장하는 것 까지 보여줍니다.

uses JPEG, GDIPAPI, GDIPOBJ;
procedure TForm1.acAddJpgExecute(Sender: TObject);
var
idx: integer;
jpg: TjpegImage;
GPImage: TGPimage;
GPGraphics: TGPGraphics;
pPropItem: PPropertyItem;
BufferSize: Cardinal;
Orientation: Byte;
RotateType: TRotateFlipType;
Bitmap: TBitmap;
TempBitmap: TBitmap;
iHeight: integer;
begin
if OpenPictureDialog1.Execute then begin
for idx := 0 to OpenPictureDialog1.Files.Count - 1 do begin
ZQuery1.Append;
ZQuery1.FieldByName('ino').AsInteger := idx*10;
ZQuery1.FieldByName('idate').AsString := DateToStr(DatePicker1.Date);
GPImage := TGPimage.Create(OpenPictureDialog1.Files[idx]);
try
BufferSize := GPImage.GetPropertyItemSize(PropertyTagOrientation);
if BufferSize > 0 then begin
GetMem(pPropItem, BufferSize);
try
GPImage.GetPropertyItem(PropertyTagOrientation, BufferSize, pPropItem);
Orientation := PByte(pPropItem.value)^;
case Orientation of
1: RotateType := RotateNoneFlipNone; // Horizontal - No rotation required
2: RotateType := RotateNoneFlipX;
3: RotateType := Rotate180FlipNone;
4: RotateType := Rotate180FlipX;
5: RotateType := Rotate90FlipX;
6: RotateType := Rotate90FlipNone;
7: RotateType := Rotate270FlipX;
8: RotateType := Rotate270FlipNone;
else RotateType := RotateNoneFlipNone; // Unknown rotation?
end;
if RotateType <> RotateNoneFlipNone then GPImage.RotateFlip(RotateType);
Bitmap := TBitmap.Create;
TempBitmap := TBitmap.Create;
try
Bitmap.Width := GPImage.GetWidth;
Bitmap.Height := GPImage.GetHeight;
Bitmap.Canvas.Lock;
try
GPGraphics := TGPGraphics.Create(Bitmap.Canvas.Handle);
try
GPGraphics.DrawImage(GPImage, 0, 0, GPImage.GetWidth, GPImage.GetHeight);
if Bitmap.Width > 1280 then begin
iHeight := Ceil((Bitmap.Height * 1280) / Bitmap.Width);
TempBitmap.Width := 1280;
TempBitmap.Height := iHeight;
SetStretchBltMode(TempBitmap.Canvas.Handle, HALFTONE);
StretchBlt(TempBitmap.Canvas.Handle, 0, 0, TempBitmap.Width, TempBitmap.Height, Bitmap.Canvas.Handle, 0, 0, Bitmap.Width, Bitmap.Height, SRCCOPY);
DBImage1.Picture.Assign(TempBitmap);
end
else DBImage1.Picture.Assign(Bitmap);
ZQuery1.Post;
finally GPGraphics.Free;
end;
finally Bitmap.Canvas.Unlock;
end;
finally
Bitmap.Free;
TempBitmap.Free;
end;
finally FreeMem(pPropItem);
end;
end
else begin
Bitmap := TBitmap.Create;
TempBitmap := TBitmap.Create;
try
Bitmap.Width := GPImage.GetWidth;
Bitmap.Height := GPImage.GetHeight;
Bitmap.Canvas.Lock;
try
GPGraphics := TGPGraphics.Create(Bitmap.Canvas.Handle);
try
GPGraphics.DrawImage(GPImage, 0, 0, GPImage.GetWidth, GPImage.GetHeight);
if Bitmap.Width > 1280 then begin
iHeight := Ceil((Bitmap.Height * 1280) / Bitmap.Width);
TempBitmap.Width := 1280;
TempBitmap.Height := iHeight;
SetStretchBltMode(TempBitmap.Canvas.Handle, HALFTONE);
StretchBlt(TempBitmap.Canvas.Handle, 0, 0, TempBitmap.Width, TempBitmap.Height, Bitmap.Canvas.Handle, 0, 0, Bitmap.Width, Bitmap.Height, SRCCOPY);
DBImage1.Picture.Assign(TempBitmap);
end
else DBImage1.Picture.Assign(Bitmap);
ZQuery1.Post;
finally GPGraphics.Free;
end;
finally Bitmap.Canvas.Unlock;
end;
finally
Bitmap.Free;
TempBitmap.Free;
end;
end;
finally GPImage.Free
end;
end;
StatusBar1.SimpleText := '사진을 읽어왔습니다, 작업사항을 입력하십시요.'
end; // for
end;

2020년 12월 3일 목요일

델파이에서 fastreport 로 pdf 생성시 한글이 깨어지는 문제가 있음

fastreport 6 vcl 에서 pdf 파일 생성시 한글이 깨어져서 네모로 출력어

델마당에 나오 방법으로 했으나 해결이 안되었는데

Memo Component 의 Charset을 

HANGEUL_CHARSET 으로 바꾸어 주니 정상으로 한글이 출력됩니다.

아마 다른버전도 그러할 것입니다.





2020년 11월 23일 월요일

REST API 연결

 델파이(delphi)에서 REST API 간단한 예제

1. 새폼을 만듭니다.

2. Palette 에서 REST로 찾아 아래 콘트롤을 폼에 드롭합니다.

    RESTClient, RESTRequest, RESTResponse, 

3. 예제로 동행복권API를 사용하겠습니다. RESTClient1 콘트롤에서

    BaseURL = https://www.dhlottery.co.kr

4. RestRequest1 콘트롤에서 

    client = RESTClient1,   responce = RESTReponce1,  resource = common.do

5. RESTRequest1 콘트롤의 Params 를 더블크릭하여 아래와 같이 추가합니다.



6. RESTRequest1dp 마우스 오른쪽을 크릭하여 Execcute... 을 선택하여

9. 아래의 결과를 받습니다.


10. Form에 memo 콘트롤을 하나 드롭하고 크기를 적당하게 조절한 다음. 오브젝트인스펙트에서 아래와 같이 확인합니다. 지금까지의 작업은 익스플러의 주소창에
https:/www.dhlottery.co.kr/common.do?method=getLottoNumber&drwNo=900
라고 입력하고 결과를 받는 것과 같습니다.




11. RESTREsponseDataSetAdapter, FDMemTable, ListView, Edit, button을 폼에 드롭합니다.

12. RESTResponseDataSetAdapter1 콘트롤에서

13. Listview1 마우스 오른쪽크릭하여 Columms Editor.. 선택하여 Columm을 추가하고, 

    ViewStyle = vsReport로 변경합니다.


14. LiveBindings Designer 를 불러냅니다.


11.  LiveBindings Designer에서 아래와 같이 연결합니다.

필요하면 BindSourceDB 콘트롤을 폼에 추가합니다.

12. 버튼을 크릭하여 아래코드를 추가하고 결과를 확인합니다.

procedure TForm3.Button1Click(Sender: TObject);
begin
  RESTRequest1.Execute;
end;

13. 결과


14. 같은 방법으로 https://www.data.go.kr/index.do 에 접속하여 REST API를 경험하세요.


2020년 5월 9일 토요일

델파이에서 TAcroPDF 사용후 종료시 프로세서가 종료되지 않을 때

델파이에서 TAcroPDF 사용후 종료시 프로세서가 종료되지 않을 때
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
var
  Ref : Integer;
begin
  Ref := AcroPdf1.ControlInterface._AddRef;
  AcroPdf1.Src := '';
  AcroPdf1.Free;
  AcroPdf1 := Nil;
end;
하거나
AcroPDFLib_Tlb.pas 에서 
Type
TAcroPDF = class(TOleControl)
  ...
  public
    destructor Destroy; override; // <- New Line
  ...
  end;

Implementation
.....  
destructor TAcroPDF.Destroy;
begin
 FIntf := NIL;
 inherited;
end;
하면 정상 종료된다.

델파이의 부활(Antigravity와의 만남)?

 델파이 프로그램을 사용하여 개인적으로 필요한 프로그램을 생성해 왔는데, 얼마전부터 파이썬으로 옮겨갔다.  그런데 Google 의 Antigravity를 만나고 나서 델파이에 대한 미련을 버리지 못해  제미나이가 Delphi이에 대한 학습도 엄청 했을...