WndProc挂起了应用程序

时间:2015-07-15 14:41:42

标签: c# winforms wndproc

我正在开发一个Windows应用程序,当他/她按下Alt + z时,它正在拍摄用户系统的屏幕截图。

表示我是处理Windows消息的WndProc

下面我提供了代码段。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Diagnostics;
using System.Reflection;

namespace QuickScreenShot
{
    public partial class Form1 : Form
    {
        // Assembly anAssembly;

        [DllImport("User32.dll")]
        protected static extern int SetClipboardViewer(int hWndNewViewer);

        [DllImport("User32.dll", CharSet = CharSet.Auto)]
        public static extern bool ChangeClipboardChain(IntPtr hWndRemove, IntPtr hWndNewNext);

        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        public static extern int SendMessage(IntPtr hwnd, int wMsg, IntPtr wParam, IntPtr lParam);

        // HOT key dlls
        [DllImport("user32.dll")]
        public static extern bool RegisterHotKey(IntPtr hWnd, int id, int fsModifiers, int vlc);
        [DllImport("user32.dll")]
        public static extern bool UnregisterHotKey(IntPtr hWnd, int id);

        IntPtr nextClipboardViewer;
        private System.Windows.Forms.ContextMenu contextMenu1;
        private System.Windows.Forms.MenuItem menuItem1;
        private System.Windows.Forms.NotifyIcon notifyIcon1;

        public Form1()
        {
            InitializeComponent();
            Clipboard.Clear();
            nextClipboardViewer = (IntPtr)SetClipboardViewer((int)this.Handle);

            // Alt =1 , Ctrl =2, Shift =4, Win =0
            //register hot Ctrl , Alt, and ‘z’ 
            bool success;

            success = Form1.RegisterHotKey(this.Handle, this.GetType().GetHashCode(), 1, (int)'Z');
            if (success)
            {
                Console.WriteLine("Alt-z hot key successfully registered");
                this.notifyIcon1 = new System.Windows.Forms.NotifyIcon();
                this.notifyIcon1.Visible = true;
                this.notifyIcon1.BalloonTipTitle = "Quick ScreenShot has been started.";
                this.notifyIcon1.BalloonTipText = "Use Alt + z to take screenshots.";
                this.notifyIcon1.Text = "Quick Screenshot is running";
                this.notifyIcon1.BalloonTipIcon = ToolTipIcon.Info;

                this.contextMenu1 = new System.Windows.Forms.ContextMenu();
                this.menuItem1 = new System.Windows.Forms.MenuItem();

                // Initialize contextMenu1 
                this.contextMenu1.MenuItems.AddRange(
                            new System.Windows.Forms.MenuItem[] { this.menuItem1 });

                // Initialize menuItem1 
                this.menuItem1.Index = 0;
                this.menuItem1.Text = "E&xit";
                this.menuItem1.Click += new System.EventHandler(this.menuItem1_Click);
                this.notifyIcon1.ContextMenu = this.contextMenu1;
                using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(
    "QuickScreenShot.images" + ".capture_icon.ico"))
                {
                    this.notifyIcon1.Icon = new Icon(stream);
                }

                this.notifyIcon1.ShowBalloonTip(30000);
            }
            else
                MessageBox.Show("Could not register Hotkey – there is probably a conflict. ", "", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }

        private void menuItem1_Click(object Sender, EventArgs e)
        {
            // Close the form, which closes the application. 
            Application.Exit();
            this.notifyIcon1.Icon = null;
        }

        protected override void WndProc(ref System.Windows.Forms.Message m)
        {
            try
            {
                // defined in winuser.h
                const int WM_DRAWCLIPBOARD = 0x308;
                const int WM_CHANGECBCHAIN = 0x030D;

                switch (m.Msg)
                {
                    case WM_DRAWCLIPBOARD:
                        DisplayClipboardData();
                        SendMessage(nextClipboardViewer, m.Msg, m.WParam, m.LParam);
                        break;

                    case WM_CHANGECBCHAIN:
                        if (m.WParam == nextClipboardViewer)
                            nextClipboardViewer = m.LParam;
                        else
                            SendMessage(nextClipboardViewer, m.Msg, m.WParam, m.LParam);
                        break;

                    case 0x0312:
                        CaptureAndSave();
                        break;
                    default:
                        base.WndProc(ref m);
                        break;
                }
            }
            catch (Exception e)
            {
                MessageBox.Show(e.ToString());
            }
        }

        void DisplayClipboardData()
        {
            try
            {
                //System.Windows.Forms.IDataObject iData = new DataObject();
                //iData = Clipboard.GetDataObject();

                //if (iData.GetDataPresent(DataFormats.Rtf))
                //    Console.WriteLine((string)iData.GetData(DataFormats.Rtf));
                //else if (iData.GetDataPresent(DataFormats.Text))
                //    Console.WriteLine((string)iData.GetData(DataFormats.Text));
                //else if (iData.GetDataPresent(DataFormats.Bitmap))
                //{
                if (Clipboard.ContainsImage())
                {

                    Console.WriteLine("retrieving image");
                    Bitmap aBitMap = (Bitmap)Clipboard.GetImage();
                    string newImageName = System.IO.Path.GetTempFileName();
                    aBitMap.Save(newImageName, System.Drawing.Imaging.ImageFormat.Png);
                    ProcessStartInfo procInfo = new ProcessStartInfo();
                    Process Proc = Process.Start("mspaint.exe", newImageName);
                    while (Proc.MainWindowHandle == IntPtr.Zero)
                    {
                        System.Threading.Thread.Sleep(100);
                    }
                    System.IO.File.Delete(newImageName);
                    Proc.Close();
                }
                else
                    Console.WriteLine("[Clipboard data is not RTF or ASCII Text]");
            }
            catch (Exception e)
            {
                MessageBox.Show(e.ToString());
            }
        }

