[VC#] Работа с чужим окном; Функция 'DefWindowProc'.
От: MuForum Молдова  
Дата: 29.10.07 18:39
Оценка:
Доброе время суток!
Я начинаю программист, недавно перешел с 'C++' на 'C#', так что строго прошу не судить, а по возможности указать на ошибки.

# Задача:
  1. Необходимо написать программу, которая будет перехватывать нажатия кнопок клавиатуры 'F11', 'F12' (Низкоуровневой) — Это осуществил.
  2. При нажатие на кнопку 'F11', Необходимо менять статус окна из 'FullScreen' в 'WindowMode' и наоборот — Это осуществил.
  3. При нажатие на кнопку 'F12', необходимо скрывать(Hide)/показывть(Show) окно. — Тут проблема.

# Детально о проблеме:


        private static int hWnd, hWnd2;
        private const int WH_KEYBOARD_LL = 13;
        private const int WM_KEYUP = 0x0101;
        private static LowLevelKeyboardProc _proc = HookCallback;
        private static IntPtr _hookID = IntPtr.Zero;
......
......
......
        private static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
        {
            if ((nCode >= 0) && (wParam == (IntPtr)WM_KEYUP))
            {
                int vkCode = Marshal.ReadInt32(lParam);
                if (vkCode == 0x7A) // if have pressed button "F11"
                {
                    if (FindWindow("MU", null) != 0)
                    {
                        hWnd = FindWindow(null, "Game");
                        SetWindowText(hWnd, "new game");
                        hWnd2 = FindWindow(null, "new game");
                    }
                    if (IsWindowVisible(hWnd2) != 0)
                    {
                        if (fullmode1 == false)
                        {
                            SetWindowLong((IntPtr)hWnd2, (int)GWL.GWL_STYLE, 0x10000000); // WS_VISIBLE = '0x10000000'
                            DEVMODE dm = new DEVMODE();
                            dm.dmBitsPerPel = Convert.ToSByte(CD);
                            dm.dmPelsWidth = CorX;
                            dm.dmPelsHeight = CorY;
                            dm.dmDisplayFrequency = RR;
                            if (ChangeDisplaySettings(ref dm, 0x02 | 0x04) != 0) ChangeDisplaySettings(ref dm, 0x04);
                            MoveWindow((IntPtr)hWnd2, 0, 0, CorX, CorY, true);
                            SetForegroundWindow(hWnd2);
                            fullmode1 = true;
                            fullmode2 = false;
                        }
                        else
                        {
                            SetWindowLong((IntPtr)hWnd2, (int)GWL.GWL_STYLE, 0x00000000 | 0x10000000 | 0x00C00000 | 0x00040000 | 0x00080000);
                            MoveWindow((IntPtr)hWnd2, 0, (-13), CorX + 5, CorY + 10, true);
                            SetWindowPos((IntPtr)hWnd2, (IntPtr)(-1), 0, (-13), CorX + 5, CorY + 10, 0x0001 | 0x0040);
                            SetForegroundWindow(hWnd2);
                            fullmode1=false;
                            fullmode2=true;
                        }
                    }
                    return (IntPtr)1;
                }
                else if (vkCode == 0x7B) // if have pressed button "F12"
                {
                    if (fullmode2 == true)
                    {
                        if (IsWindowVisible(hWnd2) != 0)
                        {
                            SetWindowPos((IntPtr)hWnd2, (IntPtr)1, 0, (-13), CorX + 5, CorY + 10, 0x0001 | 0x0002 | 0x0004 | 0x0010 | 0x0080 | 0x0400);
                            m_OrigWndProc = GetWindowLongPtr((IntPtr)hWnd2, (int)GWL.GWL_WNDPROC);
                            HookWindowMessage((IntPtr)hWnd2, SCWinProc);
                            DEVMODE d = new DEVMODE();
                            ChangeDisplaySettings(ref d, 0);
                            MessageBox.Show("Spet1");
                        }
                        else
                        {
                            SetWindowPos((IntPtr)hWnd2, (IntPtr)(-1), 0, (-13), CorX + 5, CorY + 10, 0x0001 | 0x0002 | 0x0040);
                            SetForegroundWindow(hWnd2);
                        }
                    }
                    return (IntPtr)1;
                }
            }
            return CallNextHookEx(_hookID, nCode, wParam, lParam);
        }
......
......
......
        public static IntPtr SCWinProc(IntPtr hWnd, uint uMsg, IntPtr wParam, IntPtr lParam)
        {
            MessageBox.Show("Spet2");
            const uint WM_ACTIVATE = 0x0006;
            const uint WM_KILLFOCUS = 0x0008;
            switch (uMsg)
            {
                case WM_ACTIVATE:
                case WM_KILLFOCUS:
                    MessageBox.Show("Spet3");
                    return DefWindowProc(hWnd, uMsg, wParam, lParam);
                default:
                    break;
            }
            return CallWindowProc(m_OrigWndProc, hWnd, uMsg, wParam, lParam);
        }

        // ------------------------------------------------------------

        private static IntPtr m_OrigWndProc;

        public delegate IntPtr WndProcDelegate(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);

        [DllImport("user32.dll", EntryPoint = "SetWindowLong")]
        private static extern int SetWindowLong32(IntPtr hWnd, int nIndex, [MarshalAs(UnmanagedType.FunctionPtr)] WndProcDelegate windowCallback);

        [DllImport("user32.dll", EntryPoint = "SetWindowLongPtr")]
        private static extern IntPtr SetWindowLongPtr64(IntPtr hWnd, int nIndex, [MarshalAs(UnmanagedType.FunctionPtr)] WndProcDelegate windowCallback);
        
        public static IntPtr SetWindowLongPtr(IntPtr hWnd, int nIndex, WndProcDelegate windowCallback)
        {
            if (IntPtr.Size == 8)
                return SetWindowLongPtr64(hWnd, nIndex, windowCallback);
            else
                return new IntPtr(SetWindowLong32(hWnd, nIndex, windowCallback));
        }

        [DllImport("user32.dll", EntryPoint = "GetWindowLong")]
        private static extern int GetWindowLong32(IntPtr hWnd, int nIndex);

        [DllImport("user32.dll", EntryPoint = "GetWindowLongPtr")]
        private static extern IntPtr GetWindowLongPtr64(IntPtr hWnd, int nIndex);

        public static IntPtr GetWindowLongPtr(IntPtr hWnd, int nIndex)
        {
            if (IntPtr.Size == 8)
                return GetWindowLongPtr64(hWnd, nIndex);
            else
                return new IntPtr(GetWindowLong32(hWnd, nIndex));
        }

        [DllImport("user32.dll")]
        private static extern IntPtr DefWindowProc(IntPtr hWnd, uint uMsg, IntPtr wParam, IntPtr lParam);

        [DllImport("User32.dll")]
        private static extern IntPtr CallWindowProc(IntPtr lpPrevWndFunc, IntPtr hWnd, uint iMsg, IntPtr wParam, IntPtr lParam);

        public static IntPtr HookWindowMessage(IntPtr window, WndProcDelegate callback)
        {
            return SetWindowLongPtr(window, (int)GWL.GWL_WNDPROC, callback);
        }

        [DllImport("user32.dll")]
        public static extern int EnumDisplaySettings(string deviceName, int modeNum, ref DEVMODE devMode);
        
        [DllImport("user32.dll")]
        public static extern int ChangeDisplaySettings(ref DEVMODE devMode, int flags);

        // ------------------------------------------------------------

        [DllImport("user32.dll")]
        public static extern int FindWindow(string strclassName, string strWindowName);

        [DllImport("user32.dll")]
        public static extern void SetWindowText(int h, String s);

        [DllImport("user32.dll")]
        private static extern int IsWindowVisible(int hwnd);

        [DllImport("user32.dll")]
        private static extern int SetForegroundWindow(int hwnd);

        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        private static extern int SetWindowLong(IntPtr hWnd, int Index, uint Value);

        [DllImport("user32.dll", SetLastError = true)]
        private static extern bool MoveWindow(IntPtr hwnd, int x, int y, int cx, int cy, bool repaint);

        [DllImport("user32.dll", EntryPoint = "GetSystemMetrics")]
        public static extern int GetSystemMetrics(int abc);

        [DllImport("user32.dll", ExactSpelling = true)]
        private static extern int SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags);

        // ---------- Start: Hook function. ----------

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern IntPtr SetWindowsHookEx(int idHook, LowLevelKeyboardProc lpfn, IntPtr hMod, uint dwThreadId);

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern bool UnhookWindowsHookEx(IntPtr hhk);

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);

        [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern IntPtr GetModuleHandle(string lpModuleName);

        // ---------- End: Hook function. ----------

        [StructLayout(LayoutKind.Sequential)]
        public struct DEVMODE
        {
            public const int CCHDEVICENAME = 32;
            public const int CCHFORMNAME = 32;
            public short dmBitsPerPel;
            public short dmCollate;
            public short dmColor;
            public short dmCopies;
            public short dmDefaultSource;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = CCHDEVICENAME)]
            public string dmDeviceName;
            public int dmDisplayFlags;
            public int dmDisplayFrequency;
            public int dmDitherType;
            public short dmDriverExtra;
            public short dmDriverVersion;
            public short dmDuplex;
            public int dmFields;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = CCHFORMNAME)]
            public string dmFormName;
            public int dmICMIntent;
            public int dmICMMethod;
            public short dmLogPixels;
            public int dmMediaType;
            public short dmOrientation;
            public int dmPanningHeight;
            public int dmPanningWidth;
            public short dmPaperLength;
            public short dmPaperSize;
            public short dmPaperWidth;
            public int dmPelsHeight;
            public int dmPelsWidth;
            public int dmPositionX;
            public int dmPositionY;
            public short dmPrintQuality;
            public int dmReserved1;
            public int dmReserved2;
            public short dmScale;
            public short dmSize;
            public short dmSpecVersion;
            public short dmTTOption;
            public short dmYResolution;
        }

        public enum GWL
        {
            GWL_WNDPROC = (-4),
            GWL_HINSTANCE = (-6),
            GWL_HWNDPARENT = (-8),
            GWL_STYLE = (-16),
            GWL_EXSTYLE = (-20),
            GWL_USERDATA = (-21),
            GWL_ID = (-12)
        }

        public enum SWP
        {
            SWP_NOSIZE = 0x0001,
            SWP_NOMOVE = 0x0002,
            SWP_NOZORDER = 0x0004,
            SWP_NOREDRAW = 0x0008,
            SWP_NOACTIVATE = 0x0010,
            SWP_FRAMECHANGED = 0x0020,
            SWP_SHOWWINDOW = 0x0040,
            SWP_HIDEWINDOW = 0x0080,
            SWP_NOCOPYBITS = 0x0100,
            SWP_NOOWNERZORDER = 0x0200,
            SWP_NOSENDCHANGING = 0x0400,
            SWP_DRAWFRAME = SWP_FRAMECHANGED,
            SWP_NOREPOSITION = SWP_NOOWNERZORDER,
            SWP_DEFERERASE = 0x2000,
            SWP_ASYNCWINDOWPOS = 0x4000
        }
......
......
......



P.S. -> Появляется только сообщение "Step1", а "Step2" и "Step3" не появляются=(
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.