부정확한 MovePos함수

개발환경은 MFC(Visual C++)입니다.
한글 오토메이션입니다.

InitScan, ReleaseScan사이에서 while문을 돌면서
pHwpMng->MoveScanPos();
pHwpMng->GetCurPos(&slist, &spara, &spos);
으로 얻은 좌표를 사용합니다.

MovePos함수를 호출하면 OCX에서는 커서가 해당 위치로 이동하면서 화면의 최상단에 위치가 보입니다.
하지만 OLE에서는 커서는 정상적으로 해당 위치로 이동하지만 화면의 최상단에 맞춰서 화면 갱신이 되지 않습니다.
심지어 커서가 해당 위치로 이동하지 않는 경우도 있습니다.
물론 항상 그런 것은 아니고, 문서가 클 경우가 문서의 뒤 부분으로 갈 수록 그런 현상이 발생합니다.

말이 좀 어려워서 예를 추가합니다.
예 :
1번\n2번\n3번\n4번\n5번\n6번\n7번\n8번\n9번\n10번\n11번\n12번\n
[1] 12번 선택시 커서가 12번에 가면서 화면에 7번부터 12번까지 표시됨. 즉, 최상단에 12번이 표시되지 않음
[2] 12번 선택시 커서가 8번에 있음.

HWP Automation으로 바뀌면서 MovePos함수의 첫번째 파라미터에서 moveCurrentCaret (27번)이 사라진 것을 확인했고, 이 파라미터를 사용해서 구현하지 않았다는 사실도 언급합니다. 참고로 구현을 위해서 moveMain(0번)을 사용했습니다. 하지만 moveCurrentCaret (27번)도 동작하기는 하더군요.

2개의 좋아요

해당 문제에 대한 답변은 어떻게 되는지 궁금합니다.
시간되시면 답변 부탁드립니다.

1개의 좋아요

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

현재 담당자가 내용을 확인하고 있습니다. 조금만 기다려 주세요.

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

1개의 좋아요

안녕하세요,
MovePos는 이동후 최상단으로 보여주는 API가 아닌 캐럿 자체를 옮겨주는 API 입니다.
컨트롤, 오토메이션 모두 동일한 엔진코드를 사용하고 있으며 제가 테스트시에는 동일한 동작을 진행하고있습니다.
큰 문서에서 뒤쪽으로 가도 이동이 정상적으로 동작하고있습니다.

그리고 구현시 initscan을 이용해서 while문으로 돌린다고 하셧는데 이럴 경우 API가 빠르게 동시에 호출되면서 뷰단에 문제는 생길수있을것 같습니다.
MovePos로 이동하게 되면 내부 캐럿의 위치가 이동되고 한글 뷰에 대한 업데이트 이벤트가 발생하면 해당위치로 이동하게 되는데 업데이트를 진행하는데 외부에서 API를 중복으로 계속 호출되면 뷰업데이트시 올바르지 않게 동작할수는 있을것 같습니다.

저같은 경우는 다른 프로젝트에서 뷰에 관련된 API를 다수로 호출시 ,
아래와같이 업데이트를 따로 진행하여 문서에대한 업데이트가 진행된뒤 API 호출을 하는 방식으로 쓴적이 있습니다. 참고바랍니다.

CXHwpWindows wins = rHwpObject.get_XHwpWindows();
CXHwpWindow win = wins.get_Active_XHwpWindow();

UpdateWindow((HWND)win.get_WindowHandle());

감사합니다.

2개의 좋아요

[2]번 : 커서가 제대로 이동하지 않는다는 내용은 제가 Scan한 후에 문서에 내용을 추가해서 밀린 줄만큼 위치를 못 찾아가는 것이었습니다. 죄송합니다.

예:
1번\n2번\n3번\n4번\n5번\n6번\n7번\n8번\n9번\n10번\n11번\n12번\n
을 Scan후
1번\n2번\n3번\n4번\n5번\n6번\n7번\nA번\nB번\nC번\nD번\n8번\n9번\n10번\n11번\n12번\n
으로 변경된 경우 12번을 클릭하면 8번으로 이동(당연한 결과)

