логотип нашего сайта о программировании для начинающих

Программирование на ассемблере для начинающих. Ассемблер gas под linux, fasm под windows, tasm под dos, и многое другое.


Сайт для программистов, начинающих кодеров, и людей, желающих заняться программированием.



Меню невыпадающее
Программистам : Другое :

Программа на fasm. Тест на знание неправильных глаголов английского языка.

;;;
;;; в общем сия программа предназначена для зубрёжки
неправильных глаголов

;;; для функционирования необходим текстовый файл под
названием

;;; 'irregverbs.txt' и иконка (я перерисовал иконку из
examples/minipad)

;;; структуру текстового файла смотрите в самом файле - там
ничего сложного


;;;
;;; кстать, сменил ассемблянт на fasm 1.67.26
(вынужденно)


;;; и пришлось вносить некоторые изменения в синтаксисе, а
именно

;;; 1) в директиве include более не нужно писать

'%include%\win32a.inc' (пример), а просто 'win32a.inc'

;;; т.е. '%include%\' убираем
;;; 2) при описании процедур вместо
;;; # proc MyProc, param1,param2
;;; # enter
;;; # push ebx esi edi
;;; # ; - код процедуры
;;; # pop edi esi ebx
;;; # return
;;; пишем следующим образом
;;; # proc MyProc param1,param2 (запятая не имеет
значения - можно и поставить)

;;; # push ebx esi edi
;;; # ; - код процедуры
;;; # pop edi esi ebx
;;; # ret
;;; # endp
;;; с другими изменениями в синтаксисе я пока не
сталкивался

;;;

format PE GUI 4.0 ; - как обычно формат портабельный
исполнимый, версия гуи 4,0

entry start ; - точка входа метка start

include 'win32a.inc' ; подключаем инклуд

;;; здесь мы описываем константы - так проще. Это всё объекты
блока ресурсов. Названия при ассемблировании будут заменены числами.

IDD_DLG = 37 ;#
IDE_FIRST = 101 ;#
IDE_SECOND = 102 ;# названия придумываем
исключительно из

IDE_THIRD = 103 ;;; ;# соображений удобства;
IDS_DESCRIPTION = 201 ;# IDE_бла-бла-бла - editbox
IDS_SCORES = 202 ;; ;# IDS_ - static
IDS_FIRST = 203 ;# IDB_ - button
IDS_SECOND = 204 ;# IDD_ - dialogbox
IDS_THIRD = 205 ;;; ;# числа тоже можно поставить
любые

IDB_NEXT = 401 ;# (главное не запутаться и не
перегибать)

IDB_RESET = 402 ;#
;;; далее определяем структуры и макросы
;;; для тех кто не знает - определение структур и макросов не
занимает в памяти ни байта

;;; это всё придумано для удобства
;;; там где будет определён макрос - ассемблянт вставит его
код

;;; ну а структура - это просто набор меток и данных которые
действительны только при

;;; инициализации структуры (переменной как
структуры)

;;;;; fparam - структура, содержащая параметры файла
struc fparam ; имя структуры
{
.path db 'irregverbs.txt',0 ; путь к текстовому файлу с
глаголами (в фаловой системе)

.strings db 0 ; строк (всего)
.size dd 0 ; размер файла в байтах
.pointer dd 0 ; указатель на область памяти - начало
файла в памяти

.true dw 0 ; правильных
.false dw 0 ; неправильных
.done db 0 ; сделано
.pointerpos dd 0 ; позиция указателя
.first rb 20 ; первая фрорма глагола
.second rb 20 ; вторая
.third rb 20 ; третья
.description rb 216 ; описание
}

;;;; макрос readbsn читает строку по адресу в esi по байтам в
строку с адресом mspoint

;;;; до тех пор пока не встретит в строке symbol
;;;; встретив символ переходит на код, идущий вслед за
макросом

;;;; изменения: esi,al,ecx; стэк не используется

macro readbsn mspoint,symbol,metka ;; \ readbsn = имя макроса,
mspoint = указатель на строку,

