$preferredOrder$와 #value#의 차이

 

변수 입력값이 user_id = 'admin'

 

select * form PRODUCT where PRD_ID = #user_id#

=>  select * form PRODUCT where PRD_ID = ?

=>  등록이 되고

=> ? 에 'admin' 대입되서 들어가서

=> select * form PRODUCT where PRD_ID = 'admin'  실행이됩니다.

select * form PRODUCT where PRD_ID = '$user_id$'

=> user_id 에 'admin' 값을 가져와서

=> select * form PRODUCT where PRD_ID = 'admin'

=> 등록이 되고

=> select * form PRODUCT where PRD_ID = 'admin'  실행이 됩니다.

 

밑에는 또다른 예제를 포함시켰습니다.

 

원래 쿼리
select * from Product where prd_id = #abc# order by $operator$

입력 :
#userId# 를 'admin'
$operator$ 를 'user_name asc'

 

변경되는 순서 :
1. select * from Product where PRD_ID = #user_id# order by user_name  asc

2. select * from Product where PRD_ID = ? order by user_name  asc
3. 프리페어 스테이트 먼트에 등록

4. ? 에 'admin'  을 대입합니다.
5. select * from Product where PRD_ID = 'admin' order by user_name  asc
6. 실행

 

$ $ 는 값을 가져와서 문자열로 박아준 후에 등록을 하게 되는 것입니다.

 

설명이 부족한점이 있으면 추가 설명 부탁하시면 해드리겠습니다.^^

 

출처 : 지식 IN

블로그 이미지

클라인STR

,

발생일: 2011.01.31


문제:
크로스 브라우저 처리를 위해 navigator.userAgent 프로퍼티를 보고 있다.
아래 문자열은 지금 사용하고 있는 Firefox의 userAgent 값이다.


"Mozilla/5.0 (Windows; U; Windows NT 6.1; ko; rv:1.9.2.8) Gecko/20100722 Firefox/3.6.8 IPMS/A640400A-14D460801A1-000000426571"


참고 삼아 다른 사이트와 라이브러리 소스를 보다 보니, 어떤 사이트에서는 "Gecko" 문자열을 찾아 브라우저별 구현을 나눴고, 다른 라이브러리에서는 "Firefox" 문자열을 찾아 구현해놨다. 음...


크롬이나 사파리에서 userAgent를 찍어보면, "link Gecko"라고 되어있기도 하다. 음...


userAgent에 대해 확실하게 정리를 해봐야겠다.

 


해결책:
1. Navigator 객체는?
navigator 객체는 브라우저의 종류와 버전 등 웹브라우저 전반에 대한 정보를 제공하는 객체이다.


navigator라는 객체 이름은 Netscape Navigator 브라우저에서 온 것이며, IE의 경우 벤더 중립적인 표현으로 clientInformation을 지원하기도 한다. 실제로 IE에서 navigator === clientInformation 을 실행하면 true를 반환한다.


naviagtor에는 대표적으로 다음과 같은 프로퍼티있다.


navigator.appName
브라우저의 간단한 이름
navigator.appVersion
버전 또는 버전과 관련된 정보. 브라우저 내부적으로 사용되는 버전에 대한 숫자이므로 사용자에게 표시되는 버전 숫자와 항상 일치하지는 않다.
navigator.userAgent
브라우저가 User-Agent HTTP 헤더에 넣어 전송하는 문자열로 appName과 appVersion의 모든 정보를 포함하며 더 자세한 정보를 추가로 담고 있다. 이 정보에 대해서는 표준화된 서식이 존재하지 않기 때문에 각 브라우저 특성에 따라 파싱해야 한다.
navigator.appCodeName
브라우저의 코드 네임. Netscape에서는 "Mozilla"라는 코드 네임을 사용한다. 호환성을 위해 IE도 역시 같은 코드 네임을 사용한다. 
navigator.platform
브라우저가 실행되는 하드웨어 플랫폼으로 javascript 1.2 버전부터 지원한다.

 


navigator 객체의 프로퍼티가 알려주는 정보는 완전히 신뢰할 수 있는 것이 아니다.
예를 들어, Firefox 1.0에서 appName은 "Netscape"로, appVersion은 "5.0"으로 시작한다.
모질라 코드에 기반하지 않은 사파리 브라우저에서도 똑같은 값이 반환된다.
IE 6.0에서는 마찬가지로 appName이 "Mozilla"로, appVersion은 "4.0"으로 시작한다.
이는 오래 전에 배포된 브라우저 탐지 코드들이 아주 많기 때문에, 이 프로퍼티들을 갱신하면 수 많은 웹페이지들의 호환성이 깨지게 되고, 이를 브라우저 제작사가 감당할 수 없기 때문이라고 한다. (더 자세한 이유는 아래 히스토리 참고)

 


2. History of User Agent
navigator.userAgent에 대해 더 깊게 이해하려면, User Agent에 대한 히스토리를 알아두는 게 도움이 될 수 있다.


