首页 \ 问答 \ 在Asp.net获取经纬度的经纬度?(Get latitude and longitude of address in Asp.net?)

在Asp.net获取经纬度的经纬度?(Get latitude and longitude of address in Asp.net?)

如何在asp.net MVC4中获取某个位置的经纬度?

例如,我如何获得哈菲兹中心,拉合尔,旁遮普邦,巴基斯坦的经度和纬度?


How can I get a latitude and longitude of some location in asp.net MVC4?

For example how can I get the latitude and longitude of Hafeez center, Lahore, Punjab, Pakistan?


原文:https://stackoverflow.com/questions/21112397
更新时间:2023-11-11 14:11

最满意答案

以下是一些使用.Net Automation库将所有文本复制到剪贴板的代码。

启动一个新的WinForms项目,然后添加以下引用:

  • WindowsBase
  • UIAutomationTypes
  • UIAutomationClient
  • System.Xaml
  • PresentationCore
  • PresentationFramework
  • 系统管理

该代码还介绍了如何在Visual Studio中设置菜单项以将内容复制到剪贴板。

编辑: UI自动化只返回可见的树形视图项目。 因此,要复制所有项目,将查找符号结果窗口设置为前景,然后发送{PGDN} ,并复制下一批项目。 重复此过程直到找不到新项目。 最好是使用ScrollPattern ,但是当试图设置滚动时它会抛出Exception

编辑2:试图通过在单独的线程上运行来改进AutomationElement FindAll的性能。 在某些情况下似乎很慢。

编辑3:通过使TreeView窗口非常大来提高性能。 可以在大约10秒钟内复制约400件物品。

编辑4:处理实现IDisposable对象。 更好的消息报告。 更好地处理流程参数。 把窗户放回原来的大小。

在这里输入图像描述

using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Management;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Windows.Automation;
using System.Windows.Forms;

namespace CopyFindSymbolResults {

// This program tries to find the 'Find Symbol Results' window in visual studio
// and copy all the text to the clipboard.
//
// The Find Symbol Results window uses a TreeView control that has the class name 'LiteTreeView32'
// In the future if this changes, then it's possible to pass in the class name as the first argument.
// Use TOOLS -> Spy++ to determine the class name.
//
// After compiling this code into an Exe, add a menu item (TOOLS -> Copy Find Symbol Results) in Visual Studio by:
// 1) TOOLS -> External Tools...
//      (Note: in the 'Menu contents:' list, count which item the new item is, starting at base-1).
//      Title: Copy Find Symbol Results
//      Command: C:\<Path>\CopyFindSymbolResults.exe             (e.g. C:\Windows\ is one option)
// 2) TOOLS -> Customize... -> Keyboard... (button)
//      Show Commands Containing: tools.externalcommand
//      Then select the n'th one, where n is the count from step 1).
//
static class Program {

    enum Tabify {
        No = 0,
        Yes = 1,
        Prompt = 2,
    }

