-4

在将下面的代码翻译成 VB.NET 时,我遇到了一个障碍。

我的问题是:在 C# 中,我的委托被调用时没有参数作为参数本身。如何在 VB.NET 中做到这一点?所有的在线和离线翻译器都无法按原样翻译所有代码。请参阅下面我所在的位置:

翻译失败的部分是最重要的事情......

这里:

EnumThreadWindows(t.Id, MyEnumThreadWindowsProc, IntPtr.Zero);

(没有足够的参数来调用“MyEnumThreadWindowsProc”函数)

和这里:

startWnd = FindWindowEx(IntPtr.Zero, IntPtr.Zero, (IntPtr)0xC017, "Start");

(指针)


供参考,完整来源是

/*
 *  Copyright (c) 2008..11 by Simon Baer
 * 
 *  You may use this code for whatever you want.
 */

using System;
using System.Text;
using System.Runtime.InteropServices;
using System.Diagnostics;

namespace TaskbarHide
{
    /// <summary>
    /// Helper class for hiding/showing the taskbar and startmenu on
    /// Windows XP and Vista.
    /// </summary>
    public static class Taskbar
    {
        [DllImport("user32.dll")]
        private static extern int GetWindowText(IntPtr hWnd, StringBuilder text, int count); 
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        private static extern bool EnumThreadWindows(int threadId, EnumThreadProc pfnEnum, IntPtr lParam);
        [DllImport("user32.dll", SetLastError = true)]
        private static extern System.IntPtr FindWindow(string lpClassName, string lpWindowName);
        [DllImport("user32.dll", SetLastError = true)]
        private static extern IntPtr FindWindowEx(IntPtr parentHandle, IntPtr childAfter, string className,  string windowTitle);
        [DllImport("user32.dll")]
        private static extern IntPtr FindWindowEx(IntPtr parentHwnd, IntPtr childAfterHwnd, IntPtr className, string windowText);
        [DllImport("user32.dll")]
        private static extern int ShowWindow(IntPtr hwnd, int nCmdShow);
        [DllImport("user32.dll")]
        private static extern uint GetWindowThreadProcessId(IntPtr hwnd, out int lpdwProcessId);

        private const int SW_HIDE = 0;
        private const int SW_SHOW = 5;

        private const string VistaStartMenuCaption = "Start";
        private static IntPtr vistaStartMenuWnd = IntPtr.Zero;
        private delegate bool EnumThreadProc(IntPtr hwnd, IntPtr lParam);

        /// <summary>
        /// Show the taskbar.
        /// </summary>
        public static void Show()
        {
            SetVisibility(true);
        }

        /// <summary>
        /// Hide the taskbar.
        /// </summary>
        public static void Hide()
        {
            SetVisibility(false);
        }

        /// <summary>
        /// Sets the visibility of the taskbar.
        /// </summary>
        public static bool Visible
        {
            set { SetVisibility(value); }
        }

        /// <summary>
        /// Hide or show the Windows taskbar and startmenu.
        /// </summary>
        /// <param name="show">true to show, false to hide</param>
        private static void SetVisibility(bool show)
        {
            // get taskbar window
            IntPtr taskBarWnd = FindWindow("Shell_TrayWnd", null);

            // try it the WinXP way first...
            IntPtr startWnd = FindWindowEx(taskBarWnd, IntPtr.Zero, "Button", "Start");

            if (startWnd == IntPtr.Zero)
            {
                // try an alternate way, as mentioned on CodeProject by Earl Waylon Flinn
                startWnd = FindWindowEx(IntPtr.Zero, IntPtr.Zero, (IntPtr)0xC017, "Start");
            }

            if (startWnd == IntPtr.Zero)
            {
                // ok, let's try the Vista easy way...
                startWnd = FindWindow("Button", null);

                if (startWnd == IntPtr.Zero)
                {
                    // no chance, we need to to it the hard way...
                    startWnd = GetVistaStartMenuWnd(taskBarWnd);
                }
            }

            ShowWindow(taskBarWnd, show ? SW_SHOW : SW_HIDE);
            ShowWindow(startWnd, show ? SW_SHOW : SW_HIDE);
        }