{ ;;; \ symbol = символ, metka = метка
xor ecx,ecx ; обнуляем ecx
@@: ; анонимная метка - начало цикла
lodsb ; читаем байт (из строки садресом в esi)
test al,al ; тестим (or al,al - только операнды остаются
неизменными)

jz metka ; если ноль, прыжок на метку metka
cmp al,symbol ; сравниваем с символом
je @f ; если совпадает, выходим из цикла
mov byte [mspoint+ecx],al ; если нет, помещаем байт по
адресу [mspoint+ecx]

inc ecx ; увеличиваем ecx на 1
jmp @b ; переходим в начало цикла
@@: ; анонимная метка - выход из цикла
}
; раз уж начал использовать анонимные метки - расскажу про
них вкратце

; @@: - определение анонимной метки - их модно определить
великое множество

; @b, @r - ссылается на ближайшую предыдущую анонимную
метку (before)

; @f - на ближайшую последующую анонимную метку
(follow)

; например:
;#
;# @@: <----------------+
;# ; some code |
;# jmp @b ---------+
;# ; some code
;# jmp @f ---------+
;# ; some code |
;# @@: <----------------+
;#

;;;; макрос countbn подсчитывает количество символов
symbol

;;;; в строке с адресом в esi до тех пор пока
;;;; не встретит null, результат подсчёта в cl
;;;; изменения: esi, al, cl; стэк не используется

macro countbn symbol ; countbn - имя макроса, symbol -
символ

{
xor cl,cl ; обнуляем cl
@@: ; анонимная метка - начало цикла
lodsb ; читаем байт (из строки садресом в esi)
test al,al ; тестим
jz @f ; если ноль, то выходим из цикла
cmp al,symbol ; сравниваем с символом
jne @b ; если не совпадает, то идём в начало цикла
inc cl ; если совпадает (на самом деле не не совпадает) -
увеличиваем cl на 1

jmp @b ; переход в начало цикла
@@: ; анонимная метка - выход из цикла, выходим
только если прочитали ноль

}

;;;; макрос sevennull онуляет строки first,second,third
;;;; и f.first,f.second,f.third,f.description
;;;; обнуляет 20 символов начиная с начала (215 для обоих
description)

;;;; изменения: eax, ebx, ecx, edx; стэк не используется

macro sevennull ; имя макроса
{
mov ecx,20 ; помещаем в ecx 20 - 20 символов подлежат
обнулению

@@: ; анонимная метка начало цикла
mov byte [first+ecx],0 ; ноль по адресу first+ecx
mov byte [second+ecx],0 ; аналогично: 0 ->
[second+ecx]

mov byte [third+ecx],0 ; 0 -> [third+ecx]
loop @b ; уменьшаем ecx на 1, если не равен нулю, то
прыжок в начало цикла (@@:)

mov ecx,20
@@: ;;|
mov byte [f.first+ecx],0 ;;|
mov byte [f.second+ecx],0 ;;| то ж самое, только f.first,
f.second, f.third

mov byte [f.third+ecx],0 ;;|
loop @b ;;|
mov ecx,215 ;
@@: ;
mov byte [f.description+ecx],0 ; тут тоже тока для
f.description

loop @b ;
}

;;;; макрос cmptstr сравнивает две строки указатель на первую
в esi, на вторую в edx

;;;; в случае несовпадения переходит на метку fmetka
;;;; при окончании строки (символ null) переходит на
nmetka

;;;; изменения: edi, esi; стэк не используется
; esi=first, edi=f.first

macro cmptstr fmetka ; cmptstr = имя макроса, fmetka =
метка (на неё прыгаем, если не равны)

{
@@: ; анонимная метка - начало цикла
cmpsb ; сравниваем символы по адресам в esi и edi;
esi+1, edi+1

jne fmetka ; если не равны - переходим на метку
fmetka

cmp byte [esi],0 ; сравниваем с нулём
jz @f ; follow ; если ноль - выход из цикла
jmp @b ; before ; переход в начало цикла (если равны и не
ноль)

@@: ; аннонимная метка - выход из цикла
}