    [STAThread]
    static void Main(String[] args) {

        String className = "LiteTreeView32";
        Tabify tabify = Tabify.Prompt;

        if (args.Length > 0) {
            String arg0 = args[0].Trim();
            if (arg0.Length > 0)
                className = arg0;

            if (args.Length > 1) {
                int x = 0;
                if (int.TryParse(args[1], out x))
                    tabify = (Tabify) x;
            }
        }

        DateTime startTime = DateTime.Now;
        Data data = new Data() { className = className };

        Thread t = new Thread((o) => {
            GetText((Data) o);
        });
        t.IsBackground = true;
        t.Start(data);

        lock(data) {
            Monitor.Wait(data);
        }

        if (data.p == null || data.p.MainWindowHandle == IntPtr.Zero) {
            System.Windows.Forms.MessageBox.Show("Cannot find Microsoft Visual Studio process.");
            return;
        }

        try {

        SimpleWindow owner = new SimpleWindow { Handle = data.MainWindowHandle };

        if (data.appRoot == null) {
            System.Windows.Forms.MessageBox.Show(owner, "Cannot find AutomationElement from process MainWindowHandle: " + data.MainWindowHandle);
            return;
        }

        if (data.treeViewNotFound) {
            System.Windows.Forms.MessageBox.Show(owner, "AutomationElement cannot find the tree view window with class name: " + data.className);
            return;
        }

        String text = data.text;
        if (text.Length == 0) { // otherwise Clipboard.SetText throws exception
            System.Windows.Forms.MessageBox.Show(owner, "No text was found: " + data.p.MainWindowTitle);
            return;
        }

        TimeSpan ts = DateTime.Now - startTime;

        if (tabify == Tabify.Prompt) {
            var dr = System.Windows.Forms.MessageBox.Show(owner, "Replace dashes and colons for easy pasting into Excel?", "Tabify", System.Windows.Forms.MessageBoxButtons.YesNo);
            if (dr == System.Windows.Forms.DialogResult.Yes)
                tabify = Tabify.Yes;

            ts = TimeSpan.Zero; // prevent second prompt
        }

        if (tabify == Tabify.Yes) {
            text = text.Replace(" - ", "\t");
            text = text.Replace(" : ", "\t");
        }

        System.Windows.Forms.Clipboard.SetText(text);

        String msg = "Data is ready on the clipboard.";
        var icon = System.Windows.Forms.MessageBoxIcon.None;

        if (data.lines != data.count) {
            msg = String.Format("Only {0} of {1} rows copied.", data.lines, data.count);
            icon = System.Windows.Forms.MessageBoxIcon.Error;
        }

        if (ts.TotalSeconds > 4 || data.lines != data.count)
            System.Windows.Forms.MessageBox.Show(owner, msg, "", System.Windows.Forms.MessageBoxButtons.OK, icon);

        } finally {
            data.p.Dispose();
        }
    }

    private class SimpleWindow : System.Windows.Forms.IWin32Window {
        public IntPtr Handle { get; set; }
    }

    private const int TVM_GETCOUNT = 0x1100 + 5;

    [DllImport("user32.dll")]
    static extern int SendMessage(IntPtr hWnd, int msg, int wparam, int lparam);

    [DllImport("user32.dll", SetLastError = true)]
    static extern bool MoveWindow(IntPtr hWnd, int X, int Y, int Width, int Height, bool Repaint);

    private class Data {
        public int lines = 0;
        public int count = 0;
        public IntPtr MainWindowHandle = IntPtr.Zero;
        public IntPtr TreeViewHandle = IntPtr.Zero;
        public Process p;
        public AutomationElement appRoot = null;
        public String text = null;
        public String className = null;
        public bool treeViewNotFound = false;
    }

