// ============================================================ // 文档区停靠窗口:PDF 扒图工作区 // = 独立 pdfbt.exe 主窗口的完整布局原样搬入: // 左 报价工具(PdfQuoteWindow,内嵌 Form3 报价三表) // 中 PDF 查看器(PdfViewerWindow,pdfium+OCR 框选扒图) // 内部用 Smart DockSurface 承载;F1/F2/F3 全局消息过滤器随窗口启停 // (焦点在 Form3 树内时跳过,由 Form3.ProcessCmdKey 处理,防双跑); // Umi-OCR 预热与独立版一致(已装本体且引擎为 umi 时打开即静默拉起)。 // ============================================================ using System; using System.IO; using System.Windows.Forms; namespace 成套报价软件 { /// PDF 扒图工作区(DockState.Document):报价三表 + PDF 查看器。 public class Pdf扒图窗口 : WeifenLuo.WinFormsUI.Docking.DockContent { private readonly F1MessageFilter _f1Filter = new F1MessageFilter(); private PdfQuoteWindow _quote; private PdfViewerWindow _viewer; /// 内嵌的报价界面(主窗口功能区按钮跨窗口调用用;未创建为 null)。 public MyAppPdf.Form3 报价表单 { get { return _quote != null ? _quote.报价表单 : null; } } public Pdf扒图窗口() { Text = "PDF扒图"; TabText = "PDF扒图"; this.BackColor = System.Drawing.Color.White; // 与独立版 MainForm.CreateDockWindows_dockSurface1 相同的内部结构 var dockSurface = new Smart.CustomComponents.DockSurface(); dockSurface.Dock = DockStyle.Fill; Controls.Add(dockSurface); dockSurface.EnsureDefaultTheme(); // 必须:Show 前保证有效主题 _quote = new PdfQuoteWindow(); _quote.CloseButtonVisible = false; _quote.TabText = "报价工具"; _quote.Text = "报价工具"; _quote.Show(dockSurface, WeifenLuo.WinFormsUI.Docking.DockState.DockLeft); _viewer = new PdfViewerWindow(); _viewer.CloseButtonVisible = false; _viewer.TabText = "PDF 查看器"; _viewer.Text = "PDF 查看器"; _viewer.Show(dockSurface, WeifenLuo.WinFormsUI.Docking.DockState.Document); // ★ 全局 F1/F2/F3 过滤器:焦点在任何 WinForms 控件上都触发元件合并 Application.AddMessageFilter(_f1Filter); FormClosed += (s, e) => { Application.RemoveMessageFilter(_f1Filter); // 显式关内部窗口:Form3 解绑桥事件、查看器停由本程序启动的 Umi-OCR try { if (_quote != null && !_quote.IsDisposed) _quote.Close(); } catch { } try { if (_viewer != null && !_viewer.IsDisposed) _viewer.Close(); } catch { } }; // ★ Umi-OCR 预热(独立版 MainForm 同款):已装本体且当前引擎为 umi 时, // 打开本工作区就静默拉起(--hide 托盘),不等首次框选;后台线程跑不拖慢窗口 System.Threading.ThreadPool.QueueUserWorkItem(_ => { try { string cfg = OcrPaths.ConfigPath; if (File.Exists(cfg)) { var jsv = new System.Web.Script.Serialization.JavaScriptSerializer() .Deserialize>( File.ReadAllText(cfg)); string eng = jsv != null && jsv.ContainsKey("engine") ? jsv["engine"] : "baidu"; if (eng == "umi" && UmiOcrHost.IsInstalled) UmiOcrLauncher.EnsureRunning(); } } catch { } }); } /// /// 把 F1/F2/F3 按键(0x70/0x71/0x72)转成 PdfBridge 事件。 /// ★ 焦点在报价插件(Form3)树内时不触发——那条路径由 Form3.ProcessCmdKey /// 处理,此处再触发会双跑一次(F1 合并两遍:第一遍成功、第二遍弹 /// "请先选中至少2行"的误提示)。 /// private class F1MessageFilter : IMessageFilter { public bool PreFilterMessage(ref Message m) { const int WM_KEYDOWN = 0x0100; bool isFKey = m.Msg == WM_KEYDOWN && ((int)m.WParam == 0x70 || (int)m.WParam == 0x71 || (int)m.WParam == 0x72); if (!isFKey) return false; // 焦点控件在 Form3 树内 → 交给 Form3.ProcessCmdKey,跳过 try { var focused = Control.FromHandle(m.HWnd); for (var c = focused; c != null; c = c.Parent) { if (c is MyAppPdf.Form3) return false; } } catch { } int key = (int)m.WParam; try { if (key == 0x70) PdfBridge.RaiseF1(); else if (key == 0x71) PdfBridge.RaiseF2(); else if (key == 0x72) PdfBridge.RaiseF3(); } catch { } return false; } } } }