0

I have this situation. I have two multiple line edit boxes. First is not editable and second yes. I catch EN_UPDATE message and when appears than I send updated text from second window to first window. So both of window have same text. Also If one is scrolled, than second one is scrolled too (mirrored behaviour).

Problem is that if I update text in first window after send new text from second window than scrollbar is moved at the start. If I use SetScrollPos than scrollbar is set, but text is not moved to correct position. I see the first line of text and I want to see position before update the text. How is this possible?

Update

I want that after SendMessage to first window like this to not to move window to the start position of text when replaced old text with new text. Because I have for example first window scrolled in the middle and after text is replaced that firstwindow is moved to the first line of new text but I want to stay in old position because I am updating only on letter in text in second window and than I send this change to firstWindow. But I resend all text.

 SendMessage(firstWindow, WM_SETTEXT, 0, (LPARAM) buffer);

I create multiline text box like this:

firstWindow = CreateWindowEx(
            0, TEXT("EDIT"),   // predefined class
            NULL,         // no window title
            WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_BORDER |
            ES_READONLY | ES_LEFT | ES_MULTILINE | ES_AUTOVSCROLL,
            TEXTBOX_START_X, TEXTBOX_START_Y, TEXTBOX_WIDTH, TEXTBOX_HEIGHT,
            hWnd,         // parent window
            (HMENU) ID_TEXTBOX,   // edit control ID
            (HINSTANCE) GetWindowLong(hWnd, GWL_HINSTANCE),
            NULL
        );
        savedWndProcTablet = (WNDPROC) SetWindowLongPtr(tabletWindowUtils.textboxHwnd, GWL_WNDPROC, (LONG_PTR) &textBoxProc);

Update 2

I try this:

char *buffer = new char[2];
buffer = "a\0";
DWORD l,r;
SendMessage(secondWindow, EM_GETSEL,(WPARAM)&l,(LPARAM)&r);
SendMessage(firstWindow, EM_REPLACESEL, 0, (LPARAM)buffer);
SendMessage(firstWindow, EM_SETSEL,l,r);

So I have some text in first window and where is position in second window I add new letter to this position. But this add one letter to correct position but it add no one letter but still adds aaaaaaaaaaaaaaaa. Why is it doing?

I can use only pure c++ and winapi.

Thanks.

Jaro Kollár
  • 253
  • 3
  • 15
  • 1
    http://stackoverflow.com/questions/16730252/use-wm-settext-to-replace-contents-of-window-whilst-maintaining-window-scroll-po – Mark Jansen Aug 03 '15 at 13:54

1 Answers1

0

If you want to copy consistently the whole text from second edit box to first, and ensure that scrolling position is correctly mirrored, you can just use:

// get the full text of second window
int len = ::GetWindowTextLength(secondWindow) + 1;
LPTSTR txt = new TCHAR[len];
::GetWindowText(secondWindow, txt, len);
// copies it to first one
::SetWindowText(firstWindow, txt);
// get scroll position of second window
SCROLLINFO si = { sizeof(SCROLLINFO) };
::GetScrollInfo(secondWindow, SB_VERT, &si);
// set scroll bar of first window accordingly
::SetScrollInfo(firstWindow, SB_VERT | SIF_PAGE | SIF_POS | SIF_RANGE, &si, TRUE );
// get first visible line in second window
int line = ::SendMessage(secondWindow, EM_GETFIRSTVISIBLELINE, 0, 0);
// skip to same line in first window
::SendMessage(firstWindow, EM_LINESCROLL, 0, line);
delete[] txt;

You could of course copy only a part of the text using EM_REPLACESEL, but you did not say how to find the new and old part, so I proposed to replace everything.

Serge Ballesta
  • 143,923
  • 11
  • 122
  • 252
  • That might update the scrollbar but I'd be surprised if it actually scrolled the content of the control. – Jonathan Potter Aug 03 '15 at 19:52
  • @JonathanPotter : I had forgotten an essential part. Post updated per your comment - and now tested :-) – Serge Ballesta Aug 03 '15 at 22:22
  • Ok, this works Serge Ballesta. But this do that user see that text was at start line and then is moved to correct line. So I try now to use EM_REPLACESEL. I do it after EN_UPDATE. How can I detect what was added? User can add text for example with ctrl-c + ctr+v or with paste option in dialog showed by right click. Is something effective than have saved old text before EN_UPDATE and compare changes with new text? – Jaro Kollár Aug 04 '15 at 06:45
  • @JaroKollár: As above code only uses `SendMessage` calls and no `PostMessage`, the window will not been repainted in the middle of the code. So **internally** the window is scrolled to first line and then to correct one, but the user cannot see that (if you execute it under a debugger, the window is frozen and not redisplayed). If it matters I execute this code in the EN_CHANGE notification processing ... If you want to know what changes you could try to take a copy at EN_UPDATE (notification before) and compare with what exists at EN_CHANGE (after). But IMHO just use full copy. – Serge Ballesta Aug 04 '15 at 06:55