    private static void GetText(Data data) {
        Process p = GetParentProcess();
        data.p = p;

        if (p == null || p.MainWindowHandle == IntPtr.Zero) {
            data.text = "";
            lock(data) { Monitor.Pulse(data); }
            return;
        }

        data.MainWindowHandle = p.MainWindowHandle;
        AutomationElement appRoot = AutomationElement.FromHandle(p.MainWindowHandle);
        data.appRoot = appRoot;

        if (appRoot == null) {
            data.text = "";
            lock(data) { Monitor.Pulse(data); }
            return;
        }

        AutomationElement treeView = appRoot.FindFirst(TreeScope.Subtree, new PropertyCondition(AutomationElement.ClassNameProperty, data.className));
        if (treeView == null) {
            data.text = "";
            data.treeViewNotFound = true;
            lock(data) { Monitor.Pulse(data); }
            return;
        }

        data.TreeViewHandle = new IntPtr(treeView.Current.NativeWindowHandle);
        data.count = SendMessage(data.TreeViewHandle, TVM_GETCOUNT, 0, 0);

        RECT rect = new RECT();
        GetWindowRect(data.TreeViewHandle, out rect);

        // making the window really large makes it so less calls to FindAll are required
        MoveWindow(data.TreeViewHandle, 0, 0, 800, 32767, false);
        int TV_FIRST = 0x1100;
        int TVM_SELECTITEM = (TV_FIRST + 11);
        int TVGN_CARET = TVGN_CARET = 0x9;

        // if a vertical scrollbar is detected, then scroll to the top sending a TVM_SELECTITEM command
        var vbar = treeView.FindFirst(TreeScope.Subtree, new PropertyCondition(AutomationElement.NameProperty, "Vertical Scroll Bar"));
        if (vbar != null) {
            SendMessage(data.TreeViewHandle, TVM_SELECTITEM, TVGN_CARET, 0); // select the first item
        }

        StringBuilder sb = new StringBuilder();
        Hashtable ht = new Hashtable();

        int chunk = 0;
        while (true) {
            bool foundNew = false;

            AutomationElementCollection treeViewItems = treeView.FindAll(TreeScope.Subtree, new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.TreeItem));
            if (treeViewItems.Count == 0)
                break;

            if (ht.Count == 0) {
                chunk = treeViewItems.Count - 1;
            }

            foreach (AutomationElement ele in treeViewItems) {
                try {
                    String n = ele.Current.Name;
                    if (!ht.ContainsKey(n)) {
                        ht[n] = n;
                        foundNew = true;
                        data.lines++;
                        sb.AppendLine(n);
                    }
                } catch {}
            }

            if (!foundNew || data.lines == data.count)
                break;

            int x = Math.Min(data.count-1, data.lines + chunk);
            SendMessage(data.TreeViewHandle, TVM_SELECTITEM, TVGN_CARET, x);
        }

        data.text = sb.ToString();
        MoveWindow(data.TreeViewHandle, rect.Left, rect.Top, rect.Right - rect.Left, rect.Bottom - rect.Top, false);
        lock(data) { Monitor.Pulse(data); }
    }

    // this program expects to be launched from Visual Studio
    // alternative approach is to look for "Microsoft Visual Studio" in main window title
    // but there could be multiple instances running.
    private static Process GetParentProcess() {
        // from thread: http://stackoverflow.com/questions/2531837/how-can-i-get-the-pid-of-the-parent-process-of-my-application
        int myId = 0;
        using (Process current = Process.GetCurrentProcess())
            myId = current.Id;
        String query = String.Format("SELECT ParentProcessId FROM Win32_Process WHERE ProcessId = {0}", myId);
        using (var search = new ManagementObjectSearcher("root\\CIMV2", query)) {
            using (ManagementObjectCollection list = search.Get()) {
                using (ManagementObjectCollection.ManagementObjectEnumerator results = list.GetEnumerator()) {
                    if (!results.MoveNext()) return null;
                    using (var queryObj = results.Current) {
                        uint parentId = (uint) queryObj["ParentProcessId"];
                        return Process.GetProcessById((int) parentId);
                    }
                }
            }
        }
    }

    [DllImport("user32.dll")]
    private static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect);

    [StructLayout(LayoutKind.Sequential)]
    private struct RECT {
        public int Left;
        public int Top;
        public int Right;
        public int Bottom;
    }
}
}

Here is some code that uses the .Net Automation library to copy all the text to the clipboard.

Start a new WinForms project and then add the following references:

  • WindowsBase
  • UIAutomationTypes
  • UIAutomationClient
  • System.Xaml
  • PresentationCore
  • PresentationFramework
  • System.Management

The code also explains how to setup a menu item in visual studio to copy the contents to the clipboard.

Edit: The UI Automation only returns visible tree view items. Thus, to copy all the items, the find symbol results window is set as foreground, and then a {PGDN} is sent, and the next batch of items is copied. This process is repeated until no new items are found. It would have been preferable to use the ScrollPattern, however it threw an Exception when trying to set the scroll.

Edit 2: Tried to improve the performance of AutomationElement FindAll by running on a separate thread. Seems to be slow in some cases.

Edit 3: Improved performance by making the TreeView window very large. Can copy about 400 items in about 10 seconds.

Edit 4: Dispose objects implementing IDisposable. Better message reporting. Better handling of process args. Put window back to its original size.

