반응형

ActiveX를 만들때 매개변수로 배열을 받아야 할 필요가 있다.

많은 일련의 데이터를 한번에 받기 위해서 보통 문자열에 분리자(Separator)로 분리해서 문자열로 입력하는것이 보통인데
배열을 받는 방법은 없을까 해서 알아보았다.
일단 먼저 웹 스크립트에서 배열을 사용하는 방법을 알아보자. 배열은 다음과 같이 쓸수 있다.
자바 스크립트라면,

또는 VB Script라면,

 

이 배열을 ActiveX의 매개변수에 어떻게 넣느냐가 문제이다.

 

일단 기본 데이터 형식은 아니기 때문에, VARIANT 형식으로 받아야 하겠다. 
ActiveX의 메소드는 다음과 같이 정의를 하도록 하자.
void ShowArray(VARIANT varArray)

 

나는 VS2003을 쓰는데, 휴.. MFC ActiveX에서 이렇게 메소드를 만들자마자 버그코드를 만들기 시작한다.
IDL의 선언은 void ShowArray(VARIANT varArray); 로 정의되고,
컨트롤 소스에는 void ShowArray(VARIANT varArray);로 정의되었다. ㅠㅠ
컨트롤 소스가 잘못 생성되어서 나왔다. 일단 void ShowArray(LPVARIANT varArray); 로 정의를 변경해야 한다.
이놈의 VS2003 버그..ㅠㅠ 너무 많다..

 

배열을 VARIANT값으로 입력을 받을때 Java Script(JScript)와 VB Script는 다른 형식으로 입력된다.
Java Script(이하 JScript)는 VT_DISPATCH 형식으로 들어오고,
VB Script는 VT_ARRAY | VT_BSTR | VT_BYREF 형식으로 들어온다.

 

VB Script 배열 형식을 받아서 처리할 수 있는 예제는 인터넷에 널려있을것이다.
문제는 JScript 배열 형식을 받아서 처리하는 예제는 찾기가 어렵다.(나만 못찾는건지.)

 

일단 JScript 배열을 처리하려면, JScript 배열의 길이를 알아야 하지 않는가? 다음은 배열의 값이 접근을 할 수 있어야 하고...
JScript의 배열의 길이와 값에 접근 하기위해서는 다음과 같이 코딩해야한다.

 

void TestOCX::ShowArray(LPVARIANT varArray)
{
	CComVariant vtSource;
	// VT_BYREF 형식으로 입력되면 REF 값을 VARIANT로 복사한다.
	// VB Script 배열 형식은 VT_BYREF를 포함하므로 이걸 없앤다.
	::VariantCopyInd(&vtSource, varArray);
	// Variant 형식이 VT_DISPATCH인지 확인한다.
	if(VT_DISPATCH == (VT_DISPATCH & V_VT(&vtSource)) )
	{
		COleDispatchDriver disp;
		// COleDispatchDriver에 Attach한다. MFC는 좋은 클래스들을 많이 갖고 있다.
		disp.AttachDispatch(vtSource->pdispVal, FALSE);
		
		try
		{
			DISPID diLength;
			LPOLESTR length = L"length";
			long nArrayLength = 0;
			// Dispatch에서 length의 DISPID를 구한다.
			hr = disp->m_lpDispatch->GetIDsOfNames(IID_NULL, &length, 1, LOCALE_USER_DEFAULT, &diLength);
			if(FAILED(hr))
			{
				FireError(E_INVALIDARG, "매개변수 입력이 잘못되었습니다.");
			}
			
			// length의 속성값을 획득한다.
			disp.GetProperty(diLength, VT_I4, &nArrayLength);
			
			// 배열 길이 만큼 for문 돌면서 배열 값 출력
			for(int i = 0; i < nArrayLength; i++)
			{
				DISPID diIndex;
				TCHAR szIndex[20];
				CComBSTR bstrIndex;
				CComVariant vtData;
				
				// 배열 인덱스 속성값은 문자열로 지정하면 얻을 수 있다.
				// L"0", L"1", L"2" 처럼.

				StringCchPrintf(szIndex, 20, "%d", i);
				bstrIndex = szIndex;

				// 배열 인덱스의 DISPID를 얻는다.
				disp.m_lpDispatch->GetIDsOfNames(IID_NULL, &bstrIndex, 1, LOCALE_USER_DEFAULT, &diIndex);
				
				// 배열 값을 VARIANT 형식으로 받는다.
				disp.GetProperty(diIndex, VT_VARIANT, &vtData);
				
				// 예제에서는 배열의 값이 항상 문자열이여야 한다.
				if( VT_BSTR != V_VT(&vtData) )
				{
					FireError(E_INVALIDARG, "문자열 배열만 입력 가능합니다.");
					break;
				}
				
				//배열의 값을 각각 메세지 박스로 출력한다.
				AfxMessageBox(CString(vtData.bstrVal));
			}
		}
		catch(CMemoryException *pEx)
		{
			// 메모리 예외 처리 : 예제에서는 그냥 ReportError 및 FireError로 처리
			pEx->ReportError();
			FireError(E_OUTOFMEMORY, "메모리 오류입니다.");
			pEx->Delete();
		}
		catch(COleException *pEx)
		{
			// OLE 예외 처리 : 예제에서는 그냥 ReportError 및 FireError로 처리
			pEx->ReportError();
			FireError(pEx->m_sc, "OLE 오류입니다.");
			pEx->Delete();
		}
		catch(COleDispatchException* pEx)
		{
			// OLE Dispatch 예외 처리 : 예제에서는 그냥 ReportError 및 FireError로 처리
			pEx->ReportError();
			FireError(pEx->m_scError, "OLE Dispatch 오류입니다.");
			pEx->Delete();
		}
	}
}

 