User-Agent 헤더의 탄생
1995년 HTML 2.0이 나오기 전까지 HTML은 표준화되지 않았다.
당시 Netscape나 Microsoft 같은 벤더들은 웹제작자들이 좀 더 풍부하게 컨텐츠를 제공할 수 있도록 각자 매력적인 기능을 추가하고 있었다. 이에 따라 다양한 브라우저가 출시되기 시작했고, 최신 브라우저는 좀 더 화려한 HTML을 제공했다.
여러 브라우저가 출시되면서 웹제작자들은 제작한 컨텐츠가 다양한 브라우저에 모두 정상적으로 보일 수 있도록 대책이 필요했다. 그 중 하나는 가장 낮은 버전의 HTML을 제공하는 것이었고, 다른 하나는 브라우저의 버전을 탐지해 서버가 브라우제 따라 적합한 컨텐츠를 내려주도록 하는 것이었다. 당시에는 브라우저에서 스크립트가 가능하지 않았기 때문에, 서버에서 브라우저를 탐지해내기 위해 User-Agent 헤더가 생기게 됐다.

 


"Mozilla/version",  오해의 시작
당시 브라우저는 Netscape Navigator와 Internet Explorer 뿐이었기 때문에, 브라우저를 탐지하기 위해 User Agent의 vendor와 version을 구분하는 것만으로 충분했다.


Netscape 브라우저는 "Mozilla/version" 과 같은 방식으로 코드 네임과 버전을 표시하고, 그 뒤로 추가적인 정보를 기술했다. 따라서 최초의 브라우저 탐지 기법은 userAgent에서 Mozilla/version 정보를 찾는 방식이었다.
이후의 다른 브라우저 벤더들은 자사 제품이 Netscape 브라우저의 특정 버전과 호환된다는 의미로 userAgent 정보에 Mozilla/version 을 추가했다. 실제로는 "Mozilla/version" 기반이 아니었지만 말이다.


당시 Netscape의 점유율이 가장 높았던 것을 생각하면 어쩌면 당연한 일이기도 하겠지만, 지금에 와서도 정확한 브라우저 여부를 탐지하는 것이 어려운 것은, 이 때 잘못된 이해와 표준화 되지 않은 방법으로 버전 정보를 기술한 것이 발단이 된 것으로 볼 수 있다. (호환성을 위해 지금까지도 대부분의 브라우저의 userAgent가 Mozilla/verion 의 형태로 시작한다.)

 


클라이언트 측 스크립트 출현
Netscape Navigator2 버전이 출시하면서 브라우저는 클라이언트 측 스크립트를 제공했고, 다른 브라우저들도 각자의 방식으로 스크립트를 구현하기 시작했다. 이제 웹제작자들은 서버측에서 User-Agent 헤더값으로 브라우저를 판별하지 않고, 클라이언트에서 바로 어떤 브라우저에서 접속했는지 찾아낼 수 있었다. 브라우저마다 스크립트의 구현 방법이 달랐기 때문에 웹제작자들은 document.images 같은 "객체 기반 탐지"로 브라우저를 구별해낼 수 있었다.


이런 "객체 기반 탐지"가 많이 사용되었음에도 몇몇 웹자작자들은 vendor/version 접근법을 사용했다.
브라우저에서 navigator 객체도 제공했기 때문에, 이전에 서버에서 사용한 것과 같은 로직을 클라이언트에도 적용할 수 있었다. 게다가 navigator 객체에서는 appName과 appVersion을 따로 제공했기 때문에 vendor/version 값을 바로 알아낼 수 있었다.


Netscape Navigator4 버전과 Internet Explorer4 버전부터 HTML을 클라이언트에서 직접 조작할 수 있게 되었다. (DHTML)
더불어 CSS 스타일도 제공하기 시작했다. 이 시기의 브라우저에서는, 같은 벤더임에도 이전 버전과도 호환되지 않는 기능들이 추가되기도 했다.


스크립트가 그랬던 것처럼, 각 브라우저 벤더들의 DHTML 구현 방식이 달랐기 때문에, 웹제작자들은 브라우저 여부를 판단하기 위해 "객체 탐지 기법"을 주로 사용하게 됐다. 예를 들어, document.layers 객체가 존재하면 Netscape4 라는 것을, document.all 이 존재하면 Explorer4 버전이란 걸 쉽게 알 수 있었다. 물론 이 방법은 Netscape 와 Explorer 두 가지의 브라우저가 있을 때에만 가능한 일이었다.


vendor/version 으로 브라우저를 구별해내는 방법은 Gecko와 같은 다른 브라우저들이 나오면서 더 이상 의미가 없어졌다. vendor/version 단위로 브라우저를 구별해내는 방식은 제대로 작동하지도 않을 뿐더러, 유지보수하기도 어려웠다.

 


진짜 Mozilla/5.0 - Netscape6
Netscape6 는 최초의 Gecko 기반 상용 브라우저이며 Netscape6의 userAgent 값은 HTTP 표준을 따라,
"Mozilla/5.0 (...) Gecko/20001108" 과 같은 형태로 기술되었다.


첫 번째의 vendor/version 인 Mozilla/5.0 문구는 "Netscape6이 5세대 브라우저이며, 기존 브라우저와는 같지 않다"는 걸 나타낸다.
하지만 앞서 언급했듯이, 다른 브라우저들은 "호환성의 의미"로 첫 번째 버전을 Mozilla/5.0 이라고 표시한다.
따라서 Mozilla/5.0 구문만으로는 유일하게 Gecko라는 걸 판단할 수 없다.