section '.data' data readable writeable ; секция данных
читаемых и писуемых, бла-бла-бла, всё как обычно


first rb 20 ; резервируем 20 байт
second rb 20 ; -"-
third rb 20 ; -"-
f fparam ; определяем переменную f как структуру
fparam

strue db 'true',0 ; 3-е ASCIIZ строки
sfalse db 'false',0 ;
sscores db 'done/all = 000/000',0Ah,'true/false = 000/000',0
;11,12,13/15,16,17 32,33,34/36,37,38
; числа выписаные после переменной в коментарии -
смещение в адресном пространстве

; относительно sscores (sscores указывает на превый символ
строки)

; нулей 000/000 - они нам пригодятся впоследствии
; 0Ah - шестнацатиричный код перевода строки в ASCII (enter
короче говоря)

bytescount dd ? ; для чтения файла нужна
sherror db 'mission faild',0 ; 3 строки выдаваемые при
возникновении ошибок

saerror db 'allocation faild',0
soerror db 'file opening faild',0
slast db 'больше нетути',0 ; сообщение о конце файла
last db 0 ; идентифицирует последнюю строку
snull db 0 ; пустая строка

section '.code' code readable executable ; секция кода читаемая
исполнимая бла-бла-бла

start: ; метка начала кода - святая святых

;###############################################################
###########################;

;### выделение памяти под файл и чтение из файла в эту
память #############################;

invoke CreateFile,f.path,GENERIC_READ,0,0,OPEN_EXISTING,0,0
; API функция - создает файл или открывает
существующий (и не только).

; Передаваемые параметры:
; 1 - указатель на ASCIIZ строку содержащую путь к
файлу в файловой системе,

; 2 - тип доступа к объекту - любая комбинация
следующих флагов:

; 0 - "определяет аттрубуты файла не
присоединяясь к нему" - вот и думай что это значит??? (наверное просто получить
хендл и всё)

; GENERIC_READ - доступ по чтению
; GENERIC_WRITE - доступ по записи
; 3 - набор флагов разделяющих объект
; 0 - не делить объект (пока мы не закроем хендл
из файла никто более ничего не прочитает)

; FILE_SHARE_DELETE - (работает тока у NT) - тоже
что и 0, но после закрытия файл(объект) будет удалён

; FILE_SHARE_READ - доступен другим для
чтения

; FILE_SHARE_WRITE - доступен другим для
записи

; 4 - могут ли процессы потомки использовать указатель
(0 - не могут)

; 5 - совершаемое действие (один из флагов)
; CREATE_NEW - создает новый файл (если
существут - неудача)

; CREATE_ALWAYS - создает новый файл (если
существут - перезаписывает)

; OPEN_EXISTING - открывает существующий (нету
- неудача)

; OPEN_ALWAYS - открывает файл (если нету -
создает)

; TRUNCATE_EXISTING - открывает файл, при этом
обнуляет его размер (должен быть уровень доступа GENERIC_WRITE, если файл не
существует - неудача)

; 6,7 - не важно (смотри MSDN)
mov edi,eax ; сохраняем хендл файла в edi (ошибки здесь не
рассматриваем, если всё норм - то хендл возвращается функцией в eax)

invoke GetFileSize,edi,0 ; API-функция - берём размер
файла

; параметры: 1) - хендл(указатель) файла
; 2) - максимальный размер файла
mov [f.size],eax ; в eax имеем возвращённыйф размер
файла, сохраняем его в [f.size]

inc eax ; увеличивам eax на 1 для выделения
памяти

; VirtualAlloc выделяет память и обращает выделеный
участок в нули, теперь в конце у нас будет 0

; (в конце выделеной области 0, а не последний символ
файла, для этого и увеличиваем на 1)

; выдляем память для чтения файла в RAM
; используем функцию VirltualAlloc, она позволяет
зарезервировать участок памяти

; заданого размера и обращает эту память в нули
; параметры:
; 1) начальный адрес региона,
; 2) размер региона (в байтах разумеется),
; 3) тип резервирования: а) MEM_COMMIT - эта память
может быть сброшена в файл подкачки

