Blog. Just Blog

Быстрый поиск

Введите фрагмент названия статьи для поиска

Использование мультимедийного таймера

16.08.2020 | Категория: Образ мышления: Assembler | Автор: ManHunter
Интересная разновидность системных событий - высокоточный мультимедийный таймер. Гарантированный интервал срабатывания мультимедийных таймеров - около 10 миллисекунд против 50 миллисекунд обычных таймеров, устанавливаемых при помощи функции SetTimer. Кроме того, мультимедийные таймеры позволяют использовать обработчики, которые будут срабатывать в нужные интервалы, тогда как сообщения WM_TIMER от обычных таймеров идут через общую очередь. Если главный поток подвис, заснул или продолжительное время реагирует на какое-нибудь тяжелое сообщение, то таймеру придется ожидать, пока обработчик дойдет до него. Таким образом, добиться предсказуемой периодичности таймера будет очень сложно. Мультимедийные таймеры выполняются в собственном потоке, поэтому лишены перечисленных недостатков.

Слова словами, но давайте проверим это на практике. Для этого в простом оконном приложении установим обычный таймер на интервал 1 миллисекунду, вместе с этим создадим мультимедийный таймер с таким же интервалом срабатывания. При каждом срабатывании каждого из этих таймеров будет увеличен соответствующий счетчик. По истечении определенного времени, например, 5 секунд, сравним результаты.

Обработчик окна будет выглядеть примерно так. Для удобства я оставил только минимально необходимый код.
  1.         cmp     [msg],WM_INITDIALOG
  2.         je      wminitdialog
  3.         cmp     [msg],WM_TIMER
  4.         je      wmtimer
  5.         ...
  6.         ...
  7. wminitdialog:
  8.         ; Обнулить счетчики
  9.         mov     [dCntTim],0
  10.         mov     [dCntMM],0
  11.  
  12.         ; Получить начальное время
  13.         invoke  GetTickCount
  14.         mov     [dTime],eax
  15.  
  16.         ; Установить обычный таймер на интервал 1 мс
  17.         invoke  SetTimer,[hwnddlg],1,1,NULL
  18.  
  19.         ; Установить мультимедийный таймер на интервал 1 мс
  20.         TIME_PERIODIC = 0x0001
  21.         invoke  timeSetEvent,1,1,TimeProc,777,TIME_PERIODIC
  22.  
  23.         ...
  24.         ...
  25. wmtimer:
  26.         ; Увеличить счетчик по событию WM_TIMER
  27.         inc     [dCntTim]
  28.  
  29.         ; Прошло 5 секунд?
  30.         invoke  GetTickCount
  31.         sub     eax,[dTime]
  32.         cmp     eax,5000
  33.         jb      processed
  34.         jmp     wmclose
  35.  
  36. wmclose:
  37.         ; Удалить оба счетчика
  38.         invoke  KillTimer,[hwnddlg],1
  39.         invoke  timeKillEvent,[hTimer]
При инициализации окна устанавливается обычный и мультимедийный таймеры, при получении сообщения WM_TIMER увеличиваем обычный счетчик, а в функции-обработчике высокоточного таймера увеличиваем мультимедийный счетчик.
  1. ;-----------------------------------------------------------
  2. ; Обработчик высокоточного таймера
  3. ;-----------------------------------------------------------
  4. proc TimeProc uTimerID:DWORD,uMsg:DWORD,dwUser:DWORD,dw1:DWORD,dw2:DWORD
  5.         ; Увеличить счетчик по системному событию
  6.         inc     [dCntMM]
  7.         ret
  8. endp
Ну и момент истины. По результатам тестирования выяснилось, что за 5 секунд обычный таймер вызывается всего около 320 раз, тогда как обработчик мультимедийного таймера вызывается четко не менее 5000 раз. Что и требовалось доказать.

Читать статью целиком »
Просмотров: 312 | Комментариев: 3

Передача данных приложению с помощью WM_DROPFILES

09.07.2020 | Категория: Образ мышления: Assembler | Автор: ManHunter
Обрабатывать перетаскивание файлов в окно программы мы уже умеем, а сегодня узнаем, как сэмулировать это действие, то есть передать стороннему приложению список файлов через отправку сообщения WM_DROPFILES.

Начинаем с описания структуры DROPFILES, потому что FASM про нее ничего не знает. Так часто приходится писать подобное, что впору уже вводить какую-нибудь аббревиатуру, типа "Самостоятельно Описываем Структуры, Недостающие Интерфейсы, Константы Ассемблера" - "С.О.С.Н.И.К.А". Шутка.
  1. struct DROPFILES
  2.         pFiles dd ?
  3.         pt     POINT
  4.         fNC    dw ?
  5.         fWide  dw ?
  6. ends
