Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[3.15.171.202] |
|
Сообщ.
#1
,
|
|
|
Всем привет!
Такой простой вопрос: мне надо отследить изменение времени как можно перехватить в C# какое-либо событие? Всем благодарен за помощь! |
Сообщ.
#2
,
|
|
|
Время отследить? Таймер не пробовал?
|
Сообщ.
#3
,
|
|
|
-=CAP=-
А на события -- обработчики подвесить. Либо уточнить вопросы. |
Сообщ.
#4
,
|
|
|
задача такая: когда пользователь пытается из менить системное время выдать ему сообщение, что менять нельзя и записать в журнал, что язер пытался изменить время.
|
Сообщ.
#5
,
|
|
|
Для этого тебе не нужен хук
Microsoft.Win32.SystemEvents.TimeChanged А ещё лучше огранич это правами в винде |
Сообщ.
#6
,
|
|
|
Цитата TerraGhost @ А ещё лучше огранич это правами в винде Это хорошо, но я не знаю как, т.к. это Windows Mobile 5.0 |
Сообщ.
#7
,
|
|
|
Вот такой кусок кода нашел - работает:
using System; using System.Diagnostics; using System.Windows.Forms; using System.Runtime.InteropServices; class TEST { private const int WH_KEYBOARD_LL = 13; private const int WM_KEYDOWN = 0x0100; private static LowLevelKeyboardProc _proc = HookCallback; private static IntPtr _hookID = IntPtr.Zero; public static void Main() { _hookID = SetHook(_proc); Application.Run(); UnhookWindowsHookEx(_hookID); } private static IntPtr SetHook(LowLevelKeyboardProc proc) { using (Process curProcess = Process.GetCurrentProcess()) using (ProcessModule curModule = curProcess.MainModule) { return SetWindowsHookEx(WH_KEYBOARD_LL, proc, GetModuleHandle(curModule.ModuleName), 0); } } private delegate IntPtr LowLevelKeyboardProc(int nCode, IntPtr wParam, IntPtr lParam); private static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam) { if ( (nCode >= 0) && (wParam == (IntPtr)WM_KEYDOWN) ) { int vkCode = Marshal.ReadInt32(lParam); if( ((Keys)vkCode == Keys.LWin)||((Keys)vkCode == Keys.RWin) ) { Console.WriteLine("{0} blocked!", (Keys)vkCode); return (IntPtr)1; } } return CallNextHookEx(_hookID, nCode, wParam, lParam); } [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); } но здесь перехватывается клава, параметр WH_KEYBOARD_LL равен 13 чему он будет равен, если надо перехватить изменение времени? предполагаю, что 8 |
Сообщ.
#8
,
|
|
|
Цитата -=CAP=- @ но здесь перехватывается клава, параметр WH_KEYBOARD_LL равен 13 WM_TIMECHANGE = 0x001E; P.S. Почитай интересно. |
Сообщ.
#9
,
|
|
|
juice, WM_TIMECHANGE - это сообщение.
Вот что нашел: WH_KEYBOARD = 2 WH_GETMESSAGE = 3 WH_CALLWNDPROC = 4 WH_CBT = 5 WH_SYSMSGFILTER = 6 WH_MOUSE = 7 WH_HARDWARE = 8 WH_DEBUG = 9 WH_SHELL = 10 WH_FOREGROUNDIDLE = 11 WH_CALLWNDPROCRET = 12 WH_KEYBOARD_LL = 13 WH_MOUSE_LL = 14 Когда в коде изменил значение WH_KEYBOARD_LL с 13 на 3 (WH_GETMESSAGE) в функцию HookCallback вообще не попадает, а если изменить на 4 (WH_CALLWNDPROC) - вообще система виснет! Я так понял, что мне нужен хук WH_GETMESSAGE, но почему тогда в функцию HookCallback никогда не заходит? |
Сообщ.
#10
,
|
|
|
Цитата -=CAP=- @ juice, WM_TIMECHANGE - это сообщение Я это прекрасно знаю. Сообщение которое посылается когда изменяется системное время. Попробуй с помощью АПИ перехватить его и обработать. Если бы ты программил под обычные винды на WinWorms я бы привел тебе пример. |
Сообщ.
#11
,
|
|
|
juice, буду премного благодарен, если будет хоть какой пример!
Потом уже разберусь с переводом на другую платформу |
Сообщ.
#12
,
|
|
|
public class FormTest: System.Windows.Forms.Form { private const int WM_TIMECHANGE = 0x001E; [System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name="FullTrust")] protected override void WndProc(ref Message m) { // Слушаем сообщения операционки switch (m.Msg) { case WM_TIMECHANGE: // Вставляем код для обработки того, что системное время изменилось break; } base.WndProc(ref m); } } Вот те пример работающий в WinWorms, но в Compact Framework нет возможности переопределить метод WndProc По тому линку, что я тебе кидал выше вроде есть пример с обработкой сообщений от винды. |
Сообщ.
#13
,
|
|
|
Вот, только C++ и на API, но зато можно отловить событие изменения времени юзером.
Прикреплённый файлSysTimeCangeDemo.rar (17.66 Кбайт, скачиваний: 235) |
Сообщ.
#14
,
|
|
|
Цитата juice @ но в Compact Framework нет возможности переопределить метод WndProc Вот такой код раздобыл: public class MyMessageWindow : MessageWindow { public static readonly int WM_TIMECHANGE = 0x001E; public static readonly int WM_USER = 0x0400; protected override void WndProc(ref Message m) { switch (m.Msg) { case WM_TIMECHANGE: MessageBox.Show("WM_TIMECHANGE"); case WM_USER: MessageBox.Show("WM_USER"); } base.WndProc(ref m); } } // А так его использовать MessageWindow msgWindow = new MyMessageWindow(); Message msg = Message.Create(msgWindow.Hwnd, MyMessageWindow.WM_USER, IntPtr.Zero, System.IntPtr.Zero); MessageWindow.SendMessage(ref msg); Но проблема в том, что при изменении времени руками (Пуск -> Настройка -> Система -> Часы и сигналы) ничего не отлавливается, а когда шлю сообщение WM_USER - работает без проблем. И второе: как можно сделать безоконное приложение? Если пишу Application.Run(...); - не получается: ошибка. Если не пишу, то программа просто закрывается. А мне нужно, чтоб эта прога работала без окон: чтоб ее видно не было. |