프로그램관련

[스크랩] 아래한글 자동화

쿨가이22 2013. 3. 12. 11:29

요즘은 문서 변환 프로젝트를 하고 있다. 열번은 더 만들어 본 거라 익숙하고, 소스도 많지만, 회사 애들 거하고 겹치게 하고 싶지는 않다. 굳이 코드도 안보고, 방식도 바꾸고, 라이브러리도 새로 만들고 있다. 아래한글은 2005 이후 버전은 손대본 적이 없으나 방식이 크게 바뀌지는 않았다. 2010버전의 PDF 변환기에는 고스트스크립트를 썼다. 지한이가 앞서서 한글문제 버그 다 잡아 줬으니 잘 돌아갈거다. 오픈소스는 그런게 좋지.

 

OLE 자동화 방식으로 하니 자꾸 문서 여는데 보안승인 대화상자가 열렸다. 예제가 있었는데 이해가 안돼서 한참을 골탕먹었다. BSTR 전달도 잘 안돼서 이중으로 고통.

 

1. BSTR 관련

 

C++에서 호출하면 아래 코드처럼 호출하면 된다. 다 좋은데, 문서열 때 문제가 생긴다. LPCTSTR으로 전달한 문서 파일명을 아래한글 쪽에서 받지 못한다. 한마디로 이 코드로는 문서가 열리지 않는다. 동등한 코드가 워드나 엑셀 자동화에 사용되고 있기 때문에, 타입 문제는 아닌 듯하다. 대충 유니코드 문제가 아닐까 하고 생각하고는 있지만, 더 자세히 파진 않았다. MFC 타입라이브러리 마법사를 쓰면 해결되니까.

 

// 아래한글쪽  상수 정의

#define HWP_OLE_AUTOMATION_APPLICATAION _T("HWPFrame.HwpObject.1")

#define HWP_FILE_CHECK_DLL_INDICATOR _T("FilePathCheckDLL")

#define HWP_FILE_CHECK_HANDLE_INDICATOR _T("FilePathCheckHandle")

#define HWP_METHOD_REGISTER_MODULE _T("RegisterModule")

 

 

bool the_calling_function()

