Clear함수 오류(MFC환경입니다.)

일단 MFC(Visual Studio)환경이라는 것부터 말씀드립니다.
HWP AUTOMATION입니다.

CHwpObject클래스의 Clear함수에서 "서버에서 예외 오류가 발생했습니다."라는 메시지가 뜨면서 죽는 현상이 있었습니다.
물론 항상 발생하는 오류는 아닙니다.

[1] 한글 오피스 문서를 엽니다.
[2] SetPos라는 함수([BOOL SetPos(long List, long Para, long pos)])에서
List라는 파라미터에 120처럼 상대적으로 큰 값을 넣어서 호출합니다.
[3] 문서에 10줄 이상의 여러 줄 추가합니다.
[4] Clear함수를 호출합니다. 확인 결과, 파라미터는 상관없는 것 같습니다.

시나리오 결과 : 그러면 "서버에서 예외 오류가 발생했습니다."라는 메시지가 뜨면서 죽습니다.

제 예상에 커서의 위치가 120에 있는데 그 앞부분(60정도)에 글씨가 대량으로 추가되면 문제가 발생하는 것으로 보입니다.
SetPos가 아니고 문서를 순회(사용시 InitScan, ReleaseScan를 호출)하면서 GetText를 호출해도 문제가 발생합니다.

<<샘플 소스>>

-로드해서 이동하는 부분

VARIANT varFormat, varArgument;
varFormat.vt = VT_BSTR;
varArgument.vt = VT_BSTR;

varFormat.bstrVal = L"HWP";								// HWP Format
varArgument.bstrVal = L"lock:false;forceopen:true";		// lock

static TCHAR BASED_CODE szFilter[] = _T("한글 파일(*.HWP, *.HWPX) | *.HWP;*.HWPX;*.hwp;*.hwpx |모든파일(*.*)|*.*||");
CFileDialog dlg(TRUE, _T("*.hwp"), _T("hwp"), OFN_HIDEREADONLY, szFilter);
if (IDOK == dlg.DoModal())
{
	CString pathName = dlg.GetPathName();

	CString lpszPath = _T("");
	lpszPath = pathName;

	BOOL	bOpen = m_hwpObject.Open(lpszPath, varFormat, varArgument);
	if (bOpen == FALSE)
	{
		return FALSE;
	}
	m_hwpObject.SetPos(119, 0, 0);

}

-Clear하는 부분

if (m_hwpObject.get_IsModified())
{
	// hwpSaveIfDirty
	m_hwpObject.Clear(COleVariant((short)2));
}
2개의 좋아요

안녕하세요 ^^
내부 확인후 추후 패치에 적용될수 있도록 해보겠습니다.
오류확인 감사드립니다…!!

2개의 좋아요

해당 메시지 뜨는 현상이 오류가 맞는 거죠?

2개의 좋아요

안녕하세요 ~
테스트 해보니 제자리에서는 동작을 하지 않아 여러가지로 테스트해봐야할것 같습니다 ^^
오류라고 딱 말씀드리긴 어려울것 같습니다.

SetPos의 List는 파라의 집합을 말하는데 보통 본문의 list id는 0입니다.

문서에서 다른 list가 생성되는 경우는 표안의 셀마다 list id를 가지게되고 머리말 꼬리말등 본문과 다른 텍스트 입력 영역에 listid가 부여됩니다.

120이라는 아이디를 지정해주셨는데 문서에 따라서 오류가 발생할수 있을것 같다는 예상만 해볼수 있을것 같습니다 ^^

내부에는 이러한 잘못된 값 입력에 대해서 방어 코드가 있지만 커버가 안되는 케이스가 있을수 있기때문에 한번 검토 및 확인해보겠습니다.
감사합니다 ^^

2개의 좋아요

"오류라고 딱 말하기는 어렵다."라고 하셨는데, "추후 패치에 적용될 수 있도록 해본다."는 말이 인과관계가 맞지 않는 것 같습니다.
오류를 발견하지 못 해서 그렇게 말씀하신 것 같은데, 일단 오류를 발견하는 것이 최고 우선 순위인 것 같습니다.
오류를 발견하지 못 하면 추후 패치도 못 하실 것이라고 생각이 듭니다.

– 오류를 발견하기 위한 주요 사항은
[1] 큰 문서이어야 합니다. 저도 확인을 해봤는데 샘플용으로 2페이지 정도되는 문서에서는 그 문제가 발생하지 않습니다.
50페이지 정도는 되어야 문제가 발생합니다. (문서를 준비할 필요없이 "국가법령정보센터"를 찾아가면 큰 문서를 찾을 수 있습니다.)
[2] 여러 줄을 추가해야 합니다. 저의 경우는 문서에 있는 내용을 10줄 정도 복사해서 그 다음 줄에 붙여넣어서 확인하고 있습니다.

– 상관없는 내용은
[1] 수정한 다음에 "저장"을 눌렀는지 안 눌렀는지는 상관이 없습니다.
[2] Clear함수의 파라미터는 상관이 없습니다.

제가 GetText함수를 사용했을 때도 발생한다고 말씀드렸습니다.
SetPos함수는 해당 위치가 존재하지 않아서 이동하지 않을 수 있지만 GetText함수를 사용하면 문서의 모든 위치를 찾아서 커서를 움직이기 때문에 오류가 발생할 확률이 있다고 생각이 됩니다.

해당 소스 코드도 드립니다.

-로드해서 이동하는 부분

start

	BOOL bContinue = TRUE;
	long lret;							// 텍스트 추출 함수 호출 후 리턴값
	CComBSTR strBufCom;						// 읽어온 라인데이터를 저장할 변수

	InitScan();
	while (bContinue)
	{
		lret = GetTextCarat(strBufCom);
		if (lret == 0 || lret == 1 || lret == 101 || lret == 102)
		{
			bContinue = FALSE;
		}
		else
		{
			m_hwpObject.MovePos(COleVariant((long)201/*CHwpOleManager::moveScanPos*/), COleVariant((long)0), COleVariant((long)0));

			long slist = 0, spara = 0, spos = 0;		// 문단정보
			m_hwpObject.GetPos(&slist, &spara, &spos);
		}
	}
	ReleaseScan();

end

사용되는 함수입니다.

LONG GetTextCarat(CComBSTR& strBuf)
{
if (m_hwpObject == nullptr) {
return 0L;
}

//InitScan();
// (중요) BSTR을 CComBSTR로 사용해야 합니다. 그렇지 않으면 죽습니다.
CComBSTR	strBuffer;
LONG lnGetText = m_hwpObject.GetText(&strBuffer);
strBuf = strBuffer;
//ReleaseScan();

return lnGetText;

}

BOOL InitScan()
{
// 스캐닝을 설정.
COleVariant option, range, spara, spos, epara, epos;

// maskNormal 0x00, maskChar 0x01, maskInline 0x02, maskCtrl 0x04
option.vt = VT_UINT; option.uintVal = 0x00 | 0x01 | 0x02 | 0x04;	// 모든 대상
range.vt = VT_UINT; range.uintVal = 0x0070 | 0x0007 | 0x0000;		// 문단의 시작부터 끝까지, 정방향 탐색

m_hwpObject.InitScan(option, range, spara, spos, epara, epos);

return TRUE;

}

BOOL ReleaseScan()
{
m_hwpObject.ReleaseScan();

return TRUE;

}

-GetText후에 Clear하는 부분

if (m_hwpObject.get_IsModified())
{
// hwpSaveIfDirty
m_hwpObject.Clear(COleVariant((short)2));
}

2개의 좋아요

안녕하세요,
처음 Clear 함수 오류라고 말씀하셔서 테스트 해보았나 오류가 발생하지 않았습니다.
GetText의 경우도 동일하게 오류가 발생하지 않았습니다.
처음 올려주신 내용을 보니 SetPos의 List에 120이라는 큰값을 넣어주었으나 이부분은 문서에 따라서 오류가 발생할수도 있다고 생각했습니다.
이러한 부분도 테스트 해보았으나 죽는 문제는 발생하지 않았습니다.

user106님 께서 오류가 맞는거냐고 물어보셔서 내부에서는 재현이 안되 오류라고 말씀드릴수 없다고 한것입니다 ^^
그리고 패치에 적용할수 도록 해본다는 댓글은 오류 발생이 확인되지 않아 추가적으로 확인해보고 오류가 확인되면 패치에 포함할수 있도록 한다는 말이였습니다.

