用C#调用API的“USER32.DLL”,控制开始菜单的弹出。也就是模拟用户单击键盘上的WINDOWS键。
我找了好久了,百度上出了一大堆。就是下面这段程序。。也找不到原作者是,写的不是很清楚。看不懂。大致看懂了有以下几点:
User32是他写的一个类。类里有几个结构和方法。
还有几点不明白。
1:第三行 new EnumProc(Enum),这个是什么,请高人解释一下。
2:程序流程也不太清楚。
3:还有API。也不是很清楚。            基本思路为,寻找开始菜单按钮窗口,并模拟用户单击 
            void pop()
              {
               User32.EnumWindows(new EnumProc(Enum), 0);
              }
              private bool Enum(IntPtr hWnd, uint param)
              {
               User32.STRINGBUFFER buffer=new User32.STRINGBUFFER();
               User32.GetClassName(hWnd, ref buffer, 256);
               if (buffer.szText == "Shell_TrayWnd")
               {
                User32.EnumChildWindows(hWnd, new EnumProc(Enum2), 0);
                return false;
               }
               else return true;
              }
              IntPtr lastForeGroundWindow;
              private bool Enum2(IntPtr hWnd, uint param)
              {
               User32.STRINGBUFFER buffer = new User32.STRINGBUFFER();
               User32.GetClassName(hWnd, ref buffer, 256);
               if (buffer.szText == "Button")
               {
                if (User32.SendMessage(hWnd, WndMsg.BM_GETSTATE, 0, 0) == 
            User32.BST_PUSHED)
                {
                 User32.SetForegroundWindow(lastForeGroundWindow);
                }
                else
                {
                 lastForeGroundWindow = User32.GetForegroundWindow();
                 User32.SetForegroundWindow(hWnd);
                 User32.PostMessage(hWnd, WndMsg.BM_CLICK, 0, 0);
                }
                return true;
               }
               else
                return false;
              }using System; using System.Runtime.InteropServices; public delegate bool CallBack(int hwnd, int lParam); public class EnumWindowsApp { [DllImport("user32")] public static extern int EnumWindows(CallBack x, int y); public static void Main() { CallBack myCallBack = new CallBack(EnumWindowsApp.Report); EnumWindows(myCallBack, 0); } public static bool Report(int hwnd, int lParam) { Console.Write("Window handle is :"); Console.WriteLine(hwnd); return true; } } 

