【问题标题】:How can I get a URL entered into WinForms OpenFileDialog?如何获取输入 WinForms OpenFileDialog 的 URL?
【发布时间】:2015-09-21 02:18:15
【问题描述】:

如果用户在 Windows 窗体 OpenFileDialog 中输入 URL,则 Windows 的对话框(在更现代的版本上)将下载文件并从临时目录中打开它。有什么方法可以访问输入的 URL?新奇的 IFileDialog 有帮助吗?

请注意,我不是在寻找本地文件的 file:// 等效项。这是用于当用户在文件对话框中输入 Internet 上某物的位置时。例如http://example.com/path.

This 提出了基本相同的问题,但没有得到有用的答案,可能是因为他要求结果出现在 FileName 属性中。

【问题讨论】:

  • 您能否添加有关“Windows 将下载文件并从临时目录打开它”的源链接?看起来像是在某些应用程序中实现的行为,而不是操作系统/框架功能。另外,你试过FileName 属性吗?
  • @CodingFeles,这是我在 Windows 10 计算机上使用我自己的应用程序时观察到的,但它不会在我的 Windows 7 计算机上发生。 FileName 属性包含文件已下载到的临时路径。

标签: c# winforms


【解决方案1】:

可以设置一个窗口挂钩来监听文本变化。此代码当前从所有字段中获取值更改,因此您需要弄清楚如何仅检测 ComboBox 文件名字段。

    public class MyForm3 : Form {

        public MyForm3() {
            Button btn = new Button { Text = "Button" };
            Controls.Add(btn);
            btn.Click += btn_Click;
        }

        [DllImport("user32.dll", SetLastError = true)]
        private static extern IntPtr SetWinEventHook(uint eventMin, uint eventMax, IntPtr hmodWinEventProc, WinEventProc lpfnWinEventProc, uint idProcess, uint idThread, uint dwFlags);
        [DllImport("user32.dll")]
        private static extern bool UnhookWinEvent(IntPtr hWinEventHook);
        [DllImport("user32.dll")]
        private static extern int GetWindowText(IntPtr hWnd, StringBuilder text, int count);
        [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
        private static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);    
        [DllImport("user32.dll", SetLastError = true)]
        private static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);


        private const int WINEVENT_OUTOFCONTEXT = 0;
        private const uint EVENT_OBJECT_VALUECHANGE = 0x800E;

        void btn_Click(object sender, EventArgs e) {
            uint pid = 0;
            uint tid = 0; 
            using (var p = Process.GetCurrentProcess())
                GetWindowThreadProcessId(p.MainWindowHandle, out pid);

            var hHook = SetWinEventHook(EVENT_OBJECT_VALUECHANGE, EVENT_OBJECT_VALUECHANGE, IntPtr.Zero, CallWinEventProc, pid, tid, WINEVENT_OUTOFCONTEXT);

            OpenFileDialog d = new OpenFileDialog();
            d.ShowDialog();
            d.Dispose();
            UnhookWinEvent(hHook);

            MessageBox.Show("Original filename: " + OpenFilenameText);
        }

        private static String OpenFilenameText = "";
        private static WinEventProc CallWinEventProc = new WinEventProc(EventCallback);
        private delegate void WinEventProc(IntPtr hWinEventHook, int iEvent, IntPtr hWnd, int idObject, int idChild, int dwEventThread, int dwmsEventTime);
        private static void EventCallback(IntPtr hWinEventHook, int iEvent, IntPtr hWnd, int idObject, int idChild, int dwEventThread, int dwmsEventTime) {
            StringBuilder sb1 = new StringBuilder(256);
            GetClassName(hWnd, sb1, sb1.Capacity);
            if (sb1.ToString() == "Edit") {
                StringBuilder sb = new StringBuilder(512);
                GetWindowText(hWnd, sb, sb.Capacity);
                OpenFilenameText = sb.ToString();
            }
        }
    }

【讨论】:

    【解决方案2】:

    如果您只想获取 URL(而不是下载文件),请将 CheckFileExists 标志设置为 false。 下面的示例代码

            string urlName = null;
            using (var dlg = new OpenFileDialog())
            {
                dlg.CheckFileExists = false;
    
                dlg.ShowDialog();
                urlName = dlg.FileName;
                urlName = Path.GetFileName(urlName);
    
            }
    

    【讨论】:

    • 这在某种意义上是可行的,但它使对话框无法用于选择文件,这是它的主要目的,因为它不会对文件名进行任何验证。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-10-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多