Delphi Programming Forum
C++Builder  |  Delphi  |  FireMonkey  |  C/C++  |  Free Pascal  |  Firebird
볼랜드포럼 BorlandForum
 경고! 게시물 작성자의 사전 허락없는 메일주소 추출행위 절대 금지
델파이 포럼
Q & A
FAQ
팁&트릭
강좌/문서
자료실
컴포넌트/라이브러리
FreePascal/Lazarus
볼랜드포럼 홈
헤드라인 뉴스
IT 뉴스
공지사항
자유게시판
해피 브레이크
공동 프로젝트
구인/구직
회원 장터
건의사항
운영진 게시판
회원 메뉴
북마크
델마당
볼랜드포럼 광고 모집

델파이 Q&A
Delphi Programming Q&A
[9864] Re: 자답 입니다.
박진수 [jeensoo] 1241 읽음    2004-09-21 16:40
내용은 Tip'N Tricks 란에 올려 놓았습니다.

박진수 님이 쓰신 글 :
: 퀵레포트4.03에 대해 문의 합니다.
:
: 퀵레포트 4에서는 새롭게 추가된 사항이
: preview 에서 text search 기능이 추가 되었습니다.
:
: 그런데 문제는 한글 search가 되지 않더군요.
:
: 그래서 관련 소스인 qrprev.pas, qrextra.pas qrprntr.pas를 보니
:
: 결국 퀵레포트도 메타파일을 받아서 다시 이 메타파일에서
: 메타레코드를 추출해  이것의 type을 분석해 문자열을 추출한후
:
: 이 추출한 문자열을 가지고 찾을 문자열과 비교하고 있다는 것을 알게 되었습니다.
:
: 그래서 해당소스를 보니 EnumEnhMetafile 이라는 win32 api와 이것의 콜백함수를 가지고
: 처리를 하고 있던 터라 이 콜백함수부분에서 문자열 추출이 완료되는 시점에서
: 문자열추출이 완료된 직후 break 나 showmessage를 걸어 해당 값을 화면으로 보면
: 한글은 모두 깨져서 출력이 됩니다.
:
: 그래서 델파이 6버전 부터 UTF8과 관련한 CHARATER SET CONVERT 처리 함수가 추가되어 있어서
: 제가 찾고자 하는 문자열을 직접 UTF8로 바꾸어 화면으로 본 결과 콜백함수부분에서 문자열 추출이
: 완료되는 시점에서 문자열추출이 완료된 직후의 값과 틀린 값이 나왔습니다.
:
: 메타파일에서 문자열이 어떠한 규칙으로 처리되는 지 아시는 분이 있으신지요..
: 아래는 QUICK REPORT 4.03에서 SEARTCH 부분을 처리하는 부분들을 추출한 자료입니다.
:
: ---------------------------------
:
:
: qrprev unit에서
:
: procedure TQRStandardPreview.FindButtonClick(Sender: TObject);
: var
:   FindStr : string;
:   MatchCase : boolean;
:   I : integer;
:   APage : TMetafile;
:   Dummy : TList;
: begin
:   if GetTextSearch(MatchCase, FindStr) then
:   begin
:     SearchResultBox.Enabled := true;
:     SearchTextLabel.Caption := FindStr;
:     SearchResultBox.Items.Clear;
:     for I := 1 to QRPrinter.PageCount do
:     begin                                     
:        APage := QRPrinter.GetPage(I);
:        try
:          if StrInMetafile(FindStr, APage, MatchCase) then
:             SearchResultBox.Items.Add('Page ' + IntToStr(I));
:        finally
:          APage.Free;
:        end;
:     end;
:     if SearchResultBox.Items.Count = 0 then
:     begin
:       SearchResultBox.Items.Add('일치하는 결과가 없습니다.');
:       SearchResultBox.Enabled := false;
:     end;
:   end;
: end;
:
:
: -----------------------------------------------------
:
: qrextra unit에서
:
:
: type
:   MFBar = array of Char;
: var
:   MFSearchStr : string;
:   MFFound : boolean;
:   MFMatchCase : boolean;
:   MFSearchBusy : boolean;
:
:
:
: function MetaEnum(DC : THandle; HandleTable : pointer; MetaRec : Pointer; Count : word; dummy : pointer) : shortint stdcall;
: var
:   aStr : string;
:   Ofs : integer;
:   Len : integer;
:   I : integer;
: begin
:   aStr := '';
:   with tagENHMETARECORD(MetaRec^) do
:   begin
:     case iType of
:       EMR_EXTTEXTOUTW,
:       EMR_EXTTEXTOUTA : begin
:                           aStr := '';
:                           Ofs := (tagEMREXTTEXTOUTA(Metarec^).EMRText.offString);
:                           Len := (tagEMREXTTEXTOUTA(Metarec^).EMRText.nChars);
:                           SetLength(aStr, Len);
:                           for I := 0 to len - 1 do
:                         //    aStr[I+1] := char(MFBar(MetaRec^)[ofs + (I*2)]);
:                             aStr[I+1] := MFBar(MetaRec)[ofs + (I*2)];
:                           Showmessage(aStr);
:                         end;
:     end;
:   end;
:   if not MFMatchCase then aStr := AnsiUppercase(AStr);
:   if Pos(MFSearchStr, aStr) > 0 then
:   begin
:     Result := 0;
:     MFFound := true;
:   end else
:     Result := 1;
: end;
:
: function StrInMetafile(AString : string; AMetafile : TMetafile; MatchCase : boolean) : boolean;
: begin
:   while MFSearchBusy do Application.ProcessMessages;
:   MFSearchBusy := true;
:   if MatchCase then
:     MFSearchStr := AString
:   else
:     MFSearchStr := AnsiUppercase(AString);
:   MFFound := false;
:   MFMatchCase := MatchCase;
:   EnumEnhMetafile(0, AMetafile.handle, @MetaEnum, nil, rect(0,0,0,0));
:   Result := MFFound;
:   MFSearchBusy := false;
: end;
:
:
: ----------------------------------------------
:
:
: qrprntr unit에서
:
:
: type
:   bar = array of Char;
: var
:   MFSearchStr : string;
:   MFFound : boolean;
:   MFMatchCase : boolean;           
:
: function MetaEnum(DC : THandle; HandleTable : pointer; MetaRec : Pointer; Count : word; dummy : pointer) : shortint stdcall;
: var
:   aStr : string;
:   Ofs : integer;
:   Len : integer;
:   I : integer;
: begin
:   with tagENHMETARECORD(MetaRec^) do
:   begin
:     case iType of
:       EMR_EXTTEXTOUTW,
:       EMR_EXTTEXTOUTA : begin
:                           aStr := '';
:                           Ofs := (tagEMREXTTEXTOUTA(Metarec^).EMRText.offString);
:                           Len := (tagEMREXTTEXTOUTA(Metarec^).EMRText.nChars);
:                           SetLength(aStr, Len);
:                           for I := 0 to len - 1 do
:                             aStr[I+1] := char(bar(MetaRec^)[ofs + (I*2)]);
:                         end;
:     end;
:   end;
:   if not MFMatchCase then aStr := AnsiUppercase(AStr);
:   if Pos(MFSearchStr, aStr) > 0 then
:   begin
:     Result := 0;
:     MFFound := true;
:   end else
:     Result := 1;
: end;
:
: function StrInMetafile(AString : string; AMetafile : TMetafile; MatchCase : boolean) : boolean;
: begin
:   if MatchCase then
:     MFSearchStr := AString
:   else
:     MFSearchStr := AnsiUppercase(AString);
:   MFFound := false;
:   MFMatchCase := MatchCase;
:   EnumEnhMetafile(0, AMetafile.handle, @MetaEnum, nil, rect(0,0,0,0));
:   Result := MFFound;
: end;
:
:
: -----------------------------------------------------------------------
:
:
: 기타 windows 유닛에서
:
:   PEnhMetaRecord = ^TEnhMetaRecord;
:   {$EXTERNALSYM tagENHMETARECORD}
:   tagENHMETARECORD = packed record
:     iType: DWORD; { Record type EMR_XXX}
:     nSize: DWORD; { Record size in bytes}
:     dParm: array[0..0] of DWORD; { Parameters}
:   end;
:   TEnhMetaRecord = tagENHMETARECORD;
:   {$EXTERNALSYM ENHMETARECORD}
:   ENHMETARECORD = tagENHMETARECORD;
:
:
:
:
:   {$EXTERNALSYM EMR_EXTTEXTOUTA}
:   EMR_EXTTEXTOUTA = 83;
:   {$EXTERNALSYM EMR_EXTTEXTOUTW}
:   EMR_EXTTEXTOUTW = 84;
:
:
:
:
:   {$EXTERNALSYM tagEMREXTTEXTOUTA}
:   tagEMREXTTEXTOUTA = packed record
:     emr: TEMR;
:     rclBounds: TRect;     { Inclusive-inclusive bounds in device units}
:     iGraphicsMode: DWORD; { Current graphics mode}
:     exScale: Single;       { X and Y scales from Page units to .01mm units}
:     eyScale: Single;       {   if graphics mode is GM_COMPATIBLE.}
:     emrtext: TEMRText;    { This is followed by the string and spacing array}
:   end;
:   TEMRExtTextOut = tagEMREXTTEXTOUTA;
:   {$EXTERNALSYM EMREXTTEXTOUTA}
:   EMREXTTEXTOUTA = tagEMREXTTEXTOUTA;
:
:
:
:
:
:   { Base text record type for the enhanced metafile.}
:   PEMRText = ^TEMRText;
:   {$EXTERNALSYM tagEMRTEXT}
:   tagEMRTEXT = packed record
:     ptlReference: TPoint;
:     nChars: DWORD;
:     offString: DWORD; { Offset to the string}
:     fOptions: DWORD;
:     rcl: TRect;
:     offDx: DWORD;     { Offset to the inter-character spacing array.}
:                       { This is always given.}
:   end;
:   TEMRText = tagEMRTEXT;
:   {$EXTERNALSYM EMRTEXT}
:   EMRTEXT = tagEMRTEXT;
:
:
:
:
:
:   {$EXTERNALSYM tagEMR}
:   tagEMR = packed record
:     iType: DWORD; { Enhanced metafile record type}
:     nSize: DWORD; { Length of the record in bytes.}
:                   { This must be a multiple of 4.}
:   end;
:   TEMR = tagEMR;
:   {$EXTERNALSYM EMR}
:   EMR = tagEMR;

+ -

관련 글 리스트
9860 퀵레포트4.03에 대해 문의 합니다. 박진수 1112 2004/09/16
9864     Re: 자답 입니다. 박진수 1241 2004/09/21
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.