두 번째 vendor/version 인 Gecko/20001108 은 Netscape6가 Gecko의 2000년 11월 8일 버전으로 구현됐다는 문구이다. 만약, 브라우저가 실제로 Gecko 기반인지를 확인하려 한다면 Gecko/CCYYMMDD 형태를 검색해보면 된다.


세 번째 vendor/version 인 Netscape6/6.0 은 이 브라우저가 Netscape6라는 걸 나타낸다. Netscape6의 경우, 벤더명에 버전명을 포함시켰기 때문에 효율적이지 않아 7버전부터는 벤더명에서 버전을 제외하여 아래와 같이 제공된다.
Mozilla/5.0 (...) Gecko/200207XX Netscape/7.0


따라서 기존의 vendor/version 기반 탐색을 Netscape4와 IE4에서만 가능했다.
document.all과 document.layers로 구분했던 객체 기반 탐지 방법도 Netscape6+ 와 IE5+ 가 출시되면서 더욱 복잡해졌다.

 


3. 각 브라우저 별 User Agent 정보
Firefox
Firefox는 아래와 같은 형태로 User Agent 정보를 제공한다.


Mozilla/5.0 (Windows; U; Windows NT 6.1; ko; rv:1.9.2.8) Gecko/20100722 Firefox/3.6.8 IPMS/A640400A-14D460801A1-000000426571


- Mozilla/5.0 : 모질라 5.0 기반이다.
- platform: 플랫폼 정보
- rv: Gecko 레이아웃 엔진의 배포 버전
- Gecko/yyyymmdd : Gecko의 개발용 배포일로 yyyymmdd 형태이다. 실제 배포일은 아니며, 추후 삭제될 수 있다.
- Firefox/appversion : Firefox 의 버전이다.

 


Internet Explorer
IE는 아래와 같은 형태로 User Agent 정보를 제공한다.


Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0; IPMS/A640400A-14D460801A1-000000426571; TCO_20110131100426; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; InfoPath.2; Tablet PC 2.0)


- Mozilla/4.0 : Mozilla 4.0과 "호환 가능"하다.
- MSIE 8.0 : Internet Explorer 8.0이다.
- Trident/4.0 : Trident 레이아웃 엔진 4.0 버전으로 구현됐다.

 


Chrome
Chrome의 User Agent 정보는 좀 복잡하다.


Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/534.7 (KHTML, like Gecko) Chrome/7.0.517.44 Safari/534.7


- Mozilla/5.0 : Mozilla 5.0과 호환 가능하다.
- AppleWebKit/version (KHTML, like Gecko) : "Gecko 같은" 브라우저 레이아웃 엔진인 KHTML을 사용한다.
Webkit은 KHTML를 기반으로 한 엔진이다.
- Chrome/version : Chrome이며 해당 버전이다.
- Safari/version : Safari의 해당 버전과 비슷하다.

 


Safari
Chrome과 거의 동일하지만 버전 정보를 포함하고 있다.


Mozilla/5.0 (Windows; U; Windows NT 6.1; ko-KR) AppleWebKit/533.18.1 (KHTML, like Gecko) Version/5.0.2 Safari/533.18.5

 


Opera
Opera는 가장 깔끔하다.


Opera/9.80 (Windows NT 6.1; U; ko) Presto/2.6.30 Version/10.62


- Opera/version : Opera 해당 버전이다.
- Presto/version : Presto 레이아웃 엔진을 사용하고 있다.

 


4. 결론
User Agent 정보는 브라우저마다 각각 다르게 제공하고 있으며, 이를 정확하게 파싱하는 것은 더욱 어려워졌다.
의미가 잘못 전달되어 작성된 "Mozilla/version" 정보는 이제는 거의 의미가 없으며, 신규 브라우저의 지나친 정보도 정확한 브라우저 탐지를 어렵게 한다.


브라우저 탐지를 위해서는 일단 "브라우저와 레이아웃 엔진과의 관계"를 알아두는 게 좋겠고, 각 브라우저 별 User Agent 정보 간 차이점을 파악해야겠다.
꼭 필요한 경우가 아니라면 "객체 기반 탐지"로 크로스 브라우저를 구현하는 걸 권장한다.

 


5. 참고자료
Browser Detection and Cross Browser Support(MDN) : User Agent의 히스토리와 Gecko의 User Agent 정보
Gecko user agent string reference(MDN) : MDN의 User Agent 레퍼런스
Understanding User-Agent Strings(MSDN) : MDSN의 User Agent 레퍼런스
History of the browser user-agent string : 브라우저 User Agent 정보의 히스토리
브라우저 정보에 나오는 Mozilla의 의미 : 위 포스트를 기반으로 아주 이해하기 쉽게 작성한 포스트!

블로그 이미지

클라인STR

,

<script language="JavaScript" type="text/JavaScript">
<!--
//〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓
// 모바일 페이지로 이동.
//〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓

if(  (navigator.userAgent.match(/iphone/i)) || (navigator.userAgent.match(/ipod/i)) || (navigator.userAgent.match(/android/i)) || (navigator.userAgent.match(/Symbian/i)) || (navigator.userAgent.match(/nokia/i)) || (navigator.userAgent.match(/webos/i)) || (navigator.userAgent.match(/opera mini/i)) || (navigator.userAgent.match(/sonyericsson/i)) || (navigator.userAgent.match(/opera mobi/i)) || (navigator.userAgent.match(/iemobile/i)) ) {
  // 모바일 주소 표시줄 숨기기
  window.addEventListener('load', function(){  setTimeout(scrollTo, 0, 0, 1); }, false);

  // 모바일 버전으로 페이지 이동
  document.location = "/m/";
}else{
  // 웹 버전으로 페이지 이동
  document.location = "/web/";
}
//〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓
//-->

</script>


출처 : https://blog.naver.com/sm8569/100113041304

블로그 이미지

클라인STR

,

Decode 함수는 입력된 값 또는 수식을 검사해 적당한 값을 Return 하는 Basic API 입니다.Decode는 가변갯수 인자를 취하는 Method 로 2n+1 또는 2n (n>1)개의 인자갯수를 입력할 수 있습니다.


Decode(varValue,varCase,varRetValue, ...);Decode(varValue,varCase,varRetValue, .... ,varDefault);



 Parameters
 
Parameters
Type
Description
varValueVariant비교 대상이 되는 값.
varCaseVariantvarValue와 비교될 값. 2n (n>1)위치의 값입니다.
varRetValueVariantReturn 값. 2n+1 (n>1)위치의 값입니다.
varDefaultVariantvarCase 중에 값이 없는 경우 Return 될 값. 2n (n>1)위치의 값입니다. [Default Value = null ]

ex)
Decode("1", "1", "One", "2", "Two", "Default");


Decode API는 가변 인자를 받아서 2n 위치의 인자는 varCase, 2n+1 위치의 인자는 varRetValue의 역할을 합니다.varValue의 값과 varCase의 값을 비교했을 때 값이 같으면, 2n+1위치의 값이 Return 됩니다.* 만족하는 값이 없는경우 varDefault의 값이 Return 됩니다.Expr 과 같이 If 문을 사용할 수 없는 경우 주로 사용됩니다.



그리드에서 decode 사용하기

 


 

처리상태 컬럼을 선택하고, 컬럼속성에서 Expr을 선택한다.

decode(appStatus,"2"," 출력후","3","FC레포트","4","GEUS등록","5","GEUS 전송실패","") .

 appStatus 값에 따라서 출력할 문구를 바꿔줄수있다. 마지막 조건파라메터는 "" 공백이다. appStatus 만족값이 없는경우 공백으로 처리한다. switch case 문의 default 값이라고 보면 될거 같다.

블로그 이미지

클라인STR

,

마이플랫폼 자료실에서 winDebug 를 다운로드 받는다.

 

인스톨러를 설치하면 다음과 같이 설치가 된것을 확인 할 수 있다. 
(참고로 마이플랫폼 사이트에 회원가입을 해야 자료를 받을 수 있으며, 회원인증되는곳에는 1~2정도 걸린다.)

 

 

WinDbg   실행한다.

 

 

 

파일에서 Attach to a Process 를 선택한다.

 

 

디버깅할 프로세서 (IE) 를 선택하고 OK 버튼을 누른다.

 

커맨드창이 생성되며 커맨드 입력창에 g 를 입력하고 엔터키를 누른다.

 

 

현재 디버깅 모드가 작동 중이다.

 

 

마이플랫폼 페이지를 실행하던중에 예기치 못한 Exception 이발생한 경우

 

커맨드 입력창이 활성화 되며 

!analyze -v

 

입력하면 trace 로그가 ~~ 짠하고 나타난다.

 

*** ERROR: Symbol file could not be found. Defaulted to export symbols for D:\DOCUME~1\Kiuk\LOCALS~1\APPLIC~1\TOBESOFT\MIPLAT~1\CyComctl320U.dll - 
*******************************************************************************
* *
* Exception Analysis *
* *
*******************************************************************************

*** ERROR: Symbol file could not be found. Defaulted to export symbols for D:\WINDOWS\system32\USER32.dll - 
*** ERROR: Symbol file could not be found. Defaulted to export symbols for D:\WINDOWS\system32\IEFRAME.dll - 
*** ERROR: Symbol file could not be found. Defaulted to export symbols for D:\WINDOWS\system32\kernel32.dll - 
***** OS symbols are WRONG. Please fix symbols to do analysis.