예제를 보면 JScript 배열이 어떻게 구성되어 있는지 볼 수 있다.

 

여기서 특이한 점은 속성값의 DISPID이다.

TRACE를 따라가다보면 알겠지만, 배열의 크기가 3이라고 할때, length의 DISPID는 4값이면, "0"~"2"까지의 DISPID는 1~3 이다.

 

그럼 DISPID 0값은 무엇일까?

 

DISPID 0값은 "1, 2, 3" 이런식으로 모든 배열의 데이터가 ","로 분리되어서 나온다.

 

DISPID 5,6 값이 VT_DISPATCH로 되어 있고, 각각 constructor, prototype이라는 속성이 지원되는데, javascript 객체의 생성자와 객체의 재정의에 관련된 내용이여서 배열을 받는데 크게 사용되진 않는다. 

 

위의 JScript 예제에서

 

alert(arrArray);

 

라고 하면 DISPID 0값이 나오는 것으로 확인할 수 있겠다.

 

실제 작성한 코드는 VARIANT 형식으로 배열(JScript와 VBScript 상관없이) 또는 한개의 문자열을 받는 메소드 이지만 그중에서 JScript 처리 부분만 간추려서 올린다.
반응형
반응형

SyntaxHighlighter 테스트.

 

정말 설정하기 어렵구나.

 

그러나 드디어 했다. 만세!!

/* test */
int main()
{
    printf("%d", 1);
}
반응형

'기타' 카테고리의 다른 글

Asus 노트북 AS  (0) 2016.02.26
반응형

Internet Explorer 8 버전이 나오면서 탭 브라우징을 지원하였습니다.

탭 브라우징은 Frame 윈도우와 Tab 윈도우를 별도의 프로세스로 구현하게 되어 있습니다.

여기서 Tab마다 같은 프로세스가 실행되게 하려면 다음 레지스트리 값을 변경해야 합니다.

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\Main
HKEY_CURRENT_USER\SOFTWARE\Microsoft\Internet Explorer\Main

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\Main 키의 TabProcGrowth 값을 DWORD값 1로 설정하면 같은 Tab 윈도우가 같은 프로세스 내에서 동작하게 됩니다.

또한 이 설정은 사용자 레지스트리에 역시 저장됩니다.

HKEY_CURRENT_USER\SOFTWARE\Microsoft\Internet Explorer\Main키의 TabProcGrowth입니다.

IE9 버전이 나오면서 Windows Vista 이상에서 LCIE라는 구현으로 인해 IEFrame과 Tab상의 프로세스 권한이 다르게 설정이 되었습니다.

 

