Search results for '전체'

  1. 2016.11.21 -- Out of memory 오류 해소 방안 (1)
  2. 2016.10.04 -- [필립스 휴] API 정리 (1)
  3. 2016.09.28 -- 마우스 이벤트 캡쳐 - SetCapture, ReleaseCapture
  4. 2016.09.22 -- 모바일 디바이스 화면 방향전환 이벤트 수신하기
  5. 2016.09.21 -- Object Pascal Style Guide
  6. 2016.09.20 -- TListView Dynamic Appearance로 추가한 항목을 코드로 제어하기 (1)
  7. 2016.08.31 -- 리눅스(우분투) 설치 (1)
  8. 2016.08.31 -- TWICImage를 이용해 다양한 이미지 포맷의 파일을 불러오고 저장하기.
  9. 2016.08.02 -- [마이그레이션 사례] 감리교 신학대학교
  10. 2016.08.01 -- 퀵레포트(Quick Report)에 사진 출력하기
  11. 2016.08.01 -- 퀵레포트 보고서 엑셀로 내보내기(저장하기) (1)
  12. 2016.08.01 -- BLOB 컬럼에서 (이미지 등의)데이터 읽고 쓰기
  13. 2016.07.28 -- 구글 통계(Google Analytics)를 써드파티 컴포넌트 없이 구현하는 방법
  14. 2016.07.20 -- [팁] 파라메터 값이 포함된 쿼리 문자열 만들기
  15. 2016.06.27 -- [교육] 마이그레이션 워크샵 과정
  16. 2016.06.02 -- [팁] 소스코드 압축 시 불필요한 확장자 파일 제거하고 압축하기(7zip 이용)
  17. 2016.05.27 -- VCL 스타일이 적용된 앱을 다른 프로세스에 넣을때 메인메뉴가 클릭되지 않는 이슈 해결방법
  18. 2016.05.18 -- [교육] 숭실대학교 - 컴퓨팅적 사고
  19. 2016.04.28 -- [라이브바인딩] 콤보박스에 목록표시, 선택 값 반영하기
  20. 2016.04.27 -- [게임] 매의 눈(컵속에 숨겨진 주사위 찾기 게임)

Out of memory 오류 해소 방안

2016.11.21 10:42

메모리 부족(Out of memory) 오류 해소 방안을 델파이 기준으로 설명합니다.

증상

윈도우즈 기반 애플리케이션 시작 또는 실행 중 Out of memory 예외(Exception)이 발생