        /// <summary>
        /// Returns the window handle of the Vista start menu orb.
        /// </summary>
        /// <param name="taskBarWnd">windo handle of taskbar</param>
        /// <returns>window handle of start menu</returns>
        private static IntPtr GetVistaStartMenuWnd(IntPtr taskBarWnd)
        {
            // get process that owns the taskbar window
            int procId;
            GetWindowThreadProcessId(taskBarWnd, out procId);

            Process p = Process.GetProcessById(procId);
            if (p != null)
            {
                // enumerate all threads of that process...
                foreach (ProcessThread t in p.Threads)
                {
                    EnumThreadWindows(t.Id, MyEnumThreadWindowsProc, IntPtr.Zero);
                }
            }
            return vistaStartMenuWnd;
        }

        /// <summary>
        /// Callback method that is called from 'EnumThreadWindows' in 'GetVistaStartMenuWnd'.
        /// </summary>
        /// <param name="hWnd">window handle</param>
        /// <param name="lParam">parameter</param>
        /// <returns>true to continue enumeration, false to stop it</returns>
        private static bool MyEnumThreadWindowsProc(IntPtr hWnd, IntPtr lParam)
        {
            StringBuilder buffer = new StringBuilder(256);
            if (GetWindowText(hWnd, buffer, buffer.Capacity) > 0)
            {
                Console.WriteLine(buffer);
                if (buffer.ToString() == VistaStartMenuCaption)
                {
                    vistaStartMenuWnd = hWnd;
                    return false;
                }
            }
            return true;
        }
    }
}

这是 Telerik 在线服务翻译的代码:

'
' * Copyright (c) 2008..11 by Simon Baer
' * 
' *  You may use this code for whatever you want.
' 


Imports System
Imports System.Text
Imports System.Runtime.InteropServices
Imports System.Diagnostics