enter image description here

using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Management;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Windows.Automation;
using System.Windows.Forms;

namespace CopyFindSymbolResults {

// This program tries to find the 'Find Symbol Results' window in visual studio
// and copy all the text to the clipboard.
//
// The Find Symbol Results window uses a TreeView control that has the class name 'LiteTreeView32'
// In the future if this changes, then it's possible to pass in the class name as the first argument.
// Use TOOLS -> Spy++ to determine the class name.
//
// After compiling this code into an Exe, add a menu item (TOOLS -> Copy Find Symbol Results) in Visual Studio by:
// 1) TOOLS -> External Tools...
//      (Note: in the 'Menu contents:' list, count which item the new item is, starting at base-1).
//      Title: Copy Find Symbol Results
//      Command: C:\<Path>\CopyFindSymbolResults.exe             (e.g. C:\Windows\ is one option)
// 2) TOOLS -> Customize... -> Keyboard... (button)
//      Show Commands Containing: tools.externalcommand
//      Then select the n'th one, where n is the count from step 1).
//
static class Program {

    enum Tabify {
        No = 0,
        Yes = 1,
        Prompt = 2,
    }

    [STAThread]
    static void Main(String[] args) {

        String className = "LiteTreeView32";
        Tabify tabify = Tabify.Prompt;

        if (args.Length > 0) {
            String arg0 = args[0].Trim();
            if (arg0.Length > 0)
                className = arg0;

            if (args.Length > 1) {
                int x = 0;
                if (int.TryParse(args[1], out x))
                    tabify = (Tabify) x;
            }
        }

        DateTime startTime = DateTime.Now;
        Data data = new Data() { className = className };

        Thread t = new Thread((o) => {
            GetText((Data) o);
        });
        t.IsBackground = true;
        t.Start(data);

        lock(data) {
            Monitor.Wait(data);
        }

        if (data.p == null || data.p.MainWindowHandle == IntPtr.Zero) {
            System.Windows.Forms.MessageBox.Show("Cannot find Microsoft Visual Studio process.");
            return;
        }

        try {

        SimpleWindow owner = new SimpleWindow { Handle = data.MainWindowHandle };

        if (data.appRoot == null) {
            System.Windows.Forms.MessageBox.Show(owner, "Cannot find AutomationElement from process MainWindowHandle: " + data.MainWindowHandle);
            return;
        }

        if (data.treeViewNotFound) {
            System.Windows.Forms.MessageBox.Show(owner, "AutomationElement cannot find the tree view window with class name: " + data.className);
            return;
        }

        String text = data.text;
        if (text.Length == 0) { // otherwise Clipboard.SetText throws exception
            System.Windows.Forms.MessageBox.Show(owner, "No text was found: " + data.p.MainWindowTitle);
            return;
        }

        TimeSpan ts = DateTime.Now - startTime;

        if (tabify == Tabify.Prompt) {
            var dr = System.Windows.Forms.MessageBox.Show(owner, "Replace dashes and colons for easy pasting into Excel?", "Tabify", System.Windows.Forms.MessageBoxButtons.YesNo);
            if (dr == System.Windows.Forms.DialogResult.Yes)
                tabify = Tabify.Yes;

            ts = TimeSpan.Zero; // prevent second prompt
        }

        if (tabify == Tabify.Yes) {
            text = text.Replace(" - ", "\t");
            text = text.Replace(" : ", "\t");
        }

        System.Windows.Forms.Clipboard.SetText(text);

        String msg = "Data is ready on the clipboard.";
        var icon = System.Windows.Forms.MessageBoxIcon.None;

        if (data.lines != data.count) {
            msg = String.Format("Only {0} of {1} rows copied.", data.lines, data.count);
            icon = System.Windows.Forms.MessageBoxIcon.Error;
        }

        if (ts.TotalSeconds > 4 || data.lines != data.count)
            System.Windows.Forms.MessageBox.Show(owner, msg, "", System.Windows.Forms.MessageBoxButtons.OK, icon);

        } finally {
            data.p.Dispose();
        }
    }

