Print This Post Универсальный конвертер текста 1.0

Вторник, 23. Июнь 2009
Раздел: Assembler, автор:

Очередной релиз от меня - программка для конвертации текста в разные представления и вычисления хэшей, написанная на ассемблере (masm32).
Имеется быстрое копирование и вставка текста, сохранение и открытие текстовых файлов.

Поддерживает конвертацию:
* Text -> URLEncode
* Text -> String.fromCharCode (ascii)
* Text -> String.fromCharCode (utf)
* Text -> base64
* Text -> MySQL char
* Text -> HEX
* Text -> BIN
* Text -> chr()
* Text -> MSSQL char
* Text -> PostgreSQL
* Text -> MD5
* Text -> SHA1
* Text -> &#xxx; (ascii)
* Text -> &#xxx; (utf)
* Text -> \xhh
* Text -> %XX
* Text -> VB chr$()
* Text -> C# (char)
* Text -> Транслит
* URLEncoded -> Text
* base64 -> Text

Скриншот:

Скачать exe (10кб) и исходные коды: ZIP

В общем исходный код программки ничем не отличается от тех, что я выкладывал раньше, но есть несколько интересных особенностей, которые я опишу дальше.

Я рассмотрю:
[+] как создавать формы в стиле XP (современный вид элементов управления) с помощью программы ResEd
[+] как создавать и использовать в программе Unicode-строки, в том числе на русском языке
[+] как делать всплывающие подсказки к текстовым полям
[+] как использовать Windows CryptoAPI для генерации хэшей
[+] как использовать буфер обмена Windows для копирования и вставки текста

Напомню, что я использую в коде некоторые удобные макросы из файла macros/macros.asm, входящего в пакет masm32.

1. Как создавать формы в стиле XP (современный вид элементов управления) с помощью программы ResEd?
ResEd - маленькая бесплатная утилита для удобного создания файлов ресурсов.
Скачать его можно отсюда: ResEd.
Открываем редактор, создаем новый проект (File - New Project), добавляем к нему новое диалоговое окно (Project - Add Dialog).
Устанавливаем желаемые параметры окна во вкладке справа внизу, добавляем необходимые элементы управления, устанавливаем их параметры.
Чтобы все элементы выглядели в стиле XP, нужно добавить XP Manifest (Project - Add XP Manifest).
Сохраняем проект - получаем два файла - сам проект *.rc и манифест (xpmanifest.xml).
После того, как мы сохранили проект и вышли из редактора, надо немного подготовить файл ресурсов перед его использованием.
Открываем файл ресурсов (*.rc) в блокноте и добавляем в начало строку:

#include "\masm32\include\resource.h"

После этого удаляем строку (необязательно, но без этого у меня проект не запускался):

#define имя_нашей_формы 1000

Сохраняем файл - он готов к использованию в проекте.
Как же скомпилировать исходный код в asm вместе с файлом ресурсов в exe?
Для этого я использовал такой bat-файл (допустим, назовем его COMPILE.bat):

@echo off
cls
SET PATH=C:\Masm32\bin
SET INCLUDE=C:\Masm32\INCLUDE
SET LIB=C:\Masm32\LIB
 
Rc.exe /v %1.rc
 
ML /nologo -c -coff %1.asm
if errorlevel 1 goto terminate
 
LINK /nologo %1.obj %1.res /SUBSYSTEM:WINDOWS /STUB:64stub.exe /FILEALIGN:512 /VERSION:4.0 /RELEASE /BASE:0x400000
if errorLevel 1 goto terminate
 
echo OK
 
:terminate

Вызывается этот батник так:
- положите его в папку вместе с исходным кодом и файлом ресурсов *.rc (файлы *.rc и *.asm должны называться одинаково, например, converter.asm и converter.rc, в той же папке должен лежать xpmanifest.xml)
- в командной строке (cmd) перейдите в директорию с этими файлами (с помощью команды cd)
- выполните команду COMPILE имя_проекта (например COMPILE converter)
Если будет выведено "OK" - exe-файл был успешно создан в той же директории.

2. Как создавать и использовать в программе Unicode-строки,, в том числе и на русском языке?
В последней версии пакета masm32 имеется поддержка Unicode-строк и функций, но вот создать с его помощью русскую
Unicode-строку проблематично. Я для этого использовал набор макросов с wasm.ru, который позволяет делать русские Unicode-строки.
К сожалению, макрос создания строк содержит недостаток - каждый 120-й символ просто убирается из строки.
Я поправил недочет этого макроса, скачать исправленный можно тут: windows.asm.

Теперь, чтобы создать русскую Unicode-строку, подключаем макрос с помощью include к коду и пишем так:

