CA-293683: Prevent automatic scrolling when setting text in SmartScrollTextBox

Also fix issue whereby `IsVerticalScrollBarAtBottom` would also return `True`

Signed-off-by: Danilo Del Busso <Danilo.Del.Busso@citrix.com>
This commit is contained in:
Danilo Del Busso 2022-05-16 15:33:52 +01:00
parent 6b200bef8b
commit 4f09efe475
No known key found for this signature in database
GPG Key ID: 55F556F9A25CB037
3 changed files with 39 additions and 6 deletions

View File

@ -46,8 +46,19 @@ namespace XenAdmin.Controls
/// </summary>
internal class SmartScrollTextBox : TextBox
{
protected internal bool IsVerticalScrollBarAtBottom =>
string.IsNullOrEmpty(Text) || GetPositionFromCharIndex(Text.Length).Y < Height;
private bool _scrolledProgrammatically;
protected internal bool IsVerticalScrollBarAtBottom => GetPositionFromCharIndex(Text.Length - 1).Y < Height;
public void SetTextWithoutScrolling(string text)
{
var oldVerticalPosition = Win32.GetScrollBarPosition(Handle, Win32.ScrollBarConstants.SB_VERT);
Text = text;
Win32.SetScrollPos(Handle, (int)Win32.ScrollBarConstants.SB_VERT, oldVerticalPosition, true);
_scrolledProgrammatically = true;
Win32.PostMessageA(Handle, Win32.WM_VSCROLL, (int)Win32.ScrollBarCommands.SB_THUMBPOSITION + 0x10000 * oldVerticalPosition, 0);
}
#region Custom Events
@ -76,7 +87,7 @@ namespace XenAdmin.Controls
#region Control Overrides
protected override void WndProc(ref Message m)
{
if (OnScrollChange != null)
if (OnScrollChange != null && !_scrolledProgrammatically)
{
int newPosition;
switch (m.Msg)
@ -97,6 +108,12 @@ namespace XenAdmin.Controls
}
}
if (_scrolledProgrammatically)
{
_scrolledProgrammatically = false;
}
base.WndProc(ref m);
}

View File

@ -43,6 +43,7 @@ using System.Windows.Forms;
using XenAdmin.Diagnostics.Problems;
using XenAdmin.Dialogs;
using XenAdmin.Wizards.RollingUpgradeWizard.PlanActions;
using Console = System.Console;
namespace XenAdmin.Wizards.PatchingWizard
@ -316,11 +317,19 @@ namespace XenAdmin.Wizards.PatchingWizard
stringBuilder.Append(sb);
}
textBoxLog.Text = stringBuilder.ToString();
textBoxLog.SelectionStart = textBoxLog.Text.Length;
var newText = stringBuilder.ToString();
if (!_userMovedVerticalScrollbar)
{
textBoxLog.Text = newText;
textBoxLog.SelectionStart = textBoxLog.Text.Length;
textBoxLog.ScrollToCaret();
}
else
{
textBoxLog.SetTextWithoutScrolling(newText);
}
}
private void WorkerDoWork(object sender, DoWorkEventArgs doWorkEventArgs)
{

View File

@ -387,6 +387,9 @@ namespace XenCenterLib
public static extern bool EnumUILanguages(EnumUILanguagesProc pUILanguageEnumProc,
uint dwFlags, IntPtr lParam);
[DllImport("user32.dll")]
public static extern int SetScrollPos(IntPtr hWnd, int nBar, int nPos, bool bRedraw);
#region Window scrolling functions
/// <summary>
@ -499,6 +502,10 @@ namespace XenCenterLib
[DllImport("user32.dll", SetLastError = true)]
public static extern bool PostMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
[return: MarshalAs(UnmanagedType.Bool)]
[DllImport("user32.dll")]
public static extern bool PostMessageA(IntPtr hWnd, int nBar, int wParam, int lParam);
#region Disk space functions
/// <summary>