2010-01-18 20 views
1

我使用以下代碼遍歷並在其標題欄中找到包含特定字符串的窗口。我有兩個包含這些相同信息的項目,但由於某些原因 - 它在定位到x64時有效,但FindWindowLike始終在x86上返回0。我需要這個在x86中運行。爲什麼這將運行在32位,但不是64位? (x86與編譯器選項中的x64)

我正在開發Windows 7 x64上的這個,但它需要在我的機器以及XPx32上運行。我無法捉摸就是爲什麼它編譯/運行在64位,但不是32倍(考慮我靶向用戶 .DLL)

這裏談到的代碼:

<DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)> Private Shared Function FindWindow(ByVal lpClassName As String, ByVal lpWindowName As String) As IntPtr 
    End Function 

    <DllImport("user32.dll", EntryPoint:="FindWindow", SetLastError:=True, CharSet:=CharSet.Auto)> Private Shared Function FindWindowByClass(ByVal lpClassName As String, ByVal zero As IntPtr) As IntPtr 
    End Function 

    <DllImport("user32.dll", EntryPoint:="FindWindow", SetLastError:=True, CharSet:=CharSet.Auto)> Private Shared Function FindWindowByCaption(ByVal zero As IntPtr, ByVal lpWindowName As String) As IntPtr 
    End Function 

    <DllImport("user32.dll", CharSet:=CharSet.Auto, ExactSpelling:=True)> Public Shared Function IsWindow(ByVal hWnd As IntPtr) As Boolean 
    End Function 

    Private Declare Function GetDC Lib "user32.dll" (ByVal hwnd As IntPtr) As IntPtr 
    Private Declare Function ReleaseDC Lib "user32.dll" (ByVal hwnd As IntPtr, ByVal hdc As IntPtr) As IntPtr 
    Public Declare Function GetDesktopWindow Lib "user32"() As Long 
    Public Declare Function GetWindow Lib "user32" (ByVal hwnd As Long, ByVal wCmd As Long) As Long 
    Public Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hwnd As Long, ByVal lpString As String, ByVal cch As Long) As Long 
    Public Declare Function GetClassName Lib "user32" Alias "GetClassNameA" (ByVal hwnd As Long, ByVal lpClassName As String, ByVal nMaxCount As Long) As Long 
    Public Const GW_HWNDFIRST = 0 
    Public Const GW_HWNDLAST = 1 
    Public Const GW_HWNDNEXT = 2 
    Public Const GW_HWNDPREV = 3 
    Public Const GW_OWNER = 4 
    Public Const GW_CHILD = 5 
    Public listWindows As New List(Of String) 

Private Function FindWindows() As Long 
     Dim hWndStart As Long = 0 
     Dim WindowText As String = "*message*" 
     Dim Classname As String = "*" 
     Dim hwnd As Long 
     Dim sWindowText As String 
     Dim sClassname As String 
     Dim r As Long 

     'Hold the level of recursion and 
     'hold the number of matching windows 
     Static level As Integer 

     'Initialize if necessary. This is only executed 
     'when level = 0 and hWndStart = 0, normally 
     'only on the first call to the routine. 
     If level = 0 Then 
      If hWndStart = 0 Then hWndStart = GetDesktopWindow() 
     End If 

     'Increase recursion counter  
     level = level + 1 

     'Get first child window 
     hwnd = GetWindow(hWndStart, GW_CHILD) 

     Do Until hwnd = 0 

      'Search children by recursion 
      Call FindWindows() 

      'Get the window text and class name 
      sWindowText = Space$(255) 
      r = GetWindowText(hwnd, sWindowText, 255) 
      sWindowText = Microsoft.VisualBasic.Left(sWindowText, r) 
      sClassname = Space$(255) 
      r = GetClassName(hwnd, sClassname, 255) 
      sClassname = Microsoft.VisualBasic.Left(sClassname, r) 

      'Check if window found matches the search parameters 
      If (sWindowText Like WindowText) And (sClassname Like Classname) Then 
       If listWindows.Contains(hwnd & "||||" & sClassname & "||||" & sWindowText) = False Then 
        listWindows.Add(hwnd & "||||" & sClassname & "||||" & sWindowText) 
       End If 
       FindWindows = hwnd 

       'uncommenting the next line causes the routine to 
       'only return the first matching window. 
       'Exit Do 

      End If 

      'Get next child window 
      hwnd = GetWindow(hwnd, GW_HWNDNEXT) 

     Loop 

     'Reduce the recursion counter 
     level = level - 1 
End Function 

回答

3

你的函數定義錯誤。在C LONG中是32位寬,但是在C#和VB.NET中,long在32位和64位系統上都是64位寬。此外,您的窗口句柄參數應爲IntPtr s。

Private Declare Function GetDC Lib "user32.dll" (ByVal hwnd As IntPtr) As IntPtr 
Private Declare Function ReleaseDC Lib "user32.dll" (ByVal hwnd As IntPtr, ByVal hdc As IntPtr) As IntPtr 
Private Declare Function GetDesktopWindow Lib "user32"() As IntPtr 
Private Declare Function GetWindow Lib "user32" (ByVal hwnd As IntPtr, ByVal wCmd As Integer) As IntPtr 
Private Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hwnd As IntPtr, ByVal lpString As String, ByVal cch As Integer) As Integer 
Private Declare Function GetClassName Lib "user32" Alias "GetClassNameA" (ByVal hwnd As IntPtr, ByVal lpClassName As String, ByVal nMaxCount As Integer) As Integer 

請注意,你不應該傳遞String s到GetWindowTextGetClassName。嘗試StringBuilder

+1

「不應該」幾乎不夠強,這是非常錯誤的。訪問pinvoke.net以獲得更好的聲明。 – 2010-01-18 09:14:40

+0

好吧,這不是那麼糟糕。如果你創建了一定長度的字符串並確保它沒有被執行,那麼你應該沒問題。 – wj32 2010-01-18 09:30:48

1

另一條建議是將64位系統的調用結束。這裏有一個例子GetWindowLong:

Public Shared Function GetWindowLong(ByVal hWnd As HandleRef, ByVal nIndex As Integer) As IntPtr 
    If (IntPtr.Size = 4) Then 
     Return NativeMethods.GetWindowLong32(hWnd, nIndex) 
    End If 
    Return NativeMethods.GetWindowLongPtr64(hWnd, nIndex) 
End Function 

由於nobugz說,你可以看看pinvoke.net。我更喜歡使用反射器,並且確切地看,框架如何處理它。

相關問題