.data
$$$STRINGW имя_переменной,"текст"
dw 0 ;терминирующие два нулевых байта
 
;или можно так:
$$$ZSTRINGW имя_переменной,"текст"

Соответственно, такие строки сожно использовать в любых Unicode-функциях (с постфиксом W, например, MessageBoxW).

3. Как делать всплывающие подсказки к текстовым полям?
Начиная с Win XP, у элементов управления Edit появилась возможность создавать всплывающие подсказки, как на первом скриншоте, я покажу, как такое реализовать.
Для показа такой подсказки необходимо послать текстовому полю сообщение EM_SHOWBALLOONTIP, а самой подсказкой управляет структура EDITBALLOONTIP.
Странно, но в inc-файлах масма32 такой структуры не оказалось, поэтому приходится задавать ее самим:

EDITBALLOONTIP STRUCT
    cbStruct dd ? ;размер структуры в байтах = 16
    pszTitle dd ? ;указатель на Unicode-строку с заголовком
    pszText dd ?  ;указатель на Unicode-строку с текстом
    ttiIcon dd ?  ;иконка структуры - TTI_INFO, TTI_WARNING, TTI_ERROR, TTI_NONE или TTI_INFO_LARGE, TTI_WARNING_LARGE, TTI_ERROR_LARGE
EDITBALLOONTIP ENDS

Далее, если у нас есть Edit-контрол с id=1003, то отобразить подсказку можно так:

.data
  $$$STRINGW pszTitle,"Заголовок" ;эти макросы описаны в п.2
  dw 0
  $$$STRINGW pszText,"Текст подсказки"
  dw 0
.data?
  btt EDITBALLOONTIP <>
.code
    mov btt.pszTitle,offset  ;заполняем структуру
    mov btt.pszText,offset pszText
    mov btt.ttiIcon,TTI_INFO
    mov btt.cbStruct,16
 
    invoke SendDlgItemMessage,hWnd,1004,EM_SCROLLCARET,0,0 ;скроллим поле ввода, чтобы была видна каретка - подсказка отображается именно в этом месте
    invoke SendDlgItemMessage,hWnd,1004,EM_SHOWBALLOONTIP,0,offset btt ;отображаем подсказку

4. Как использовать Windows CryptoAPI для генерации хэшей?
Для примера я покажу, как генерировать хэши MD5 и SHA1 для заданных строк.
Во-первых, для работы с крипто апи необходимо подключить inc-файл advapi32.inc и lib-файл advapi32.lib.
Приведу пример с комментариями из кода конвертора:

;здесь я определяю типы данных и константы, которых почему-то не оказалось в windows.inc
HCRYPTHASH equ dd
HCRYPTPROV equ dd
ALG_CLASS_HASH equ 32768
 
;...
 
.data? ;в секции неинициализированных данных определяю несколько переменных
        hHash HCRYPTHASH ?
        hProv HCRYPTPROV ?
        hash_size dd ?     ;сюда будет возвращаться размер хэша
        hash db 41 dup(?)  ;а сюда сам хэш
 
;...
 
.code
 
;...
 
      .if eax==9 || eax==10 ;если мы генерируем MD5 или SHA1 хэш
        push eax
        mov textlen,FUNC(lstrlen,membuf) ;записываем длину введенного текста в первое поле ввода
        invoke CryptAcquireContext,offset hProv, NULL, NULL, PROV_RSA_FULL, 0 ;создаем контекст для создания хэшей
        ;PROV_RSA_FULL как раз позволяет генерировать мд5 и sha1 (<a href="http://msdn.microsoft.com/en-us/library/aa387448(VS.85).aspx">тут - подроблее</a>).
 
        pop eax
        ;создаем хэш
        .if eax==9 ;если генерируем md5
          invoke CryptCreateHash,hProv,CALG_MD5,0,0,offset hHash ;тут мы указываем провайдер для криптования - hProv, для которого ранее создали контекст
        .else ;если sha1
          invoke CryptCreateHash,hProv,CALG_SHA1,0,0,offset hHash
        .endif
 
        invoke CryptHashData,hHash,membuf,textlen,0 ;генерируем хэш из строки в памяти membuf с длиной textlen
        invoke CryptGetHashParam,hHash,HP_HASHSIZE,offset hash_size,offset dwSize,0 ;получаем длину хэша
        invoke CryptGetHashParam,hHash,HP_HASHVAL,offset hash,offset hash_size,0 ;получаем его значение
        invoke CryptDestroyHash,hHash ;удаляем хэш
        invoke CryptReleaseContext,hProv,0 ;освобождаем контекст
 
        mov esi,membuf2
        mov edi,offset hash
 
        mov ecx,0
      hash_get: ;начинаем преобразовывать хэш в приемлемый текстовый вид
        push ecx
        movzx eax,byte ptr [edi]
        invoke wsprintf,esi,chr$("%2.2x"),eax
 
        inc edi
        add esi,2
 
        pop ecx
        inc ecx
        cmp ecx,hash_size
      jne hash_get
 
      ;теперь в памяти membuf2 содержится хэш в текстовом виде, и его можно вывести или использовать по своему усмотрению