*************************************************************************
*** ***
*** ***
*** Your debugger is not using the correct symbols ***
*** ***
*** In order for this command to work properly, your symbol path ***
*** must point to .pdb files that have full type information. ***
*** ***
*** Certain .pdb files (such as the public OS symbols) do not ***
*** contain the required information. Contact the group that ***
*** provided you with these symbols if you need this command to ***
*** work. ***
*** ***
*** Type referenced: ntdll!_PEB ***
*** ***
*************************************************************************
*** ERROR: Symbol file could not be found. Defaulted to export symbols for D:\WINDOWS\system32\IEUI.dll - 
*** ERROR: Module load completed but symbols could not be loaded for D:\Program Files\Internet Explorer\iexplore.exe
*********************************************************************
* Symbols can not be loaded because symbol path is not initialized. *
* *
* The Symbol Path can be set by: *
* using the _NT_SYMBOL_PATH environment variable. *
* using the -y <symbol_path> argument when starting the debugger. *
* using .sympath and .sympath+ *
*********************************************************************
*** ERROR: Symbol file could not be found. Defaulted to export symbols for D:\WINDOWS\system32\ADVAPI32.dll - 
*********************************************************************
* Symbols can not be loaded because symbol path is not initialized. *
* *
* The Symbol Path can be set by: *
* using the _NT_SYMBOL_PATH environment variable. *
* using the -y <symbol_path> argument when starting the debugger. *
* using .sympath and .sympath+ *
*********************************************************************
*** ERROR: Symbol file could not be found. Defaulted to export symbols for D:\WINDOWS\system32\msvcrt.dll - 
*********************************************************************
* Symbols can not be loaded because symbol path is not initialized. *
* *
* The Symbol Path can be set by: *
* using the _NT_SYMBOL_PATH environment variable. *
* using the -y <symbol_path> argument when starting the debugger. *
* using .sympath and .sympath+ *
*********************************************************************
*** ERROR: Symbol file could not be found. Defaulted to export symbols for D:\WINDOWS\system32\RPCRT4.dll - 
*********************************************************************
* Symbols can not be loaded because symbol path is not initialized. *
* *
* The Symbol Path can be set by: *
* using the _NT_SYMBOL_PATH environment variable. *
* using the -y <symbol_path> argument when starting the debugger. *
* using .sympath and .sympath+ *
*********************************************************************

... (중략)... 대충 이런식으로

 

 

로그를 카피해서 마이플랫폼 게시판에 문의를 한다. -_-

주로 다음과 같은 에러가 발생할 때 사용해보는 것이 좋겠다.

 

 

 

출처 : http://www.miplatform.co.kr/index.asp

블로그 이미지

클라인STR

,

CVS나 SVN에 올려서 사용할경우 배포를 시켜줘야된다.

배포는 다음과 같이 한다.

 

 

이클립스에서 install 폴더에 생성된 DLL파일을 복사한다.

그리고 component320U.xml파일을 열어 다음과 같이 편집한다.

 

 

<?xml version="1.0" encoding="UTF-8" ?>
  <root>
    <params>
  <param id="DEVICE" type="string">Win32</param>
  <param id="SOURCE" type="string">component320U</param>
  <param id="TARGET" type="string">%UserApp%TobeSoft\ing_life\components</param>
  <param id="FILENAME" type="string"></param>
  <param id="VERSION" type="string">2007,05,21,1</param>
  <param id="ACTION" type="string">DOWN</param>
  <param id="STATUS" type="string">0</param>
 </params>
 <dataset id="output">
  <colinfo id="DEVICE" type="string" size="255"/>
  <colinfo id="SOURCE" type="string" size="255"/>
  <colinfo id="TARGET" type="string" size="255"/>
  <colinfo id="FILENAME" type="string" size="255"/>
  <colinfo id="VERSION" type="string" size="255"/>
  <colinfo id="ACTION" type="string" size="255"/>
  <colinfo id="STATUS" type="string" size="2"/>

  <record><FILENAME>CyCalendarExU.dll</FILENAME><VERSION>system::2007.6.29.1</VERSION></record>
  <record><FILENAME>CyGridU.dll</FILENAME><VERSION>system::2007.8.8.1</VERSION></record>
  <record><FILENAME>CyTreeViewU.dll</FILENAME><VERSION>system::2007.6.7.1</VERSION></record>
  <record><FILENAME>CyWebBrowserU.dll</FILENAME><VERSION>system::2007.6.1.1</VERSION></record>
  <record><FILENAME>CyXecureAdp7U.dll</FILENAME><VERSION>system::2007.7.12.1</VERSION></record>
  <!-- User Extend Api -->
  <record><FILENAME>ExtCommonApiU.dll</FILENAME><VERSION>system::2007.4.17.1</VERSION></record>
  <record><FILENAME>CyCalendarEx2U.dll</FILENAME><VERSION>system::2007.3.23.1</VERSION></record>
  <record><FILENAME>CyMultiLineTabU.dll</FILENAME><VERSION>system::2007.6.7.1</VERSION></record>
  <record><FILENAME>CyLiteDBAdpU.dll</FILENAME><VERSION>system::2007.10.2.1</VERSION></record>
  <record><FILENAME>AdaptDBAdoU.dll</FILENAME><VERSION>system::2007.10.2.1</VERSION></record>
  <record><FILENAME>AdaptDBOdbcU.dll</FILENAME><VERSION>system::2007.10.2.1</VERSION></record>
  <record><FILENAME>CyMaPrintListU.dll</FILENAME><VERSION>system::2009.9.1.1</VERSION></record>


 </dataset>
</root>

 

* 빨간색으로 강조된것이 새로 추가된 부분이다.

이때  DLL파일의 파일버전 정보가 0.0.0.1 로 설정되있을 것이다.

버전관리를 위해서 VS2005 리소스 뷰에서 파일 버전정보를 년도.월.일.1 과 같은 형식으로 수정해준다.

 

 

 

FiLEVERSION 을 선택하여 클릭하면 버전정보를 수정할수있다. 버전정보를 년도.월.일.1로 수정한다.

 

배포가 제대로 되는지 테스트 해보자.

 

D:\Documents and Settings\Kiuk\Local Settings\Compatible LocalLow\Tobesoft\ing_life\components