; б) MEM_RESERVE - этот участок памяти
не может быть сброшен в файл подкачки

; он будет присутствовать в
физической памяти всегда, пока эту память процесс не ввысвободит

; в) MEM_TOP_DOWN - зарезервировать
виртуальную память,

; которая будет
соответствовать максимально возможному физическому адресу;

; 4) тип доступа к памяти: PAGE_READONLY
; PAGE_READWRITE
; PAGE_EXECUTE позволяет передавать
управление этому региону попытка чтения или записи приводит к нарушению прав
доступа.

; PAGE_EXECUTE_READ
; PAGE_EXECUTE_READWRITE
; PAGE_NOACCESS
; (я надеюсь тут всё понятно)

invoke VirtualAlloc,0,eax,MEM_COMMIT,PAGE_READWRITE ;
выделяем память

test eax,eax ; в случае ошибки в eax будет ноль,
поэтому провряем eax

jz aerror ; если не получилось выделить память
переходим к сообщению об ошибке

mov [f.pointer],eax ; если всё ноормально, то
сохраняем указатель на область выделеной памяти в [f.pointer]

; читаем из файла в память
invoke ReadFile,edi,[f.pointer],[f.size],bytescount,0 ; ну тут edi -
указатель на файл,

; [f.pointer] - указатель на область памяти (в которую
читаем)

; [f.size] - размер файла
; два последних параметра: указатель на переменную
(dword) и 0 (не берите в голову их предназначение)

test eax,eax ; провряем eax
jz oerror ; если 0, то прыгаем на сообщени об
ошибке

invoke CloseHandle,edi ; закрываем файл, он нам больше не
понадобится

;; определяем кол-во строк в файле
mov esi,[f.pointer] ; в esi область памяти с прочтённым в неё
файлом

countbn 0Ah ; с помощью макроса считаем сколько в файле
переводов строки (0Ah - перевод строки по ASCII)

dec cl ; кол-во переводов строки - 1 = кол-во строк
(последняя не считается - см. текстовый файл)

mov [f.strings],cl ; сохраням в [f.strings]

;###############################################################
###########################;

;####################################### диалоговое окно
###########################################;


invoke GetModuleHandle,0 ; получаем хендл
test eax,eax ; если не получается получить хендл - то
jz herror ; прыгаем на сообщени об ошибке
invoke DialogBoxParam,eax,IDD_DLG,HWND_DESKTOP,DialogProc,0 ; создаем диалоговое окно
; eax - хендл
; IDD_DLG - ресурсы
; владелец (рабочий стол)
; процедура окна
; пеpедается в паpаметpе lParam сообщения
WM_INITDIALOG (мы ничё не передаём - 0)

jmp exit ; переходим на выход из программы
herror: ;|
invoke MessageBox,NULL,sherror,NULL,MB_ICONERROR+MB_OK ;|
jmp exit ;|
aerror: ;| сообщения об ошибках
invoke MessageBox,NULL,saerror,NULL,MB_ICONERROR+MB_OK ;|
jmp exit ;|
oerror: ;|
invoke MessageBox,NULL,soerror,NULL,MB_ICONERROR+MB_OK ;|
exit:
invoke ExitProcess,0 ; выход из программы
;###############################################################
###########################;

;###################### процедура диалогового окна
########################################;


proc DialogProc hwnddlg,msg,wparam,lparam
push ebx esi edi
cmp [msg],WM_INITDIALOG
je .wminitdialog
cmp [msg],WM_COMMAND
je .wmcommand
cmp [msg],WM_CLOSE
je .wmclose
xor eax,eax
jmp .finish
; инициализация окна
.wminitdialog:
xor ax,ax ; обнуляем ax
mov al,[f.strings] ; в al помещаем число строк (из
[f.strings])

mov edx,sscores+14 ; в edx помещаем указатель на
замещаемые символы в строке (3 шт. по убыванию)

call toASCII ; вызываем функцию toASCII (см. внизу
секции кода)

invoke SetDlgItemText,[hwnddlg],IDS_SCORES,sscores ; замена
текста IDS_SCORES

