Добрый вечер! В программировании я новичок. Хочу скрафтать аналоговые часы. С помощью Бога и Mikl___ создал окошко. Что делать дальше? Да-да... видел примеры часов на C но не совсем разобрался с порядком функций и их назначением. Если кто в теме объясните пожалуйста порядок действий.
Orbit, рисовать лучше наверное через GDI+ - там и антиалиасинг и полупрозрачность поддерживается в отличии от GDI. Если есть желание и интерес то можно Direct2D/3D заюзать. Для GDI+ следующие функции для рисования: GdiplusStartup/GdiplusShutdown GdipCreateFromHDC/GdipCreateFromHWND/GdipDeleteGraphics GdipGraphicsClear GdipSetSmoothingMode GdipCreatePen1/GdipDeletePen/GdipDeletePen GdipCreateSolidFill/GdipCreateHatchBrush/GdipCreateLineBrush/GdipCreateTexture/GdipDeleteBrush GdipDrawLine/GdipDrawLineI GdipDrawEllipse/GdipDrawEllipseI GdipStringFormatGetGenericDefault/GdipDeleteStringFormat GdipSetTextRenderingHint GdipCreateFontFromDC/GdipDeleteFont GdipMeasureString GdipDrawString
Подскажите библиотека работает только со спрайтами или я могу с помощью нее начертить круг и условно разделить его допустим на 12 частей?
Как рекомендация посмотрите пури(purebasic). Там это всё просто чудесно реализовано и как обучалка годная весьма. Собирается его скрипт асм компилером.
Забудьте про библиотеку. Читайте "Компьютерную графику" Борескова. И еще - еще 1 ссылка типа той, что была в посте #6 - улетите в бан.
Пытаюсь инициализировать библиотеку. Программа вываливается. То ли что то с размерами аргументов структуры то ли что-то другое в каком месте программы начинать использование библиотеки? Код (ASM): format PE64 GUI 6.0 entry start include 'win64a.inc' section '.code' code readable executable ;----------------------------------------------------------------------- start: sub rsp,8 ; Make stack dqword aligned invoke GetModuleHandle,0 mov [wc.hInstance],rax mov [wc.cbSize],sizeof.WNDCLASSEX mov [wc.style],CS_HREDRAW or CS_VREDRAW mov [wc.lpfnWndProc],WindowProc mov [wc.cbClsExtra],0 invoke LoadIcon,0,IDI_APPLICATION mov [wc.hIcon],rax mov [wc.hIconSm],rax invoke LoadCursor,0,IDC_ARROW mov [wc.hCursor],rax mov [wc.hbrBackground],COLOR_WINDOW+1 mov [wc.lpszMenuName],NULL mov [wc.lpszClassName],szTitle invoke RegisterClassEx,wc invoke CreateWindowEx,0,szTitle,szTitle,WS_VISIBLE + WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,444,444,NULL,NULL,[wc.hInstance],NULL mov [GdiplusStartupInput.GdiplusVersion],1 mov [GdiplusStartupInput.DebugEventCallback],0 mov [GdiplusStartupInput.SuppressBackgroundThread],0 mov [GdiplusStartupInput.SuppressExternalCodecs],0 msg_loop: invoke GetMessage,msg,NULL,0,0 or rax,rax je exit invoke TranslateMessage,msg invoke DispatchMessage,msg jmp msg_loop exit: invoke ExitProcess,[msg.wParam] ;-------------------------------------------------------------------------------- proc WindowProc hwnd,wmsg,wparam,lparam mov [hwnd],rcx mov [wmsg],rdx mov [wparam],r8 mov [lparam],r9 cmp [wmsg],WM_DESTROY jne .defwndproc invoke PostQuitMessage,0 ret .defwndproc: invoke DefWindowProc,[hwnd],[wmsg],[wparam],[lparam] ret endp ;---------------------------------------------------------------------- section '.data' data readable writeable szTitle db 'CLOCK',0 struct GdiplusStartupInput GdiplusVersion dd ? DebugEventCallback dq ? SuppressBackgroundThread dd ? SuppressExternalCodecs dd ? ends wc WNDCLASSEX msg MSG ;---------------------------------------------------------------------- section '.idata' import data readable writeable library kernel,'KERNEL32.DLL',\ user,'USER32.DLL',\ gdiplus,'GDIPLUS.DLL' import kernel,\ ExitProcess,'ExitProcess',\ GetModuleHandle,'GetModuleHandleA' import user,\ PostQuitMessage,'PostQuitMessage',\ LoadIcon,'LoadIconA',\ LoadCursor,'LoadCursorA',\ RegisterClassEx,'RegisterClassExA',\ CreateWindowEx,'CreateWindowExA',\ DefWindowProc,'DefWindowProcA',\ GetMessage,'GetMessageA',\ TranslateMessage,'TranslateMessage',\ DispatchMessage,'DispatchMessageA'
Пытаюсь сделать вот по этому пособию. http://www.manhunter.ru/assembler/923_vivod_izobrazheniya_na_assemblere_s_pomoschyu_gdi.html
Orbit, начни с WinAPI, а к GDIPlus перейдешь чуть погодя. Вот псевдо-код для WinAPI движение секундной стрелки по кругу. Значение в Sec увеличивай с приходом сообщения WM_TIMER Код (Text): Rectangle(150, 100, 750, 500); Ellipse(250, 100, 650, 500); MoveTo(450, 300); LineTo(Round(450-200*Cos((Sec*6+90)/180*Pi)), Round(300-200*Sin((Sec*6+90)/180*Pi))); Ellipse(443, 293, 457, 307);
Для меня пока тяжеловато, нужно разобраться с сообщениями окну. WM_TIMER приходит постоянно это понятно. а WM_PAINT один раз после запуска программы?
Нужно расширить WindowProc Код (ASM): cmp [wmsg],WM_CREATE je wmCREATE cmp [wmsg],WM_PAINT je wmPAINT cmp [wmsg],WM_TIMER je wmTIMER cmp [wmsg],WM_DESTROY jne .defwndproc invoke PostQuitMessage,0 jmp wmBYE .defwndproc: invoke DefWindowProc,[hwnd],[wmsg],[wparam],[lparam] ret wmCREATE: ... jmp wmBYE wmPAINT: ... jmp wmBYE wmTIMER: ... wmBYE: ret Движение по кругу посмотри в Глава шестая. Вращающийся текст WM_TIMER будет вызывать сообщение WM_PAINT чтобы перерисовать часовую, минутную и секундную стрелки на новом месте. Разберись пока с секундной стрелкой...
Спасибо, хорошо, я понял, наклон по градусам.. буду вникать. Но неплохо было бы увидеть как это происходит на живую Код (ASM): format PE64 GUI 6.0 entry start include 'win64a.inc' section '.code' code readable executable ;---------------------------------------------------------------------- start: sub rsp,8 ; Make stack dqword aligned invoke GetModuleHandle,0 mov [wc.hInstance],rax mov [wc.cbSize],sizeof.WNDCLASSEX mov [wc.style],CS_HREDRAW or CS_VREDRAW mov [wc.lpfnWndProc],WindowProc mov [wc.cbClsExtra],0 invoke LoadIcon,0,IDI_APPLICATION mov [wc.hIcon],rax mov [wc.hIconSm],rax invoke LoadCursor,0,IDC_ARROW mov [wc.hCursor],rax mov [wc.hbrBackground],COLOR_WINDOW+1 mov [wc.lpszMenuName],NULL mov [wc.lpszClassName],szTitle invoke RegisterClassEx,wc invoke CreateWindowEx,0,szTitle,szTitle,WS_OVERLAPPED + WS_VISIBLE + WS_CAPTION + WS_SYSMENU + WS_MINIMIZEBOX ,CW_USEDEFAULT,CW_USEDEFAULT,444,444,NULL,NULL,[wc.hInstance],NULL msg_loop: invoke GetMessage,msg,NULL,0,0 or rax,rax je exit invoke TranslateMessage,msg invoke DispatchMessage,msg jmp msg_loop exit: invoke ExitProcess,[msg.wParam] ;---------------------------------------------------------------------- proc WindowProc hwnd,wmsg,wparam,lparam mov [hwnd],rcx mov [wmsg],rdx mov [wparam],r8 mov [lparam],r9 cmp [wmsg],WM_CREATE je .create cmp [wmsg],WM_TIMER je .timer cmp [wmsg],WM_PAINT je .paint cmp [wmsg],WM_DESTROY jne .defwndproc invoke PostQuitMessage,0 jmp .exit .defwndproc: invoke DefWindowProc,[hwnd],[wmsg],[wparam],[lparam] ret .create: ;mov [GdiplusStartupInput.GdiplusVersion],1 ;mov [GdiplusStartupInput.DebugEventCallback],0 ;mov [GdiplusStartupInput.SuppressBackgroundThread],0 ;mov [GdiplusStartupInput.SuppressExternalCodecs],0 .timer: .paint: .exit: ret endp ;---------------------------------------------------------------------- section '.data' data readable writeable szTitle db 'CLOCK',0 struct GdiplusStartupInput GdiplusVersion dd ? DebugEventCallback dq ? SuppressBackgroundThread dd ? SuppressExternalCodecs dd ? ends wc WNDCLASSEX msg MSG ;---------------------------------------------------------------------- section '.idata' import data readable writeable library kernel,'KERNEL32.DLL',\ user,'USER32.DLL',\ gdiplus,'GDIPLUS.DLL' import kernel,\ ExitProcess,'ExitProcess',\ GetModuleHandle,'GetModuleHandleA' import user,\ PostQuitMessage,'PostQuitMessage',\ LoadIcon,'LoadIconA',\ LoadCursor,'LoadCursorA',\ RegisterClassEx,'RegisterClassExA',\ CreateWindowEx,'CreateWindowExA',\ DefWindowProc,'DefWindowProcA',\ GetMessage,'GetMessageA',\ TranslateMessage,'TranslateMessage',\ DispatchMessage,'DispatchMessageA'
Это не курсовая, пишу для себя... Код (ASM): format PE64 GUI 6.0 entry start include 'win64a.inc' section '.code' code readable executable ;---------------------------------------------------------------------- start: sub rsp,8 ; Make stack dqword aligned invoke GetModuleHandle,0 mov [wc.hInstance],rax mov [wc.cbSize],sizeof.WNDCLASSEX mov [wc.style],CS_HREDRAW or CS_VREDRAW mov [wc.lpfnWndProc],WindowProc mov [wc.cbClsExtra],0 invoke LoadIcon,0,IDI_APPLICATION mov [wc.hIcon],rax mov [wc.hIconSm],rax invoke LoadCursor,0,IDC_ARROW mov [wc.hCursor],rax mov [wc.hbrBackground],COLOR_WINDOW+1 mov [wc.lpszMenuName],NULL mov [wc.lpszClassName],szTitle invoke RegisterClassEx,wc invoke CreateWindowEx,0,szTitle,szTitle,WS_OVERLAPPED + WS_VISIBLE + WS_CAPTION + WS_SYSMENU + WS_MINIMIZEBOX ,CW_USEDEFAULT,CW_USEDEFAULT,444,444,NULL,NULL,[wc.hInstance],NULL msg_loop: invoke GetMessage,msg,NULL,0,0 or rax,rax je exit invoke TranslateMessage,msg invoke DispatchMessage,msg jmp msg_loop exit: invoke ExitProcess,[msg.wParam] ;---------------------------------------------------------------------- proc WindowProc hwnd,wmsg,wparam,lparam mov [hwnd],rcx mov [wmsg],rdx mov [wparam],r8 mov [lparam],r9 cmp [wmsg],WM_CREATE je .create cmp [wmsg],WM_TIMER je .timer cmp [wmsg],WM_PAINT je .paint cmp [wmsg],WM_DESTROY jne .defwndproc invoke PostQuitMessage,0 jmp .exit .defwndproc: invoke DefWindowProc,[hwnd],[wmsg],[wparam],[lparam] ret .create: mov [GdiplusSInput.GdiplusVersion],1 mov [GdiplusSInput.DebugEventCallback],0 mov [GdiplusSInput.SuppressBackgroundThread],0 mov [GdiplusSInput.SuppressExternalCodecs],0 invoke GetLocalTime,systime .timer: .paint: .exit: ret endp ;---------------------------------------------------------------------- section '.data' data readable writeable szTitle db 'CLOCK',0 struct GdiplusStartupInput GdiplusVersion dd ? DebugEventCallback dq ? SuppressBackgroundThread dd ? SuppressExternalCodecs dd ? ends wc WNDCLASSEX msg MSG systime SYSTEMTIME GdiplusSInput GdiplusStartupInput ;---------------------------------------------------------------------- section '.idata' import data readable writeable library kernel,'KERNEL32.DLL',\ user,'USER32.DLL',\ gdiplus,'GDIPLUS.DLL' import kernel,\ ExitProcess,'ExitProcess',\ GetModuleHandle,'GetModuleHandleA',\ GetLocalTime,'GetLocalTime' import user,\ PostQuitMessage,'PostQuitMessage',\ LoadIcon,'LoadIconA',\ LoadCursor,'LoadCursorA',\ RegisterClassEx,'RegisterClassExA',\ CreateWindowEx,'CreateWindowExA',\ DefWindowProc,'DefWindowProcA',\ GetMessage,'GetMessageA',\ TranslateMessage,'TranslateMessage',\ DispatchMessage,'DispatchMessageA'
Вот круг: Код (ASM): .386 .model flat, stdcall option casemap :none include \masm32\include\windows.inc include \masm32\include\gdiplus.inc include \masm32\include\user32.inc include \masm32\include\kernel32.inc includelib \masm32\lib\gdiplus.lib includelib \masm32\lib\user32.lib includelib \masm32\lib\kernel32.lib DialogProc proto :DWORD,:DWORD,:DWORD,:DWORD GdiplusStartupInput STRUCT GdiplusVersion dd ? DebugEventCallback dd ? SuppressBackgroundThread dd ? SuppressExternalCodecs dd ? GdiplusStartupInput ENDS UnitPixel equ 2 SmoothingModeAntiAlias equ 4 .data DLG_TEMP dd WS_OVERLAPPEDWINDOW XOR WS_THICKFRAME OR DS_CENTER, WS_EX_APPWINDOW dw 0, 0, 0, 200, 200, 0, 0, 0 hPen dd ? lToken dd ? tGpInput GdiplusStartupInput {1, 0, 0, 0} .code start: invoke GetModuleHandle, NULL; invoke DialogBoxIndirectParam, eax, offset DLG_TEMP, NULL, offset DialogProc, NULL; invoke ExitProcess, 0 DialogProc proc hwndDlg :DWORD, uMsg :DWORD, wParam :DWORD, lParam :DWORD LOCAL ps:PAINTSTRUCT LOCAL hGraphics:DWORD xor eax, eax .if uMsg == WM_INITDIALOG invoke GdiplusStartup, offset lToken, offset tGpInput, NULL invoke GdipCreatePen1, 0ff0000ffh, 40400000h, UnitPixel, offset hPen .elseif uMsg == WM_PAINT invoke BeginPaint, hwndDlg, ADDR ps invoke GdipCreateFromHDC, ps.hdc, ADDR hGraphics invoke GdipSetSmoothingMode, hGraphics, SmoothingModeAntiAlias invoke GdipGraphicsClear, hGraphics, 0ffffffffh invoke GdipDrawEllipseI, hGraphics, hPen, 100, 100, 200, 200 invoke GdipDeleteGraphics, hGraphics invoke EndPaint, hwndDlg, ADDR ps .elseif uMsg == WM_CLOSE invoke GdipDeletePen, hPen invoke GdiplusShutdown, lToken invoke EndDialog, hwndDlg, 0 .endif ret DialogProc endp end start
Thetrik, я бы не перегружал Orbit GDIPlus'ом -- достаточно было WinAPI'шных Ellipse, MoveTo, LineTo + перерисовка каждую секунду, а так он в деталях запутается