배포디렉토리 항목은 다음과 같다.

 

 

 

웹사이트를 실행한다.

 

 

웹사이트 실행시 자동으로 dll파일이 생성된것을 알 수 있다.

 

블로그 이미지

클라인STR

,


MiplatForm에서  특정 DLL 파일에 API를 사용하기 위해서는 DLL파일을 마이플랫폼에서 사용할 수 있게 맵핑해야 된다.

 

 

 

파일 -> 새로만들기 -> 프로젝트 생성을 선택하고

TobeSoftComponent Wizard를 선택하고  적당한 이름을 적어 프로젝트를 생성한다.

 

 

 

 

 

 

 

 

Module type에서 ExtApi를 선택하고, Module name에는  API이름을 적는다.
다.
( Module name은 나중에 StartXML에 등록할 때 사용할 이름과 같게 하시면 편리합니다.)


 *  MiPlatform SDK Path를 Browse를 사용하거나 입력하여 설정합니다. MiPlatform SDK Path를 지정해야 정상적으로 컴파일이 가능합니다.
* MiPlatform SDK Path는 MiPlatform과 함께 제공되는 MiPlatformSDK의 Root Directory를 지
정하셔야 합니다. 실제 디렉토리 지정은 환경설정에서 지정했던 

D:\Documents and Settings\Kiuk\My Documents\Visual Studio 2005\Templates\ProjectTemplates\Visual C++\Tobesoft\MiPlatform  상관없음 

* Component가 ANSI로도 사용할 예정이라면, “Add ANSI Configurations” 앞의 CheckBox를
체크해 주십시오. MiPlatform 3.2는 UNICODE를 권장합니다.
* MFC를 사용하지 않고자 하면, Not use MFC를 선택합니다.MFC를 사용하더라도 MFC 확장
DLL 형태로 제작하지 않아야 된다면, Use shared MFC DLL을 선택합니다.

설정이 끝났으면 다음으로 넘어간다.

 

 

 

 

외부 Dll 파일을 import 하는 경우라면 Use DLL Import를 체크합니다. 그리고 DLL target
module에서 import 대상 파일을 선택합니다

현재 내가 작업할  D:\windos\system32\MaApi_RD.dll   을 선택해준다 .

 

 

 

 

 

외부 Dll을 import하는 경우 해당 Dll에서 이용할 함수를 편하게 이용할 수 있도록 지정
할 수 있습니다. 해당 함수의 정확한 prototype을 입력해야 합니다. 각 입력값에 따라
Function signature를 통해 prototype의 형식을 가늠할 수 있습니다.

 

* 마크애니에서 지정한 출력프린터 리스트만 얻기위해서는

MaGetUsablePrinters2()

MaGetUsablePrinterCount2() 메서드를

 

MaPrtAPI.h 에 정의된 형태대로  추가해준다. 

즉 ExtAPI 에서 외부 DLL 작업을 할경우 헤더파일이 필요하다. DLL에 정의된 함수를 사용하기 위해서라면

 

 

 

 

마이플랫폼에서 호출해서 사용할 API 함수 형태를 정의한다.

 

*  Method name : method를 call할 때 사용하는 이름
*  Arguments prototype : method에서 사용할 argument의 형태를 지정합니다.
*  Input arguments : 입력인자의 개수를 검사할 때의 개수. 가변으로 할 때는 최소값을
입력한 후 소스코드에서 직접 고쳐야 합니다.
*  Return : Return값의 존재여부.
*  Method signature : PID에서 Method를 사용할 때 표시될, 메소드의 설명. 일반적으로
Method의 원형을 표시합니다. 주석을 제외한 부분이 보여집니다.

 

 

Finish 버튼을 눌러 프로젝트 생성을  완료한다.

 

 

 

 

 

완성된 프로젝트  다음과 같이 생성된다.

 

 

* . API 구현하기

 

 

구현 해야될 Sample 소스 코드는 다음과 같다.

 

PrinterList.cpp

 

#include <stdio.h>
#include <windows.h>
#include "../MaApi_RD/MaPrtAPI.h"

int main()
{
 int i = 1;
 char **szModelTmpText, **szDrvTmpText;

 int nCount = 0;
 int ret = 0;

 ret= MaGetUsablePrinterCount2(&nCount, 7); //Printer 갯수 구하기

 printf("%d",nCount);

 //memory 할당
 szModelTmpText = (char**)malloc(sizeof(char*) * nCount);
 szDrvTmpText = (char**)malloc(sizeof(char*) * nCount);

  for(i=0; i<nCount; i++)
  {
  szModelTmpText[i] = (char*)malloc(sizeof(char) * MAX_PATH);
  szDrvTmpText[i] = (char*)malloc(sizeof(char) * MAX_PATH);
  memset(szModelTmpText[i], 0x00, sizeof(szModelTmpText[i]));
  memset(szDrvTmpText[i], 0x00, sizeof(szDrvTmpText[i]));
  }
 
 //프린터이름/모델 배열 구하기 
 ret = MaGetUsablePrinters2(szModelTmpText, szDrvTmpText, &nCount, 7);

 for(i=0; i<nCount; i++)
 {
  printf("%s",szModelTmpText[i]);
 }

 return ret;
}

 

 

 

 

 

Cy_MaPrintList.h

 

 

