You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WinForm中CefSharp控件在Microsoft Surface触摸场景下焦点异常问题求助

WinForm嵌入CefSharp在Surface触摸场景下无法输入的问题

问题描述

我在Microsoft Surface平板上使用触摸输入操作WinForm应用时遇到问题,已知WinForm原生不支持触摸输入,但希望找到可行的解决方法。我的WinForm应用窗体内包含两个控件:一个简单的列表框(List Box)和CefSharp ChromiumWebBrowser控件。
应用启动后HTML正常加载,使用普通鼠标操作时一切正常,点击文本框即可正常输入内容。但在Surface设备上使用触摸操作执行相同步骤时,ChromiumWebBrowser控件似乎无法获得焦点:浏览器内部的HTML文本框已被激活,但WinForm层面的ChromiumWebBrowser控件未获得焦点,因此输入时没有内容传递到文本框中。
我尝试通过WinForm的C#代码手动设置焦点,但触摸模式下除了Enter事件仅触发一次外,其余点击类事件都不会触发,目前没有可行的规避思路。
业务场景要求用户可以点击浏览器控件外的区域完成其他操作,之后返回浏览器即可正常在文本框中输入内容。
问题复现动图:问题复现动图

已有代码

private void Form1_Load(object sender, EventArgs e)
{
    var asForm = System.Windows.Automation.AutomationElement.FromHandle(this.Handle);

    wbMap = initBrowser();

    this.panel1.Enabled = true;
    this.panel1.Controls.Add(wbMap);

    wbMap.FrameLoadEnd += WbMap_FrameLoadEnd;
    wbMap.Click += WbMap_Click;
    wbMap.Enter += WbMap_Enter;
    wbMap.MouseClick += WbMap_MouseClick;
    wbMap.DoubleClick += WbMap_DoubleClick;
    wbMap.Leave += WbMap_Leave;
    wbMap.LostFocus += WbMap_LostFocus;
    wbMap.GotFocus += WbMap_GotFocus;
    wbMap.PreviewKeyDown += WbMap_PreviewKeyDown;
}

private ChromiumWebBrowser initBrowser()
{
    ChromiumWebBrowser wbMap = new ChromiumWebBrowser();

    BrowserSettings browserSettings = new BrowserSettings();
    browserSettings.FileAccessFromFileUrls = CefState.Enabled;
    browserSettings.UniversalAccessFromFileUrls = CefState.Enabled;
    wbMap.BrowserSettings = browserSettings;

    wbMap.LoadHtml("<!DOCTYPE html><html lang=\"en\" xmlns=\"http://www.w3.org/1999/xhtml\"><head><meta charset=\"utf-8\" /><title></title></head><body><input type=\"text\"><input /></body></html>");
    wbMap.Dock = DockStyle.Fill;

    return wbMap;
}

private void WbMap_FrameLoadEnd(object sender, FrameLoadEndEventArgs e)
{
    Console.WriteLine("QGIS_WbMap_FrameLoadEnd");
}

解决方案

1 全局开启CefSharp触摸支持

在应用入口Program.cs中初始化Cef时添加触摸相关配置,避免触摸事件被默认拦截:

[STAThread]
static void Main()
{
    CefSettings cefSettings = new CefSettings();
    // 显式开启触摸事件支持
    cefSettings.TouchEventsEnabled = CefState.Enabled;
    Cef.Initialize(cefSettings);
    
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);
    Application.Run(new Form1());
}

2 拦截系统触摸消息主动同步焦点

重写窗体的WndProc方法,直接监听系统级触摸消息,不需要依赖CefSharp控件暴露的点击类事件,只要触摸点落在浏览器控件范围内就主动同步焦点:

// 触摸系统消息ID
private const int WM_TOUCH = 0x0240;
protected override void WndProc(ref Message m)
{
    base.WndProc(ref m);
    if (m.Msg == WM_TOUCH)
    {
        // 解析触摸点屏幕坐标
        Point screenTouchPos = new Point(m.LParam.ToInt32());
        // 转换为窗体客户区坐标
        Point clientTouchPos = PointToClient(screenTouchPos);
        // 判断是否点击到浏览器控件区域
        if (wbMap.Bounds.Contains(clientTouchPos) && !wbMap.Focused)
        {
            // 先设置WinForm层面控件焦点
            wbMap.Focus();
            // 再同步设置Chromium内核层面的输入焦点
            if (wbMap.IsBrowserInitialized)
            {
                wbMap.GetBrowser().GetHost().SetFocus(true);
            }
        }
    }
}

以上方案兼容所有Win10/11版本的Surface设备,不会干扰浏览器外其他控件的操作逻辑,完全符合业务要求。如果使用的CefSharp版本低于75,只需要删掉内核焦点设置的代码即可正常运行。


内容的提问来源于stack exchange,提问作者semmelbrot

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 01:15:04