{

IDispatch* m_phwp;

CLSID clsid;

 

m_hr = CoInitialize(NULL);

if(FAILED(m_hr))

return false;

 

m_hr = CLSIDFromProgID(HWP_OLE_AUTOMATION_APPLICATAION,&clsid);

if(FAILED(m_hr))

{

CoUninitialize();

return false;

}

m_hr = CoCreateInstance(clsid, NULL, CTSCTX_LOCAL_SERVER, IID_IDispathc, (void**) &m_phwp);

 

if(FAILED(m_hr))

{

CoUninitialize();

return false;

}

 

COleVariant hwpSecuID(HWP_FILE_CHECK_DLL_INDICATOR);

COleVariant secuDllID(_T("secsec"));

long secunid =  333;

 

// Invoker는 GetIDsOfNames와 Invoke 함수를 엮어놓은 함수다. 함수명 가져다 Invoke를 부른다고 생각하면 된다. 소스 쓰기 귀찮다.

m_hr = Invoker(DISPATCH_METHOD, NULL, m_phwp, HWP_METHOD_REGISTER_MODULE, 2, hwpSecuID, secuDllID);

if(FAILED(m_hr))

{

CoUninitialize();

return false;

}

 

m_hr = Invoker(DISPATCH_METHOD, NULL, m_phwp, HWP_METHOD_REGISTER_MODULE, 2, hwpSecuID, (COleVariant)(secunid);

if(FAILED(m_hr)

{

CoUninitialize();

return false;

}


 COleVariant format(_T("")), arg(_T(""));
 VARIANT vformat = format.Detach();
 VARIANT varg = arg.Detach();

 

//이 부분에서 100% 파일명이 전달되지 않는다.

m_hr = Invoker(DISPATCH_METHOD, NULL, m_phwp, HWP_METHOD_OPEN, 3, (COleVariant)(_T("..파일명")), vformat, varg);

if(FAILED(m_hr)

{

CoUnitialize();

return false;

}

// 에러 리턴 부분에서도 아래 릴리즈 해줘야 한다. 역시 귀찮은...

m_phwp->Release();

CoUnitialize();

return true;

}

 

2.  MFC 타입 라이브러리 마법사

 

MFC의 타입라이브러리를 쓰면 (간단히,  추가  > 클래스 > TypeLib의 MFC 클래스 > 사용가능한 형식 라이브러리에서 HwpAutomationApp 1.0 형식 라이브러리... 이렇게 하면 추가되고, 인터페이스는 IHwpAutomation을 선택하고 나머지는 알아서 불러오면 된다. ) 자동화용 클래스가 만들어진다. 이걸쓰면 인생이 편한데, 뭐하러 Invoke를 써서 직접 작업하느냐 하면, Invoke 쪽은 대체로 생략가능한 매개변수가 많다. 해당 응용프로그램을 잘 모를 떄는 Invoke 쪽이 훨씬 편하다. 특히 VB로 만든 예제가 있는 경우는 거의 코드를 베껴올 수 있다. 반면 MFC-타입라이브러리는 꼬박꼬박 변수를 챙겨줘야 되니 불편하다. 이런 문제는 타입라이브러리가 자주 바뀌는 MS오피스 쪽의 경우에는 거의 100% 들어맞는다. 반면 아래한글은 VB 예제도 없고, 타입라이브러리도 아직까지는 안바뀌었으니까 불편이랄 것은 없다. 다만 MS오피스 자동화와 같은 패턴으로 작업하고픈, 뭐랄까, 강박이랄까...

 

아래 코드는 잘 돌아가고, 파일 열릴 때 보안 승인 대화상자도 열리지 않는다.

 

#include "CHwpAutomation.h"

 

bool the_function()

{

CHwpAutomation m_hwp;

m_hwp.CreateDispatch( HWP_OLE_AUTOMATION_APPLICATAION );

 

if(!m_hwp.RegisterModule(HWP_FILE_CHECK_DLL_INDICATOR, COleVariant(_T("secusecu"))))

{ return false;}

long nid = 333;

if(!m_hwp.RegisterModule(HWP_FILE_CHECK_HANDLE_INDICATOR, COleVariant(nid)))

{ return false;}

 

 COleVariant format(_T("")), arg(_T(""));
 VARIANT vname = format.Detach();
 VARIANT vformat = arg.Detach();

if(!m_hwp.Open(_T("...hwp"), vname, vformat))

{ return false;}

return true;

}

 

3. 보안승인 대화 상자

 

보안 승인 대화상자 관련 예제 코드는 아래한글 자동화 문서와 함께 한글과컴퓨터 홈페이지에서 다운받을 수 있다. 예전에 비해 한글과컴퓨터의 기술 지원 속도나 의지가 나아졌다고 하는데, 홈페이지는 그래 보이기는 한다. 하지만 기술 예제는 부족하기 그지 없다.

 

3-1. OLE 자동화 시에 아래한글에서 외부 파일을 열려고 할 때는 보안 관련 경고를 내보낸다.

의도하지 않은 외부 파일 변경에 대비하는 정책인듯 하다. 왈가왈부할 필요는 없다. 특히 웹파일 관련 동작인 경우에는 유용하기도 하다.

 

3-2. 보안관련 콜백 DLL을 OLE 자동화 클라이언트에서 지정할 수 있다.

RegisterModule 메서드를 이용하면 보안관련 콜백 DLL을 지정할 수 있다. 우선 레지스트리의 다음 위치에 DLL의 고유명과 DLL의 절대 경로를 지정해 주어야 한다.

 

HKEY_CURRENT_USER\Software\HNC\HwpAutomation\Modules

문자열 형으로 이름이 DLL 고유명이고 값이 DLL의 절대 경로다. 이때 DLL 고유명을 [secusecu]로 지정했고 DLL의 절대경로가 [d:\fsecu.dll]이라고 하면 다음과 같이 지정할 수 있다.

 

RegisterModule(_T("FilePathCheckDLL"), (COleVariant)(_T("secusecu")));

 

3-3. 보안 관련 콜백 DLL의 핸들값을 지정할 수 있다.

보안관련 콜백 DLL을 지정한 다음에는 핸들값도 지정할 수 있다.

RegisterModule(_T("FilePathCheckHandle"), (COleVariant)((long)500));

 

3-4. 보안관련 콜백 DLL의 IsAccessiblePath 함수

아래한글은 파일 열기 동작 시에 IsAccessiblePath 함수를 콜백한다. true를 리턴하면 파일을 열어 주고, false를 리턴하면 파일을 닫는다. 이 함수 안에서 대화상자를 열 수도 있다. 당연히 위의 secu.dll은 __stdcall 형식으로 해당 함수를 공개해야 한다. 다행히 한컴 홈페이지에서 DLL 예제함수를 다운받을 수 있다.

 

bool IsAccessiblePath(HWND hWnd, LONG nID, LPCTSTR szFilePath);

 

hWnd는 대화상자를 열 때 쓸 상위 윈도우 핸들이다. nID는 위에서 등록한 FilePathCheckHandle이다. 500이다. szFilePath는 IE 등에서 콜백하는 거라는데, 난 써본적이 없다.  간단히 모두 return true하면 간단하다. 다만 경우의 수를 생각해서 nID를 등록해 두고 nID가 500일 때만 true를 리턴하도록 하면 안전하게 쓸 수 있을 것이다.

 

 

 

 

 

출처 : 세모네모농장
글쓴이 : 짐승이 원글보기
메모 :