解决方案 »

  1.   

    我的目的是让开始菜单弹出来。而不是模拟什么。呵呵。说来不好意思了。我的键盘上WINDOWS键坏了。不想换。就想用程序控制 把击其他键(如F)时让程序转到WINDOWS键上。。以此来弹出开始菜单。
      

  2.   

         User32.EnumWindows(new EnumProc(Enum), 0); 
    回调函数
      

  3.   

    建立一个c#的windows程序,下面的代码就可以实现你的要求了,结贴吧,呵呵
        public partial class Form1 : Form
        {
            [StructLayout(LayoutKind.Sequential)]
            //定义一个表示上下左右的结构
            struct NativeRECT
            {
                public int left;
                public int top;
                public int right;
                public int bottom;
            }        [Flags]
            //定义鼠标动作
            enum MouseEventFlag : uint
            {
                Move = 0x0001,
                LeftDown = 0x0002,
                LeftUp = 0x0004,
                RightDown = 0x0008,
                RightUp = 0x0010,
                MiddleDown = 0x0020,
                MiddleUp = 0x0040,
                XDown = 0x0080,
                XUp = 0x0100,
                Wheel = 0x0800,
                VirtualDesk = 0x4000,
                Absolute = 0x8000
            }
            #region 定义需要用到的Windows API
            [DllImport("user32.dll")]
            static extern bool SetCursorPos(int X, int Y);        [DllImport("user32.dll")]
            static extern void mouse_event(MouseEventFlag flags, int dx, int dy, uint data, UIntPtr extraInfo);        [DllImport("user32.dll")]
            static extern IntPtr FindWindow(string strClass, string strWindow);        [DllImport("user32.dll")]
            static extern IntPtr FindWindowEx(HandleRef hwndParent, HandleRef hwndChildAfter, string strClass, string strWindow);        [DllImport("user32.dll")]
            static extern bool GetWindowRect(HandleRef hwnd, out NativeRECT rect);
            #endregion        private Point endPosition;        public Form1()
            {
                InitializeComponent();
            }        private void button1_Click(object sender, EventArgs e)
            {
                NativeRECT rect;
                //找到任务栏
                IntPtr ptrTaskbar = FindWindow("Shell_TrayWnd", null);
                if (ptrTaskbar == IntPtr.Zero)
                {
                    MessageBox.Show("No taskbar found.");
                    return;
                }            //找到任务栏上的开始菜单按钮
                IntPtr ptrStartBtn = FindWindowEx(new HandleRef(this, ptrTaskbar), new HandleRef(this, IntPtr.Zero), "Button", null);
                if (ptrStartBtn == IntPtr.Zero)
                {
                    MessageBox.Show("No start button found.");
                    return;
                }            //获取开始菜单按钮的上下左右坐标点
                GetWindowRect(new HandleRef(this, ptrStartBtn), out rect);            //计算出开始菜单按钮的中央位置坐标
                endPosition.X = (rect.left + rect.right) / 2;
                endPosition.Y = (rect.top + rect.bottom) / 2;            //将鼠标定位到开始菜单按钮的中央位置
                SetCursorPos(endPosition.X, endPosition.Y);
                //模拟鼠标左键按下动作
                mouse_event(MouseEventFlag.LeftDown, 0, 0, 0, UIntPtr.Zero);
                mouse_event(MouseEventFlag.LeftUp, 0, 0, 0, UIntPtr.Zero);
            }
        }
      

  4.   

    别忘记了引用这个命名空间哦
    using System.Runtime.InteropServices;
      

  5.   

    这个程序应该是使用Platform invoke 调用windows api.
    void pop() 
    {
       //调用EnumWindows api枚举窗口,EnumWindows 的用法参见msdn。大体上就是每找到一个窗口就调用callback函数。
       User32.EnumWindows(new EnumProc(Enum), 0); 
    } private bool Enum(IntPtr hWnd, uint param) 

        User32.STRINGBUFFER buffer=new User32.STRINGBUFFER(); 
        
        //当找到一个ClassName叫Shell_TrayWnd的时候再枚举这个窗口的子窗口,Shell_TrayWnd应该就是任务栏。
        User32.GetClassName(hWnd, ref buffer, 256); 
        if (buffer.szText == "Shell_TrayWnd") 
        { 
            User32.EnumChildWindows(hWnd, new EnumProc(Enum2), 0); 
            return false; 
        } 
        else return true; 
        } 
        IntPtr lastForeGroundWindow; 
        private bool Enum2(IntPtr hWnd, uint param) 
        { 
            User32.STRINGBUFFER buffer = new User32.STRINGBUFFER(); 
            //再在子窗口找ClassName是button的窗口
            User32.GetClassName(hWnd, ref buffer, 256); 
            if (buffer.szText == "Button") 
            { 
                if (User32.SendMessage(hWnd, WndMsg.BM_GETSTATE, 0, 0) == 
                    User32.BST_PUSHED) 
                { 
                    //如果这个窗口的State是BST_PUSHED,就调用SetForegroundWindow把前一个前景窗口设置成当前的前景窗口。
                    User32.SetForegroundWindow(lastForeGroundWindow); 
                } 
                else 
                { 
                    //否则给这个button发送click消息
                    lastForeGroundWindow = User32.GetForegroundWindow(); 
                    User32.SetForegroundWindow(hWnd); 
                    User32.PostMessage(hWnd, WndMsg.BM_CLICK, 0, 0); 
                } 
                return true; 
            } 
            else 
            return false; 
        } 
      

  6.   

    platform invoke的知识参见msdn:
    ms-help://MS.MSDNQTR.v90.en/dv_fxinterop/html/eca7606e-ebfb-4f47-b8d9-289903fdc045.htm
      

  7.   

    除了写程序之外,
    你可以Ctrl+Esc弹出开始菜单
      

  8.   

    你可一下载 我的一个程序07年写的 我的IBM 上面 也没有哪个键 我用右侧 alt 模拟windows 徽标键,现在还在用刚刚翻出来的,不知道版本对不对,你可以在这里下载:http://cid-35f88a68c5600486.skydrive.live.com/browse.aspx/Public/IBM%7C_WINKEY有一个bug 希望你能发现