반응형
반응형

VC++ 2005로 개발한 응용프로그램 및 모듈은 컴파일 옵션을 /MD로 주게되면 Side by side로 C Runtime을 물기 때문에 재배포 패키지를 같이 배포해 주어야 한다.

그러나, Side by side 영향 때문에 VC2005 재배포 패키지라고 해도 현재 사용하고 있는 런타임의 재배포 패키지를 설치하지 않으면 실행이 되지 않는다. 때문에 아무리 VC2005 재배포 패키지를 깔아도 여전히 Side by side 때문에 실행이 되지 않고 오류가 발생한다.

개발자는 보통 보안패치를 잘 하는 경우가 대부분이기 때문에, 재배포 패키지를 배포하려면 현재 자신이 배포하는 모듈의 Manifest를 한번 검사하고 최신 재배포 패키지를 배포하는 것이 맞다.

일단 side by side로 만들어진 모듈은 manifest를 확인해보고 배포해야 한다. 특히 정적 라이브러리를 포함한 모듈을 만들경우 항상 한가지 버전의 c runtime dll에 종속성이 생기는 것이 아니다.

VC2005의 경우 재배포 패키지는 버전별로 현재 4개 정도 나와 있는 듯하다.

  • Microsoft Visual C++ 2005 재배포 가능 패키지(2006-04-05):
    (버전: 8.0.50727.163)

Microsoft Visual C++ 2005 재배포 가능 패키지(x86):

http://www.microsoft.com/downloads/ko-kr/details.aspx?FamilyID=32BC1BEE-A3F9-4C13-9C99-220B62A191EE

Microsoft Visual C++ 2005 재배포 가능 패키지(x64):

http://www.microsoft.com/downloads/ko-kr/details.aspx?FamilyID=90548130-4468-4BBC-9673-D6ACABD5D13B

  • Microsoft Visual C++ 2005 SP1 재배포 가능 패키지(2007-11-15):
    (버전: 8.0.50727.762)

Microsoft Visual C++ 2005 SP1 재배포 가능 패키지(x86)

http://www.microsoft.com/downloads/ko-kr/details.aspx?FamilyID=200B2FD9-AE1A-4A14-984D-389C36F85647

Microsoft Visual C++ 2005 SP1 재배포 가능 패키지(x64):

http://www.microsoft.com/downloads/ko-kr/details.aspx?FamilyID=EB4EBE2D-33C0-4A47-9DD4-B9A6D7BD44DA

  • Microsoft Visual C++ 2005 서비스 팩 1 재배포 가능 패키지 ATL 보안 업데이트(2010-09-20):
    (버전: 8.0.50727.4053)

http://www.microsoft.com/downloads/ko-kr/details.aspx?FamilyID=766A6AF7-EC73-40FF-B072-9112BAB119C2

  • Microsoft Visual C++ 2005 Service Pack 1 재배포 가능 패키지 MFC 보안 업데이트(2011-06-07):
    (버전: 8.0.50727.6195)

http://www.microsoft.com/downloads/ko-kr/details.aspx?FamilyID=ae2e1a40-7b45-4fe9-a20f-2ed2923aca62

    URL은 시간이 지나면 예고도 없이 바뀌기 때문에 링크가 제대로 될지는 알수 없으나 현재까지 URL은 위와 같다.

    MS에서 일괄되게 검색이 되면 얼마나 좋을까? 다운로드 사이트에 가서도 재배포 패키지를 받으려면 이곳 저곳 찾아야 되니 참 귀찮다.

    재배포 패키지 제목 좀 통일했으면. 어쩔 때는 SP1, 서비스 팩 1 또는 Service Pack 1 이것 참 번역 할 때 마다 쓰는 단어가 틀려지는 건지 참..

    ATL보안 업데이트와 MFC보안 업데이트 재배포 패키지는 Windows Update를 통해서도 자동 업데이트가 되긴하나 프로그램 설치하면서 Windows Update 먼저 하십시요라고 할 수는 없지 않은가? ㅠㅠ

    반응형

    + Recent posts