Blog. Just Blog

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

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

Tesseract OCR - система распознавания текста

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

Tesseract OCR - система распознавания текста

Вряд ли кто-то поспорит, что самой продвинутой системой распознавания текста в настоящее время является ABBYY FineReader. Я сам его постоянно использую при подготовке статей для сайта. Но вот возникла задача по распознаванию определенных текстов на большом количестве изображений (что-то типа схем или чертежей). Естественно, все должно делаться в автоматическом режиме, а результат был нужен уже вчера. Поискав возможные варианты решений, я остановился на Tesseract OCR. Это библиотека для распознавания текста с открытым исходным кодом, кроссплатформенная, с поддержкой юникода и более 100 языков "из коробки".

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

Отслеживание изменения метки тома

27.09.2023 | Категория: Образ мышления: Assembler | Автор: ManHunter
Несколько лет назад я демонстрировал, как можно легко и просто отслеживать изменения в каком-нибудь каталоге. Кроме отслеживания подобных глобальных движений, система позволяет отслеживать изменения более точечно, например, на отдельных объектах файловой системы. Для этого есть функция SHChangeNotifyRegister. В качестве примера я разберу, как можно отслеживать изменение метки тома. На самом деле функция SHChangeNotifyRegister обладает гораздо более широкими возможностями по отслеживанию различных системных уведомлений.

Сперва небольшое количество данных для работы, которые отсутствуют в инклудах FASM.
  1. struct SHChangeNotifyEntry
  2.         pidl       dd ?
  3.         fRecursive dd ?
  4. ends
  5.  
  6. SHCNRF_ShellLevel  = 0x0002
  7. SFGAO_FILESYSTEM   = 0x40000000
  8. SHCNE_RENAMEFOLDER = 0x00020000
Первым делом преобразуем имя отслеживаемого файла, диска или каталога в объект, для этого вызовем функцию SHParseDisplayName. После этого надо заполнить массив отслеживаемых объектов. У нас только один объект - диск C:\, но можно добавить любое их количество.
  1.         ; Настроить отслеживаемый объект
  2.         invoke  SHParseDisplayName,szWatch,NULL,\
  3.                 pidl,SFGAO_FILESYSTEM,NULL
  4.  
  5.         ; Заполнить массив отслеживаемых объектов
  6.         mov     eax,[pidl]
  7.         mov     [shentry.pidl],eax
  8.         mov     [shentry.fRecursive],FALSE
  9.  
  10.         ; Зарегистрировать обработчик уведомлений
  11.         invoke  SHChangeNotifyRegister,\
  12.                 [hwnddlg],\
  13.                 SHCNRF_ShellLevel,\
  14.                 SHCNE_RENAMEFOLDER,\
  15.                 WM_LABEL_CHANGED,\
  16.                 1,\
  17.                 shentry
  18.         mov     [cookie],eax
  19.  
  20.         ; Освободить неиспользуемую память
  21.         invoke  CoTaskMemFree,[pidl]
Так как мы отслеживаем изменение метки тома, а метка тома по сути является разновидностью каталога, то нам достаточно типа уведомления SHCNE_RENAMEFOLDER. Но никто не мешает скомбинировать типы уведомлений для отслеживания или вообще подписаться на все подряд, указав флаг SHCNE_ALLEVENTS.

Код WM_LABEL_CHANGED - это пользовательское сообщение окну приложения, его можно описать, например, как WM_LABEL_CHANGED = WM_USER + 200. При поступлении уведомления от системы именно это сообщение будет отправлено целевому окну обработчика. В параметре lParam находится код события, что очень полезно, когда приложение подписано сразу на несколько событий.

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

Пользовательская фильтрация в функции SHBrowseForFolder

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

