Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Отчеты по Курсовой Работе / всплывающие подсказки Саляхутдинов 8-78-1.doc
Скачиваний:
37
Добавлен:
12.03.2015
Размер:
190.98 Кб
Скачать

Файл hint.Asm

; файл HINT.ASM

.386P

; плоская модель

.MODEL FLAT, stdcall

include hint.inc

; директивы компоновщику для подключения библиотек

; для компоновщика LINK.EXE

includelib d:\masm32\lib\user32.lib

includelib d:\masm32\lib\kernel32.lib

includelib d:\masm32\lib\gdi32.lib

; сегмент данных

_DATA SEGMENT DWORD PUBLIC USE32 'DATA'

MSG MSGSTRUCT <?>

HINST DD 0 ; дескриптор приложения

PA DB "DIAL1",0

HIN DB "HINTW",0

XX DD ?

YY DD ?

;-------------------------------

R1 RECT <?> ; поле редактирования

R2 RECT <?> ; кнопка

R3 RECT <?> ; флажок

S SIZ <?>

PS PAINTSTR <?>

PT POINT <?>

; дескрипторы окон-подсказок, для первого и второго элемента

H1 DD 0 ; поле редактирования

H2 DD 0 ; кнопка

H3 DD 0 ; флажок

; строка-подсказка

HINTS DB 60 DUP (?)

; перечень подсказок

HINT1 DB "Подсказка – Редактирование строки",0

HINT2 DB "Подсказка – Кнопка выхода",0

HINT3 DB "Подсказка - флаг",0

; для временного хранения контекста устройства

DC DD ?

; счетчик

P1 DD ?

_DATA ENDS

; сегмент кода

_TEXT SEGMENT DWORD PUBLIC USE32 'CODE'

START:

; получить дескриптор приложения

PUSH 0

CALL GetModuleHandleA@4

MOV [HINST], EAX

;----------------------------

PUSH 0

PUSH OFFSET WNDPROC

PUSH 0

PUSH OFFSET PA

PUSH [HINST]

CALL DialogBoxParamA@20

CMP EAX,-1

JNE KOL

KOL:

;-----------------------------

PUSH 0

CALL ExitProcess@4

;-----------------------------

; процедура окна

; расположение параметров в стеке

; [EBP+014Н] ; LPARAM

; [EBP+10Н] ; WAPARAM

; [EBP+0CH] ; MES

; [EBP+8] ; HWND

WNDPROC PROC

PUSH EBP

MOV EBP,ESP

PUSH EBX

PUSH ESI

PUSH EDI

;------------------------------

CMP DWORD PTR [EBP+0CH],WM_CLOSE

JNE L1

; здесь реакция на закрытие окна

; удалить таймер

L4:

PUSH 2 ; идентификатор таймера

PUSH DWORD PTR [EBP+08H]

CALL KillTimer@8

; закрыть диалог

PUSH 0

PUSH DWORD PTR [EBP+08H]

CALL EndDialog@8

JMP FINISH

L1:

CMP DWORD PTR [EBP+0CH], WM_INITDIALOG

JNE L2

; здесь начальная инициализация

; установить таймер

PUSH OFFSET TIMPROC

PUSH 500 ; интервал 0.5 с.

PUSH 2 ; идентификатор таймера

PUSH DWORD PTR [EBP+08H]

CALL SetTimer@16

JMP FINISH

L2:

CMP DWORD PTR [EBP+0CH],WM_COMMAND

JNE L3

; кнопка выхода?

CMP WORD PTR [EBP+10H],2

JNE L3

JMP L4

L3:

FINISH:

POP EDI

POP ESI

POP EBX

POP EBP

MOV EAX,0

RET 16

WNDPROC ENDP

;---------------------------------------------

; процедура таймера

; расположение параметров в стеке

; [EBP+014Н] ; LPARAM - промежуток запуска Windows

; [EBP+10Н] ; WAPARAM - идентификатор таймера

; [EBP+0CH] ; WM_TIMER

; [EBP+8] ; HWND

TIMPROC PROC

PUSH EBP

MOV EBP,ESP

; получить положение курсора

PUSH OFFSET PT

CALL GetCursorPos@4

; запомнить координаты

MOV EAX,PT.X

MOV XX,EAX

MOV EAX,PT.Y

MOV YY,EAX

; получить положение элементов

; окно редактирования

PUSH 1

PUSH DWORD PTR [EBP+08H]

CALL GetDlgItem@8

PUSH OFFSET R1

PUSH EAX

CALL GetWindowRect@8

; кнопка выхода

PUSH 2

PUSH DWORD PTR [EBP+08H]

CALL GetDlgItem@8

PUSH OFFSET R2

PUSH EAX

CALL GetWindowRect@8

; кнопка флажка

PUSH 3

PUSH DWORD PTR [EBP+08H]

CALL GetDlgItem@8

PUSH OFFSET R3

PUSH EAX

CALL GetWindowRect@8

; увеличить счетчик

INC P1

MOV ECX,XX

MOV EDX,YY

; проверка условий

; поле редактирования:

.IF H1==0 && P1>5

.IF EDX<=R1.B && EDX>=R1.T && ECX>=R1.L && ECX<=R1.R

; подготовить строку

PUSH OFFSET HINT1

PUSH OFFSET HINTS

CALL lstrcpyA@8

; создать диалоговое окно - подсказку

PUSH 0

PUSH OFFSET HINT