mov esi,[f.pointer] ; указатель на файл в esi
mov [f.pointerpos],esi ; указатель в f.pointerpos - позиция
указателя

readbsn f.description,'/',.ieof ; записываем описание
mov [f.pointerpos],esi ; сохраняем текущую позицию
указателя

invoke SetDlgItemText,[hwnddlg],IDS_DESCRIPTION,f.description
; записываем текст описания IDS_DESCRIPTION
jmp .processed ; на метку .processed
; поступление команды
.wmcommand:
cmp [wparam],BN_CLICKED shl 16 + IDB_RESET ; если команда
- нажатие кнопки IDB_RESET

je .bcreset ; то переходим на .bcreset
cmp [wparam],BN_CLICKED shl 16 + IDB_NEXT ; если команда -
не нажатие IDB_NEXT

jne .processed ; то её не обрабатываем
; а вот если нажатие кнопки IDB_NEXT
cmp [last],1 ; пироверяем не последняя ли строка
je .ieof ; если последняя - на .ieof
sevennull ; обнуляем строки (макросом)
mov esi,[f.pointerpos] ; позицию указателя в esi
readbsn f.first,'/',.ieof ; записываем первую форму из
файла

readbsn f.second,'/',.ieof ; записываем вторую форму из
файла

readbsn f.third,0Ah,.ieof ; записываем третью форму из
файла

mov [f.pointerpos],esi ; сохраняем текущую позицию
указателя

invoke GetDlgItemText,[hwnddlg],IDE_FIRST,first,19 ;|
invoke GetDlgItemText,[hwnddlg],IDE_SECOND,second,19 ;|
берём введённый текст из editBox'ов

invoke GetDlgItemText,[hwnddlg],IDE_THIRD,third,19 ;|
;********************************************************************
;;сравнение строк
mov esi,first ; с поощью макроса cmpstr
mov edi,f.first ; сравниваем введённое слово со словом в
файле, если не совпадает, то переходим на указаную метку

cmptstr .cffalse
invoke SetDlgItemText,[hwnddlg],IDS_FIRST,strue ;
заисываем в строку "true"

inc [f.true] ; увеличиваем количество
правильных

jmp .cfend
.cffalse:
invoke SetDlgItemText,[hwnddlg],IDS_FIRST,sfalse ;
заисываем в строку "false"

inc [f.false] ; увеличиваем количество
неправильных

.cfend:
;********************************************************************
; повторяем то же самое для second и third
mov esi,second
mov edi,f.second
cmptstr .csfalse
invoke SetDlgItemText,[hwnddlg],IDS_SECOND,strue ;
заисываем в строку "true"

inc [f.true]
jmp .csend
.csfalse:
invoke SetDlgItemText,[hwnddlg],IDS_SECOND,sfalse ;
заисываем в строку "false"

inc [f.false]
.csend:
mov esi,third
mov edi,f.third
cmptstr .ctfalse
invoke SetDlgItemText,[hwnddlg],IDS_THIRD,strue ; заисываем
в строку "true"

inc [f.true]
jmp .ctend
.ctfalse:
invoke SetDlgItemText,[hwnddlg],IDS_THIRD,sfalse ;
заисываем в строку "false"

inc [f.false]
.ctend:
mov esi,[f.pointerpos] ; в esi помещаем текущую позицию
указателя [f.pointerpos]

readbsn f.description,'/',.ieof ; записываем описание (уже
следующего глагола)

jmp .next ; если записывать нечего (конец файла), то
макрос переведёт нас на метку .ieof, а так обходим её стороной

.ieof: ; конец файла
cmp [last],1 ; сравниваем с 1
jne @f ; если не равно - прыгаем на ближайшую последущую
анонимную метку

invoke MessageBox,[hwnddlg],slast,NULL,MB_ICONERROR+MB_OK
; если равно - выводим сообщение о конце файла
@@: ; если не равно
mov [last],1 ; записываем в [last] 1 (для последующего
нажатия кнопки next)

