|
|
Алексей Андрюнин
assembler source
;******************************************************************
;* *
;* eyes.asm : Основной файл программы для зрения *
;* *
;* Copyright (c) 2003, Андрюнин А.В. *
;* *
;******************************************************************
include windows.inc
include kernel32.inc
include shell32.inc
include user32.inc
include gdi32.inc
include eyes.inc
includelib kernel32.lib
includelib shell32.lib
includelib user32.lib
includelib gdi32.lib
wsprintfA PROTO :DWORD,:DWORD,:DWORD
wsprintf equ <wsprintfA>
WM_NOTIFYICOMSG equ WM_USER + 1
DEF_TIME equ 40
.data
szClassName db "EyesAppMainWin",0
szAppTitle db "Программа для зрения вер. 2.0",0
szTimerOffMsg db "Таймер отключен",0
szCurMsg db "Время работы (интервал %i мин.): %i мин. %i сек.",0
szTryRest db "Пора дать глазам отдых!",0
szWarning db "ПРЕДУПРЕЖДЕНИЕ!",0
szProfileSection db "ProgParams",0
szTimeKey db "Time",0
szStopAfterSoundKey db "StopAfterSound",0
szStartInTrayKey db "StartInTray",0
dwCurInterval dd DEF_TIME*60
bIddleMode db 0
bStopAfterSound db 1
bStartInTray db 1
dwCurTimer dd 0
msgRect RECT <1,1,1000,1000>
.data?
nIDTimer dd ?
tnid NOTIFYICONDATA <>
.code
Start:
;********************************************************************
;* Точка входа *
;********************************************************************
INVOKE GetModuleHandle, NULL
mov hInstance,eax
INVOKE GetCommandLine
mov lpCmdLine,eax
INVOKE WinMain, hInstance, NULL, lpCmdLine, SW_SHOWDEFAULT
INVOKE ExitProcess, eax
;********************************************************************
;* Проверка на предыдущий запущенный экземпляр: если он есть - *
;* делаем окно видимым и выдвигаем его на передний план. *
;********************************************************************
CheckPrevInstance PROC
INVOKE FindWindow, ADDR szClassName, NULL
.IF(eax)
mov ebx, eax
INVOKE ShowWindow, eax, SW_SHOW
INVOKE SetForegroundWindow, ebx
return 1
.ELSE
return 0
.ENDIF
ret
CheckPrevInstance ENDP
;********************************************************************
;* Инициализация приложения *
;********************************************************************
InitApplication PROC
LOCAL wc : WNDCLASSEX
LOCAL hwnd : HWND
LOCAL hRGN : HRGN
; Регистрируем класс
mov wc.cbSize, SIZEOF WNDCLASSEX
mov wc.style, CS_HREDRAW or CS_VREDRAW or CS_BYTEALIGNWINDOW
mov wc.lpfnWndProc, OFFSET WndProc
mov wc.cbClsExtra, NULL
mov wc.cbWndExtra, NULL
m2m wc.hInstance, hInstance
mov wc.hbrBackground, COLOR_WINDOW+1; NULL
mov wc.lpszMenuName, IDR_MAINMENU
mov wc.lpszClassName, OFFSET szClassName
INVOKE LoadIcon, hInstance, IDI_EYESICON
mov wc.hIcon, eax
mov wc.hIconSm, NULL
INVOKE LoadCursor,NULL, IDC_ARROW
mov wc.hCursor, eax
INVOKE RegisterClassEx, ADDR wc
call CheckPrevInstance
.IF (!eax)
; Создаем окно
INVOKE CreateWindowEx,NULL,
ADDR szClassName,
ADDR szAppTitle,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
500,
150,
NULL,
NULL,
hInstance,
NULL
mov hwnd, eax
mov hMainWnd, eax
INVOKE SetTimer, hMainWnd, 0, 1000, NULL
mov nIDTimer, eax
mov tnid.cbSize, SIZEOF NOTIFYICONDATA
m2m tnid.hwnd, hwnd
mov tnid.uID, 1
mov tnid.uFlags, NIF_MESSAGE or NIF_ICON or NIF_TIP
mov tnid.uCallbackMessage, WM_NOTIFYICOMSG
m2m tnid.hIcon, wc.hIcon
INVOKE lstrcpyn, ADDR tnid.szTip, ADDR szTimerOffMsg, LENGTHOF szAppTitle
INVOKE Shell_NotifyIcon, NIM_ADD, ADDR tnid
INVOKE DestroyIcon, wc.hIcon
;INVOKE CreateEllipticRgn, 100, 124, 500, 150
;mov hRGN, eax
;INVOKE SetWindowRgn, hwnd, hRGN, FALSE
call GetProfileSettings
.IF(bStartInTray)
mov ebx, SW_HIDE
.ELSE
mov ebx, SW_SHOW
.ENDIF
INVOKE ShowWindow, hwnd, ebx
INVOKE UpdateWindow, hwnd
call CheckMItem
return 1
.ELSE
INVOKE DestroyIcon, wc.hIcon
return 0
.ENDIF
ret
InitApplication ENDP
;********************************************************************
;* WinMain *
;********************************************************************
WinMain PROC hInst:HINSTANCE, hPrevInst:HINSTANCE, CmdLine:LPSTR, CmdShow:SDWORD
LOCAL msg:MSG
call InitApplication
.IF (eax)
.WHILE TRUE
INVOKE GetMessage, ADDR msg, NULL, 0, 0
.BREAK .IF (!eax)
INVOKE TranslateMessage, ADDR msg
INVOKE DispatchMessage, ADDR msg
.ENDW
return msg.wParam
.ELSE
return 1
.ENDIF
ret
WinMain ENDP
;********************************************************************
;* Функция окна *
;********************************************************************
WndProc PROC hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
.IF uMsg == WM_CLOSE
INVOKE ShowWindow, hWnd, SW_HIDE
return 0
.ELSEIF uMsg == WM_COMMAND
HIWORD wParam
.IF eax == 0
LOWORD wParam
.IF eax == IDM_EXIT
INVOKE Shell_NotifyIcon, NIM_DELETE, ADDR tnid
INVOKE PostQuitMessage, NULL
return 0
.ELSEIF eax == IDM_START_TIMER
mov bIddleMode, 0
mov dwCurTimer, 0
INVOKE InvalidateRect, hWnd, ADDR msgRect, 1
INVOKE ShowWindow, hWnd, SW_HIDE
return 0
.ELSEIF eax == IDM_STOPTIMER
mov bIddleMode, 1
INVOKE lstrcpyn, ADDR tnid.szTip, ADDR szTimerOffMsg, LENGTHOF szAppTitle
INVOKE Shell_NotifyIcon, NIM_MODIFY, ADDR tnid
INVOKE InvalidateRect, hWnd, ADDR msgRect, 1
return 0
.ELSEIF eax == IDM_STOPAFTERSOUND
xor bStopAfterSound, 1
call CheckMItem
return 0
.ELSE
INVOKE DefWindowProc, hWnd, uMsg, wParam, lParam
.ENDIF
.ELSE
INVOKE DefWindowProc, hWnd, uMsg, wParam, lParam
.ENDIF
.ELSEIF uMsg == WM_NOTIFYICOMSG
.IF (lParam == WM_LBUTTONDOWN) || (lParam == WM_LBUTTONDBLCLK)
INVOKE ShowWindow, hWnd, SW_SHOW
INVOKE UpdateWindow, hWnd
INVOKE SetForegroundWindow, hWnd
return 0
.ELSEIF lParam == WM_RBUTTONDOWN
INVOKE ShowWindow, hWnd, SW_HIDE
return 0
.ELSE
INVOKE DefWindowProc, hWnd, uMsg, wParam, lParam
.ENDIF
.ELSEIF uMsg == WM_PAINT
mov eax, hWnd
call On_Paint
return 0
.ELSEIF uMsg == WM_TIMER
.IF (!bIddleMode)
mov eax, hWnd
call On_Timer
.ENDIF
return 0
.ELSE
INVOKE DefWindowProc, hWnd, uMsg, wParam, lParam
.ENDIF
ret
WndProc ENDP
;********************************************************************
;* Перерисовка окна (хэндл в eax) *
;********************************************************************
On_Paint PROC
LOCAL PS:PAINTSTRUCT
LOCAL hdc:HDC
LOCAL Buf[100]:BYTE
LOCAL va_alist[3]:DWORD
mov ebx, eax
.IF (bIddleMode)
INVOKE lstrcpy, ADDR Buf, ADDR szTimerOffMsg
.ELSE
mov ecx, 60
.IF dwCurInterval < 60
mov DWORD PTR [va_alist], 0
.ELSE
mov eax, dwCurInterval
xor edx, edx
div ecx
mov [va_alist], eax
.ENDIF
mov eax, dwCurTimer
xor edx, edx
div ecx
mov [va_alist + 4], eax
mov [va_alist + 8], edx
INVOKE wvsprintf, ADDR Buf, ADDR szCurMsg, ADDR va_alist
.ENDIF
INVOKE BeginPaint, ebx, ADDR PS
mov hdc, eax
INVOKE lstrlen, ADDR Buf
INVOKE TextOut, hdc, 65, 35, ADDR Buf, eax
INVOKE EndPaint, ebx, ADDR PS
ret
On_Paint ENDP
;********************************************************************
;* Обработка таймера *
;********************************************************************
On_Timer PROC
LOCAL hwnd:HWND
LOCAL va_alist[3]:DWORD
mov hwnd, eax
mov ebx, dwCurInterval
cmp dwCurTimer, ebx
jb IncTimer
inc bIddleMode
INVOKE ShowWindow, hwnd, SW_SHOW
INVOKE SetForegroundWindow, hwnd
mov ebx, MB_SYSTEMMODAL
or ebx, MB_ICONINFORMATION
INVOKE lstrcpyn, ADDR tnid.szTip, ADDR szTimerOffMsg, LENGTHOF szAppTitle
INVOKE Shell_NotifyIcon, NIM_MODIFY, ADDR tnid
INVOKE InvalidateRect, hwnd, ADDR msgRect, 1
INVOKE MessageBox, hwnd, ADDR szTryRest, ADDR szWarning, ebx
.IF(!bStopAfterSound)
dec bIddleMode
.ENDIF
mov dwCurTimer, 0
ret
IncTimer:
inc dwCurTimer
mov ecx, 60
.IF dwCurInterval < 60
mov DWORD PTR [va_alist], 0
.ELSE
mov eax, dwCurInterval
xor edx, edx
div ecx
mov [va_alist], eax
.ENDIF
mov eax, dwCurTimer
xor edx, edx
div ecx
mov [va_alist + 4], eax
mov [va_alist + 8], edx
INVOKE wvsprintf, ADDR tnid.szTip, ADDR szCurMsg, ADDR va_alist
INVOKE Shell_NotifyIcon, NIM_MODIFY, ADDR tnid
INVOKE InvalidateRect, hwnd, ADDR msgRect, 1
ret
On_Timer ENDP
;********************************************************************
;* Отметка пункта меню "Выключить таймер после звука" *
;********************************************************************
CheckMItem PROC
INVOKE GetMenu, hMainWnd
.IF(bStopAfterSound)
INVOKE CheckMenuItem, eax, IDM_STOPAFTERSOUND, MF_CHECKED
.ELSE
INVOKE CheckMenuItem, eax, IDM_STOPAFTERSOUND, MF_UNCHECKED
.ENDIF
ret
CheckMItem ENDP
;********************************************************************
;* Получение параметров программы из файла инициализации *
;********************************************************************
GetProfileSettings PROC
LOCAL szFName[MAX_PATH + 1]:BYTE
INVOKE GetModuleFileName, hInstance, ADDR szFName, MAX_PATH
.IF(eax)
lea edx, szFName
add edx, eax
sub edx, 3
mov BYTE PTR [edx], "i"
mov BYTE PTR [edx+1], "n"
mov BYTE PTR [edx+2], "i"
INVOKE GetPrivateProfileInt, ADDR szProfileSection, ADDR szTimeKey, DEF_TIME, ADDR szFName
mov ebx, 60
mul ebx
mov dwCurInterval, eax
xor ebx, ebx
mov bl, bStopAfterSound
INVOKE GetPrivateProfileInt, ADDR szProfileSection, ADDR szStopAfterSoundKey, ebx, ADDR szFName
.IF(eax > 1)
mov bStopAfterSound, 1
.ELSE
mov bStopAfterSound, al
.ENDIF
xor ebx, ebx
mov bl, bStartInTray
INVOKE GetPrivateProfileInt, ADDR szProfileSection, ADDR szStartInTrayKey, ebx, ADDR szFName
.IF(eax > 1)
mov bStartInTray, 1
.ELSE
mov bStartInTray, al
.ENDIF
.ENDIF
ret
GetProfileSettings ENDP
end Start
|
|