PUSH DWORD PTR [EBP+08H]

PUSH OFFSET HIN

PUSH [HINST]

CALL CreateDialogParamA@20

MOV H1,EAX

; установить фокус

PUSH DWORD PTR [EBP+08H]

CALL SetFocus@4

; обнулить счетчик

MOV P1,0

JMP _END

.ENDIF

.ENDIF

.IF H1!=0

.IF (EDX>R1.B || EDX<R1.T) || (ECX<R1.L || ECX>R1.R)

; удаление подсказки в связи с перемещением курсора

PUSH H1

CALL DestroyWindow@4

MOV H1,0

JMP _END

.ENDIF

.ENDIF

; кнопка:

.IF H2==0 && P1>5

.IF EDX<=R2.B && EDX>=R2.T && ECX>=R2.L && ECX<=R2.R

; подготовить строку

PUSH OFFSET HINT2

PUSH OFFSET HINTS

CALL lstrcpyA@8

; создать диалоговое окно - подсказку

PUSH 0

PUSH OFFSET HINT

PUSH DWORD PTR [EBP+08H]

PUSH OFFSET HIN

PUSH [HINST]

CALL CreateDialogParamA@20

MOV H2,EAX

; установить фокус

PUSH DWORD PTR [EBP+08H]

CALL SetFocus@4

; обнулить счетчик

MOV P1,0

JMP _END

.ENDIF

.ENDIF

.IF H2!=0

.IF (EDX>R2.B || EDX<R2.T) || (ECX<R2.L || ECX>R2.R)

;удаление подсказки в связи с перемещением курсора

PUSH H2

CALL DestroyWindow@4

MOV H2,0

JMP _END

.ENDIF

.ENDIF

; флажок:

.IF H3==0 && P1>5

.IF EDX<=R3.B && EDX>=R3.T && ECX>=R3.L && ECX<=R3.R

; подготовить строку

PUSH OFFSET HINT3

PUSH OFFSET HINTS

CALL lstrcpyA@8

; создать диалоговое окно - подсказку

PUSH 0

PUSH OFFSET HINT

PUSH DWORD PTR [EBP+08H]

PUSH OFFSET HIN

PUSH [HINST]

CALL CreateDialogParamA@20

MOV H3,EAX

; установить фокус

PUSH DWORD PTR [EBP+08H]

CALL SetFocus@4

; обнулить счетчик

MOV P1,0

JMP _END

.ENDIF

.ENDIF

.IF H3!=0

.IF (EDX>R3.B || EDX<R3.T) || (ECX<R3.L || ECX>R3.R)

;удаление подсказки в связи с перемещением курсора

PUSH H3

CALL DestroyWindow@4

MOV H3,0

JMP _END

.ENDIF

.ENDIF

; восстановить стек

_END:

POP EBP

RET 16

TIMPROC ENDP

; процедура окна всплывающей подсказки

HINT PROC

PUSH EBP

MOV EBP,ESP

CMP DWORD PTR [EBP+0CH],WM_INITDIALOG

JNE NO_INIT

; инициализация

; получить контекст

PUSH DWORD PTR [EBP+08H]

CALL GetDC@4

MOV DC,EAX

; получить длину строки

PUSH OFFSET HINTS

CALL lstrlenA@4

; получить длину и ширину строки

PUSH OFFSET S

PUSH EAX

PUSH OFFSET HINTS

PUSH DC

CALL GetTextExtentPoint32A@16

; установить положение и размер окна-подсказки

PUSH 0

PUSH S.Y

ADD S.X,2

PUSH S.X

SUB YY,20

PUSH YY

ADD XX,10

PUSH XX

PUSH DWORD PTR [EBP+08H]

CALL MoveWindow@24

; закрыть контекст

PUSH DC

PUSH DWORD PTR [EBP+08H]

CALL ReleaseDC@8

; установить таймер

PUSH 0

PUSH 6000 ; интервал 6 с.

PUSH 3 ; идентификатор таймера

PUSH DWORD PTR [EBP+08H]

CALL SetTimer@16

JMP FIN

NO_INIT:

CMP DWORD PTR [EBP+0CH],WM_PAINT

JNE NO_PAINT

; перерисовка окна

; получить контекст

PUSH OFFSET PS

PUSH DWORD PTR [EBP+08H]

CALL BeginPaint@8

MOV DC,EAX

; установить цвета фона и текста подсказки

PUSH RGBB

PUSH EAX

CALL SetBkColor@8

PUSH RGBT

PUSH DC

CALL SetTextColor@8

; вывести текст

PUSH OFFSET HINTS

CALL lstrlenA@4

PUSH EAX

PUSH OFFSET HINTS

PUSH 0

PUSH 0

PUSH DC

CALL TextOutA@20

; закрыть контекст

PUSH OFFSET PS

PUSH DWORD PTR [EBP+08H]

CALL EndPaint@8

JMP FIN

NO_PAINT:

CMP DWORD PTR [EBP+0CH],WM_TIMER

JNE FIN

; обработка события таймера

; удалить таймер и удалить диалоговое окно

; подсказка удаляется в связи с истечением срока 6 с.

PUSH 3

PUSH DWORD PTR [EBP+08H]

CALL KillTimer@8

PUSH DWORD PTR [EBP+08H]

CALL DestroyWindow@4

FIN:

POP EBP

RET 16

HINT ENDP

_TEXT ENDS

END START