Извините за длинный пост!Боюсь, у меня есть кое-какие объяснения ... У меня есть приложение (в Unity3d, но для Windows), которое не использует WinForms, поэтому я не могу использовать класс Cursor, который является частью пространства имен System.Windows.Forms.,Но все же я хотел бы иметь возможность установить текущую форму курсора.
После долгих исследований и большого количества поисков в Google я обнаружил, что это возможно при использовании вызовов P / Invoke для определенных методов.в user32.dll.Я понял (вроде), работая:
Найдите дескриптор окна, используя:
[DllImport("user32.dll")]
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
И укажите null для имени класса и заголовок окна для имени ветра.Затем используйте возвращенный IntPtr для вызова этого:
[DllImport("user32.dll")]
public static extern IntPtr SetClassLong(IntPtr hwnd, int index, IntPtr dwNewLong);
И укажите «-4» для индекса, чтобы нацелить указатель на WindowProc, который обрабатывает все сообщения окна нижнего уровня, и затем используйте:
System.Runtime.InteropServices.Marshal.GetFunctionPointerForDelegate()
Чтобы создать собственный указатель на новый делегат WndProc, который я реализую в своем управляемом коде.Его подпись выглядит следующим образом:
public long WndProc(IntPtr hwnd, uint msg, uint wparam, int lparam);
Таким образом, я в основном переопределяю собственную оконную процедуру с управляемым обратным вызовом, и тогда я отвечаю за обработку всех оконных сообщений.Но я не заинтересован в переписывании всей реализации для стандартного оконного процесса, я просто хочу иметь возможность контролировать способ рисования формы курсора мыши, когда курсор находится над окном.Итак, чтобы сделать это, я могу вызвать процедуру окна по умолчанию с этой функцией:
[DllImport("user32.dll")]
public static extern long DefWindowProc(IntPtr hwnd, uint msg, uint wparam, int lparam);
И затем сразу после этого установить курсор на что-то другое, используя:
[DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
private static extern IntPtr SetCursor(IntPtr hCursor);
Этот видработ.:) Я говорю «что-то вроде», потому что я вижу небольшое мерцание, которое возникает из-за того, что процедура окна по умолчанию сначала устанавливает курсор на курсор класса, а затем сразу после этого моя реализация устанавливает его на пользовательский курсор, который я хочу использоватьSetCursor.Эту ситуацию можно исправить, установив курсор класса в нуль.Это приводит к тому, что система не рисует курсор и ожидает, что приложение установит курсор для каждого сообщения окна, и это именно то, что я делаю, так что это остановит их борьбу за то, кто установит курсор, и устранитмерцает.Это задокументировано в MSDN по адресу:
http://msdn.microsoft.com/en-us/library/windows/desktop/ms648393%28v=vs.85%29.aspx
Там, где они объясняют, что нужно установить курсор класса в нуль.Но вот где мои знания не хватает.:( Курсор класса устанавливается с помощью SetClassLong, как объяснено в статье выше.
Но тип данных для нового значения курсора - IntPtr. Этот тип данных не может иметь значение null, компилятор жалуется, если я передаю ноль,и передача в IntPtr.zero не работает. Итак, как мне выполнить то, что советует статья? Как установить курсор класса на ноль, используя P / Invoke?