tags:

views:

107

answers:

2

Dear all,

i've developed a simple application (.dll) in LABVIEW and i implorted that dll to a C# windows application(Winforms) . Like

    [DllImport(@".\sample.dll")]
    public static extern void MyFunc(char[] a, StringBuilder b ,Int32 c); 

so when i call the function MyFunc a window will be popped up( the Lab View window( Front panel of my labview application

Window

i need to get the window name (ExpectedFuncName) in my C# application. i.e i need to get the name of the external window which is opend by my C# application. Can we use FileVersionInfo or assembly loader to get the name?

Is there any idea to do this? Thanks in advance.

+3  A: 

If you have the window handle, this is relatively easy:

[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);


[DllImport("user32.dll", SetLastError=true, CharSet=CharSet.Auto)]
static extern int GetWindowTextLength(IntPtr hWnd);

...

int len;

// Window caption
if ((len = GetWindowTextLength(WindowHandle)) > 0) {
    sb = new StringBuilder(len + 1);
    if (GetWindowText(WindowHandle, sb, sb.Capacity) == 0)
        throw new Exception(String.Format("unable to obtain window caption, error code {0}", Marshal.GetLastWin32Error()));
    Caption = sb.ToString();
}

Here, 'WindowHandle' is the handle of the created window.

In the case you do not have a window handle (I see you don't), you have to enumerate every desktop top-level window, filter them by the creating process (I see the window is created by you application by calling MyFunc, so you know the process ID [*]), and then use some heuristic to determine the required information.

Here is the C# import of the functions you shall use in the case you do not have the handle:

[DllImport("user32.dll", ExactSpelling = true, SetLastError = true)]
static extern int GetWindowThreadProcessId(IntPtr hWnd, out int lpdwProcessId);

[DllImport("user32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool EnumWindows(EnumWindowsProc lpEnumFunc, IntPtr lParam);

private delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam);

Basically EnumWindows calls EnumWindowsProc for each window found in the current desktop. So you can get the window caption.

List<string> WindowLabels = new List<string>();

string GetWindowCaption(IntPtr hWnd) { ... }

bool MyEnumWindowsProc(IntPtr hWnd, IntPtr lParam) {
    int pid;

    GetWindowThreadProcessId(hWnd, out pid);

    if (pid == Process.GetCurrentProcess().Id) {
        // Window created by this process -- Starts heuristic
        string caption = GetWindowCaption(hWnd);

        if (caption != "MyKnownMainWindowCaption") {
           WindowLabels.Add(caption);
        }
    }

    return (true);
}

void DetectWindowCaptions() {
    EnumWindows(MyEnumWindowsProc, IntPtr.Zero);

    foreach (string s in WindowLabels) {
        Console.WriteLine(s);
    }
}

[*] In the case the window is not created by your application (i.e but from another background process), you shall filter the values returned by GetWindowThreadProcessId using another process ID, but this requires another question...

Luca
Thank you... could you please explain the second method with sample code.
Pramodh
Done. The heuristic part is simple but it should actually work till all application window captions are known at compile time.
Luca
+2  A: 

If you activate LabVIEW scripting (LabVIEW 2010), or install it (LV 8.6, 2009) there is a front-panel property called 'FP.nativewindow'. This returns a handle to the front panel window.
Use the following snippet to get the property:
FP.NativeWindow

Ton