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> /// </summary>
internal class SmartScrollTextBox : TextBox internal class SmartScrollTextBox : TextBox
{ {
protected internal bool IsVerticalScrollBarAtBottom => private bool _scrolledProgrammatically;
string.IsNullOrEmpty(Text) || GetPositionFromCharIndex(Text.Length).Y < Height;
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 #region Custom Events
@ -76,7 +87,7 @@ namespace XenAdmin.Controls
#region Control Overrides #region Control Overrides
protected override void WndProc(ref Message m) protected override void WndProc(ref Message m)
{ {
if (OnScrollChange != null) if (OnScrollChange != null && !_scrolledProgrammatically)
{ {
int newPosition; int newPosition;
switch (m.Msg) switch (m.Msg)
@ -97,6 +108,12 @@ namespace XenAdmin.Controls
} }
} }
if (_scrolledProgrammatically)
{
_scrolledProgrammatically = false;
}
base.WndProc(ref m); base.WndProc(ref m);
} }

View File

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

View File

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