        private void CaptureAndSave()
        {
            uint intReturn = 0;
            NativeWIN32.INPUT structInput;
            structInput = new NativeWIN32.INPUT();
            structInput.type = (uint)1;
            structInput.ki.wScan = 0;
            structInput.ki.time = 0;
            structInput.ki.dwFlags = 0;
            structInput.ki.dwExtraInfo = 0;
            //Press Alt Key 
            structInput.ki.wVk = (ushort)NativeWIN32.VK.MENU;
            intReturn = NativeWIN32.SendInput((uint)1, ref structInput, Marshal.SizeOf(structInput));
            // Key down the actual key-code
            structInput.ki.wVk = (ushort)NativeWIN32.VK.SNAPSHOT;
            //vk;
            intReturn = NativeWIN32.SendInput((uint)1, ref structInput, Marshal.SizeOf(structInput));
            // Key up the actual key-code
            structInput.ki.dwFlags = NativeWIN32.KEYEVENTF_KEYUP;
            structInput.ki.wVk = (ushort)NativeWIN32.VK.SNAPSHOT;
            //vk;
            intReturn = NativeWIN32.SendInput((uint)1, ref structInput, Marshal.SizeOf(structInput));
            //Keyup Alt
            structInput.ki.dwFlags = NativeWIN32.KEYEVENTF_KEYUP;
            structInput.ki.wVk = (ushort)NativeWIN32.VK.MENU;
            intReturn = NativeWIN32.SendInput((uint)1, ref structInput, Marshal.SizeOf(structInput));

        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }
    }

    public class NativeWIN32
    {
        public const ushort KEYEVENTF_KEYUP = 0x0002;

        public enum VK : ushort
        {
            SHIFT = 0x10,
            CONTROL = 0x11,
            MENU = 0x12,
            ESCAPE = 0x1B,
            BACK = 0x08,
            TAB = 0x09,
            RETURN = 0x0D,
            PRIOR = 0x21,
            NEXT = 0x22,
            END = 0x23,
            HOME = 0x24,
            LEFT = 0x25,
            UP = 0x26,
            RIGHT = 0x27,
            DOWN = 0x28,
            SELECT = 0x29,
            PRINT = 0x2A,
            EXECUTE = 0x2B,
            SNAPSHOT = 0x2C,
            INSERT = 0x2D,
            DELETE = 0x2E,
            HELP = 0x2F,
            NUMPAD0 = 0x60,
            NUMPAD1 = 0x61,
            NUMPAD2 = 0x62,
            NUMPAD3 = 0x63,
            NUMPAD4 = 0x64,
            NUMPAD5 = 0x65,
            NUMPAD6 = 0x66,
            NUMPAD7 = 0x67,
            NUMPAD8 = 0x68,
            NUMPAD9 = 0x69,
            MULTIPLY = 0x6A,
            ADD = 0x6B,
            SEPARATOR = 0x6C,
            SUBTRACT = 0x6D,
            DECIMAL = 0x6E,
            DIVIDE = 0x6F,
            F1 = 0x70,
            F2 = 0x71,
            F3 = 0x72,
            F4 = 0x73,
            F5 = 0x74,
            F6 = 0x75,
            F7 = 0x76,
            F8 = 0x77,
            F9 = 0x78,
            F10 = 0x79,
            F11 = 0x7A,
            F12 = 0x7B,
            OEM_1 = 0xBA,   // ',:' for US
            OEM_PLUS = 0xBB,   // '+' any country
            OEM_COMMA = 0xBC,   // ',' any country
            OEM_MINUS = 0xBD,   // '-' any country
            OEM_PERIOD = 0xBE,   // '.' any country
            OEM_2 = 0xBF,   // '/?' for US
            OEM_3 = 0xC0,   // '`~' for US
            MEDIA_NEXT_TRACK = 0xB0,
            MEDIA_PREV_TRACK = 0xB1,
            MEDIA_STOP = 0xB2,
            MEDIA_PLAY_PAUSE = 0xB3,
            LWIN = 0x5B,
            RWIN = 0x5C
        }


        public struct KEYBDINPUT
        {
            public ushort wVk;
            public ushort wScan;
            public uint dwFlags;
            public long time;
            public uint dwExtraInfo;
        };

        [StructLayout(LayoutKind.Explicit, Size = 28)]
        public struct INPUT
        {
            [FieldOffset(0)]
            public uint type;
            [FieldOffset(4)]
            public KEYBDINPUT ki;
        };


        [DllImport("user32.dll")]
        public static extern uint SendInput(uint nInputs, ref INPUT pInputs, int cbSize);

    }
}

一切正常,但是当应用程序获得消息类型WM_WININICHANGE时,它将转到case语句的默认部分并挂起应用程序。

我不知道如何处理此消息,因此它不会挂起我的系统和应用程序。

请帮帮我。

非常感谢。

0 个答案:

没有答案