dec [f.done] ; сделаных + 1
.next:
mov [f.pointerpos],esi ; сохраняем текущую позицию
указателя

invoke SetDlgItemText,[hwnddlg],IDS_DESCRIPTION,f.description
; записываем описание следующего глагола
inc [f.done] ; сделаные + 1
; переводим в десятичные числа с помощью функции toASCII
xor ax,ax ; сделаные
mov al,[f.done]
mov edx,sscores+10
call toASCII
xor ax,ax ; правильные
mov ax,[f.true]
mov edx,sscores+31
call toASCII
xor ax,ax
mov ax,[f.false] ; неправильные
mov edx,sscores+35
call toASCII
invoke SetDlgItemText,[hwnddlg],IDS_SCORES,sscores
; переписываем IDS_SCORES
jmp .processed
.bcreset: ; нажатие кнопки reset
mov [last],0 ; обнуляем [last]
mov [f.true],0 ; обнуляем [f.true]
mov [f.false],0 ; обнуляем [f.false]
mov [f.done],0 ; обнуляем [f.done]
xor ax,ax ;|
mov al,[f.done] ;|
mov edx,sscores+10 ;|
call toASCII ;|
xor ax,ax ;|
mov ax,[f.true] ;| переводим обнулённые переменные в
десятичный формат

mov edx,sscores+31 ;|
call toASCII ;|
xor ax,ax ;|
mov ax,[f.false] ;|
mov edx,sscores+35 ;|
call toASCII ;|
invoke SetDlgItemText,[hwnddlg],IDS_SCORES,sscores
; переписываем IDS_SCORES
mov ecx,215 ;
@@: ;
mov byte [f.description+ecx],0 ; обнуляем [f.description]
loop @b ;
invoke SetDlgItemText,[hwnddlg],IDS_DESCRIPTION,f.description
; записываем в IDS_DESCRIPTION пустую строку
;
invoke SetDlgItemText,[hwnddlg],IDS_FIRST,snull ; выставляем
в ноль IDS_FIRST

invoke SetDlgItemText,[hwnddlg],IDS_SECOND,snull
; -"- IDS_SECOND
invoke SetDlgItemText,[hwnddlg],IDS_THIRD,snull ; -"-
IDS_THIRD - там теперь пустые строки

jmp .wminitdialog ; переходим на .wminitdialog
.wmclose: ; сообщение о закрытие окна
invoke EndDialog,[hwnddlg],0 ; закрытие окна
.processed: ; продолжение работы диалогового окна
mov eax,1 ; записываем в eax 1, если записать 0, то окно
завершится

.finish:
pop edi esi ebx
ret
endp
;;@ функция, преобразует двоичное число в десятичное (не
более трёхзначного)

toASCII:
;; в ax двоичное число (ah - пусто, al - байт)
;; в edx указатель на строку данных -1, в которую записываем
результат

mov bl,10 ; в bl делитель -> 10
mov ecx,3 ; в ecx число повторения цикла
@@:
div bl ; частное -> al,остаток -> ah
or ah,30h ; прибавляем к остатку 30h: 0 - 30h, 9 - 39h по
таблице ASCII

mov byte [edx+ecx],ah ; ппомещаем ASCII результат в память с
адресом в edx

xor ah,ah ; обнуляем ah
loop @b ; цикл пока cx не ноль
ret ; возврат
;;@

; импортные данные как обычно
; в fasm 1.67.26 можно не перечислять все функции, а просто написать
;
; section '.idata' import data readable writeable
;
; library kernel32,'KERNEL32.DLL',\
; user32,'USER32.DLL',\
; gdi32,'GDI32.DLL'
;
; include 'api\kernel32.inc'
; include 'api\user32.inc'
; include 'api\gdi32.inc'
;

section '.idata' import data readable writeable

library kernel,'KERNEL32.DLL',\
user,'USER32.DLL'

import kernel,\
GetModuleHandle,'GetModuleHandleW',\
ExitProcess,'ExitProcess',\
CreateFile,'CreateFileA',\
VirtualAlloc,'VirtualAlloc',\
ReadFile,'ReadFile',\
GetFileSize,'GetFileSize',\
CloseHandle,'CloseHandle'

