добрый день, уважаемые кодеры. учу азм, задался целью написать примитивные "часы", дабы постигнуть дзен WinAPI. в окне должно выводится текущее время; исходник компилится, но вместо текущего времени, в окне выводится '%02d:%02d:%02d' Код (Text): format PE GUI 4.0 entry start include '%fasminc%\win32a.inc' section '.data' data readable writeable ;------------------------------------------------------------------------- whmain dd ? whinst dd ? wtitle db 'simple clock',0 class_name db 'class',0 wmsg MSG wcls WNDCLASS stime SYSTEMTIME _ps PAINTSTRUCT _hdc dd ? _rect RECT _time db '%02d:%02d:%02d',0 _buff db 9 section '.code' readable executable ;------------------------------------------------------------------------- start: ;--> registering the window class -------------------------------- ;GetModuleHandle (GMH,NULL) returns a handle of the file used to create the calling process invoke GetModuleHandle,NULL mov [whinst],eax mov [wcls.hInstance],eax mov [wcls.style],CS_HREDRAW or CS_VREDRAW mov [wcls.lpfnWndProc],window_procedure mov [wcls.lpszClassName],class_name mov [wcls.hbrBackground],COLOR_WINDOW+1 invoke LoadIcon,NULL,IDI_WINLOGO mov [wcls.hIcon],eax invoke LoadCursor,NULL,IDC_ARROW mov [wcls.hCursor],eax invoke RegisterClass,wcls ;--> creating the main window -------------------------------- invoke CreateWindowEx,\ 0,\ class_name,\ wtitle,\ WS_OVERLAPPEDWINDOW or WS_VISIBLE,\ 150,\ 50,\ 500,\ 500,\ NULL,\ NULL,\ [whinst],\ NULL mov [whmain],eax invoke ShowWindow,[whmain],SW_SHOWNORMAL ;--> getting system time ------------------------------ invoke GetLocalTime,stime movzx eax,[stime.wHour] movzx ebx,[stime.wMinute] movzx edi,[stime.wSecond] invoke wsprintf,_buff,_time,0,eax,ebx,edi ;--> entering the message loop ------------------------------ window_msg_loop_start: invoke GetMessage,wmsg,NULL,0,0 or eax,eax je window_message_loop_end invoke TranslateMessage,wmsg invoke DispatchMessage,wmsg jmp window_msg_loop_start window_message_loop_end: invoke ExitProcess,0 ;--> the window procedure ---------------------------------- proc window_procedure,hWnd,uMsg,wParam,lParam push ebx push esi push edi cmp [uMsg],WM_PAINT je _wmPAINT cmp [uMsg],WM_DESTROY je _wmDESTROY _wmDEFAULT: invoke DefWindowProc,[hWnd],[uMsg],[wParam],[lParam] jmp _wmBYE _wmPAINT: invoke BeginPaint,[hWnd],_ps mov [_hdc],eax invoke GetClientRect,[hWnd],_rect invoke DrawText,\ [_hdc],\ _time,\ -1,\ _rect,\ DT_SINGLELINE or DT_CENTER or DT_VCENTER invoke EndPaint,[hWnd],_ps jmp _wmBYE _wmDESTROY: invoke PostQuitMessage,0 _wmBYE: pop edi pop esi pop ebx ret endp section '.idata' import data readable writeable library KERNEL32, 'KERNEL32.DLL',\ USER32, 'USER32.DLL',\ GDI32, 'GDI32.DLL' import KERNEL32,\ GetModuleHandle, 'GetModuleHandleA',\ ExitProcess, 'ExitProcess',\ GetLocalTime, 'GetLocalTime' import USER32,\ RegisterClass, 'RegisterClassA',\ CreateWindowEx, 'CreateWindowExA',\ DefWindowProc, 'DefWindowProcA',\ ShowWindow, 'ShowWindow',\ LoadCursor, 'LoadCursorA',\ LoadIcon, 'LoadIconA',\ BeginPaint, 'BeginPaint',\ InvalidateRect, 'InvalidateRect',\ EndPaint, 'EndPaint',\ GetMessage, 'GetMessageA',\ GetClientRect, 'GetClientRect',\ DrawText, 'DrawTextA',\ TranslateMessage, 'TranslateMessage',\ DispatchMessage, 'DispatchMessageA',\ PostQuitMessage, 'PostQuitMessage',\ wsprintf, 'wsprintfA' import GDI32,\ TextOut, 'TextOutA' где ошибка? =\
Код (Text): .486 .model flat, stdcall option casemap:none include \masm32\include\windows.inc include \masm32\include\kernel32.inc include \masm32\include\user32.inc includelib user32.lib includelib kernel32.lib .DATA szCaption db "LocalTime",0 ALIGN DWORD szFormat db "%s %02u %04u at %02u:%02u:%02u",0 ALIGN DWORD month db "Jan",0 db "Feb",0 db "Mar",0 db "Apr",0 db "May",0 db "Jun",0 db "Jul",0 db "Aug",0 db "Sep",0 db "Oct",0 db "Nov",0 db "Dec",0 .DATA? ALIGN DWORD _st SYSTEMTIME <> ALIGN DWORD buffer db 128 dup (?) .CODE ALIGN DWORD start: mov ebx, OFFSET _st invoke GetLocalTime, ebx assume ebx:ptr SYSTEMTIME xor eax, eax mov ax, [ebx].wSecond push eax ; 1 mov ax, [ebx].wMinute push eax ; 2 mov ax, [ebx].wHour push eax ; 3 mov ax, [ebx].wYear push eax ; 4 mov ax, [ebx].wDay push eax ; 5 mov ax, [ebx].wMonth lea eax, [month-4+eax*4] push eax ; 6 assume ebx:nothing push OFFSET szFormat ; 7 mov esi, OFFSET buffer push esi ; 8 call wsprintf add esp, (8 * SIZEOF DWORD) invoke MessageBox, NULL, esi, OFFSET szCaption, MB_OK or MB_ICONINFORMATION invoke ExitProcess, 0 End start почти то же самое (фасм) Код (Text): format PE GUI 4.0 entry start include '%fasminc%\win32a.inc' section '.code' code readable writeable executable align 4 start: invoke CreateFile, FileName, GENERIC_WRITE,\ FILE_SHARE_READ, 0, CREATE_ALWAYS,\ FILE_ATTRIBUTE_NORMAL, 0 cmp eax, INVALID_HANDLE_VALUE je @exit mov [hFile], eax mov ebx, _st invoke GetLocalTime, ebx virtual at ebx systime SYSTEMTIME end virtual xor eax, eax mov ax, [systime.wSecond] push eax ; 1 mov ax, [systime.wMinute] push eax ; 2 mov ax, [systime.wHour] push eax ; 3 mov ax, [systime.wYear] push eax ; 4 mov ax, [systime.wDay] push eax ; 5 mov ax, [systime.wMonth] lea eax, [month-4+eax*4] push eax ; 6 push szFormat ; 7 mov esi, buffer push esi ; 8 call [wsprintf] add esp, (8 * 4) invoke WriteFile, [hFile], esi, eax, NumberOfBytesWritten, 0 invoke CloseHandle, [hFile] @exit: invoke ExitProcess, 0 section '.data' data readable writeable FileName db 'CompileTime.inc',0 align 4 szFormat db 'CompileTime db "%s %02u %04u at %02u:%02u:%02u",0',0 align 4 month db "Jan",0 db "Feb",0 db "Mar",0 db "Apr",0 db "May",0 db "Jun",0 db "Jul",0 db "Aug",0 db "Sep",0 db "Oct",0 db "Nov",0 db "Dec",0 section '.udata' readable writeable hFile dd ? NumberOfBytesWritten dd ? align 4 _st SYSTEMTIME align 4 buffer rb 128 section '.idata' import data readable writeable library kernel32,'KERNEL32.DLL',\ user32,'USER32.DLL' include '%fasminc%\APIA\KERNEL32.INC' include '%fasminc%\APIA\USER32.INC'
rmn: спасибо, замечания были учтены, программа работает. =) Asterix thx, за исходники, очень наглядные пособия, законспектировал. )
подскажите, пожалуйста, как заставить часы "тикать"? я пробую в оконной процедуре обновлять клитентскую область, используя GetUpdateRect, но, очевидно, это неправильно... =\
Пример в приложении. Правда он не совсем оптимальный, и использует макросы, но полагаю у Вас найдутся свои, более эффективные.
извините за назойливость; пришел к следующему коду, время показывает, но программа не реагирует на системные вызовы, нельзя закрыть, свернуть или переместить окно; Код (Text): format PE GUI 4.0 entry start include '%fasminc%\win32a.inc' section '.data' data readable writeable ;------------------------------------------------------------------------- whmain dd ? whinst dd ? wtitle db 'clock',0 class_name db 'class',0 id_timer db 'timer' wmsg MSG wcls WNDCLASS stime SYSTEMTIME _ps PAINTSTRUCT _hdc dd ? _rect RECT _time db '%02d:%02d:%02d',0 _buff rb 9 db 0 section '.code' readable executable ;------------------------------------------------------------------------- start: ;--> registering the window class -------------------------------- invoke GetModuleHandle,NULL mov [whinst],eax mov [wcls.hInstance],eax mov [wcls.style],CS_HREDRAW or CS_VREDRAW mov [wcls.lpfnWndProc],window_procedure mov [wcls.lpszClassName],class_name mov [wcls.hbrBackground],COLOR_WINDOW+1 invoke LoadIcon,NULL,IDI_WINLOGO mov [wcls.hIcon],eax invoke LoadCursor,NULL,IDC_ARROW mov [wcls.hCursor],eax invoke RegisterClass,wcls ;--> creating the main window -------------------------------- invoke CreateWindowEx,\ 0,\ class_name,\ wtitle,\ WS_OVERLAPPEDWINDOW or WS_VISIBLE,\ CW_USEDEFAULT,\ CW_USEDEFAULT,\ 120,\ 50,\ NULL,\ NULL,\ [whinst],\ NULL mov [whmain],eax invoke ShowWindow,[whmain],SW_SHOWNORMAL ;--> entering the message loop ------------------------------ window_msg_loop_start: invoke GetMessage,wmsg,NULL,0,0 or eax,eax je window_message_loop_end invoke TranslateMessage,wmsg invoke DispatchMessage,wmsg jmp window_msg_loop_start window_message_loop_end: invoke ExitProcess,0 ;--> the window procedure ---------------------------------- proc window_procedure,hWnd,uMsg,wParam,lParam invoke DefWindowProc,[hWnd],[uMsg],[wParam],[lParam] push ebx push esi push edi cmp [uMsg],WM_CREATE je .wm_create cmp [uMsg],WM_TIMER je .wm_timer cmp [uMsg],WM_DESTROY je .wm_destroy ;--------------------------------------- .wm_create: invoke SetTimer,[hWnd],id_timer,200,NULL ;0.2 seconds interval jmp .finish ;--------------------------------------- .wm_timer: invoke GetLocalTime,stime movzx eax,[stime.wHour] movzx ebx,[stime.wMinute] movzx edi,[stime.wSecond] invoke wsprintf,_buff,_time,eax,ebx,edi invoke GetDC,[hWnd] mov [_hdc],eax invoke GetClientRect,[hWnd],_rect invoke DrawText,\ [_hdc],\ _buff,\ -1,\ _rect,\ DT_SINGLELINE or DT_CENTER or DT_VCENTER invoke ReleaseDC,[hWnd],[_hdc] jmp .finish ;--------------------------------------- .wm_destroy: invoke KillTimer,[hWnd],id_timer invoke PostQuitMessage,0 jmp .finish ;--------------------------------------- .finish: pop edi pop esi pop ebx ret endp ;------------------------------------------------------------------------- section '.idata' import data readable writeable library KERNEL32, 'KERNEL32.DLL',\ USER32, 'USER32.DLL',\ GDI32, 'GDI32.DLL' import KERNEL32,\ GetModuleHandle, 'GetModuleHandleA',\ ExitProcess, 'ExitProcess',\ GetLocalTime, 'GetLocalTime' import USER32,\ RegisterClass, 'RegisterClassA',\ CreateWindowEx, 'CreateWindowExA',\ DefWindowProc, 'DefWindowProcA',\ ShowWindow, 'ShowWindow',\ LoadCursor, 'LoadCursorA',\ LoadIcon, 'LoadIconA',\ BeginPaint, 'BeginPaint',\ InvalidateRect, 'InvalidateRect',\ EndPaint, 'EndPaint',\ GetMessage, 'GetMessageA',\ GetClientRect, 'GetClientRect',\ GetDC, 'GetDC',\ ReleaseDC, 'ReleaseDC',\ DrawText, 'DrawTextA',\ TranslateMessage, 'TranslateMessage',\ DispatchMessage, 'DispatchMessageA',\ PostQuitMessage, 'PostQuitMessage',\ wsprintf, 'wsprintfA',\ SetTimer, 'SetTimer',\ KillTimer, 'KillTimer' import GDI32,\ TextOut, 'TextOutA' прошу тыкнуть меня интерфейсом в ошибку, буду весьма признателен; спасибо.
Код (Text): cmp [uMsg],WM_TIMER je .wm_timer cmp [uMsg],WM_DESTROY je .wm_destroy jmp .finish ;;!!!!!!!!!!!!!! .wm_create: