classid="clsid:F5016FB1-5236-11D3-9FEF-00001C1A962C" codebase="C:/activechatclient.cab#version=3,0,9,0" border="0" width="265" height="183">
로그인 상태 유지
황용호 님의 답변으로 해결 했죠...
지금 하시는 것 하고 똑같은 문제 였네요...
그럼
--------------------------------------------------------------------
안녕하세요? 조각달 황용호입니다.
질문이 조금 모호한데요...
질문하신 내용이 사용자 정의 프로퍼티를 만드시려고 하는 것인지
OCX의 property를 HTML에서 설정하거나 값을 읽으시려고 하시는지
아니면 반드시 태그를 이용하여 프로퍼티를 설정하시려는 것인지
모르겠습니다.
전부 설명해 드리겠습니다.
우선 사용자 정의 프로퍼티를 만드시려면...
ActiveForm을 사용하신다고 하셨으니 타입 라이브러리 위자드를 사용하시면
될 것 같군요.
ActiveForm을 보고 계신 상태에서 메뉴의 View - Type Library를 선택하시면
타입 라이브러리 위자드가 뜹니다.
왼쪽의 트리뷰에 보시면 IxxxX가 있고 IxxxXEvents 머 이렇게 주욱 있을 겁니다.
이 중 가장 위에 있는 IxxxX에서 (xxx는 ActiveForm을 만들 때의 이름입니다.)
마우스 오른쪽 버튼을 클릭하셔서 new - Property를 선택합니다.
그러면 IxxxX 밑에 Property1이 두개 생기는데 이를 클릭하시면
오른쪽 뷰에 프로퍼티의 속성이 나타나고 여기에 이름과 타입을 적어 줍니다.
주의하실 점은 두개의 프로퍼티 중 하나는 invoke kind를 'property get'으로,
나머지 하나는 'property put'으로 설정하셔야 합니다.
이 상태에서 strl-s를 누르셔서 저장을 하시면 ActiveForm의 pas파일에
'Get_프로퍼티명'과 'Set_프로퍼티명'이라는 함수와 프로시저가 생깁니다.
(사실 안생기는 경우가 더 많습니다. 델파이 버그 같은데 이런 경우
프로젝트명_TLB.pas 파일을 여시거나 타입 라이브러리 위자드에서 f12를 누르셔서
'Get_프로퍼티명'과 'Set_프로퍼티명'을 찾으신 후 - IxxxX interface 안에
있습니다. - ActiveForm class의 protected 절 밑으로 복사하신 후
ctrl-shift-C를 누르시면 해당 함수의 body가 생겨납니다.)
그런 후 'Get_프로퍼티명' 함수 안에는 외부에서 해당 프로퍼티를 읽을 때의
처리를 해 주시면 되고 'Set_프로퍼티명' 프로시저 안에 외부에서 해당 프로퍼티
의 값을 써 줄 때의 처리를 해 주시면 됩니다. 이것은 class나 콤포넌트 내에서
property를 설정해 주는 방식과 유사하게 보시면 됩니다.
다음 두 번째 이렇게 만들어진 OCX의 프로퍼티를 HTML에서 설정하는 방법입니다.
OCX의 프로퍼티를 HTML page에서 설정하는 방식은 두가지가 있는데,
하나는 다음에 설명할 태그를 이용하는 것이고 다른 하나는 자바나
VB스크립트를 이용하는 밥법입니다.
VB 스크립트로 예를 들겠습니다. (편의상 만들어진 OCX의 프로퍼티를
스트링 타입의 MyProperty라 하겠습니다.)
머 설명드릴 것은 없고 직접 HTML소스를 보시는 것이 빠를 것 같습니다.
classid="clsid:XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
CODEBASE=".../TestOCX.OCX">
여기서 'classid='의 값은 해당 OCX의 GUID인 CLASSID입니다.
이 CLASSID는 아까 타입 라이브러리 위자드에서 CoClass의 GUID를 보시거나
아니면 프로젝트명_TLB.pas에서 CLASS_ActiveFormX의 값을 복사하셔서
넣어 주시면 됩니다.
(흠... 쓰고 생각해 보니 델파이에서 Web Deploy를 해주면 자동으로
오브젝트는 생성이 되는군요. 그것을 이용하셔서 오브젝트의 id만
추가하시면 됩니다.)
마지막으로 태그를 이용하는 것인데 이것이 좀 어렵습니다.
헉! 제가 간과한게 하나 하나 있군요.
태그가 먹지 않던가요? 그렇다면 델파이 3.0을 사용하시는가 보군요.
일단 위의 설명은 모두 4.0 기준입니다. 제가 지금 3.0이 없어서 3.0으로
위의 과정을 수행하는 방법은 말씀드릴 수가 없군요. 하지만 방식이 크게
달라진 것이 없으니 쉽게 수행하실 수 있을 겁니다.
여튼 이 태그로 프로퍼티를 받는 방식에 대해서 설명해 드리겠습니다.
태그로 프로퍼티를 받기 위해서는 OCX는 IPersistPropertyBag이라는
재미있는 이름의 인터페이스를 상속받으셔서 구현하여야 합니다.
델파이 4.0의 TActiveForm은 이미 이 인터페이스를 상속받아서 구현까지
다 해놓았으므로 그냥
classid="clsid:XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
codebase=".../OCX명.OCX#version=X,X,X,X"
width=...
height=...
align=...
hspace=...
vspace=...
>
이렇게 넣어 주시면 알아서 프로퍼티가 세팅이 됩니다.
위에 말씀드린 대로 델파이 3.0에서는 이 IPersistPropertyBag을
구현해 놓지 않았기 때문에 이 태그가 먹지 않습니다.
그래서 다음과 같이 수동으로 IPersistPropertyBag을 구현해 주셔야 합니다.
우선 3.0에서 IPersistPropertyBag이 선언이 되어 있던가가 가물가물하군요.
IPersistPropertyBag의 선언은 다음과 같습니다.
IPersistPropertyBag = interface(IPersist)
['{37D84F60-42CB-11CE-8135-00AA004BB851}']
function InitNew: HResult; stdcall;
function Load(const pPropBag: IPropertyBag;
const pErrorLog: IErrorLog): HResult; stdcall;
function Save(const pPropBag: IPropertyBag; fClearDirty: BOOL;
fSaveAllProperties: BOOL): HResult; stdcall;
end;
만일 uses에 ActiveX를 넣어 주셨는데 IPersistPropertyBag이 없다고
징징거리면 위의 선언을 type절의 ActiveForm선언 위에 넣어 주세요.
다음 ActiveForm의 클래스 선언 부를 다음과 같이 고쳐줍니다.
TxxxX = class(TActiveForm, IActiveFormX)를
TxxxX = class(TActiveForm, IActiveFormX, IPersistPropertyBag)로.
(인터페이스는 아시겠지만 다중 상속이 가능합니다.)
다음 IPersistPropertyBag의 멤버 함수와 그의 베이스 인터페이스인
IPersisit의 멤버 함수를 구현해 줍니다.
// 이것은 IPersist의 멤버.
function TxxxX.GetClassID(out ClassID: TCLSID): HResult; stdcall;
begin
ClassID := // 요기다가 클래스 아이디를 넣어 줍니다.
// CLASSID는 위에 써 놓은 대로 알아내시면 됩니다.
Result := S_OK;
end;
// 여기부터는 IPersistPropertyBag의 멤버
// 초기화 (아무 것도 안합니다.)
function TxxxX.InitNew: HResult;
begin
Result := S_OK;
end;
// HTML의 태그로부터 값을 읽을 때.
function TxxxX.Load(const pPropBag: IPropertyBag;
const pErrorLog: IErrorLog): HResult; stdcall;
var
V: OleVariant;
begin
TVarData(V).VType := varOleStr;
if pPropBag.Read('MyProperty', V, pErrorLog) = S_OK then begin
// V는 OleVariant의 string형태로 프로퍼티의 값이 들어 있습니다.
// 여기서 이 값을 사용하시면 되겠군요.
end;
// 만일 프로퍼티가 더 있다면
if pPropBag.Read('...', V, pErrorLog) = S_OK then begin
// 해당 프로퍼티 사용
end;
Result := S_OK;
end;
// HTML의 PersistPropertyBag으로 값을 쓸 때 사용되는데 저도 써본 적은
// 없군요. 여튼 구현은 되어 있어야 하니.
function TxxxX.Save(const pPropBag: IPropertyBag; fClearDirty: BOOL;
fSaveAllProperties: BOOL) : HResult; stdcall;
var
V : OleVariant;
begin
V := // 쓰실 값을 넣어 주세요.
pPropBag.Write('프로퍼티명', V);
V := // 쓸 게 두 개 이상이라면 또 써주시면 됩니다.
pPropBag.Write('프로퍼티명2', V);
Result := S_OK;
end;
이렇게 구현해 주시면 3.0에서도 태그로 프로퍼티를 받으실 수
있습니다.
이상입니다. 글이 많이 길어 졌군요.
인터페이스나 COM에 대한 설명은 쓰지 않았습니다. 따로 공부하시길...
참고가되셨으면 합니다.
그럼 이만...