[1]번 : "캐럿 자체를 옮겨주는 API"이고 "이동후 최상단으로 보여주는 API"는 아니라고 하셨는데,
다시 Scan한 후에는 “이동후 최상단으로 보여주는 API” 기능도 정상적으로 동작하였습니다.
감사합니다.

2개의 좋아요

[1] 번 : "캐럿 자체를 옮겨주는 API"이고 "이동후 최상단으로 보여주는 API"는 아니라고 하셨는데,
제가 "이동후 최상단으로 보여주는 API"기능도 정상적으로 동작한다고 말씀드렸었습니다.
확인 결과 제가 착각한 것 같습니다.
OCX에서는 해당 기능이 포함되어 있는데 OLE(Hwp Automation)에서는 해당 기능이 포함되어 있지 않습니다.
OCX처럼 이 기능(“이동후 최상단으로 보여주는 API”)이 포함되면 참 좋을 거 같기는 합니다.

2개의 좋아요

OLE(HWP AUTOMATION)에서도 OCX처럼 캐럿을 이동할 때, 화면의 최상단에 위치시킬 수 있는 방법이 없나요?
기존 사용자들은 화면의 최상단으로 이동하는 것에 익숙해져 있는데, 어느 날 갑자기(물론 어느 날 갑자기는 아니지만) 안 된다는 말이 안 통할 것 같습니다.
답변을 기다리겠습니다.

2개의 좋아요

user106님 안녕하세요?
캐럿위치가 화면 최상단에 있게 뷰를 이동해야 하는 경우라면,
조금은 야매 같지만

  1. 먼저 화면 최하단으로 이동 한 다음
  2. 캐럿을 특정위치로 옮기면 뷰 최상단에 캐럿이 위치합니다.
    (3. 필요시 HAction.Run(“MoveScrollDown”) 을 2~3회 실행해서 미세조정합니다.)

그러면 아래와 같은 모습으로 실행됩니다.

녹화_2023_12_20_15_05_58_919

도움이 될지는 모르겠습니다^^;

1개의 좋아요

안녕하세요 ^^
보니 Goto 액션으로 최상단으로 이동이 가능할것 같습니다.
아래와 같이 테스트 해보니 최상단으로 이동이 가능합니다.
감사합니다

IDHwpAction action=  myHwpObj.CreateAction("Goto");

IDHwpParameterSet set =  action.CreateSet();

set.SetItem("DialogResult", 1);
set.SetItem("SetSelectionIndex", 1);
action.Execute(set);
2개의 좋아요

음, 그냥 문서최상단으로 이동해버리는 코드 같은데요?ㅎ

1개의 좋아요

DialogResult에 쪽의 수를 넣어주면 해당 쪽의 최상단으로 이동이 가능합니다~!

2개의 좋아요

아, 제가 애초에 질문을 잘못 이해했나보네요^^;
이동을 마친 캐럿이 뷰의 최상단에 위치해 있게
뷰 스크롤을 조정하는 기능을 질문자님께서 물어보신 줄 알았습니다ㅎ

이와는 별개로,
혹시 bhjung님께서 첫 댓글로 달아주셨던,
"뷰업데이트가 진행된 뒤 API 호출을 하는 방식"에 대해서
조금만 구체적으로 알려주실 수 있나요?^^;

저도 빠르게 뷰 관련 API를 여러 번 호출하는 경우가 있는데
불필요한(?) sleep을 항상 넉넉하게 줘야 하더라고요ㅜㅜ

1개의 좋아요

lico님이 이해하신 내용이 제가 질문한 내용이 맞습니다.
특정 페이지의 최상단으로 이동하는 것을 질문하지 않았습니다.
감사합니다.

2개의 좋아요

언급하신 방식으로 처리해서 해결되었습니다.
######################################
하지만 MoveScrollDown을 두번 호출했더니 오히려 다른 곳으로 이동했습니다. 그래서 그 부분은 적용하지 않았습니다.
그리고 "화면 최하단"이라는 의미가 옮기려는 커서이 속한 페이지의 마지막 부분으로 이동하라는 의미인 것 같습니다.
하지만 (List, Para, Pos)값만 가지고 페이지 번호를 얻기는 어려운 것으로 알고 있어서 그냥 문서의 최하단으로 이동한 후에 해당 위치로 커서를 이동했더니 "화면 최상단"으로 이동했습니다.
감사합니다.

2개의 좋아요