На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
  
> Хуки в C# , C#, Framework 2.0, Windows Mobile 5.0
    Всем привет!

    Такой простой вопрос:

    мне надо отследить изменение времени
    как можно перехватить в C# какое-либо событие?

    Всем благодарен за помощь!
      Время отследить? Таймер не пробовал?
        -=CAP=-
        А на события -- обработчики подвесить. Либо уточнить вопросы.
          задача такая: когда пользователь пытается из менить системное время выдать ему сообщение, что менять нельзя и записать в журнал, что язер пытался изменить время.
            Для этого тебе не нужен хук

            Microsoft.Win32.SystemEvents.TimeChanged

            А ещё лучше огранич это правами в винде
            Сообщение отредактировано: TerraGhost -
              Цитата TerraGhost @
              А ещё лучше огранич это правами в винде

              Это хорошо, но я не знаю как, т.к. это Windows Mobile 5.0 :)
                Вот такой кусок кода нашел - работает:
                ExpandedWrap disabled
                  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 :)
                  Цитата -=CAP=- @
                  но здесь перехватывается клава, параметр WH_KEYBOARD_LL равен 13

                  WM_TIMECHANGE = 0x001E;

                  P.S. Почитай интересно.
                  Сообщение отредактировано: juice -
                    juice, WM_TIMECHANGE - это сообщение.

                    Вот что нашел:
                    ExpandedWrap disabled
                          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 никогда не заходит?
                      Цитата -=CAP=- @
                      juice, WM_TIMECHANGE - это сообщение

                      Я это прекрасно знаю. Сообщение которое посылается когда изменяется системное время. Попробуй с помощью АПИ перехватить его и обработать. Если бы ты программил под обычные винды на WinWorms я бы привел тебе пример.
                        juice, буду премного благодарен, если будет хоть какой пример!
                        Потом уже разберусь с переводом на другую платформу :)
                          ExpandedWrap disabled
                            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

                          По тому линку, что я тебе кидал выше вроде есть пример с обработкой сообщений от винды.
                          Сообщение отредактировано: juice -
                            Вот, только C++ и на API, но зато можно отловить событие изменения времени юзером.
                            Прикреплённый файлПрикреплённый файлSysTimeCangeDemo.rar (17.66 Кбайт, скачиваний: 235)
                              Цитата juice @
                              но в Compact Framework нет возможности переопределить метод WndProc

                              Вот такой код раздобыл:
                              ExpandedWrap disabled
                                    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(...); - не получается: ошибка.
                              Если не пишу, то программа просто закрывается.
                              А мне нужно, чтоб эта прога работала без окон: чтоб ее видно не было.
                              0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                              0 пользователей:


                              Рейтинг@Mail.ru
                              [ Script execution time: 0,0426 ]   [ 16 queries used ]   [ Generated: 3.05.24, 02:42 GMT ]