Перед отправкой сообщения окну надо заполнить структуру DROPFILES. Значимыми полями являются pFiles - указатель на список файлов относительно начала структуры, и fWide - в каком формате передаются имена файлов, ASCII или юникод. Хотя на расположение списка файлов в памяти нет явных ограничений, обычно этот список размещается прямо за структурой и завершается нулевым байтом. Соответственно, указатель на этот список будет равен размеру структуры DROPFILES. Память под все это дело надо выделять с учетом нулевых разделителей между именами файлов и завершающим нулем.

Ну и сам код. Определяем размер и выделяем память, заполняем структуру и имена файлов, отправляем сообщение целевому окну.
  1.         ; Размер структуры DROPFILES
  2.         mov     ebx,sizeof.DROPFILES
  3.         inc     ebx
  4.  
  5.         ; Длина имени первого файла
  6.         invoke  lstrlen,file1
  7.         add     ebx,eax
  8.         inc     ebx
  9.  
  10.         ; Длина имени второго файла
  11.         invoke  lstrlen,file2
  12.         add     ebx,eax
  13.         inc     ebx
  14.  
  15.         ; Выделить память
  16.         invoke  GlobalAlloc,GMEM_SHARE+GMEM_MOVEABLE+GMEM_ZEROINIT,ebx
  17.         mov     [mem],eax
  18.         invoke  GlobalLock,eax
  19.         mov     [dfiles],eax
  20.  
  21.         ; Заполнить структуру DROPFILES
  22.         mov     edi,[dfiles]
  23.         mov     [edi+DROPFILES.pFiles],sizeof.DROPFILES
  24.         mov     [edi+DROPFILES.pt.x],0
  25.         mov     [edi+DROPFILES.pt.y],0
  26.         mov     [edi+DROPFILES.fNC],FALSE
  27.         mov     [edi+DROPFILES.fWide],FALSE
  28.         add     edi,sizeof.DROPFILES
  29.  
  30.         ; Дописать к ней передаваемые файлы
  31.         mov     esi,file1
  32. @@:
  33.         lodsb
  34.         stosb
  35.         or      al,al
  36.         jnz     @b
  37.  
  38.         mov     esi,file2
  39. @@:
  40.         lodsb
  41.         stosb
  42.         or      al,al
  43.         jnz     @b
  44.  
  45.         ; Завершающий нулевой байт
  46.         xor     eax,eax
  47.         stosb
  48.  
  49.         ; Отправить сообщение WM_DROPFILES
  50.         invoke  GlobalUnlock,[mem]
  51.         invoke  PostMessage,[destination_window],WM_DROPFILES,[mem],0
  52.         invoke  GlobalFree,[mem]
Обратите внимание, что отправка сообщения выполняется через PostMessage, иначе целевое приложение по какой-то причине может подвиснуть.

Читать статью целиком »
Просмотров: 248 | Комментариев: 0

Как в Windows 7 установить разные обои на разные мониторы

04.07.2020 | Категория: Software | Автор: ManHunter

Как в Windows 7 установить разные обои на разные мониторы

Посмотрел как-то на свои два монитора с одинаковыми обоями и подумал: а можно ли поставить на каждый из мониторов свой рисунок? Как оказалось, официальный ответ - в Windows 7 это сделать нельзя. На более новых системах это делается штатными средствами, но это ни в коем случае не их преимущество, а всего лишь небольшая недоработка Windows 7. И сегодня я расскажу, как эту недоработку можно устранить.

Читать статью целиком »
Просмотров: 583 | Комментариев: 3

Анимированные обои для рабочего стола Windows 7

22.06.2020 | Категория: Software | Автор: ManHunter

Анимированные обои для рабочего стола Windows 7

Одним из новшеств в Windows Vista стала возможность устанавливать видеофайлы в качестве обоев рабочего стола. Но в Windows 7 эту возможность по какой-то причине убрали. Тут я полностью соглашусь, что есть более интересные направления для применения мощностей компьютера, чем крутить видяшки на рабочем столе. Но спрос родил предложение, нашлись энтузиасты, которые выделили из Windows Vista необходимые компоненты для анимации и портировали их на Windows 7. Я знаю как минимум две программы, которые это делают.

Читать статью целиком »
Просмотров: 251 | Комментариев: 0

Как отключить блокировку компьютера в Windows

04.06.2020 | Категория: Software | Автор: ManHunter

Как отключить блокировку компьютера в Windows

Блокировка компьютера - обычная мера защиты системы от посторонних глаз и шаловливых рук, когда вам надо ненадолго отойти от компьютера. А можно ли вообще отключить эту блокировку? Честно говоря, я не придумал, для каких случаев это может понадобиться, но на всякий случай расскажу, как это сделать.

Читать статью целиком »
Просмотров: 876 | Комментариев: 5

Наверх
Powered by PCL's Speckled Band Engine 0.2 RC3
© ManHunter / PCL, 2008-2021
При использовании материалов ссылка на сайт обязательна
Время генерации: 0.12 сек. / MySQL: 3 (0.0471 сек.) / Память: 4.75 Mb
Наверх