Search results for '전체'

  1. 2016.08.02 -- [마이그레이션 사례] 감리교 신학대학교
  2. 2016.08.01 -- 퀵레포트(Quick Report)에 사진 출력하기
  3. 2016.08.01 -- 퀵레포트 보고서 엑셀로 내보내기(저장하기) (1)
  4. 2016.08.01 -- BLOB 컬럼에서 (이미지 등의)데이터 읽고 쓰기
  5. 2016.07.28 -- 구글 통계(Google Analytics)를 써드파티 컴포넌트 없이 구현하는 방법
  6. 2016.07.20 -- [팁] 파라메터 값이 포함된 쿼리 문자열 만들기
  7. 2016.06.27 -- [교육] 마이그레이션 워크샵 과정
  8. 2016.06.02 -- [팁] 소스코드 압축 시 불필요한 확장자 파일 제거하고 압축하기(7zip 이용)
  9. 2016.05.27 -- VCL 스타일이 적용된 앱을 다른 프로세스에 넣을때 메인메뉴가 클릭되지 않는 이슈 해결방법
  10. 2016.05.18 -- [교육] 숭실대학교 - 컴퓨팅적 사고
  11. 2016.04.28 -- [라이브바인딩] 콤보박스에 목록표시, 선택 값 반영하기
  12. 2016.04.27 -- [게임] 매의 눈(컵속에 숨겨진 주사위 찾기 게임)
  13. 2016.04.21 -- delphi-markdown(델파이 마크다운 라이브러리) 소개
  14. 2016.04.14 -- [마이그레이션 사례] 에스엔유프리시젼
  15. 2016.04.04 -- [OSX/맥] 맥의 스크린세이버 비활성화/활성화 시키기 (2)
  16. 2016.04.04 -- [FMX] 앱에서 문장을 출력하는 3가지 방법
  17. 2016.03.31 -- [안드로이드/iOS] 이미 배포(Deployment)된 파일 업데이트 하기
  18. 2016.03.07 -- [VCL] 다른 프로세스의 폼을 패널등에 넣기 (1)
  19. 2016.02.29 -- RAD Studio IDE에서 SVN 사용하기 + TortoiseSVN 사용하기
  20. 2016.02.29 -- SVN 서버 설치하기 - Visual SVN 이용

[마이그레이션 사례] 감리교 신학대학교

2016.08.02 15:28

고객들의 PC환경과 요구사항이 아주 빠르게 발전하고 있습니다. 윈도우10 등의 최신 운영체제를 탑재한 PC환경과 새로운 요구사항에 대응하기 위해서는 RAD 스튜디오(델파이, C++빌더)에서 제공하는 최신 기능을 활용할 수 있도록 마이그레이션이 필요합니다.


저는 여러분들이 직접 마이그레이션을 진행할 수 있는 마이그레이션 관련 자료와 팁을 제공하고, 

마이그레이션 컨설팅, 마이그레이션 워크샵 등을 통해 직접적인 도움이 필요한 프로젝트나 기업을 지원하고 있습니다.

마이그레이션을 계획하거나 진행하고 계신 분들에게 도움되도록 마이그레이션 프로젝트 과정의 일부를 간단히 정리해 공유합니다.


감리교 신학대학교 - 마이그레이션 컨설팅

  • 프로젝트 기간 : 2016년 5월 ~ 7월(3개월)
  • 지원방법 : 마이그레이션 방문컨설팅
  • 버전 : 델파이 3 -> 델파이 10.1 베를린(Berlin)


감리교 신학대학교의 학사관리 프로그램(학부, 대학원, 평생교육원, 행정 등)을 델파이 3에서 델파이 10.1 베를린으로 마이그레이션 하는 프로젝트를 3개월간 진행했습니다.


감리교 신학대학은 1887년 설립된 국내최초의 신학교입니다. 오래된 전통만큼 상당히 오래된 델파이 3 버전을 최신버전인 델파이 10.1 베를린으로 마이그레이션 진행했습니다.


마이그레이션 진행사항

감리교 신학대학교의 마이그레이션 프로젝트의 작업 대상은  총 27개 실행파일에 약 3000여개의 소스파일과 3000여개의 화면이었습니다.


핵심과제

이번 마이그레이션 프로젝트의 핵심 과제는 아래와 같습니다.


1, 최신 운영체제 지원 - 델파이 버전을 업그레이드 하고, 오래된 기술인 BDE를 걷어내는 작업

2, 디자인 개선 - 오래된 구식 화면의 일부(로그인, 메인화면)를 개선하고 최신 스타일 적용


위와 같이 핵심과제를 선정한 이유는, 

보통 마이그레이션 계획 시 소스코드만 상위버전으로 마이그레이션을 계획하는 경우가 있습니다.

하지만, 이경우 개발자(또는 개발팀) 입장에서는 소스코드를 마이그레이션하는 것이 중요 과업일 수 있지만, 

실 사용자 입장에서는 마이그레이션 전과 후가 변경된 것이 없어 성공적이지 못한 작업으로 인식할 수 있습니다.


그래서, 제안하는 바는 마이그레이션 계획 시 소스코드 마이그레이션을 핵심 과업으로 계획하고, 사용자들이 자주 사용하는 몇개의 화면에 대해 디자인 강화나, 필요한 기능을 몇개 선정해 구현한다면 사용자들도 만족하는 성공적인 마이그레이션 프로젝트가 될 것 입니다.


마이그레이션 작업 사이클

마이그레이션 작업을 성공적으로 수행하려면, 마이그레이션 작업을 잘 수행하는 것과 더불어 테스트와 문서화가 매우 중요합니다.

정해진 일정에서 테스트 시간을 확보하기 위해서는, 마이그레이션 작업 시간을 단축해야 하는데요. 저는 마이그레이션 대부부의 작업을 자동화(또는 반자동화)하는 것으로 실질적인 마이그레이션 작업시간을 줄이고, 테스트와 기능추가 문서화에 시간을 투자했습니다.


마이그레이션 작업의 자동화 작업은  작업시간을 단축시켜 줄뿐 아니라 작업자의 실수를 방지해주고, 작업을 단순하게 해주기 때문에 규모에 상관없이 자동화 할 수 있는 방안을 찾아보시기 바랍니다.(자동화 방안은 아래에서 추가로 설명합니다.)


제가 진행한 마이그레이션 사이클은 다음과 같습니다.

  1. 대상선정
    • 작업대상을 세분화해서 부분적으로 작업합니다. 
    • 중요도와 상관없이 다양한 화면과 기술이 구현된 대상을 우선 진행합니다.
    • 마이그레이션 작업이 익숙하지 않다면 작업량이 작고, 쉬운 대상을 먼저 진행합니다.
    • 모듈화(별도의 프로젝트)되어 있다면 더욱 좋습니다.
  2. 마이그레이션 작업
    • 자동화 도구를 이용해 작업진행
    • 마이그레이션 가이드 참고
  3. 이슈해결
    • 마이그레이션 작업 후 발생하는 이슈(컴파일 오류 등)을 해결합니다.
    • 이슈를 정확히 해결하기 위해서는 신규 프로젝트를 생성후 이슈 재현해 해결하면 더욱 좋습니다.
  4. 자동화방안수립
    • 자동화 패턴(reFind.exe 용)을 작성하거나, 텍스트 에디터로 여러파일 일괄전환 방법을 수립합니다.
    • 필요한 경우 전환 프로그램을 개발합니다.
  5. 마이그레이션 가이드 작성
    • 이슈와 해결방안을 기록하고, 자동화 방안도 기록합니다.(다음 작업 시 참고합니다)
    • 프로젝트 옵션, 컴포넌트의 속성 변경 등 빠트릴 수 있는 내용을 기록합니다.
    • 공통적으로 변경해야할 코드들을 기록합니다.
  6. 이전 작업분에 반영
    • 이미 마이그레이션 진행한 작업분에 추가된 이슈해경 방안을 반영합니다.
  7. 테스트

위의 사이클로 마이그레이션 작업을 하게되면, 반복적인 작업은 자동화 도구로, 수작업은 문서를 참고하기 때문에 상당히 빠르고 정확하게 진행할 수 있습니다.

이번 프로젝트에서도 실질적인 마이그레이션 작업시간은 약 1~2주로 전체의 1/6이 안되는 시간을 사용했고, 나머지 시간을 이슈해결, 자동화 방안수립, 테스트 등에 활용해 성공적으로 마무리 할 수 있었습니다.


작업내용

작업한 내용을 간단하게 공유합니다.(좀 더 자세한 사항은 내용 하단 참고자료를 이용해 확인할 수 있습니다.)


사용성