Для реализации фильтрации используется технология COM, а это значит, что нам потребуется некоторое количество GUID'ов, структур и констант, которые не знает FASM.
  1. ; GUID {00000000-0000-0000-C000-000000000046}
  2. IID_IUnknown \
  3.     dd 000000000h
  4.     dw 00000h
  5.     dw 00000h
  6.     db 0C0h, 000h, 000h, 000h, 000h, 000h, 000h, 046h
  7.  
  8. ; GUID {C0A651F5-B48B-11D2-B5ED-006097C686F6}
  9. IID_IFolderFilterSite \
  10.     dd 0C0A651F5h
  11.     dw 0B48Bh
  12.     dw 011D2h
  13.     db 0B5h, 0EDh, 000h, 060h, 097h, 0C6h, 086h, 0F6h
  14.  
  15. ; IID_IFolderFilterSite Interface
  16. struct IFolderFilterSite
  17.     ; IUnknown
  18.     QueryInterface dd ?   ; 000h
  19.     AddRef         dd ?   ; 004h
  20.     Release        dd ?   ; 008h
  21.     ; IFolderFilterSite
  22.     SetFilter      dd ?   ; 00Ch
  23. ends
  24.  
  25. ; GUID {9CC22886-DC8E-11D2-B1D0-00C04F8EEB3E}
  26. IID_IFolderFilter \
  27.     dd 09CC22886h
  28.     dw 0DC8Eh
  29.     dw 011D2h
  30.     db 0B1h, 0D0h, 000h, 0C0h, 04Fh, 08Eh, 0EBh, 03Eh
  31.  
  32. ; IID_IFolderFilter Interface
  33. struct IFolderFilter
  34.     ; IUnknown
  35.     QueryInterface dd ?   ; 000h
  36.     AddRef         dd ?   ; 004h
  37.     Release        dd ?   ; 008h
  38.     ; IFolderFilter
  39.     ShouldShow     dd ?   ; 00Ch
  40.     GetEnumFlags   dd ?   ; 010h
  41.     refcount       dd ?
  42. ends
  43.  
  44. ; IID_IShellFolder Interface
  45. struct IShellFolder
  46.     ; IUnknown
  47.     QueryInterface   dd ?   ; 000h
  48.     AddRef           dd ?   ; 004h
  49.     Release          dd ?   ; 008h
  50.     ; IShellFolder
  51.     ParseDisplayName dd ?   ; 00Ch
  52.     EnumObjects      dd ?   ; 010h
  53.     BindToObject     dd ?   ; 014h
  54.     BindToStorage    dd ?   ; 018h
  55.     CompareIDs       dd ?   ; 01Ch
  56.     CreateViewObject dd ?   ; 020h
  57.     GetAttributesOf  dd ?   ; 024h
  58.     GetUIObjectOf    dd ?   ; 028h
  59.     GetDisplayNameOf dd ?   ; 02Ch
  60.     SetNameOf        dd ?   ; 030h
  61. ends
  62.  
  63. struct STRRET
  64.     uType dd ?
  65.     cStr  rb 260
  66. ends
  67.  
  68. SHCONTF_FOLDERS    = 0x00000020
  69. SHCONTF_NONFOLDERS = 0x00000040
  70.  
  71. SFGAO_FOLDER = 0x20000000
  72.  
  73. SHGDN_FORPARSING = 0x8000
  74.  
  75. BFFM_IUNKNOWN = 5
  76.  
  77. ; Флаги открытия диалога
  78. BIF_RETURNONLYFSDIRS   = 1
  79. BIF_DONTGOBELOWDOMAIN  = 2
  80. BIF_BROWSEINCLUDEFILES = 0x00004000
  81. BIF_NEWDIALOGSTYLE     = 0x00000040
Теперь немного теории. В callback-функцию BrowseCallbackProc диалога выбора помимо прочих сообщений приходит сообщение BFFM_IUNKNOWN, в параметре lParam которого системой передается указатель на интерфейс IUnknown. Через метод QueryInterface этого интерфейса можно получить указатель на интерфейс IFolderFilterSite. Затем с помощью метода SetFilter этого интерфейса нужно установить пользовательский фильтр. Фильтр представляет собой объект IFolderFilter, реализация методов которого ложится целиком и полностью на разработчика приложения. Благо их совсем немного.

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

Многострочные и юникодные данные в INI-файлах

15.06.2023 | Категория: Образ мышления: Assembler | Автор: ManHunter

Многострочные и юникодные данные в INI-файлах

При всех неоспоримых плюсах ini-файлов у них есть ряд недостатков, которые так любят приводить в пример их противники. Например, ini-файлы не поддерживают значения ключей в юникоде, а также не позволяют сохранять многострочные текстовые данные. Основные функции и способы работы с ini-файлами мы уже разобрали, осталось устранить выявленные недостатки и на этом можно будет закрыть тему.

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

Как получить список установленных принтеров

20.05.2023 | Категория: Образ мышления: Assembler | Автор: ManHunter

Как получить список установленных принтеров

Если требуется получить информацию об установленных в системе принтерах, то для этого есть несколько вариантов решения: с помощью PowerShell, WMI или различных языков программирования. У меня, как обычно, будет Ассемблер и WinAPI. Приведенный код получает информацию о всех принтерах в системе, в том числе сетевых.

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

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