Namespace TaskbarHide
    ''' <summary>
    ''' Helper class for hiding/showing the taskbar and startmenu on
    ''' Windows XP and Vista.
    ''' </summary>
    Public NotInheritable Class Taskbar
        Private Sub New()
        End Sub
        <DllImport("user32.dll")> _
        Private Shared Function GetWindowText(hWnd As IntPtr, text As StringBuilder, count As Integer) As Integer
        End Function
        <DllImport("user32.dll", CharSet := CharSet.Auto)> _
        Private Shared Function EnumThreadWindows(threadId As Integer, pfnEnum As EnumThreadProc, lParam As IntPtr) As Boolean
        End Function
        <DllImport("user32.dll", SetLastError := True)> _
        Private Shared Function FindWindow(lpClassName As String, lpWindowName As String) As System.IntPtr
        End Function
        <DllImport("user32.dll", SetLastError := True)> _
        Private Shared Function FindWindowEx(parentHandle As IntPtr, childAfter As IntPtr, className As String, windowTitle As String) As IntPtr
        End Function
        <DllImport("user32.dll")> _
        Private Shared Function FindWindowEx(parentHwnd As IntPtr, childAfterHwnd As IntPtr, className As IntPtr, windowText As String) As IntPtr
        End Function
        <DllImport("user32.dll")> _
        Private Shared Function ShowWindow(hwnd As IntPtr, nCmdShow As Integer) As Integer
        End Function
        <DllImport("user32.dll")> _
        Private Shared Function GetWindowThreadProcessId(hwnd As IntPtr, lpdwProcessId As Integer) As UInteger
        End Function

        Private Const SW_HIDE As Integer = 0
        Private Const SW_SHOW As Integer = 5

        Private Const VistaStartMenuCaption As String = "Start"
        Private Shared vistaStartMenuWnd As IntPtr = IntPtr.Zero
        Private Delegate Function EnumThreadProc(hwnd As IntPtr, lParam As IntPtr) As Boolean

        ''' <summary>
        ''' Show the taskbar.
        ''' </summary>
        Public Shared Sub Show()
            SetVisibility(True)
        End Sub

        ''' <summary>
        ''' Hide the taskbar.
        ''' </summary>
        Public Shared Sub Hide()
            SetVisibility(False)
        End Sub

        ''' <summary>
        ''' Sets the visibility of the taskbar.
        ''' </summary>
        Public Shared WriteOnly Property Visible() As Boolean
            Set
                SetVisibility(value)
            End Set
        End Property

        ''' <summary>
        ''' Hide or show the Windows taskbar and startmenu.
        ''' </summary>
        ''' <param name="show">true to show, false to hide</param>
        Private Shared Sub SetVisibility(show As Boolean)
            ' get taskbar window
            Dim taskBarWnd As IntPtr = FindWindow("Shell_TrayWnd", Nothing)

            ' try it the WinXP way first...
            Dim startWnd As IntPtr = FindWindowEx(taskBarWnd, IntPtr.Zero, "Button", "Start")

            If startWnd = IntPtr.Zero Then
                ' try an alternate way, as mentioned on CodeProject by Earl Waylon Flinn
                startWnd = FindWindowEx(IntPtr.Zero, IntPtr.Zero, DirectCast(&Hc017, IntPtr), "Start")
            End If

            If startWnd = IntPtr.Zero Then
                ' ok, let's try the Vista easy way...
                startWnd = FindWindow("Button", Nothing)

                If startWnd = IntPtr.Zero Then
                    ' no chance, we need to to it the hard way...
                    startWnd = GetVistaStartMenuWnd(taskBarWnd)
                End If
            End If

            ShowWindow(taskBarWnd, If(show, SW_SHOW, SW_HIDE))
            ShowWindow(startWnd, If(show, SW_SHOW, SW_HIDE))
        End Sub

        ''' <summary>
        ''' Returns the window handle of the Vista start menu orb.
        ''' </summary>
        ''' <param name="taskBarWnd">windo handle of taskbar</param>
        ''' <returns>window handle of start menu</returns>
        Private Shared Function GetVistaStartMenuWnd(taskBarWnd As IntPtr) As IntPtr
            ' get process that owns the taskbar window
            Dim procId As Integer
            GetWindowThreadProcessId(taskBarWnd, procId)

            Dim p As Process = Process.GetProcessById(procId)
            If p IsNot Nothing Then
                ' enumerate all threads of that process...
                For Each t As ProcessThread In p.Threads
                    EnumThreadWindows(t.Id, MyEnumThreadWindowsProc, IntPtr.Zero)
                Next
            End If
            Return vistaStartMenuWnd
        End Function

        ''' <summary>
        ''' Callback method that is called from 'EnumThreadWindows' in 'GetVistaStartMenuWnd'.
        ''' </summary>
        ''' <param name="hWnd">window handle</param>
        ''' <param name="lParam">parameter</param>
        ''' <returns>true to continue enumeration, false to stop it</returns>
        Private Shared Function MyEnumThreadWindowsProc(hWnd As IntPtr, lParam As IntPtr) As Boolean
            Dim buffer As New StringBuilder(256)
            If GetWindowText(hWnd, buffer, buffer.Capacity) > 0 Then
                Console.WriteLine(buffer)
                If buffer.ToString() = VistaStartMenuCaption Then
                    vistaStartMenuWnd = hWnd
                    Return False
                End If
            End If
            Return True
        End Function
    End Class
End Namespace

'=======================================================
'Service provided by Telerik (www.telerik.com)
'Conversion powered by NRefactory.
'Twitter: @telerik, @toddanglin
'Facebook: facebook.com/telerik
'=======================================================
4

2 回答 2

3

我认为这很简单:

For Each t As ProcessThread In p.Threads
     EnumThreadWindows(t.Id, AddressOf MyEnumThreadWindowsProc, IntPtr.Zero)
Next

VB.NET 使用AddressOf关键字来指示委托等的方法指针。

对于 IntPtr 转换,也许使用CType代替DirectCast

startWnd = FindWindowEx(IntPtr.Zero, IntPtr.Zero, CType(&HC017, IntPtr), "Start")
于 2013-06-04T17:46:57.643 回答
1

我在这里猜,所以请试一试:

代替:

            For Each t As ProcessThread In p.Threads
                EnumThreadWindows(t.Id, MyEnumThreadWindowsProc, IntPtr.Zero)
            Next

尝试:

            For Each t As ProcessThread In p.Threads
                Dim returnMyEnumThreadWindowsProc As Object
                returnMyEnumThreadWindowsProc = MyEnumThreadWindowsProc ( ... )
                EnumThreadWindows(t.Id, returnMyEnumThreadWindowsProc , IntPtr.Zero)
            Next

我知道 VB.NET 不像 C# 那样做匿名函数,但我不确定替代方法是如何工作的。

于 2013-06-04T17:08:07.563 回答