5. Как использовать буфер обмена Windows для копирования и вставки текста?
Опять-таки приведу пару примеров из кода конвертора.

Копирование текста из текстового поля с id=1004:

      invoke OpenClipboard,hWnd ;откроем буфер обмена
      test eax,eax
      jz endcopy ;если не удалось открыть - выходим
 
      invoke EmptyClipboard ;очищаем буфер обмена
 
 
      invoke GetDlgItemText,hWnd,1004,membuf,buflen-1 ;получаем текст из текстового поля в память membuf
      inc eax
 
      mov clipboard,FUNC(GlobalAlloc,GMEM_MOVEABLE,eax) ;выделяем память для копирования
      test eax,eax
      jz endcopy2 ;если не удалось выделить - выходим и закрываем буфер обмена
 
      invoke GlobalLock,clipboard ;блокируем память и получаем указатель на первый байт этой памяти
 
      invoke lstrcpy,eax,membuf ;копируем туда текст
 
      invoke GlobalUnlock,clipboard ;разблокируем память
 
      invoke SetClipboardData,CF_TEXT,clipboard ;записываем данные в буфер обмена
 
 
      endcopy2:
      invoke CloseClipboard ;закрываем буфер обмена
 
      endcopy:

Вставка текста в поле с id=1003:

      invoke IsClipboardFormatAvailable,CF_TEXT ;есть ли в буфере обмена текстовые данные в ASCII?
      test eax,eax
      jz endpaste ;если нет - выходим
 
      invoke OpenClipboard,hWnd ;откроем буфер обмена
      test eax,eax
      jz endpaste ;если не удалось открыть - выходим
 
      mov clipboard,FUNC(GetClipboardData,CF_TEXT) ;получаем указатель на первый байт памяти
      test eax,eax
      jz endpaste2 ;если не удалось - выходим и закрываем буфер
 
      invoke GlobalLock,eax ;блокируем память и получаем указатель на первый байт этой памяти
      test eax,eax
      jz endpaste2 ;если не удалось - выходим и закрываем буфер
 
      invoke SetDlgItemText,hWnd,1003,eax ;устанавливаем текст в поле для ввода из этой памяти
 
      invoke GlobalUnlock,clipboard ;разблокируем память
 
      endpaste2:
      invoke CloseClipboard ;закрываем буфер обмена
 
      endpaste:

Также рекомендую почитать

 Обсудить на форуме


Получать обновления на почту:     

Метки: , , , , .

Комментариев: 11 к “Универсальный конвертер текста 1.0”


  1. webzer :

    на xp при кодировке в md5,программа виснет

    [Ответить]

    dx:

    Проверял в xp и в висте, работает. На скрине собственно процесс получения мд5 от строки в xp)

    [Ответить]


  2. Users :

    А в прграмме есть возможность кодить ссыль которая принимаятся контакотом ?

    [Ответить]

    dx:

    А в прграмме есть возможность кодить ссыль которая принимаятся контакотом ?

    Нет, это просто помогает перекодировать текст в разные представления. Скрипт для кодирования ссылок контакта - несколькими постами ниже тут.

    PS. Только что обновил программу, заглавные русские буквы в транслит не переводила)

    [Ответить]

  3. А при переводе в двоичную систему должно быть вначале 0b? Программка в целом хорошая, но помоему одну из кнопок "Кодировать" или "Копировать" нужно переименовать :)

    [Ответить]


  4. Chrome~ :

    Большое спасибо, dx

    [Ответить]


  5. Chrome~ :

    По каким книгам ты изучал Assembler?

    [Ответить]

    dx:

    "Язык ассемблера для процессоров Intel" - Кип Р. Ирвин. А в основном - много гугла, мсдна, разбор примеров из пакета masm32, там много чего можно почерпнуть.

    [Ответить]


  6. Tigger :

    Сделай, пожалуйста, чтобы в трей сворачивать можно было ;)

    [Ответить]


  7. Кусок :

    Как тебе не лень столько кодить на асме ?

    [Ответить]


  8. Дмитрий :

    Спс, а то сам уже хотел писать.
    тока плохо что нет обратной операции

    [Ответить]


Оставьте ваш комментарий