Unable to detected visibility of Onscreen keyboard using user32.dll

Shaik Rizwan 0 Reputation points
2024-12-10T10:27:49.5466667+00:00

Below code is always showing on screen keyboard as visible. Even if it is closed.

using System;
using System.Diagnostics;
using Microsoft.Win32;
using System.Runtime.InteropServices;
using System.Threading;

namespace CSharpTesting
{
    class Program
    {
        /// <summary>
        /// The window is disabled. See http://msdn.microsoft.com/en-gb/library/windows/desktop/ms632600(v=vs.85).aspx.
        /// </summary>
        public const UInt32 WS_DISABLED = 0x8000000;

        /// <summary>
        /// Specifies we wish to retrieve window styles.
        /// </summary>
        public const int GWL_STYLE = -16;

        [DllImport("user32.dll")]
        public static extern IntPtr FindWindow(String sClassName, String sAppName);

        [DllImport("user32.dll", SetLastError = true)]
        static extern UInt32 GetWindowLong(IntPtr hWnd, int nIndex);

        static void Main(string[] args)
        {
            // Crappy loop to poll window state.
            while (true)
            {
                if (IsKeyboardVisible())
                {
                    Console.WriteLine("keyboard is visible");
                }
                else
                {
                    Console.WriteLine("keyboard is NOT visible");
                }

                Thread.Sleep(1000);
            }
        }

        /// <summary>
        /// Gets the window handler for the virtual keyboard.
        /// </summary>
        /// <returns>The handle.</returns>
        public static IntPtr GetKeyboardWindowHandle()
        {
            return FindWindow("IPTip_Main_Window", null);
        }

        /// <summary>
        /// Checks to see if the virtual keyboard is visible.
        /// </summary>
        /// <returns>True if visible.</returns>
        public static bool IsKeyboardVisible()
        {
            IntPtr keyboardHandle = GetKeyboardWindowHandle();

            bool visible = false;

            if (keyboardHandle != IntPtr.Zero)
            {
                UInt32 style = GetWindowLong(keyboardHandle, GWL_STYLE);
                visible = ((style & WS_DISABLED) != WS_DISABLED);
            }

            return visible;
        }
    }
}

Windows Presentation Foundation
Windows Presentation Foundation
A part of the .NET Framework that provides a unified programming model for building line-of-business desktop applications on Windows.
2,804 questions
Windows API - Win32
Windows API - Win32
A core set of Windows application programming interfaces (APIs) for desktop and server applications. Previously known as Win32 API.
2,700 questions
C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
11,152 questions
{count} votes

2 answers

Sort by: Most helpful
  1. Castorix31 86,406 Reputation points
    2024-12-11T01:11:23.8566667+00:00

    If you're talking about OSK (Win + Ctrl + O), the class of the window is "OSKMainClass"

    (and to test if a window is visible is WS_VISIBLE style or IsWindowVisible, but when I close it on Windows 10, the window is destroyed)

    0 comments No comments

  2. Minxin Yu 12,341 Reputation points Microsoft Vendor
    2024-12-11T03:05:47.29+00:00

    Hi,

    You can use the solution :
    https://stackoverflow.com/a/24499623

    It works for me on Win11 24h2
    C++:

    #include <windows.h>
    #include<shobjidl_core.h>
    BOOL __cdecl IsVirtualKeyboardVisible()
    {
        BOOL    bRet = FALSE;
        RECT    InputPaneScreenLocation = { 0, 0, 0, 0 };
    
        __try
        {
            HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
    
            IFrameworkInputPane *IinputPane = NULL;
    
            if (SUCCEEDED(hr))
            {
                //
                // http://msdn.microsoft.com/en-us/library/windows/desktop/hh706967(v=vs.85).aspx
                //
                hr = CoCreateInstance(__uuidof(FrameworkInputPane), 0, CLSCTX_ALL, __uuidof(IFrameworkInputPane), (LPVOID*)&IinputPane);
                IinputPane->Location(&InputPaneScreenLocation);
    
                if (InputPaneScreenLocation.bottom == 0 && InputPaneScreenLocation.left == 0 &&
                    InputPaneScreenLocation.right == 0 && InputPaneScreenLocation.top == 0)
                {
                    // VKB is not visible
                    bRet = FALSE;
                }
                else
                {
                    // VKB is visible
                    bRet = TRUE;
                } 
            }
    
        }   // try
        __finally
        {
            CoUninitialize();
        }
    
        return bRet;
    }
    

    Best regards,

    Minxin Yu


    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.


Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.