    private class SimpleWindow : System.Windows.Forms.IWin32Window {
        public IntPtr Handle { get; set; }
    }

    private const int TVM_GETCOUNT = 0x1100 + 5;

    [DllImport("user32.dll")]
    static extern int SendMessage(IntPtr hWnd, int msg, int wparam, int lparam);

    [DllImport("user32.dll", SetLastError = true)]
    static extern bool MoveWindow(IntPtr hWnd, int X, int Y, int Width, int Height, bool Repaint);

    private class Data {
        public int lines = 0;
        public int count = 0;
        public IntPtr MainWindowHandle = IntPtr.Zero;
        public IntPtr TreeViewHandle = IntPtr.Zero;
        public Process p;
        public AutomationElement appRoot = null;
        public String text = null;
        public String className = null;
        public bool treeViewNotFound = false;
    }

    private static void GetText(Data data) {
        Process p = GetParentProcess();
        data.p = p;

        if (p == null || p.MainWindowHandle == IntPtr.Zero) {
            data.text = "";
            lock(data) { Monitor.Pulse(data); }
            return;
        }

        data.MainWindowHandle = p.MainWindowHandle;
        AutomationElement appRoot = AutomationElement.FromHandle(p.MainWindowHandle);
        data.appRoot = appRoot;

        if (appRoot == null) {
            data.text = "";
            lock(data) { Monitor.Pulse(data); }
            return;
        }

        AutomationElement treeView = appRoot.FindFirst(TreeScope.Subtree, new PropertyCondition(AutomationElement.ClassNameProperty, data.className));
        if (treeView == null) {
            data.text = "";
            data.treeViewNotFound = true;
            lock(data) { Monitor.Pulse(data); }
            return;
        }

        data.TreeViewHandle = new IntPtr(treeView.Current.NativeWindowHandle);
        data.count = SendMessage(data.TreeViewHandle, TVM_GETCOUNT, 0, 0);

        RECT rect = new RECT();
        GetWindowRect(data.TreeViewHandle, out rect);

        // making the window really large makes it so less calls to FindAll are required
        MoveWindow(data.TreeViewHandle, 0, 0, 800, 32767, false);
        int TV_FIRST = 0x1100;
        int TVM_SELECTITEM = (TV_FIRST + 11);
        int TVGN_CARET = TVGN_CARET = 0x9;

        // if a vertical scrollbar is detected, then scroll to the top sending a TVM_SELECTITEM command
        var vbar = treeView.FindFirst(TreeScope.Subtree, new PropertyCondition(AutomationElement.NameProperty, "Vertical Scroll Bar"));
        if (vbar != null) {
            SendMessage(data.TreeViewHandle, TVM_SELECTITEM, TVGN_CARET, 0); // select the first item
        }

        StringBuilder sb = new StringBuilder();
        Hashtable ht = new Hashtable();

        int chunk = 0;
        while (true) {
            bool foundNew = false;

            AutomationElementCollection treeViewItems = treeView.FindAll(TreeScope.Subtree, new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.TreeItem));
            if (treeViewItems.Count == 0)
                break;

            if (ht.Count == 0) {
                chunk = treeViewItems.Count - 1;
            }

            foreach (AutomationElement ele in treeViewItems) {
                try {
                    String n = ele.Current.Name;
                    if (!ht.ContainsKey(n)) {
                        ht[n] = n;
                        foundNew = true;
                        data.lines++;
                        sb.AppendLine(n);
                    }
                } catch {}
            }

            if (!foundNew || data.lines == data.count)
                break;

            int x = Math.Min(data.count-1, data.lines + chunk);
            SendMessage(data.TreeViewHandle, TVM_SELECTITEM, TVGN_CARET, x);
        }

        data.text = sb.ToString();
        MoveWindow(data.TreeViewHandle, rect.Left, rect.Top, rect.Right - rect.Left, rect.Bottom - rect.Top, false);
        lock(data) { Monitor.Pulse(data); }
    }