자동생성된 코드의 설명은 생략하겠다.

// Cy_MaPrintList.h
//
//////////////////////////////////////////////////////////////////////////

#pragma once

#include "ExtApi/Cy_ExtAPIService.h"
#include "Cy_MaPrintListWrap.h"
#include "stdio.h"
#include "string.h"

 

 

int nCount=0; //프린터개수 
char **szModelTmpText;// 모델명
char** szDrvTmpText; // 드라이브명
int ret;

 

//클래스 내부에 있어야될 데이터가 외부에 전역으로 나와있다.

//클래스 내부에서 선언할경우 CY_RESULT Cy_MaPrintList::api_getMaprintList(Cy_ExprObject *pExprContext, const Cy_VariantList *pVars, Cy_Variant &RetVar)

내부에서 접근이 불가능하므로 부득이하게 외부에서 전역변수로 선언하여 사용하였다. (-_- 더좋은 대안이있다면 답변좀)


class Cy_MaPrintList :
 public Cy_ExtAPIService 
{
    static Cy_MaPrintListWrap c_MaPrintListWrap;
    static int c_nMaPrintListWrapRef;


 
public:
 Cy_MaPrintList ();
 virtual ~Cy_MaPrintList ();
 
 // API Map
 DECLARE_EXTAPI_MAP(Cy_MaPrintList);
 //  DECLARE_EXTAPI(apiname)
 DECLARE_EXTAPI(getMaprintList);   //API선언부 (자동생성된 코드임 )
 


 
private:
 
 void deleteMemory(char** pStrPrinterName , char** pStrPrinterModel);

// 동적으로할당한 메모리를 해제
 void GetMaPrintList(void);

//프린터 리스트 객체를 얻는 메서드
 

};

 

Cy_MaPrintList.cpp

// 자동으로 생성된 코드는 설명 생략

 

// Cy_MaPrintList.cpp : implementation of the Cy_MaPrintList class.
//
//////////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "Cy_ErrorCode.h"
#include "Platform/Cy_Common.h"
#include "Script/Cy_ExprOp.h"
#include "Cy_MaPrintList.h"


DECLARE_SERVICE_AFXDLL_ENTRY(EXTAPI_MODULE_TYPE, Cy_MaPrintList, 1000)

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

BEGIN_CY_EXTAPI_MAP(Cy_MaPrintList)
// CY_EXTAPI_INFO(class, method_name,  i, o , comment)
    CY_EXTAPI_INFO(Cy_MaPrintList,  getMaprintList,  0,   1, _T("getMaprintList()"))

END_CY_EXTAPI_MAP(Cy_MaPrintList)

Cy_MaPrintListWrap Cy_MaPrintList::c_MaPrintListWrap;
int Cy_MaPrintList::c_nMaPrintListWrapRef = 0;

Cy_MaPrintList::Cy_MaPrintList()
{
    if( Cy_MaPrintList::c_nMaPrintListWrapRef == 0 )
     Cy_MaPrintList::c_MaPrintListWrap.Init();
    Cy_MaPrintList::c_nMaPrintListWrapRef ++;
 
     this->GetMaPrintList(); //생성자 내부에서 프린트리스트를 얻어오는 메서드를 호출 
 
 
}

Cy_MaPrintList::~Cy_MaPrintList()
{
 
 this->deleteMemory(szModelTmpText,szDrvTmpText); //메모리 해제

    Cy_MaPrintList::c_nMaPrintListWrapRef --;
    if( Cy_MaPrintList::c_nMaPrintListWrapRef == 0 )
     Cy_MaPrintList::c_MaPrintListWrap.UnInit();
    ASSERT( Cy_MaPrintList::c_nMaPrintListWrapRef >= 0 );
}

//////////////////////////////////////////////////////////////////////////
// methods body
CY_RESULT Cy_MaPrintList::api_getMaprintList(Cy_ExprObject *pExprContext, const Cy_VariantList *pVars, Cy_Variant &RetVar)
{
 
 
 // Check Argument Count
 if( pVars == NULL || pVars->Count() != 0 )
 {
  if( pExprContext != NULL && pExprContext->IsSystemLogMode() )
  {
   Cy_Result err;
   err.AddMsg( CY_WRONGARGUMENT, __FILE__, __LINE__, _T("[ExtAPI:MaPrintList]"), _T("getMaprintList"), NULL );
   pExprContext->OnSystemError( err );
  }
  return CY_WRONGARGUMENT;
 }
 
 
 Cy_VariantList prnList;

 for(int i=0; i<nCount;i++)
 {  
  prnList.Add((Cy_Variant)szModelTmpText[i]);
 }
 
 
 RetVar.Set(prnList);

 
 
 return CY_OK;
}

 

 

이상하게도 메소드내에서 클래스 내부변수나 객체의 접근이 불가능하다. -_-도통이놈의 wizard툴이란..

MIP에서 자세한 기술지원을 해주지않아서 더 알아 내지는 못해서 결과를 내는데 급급하였다.

실제로 내부함수에서 리턴되는 CY_OK란  API호출의 성공, 실패여부만을 리턴하기때문에 결과적으로 이놈을 사용해서 값을 넘겨줄수 없다.

Cy_Variant RetVar 를 사용하여 값을 리턴시켜줘야된다.

