|
폼 하나에다가 두 개의 RichEdit를 좌우로 놓고 두 RichEdit의 스크롤을 동기화하는 방법을 고민하다가
www.torry.net에서 다음과 같은 팁을 찾았습니다.
//...
private
PRichEdWndProc, POldWndProc: Pointer;
procedure RichEdWndProc(var Msg: TMessage);
//...
procedure TForm1.FormCreate(Sender: TObject);
begin
PRichEdWndProc := MakeObjectInstance(RichEdWndProc);
POldWndProc := Pointer(SetWindowLong(RichEdit1.Handle, GWL_WNDPROC,
end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
if Assigned(PRichEdWndProc) then
begin
SetWindowLong(RichEdit1.Handle, GWL_WNDPROC, Integer(POldWndProc));
FreeObjectInstance(PRichEdWndProc);
end;
end;
procedure TForm1.RichEdWndProc(var Msg: TMessage);
begin
Msg.Result := CallWindowProc(POldWndProc, RichEdit1.Handle, Msg.Msg,
Msg.wParam, Msg.lParam);
if (Msg.Msg = WM_VSCROLL) and (LOWORD(Msg.wParam) = SB_THUMBTRACK) then
begin
Label1.Caption := 'Pos is ' + IntToStr(HIWORD(Msg.wParam));
RichEdit2.Perform(Msg.Msg, Msg.wParam, Msg.lParam);
SetScrollPos(RichEdit2.Handle, SB_VERT, HIWORD(Msg.wParam), True);
end;
end;
이렇게 했더니 RichEdit에 라인을 삽입할 때에 에러가 나더군요. 그래서 RcihEdit 둘 다에 라인을
삽입한 다음 FormCreate()의 다음 두 프로시저를 호출했더니 에러가 없었고 두 개의 RichEdit가
잘 동기화되더군요
PRichEdWndProc := MakeObjectInstance(RichEdWndProc);
POldWndProc := Pointer(SetWindowLong(RichEdit1.Handle, GWL_WNDPROC, Integer(PRichEdWndProc)));
저는 씨++빌더를 사용하는데 제가 테스트한 코드는 다음과 같습니다.
겉으로 보아서는 에러가 없는 것 같은데 에러 없이 잘 동작할 수 있는 코드인지 조언 바랍니다.
헤더파일
public:
Pointer PRichEdWndProc, POldWndProc;
void __fastcall RichEdWndProc(TMessage &Msg);
Cpp파일
void __fastcall TMDIChildTntRichEdit::RichEdWndProc(TMessage &Msg)
{
Msg.Result=CallWindowProc((int (__stdcall *)())POldWndProc, RichEdit1->Handle, Msg.Msg,Msg.WParam, Msg.LParam);
if((Msg.Msg ==WM_VSCROLL)&&(LOWORD(Msg.WParam) == SB_THUMBTRACK))
{
// Label1.Caption := 'Pos is ' + IntToStr(HIWORD(Msg.wParam));
RichEdit1->Perform(Msg.Msg, Msg.WParam, Msg.LParam);
SetScrollPos(RichEdit2->Handle, SB_VERT, HIWORD(Msg.WParam), True);
}
}
두 개의 RichEdit에 라인을 삽입한 다음 다음 두 코드를 실행시키니 스크롤 동기화가 잘 되더군요
물론 현재의 코드는 RichEdit1의 스크롤바를 클릭했을 때만 동작합니다.
PRichEdWndProc=MakeObjectInstance(RichEdWndProc);
POldWndProc= Pointer(SetWindowLong(RichEdit1->Handle, GWL_WNDPROC,Integer(PRichEdWndProc)));
그리고 폼이 닫힐 때 FormClose()를 호출해 주어야 하는데
위의 델파이코드에서 'Assigned'는 빌더에서는 어떤 식별자를 써 주어야 하는지요.
|