    // this program expects to be launched from Visual Studio
    // alternative approach is to look for "Microsoft Visual Studio" in main window title
    // but there could be multiple instances running.
    private static Process GetParentProcess() {
        // from thread: http://stackoverflow.com/questions/2531837/how-can-i-get-the-pid-of-the-parent-process-of-my-application
        int myId = 0;
        using (Process current = Process.GetCurrentProcess())
            myId = current.Id;
        String query = String.Format("SELECT ParentProcessId FROM Win32_Process WHERE ProcessId = {0}", myId);
        using (var search = new ManagementObjectSearcher("root\\CIMV2", query)) {
            using (ManagementObjectCollection list = search.Get()) {
                using (ManagementObjectCollection.ManagementObjectEnumerator results = list.GetEnumerator()) {
                    if (!results.MoveNext()) return null;
                    using (var queryObj = results.Current) {
                        uint parentId = (uint) queryObj["ParentProcessId"];
                        return Process.GetProcessById((int) parentId);
                    }
                }
            }
        }
    }

    [DllImport("user32.dll")]
    private static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect);

    [StructLayout(LayoutKind.Sequential)]
    private struct RECT {
        public int Left;
        public int Top;
        public int Right;
        public int Bottom;
    }
}
}

相关问答

更多

相关文章

更多

最新问答

更多
  • 获取MVC 4使用的DisplayMode后缀(Get the DisplayMode Suffix being used by MVC 4)
  • 如何通过引用返回对象?(How is returning an object by reference possible?)
  • 矩阵如何存储在内存中?(How are matrices stored in memory?)
  • 每个请求的Java新会话?(Java New Session For Each Request?)
  • css:浮动div中重叠的标题h1(css: overlapping headlines h1 in floated divs)
  • 无论图像如何,Caffe预测同一类(Caffe predicts same class regardless of image)
  • xcode语法颜色编码解释?(xcode syntax color coding explained?)
  • 在Access 2010 Runtime中使用Office 2000校对工具(Use Office 2000 proofing tools in Access 2010 Runtime)
  • 从单独的Web主机将图像传输到服务器上(Getting images onto server from separate web host)
  • 从旧版本复制文件并保留它们(旧/新版本)(Copy a file from old revision and keep both of them (old / new revision))
  • 西安哪有PLC可控制编程的培训
  • 在Entity Framework中选择基类(Select base class in Entity Framework)
  • 在Android中出现错误“数据集和渲染器应该不为null,并且应该具有相同数量的系列”(Error “Dataset and renderer should be not null and should have the same number of series” in Android)
  • 电脑二级VF有什么用
  • Datamapper Ruby如何添加Hook方法(Datamapper Ruby How to add Hook Method)
  • 金华英语角.
  • 手机软件如何制作
  • 用于Android webview中图像保存的上下文菜单(Context Menu for Image Saving in an Android webview)
  • 注意:未定义的偏移量:PHP(Notice: Undefined offset: PHP)
  • 如何读R中的大数据集[复制](How to read large dataset in R [duplicate])
  • Unity 5 Heighmap与地形宽度/地形长度的分辨率关系?(Unity 5 Heighmap Resolution relationship to terrain width / terrain length?)
  • 如何通知PipedOutputStream线程写入最后一个字节的PipedInputStream线程?(How to notify PipedInputStream thread that PipedOutputStream thread has written last byte?)
  • python的访问器方法有哪些
  • DeviceNetworkInformation:哪个是哪个?(DeviceNetworkInformation: Which is which?)
  • 在Ruby中对组合进行排序(Sorting a combination in Ruby)
  • 网站开发的流程?
  • 使用Zend Framework 2中的JOIN sql检索数据(Retrieve data using JOIN sql in Zend Framework 2)
  • 条带格式类型格式模式编号无法正常工作(Stripes format type format pattern number not working properly)
  • 透明度错误IE11(Transparency bug IE11)
  • linux的基本操作命令。。。