최신 운영체제 지원

델파이3으로 개발된 프로그램은 최신 운영체제(윈도우10, 윈도우8)에서 설치 및 사용 시 알수 없는 오류가 발생했습니다. 특히 오래된 데이터 접속 기술인 BDE가 최신 윈도우와 64비트 환경을 지원하지 않고, 프로그램 배포 시 BDE Admin을 별도로 설치해야하는 번거로움이 있었습니다.


마이그레이션 작업에서는 델파이 버전을 델파이3을 델파이 10.1 베를린으로, 데이터 접속 기술을 BDE에서 FireDAC으로 변경하므로 최신 윈도우를 완벽 지원하게되었습니다.


이 과정의 대부분은 마이그레이션 자동화 도구인 reFind.exe를 이용해 작업시간을 대폭 단축 시켰습니다.

배포과정 간소화

FireDAC을 사용하게되면서 프로그램 배포시 기존에는 BDE Admin, 오라클 클라이언트 소프트웨어등을 별도로 설치해야 했지만, FireDAC을 사용하는 경우 프로그램 실행파일과 몇개의 오라클 관련 DLL(Oracle thin client dll)만 배포하도록 배포과정을 간소화 할 수 있었습니다.


☞ 참고자료

디자인

슬라이드 메뉴 적용

오래된 프로그램인만큼 화면과 레이아웃도 오래전의 방식을 사용하고 있어, 개선이 필요했습니다.
마침 VCL 윈도우 10 컨트롤 중 슬라이드 메뉴를 제공하는 TSplitView를 델파이 10 시애틀 부터 제공해 TSplitView를 이용해 업무별 바로가기 기능을 구현했습니다.(위 그림 참고)

☞ 참고자료

최신 윈도우 스타일 적용

전체적인 화면의 컨트롤, 테두리, 배경색등을 일괄적으로 최신 윈도우 스타일을 적용하기 위해 VCL 스타일을 적용했습니다. 프로젝트 옵션을 설정하는 것만으로 모든 화면과 각 컨트롤이 일괄적으로 스타일이 적용되어 손쉽게 스타일을 업그레이드 할 수 있었습니다.

☞ 참고자료


기능

보고서 엑셀저장

보고서 프로그램으로 사용하는 퀵레포트(Quick Report)를 업그레이드 했더니, 보고서 저장하는 기능이 추가되었습니다. 마침 엑셀로 저장하는 기능이 활용성이 높다 판단되어 엑셀로 저장하는 필터 컴포넌트(TQRXLSXFilt)를 보고서 화면에 추가해 간단히 엑셀로 저장하는 기능을 구현했습니다.

하지만, 보고서 화면이 너무 많아 일일이 필터 컴포넌트를 올리는 작업량이 많아 텍스트 에디터의 여러파일 찾기 기능과 치환 기능을 이용해 폼파일(*.dfm)과 소스파일(*.pas)에 컴포넌트 추가하는 작업을 자동화 했습니다.


☞ 참고자료


학적부 사진 저장, 보고서 사진 출력

학생들의 사진을 프로그램에 표시하기 위해, DB에 사진 테이블 생성 후 BLOB 컬럼을 추가해 사진데이터를 저장했습니다. 기존에 웹상에서 관리하던 이미지 파일을 다운로드 해 DB에 일괄저장 후 화면과 보고서 화면에 표시했습니다.


☞ 참고자료


SQL 문 로그 기능 구현

"DB에 호출하는 모든 SQL 문을 로그로 남겨주세요."라는 요구사항을 처리하기위해 TFDQuery 컴포넌트를 상속받아 일부 메소드의 기능을 확장하도록 진행했습니다.

대부분의 DB 작업이 TFDQuery와 TFDUpdateSQL로 SELECT, INSERT, UPDATE, DELETE 문이 컴포넌트 내에 기록되어 수작업으로 로그를 기록할 경우 이미 작업한 분량만큼(또는 더 많은 분량을) 추가 작업해야 하기 때문에 수작업으로 로그를 남기는 작업은 사실상 불가능했습니다.

그래서, TFDQuery에서 SQL문을 DB로 전달하는 부분(메소드)을 추적해 해당 메소드를 재구현(Override)해 처리했습니다.


☞ 참고자료

  • (작성 중)

성능

데이터베이스 처리 성능 개선

BDE를 FireDAC으로 교체하는 것만으로도 일부의 데이터 엑세스 성능을 개선할 수 있습니다. FireDAC은 멀티-플랫폼을 지원하는 데이터 엑세스 컴포넌트로 매우 다양한 기능을 제공하며, 성능도 이전의 데이터 엑세스 컴포넌트(BDE, dbExpress 등)에 비해 향상되었습니다.


☞ 참고자료


추가안내

마이그레이션 지원

저는 데브기어를 통해 아래 3가지 방식으로 마이그레이션을 지원합니다.

마이그레이션 정보 제공

마이그레이션 기술자료를 마이그레이션 센터와 데브기어 테크게시판을 통해 제공합니다. 마이그레이션에 대한 질문도 질문 게시판을 통해 받고있습니다.

마이그레이션 무상 컨설팅

마이그레이션 체크리스트와 가이드 문서를 제공합니다. 작성 후 메일을 보내주시면 이메일과 방문을 통해 컨설팅을 지원합니다.


마이그레이션 워크샵(4일)

마이그레이션을 좀 더 효과적으로 직접 진행하고 싶다면, 워크샵 과정에 참석하세요. 마이그레이션 자동화 방안, 가이드 문서 작성 등을 배우고, 혼자 해결하기 어려운 부분을 멘토링을 통해 해결해 더 쉽고, 빠르게 마이그레이션 할 수 있습니다.

마이그레이션 컨설팅(유상)

마이그레이션 시의 위험요소 파악, 전환체계(자동화 방안, 마이그레이션 가이드 작성 등) 구축 등을 경험많은 마이그레이션 전문가를 통해 진행할 수 있습니다.

  • 별도로 요청해 주세요.. : ask@embarcadero.kr

험프리.김현수 마이그레이션

퀵레포트(Quick Report)에 사진 출력하기

2016.08.01 17:34

DBMS의 Blob 컬럼의 이미지 데이터를 퀵레포트 보고서에 출력하는 내용입니다.


(추가)

 2016.09.02 : 미리보기에서 사진이 나오는데, 실제 인쇄 시 사진이 출력되지 않는 이슈해결 방안을 추가했습니다.



쿽레포트에 사진을 출력하려면 TQRImage, TQRDBImage 2개의 컴포넌트를 이용할 수 있습니다.

(TQRDBImage는 비트맵 데이터만 출력할 수 있습니다.)


저는 JPEG, GIF, PNG 등을 지원하기 위해 TQRImage를 이용합니다.


아래 델파이 샘플은 BOOK_THUMB(Blob 컬럼)의 데이터를 읽어 TQRImage에 표시하는 내용입니다.

Blob 컬럼을 읽기 위해 TBlobField를 사용하고, TWICImage를 이용해 다양한 포맷을 지원합니다.

