пользовательский интерфейс — c ++ winapi: переместить полосу прокрутки после WM_SETTEXT в старое положение

У меня такая ситуация. У меня есть два многострочных поля ввода. Первый не редактируется, а второй да. Я ловлю сообщение EN_UPDATE, и когда появляется, я отправляю обновленный текст из второго окна в первое окно. Таким образом, оба окна имеют одинаковый текст. Также Если прокручивается один, прокручивается также и второй (зеркальное поведение).

Проблема в том, что если я обновляю текст в первом окне после отправки нового текста из второго окна, тогда полоса прокрутки перемещается в начале. Если я использую SetScrollPos, то устанавливается полоса прокрутки, но текст не перемещается в правильное положение. Я вижу первую строку текста и хочу увидеть позицию перед обновлением текста. Как это возможно?

Обновить

Я хочу, чтобы после SendMessage к первому окну, как это, чтобы не перемещать окно в начальную позицию текста при замене старого текста новым текстом. Так как у меня, например, первое окно прокручивается посередине и после замены текста это первое окно перемещается в первую строку нового текста, но я хочу остаться в старой позиции, потому что я обновляю только текст в письме во втором окне, а затем отправьте это изменение в firstWindow. Но я пересылаю весь текст.

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

Я создаю многострочное текстовое поле следующим образом:

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);

Обновление 2

Я пытаюсь это:

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);

Итак, у меня есть текст в первом окне, и где находится позиция во втором окне, я добавляю новое письмо в эту позицию. Но это добавляет одну букву к правильной позиции, но это не добавляет ни одной буквы, но все же добавляет aaaaaaaaaaaaaaaa. Почему это происходит?

Я могу использовать только чистый с ++ и winapi.

Благодарю.

0

Решение

Если вы хотите последовательно копировать весь текст из второго поля редактирования в первое и убедиться, что позиция прокрутки правильно отражена, вы можете просто использовать:

// 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;

Конечно, вы можете скопировать только часть текста, используя EM_REPLACESEL, но вы не сказали, как найти новую и старую часть, поэтому я предложил заменить все.

0

Другие решения