원인

  • 데스크탑 힙 제한에 의한 메모리 부족
  • 메모리 누수(Leak)에 의한 메모리 부족
  • 과도한 메모리 사용에 의한 메모리 부족


    조치방법

    데스크탑 힙 제한에 의한 메모리 부족

    데스크탑 힙 제한에 의한 메모리 부족 오류가 발생할 수 있습니다.

    마이크로소프트 지원 페이지에서 레지스트리를 수정하는 해결 방법을 안내합니다.


    메모리 누수(Leak)에 의한 메모리 부족

    프로그램내에서 할당된 메모리를 사용 후 반환하지 않는 메모리 누수가 반복될 경우 메모리 부족이 발생합니다.


    델파이에서는 FastMM 메모리 관리자(2006 이후 기본 제공)의 정지 시 메모리 누수 보고 기능을 이용해 애플리케이션 종료 시 메모리 누수 보고를 받을 수 있습니다.


    종료 시 메모리 누수 보고 기능을 활성화 하려면

    • ReportMemoryLeaksOnShutdown 전역 변수를 True로 설정합니다.
    • 보통 프로젝트 파일에 선언합니다.

    begin

      ReportMemoryLeaksOnShutdown := True;


      Application.Initialize;

      Application.MainFormOnTaskbar := True;

      Application.CreateForm(TForm1, Form1);

      Application.Run;

    end. 

    • 프로그램 종료 시 메시지 박스를 통해 누수된 내용을 표시합니다.
      • 생성 후 해재하지 않은 객체의 클래스명과 크기, 갯수를 알려줍니다.
      • 단, 어느 지점에서 발생한지는 알 수 없습니다.
      • 되도록, 개발시점에 메모리 릭을 파악하는 용도록 활용하는 것이 좋습니다.

    기타 자세한 내용은 아래 엠바카데로 기술문서를 참고하시기 바랍니다.


    과도한 메모리 사용에 의한 메모리 부족

    시스템 상의 메모리보다 과도한 메모리를 사용한 경우 메모리 부족 오류가 발생할 수 있습니다.


    이경우 작은 범위의 테스트에서 문제가 발생하지 않다가, 실사용 시 문제가 발생할 수 있습니다.

    보통 다수의 UI 컨트롤들을 갖는 화면 여러개를 동시에 표시하거나, 다수의 응용 프로그램을 동시에 실행하는 경우 발생할 수 있습니다.


    이 경우 구현상의 이슈보다는 운영상의 이슈이므로, 운영 중 사용자의 메모리 상태를 모니터링 하고, 동시에 표시할 수 있는 화면을 제한하는 등의 과도한 메모리 사용 방어 장치가 필요합니다.


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

    1. UMDH(user-mode dump heap)를 이용해 메모리 릭을 찾아내는 방법이 있네요.
      http://www.gamedevforever.com/103
      https://support.microsoft.com/ko-kr/help/268343/umdhtools.exe-how-to-use-umdh.exe-to-find-memory-leaks

      나중에 저도 한번 (델파이 코드에 대해)테스트 해봐야겠습니다.

      UMLD: Memory Leak Detector and Bug Reporter v.1.0
      http://torry.net/pages.php?id=1526

    [필립스 휴] API 정리

    2016.10.04 11:44

    필립스 휴는 REST API를 통해 전구를 제어할 수 있는 제품입니다.


    구성


    전구는 브릿지를 통해 제어하며, 애플리케이션은 브릿지에게 명령을 전송하면 브릿지가 개별전구를 제어하는 방식으로 구성됩니다. 

    브릿지는 여러개의 전구와 ZigBee로 연결되어 있습니다.


    필립스 휴 API 시작하기

    http://www.developers.meethue.com/documentation/getting-started

    사용자 등록

    Addresshttp://<bridge ip address>/api
    Body{"devicetype":"사용자 아이디"}
    MethodPOST

    조명 ON/OFF

    Addresshttp://<bridge ip address>/api/{사용자 아이디}/lights/1/state
    Body{"on":false}
    MethodPUT



    새로운 조명 추가

    http://www.developers.meethue.com/documentation/lights-api#13_search_for_new_lights


    새 전구 검색

    URL/api/<username>/lights
    MethodPOST
    Version1.0
    PermissionWhitelist

    새로운 조명에 전원을 연결하고 위 명령 전송

    조명이 검색되면 조명이 깜빡임




    험프리.김현수 기타정보

    1. Blog Icon

      비밀댓글입니다

    마우스 이벤트 캡쳐 - SetCapture, ReleaseCapture

    2016.09.28 17:10

    마우스 이벤트를 캡쳐해야 하는 경우 SetCapture(Win32 API)를 이용하면 됩니다.

    다 사용한 경우 ReleaseCapture로 해제합니다.



    아래 예제는

    1) 폼위에 패널 위치

    2) 폼과 패널은 각각 MouseMove 이벤트에서 로그 기록

    3) 패널에서 MouseDown 시 폼으로 SetCapture 시도 > 이후 패널 및 메모 위의 마우스 이벤트가 폼에서 발생

    4) MouseUp 시(폼에서 마우스 이벤트를 가져가 폼의 MouseUp이벤트에서 구현필요) ReleaseCapture로 캡쳐 해제

    procedure TForm2.FormCreate(Sender: TObject);
    begin
      FIsCaptured := False;
    end;
    
    procedure TForm2.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Integer);
    begin
      Memo1.Lines.Add(Format('F> X: %d, Y: %d', [X, Y]))
    end;
    
    procedure TForm2.FormMouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    begin
      if FIsCaptured then
      begin
        Memo1.Lines.Add('Form> ReleaseCapture');
        ReleaseCapture;
      end;
    end;
    
    procedure TForm2.Panel1MouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    begin
      SetCaptureControl(Self);
    //  SetCapture(Self.Handle);
      Memo1.Lines.Add('Panel> Capture');
    
      FIsCaptured := True;
    end;
    
    procedure TForm2.Panel1MouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Integer);
    begin
      Memo1.Lines.Add(Format('P> X: %d, Y: %d', [X, Y]))
    end;
    
    procedure TForm2.Panel1MouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    begin
      ReleaseCapture;
      Memo1.Lines.Add('Panel> ReleaseCapture');
    end;



    샘플 : 

    SetCaptureReleaseCapture.zip


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

    모바일 디바이스 화면 방향전환 이벤트 수신하기

    2016.09.22 10:23

    모바일 디바이스의 방향을 가로 또는 세로, 그리고 역방향으로 돌리는 동작을 알아낼 수 있습니다.


    파이어몽키 프레임워크에서 제공하는 기능으로 TMessageManager에 구독해 이벤트를 받을 수 있습니다.

    (부가적으로 이런 개발 방식을 옵저버 패턴이라고 합니다.^^)



    위 스크린샷은 

    1) 시작(폼생성) 시 TMessageMenager에 TOrientationChageMessage에 대해 OrientationChaged 이벤트를 구독하고

    2) 종료 시 : 구독을 해지합니다.

    3) 현재 스크린 방향은 IFMXScreenService.GetScreenOrientation 메소드를 통해 알아 올 수 있습니다.


    자세한 내용은 아래 샘플코드를 통해 확인하세요.

    델파이 10.1 베를린 버전으로 작성되었습니다.

    ScreenOrientation-Berlin.zip




    해당 내용은 델파이 부트캠프 - 델파이 게임 개발 소스코드를 살펴보다 발견했습니다.

    델파이 부트캠프: 게임 개발 - http://community.embarcadero.com/blogs?view=entry&id=8785

    델파이 게임개발 소스코드(Github) : https://github.com/EmbarcaderoPublic/DelphiArcadeGames

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

    Object Pascal Style Guide

    2016.09.21 13:30

    여러명이 협업하는 프로젝트에서는 표준화가 매우 중요합니다.

    코딩 스타일 표준화에 참고할 수 있는 Object Pascal 스타일 가이드문서입니다.


    영문(원문): 

    http://edn.embarcadero.com/article/10280


    한글번역 문서:

    http://documents.mx/documents/object-pascal-style-guide-kor.html



    델마당의 김시준님글과 깨몽(이선우)님의 글을 참고했습니다.

    http://www.delmadang.com/community/bbs_view.asp?bbsNo=3&bbsCat=0&indx=451050&page=1

    험프리.김현수 RAD Studio 정보

    TListView Dynamic Appearance로 추가한 항목을 코드로 제어하기

    2016.09.20 15:16

    (해당 기능은 RAD 스튜디오 10.1 베를린 이상에서 사용할 수 있습니다.)


    TListView는 이미 정의된 ItemAppreance를 이용해 목록을 구성하기 때문에 TListBox에 비해 스크롤이 부드럽고 빠릅니다.


    하지만, 베를린 버전에서 Dynamic appreance 기능이 추가되어 아래 그림과 같이 아이템 항목을 마음대로 정의할 수 있습니다.



    Dynamic Appreance에 대한 자세한 내용은 아래 링크를 참고하세요.

    오늘 소개할 내용은 위와 같이 사용자가 추가한 항목을 코드를 통해 제어하는 예제입니다.


    아래 코드는 ListView1에서 Text2 아이템을 찾아 글자색을 녹색으로, 글자 스타일을 Bold, Italic으로 설정합니다.

    procedure TForm2.Button3Click(Sender: TObject);
      function GetTextItem2: TCustomTextObjectAppearance;
      var
        Obj: TCommonObjectAppearance;
      begin
        Result := nil;
        for Obj in ListView1.ItemAppearanceObjects.ItemObjects.Objects do
        begin
          if not (Obj is TCustomTextObjectAppearance) then
            Continue;
    
          if Obj.Name = 'Text2' then
          begin
            Result := Obj as TCustomTextObjectAppearance;
            Break;
          end;
        end;
      end;
    var
      Text2: TCustomTextObjectAppearance;
    begin
      // Text2 항목 찾기
      Text2 := GetTextItem2;
    
      if not Assigned(Text2) then
        Exit;
    
      Text2.TextColor := TAlphaColorRec.Green;
      Text2.Font.Style := [TFontStyle.fsBold, TFontStyle.fsItalic];
    //  Text2.re
    end;


    아래 코드는 ListView의 크기가 변경된 경우(TListView.OnResize) 내부 항목들의 위치와 너비를 일괄조정하는 샘플입니다.

    procedure TForm2.ListView1Resize(Sender: TObject);
    var
      L, R, W, Ratio: Single;
      Obj: TCommonObjectAppearance;
    begin
      W := ListView1.Width - ListView1.ItemSpaces.Left - ListView1.ItemSpaces.Right;
      L := W;
      R := 0;
    
      for Obj in ListView1.ItemAppearanceObjects.ItemObjects.Objects do
      begin
        // 가장 왼쪽의 이미지 제외
        if Obj is TCustomImageObjectAppearance then
          Continue;
    
        // 가장 왼쪽 위치
        if Obj.PlaceOffset.X < L then
          L := Obj.PlaceOffset.X;
        // 가장 오른쪽 위치
        if (Obj.PlaceOffset.X + Obj.Width) > R then
          R := Obj.PlaceOffset.X + Obj.Width;
      end;
    
      Ratio := (W-L) / (R-L); // (변경된 너비 / 원래너비)
      for Obj in ListView1.ItemAppearanceObjects.ItemObjects.Objects do
      begin
    //    if Obj.PlaceOffset.X < L then
        if Obj is TCustomImageObjectAppearance then
          Continue;
    
        Obj.PlaceOffset.X := ((Obj.PlaceOffset.X - L)  * Ratio) + L;
        Obj.Width := Obj.Width * Ratio;
      end;
    end;


    샘플 프로젝트

    ListViewDynamicAppearance.zip


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

    1. Blog Icon
      채종일

      안녕하세요. 해당 기능을 사용하려고 하는데

      라이브 바인딩이 아니라 직접 소스코드로 항목을 추가하려면 어떻게 해야할까요??

    리눅스(우분투) 설치

    2016.08.31 13:36

    델파이와 C++빌더가 리눅스 서버를 지원하는 등의 로드맵이 2016년 8월 공개되었습니다.

    그래서, 가상머신(VMWare)에 리눅스를 설치해봤습니다. 그것도 최근 핫한 우분투로...



    설치 과정은 상당히 간단했구요. 한글설정 관련해 몇가지 이슈가 있었지만 인터넷을 찾아 금방 해결했습니다.

    관련 링크 몇가지 공유합니다.


    PS - 델파이 제품관리자 Marco Cantu가 리눅스 25주년 기념으로 델파이로 리눅스 컴파일한 이미지 몇장을 올려놨네요.


    리눅스도 OSX과 마찮가지로 PAServer를 이용하고, IDE에서 F9를 이용해 빌드 및 컴파일 할 수 있을 것으로 예상합니다.

    리눅스도 준비되었으니 빨리 델파이로 리눅스 서버를 만들 수 있는 날이 기다려지네요^^


    참고링크




    험프리.김현수 기타정보

    1. Blog Icon
      개발기능 여쭤봅니다.

      안녕하세요 저가 델파이 iOS와 안드로이드 앱을 개발하는 책을샀는데 이책으로 메신저앱도 개발할수 있나요? 무료통화 화상채팅 무료메시지 그런 기능도 개발할수 있나요??

    TWICImage를 이용해 다양한 이미지 포맷의 파일을 불러오고 저장하기.

    2016.08.31 10:23


    TWICImage는 Microsoft Windows Imaging Component를 캡슐화 한 클래스로 다양한 이미지 포맷을 조작할 수 있습니다.


    사용법은 아래 샘플코드와 같이 TImage 컨트롤에서 파일을 로드하기 전에 TWICImage로 먼저 로드한 후 TImage에 할당하면 다양한 이미지 포맷을 TWICImage가 처리해 줍니다.

    (TWICImage는 RAD Studio 2010 부터 지원합니다.)


    procedure TForm2.btnImageLoadClick(Sender: TObject);
    var
      wic: TWICImage;
    begin
      if OpenDialog1.Execute then
      begin
        wic := TWICImage.Create;
        try
          wic.LoadFromFile(OpenDialog1.FileName);
          Image1.Picture.Assign(wic);
        finally
          wic.Free;
        end;
      end;
    end;
    
    procedure TForm2.btnImageSaveClick(Sender: TObject);
    var
      wic: TWICImage;
      filter: string;
      filename: string;
    begin
      wic := TWICImage.Create;
      try
        wic.Assign(Image1.Picture);
    
        case wic.ImageFormat of
        wifBmp:
          begin
            filter := '비트맵(*.bmp)|*.bmp';
            Filename := 'image.bmp';
          end;
        wifPng:
          begin
            filter := 'PNG(*.png)|*.png';
            Filename := 'image.png';
          end;
        wifJpeg:
          begin
            filter := 'JPEG(*.jpg)|*.jpg';
            Filename := 'image.jpg';
          end;
        wifGif:
          begin
            filter := 'GIF(*.gif)|*.gif';
            Filename := 'image.gif';
          end;
        else
          begin
            ShowMessage('지원하지 않는 이미지 포맷입니다');
            Exit;
          end;
        end;
    
        SaveDialog1.FileName := filename;
        SaveDialog1.Filter := filter;
        if SaveDialog1.Execute then
        begin
          wic.SaveToFile(SaveDialog1.FileName);
        end;
      finally
        wic.Free;
      end;
    end;

    다운로드

    WICImageSample.zip


    문단제목



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

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

    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

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

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


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


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




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