(BLOB 컬럼에서 (이미지 등의)데이터 읽고 쓰기: http://blog.hjf.pe.kr/437)


레코드 별로 이미지를 표시하기 위해 TFDQuery의 AfterScroll 이벤트에 이미지 불러오는 코드를 작성합니다.

  private
    { Private declarations }
    FWicImage: TWICImage;
    FMemoryStream: TMemoryStream;
  public
    { Public declarations }
  end;
... 중략 ...

procedure TForm1.FormCreate(Sender: TObject);
begin
  FWicImage := TWICImage.Create;
  FMemoryStream := TMemoryStream.Create;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  FWicImage.Free;
  FMemoryStream.Free;
end;

procedure TForm1.FDQuery1AfterScroll(DataSet: TDataSet);
begin
  FMemoryStream.Clear;
  (FDQuery1.FieldByName('BOOK_THUMB') as TBlobField).SaveToStream(FMemoryStream);
  if FMemoryStream.Size = 0 then
    Exit;
  FWicImage.LoadFromStream(FMemoryStream);
  QRImage1.Picture.Assign(FWicImage);
end;

아래와 같이 보고서에 이미지를 출력할 수 있습니다.


== 내용 추가 ==

 2016.09.02 : 미리보기에서 사진이 나오는데, 실제 인쇄 시 사진이 출력되지 않는 이슈해결 방안


일부 프린터에서 고해상도 또는 크기가 큰 사진이 포함된 보고서가 출력되지 않아, 

아래와 같이 AfterScroll 이벤트 핸들러의 코드를 수정해 해결했습니다.

procedure TForm1.FDQuery1AfterScroll(DataSet: TDataSet);
var
  bmp: TBitmap;
begin
  FMemoryStream.Clear;
  (FDQuery1.FieldByName('BOOK_THUMB') as TBlobField).SaveToStream(FMemoryStream);
  if FMemoryStream.Size = 0 then
    Exit;

  FWicImage.LoadFromStream(FMemoryStream);

   // wic 이미지를 16비트 비트맵으로 변경
  bmp := TBitmap.Create;
  try
    bmp.PixelFormat := pf16bit; // pf4bit, pf8bit, pf15bit, pf16bit, pf24bit, pf32bit
    bmp.Assign(FWicImage);

    // QRImage에 크기를 줄여 그리기
    QRImage1.Picture.Bitmap.Width := QRImage1.Width;
    QRImage1.Picture.Bitmap.Height := QRImage1.Height;
    QRImage1.Picture.Bitmap.Canvas.StretchDraw(Rect(0, 0, QRImage1.Width, QRImage1.Height), bmp);
  finally
    bmp.Free;
  end;
end;


험프리.김현수 Delphi/C++Builder

퀵레포트 보고서 엑셀로 내보내기(저장하기)

2016.08.01 16:08

(Quick Report 5.0.6 버전으로 작성된 내용입니다.)

퀵레포트(QuickReport)로 작성한 보고서를 저장해야 하는 경우 퀵레포트 필터를 통해 다양한 포맷을 추가할 수 있습니다.



위 필터 중 TQRXLSXFilter를 통해 엑셀로 보고서를 내보내기(저장)할 수 있습니다.



하지만 엑셀로 내보내기 기능을 제공하려면 XLColumn 속성을 설정해야 합니다.

XLColumn 속성은 엑셀에 표시되는 컬럼 순서로, 인쇄가능한 퀵레포트 컴포넌트들(TQRLabel, TQRDBText 등의 TQRPrintable 클래스를 상속받는 컴포넌트 들)은 모두 XLColumn 속성을 갖고 있습니다.(다시 말해 대부분의 컨트롤의 XLColumn 속성을 설정해야 합니다.)


XLColumn 속성은 다음 특징을 참고해 신중히 설정해야 합니다.

  1. 동일한 밴드(TQRBand)에서 Top 속성의 값이 같은 경우 엑셀의 같은 행에 표시된다.
  2. 만약, Top 속성이 같은 컨트롤이 있을 경우 중복 에러를 발생해 엑셀 내보내기 기능이 동작하지 않는다.


다음과 같이 XLColumn을 설정해야 합니다.



보고서 미리보기 후 저장 시 XLSX spreadsheet 파일 형식이 추가되고, 


저장하면 아래와 같이 엑셀로 저장됩니다.



주의!!!

Top 속성이 같은 컨트롤이 있을 경우 아래와 같은 오류를 발생하고, 엑셀 내보내기 기능을 동작하지 않습니다.

아래와 같은 오류가 발생한다면 레포트 화면의 컨트롤의 XLColumn 속성을 검토하시기 바랍니다.

(Duplicate cell reference detected - please check 'XLColumn' properties)



관련링크



험프리.김현수 Delphi/C++Builder

  1. Blog Icon
    이현국

    혹시 delphi 안드로이드 구글 지도 맵 은 강의 안하시나요..?

    소스코딩을 찾아보아도 어떻게 해야 할지 모르겠어요!

BLOB 컬럼에서 (이미지 등의)데이터 읽고 쓰기

2016.08.01 15:15

(해당 내용은 모든 데이터셋(TDataSet을 상속받은 컴포넌트) 즉, FireDAC, dbExpress, dbGo(ADO) 등에 적용할 수 있습니다.)


대부분의 DBMS에서 Blob(Binary Large object) 타입의 컬럼을 만들 수 있습니다. 이 컬럼에는 이미지등의 큰 바이너리 데이터를 취급할 수 있습니다.


아래 코드는 Blob 컬럼에서 이미지를 읽고, 쓰는 델파이 예제입니다.


Blob 컬럼에 이미지 데이트 쓰기

var
  wic: TWICImage; // Microsoft Windows Imaging Component
  Stream: TMemoryStream;
begin
  Stream := TMemoryStream.Create;
  try
    Image1.Picture.SaveToStream(Stream);
    qryPhoto.Edit; // 데이터셋 수정
    (qryPhoto.FieldByName('PHOTO_PHOTO') as TBlobField).LoadFromStream(Stream);
    qryPhoto.Post;
  finally
    Stream.Free;
  end;
end;


Blob 컬럼에서 이미지 데이터 읽기

var
  wic: TWICImage; // Microsoft Windows Imaging Component
  Stream: TMemoryStream;
begin
  Stream := TMemoryStream.Create;
  wic := TWICImage.Create;
  try
    (qryPhoto.FieldByName('PHOTO_FIELD') as TBlobField).SaveToStream(Stream);
    if Stream.Size > 0 then
    begin
      try
        wic.LoadFromStream(Stream);
        Image1.Picture.Assign(wic);
      except
      end;
    end;
  finally
    Stream.Free;
    wic.Free;
  end;
end;

위에서 사용한 TWICImage는 Microsoft Windows Imaging Component를 캡슐화한 클래스로, 다양한 이미지 형식(Bitmap, JPEG, PNG, GIF, TIFF 등)을 로드할 수 있는 컨테이너 입니다.(http://docwiki.embarcadero.com/Libraries/en/Vcl.Graphics.TWICImage)


험프리.김현수 데이터 엑세스

구글 통계(Google Analytics)를 써드파티 컴포넌트 없이 구현하는 방법

2016.07.28 10:55

델파이 개발자인 Rafael Ribas Aguiló의 블로그에서 델파이에서 써드파티 컴포넌트 없이 구글 통계(Google Analytics)와 연동하는 내용이 있어 소개합니다.


해당 내용은 안드로이드 기반으로 작성되었습니다. 안드로이드 앱 개발하시는 분들은 참고하시기 바랍니다.


최근에는 앱을 만드는 작업도 중요하지만, 사용성(Usability)을 높이는 작업이 상당히 중요합니다.

여러분들의 고객이 어떤 메뉴나 기능을 얼마나 많이 사용하는지 분석하는 작업에 이용하면 구글 통계를 이용해 더 완성도 높고 사용성 높은 앱을 만들어 보세요.




험프리.김현수 파이어몽키

[팁] 파라메터 값이 포함된 쿼리 문자열 만들기

2016.07.20 14:41

SQL 작성 시 아래와 같이 파라메터를 많이 이용합니다.


SELECT * FROM EMPLOYEE WHERE EMP_ID = :EMP_ID


하지만, SQL을 로그로 기록할 경우 파라메터 명(:EMP_ID) 대신 파라메터 값이 들어가야 할 경우 아래와 같이 파라메터 값이 적용된 SQL을 만들어 사용할 수 있습니다.


procedure TForm1.Button1Click(Sender: TObject);
var
  I: Integer;
  SQLStr, ParamName, ParamValue: string;
begin
  Query1.Close;
  Query1.ParamByName('Name').AsString := '홍길동';
  Query1.ParamByName('JUNHYEONG').AsString := '2';
  Query1.ParamByName('yundo').AsString := '2016';
  Query1.Open;

  SQLStr := Query1.SQL.Text;
  for I := 0 to Query1.ParamCount - 1 do
  begin
    ParamName := ':' + Query1.Params[I].Name;
    ParamValue := Query1.Params[I].AsString;
    if Query1.Params[I].DataType in [ftString, ftWideString, ftMemo, ftWideMemo] then
      ParamValue := '''' + ParamValue + '''';
    SQLStr := SQLStr.Replace(ParamName, ParamValue);
  end;

  Memo1.Lines.Text := SQLStr;
end;

위와 같이 처리하면 메모에 아래와 같이 파라메터 명에 파라메터 값이 치환된 쿼리가 표시됩니다.


select *

from IPSI_MAST

where MAST_SUHEOM_BUNHO like '' || '%'

   and MAST_NAME like '홍길동' || '%'

   and MAST_JIMANG = '0'

   AND MAST_GUBUN = '2' 

   and MAST_JUNHYEONG like '2' || '%'

   and MAST_YUNDO ='2016'

order by MAST_SUHEOM_BUNHO

험프리.김현수 데이터 엑세스

[교육] 마이그레이션 워크샵 과정

2016.06.27 13:29


마이그레이션 가이드 문서 샘플

마이그레이션절차_샘플_v0.1.docx


양식


마이그레이션 가이드

https://docs.google.com/document/d/1qrmFU2tbI09-aXcBgtaXeUNwapkhxqDVlRe9-rTt_SU/edit?usp=sharing


마이그레이션 이슈공유

https://docs.google.com/spreadsheets/d/1riUy-er4E-Uop1SH_k8D1dRrmMUO42DuzZj3vVMhlUA/edit?usp=sharing



이슈 공유 문서

마이그레이션 이슈 공유


마이그레이션 워크샵 이슈 공유


컴포넌트 마이그레이션 방안 안내


참고링크




험프리.김현수 교육, 세미나 교육

[팁] 소스코드 압축 시 불필요한 확장자 파일 제거하고 압축하기(7zip 이용)

2016.06.02 11:12

버전관리 시스템(SVN, VSS, Git, Mercurial 등)을 이용해 소스코드를 관리하는 것이 가장 좋은 선택입니다.

하지만 소스코드를 압축해야 할 경우가 있는데요.


7zip의 커맨드라인 명령어를 이용해 필요없는 파일들을 제외하고 압축할 수 있습니다.


7z.exe a -tzip Source.zip Source\ -xr!*.dcu -xr!*.~* -xr!*.exe -xr!*.bak


pause


위의 코드는 Source.zip으로 압축하되 -x(eXclude) 파라메터를 이용해 필요없는 파일을 지정합니다.

연속으로 파일포맷을 지정하는 방법을 몰라 여러번 기록하니 잘되네요.


참고링크



험프리.김현수 기타정보

VCL 스타일이 적용된 앱을 다른 프로세스에 넣을때 메인메뉴가 클릭되지 않는 이슈 해결방법

2016.05.27 13:30

다음 글을 참고하면 다른 프로세스의 화면을 특정 영역(패널 등)에 넣을 수 있습니다.

[Delphi/C++Builder] - [VCL] 다른 프로세스의 폼을 패널등에 넣기


그런데, VCL 스타일이 적용된 프로세스를 위 방법으로 진행할 경우 메인메뉴가 클릭되지 않는 증상이 발생합니다.


이 경우 VCL 스타일이 적용된 프로젝트에서, 메인폼의 StyleElements 속성의 seBorder 항목을 False로 변경 후 다시 컴파일 하면 메인메뉴 클릭이 정상 동작합니다.

험프리.김현수 Delphi/C++Builder

[교육] 숭실대학교 - 컴퓨팅적 사고

2016.05.18 17:53

1회차 - RAD 개발도구의 이해

20160516_컴퓨팅적사고_1회.pdf



2회차 - 데이터베이스 프로그래밍 맛보기

20160516_컴퓨팅적사고_2회.pdf



3회차 - 모바일 프로그래밍 맛보기

카메라 앱 만들기

// Switch1.OnSwitch 이벤트 생성 후 코딩

procedure TForm1.Switch1Switch(Sender: TObject);

begin

  if Switch1.IsChecked then

    CameraComponent1.TorchMode := TTorchMode.ModeOn

  else

    CameraComponent1.TorchMode := TTorchMode.ModeOff;

end;

// Button1.OnClick 이벤트 생성 후 코딩

procedure TForm1.Button1Click(Sender: TObject);

begin

  CameraComponent1.Active := not CameraComponent1.Active;

end;


// CameraComponent1.OnSampleBufferReady 이벤트 생성 후 코딩

procedure TForm1.CameraComponent1SampleBufferReady(Sender: TObject;

  const ATime: TMediaTime);

begin

  TThread.Synchronize(TThread.CurrentThread, GetImage);

end;

// private 영역에 procedure GetImage; 입력 후 Ctrl + Shift + C 누리고 입력(23번 줄, 그림 참고)

procedure TForm1.GetImage;

begin

  CameraComponent1.SampleBufferToBitmap(Image1.Bitmap, True);

end;


추가정보

모바일 개발환경 설정

http://tech.devgear.co.kr/delphi_news/402210


Using FireDAC and SQLite (iOS and Android)

http://docwiki.embarcadero.com/RADStudio/Berlin/en/Mobile_Tutorial:_Using_FireDAC_and_SQLite_(iOS_and_Android)


모바일앱에 사용자 파일 추가하기

http://blog.hjf.pe.kr/104


나의 도서관 앱 따라하기

http://blog.hjf.pe.kr/255


사물인터넷 : #1 - 비콘을 이용해 위험지역 진입 경보앱 만들기

http://blog.hjf.pe.kr/384


사물인터넷 : #1 - BLE 기반 스마트 체중계에서 실시간 데이터 받기

http://blog.hjf.pe.kr/404



참고링크

• 델파이 교육 : http://devgear.co.kr/edu

시작하는 사람을 위한 델파이 프로그래밍 : http://tech.devgear.co.kr/421276
한 번에 개발하는 안드로이드/iOSwith 델파이 1, 2권 : http://tech.devgear.co.kr/406570

데브기어 홈페이지 : http://devgear.co.kr/
데브기어 기술게시판 : http://tech.devgear.co.kr/
엠바카데로 기술자료 : http://docwiki.embarcadero.com
델마당(커뮤니티) : http://www.delmadang.com/
볼랜드 포럼(커뮤니티) : http://borlandforum.com
파이어몽키 카페 : http://cafa.naver.com/delphifmx
험프리 블로그 : http://blog.hjf.pe.kr/


험프리.김현수 교육, 세미나 교육

[라이브바인딩] 콤보박스에 목록표시, 선택 값 반영하기

2016.04.28 15:03

콤보박스에 목록을 표시하고, 선택한 항목의 키값을 다른 데이터셋에 적용하는 방법입니다.

DB Controls의 DBLookupComboBox의 기능을 라이브바인딩으로 구현하는 내용입니다.


아래 라이브바인딩 내용은 사원 테이블(qryMember)의 팀정보(MEM_TEAM_SEQ)를 콤보박스에서 선택하도록 구현한 것입니다.


  1. 콤보박스 목록 표시할 내용 - 팀명(DPT_TEAM)을 목록으로 표시
  2. 콤보박스 선택한 값을 반영 - 선택한 항목을 MEM_TEAM_SEQ에 반영(Item.LookupData와 연결된 필드의 값)
  3. 목록의 키값(LookupData) - 목록의 키값으로 사용할 필드를 Item.LooupData와 연결)

위와 같이 적용 시 콤보박스에 팀정보가 표시되고, 콤보박스를 선택하면 사원정보의 팀정보가 변경됩니다.

하지만, 콤보박스 변경 시 실시간으로 사원정보가 갱신(Refresh)되지 않고, 다른 레코드를 선택할 때 변경됩니다.

만약, 실시간으로 변경(콤보박스 변경 시 바로 사원정보의 소속팀 변경)이 필요하면 위의 그림과 같이 2번 링크를 선택 후 Track 속성을 True로 변경하면 실시간으로 반영됩니다.


참고링크



험프리.김현수 Delphi/C++Builder 라이브바인딩

[게임] 매의 눈(컵속에 숨겨진 주사위 찾기 게임)

2016.04.27 12:58

구글 플러스 델파이 개발자 그룹에 오대우님이 매의 눈이라는 게임의 소스코드를 공개하셨습니다.

매의 눈은 컵안에 숨겨진 주사위를 찾는 게임으로 현재 안드로이드 마켓에 올려놓으셨네요.


추억의 야바위(?) 게임 다운받아서 술자리에서하면 재밌을 것 같습니다.


소스코드는 드롭박스에 올려주셨네요.(미러도 제공하겠습니다.)




험프리.김현수 파이어몽키

delphi-markdown(델파이 마크다운 라이브러리) 소개

2016.04.21 17:10
마크다운 문법을 해석해 html로 반환하는 라이브러리를 발견해 공유합니다.

마크다운은? (위키백과 참고)

delphi-markdown

delphi-markdown은 마크다운(평문)을 html로 변환해 반환해주는 델파이 라이브러리로 그래함 그리브(Grahame Grieve)가 공개한 오픈소스입니다.(그래함 그리브는 세계적인 의료정보 표준화 전문가라고 합니다. FHIR 관련 프로젝트도 함께 오픈되어 있으니 의료계 관련자 분들은 참고하면 좋겠습니다.)


VCL 프로젝트에서는 해당 라이브러리를 다운로드 후 바로 (uses 절에)추가해 사용할 수 있습니다.


이 라이브러리는 RTL위주로 작성되어 약간 수정하면 모바일(파이어몽키) 프로젝트에서도 동작합니다.(아래는 아이폰6 플러스에서 실행한 모습입니다.)

파이어몽키 프로젝트에서 사용하려면 아래의 링크를 참고해 1-based 문자열 기반으로 작성된 코드를 0-bassed 문자열도 지원하도록 수정해야 합니다.


제가 테스트한 코드와 모바일에서 동작하도록 수정한 코드(기능확인을 위해 테스트 없이 문제되는 부분만 테스트 했습니다.)는 참고(만)하시기 바랍니다.^^


delphi-markdown-master.zip


험프리.김현수 Delphi/C++Builder

[마이그레이션 사례] 에스엔유프리시젼

2016.04.14 14:07

고객들의 PC환경과 요구사항이 아주 빠르게 변화하고 있습니다. 최신 PC환경과 새로운 요구사항에 대응하기 위해서는 RAD Studio(델파이, C++빌더)에서 제공하는 최신 기능을 활용하도록 마이그레이션이 필요합니다.


저도 마이그레이션 컨설팅과 마이그레이션 워크샵을 통해 마이그레이션이 필요한 프로젝트나 기업을 지원하고 있습니다.

마이그레이션을 계획하거나 진행하고 계시는 분들에게 도움되도록 과정을 간단히 정리해 공유합니다.


에스엔유프리시전 - 마이그레이션 워크샵

  • 일시 : 2016년 4월 5일 ~ 8일(4일간)
  • 지원방법 : 마이그레이션 워크샵
  • 버전 : 델파이 7 -> 델파이 XE5



지난 4월 5일~9일간 델파이 마이그레이션 워크샵 과정을 진행했습니다. 이번 워크샵 과정에 에스엔유프리시전에서 참석해 마이그레이션을 지원했습니다.


에스엔유프리시전은 OLED 장비 제조업체로 OLED 장비를 운영/제어하는 소프트웨어를 델파이7에서 델파이 XE5로 마이그레이션 진행했습니다.


사실 공장자동화와 설비 분야는 제가 익숙치 않아서 도움을 많이 못드릴까 내심 걱정했는데요. 소스가 클래스 기반으로 화면과 로직이 분리되어 있어 큰 어려움 없이 진행했습니다.


마이그레이션 과제

에스엔유프리시전의 마이그레이션 과제는 크게 2가지로 다음과 같이 해결했습니다.

1, 써드파티 컴포넌트 통합

오래된 코드들의 특징처럼 다양한 종류의 써드파티 컴포넌트를 사용중이어서, 대부분을 걷어내고 TMS 컴포넌트 셋과 기본 컴포넌트로 통합했습니다.

단순히 컴포넌트를 변경하는 작업이라면 reFind를 통해 자동화 했을텐데, 컴포넌트 변경과 함께 여러가지 속성을 추가로 설정, 변경해야 했기 때문에 컴포넌트 전환 도구(글추가)를 별도로 만들어 제공했습니다.

그리고, 단순 컴포넌트 전환은 GExpert의 Replace Components 기능을 이용해 바로바로 변환하며 작업했습니다.

UI 전환작업은 손은 많이 가지만, 난이도가 높은 작업이 아니어서 부분적으로 진행하고 다른 작업을 먼저 진행했습니다.


2, 유니코드 기반에서 통신 프로토콜의 문자 처리

시리얼통신(RS232 등)과 TCP/IP로 통신 시 문자열 처리하는 부분과 DLL 인터페이스에 대해 유니코드 적용을 검토했습니다.

유니코드 검토 도구 미리 준비해 오셔서 바로 검토 진행했습니다. 

유니코드 적용의 규칙은 간단합니다. 대상이 문자열을 AnsiString으로 받으면 AnsiString으로 넘겨주면 되고, UnicodeString으로 받으면 UnicodeString으로 넘겨주면 됩니다.

이때 대상은 윈도우API일 수도 있고, TCP/IP 서버, 장비일 수 있습니다. 코드를 살펴 대상을 확인 후 장비 등이라면 기존 델파이7에서와 마찮가지로 AnsiString으로 전달하고, 윈도우API라면 파라메터의 데이터타입을 확인해 Char를 AnsiChar로 string을 AnsiString으로 변경해주면 됩니다.

의심이 가는 코드들은 반드시 테스트 코드를 작성해 검증하고 적용해야 합니다.


추가 지원 정보 및 시스템 확장

마이그레이션 과제로 가져온 내용 외에 필요한 마이그레이션 대상과 시스템을 확장할 수 있는 방안을 소개해드렸습니다.

1, 데이터베이스 전환

BDE를 FireDAC으로 전환했는데, DB 접근하는 곳을 하나의 클래스로 모아놔서 별도의 자동화 도구 없이 손쉽게 적용했습니다. 대신 DB 프로그래밍이 익숙치 않으셔서 간단히 사용법을 안내드렸습니다.

그리고, 라이선스가 있는 MS Access를 대신할 수 있는 IBLite와 SQLite를 소개하고 연결하는 과정을 진행했습니다.


2, 델파이7 이후 새로운 기능  소개

오랫동안 델파이7으로 개발한 경우 IDE 사용법이 낮설고, 추가된 기능들을 잘활용하지 못하는 경우가 많습니다. 마침 제가 정리해 놓은 델파이7 이후의 새로운 기능 페이지를 통해 IDE 그리고 새로운 기능, 컴포넌트 등을 소개했습니다.


3, OOP 소개

소스가 OOP 기반으로 견고히 구축되어 있고, OOP와 설계에 관심이 많으셔서 제가 이전에 사용했던 패턴(옵저버 + 커맨드 패턴)을 소개해 드리고, 인터페이스 개념과 사용법을 안내해 드렸습니다. 워낙 도움이 많이 되셨다고 칭찬해 주셔서 특강이나 별도의 글로 작성해야 겠다는 욕심이 들었네요.(생각보다 OOP에 대한 관심이 많은 것 같습니다. 혹시 OOP 특강이 필요하시면 저에게 요청해주세요.^^)


4, 현대식 문법 소개

타입 헬퍼, 제너릭, 익명메소드등 코드를 더 간격하게 작성할 수 있는 델파이 현대식 문법의 사용법을 소스코드 기반으로 소개


5, 모바일과 사물인터넷으로 확장

최신 버전으로 마이그레이션 했다는 것은 모바일, 사물인터넷 기능을 이용해 기능을 확장할 수 있도록 준비되었다는 의미입니다. 설비등 공장의 장비를 제어하는 경우 외부에서 모바일로 장비를 모니터링하고, 긴급상황에 대한 알림을 제공한다면, 기존 시스템을 한단계 업그레이드해 경쟁의 우위를 갖을 수 있습니다. 이 기능을 멀티-디바이스 프레임워크인 파이어몽키 프레임워크와 앱테더링 을 통해 모니터링 및 제어할 수 있는 모바일 앱을, 긴급상황 알림 등은  비콘, 블루투스 등으로 사물인터넷으로 확장하는 방안을 작은 규모로 컨설팅(?) 해 드렸습니다.


총 평

아직 많은 분들이 마이그레이션을 준비하고, 계획하고 있는것으로 압니다.

사신 마이그레이션 자체는 기술적으로 크게 어렵지 않습니다. 대부분 어려워하는 부분이 수많은 코드를 어떻게(언제) 작업 할지에 대한 고민입니다.그런 고민이 있다면 최대한 자동화하는 방법을 찾아보시기 바랍니다. 컴포넌트 전환을 자동화 하는 도구 들을 이용하고, 필요하다면 자동화 도구를 직접 만드시기 바랍니다. 마이그레이션을 자동화하면 작업 일정을 대폭 줄이고, 소스코드 품질 향상과 안정성을 확보할 수 있는 테스트에 더 많은 시간을 할애할 수 있습니다.


이번 마이그레이션 작업도 마이그레이션 작업보다, UI 개선(써드파티 컴포넌트 통합, TMS 컨트롤 적용), 소스코드 품질향상(현대식 문법, OOP 적용 등), 안정성/성능향상(BDE > FireDAC), 그리고 시스템 확장(모바일, 사물인터넷)하는 부분에 더 많은 시간을 투자했습니다.


마지막으로 마이그레이션을 진행한 담당자가 이야기해준 마이그레이션 워크샵의 좋은 점과 아쉬운점을 남기고 마무리합니다.


워크샵에 참석해 좋은 점은

  • 작업하며 막히는 부분을 바로바로 풀어줘서 빠르게 막힘없이 빠르게 진행해 좋았다.
  • 새로운 개발환경이 부담 되었는데 함께 작업하며 새 버전의 IDE에 익숙해 져서 좋았다.
  • 현대식 문법과 OOP 등 평상시 궁금했던 내용을 자유롭게 이야기하고 들을 수 있어서 좋았다.
  • 시스템 확장할 수 있는 아이디어와 방법, 기술을 알게되어 좋았다.

아쉬운 점은 

  • 실 장비와 떨어진 환경에서 제한적으로 테스트해서 북귀 후 추가작업을 진행해서 아쉬웠다.


마이그레이션이 부담되거나, 어떻게 시작할지 어려움이 있다면 마이그레이션 워크샵과정에 참석하세요.

마이그레이션 자동화 도구로 수작업을 줄여 기간을 단축해주고, 어려운 부분은 멘토링으로 해결해 드립니다.
(마이그레이션 컨설팅(1~2 주 이상 방문해 진행)이 필요한 경우 데브기어(ask@embarcadero.kr)로 별도로 연락주세요.)


험프리.김현수 마이그레이션

[OSX/맥] 맥의 스크린세이버 비활성화/활성화 시키기

2016.04.04 13:25

볼랜드포럼에서 무대뽀님이 남겨준 팁 공유합니다.(작업한 내용 공유해주셔서 감사합니다^^)



무대뽀님께서 맥용 애플리케이션 개잘 중 맥의 스크린 세이버를 비활성화 시키는 질문을 볼랜드포럼에 올려서 간단히 댓글을 드렸더니 멋지게 기능을 완성하셨네요.(http://firemonkey.borlandforum.com/impboard/impboard.dll?action=read&db=firemonkey_qna&no=146)


제가 작성한 답변입니다.

맥 개발자 라이브러리에 아래와 같은 샘플이 있습니다. 

https://developer.apple.com/library/mac/samplecode/SceneKitWWDC2014/Listings/Scene_Kit_Session_WWDC_2014_AAPLAppDelegate_m.html 

그 중 아래 코드를 호출하면 됩니다. 
IOPMAssertionID _assertionID; 

- (void)disableDisplaySleeping { 
    CFStringRef reasonForActivity = CFSTR("Scene Kit Presentation"); 
    IOPMAssertionCreateWithName(kIOPMAssertionTypeNoDisplaySleep, kIOPMAssertionLevelOn, reasonForActivity, &_assertionID); 


- (void)enableDisplaySleeping { 
    if (_assertionID) 
        IOPMAssertionRelease(_assertionID); 


위가 잠자는걸 막는 거고 아래는 막은걸 해지하는 겁니다. 

위 메소드 들은 Macapi 중 IOKit에 구현되어 있습니다.(즉 맥의 라이브러리를 이용해야 한다는 거죠.) 
아쉽게도 파이어몽키에 구현된 IOKit을 보면 구현된 API가 몇가지 안됩니다. 
(C:\Program Files (x86)\Embarcadero\Studio\17.0\source\rtl\osx\Macapi.IOKit.pas) 

위 문서와 애플 기술문서를 참고하셔서 필요한 API를 추가하시고 호출하는 코드를 작성해 보시기 바랍니다. 
아래 애플 기술문서가 도움이 될것입니다. 
https://developer.apple.com/library/mac/documentation/IOKit/Reference/IOPMLib_header_reference/#//apple_ref/c/econst/kIOPMAssertionLevelOn 


위 내용을 참고로 Macapi.IOKit.pas에 필요한 메소드를 추가/확장했습니다.

기존의 유닛(C:\Program Files (x86)\Embarcadero\Studio\17.0\source\rtl\osx\Macapi.IOKit.pas)을 확장하기 위해서는 유닛파일(*.pas)를 복사 해 프로젝트 파일(*.dpr)과 같은 경로에 복사후 수정하면 프로젝트 파일과 같은 경로의 유닛을 먼저 참조합니다.


unit Macapi.IOKit 

... 

const 
  kIOMasterPortDefault: mach_port_t = 0; 
  kIOPlatformUUIDKey = 'IOPlatformUUID'; 

  // add 
  kIOPMAssertionLevelOff = 0; 
  kIOPMAssertionLevelOn  = 255; 
  kIOPMAssertionTypeNoDisplaySleep = 'NoDisplaySleepAssertion'; 

... 
type 
... 
function ... 
... 
function IOObjectRelease(anObject: io_object_t): kern_return_t; cdecl; external libIOKit name _PU + 'IOObjectRelease'; 

// add // AssertionID는 Uint32의 포인터형 
function IOPMAssertionCreateWithName(AssertionType : CFStringRef; AssertLevel : uint32_t; 
  AssertionName : CFStringRef; AssertionID : uint32_t) : uint32_t; cdecl; external libIOKit name _PU + 'IOPMAssertionCreateWithName'; 
function IOPMAssertionRelease(AssertionID : uint32_t) : uint32_t; cdecl; external libIOKit name _PU + 'IOPMAssertionRelease'; 


추가한 API를 사용하는 코드는 아래와 같습니다. 버튼을 눌러 비활성화/활성화 시킵니다.

TForm1 = class(TForm) 
  procedure BtnDisableClick(Sender: TObject); 
  procedure BtnEnableClick(Sender: TObject); 
private 
  FSleepAssert : UInt32; 
public 
end; 

implementation 

uses 
  Macapi.IOKit, Macapi.CoreFoundation; 

............ 
procedure TForm1.BtnDisableClick(Sender: TObject); 
begin 
  FSleepAssert := 0; 
  IOPMAssertionCreateWithName(CFSTR(kIOPMAssertionTypeNoDisplaySleep), kIOPMAssertionLevelOn, CFSTR('MyProject is Good'), FSleepAssert); 
  if FSleepAssert = 0 then 
    ShowMessage('Disable Failed!!'); 
end; 

procedure TForm1.BtnEnableClick(Sender: TObject); 
begin 
  if FSleepAssert > 0 then 
    IOPMAssertionRelease(@FSleepAssert); 
end; 

다시한번 좋은 자료 공유해 주신 무대뽀님에게 감사인사를 전합니다.

험프리.김현수 파이어몽키

  1. Blog Icon
    무대뽀

    제가 Disable에만 신경쓰느라 미쳐 못봐서 실수한부분이 있었네요. 번거롭지만 다시 수정 부탁드려요 ^^;;
    function IOPMAssertionRelease(AssertionID : Pointer) : uint32_t; ... 에서
    파라메터가 Pointer가 아닌 uint32_t 입니다. ㅠ_ㅠ
    function IOPMAssertionRelease(AssertionID : uint32_t) : ... 이고
    예제의 파라메터도 @FSleepAssert가 아닌 @뺀 FSleepAssert로 수정 부탁드릴께요.

    정리된 자료들 아주 잘 보고있습니다. 정말 도움이 많이 되고있습니다.!!
    이자리에서나마 정말 고마움을 표합니다. ^^*

  2. 네. 수정했습니다.
    도움이 되셨다니 제가 감사합니다.
    무대뽀님도 정리차원에서 많은 자료 공유 부탁드립니다.

[FMX] 앱에서 문장을 출력하는 3가지 방법

2016.04.04 11:22

앱에서 긴 글을 표시해야 하는 경우 3가지 방법을 이용해 표현할 수 있습니다.(아래 방법외에도 더 많은 방법이 있을 수 있습니다.)



TextContents.zip


1, TMemo 이용

문장을 나타내는 대표적인 컴포넌트입니다. 문장 출력뿐아니라 입력도 받을 수 있습니다.

출력이 목적인 경우 ReadOnly 속성을 True로 설정하면 입력을 제한합니다.

자동 줄바꿈이 필요하면 TextSettings.WordWrap 속성을 True로 설정합니다.


2, TWebBrowser + HTML 이용

HTML을 표현하는 웹브라우저에 문장을 출력하는 방법입니다. HTML 태그를 이용해 글자크기, 색상, 스타일 등을 자유롭게 사용할 수 있습니다. 만약, 문장이 HTML로 구성된 경우 아주 좋은 선택 입니다.
웹브라우저에 HTML을 불러오려면 아래와 같이 LoadFromString 메소드를 이용합니다.
  WebBrowser1.LoadFromStrings(html, '');

3, TVertScrollBox + TText 이용

수직으로만 스크롤되는 스크롤박스(TVerScrollBox)에 텍스트(TText)를 추가해 문장을 표현하는 방법입니다.

여러개의 텍스트를 추가하면 글자크기, 색상, 스타일을 다르게 지정할 수 있습니다.

텍스트를 상단에 정렬(Align := Top)하면 추가된 순서대로 위에서부터 표시되며, AutoSize 속성을 True로 설정해 높이를 자동 조정할 수 있습니다.

아래 코드는 몇가지 속성을 설정해 동적(코드작성)으로 텍스트를 추가하는 코드 입니다.

procedure TForm1.Button2Click(Sender: TObject);
  procedure AddText(const AText: string; AFontSize: Integer = 12; AFontColor: TAlphaColor = TAlphaColorRec.Black);
  var
    Text: TText;
  begin
    Text := TText.Create(Self);
    Text.Parent := VertScrollBox1;
    Text.Align := TAlignLayout.Top;
    Text.TextSettings.HorzAlign := TTextAlign.Leading;
    Text.TextSettings.Font.Size := AFontSize;
    Text.TextSettings.FontColor := AFontColor;
    Text.AutoSize := True;
    Text.Text := AText;
  end;

var
  S: string;
begin
  AddText('제목1', 20);
  S := 'SVN 서버 소프트웨어는 소스코드 ......';
  S := S + '예를들어, 팀내에서 소스코드를 ......';
  S := S + '만약, 외부와 협업이 필요한 경우 ......';
  AddText(S);

  AddText('제목2', 15, TAlphaColorRec.Red);

  S := 'SVN 서버 소프트웨어는 오픈 소프트웨어 부터 상용 소프트웨어까지 다양하게 선택할 수 있습니다.';
  S := S + '아래 링크를 참고해 원하는 플랫폼과 원하는 SVN 서버 소프트웨어를 설치할 수 있습니다.';
  AddText(S);
end;

추가로, 

델파이 마크다운 라이브러리를 이용할 수 있습니다. 다음 링크를 확인하세요.

http://blog.hjf.pe.kr/428

험프리.김현수 파이어몽키

[안드로이드/iOS] 이미 배포(Deployment)된 파일 업데이트 하기

2016.03.31 11:06

사운드, 이미지, 텍스트 파일을 최초배포하고, 변경된 파일을 다시 배포할 경우 덮어쓰기(overwrite)가 되지않는 이슈가 있습니다.(10 시애틀. 2016년 3월) 해당 증상은 안드로이드와 iOS 모두 해당됩니다.

해당 이슈는 파일을 배포하는 System.StartUpCopy.pas에 구현된 내용을 살펴보니 배포 대상파일이 있는 경우(FileExist) 배포를 진행하지 않도록 구현되어 있습니다.


위 이슈를 해결하는 방법은 3가지 정도로 생각해볼 수 있습니다.

1, System.StartUpCopy.pas를 수정하는 방법

2, 업데이트할 파일을 새로운 이름으로 배포하고, 앱 시작시 기존 파일로 덮어쓰는 방법

3, 파일을 앱과 함께 최초 배포 후, 파일 변경이 필요할 경우 인터넷 등을 통해 자동 업데이트 하는 방법


1, System.StartUpCopy.pas를 수정하는 방법

http://qc.embarcadero.com/wc/qcmain.aspx?d=125481 링크를 방문해 Xavier Dufaure de Citres 글을 참고해 수정할 수 있습니다.

Xavier Dufaure de Citres at 12/14/2014 3:10:58 PM -
Here is a workaround on Android:
* modify System.StartUpCopy
   - in the interface section add "Var ASSET_OVERWRITE : Boolean = false;"
   - in the interface section exopose "procedure CopyStartUpFiles;"
   - in the CopyAssetToFile change "if (not FileExists(DestFileName)) then" by "if (not FileExists(DestFileName)) or ASSET_OVERWRITE then"

* in your own code, store in the preference file the last version the user ran. If the current version is newer do
  if optLastVersionRan<Version then
  Begin
    ASSET_OVERWRITE := true;
    CopyStartUpFiles;
    ASSET_OVERWRITE := false;
  End;

On the 1st installation the data will be copied twice (no biggy), on update the file will be overwritten.

Note for iOS: i find out that deploying the files i need in ".\Data\" is much better: it put the file directly in the bundle, this way the file are not archived (i got my app rejected because i had 12 Mb of data that was archived). Of course these files can only be read only.


2, 업데이트할 파일을 새로운 이름으로 배포하고, 앱 시작시 기존 파일로 덮어쓰는 방법 

배포파일이 업데이트 되면 새로운 파일명으로 배포 후 앱 시작 시 원래파일로 덮어쓰는 방식입니다.

위 이미지와 같이, "deploy.txt" 파일 배포 시 remote name을 "deploy_2.txt"로 배포했습니다.


프로젝트에는 아래와 같은 코드를 구현했습니다.(코드에 대한 설명은 생략합니다.)

uses
  System.IOUtils;

procedure TForm1.Button1Click(Sender: TObject);
var
  Path: string;
begin
  Path := TPath.Combine(TPath.GetDocumentsPath, 'deploy.txt');
  Memo1.Lines.LoadFromFile(Path);
end;

procedure TForm1.DeployFileUpdate(const AFilename, AUpdateFilename: string);
var
  OrgPath, UptPath: string;
begin
  OrgPath := TPath.Combine(TPath.GetDocumentsPath, AFilename);
  UptPath := TPath.Combine(TPath.GetDocumentsPath, AUpdateFilename);

  if TFile.Exists(UptPath) then
  begin
    if TFile.Exists(OrgPath) then
      TFIle.Delete(OrgPath);
    TFile.Move(UptPath, OrgPath);
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  DeployFileUpdate('deploy.txt',  'deploy_2.txt');
//  DeployFileUpdate('sound1.wav',  'sound1_2.wav');
//  DeployFileUpdate('env.ini',     'env_2.ini');
end;


3, 파일을 앱과 함께 최초 배포 후, 파일 변경이 필요할 경우 인터넷 등을 통해 자동 업데이트 하는 방법

배포파일 자동 업데이트는 파일별 버전관리가 필요하며, 업데이트 파일을 내려주는 서버가 필요합니다.

앱 실행 시 배포파일 버전을  서버에서 확인 후 업데이트할 파일이 있으면, Http, FTP 등으로 파일을 다운로드해 배포파일을 교채하는 방식입니다.

웹상의 파일을 다운로드 받는 방법은 아래 링크를 참고할 수 있습니다.

참고링크


  • 모바일(iOS, Android)에서 사용자 파일 배포 및 사용 : http://blog.hjf.pe.kr/104



험프리.김현수 파이어몽키

[VCL] 다른 프로세스의 폼을 패널등에 넣기

2016.03.07 15:52

프로세스를 생성하고 프로세스의 폼을 내 애플리케이션의 특정 영역(패널 등)에 넣도록 하는 코드입니다.


1, 아래 그림과 같이 메모장(notepad.exe)을 실행해 Panel에 넣어봤습니다. 

2, 프로세스의 폼(메모장)의 테두리를 없앴습니다.

3, 창 크기가 변경될때 프로세스의 폼 크기를 변경하도록 했습니다.(비동기)


EmbedFormSource.zip


uses
  Winapi.ShellAPI;

// 메모장 실행 / Embed  시키기
procedure TForm1.Button1Click(Sender: TObject);
var
  ExecuteFile : string;
  SEInfo: TShellExecuteInfo;
  RetryCount: Integer;
begin
  ExecuteFile:='c:\Windows\notepad.exe';

  FillChar(SEInfo, SizeOf(SEInfo), 0) ;
  SEInfo.cbSize := SizeOf(TShellExecuteInfo) ;
  with SEInfo do
  begin
    fMask := SEE_MASK_NOCLOSEPROCESS;
    Wnd := Panel1.Handle;
    lpFile := PChar(ExecuteFile) ;
    nShow := SW_HIDE;
  end;
  if ShellExecuteEx(@SEInfo) then
  begin
    // 실행 후 바로 찾을 수 없어 윈도우 핸들 찾기 재시도
    RetryCount := 0;
    repeat
      FAppWnd := FindWindow(PChar('notepad'), PChar('제목 없음 - 메모장'));
      Sleep(100);
      Inc(RetryCount);
    until (FAppWnd <> 0) or (RetryCount > 10);

    // 부모설정, 테두리제거, 최대화
    if FAppWnd <> 0 then
    begin
      WinAPI.Windows.SetParent(FAppWnd, SEInfo.Wnd);
      SetWindowLong(FAppWnd, GWL_STYLE,
              GetWindowLong(Handle, GWL_STYLE)  // 기존 스타일에서
          and not WS_BORDER                     // 크기조정 테두리 - 제거
          and not WS_THICKFRAME                 // 두꺼운 프레임 - 제거
          and not WS_DLGFRAME                   // 이중 테두리 - 제거
      );
      ShowWindow(FAppWnd, SW_SHOWMAXIMIZED);
    end;
  end;
end;

// 메모장 닫기(프로세스 종료)
procedure TForm1.Button2Click(Sender: TObject);
begin
  if FAppWnd <> 0 then
  begin
    PostMessage(FAppWnd, WM_Close, 0, 0);
    FAppWnd := 0;
  end;
end;

// 메모장 크기 조절
procedure TForm1.Panel1Resize(Sender: TObject);
begin
  if IsWindow(FAppWnd) then
    SetWindowPos(FAppWnd, 0, 0, 0, Panel1.Width, Panel1.Height, SWP_ASYNCWINDOWPOS);
end;


참고링크



험프리.김현수 Delphi/C++Builder

  1. 정말 감사합니다. 올바른 사용법을 찾았네요

    ActionList가 dll폼에서 제대로 작동하지 않아 exe를 패널안에 만들어 넣어보려고 하던중이었습니다.

RAD Studio IDE에서 SVN 사용하기 + TortoiseSVN 사용하기

2016.02.29 16:26

소스코드 버전관리 시스템으로 SVN을 사용하기 위해 SVN 서버 소프트트웨어를 서버에, 사용자 PC에 SVN 클라이언트 소프트웨어를 설치해야 합니다. 


이 글에서는 RAD Studio IDE에 내장된 SVN 클라이언트 플러그인을 이용해 SVN 서버 저장소에 파일을 등록(Import)하고 변경내역을 가져오고(Update), 작업내용을 저장(Commit)하는 내용을 설명합니다.

(RAD Studio에는 SVN, Git, Mercurial 3가지 버전관리 클라이언트 기능을 제공합니다.)


RAD Studio에 내장된 SVN 클라이언트 플러그인

SVN 저장소를 준비합니다.(만약, SVN 저장소가 없다면 다음 글을 참고해 SVN 서버 설치 후 저장소를 추가합니다. - http://blog.hjf.pe.kr/417)


SVN 저장소에 추가하기 - Add to Version Control(SVN: Import)

작성중인  소스코드를 SVN 서버의 중앙 저장소에 저장합니다. 이후 프로젝트 파일을 열고 소스코드를 변경 하구 중앙저장소에 반영(Commit)할 수 있습니다.
  1. 새로운 프로젝트를 추가(또는 작업 중인 프로젝트 열기) 합니다.
  2. 프로젝트 매니저에서 프로젝트를 우측 마우스 클릭 후 "Add to Version Control" 메뉴를 선택합니다.
  3. 버전관리 시스템 중 Subversion을 선택 합니다.
  4. Import 팬이 표시됩니다.
  5. URL of repository: 우측의 [...] 버튼을 누릅니다.
  6. SVN 저장소 주소를 입력 후 [Load] 버튼을 눌러 저장소와 연결합니다.
  7. 좌측 트리에서 저장할 디렉토리를 선택 후 [OK] 버튼을 누릅니다.
  8. [Import] 버튼을 눌러 서버 저장소에 저장합니다.

RAD Studio 10 시애틀에서 테스트 중 중앙저장소에 연결된 프로젝트에 프로젝트를 추가한 경우 [Import] 버튼이 비활성화 되는 현상이 발생했습니다.

이 경우 별도의 TortoiseSVN 등의 클라이언트 프로그램을 이용해 Import 작업을 진행하면 Commit / Upate 등의 작업을 IDE에서 이어서 진행할 수 있습니다.

SVN 저장소의 소스코드 가져오기 - Open From Version Control(SVN: Check out)

SVN 서버의 중앙저장소에 저장된  소스코드를 가져와 편집 후 작업내용을 중앙저장소에 저장할 수 있습니다.

  1. RAD Studio IDE에서 모든 파일을 닫습니다.
  2. File > Open From Version Control... 메뉴를 선택합니다.
  3. 버전관리 시스템 중 Subversion을 선택합니다.
  4. 저장소 경로(URL of Repository)와 저장할 로컬 경로(Destination)를 입력 후 [OK] 버튼을 클릭합니다.
  5. 다운로드 작업이 진행되며 완료 후 프로젝트를 선택해 열수 있습니다.

저장소에 작업내용 적용하기 / 중앙저장소 변경내역 가져오기 - Commit / Update

SVN 서버의 중앙저장소와 연결된 프로젝트는 작업내용(변경된 내용)을 중앙저장소에 적용하는 커밋(Commit)과 다른 사용자가 변경한 변경내역을 가져오는 Update 작업을 수행할 수 있습니다.

  1. SVN 서버의 저장소와 연결된 프로젝트를 엽니다.
  2. 프로젝트 매니저에서 우측 마우스 클릭 후 Subversion > Commit 메뉴를 선택합니다.
  3. Commit 팬이 표시됩니다.
  4. 중앙저장소에 저장할 파일을 선택(체크박스 선택)합니다.
  5. 변경한 작업에 대한 설명을 다른 사용자가 알아볼 수 있도록 작성합니다.
  6. [Commit] 버튼을 눌러 중앙저장소에 반영합니다.
  7. 프로젝트 매니저에서 우측 마우스 클릭 후 Subversion > Update 메뉴를 선택해 중앙저장소의 변경된 내역을 받아옵니다.

기타 더 많은 기능을 엠바카데로 기술문서를 참고해서 익힐 수 있습니다.

SVN 클라이언트 프로그램 이용

RAD Studio IDE에서 SVN을 제공하지 않는 버전을 사용한다면 별도로 SVN 클라이언트 프로그램을 설치해서 RAD Studio 소스코드를 버전관리 할 수 있습니다.

아래 링크를 참고해 원하는 플랫폼과 원하는 SVN 소프트웨어를 설치할 수 있습니다.

그 중 TortoiseSVN의 경우 윈도우의 기본 탐색기 팝업메뉴를 이용해 SVN 클라이언트 기능을 활용할 수 있습니다.



Tortoise SVN 사용법은 아래 링크들에서 자세히 확인해보시기 바랍니다.


관련자료

험프리.김현수 Delphi/C++Builder

SVN 서버 설치하기 - Visual SVN 이용

2016.02.29 14:40

소스코드 버전관리 시스템으로 SVN을 사용하기 위해 SVN 서버 소프트트웨어를 서버에, 사용자 PC에 SVN 클라이언트 소프트웨어를 설치해야 합니다.


이 글에서는 SVN 서버 소프트웨어를 서버에 설치하는 내용을 설명합니다.


SVN 서버 소프트웨어는 소스코드 버전관리 해야하는 작업자들이 접속할 수 있는 서버 머신에 설치해야 합니다.

예를들어, 팀내에서 소스코드를 버전관리 해야하는 경우 팀내에서 운영 중인 사내의 팀서버에 설치하는 것이 좋습니다.

만약, 외부와 협업이 필요한 경우 IDC 등에 SVN 서버 소프트웨어를 설치하면 외부 인원과도 소스코드 버전관리 할 수 있습니다.


SVN 서버 소프트웨어

SVN 서버 소프트웨어는 오픈 소프트웨어 부터 상용 소프트웨어까지 다양하게 선택할 수 있습니다.

아래 링크를 참고해 원하는 플랫폼과 원하는 SVN 서버 소프트웨어를 설치할 수 있습니다.

❑ Visual SVN 설치

저는 윈도우에서 손쉽게 설치 및 사용할 수 있는 Visual SVN Server을 설치했습니다.

라이선스

Visual SVN Server는 기능에 따라 Standard와 Enterprise로 구분되며 Standard는 회사에서도 무료로 설치(Avaliable for commercial use)할 수 있습니다.

설치

본인의 환경에 따라 32 bit 또는 64 bit 설치 파일을 받아 설치 파일 실행 후 안내에 따라 설치 합니다.

설치가 완료되면 시작 메뉴에서 "VisualSVN Server Mnager"를 찾아 실행하면 아래 화면이 표시됩니다.

❑ 저장소 및 사용자 생성

SVN  서버로 사용하기 위해서는 소스코드 저장소  생성과 사용자를 추가해야 합니다.(이 작업은 지정된 관리자가 하게 됩니다.)

저장소 생성

소스코드 버전관리가 필요한 프로젝트 또는 서비스 별로 저장소를 생성합니다.

왼편 트리메뉴에서 Repositories 항목  선택 후 오른쪽 팬에서 우측 마우스 버튼을 이용해 저장소를 생성(Create New Repository...)합니다.


저장소 유형, 저장소 이름, 저장소 구조를 선택합니다.

접근권한(접근 권한은 사용자 추가 후 다시 조정합니다.) 확인 후 저장소 생성을 마칩니다.


사용자 추가

왼쪽 트리메뉴에서 Users 메뉴 선택 후 오른쪽 팬에서 사용자를 추가(Create user)합니다.


저장소의 속성(Properties) 창의 Security 탭에서 접근 권한을 사용자 별로 조정합니다.

기타 참고사항

기타 추가적인 내용은 아래 링크를 참고해 확인하시기 바랍니다.

관련자료



험프리.김현수 Delphi/C++Builder