2013년 6월 24일 월요일

WebBroker 에서 JavaScript 사용

웹브로커에서 자자 스크립트를 사용 할때   아래와 같은 방법으로 하면 됩니다.

procedure TWebModule1.WebModule1DefaultHandlerAction(Sender: TObject;
  Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
var iStr: string;
begin
  // Response.Content := HTPpEncode( '<input type="button" onClick="alert(''Hello World'')" Value="Hello World"/>');
  iStr:= '<input type="button" onClick="alert('+ QuotedStr('Hello World')+')" Value="Hello World"/>';
  response.content := HTMLEncode( iStr ) + '<br>' + iStr;
end;

HtmlEncode 는 HTML 형식을 문장으로 그래도 보여 줍니다.

ftp://po.istu.ru/public/docs/other/_New/Books/Lang/Delphi/Delphi%20Developer's%20Guide/Ebooks/d6dg/chapter23.pdf

2013년 6월 23일 일요일

WebSnap 을 이용하여 모바일 홈페이지 만들기 2

모바일 웹에서 가장 많이 사용되는 것이 ListView 일 것입니다.

이것을 구현하기 위하여 역시 Web.WbWeb 유니트를 약간 수정 하도록 합니다.
 DataSetTableProducer1.tag 를 이용하여 tag 가 99 이면 Table 처리를 하고 아니면 
LiveCiew 처리를 하면 되지 않나 생각합니다.
procedure TWebModule2.DataSetTableProducer1FormatCell 에서 
  if CellColumn = DataSetTableProducer1.tag then
    CellData:= '<a href="#">'+CellData+'</a>';

으로 처리 하게끔하고 
Web.DBWeb 에서 

function TDataSetTableProducer.HtmlTable(DataSet: TDataSet; DataSetHandler: TDSTableProducer; MaxRows: Integer): string;
var
  I, J: Integer;
  DisplayText, RowHeaderStr: string;
  Field: TField;
  Column: THTMLTableColumn;
begin
  if DataSet.State = dsBrowse then begin
    J := 1;
    while (MaxRows <> 0) and not DataSet.EOF do begin
      // Result := Result + RowHeaderStr;
      if SameText(Caption,'table') then begin
        for I := 0 to DataSetHandler.Columns.Count - 1 do begin
          Column := DataSetHandler.Columns[I];
          Field := Column.Field;
          if Field <> nil then
            DisplayText := Field.DisplayText
          else DisplayText := '';
          with Column do
            Result := Result + DataSetHandler.FormatCell(J, I, DisplayText, 'TD', BgColor, Align, VAlign, Custom);
        end;
      end else begin
        if i <  DataSetHandler.Columns.Count then I := Tag
        else I:= 0;
        Column := DataSetHandler.Columns[I];
        Field := Column.Field;
        if Field <> nil then
          DisplayText := Field.DisplayText
        else DisplayText := '';
        with Column do
          Result := Result + DataSetHandler.FormatCell(J, I, DisplayText, 'li',  BgColor, Align, VAlign, Custom);
      end;
      Result := Result + EndRow + #13#10;
      DataSet.Next;
      Dec(MaxRows);
      Inc(J);
    end;
end;

당연히 헤더 부분도 수정 하여야 겠지요.
<div data-role="page">
<div data-role="header"><h1>Page Title</h1></div><!-- /header -->
<div data-role="content">
<ul data-role="listview" data-inset="true">

footer 부분도
</ul>
로 수정하여 주면 Caption 에다 Table/Ul 구분하여 넣어 주고 UL 이면 어떠한 컬럼으로 할것이지 지정하면 됩니다. 그렇지 않고 한 컬럼 만 있어도 되겠지요.

WebSnap 을 이용하여 모바일 홈페이지 만들기

현재 WebSnap을 이용하여 모방일 웹을 만들고 있습니다.
모바일 웹은 특성한 간결함이 기본이기에 WebSnap 만으로 충분하지 않아 생각되어 진행하고 있습니다.
당연이 JQueryMobile 을 이용하고 있습니다.

코딩을 줄이기 위하여 PageProcedure , DataSetTableProcedure 을 사용하는데 몇가지 마음에 맞지 않는 부분이 있어 Web.DbWeb.수정하였습니다.
수정을 위하여
1. Web Server Application을 새로운 르로젝트로 만듭니다. (Stand-alone)
2. 새로운 폴더에 생성된 모든 파일을 저장합니다. (프로젝트 저장)
3. ClientDataSet 과 DataSource 컴포넌트를 올려 놓습니다.
4. ClientDataset.FileName 에 biolife.xml 을 지정합니다.
5. DataSetTableProducer 를 폼에 올령 놓습니다.
6. 컨트로 F9 하여 빌드 하고 Code 최 상단에 보면 Web.DBWeb 유니트가 Uses 되어 있습니다.
7. 컨트롤 키를 누르고 DBWeb 단어를 크릭하면 해당 유니트를 불러옵니다.
8. [File > Save AS.. 하여 새로 만든 프로젝트 폴더에 저장합니다. !주의, !주의 폴더 확인
9. Class Helper를 이용하려고 했는데  function HtmlTabled 를 유니트 함수로 만들어 놓아서 별 수 없이 원본을 수정하게 되었습니다. 설마하니 이것을 계승한 녀석은 없겠지요.
있다하더라도 내 프로젝트에서만 수정하여 사용하니 별 문제 없을 것입니다.
10. 필요하면  function HtmlTabled 를
  TDataSetTableProducer = class(TDSTableProducer)
  ....................
     function HtmlTable(DataSet: TDataSet; DataSetHandler: TDSTableProducer; overrride; MaxRows: Integer): string;
  ....................
  하여 클래스 안에 집어 넣어 버리세요. 원본을 그렇게 하여도 될 것 같아요..
11. HtmlTable 마지막행에  < /Table> 앞에 < / TBody >를 추가합니다.
  Result := Result + '</Body></Table>';  { do not localize }
12. 아래 부분을 코멘트 처리합니다.
  {
  RowHeaderStr := DataSetHandler.RowHeader;
  Result := DataSetHandler.TableHeader + DataSetHandler.TableCaption + #13#10 +
    RowHeaderStr;
  Result := Result + DataSetHandler.ColumnHeader + EndRow + #13#10;
  }
  .....
   // Result := Result + RowHeaderStr;
  즉 테이블의 컬럼 해드를 외부에서 지정하겠다는 의미입니다.
13. DataSetTableProducer.Header 에 아래와 같이 수정합니다.
<body><div data-role="page">
<div data-role="header"><h1>Page Title</h1></div><!-- /header -->
<div data-role="content">
<TABLE id="FishList" class="ui-responsive table-stroke" data-role="table" data-mode="reflow"><THEAD><TR> 
<TH data-priority="1">Species No</TH><TH data-priority="2">Category</TH>
<TH data-priority="3">Common Name</TH> <TH data-priority="4">Species Name</TH>
<TH data-priority="5">Length (cm)</TH></TR></THEAD> <TBODY> 
필요하면 Page Title과 기타를 수정합니다
14. Footer 도 수정합니다.
</TBody></Table>
15. 앵커 처리를 합니다.
procedure TWebModule1.DataSetTableProducer1FormatCell(Sender: TObject; CellRow, CellColumn: Integer; var BgColor: THTMLBgColor;
  var Align: THTMLAlign; var VAlign: THTMLVAlign; var CustomAttrs, CellData: string);
begin
  if CellColumn = 0 then
    CellData:= '<a href="#" data-rel="external">'+CellData+'</a>';
end;
16. Pagrproducer를 하나를 폼에 올려 놓고 ppHeader로 이름 짓고
<!DOCTYPE html><html><head>
<title>Page Title</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.3.1/jquery.mobile-1.3.1.min.css" />
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script src="http://code.jquery.com/mobile/1.3.1/jquery.mobile-1.3.1.min.js"></script>
</head>
17. Pagrproducer를 하나를 폼에 올려 놓고 ppHeader로 이름 짓고
<div data-role="footer"><h4>Page Footer</h4></div><!-- /footer -->
</div><!-- /page --></body></html>

18. 최종 액션 부분을 수정합니다.
procedure TWebModule1.WebModule1DefaultHandlerAction(Sender: TObject;
  Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
begin
  ClientDataSet1.Open;
  Response.Content := ppHeader.Content+ DataSetTableProducer1.Content
     + ppFooter.Content;
  ClientDataSet1.Close;

16. 아마 uses 절에 Web.HTTPProd 을 넣어 주어야 할 것입니다.

2013년 6월 21일 금요일

MySql 사용시..

  MySql 을 사용하면서..
재설치 할때 갑자기 이전 암호가 보이는 경우가 있다.
분명히 MySql 폴더를 전부 삭제 했는데도 이러한 현상이 보이는 것은
윈도우 상위버전에서는 데이터를 Application Data 영역에다 저장하기 때문입니다.

c:₩users₩all users₩mysql₩mysql server 5.1₩data
폴더를 확인해 보세요.

방화벽 때문에 3306 포트를 사용할 수 없으면 원격 접속이 안됩니다.
그러나 해당 서버에 웹서버가 있으면 http tunneling (터널링) 방법이 있는데
dll 과 php 를 사용하는 방법이 있습니다.

DeVart 의 mysql 컴포넌트(MyDac)를 사용하면 됩니다.
먼저 해당 서버의 적당한 위치에 MyDac가 설치된 폴더의 http 폴더에 있는 tunnel.php 라는 파일을 복사 시킵니다.

MyConnection.url:= http://server/tunnel.php
MyConnection.Options['protocal']:= mpHttp;
로 하면 된다고 하는데 실제 해보니 연결이 안되네요. 좀, 삽질좀 해야겠습니다.

2013년 6월 20일 목요일

Delphi WebBroker 등에서 utf-8 처리 (Get,Post)

델파이에서 웹브로커를 이용하여 모바일용 웹을 만들고 있는데 JQueryMobile 을 하용하면 쉽고 멋있게 만들 수 있습니다. 비교적 깔끔한 형태이기에 웹브로커로 만들어도 좋을 듯 합니다.

작업을 하면서 몇가지 정리하고 넘어가야 할 사안이 있어 정리합니다.

우선 화면상에 한글을 정상적으로 표현하기 위하여는

PageProdecer에 html을 불러올 경우에는 utf-8 형식으로 저장하여야 합니다.(XE2 기준)

또한 아래와 같이 Response.ContentType 을 지정하여야 합니다.

procedure TWebModule1.WebModule1DefaultHandlerAction(Sender: TObject;
Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
begin
Response.ContentType:= 'text/html; charset=utf-8';
Response.Content := PageProducer1.Content;
end;

Form 에서 데이터를 Query 하는 방법에는 Post 와 Get 이 있는데
Get은 Url 상에 Query 내용이 보이는 것이고,
( http://localhost:8080/test?param=%ED%95%9C%EA%B8%80&hidden=hidden+%EB%AC%B8%EC%9E%90&submit=UTF-8+%ED%95%9C%EA%B8%80+%EC%9D%B4%EC%A0%95%EA%B7%80 )

Post는 Url 상에 Query 내용이 보이지 않는다는 점을 제외하고는 큰 의미는 없습니다.
( http://localhost:8080/test )
단, Get은 Get 이고 Post는 Post입니다. 가져오고, 뭔가를 보내고의 의미차이겠지요.

Query 를 읽어오는 방법에는
Request.ContentFields.Values['name'] 과
Request.QueryFields.Values['hidden'] 방법이 있는데,
Help 상에는 ContentFiels 는 mtPost에서 사용하는 것 처럼 되어 있고
QueryFields.Values 은 Hidden 필드를 읽어오는 것 처럼 되어 있어 이게 mtGet에서 작동되는 것처럼 곡해되고 있는 것 같습니다.

Request.ContentFields.Values['name'] 으로 모두 읽어 올 수 있습니다.

그리고 가장 중요한 것은!!!!!!!!!!!!!!
이렇게 읽어온 UTF-8 문자가 일부 깨어진다는 점입니다.

이것을 해결하기위하여 거의 하루를 삽집하였습니다.

결론은 항상그러하듯이 너무 허망하네요..

Progect에 아래와 같이   utf8ContentParser 를 포함만 시켜주면 됩니다.

program Project2;
{$APPTYPE GUI}

uses
  Vcl.Forms,
  Web.WebReq,
  IdHTTPWebBrokerBridge,
  utf8ContentParser,
  FormUnit1 in 'FormUnit1.pas' {Form1},
  WebModuleUnit1 in 'WebModuleUnit1.pas' {WebModule1: TWebModule};


이렇게 할경우 Get 에서는 Hidden 필드의 한글이 깨어 지네요.
역시나 Hidden 필드는 QueryFields.Values['hidden']으로 읽어와야 깨어지지 않습니다.

2013년 6월 5일 수요일

아이패드에서 윈도우 95 설치하고 델파이 2.0 사용하기(3)

IPAD 에서 Windows95 를 샐행 시키기 위히여는 부팅이 가능한 img 파일이 있어야합니다.
이를 위하여는
1. 데스크탑에 DOSBOX를 설치하고
* IMG 파일을 생성하기 위하여는 DOSBOX SVN 버전을 설치하여야 합니다.(다음 카페)
2. IMG 파일을 생성한 다음
3. 이미지 파일을 FDISK 로 파트션을 만들고 포맷합니다.
4. 이미지 파일에 SYS 명령을 이용하여 부트로더와 io.sys msdos.sys 파일을 복사한다.
5. 이미지 파일에 윈도우 95를 설치용 파일을 복사 합니다.
6. 설치된 윈도우 이미지 파일에 델파이 설치 프로그램도 복사합니다. (1.0 과 2.0 같이)
7. 이미지 파일(Lee520g.img)을 마운트하고 부팅합니다.
8. 윈도우95를 설치합니다.
9. DOSBOX를 종료하고 다시 시작하여 Lee510g.img 를 마운트 하고 부팅합니다.
10. 윈도우95 기본 화면이 나타납니다.
11.(중요) 시작 > 실행 하여 SYSEDIT 하여 SYSTEM.INI 파일을 수정합니다.
[boot]
.........
shell=ProgMan.exe
..........
12. 윈도우 95를 종료합니다.
13. IPAD를 데스크탑에 연결하고 iFUNbox 프로그램을 이용하여 iDOS의 Documents 폴더에 Lee520g.lee 파일을 복사합니다.
14. IPAD 에서 iDOS앱을 실행합니다.
15. dospad.cfg를 수정합니다. [CPU 속도 이미지 오른쪽의 아이콘 터치]
[cpu]
.............
core= normal ; simple 도 가능
cycles= 6000  ;정도 max 도 가능
cputype = 386  ;정도로 바꾸어 보심도...
.............
15: c:\ 아이콘을 터치하여 DOS 모드로 진입합니다.
16. dir 하여 lee520g.img 파일을 확인합니다.
17. imgmount d lee520g.img 하여 d 드라이버로 마운트 합니다.
18. boot lee520g.img 하여 이미지로 부팅합니다.
19. 윈도우 95가 실행되고 TaskMan 이 셀로서 실행되어 있음을 확인 할수 있습니니다.

* shell 로서 ProgMan을 사용하는 것은 explorer.exe 가 워낙 버겁고, 에러가 자주 발생되기 때문입니다. explorer 은 데스크탑에서도 상당히 골치 아픈 프로그램 이었습니다.

20. ProgMan 에 winfile을 등록합니다.
21. 델파이 1.0 폴더로 이동하여 setup.exe 를 샐행하여 Delphi 1.0을 설치합니다.
22. 델파이 2.0 폴더로 이동하여 setup.exe 를 실행하여 Delphi 2.0을 설치합니다.
- 2.0을 설치하면 ***32.exe 에서 에러가 나서 설치 할 수 없습니다. 라는 메세지가 보입니다.
- 인스톨실드가 iDOS에 없는 루틴을 실행하려는 것 같습니다.
- 걱정하지 마십시요. 프로그램은 정상적으로 복사되어 설치되어 있으니
- ProgMan을 이용하여 등록하면 됩니다.

* 참고로 제가 iPAD 에서 iDOS 환경을 통해서라도 window 환경에서 Delphi 를 설치하려는 것은 그동안에 익힌 프로그램 기술을 활용하여 나만의 프로그램을 iPAD에서 구현해 보려고 하는 것입니다.
* 덕분에 간단한 자기학습용(암기 도우미) 프로그램을 델파이로 간단하게 만들어서 공부 한 결과 59이라는 많은 나이에도 불구하고 소방설비기사(전기) 자격증을 획득하게 되었습니다.
* 소방설비기사(기계) 1차를 합격하고 2차를 준비하면서도 암기 도우미를 활용하여 공부 할려고 합니다.

아이패드에서 윈도우 95 설치하고 델파이 2.0 사용하기(2)

IDOS에서 윈도우95 환경에서 델파이 2.0을 실행 한 이미지 입니다.

IDOS에서 IPAD를 행으로 놓고 시작 LEE520G.IMG 확인
LEE520G.IMG 로 mountting, booting
windos95 가 실행 되고 있는 모습
Shell 프로그램을 Explorer가 아니고 TaskMan으로 바꿈
Delphi 2.0 에서 컴파일 하여 디버깅모드로 실행중

아이패드에서 윈도우 95 설치하고 델파이 2.0 사용하기(1)

아이패드에 IDOS 앱이 올라온이후 예전 도스용 프로그램을 아이패드에서 실행해 볼 수 있습니다. 저는 아이패드2에서 윈도우 95와 윈도우 98을 실행해 보았는데 윈도우98은 실행에 문제가 많더군요.

우선 기본적인 지식이 있어야 할 것 같습니다.
IDOS 앱에 대하여 알아야 합니다.
이앱은 윈도우또는 다른 OS(예를들어 Linux)에서 예전 도스용 게임을 실행 시킬 목적으로 개발된 DOSBOX의 소스(소스는 공개되어 있습니다)를 이용하여 IPAD, IPHONE 등에서 돌아가도록 컴파일 하여 올려 놓은것 같습니다.

DosBox는 우리나라 다음카페에서 관련 정보와 자료를 얻을 수 있습니다.

윈도우에 대해서도 알아야 겠네요.
윈도우3.1은 도스 프로그램이며 GUI만 윈도우라도 보면 됩니다.
DOS나 윈도우 3.1은 16비트용 프로그램입니다. 기본적으로 80286 이상의 CPU 에서 돌아가지요.
델파이 1.0은 16비트용 터보파스칼 컴파일러를 사용하여 16비트용 실행 프로그램을 만들어 냅니다. 해서 도스상태에서 윈도우 3.1을 실행시켜 윈도우 3.1의 WinAPI를 이용하여 실행프로그램을 실행합니다.

CPU 기술이 발달되어 80386이 나오면서 32비트 처리가 가능하여 윈도우95가 탄생하였으며 OS로서의 자리 매김을 하게 되었습니다. 그러나 윈도우 95는 16비트와 32비트 과도기에 만들어진 OS라서 16비트 프로그램과 32 비트 프로그램의 호완성을 갖게하였습니다. 시장에 맞추었다고 보면 되겠네요.

윈도우 95부터는 부팅자체를 윈도우로만 하게 기본으로 하였습니다. 만, MSDOS를 먼저 실행 시키고 윈도우 95를 실행 시켜도됩니다.

이방법을 이용하면 IDOS에서 MSDOS를 샐행하고 이미 설치된 윈도우95를 실행 해도 되어야 하는데 몇가지 시도를 해보았지만 실패하였습니다.
IDOS에 깔려 있는 DOS가 MSDSO와 호환되지 않아서죠. 윈3.1과는 호환되는데요...

윈도우 95를 설치하기 위하여는 인스톨 과정을 거쳐 하드디스크를 FAT-16(?)으로 포멧하고 부트로더 즉 IO.SYS를 하드에 깔아 이 IO.SYS를 이용하여 부팅하게 합니다. IDOS 에서 윈95를 실행하지 못하는 원인도 이것 때문 인것 같습니다.

IDOS 상태에서만으로 윈도우 95를 설치 할 수는 없는 이유이지요.(IDSO가 win95 호환의 IO.SYS를 지원하기되면...)

DOSBOS 나 IDOS에는 mount, imgmount, boot 라는 개념이 있습니다.
윈도우시스템에 있는 특정 폴더나 이미지파일을 하드디스크로 에뮬레이트하여 DOSBOX 나 IDOS에서 새로룬 하드디스크로 인지하게 할수 있으며, mount 된 가상 하드디스크로 부팅을 할 수 있다는 것입니다.

너무 길어져서 다음에 계속 할께요..

델파이 12.1이냐 11.3이냐?

 델파이가 12.1이 나왔습니다. 혹시 11.3버전의 커뮤니티버전이 필요하시는분이 있을 수 있을 것 같아 https://altd.embarcadero.com/.../RADStudio_11_3_esd_28... 와 이것 찾느랴 엄청고생함.