File: Interop\User32\GetWindowTextTests.cs
Web Access
Project: src\src\System.Windows.Forms.Primitives\tests\UnitTests\System.Windows.Forms.Primitives.Tests.csproj (System.Windows.Forms.Primitives.Tests)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
 
namespace System.Windows.Forms.Primitives.Tests.Interop.User32;
 
public class GetWindowTextTests
{
    [StaFact]
    public void GetWindowText_DoesNotTruncateText()
    {
        CallGetWindowText(useBeforeGetTextLengthCallback: false);
    }
 
    [StaFact]
    public void GetWindowText_DoesNotLoopInfinitely()
    {
        CallGetWindowText(useBeforeGetTextLengthCallback: true);
    }
 
    private void CallGetWindowText(bool useBeforeGetTextLengthCallback)
    {
        const string shortText = "A";
 
        // Use a long string that exceeds the initial buffer size (16).
        string longText = new('X', 50);
 
        ChangeWindowTextClass windowClass = new();
        windowClass.Register();
        HWND windowHandle = (HWND)windowClass.CreateWindow(shortText);
 
        windowClass.BeforeGetTextCallback = () => longText;
        if (useBeforeGetTextLengthCallback)
        {
            windowClass.BeforeGetTextLengthCallback = () => shortText;
        }
 
        string result = PInvoke.GetWindowText(windowHandle);
        PInvoke.DestroyWindow(windowHandle);
 
        Assert.Equal(longText, result);
    }
 
    private class ChangeWindowTextClass : WindowClass
    {
        public Func<string>? BeforeGetTextLengthCallback
        {
            get;
            set;
        }
 
        public Func<string>? BeforeGetTextCallback
        {
            get;
            set;
        }
 
        protected override LRESULT WNDPROC(HWND hWnd, MessageId msg, WPARAM wParam, LPARAM lParam)
        {
            switch (msg)
            {
                case PInvoke.WM_GETTEXTLENGTH:
                    string? text = BeforeGetTextLengthCallback?.Invoke();
                    if (text is not null)
                    {
                        PInvoke.SetWindowText(hWnd, text);
                    }
 
                    break;
                case PInvoke.WM_GETTEXT:
                    text = BeforeGetTextCallback?.Invoke();
                    if (text is not null)
                    {
                        PInvoke.SetWindowText(hWnd, text);
                    }
 
                    break;
            }
 
            return base.WNDPROC(hWnd, msg, wParam, lParam);
        }
    }
}