RetVar에 어떤행위(?)를하여 반환하고자하는 값들을 set해서 넘겨주면된다.

현재 프린터 리스트 배열을 넘겨야 하므로  Cy_VariantList 객체를 사용하였다.

자세한내용은 각 형의 .h헤더파일을 참조하기바란다. 

Cy_VariantList 객체에 값을 담을경우 유니코드 인코딩이 자동으로 해주는것같다.

실제로 내부코드를  "aaaa", "가나다라" 로 넘길경우 인코딩에 문제가 발생한다.


// end methods body
//////////////////////////////////////////////////////////////////////////

 

//Ma_API를 사용하여 등록된 프린터 리스트만 얻어오는 함수

void Cy_MaPrintList::GetMaPrintList(void)
{
 int i = 1;

 ret= this->c_MaPrintListWrap.MaGetUsablePrinterCount2(&nCount, 7); //Printer 갯수 구하기

 //memory 할당
 szModelTmpText = (char**)malloc(sizeof(char*) * nCount);
 szDrvTmpText = (char**)malloc(sizeof(char*) * nCount);

  for(i=0; i<nCount; i++)
  {
  szModelTmpText[i] = (char*)malloc(sizeof(char) * MAX_PATH);
  szDrvTmpText[i] = (char*)malloc(sizeof(char) * MAX_PATH);
  memset(szModelTmpText[i], 0x00, sizeof(szModelTmpText[i]));
  memset(szDrvTmpText[i], 0x00, sizeof(szDrvTmpText[i]));
  }
 
 //프린터이름/모델 배열 구하기 
  
 ret = this->c_MaPrintListWrap.MaGetUsablePrinters2(szModelTmpText, szDrvTmpText, &nCount, 7);

}

 

//메모리  해제 함수

void Cy_MaPrintList::deleteMemory(char** pStrPrinterName , char** pStrPrinterModel)
{
 int i=0;
 
 if(nCount>0)
 {
  for(i=0; i<nCount; i++)
  {
   delete  szModelTmpText[i];
   delete  szDrvTmpText[i];
  }
  delete szModelTmpText;
  delete szDrvTmpText;
 }
}

 

빌드하여 DLL 파일을 생성한다.

그담 제대로 됬는지 테스트가 필요하다.

 

ExtAPI  적용 및 테스트 하기

 

 

 

바로전에 작업한 DLL이 생성된폴더에서 DLL파일을 복사하여

D:\Documents and Settings\Kiuk\Local Settings\Application Data\TOBESOFT\MiPlatform320U\Component

디릭토리에 붙여넣기한다.

 

 

 

[마이플랫폼에서 EXTAPI 컴포넌트 추가하기]

ProjectExplorer 에서

Global 탭을 선택하고

EXTAPIS 를 선택하고 더블클릭한다.

EXTAPI 이름을 적어준다. 이때 DLL 이름일아 맞지 않는다. 즉 최초로

프로젝트 생성시 입력한 API이름으로 적어준다.

 

 

마이플랫폼에서 test1폼을 생성하고 다음과 같이 코딩한다.

 


function test1_OnLoadCompleted(obj)
{
 
 var printList = this.getMaprintList();

 for (i = 0 ; i <printList.Length ; i++)
 {
 
  alert("prnList "+i+" "+ printList[i]);
 }
 
}

 

this하고 점을 찍었을경우 메서드목록에 나오지않을 경우도 있다. 그냥

API 정의된대로 메서드명을 적어준다.

 

테스트 결과

 


 

 

제대로 작동하는것을 알 수 있다.

 

 

'개발이야기' 카테고리의 다른 글

마이플랫폼 winDebug 사용하는방법  (0) 2018.10.18
EXTAPI DLL 배포하기  (0) 2018.10.18
Spring Security 이해하기  (0) 2018.10.11
Spring Security적용기 (1)  (0) 2018.08.02
IBATIS 동적 컬럼 만들기  (0) 2016.01.05
블로그 이미지

클라인STR

,

TouchableOpacity View가 터치에 적절하게 응답하도록하는 래퍼이다. 

아래로 누르면 래핑된 뷰의 불트명도가 감소하여 흐리게 표시된다.


render() {
let opacity = this.props.disabled ? 1 : 0.5;
return (
<TouchableOpacity
activeOpacity={opacity}
onPress={this.props.onPress}
style={[styles.wideButton, this.props.style]}
>
{this.props.children}
</TouchableOpacity>
);
}



  • activeOpacity : 터치가 활성화 되었을때 래핑된 뷰의 불투명도 값 (Default 0,2)
  • tvParallaxProperties : Apple Tv 시차 효과를 제어한다. (Only Apple TV)
  • hasTVPreferredFocus : Tv 우선 포커스 설정 (Only Apple TV)
출처 : https://facebook.github.io/react-native/docs/touchableopacity#activeopacity


'React & React Native ' 카테고리의 다른 글

ReactNative flexBox 연습1  (0) 2018.11.15
리액트란? (React)  (0) 2018.10.21
react-native 특정버전으로 프로젝트 생성하기  (0) 2018.10.17
FlexBox 레이아웃이란? (2)  (0) 2018.10.17
FlexBox 레이아웃이란? (1)  (0) 2018.10.14
블로그 이미지

클라인STR

,