다시 올려주신 코드로도 한번 다시확인해보겠습니다 ^^
혹시 user106님의 사용중인 한글 버전을 알려주실수있을까요?
저는 2022, 2020, 2018 버전으로 테스트해보았습니다.

감사합니다.

2개의 좋아요

한글 오피스 2022입니다. 감사합니다.

2개의 좋아요

버전 영향 받지 않습니다.
한글 오피스 2018, 한글 오피스 2010에서도 동일하게 문제 발생합니다.

2개의 좋아요

일단 오류를 피해서 구현을 하였으니 너무 다급하게 생각하지는 않으셔도 될 것 같습니다.

2개의 좋아요

제가 ocx와 해깔렸습니다. 2018, 2010은 확인하지 않았습니다.

2개의 좋아요

오류를 피해서 구현했다고 생각했는데 최근에 다시 문제가 발생하고 있습니다.
조금 더 확인해보고 자세히 글 드리겠습니다.
아직 재현 안 되었나요?

2개의 좋아요

안녕하세요 ^^
주신 코드 확인해보았지만 재현되지 않고 있습니다.
70페이지가 넘는 문서를 통해서 확인해보았습니다.
로직도 정상적으로 돌고 clear도 정상 동작하고있습니다.
추가적으로 확인되는 내용올려주시면 확인해보겠습니다 ^^
감사합니다.

2개의 좋아요

더 추가적으로 확인을 해보고 있고, 문서에 표가 반드시 있어야 오류가 재현이 됩니다.
오류 발견에 도움이 되시기 바랍니다.

2개의 좋아요

글씨가 앞에 있고 표가 그 뒤에 있어야 합니다.
(표가 앞에 있고, 글씨가 뒤에 있으면 오류가 없습니다.)

그리고 앞에 있는 글씨 부분을 수정해야 합니다.
저도 단위 테스트를 하고 있는데 “서버에서 예외 오류가 발생했습니다.” 메시지 없이 그냥 죽어 버립니다. 더 확인해서 전달드리겠습니다.

2개의 좋아요

글씨가 앞에 있다는 것은 문서의 상단에 있다는 의미입니다.
같은 줄에 글씨와 표가 있다는 의미는 아닙니다.
감사합니다.

2개의 좋아요

죽을 때 메시지입니다.
처리되지 않은 예외 발생(0x00007FFE5F55CF19, (해당 실행파일).exe): Microsoft C++ 예외: COleException, 메모리 위치 0x0000000BEE2FF1D8.

2개의 좋아요

HWP Automation을 사용할 때,
HWND m_hwndApp;
::SetParent(m_hwndApp, pParentWnd->GetSafeHwnd());
같이 다른 프로그램의 내부에 붙여서 쓰면 안 되나요?

한글 오피스가 독립적으로 떠 있을 때는 오류가 없는데,
다른 MDI프로그램의 창으로 붙어들어갈 때는 해당 메시지가 나옵니다.

오류 시나리오를 한글과 컴퓨터 담당자분들께 알려드리기 위해서 단위 테스트를 하고 있는데,
그렇게 밖에 해석이 안 됩니다.

대부분의 사용자들이 그렇게 사용할 것 같습니다.

2개의 좋아요

안녕하세요.
혹시 한글 오토메이션을 내부로 사용하는 프로그램이 64비트 프로그램일까요?
32비트로 빌드 후 테스트 부탁드립니다.

저도 Inplace 방식은 사용해본적이 없어서 확인해보겠습니다 ^^
감사합니다.

2개의 좋아요

32비트도 64비트와 동일합니다. 감사합니다.

2개의 좋아요

안녕하세요. 한컴디벨로퍼입니다.

해당 문의를 여러 차례 숙고 및 검토한 바, 일부 답변에 한계가 있어 구매 및 설치를 담당하셨던 담당자나 영업 사원을 통해 확인하시는 것을 추천 드립니다. 바로 도움을 드리지 못해 죄송합니다.

한컴디벨로퍼를 이용해 주셔서 감사합니다.

한컴디벨로퍼 드림

2개의 좋아요