import user,\
DialogBoxParam,'DialogBoxParamA',\
CheckRadioButton,'CheckRadioButton',\
GetDlgItemText,'GetDlgItemTextA',\
SetDlgItemText,'SetDlgItemTextA',\
IsDlgButtonChecked,'IsDlgButtonChecked',\
MessageBox,'MessageBoxA',\
EndDialog,'EndDialog'

; ресурсы, надеюсь тут всё понятно

section '.rsrc' resource data readable

directory RT_DIALOG,dialogs,\
RT_ICON,icons,\
RT_GROUP_ICON,group_icons,\
RT_VERSION,versions

resource dialogs,\
IDD_DLG,LANG_RUSSIAN,demonstration

dialog demonstration,'Irregverbs-s v0.0a

/121',70,70,190,175,WS_CAPTION+WS_POPUP+WS_SYSMENU+DS_MODALFRAME+WS_MINIMIZEBOX
dialogitem 'STATIC','&Description',-1,10,5,70,80,WS_VISIBLE
dialogitem 'STATIC','..',IDS_DESCRIPTION,10,15,180,40,WS_VISIBLE
;
dialogitem 'STATIC','&First:',-1,10,60,70,8,WS_VISIBLE
dialogitem 'EDIT','',IDE_FIRST,10,70,150,13,WS_VISIBLE+WS_BORDER+WS_TABSTOP
dialogitem 'STATIC','----',IDS_FIRST,165,70,20,10,WS_VISIBLE
;
dialogitem 'STATIC','&Second:',-1,10,90,70,8,WS_VISIBLE
dialogitem 'EDIT','',IDE_SECOND,10,100,150,13,WS_VISIBLE+WS_BORDER+WS_TABSTOP
dialogitem 'STATIC','----',IDS_SECOND,165,100,20,10,WS_VISIBLE
;
dialogitem 'STATIC','&Third:',-1,10,120,70,8,WS_VISIBLE
dialogitem 'EDIT','',IDE_THIRD,10,130,150,13,WS_VISIBLE+WS_BORDER+WS_TABSTOP
dialogitem 'STATIC','----',IDS_THIRD,165,130,20,10,WS_VISIBLE
;
dialogitem 'STATIC','&Scores',-1,10,145,70,8,WS_VISIBLE
dialogitem 'STATIC','done/all = 0/178 true/false = 0/34',IDS_SCORES,10,155,70,80,WS_VISIBLE
;
dialogitem 'BUTTON','next >>',IDB_NEXT,85,150,45,15,WS_VISIBLE+WS_TABSTOP+BS_DEFPUSHBUTTON
dialogitem 'BUTTON','reset',IDB_RESET,135,150,45,15,WS_VISIBLE+WS_TABSTOP+BS_PUSHBUTTON
enddialog

resource icons,\
1,LANG_NEUTRAL,icon_data
resource group_icons,\
17,LANG_NEUTRAL,main_icon
resource versions,\
1,LANG_NEUTRAL,version
icon main_icon,icon_data,'minipad.ico'

versioninfo

version,VOS__WINDOWS32,VFT_APP,VFT2_UNKNOWN,LANG_ENGLISH+SUBLANG_DEFAULT,0,\
'FileDescription','Irregverbs',\
'LegalCopyright','No rights reserved.',\
'FileVersion','0.0a',\
'ProductVersion','0.0a-121',\
'PlatformVersion','0.0a',\
'InterfaceVersion','0.0a',\
'OriginalFilename','IRREGVERBS-S.EXE'


Как обычно код - фиолетовый, комментарии - зеленые.
Скачать программу, исходник и комментарии в архиве zip

С уважением , Kostik

Здесь со времнем появятся ссылки дружественных и понравившихся сайтов

Информер ТИЦ



Сайт создан Pauk_pv // Pauk@paukpv.pp.ru

Rambler's Top100 Каталог@MAIL.RU - каталог ресурсов интернет

При использовании информации с сайта обязательна ссылка на сайт
Pauk_pv ©