Видео-плеер на Component Object Modelasm-файл Код (ASM): ; GUI # include win64a.inc include ole32.inc includelib ole32.lib IDC_ICON1 equ 500 ;------------------------------- CLSCTX_INPROC_SERVER equ 1 WM_GRAPHNOTIFY equ 40Dh Size_of_buffer equ 100h MSGBOXPARAMS struct cbSize dd ?,? hwndOwner dq ? hInstance dq ? lpszText dq ? lpszCaption dq ? dwStyle dd ?,? lpszIcon dq ? dwContextHelpId dd ?,? lpfnMsgBoxCallback dq ? dwLanguageId dd ?,? MSGBOXPARAMS ends IMediaControlVtbl STRUCT ;IUnknown methods QueryInterface QWORD ? AddRef QWORD ? Release QWORD ? ;IMediaControl methods GetTypeInfoCount QWORD ? GetTypeInfo QWORD ? GetIDsOfNames QWORD ? Invoke_ QWORD ? Run QWORD ? Pause_ QWORD ? Stop QWORD ? GetState QWORD ? RenderFile QWORD ? AddSourceFilter QWORD ? get_FilterCollection QWORD ? get_RegFilterCollection QWORD ? StopWhenReady QWORD ? IMediaControlVtbl ENDS ;------------------------------- ; IMediaEventEx virtual method table ;------------------------------- IMediaEventExVtbl STRUCT ;IUnknown methods QueryInterface QWORD ? AddRef QWORD ? Release QWORD ? ;IMediaEventEx methods GetTypeInfoCount QWORD ? GetTypeInfo QWORD ? GetIDsOfNames QWORD ? Invoke_ QWORD ? GetEventHandle QWORD ? GetEvent QWORD ? WaitForCompletion QWORD ? CancelDefaultHandling QWORD ? RestoreDefaultHandling QWORD ? FreeEventParams QWORD ? SetNotifyWindow QWORD ? SetNotifyFlags QWORD ? GetNotifyFlags QWORD ? IMediaEventExVtbl ENDS ;------------------------------- ; IGraphBuilder virtual method table ;------------------------------- IGraphBuilderVtbl STRUCT ;IUnknown methods QueryInterface QWORD ? AddRef QWORD ? Release QWORD ? ;IGraphBuilder methods AddFilter QWORD ? RemoveFilter QWORD ? EnumFilters QWORD ? FindFilterByName QWORD ? ConnectDirect QWORD ? Reconnect QWORD ? Disconnect QWORD ? SetDefaultSyncSource QWORD ? Connect QWORD ? Render QWORD ? RenderFile QWORD ? AddSourceFilter QWORD ? SetLogFile QWORD ? Abort QWORD ? ShouldOperationContinue QWORD ? IGraphBuilderVtbl ENDS ;----------------------------------------------------- ; IVideoWindow virtual method table ;------------------------------------------------ IVideoWindowVtbl STRUCT ;IUnknown methods QueryInterface QWORD ? AddRef QWORD ? Release QWORD ? ;IVideoWindow methods GetTypeInfoCount QWORD ? GetTypeInfo QWORD ? GetIDsOfNames QWORD ? Invoke_ QWORD ? put_Caption QWORD ? get_Caption QWORD ? put_WindowStyle QWORD ? get_WindowStyle QWORD ? put_WindowStyleEx QWORD ? get_WindowStyleEx QWORD ? put_AutoShow QWORD ? get_AutoShow QWORD ? put_WindowState QWORD ? get_WindowState QWORD ? put_BackgroundPalette QWORD ? get_BackgroundPalette QWORD ? put_Visible QWORD ? get_Visible QWORD ? put_Left QWORD ? get_Left QWORD ? put_Width QWORD ? get_Width QWORD ? put_Top QWORD ? get_Top QWORD ? put_Height QWORD ? get_Height QWORD ? put_Owner QWORD ? get_Owner QWORD ? put_MessageDrain QWORD ? get_MessageDrain QWORD ? get_BorderColor QWORD ? put_BorderColor QWORD ? get_FullScreenMode QWORD ? put_FullScreenMode QWORD ? SetWindowForeground QWORD ? NotifyOwnerMessage QWORD ? SetWindowPosition QWORD ? GetWindowPosition QWORD ? GetMinIdealImageSize QWORD ? GetMaxIdealImageSize QWORD ? GetRestorePosition QWORD ? HideCursor QWORD ? IsCursorHidden QWORD ? IVideoWindowVtbl ENDS .code WinMain proc local bufferANSI[Size_of_buffer]:BYTE local bufferUNICODE[Size_of_buffer*2]:BYTE local pGraph:QWORD local pControl:QWORD local pEvent:QWORD local pWindow:QWORD local ofn:OPENFILENAME ;AVIOpenFile------------------------------------------------- ;fill OPENFILENAME invoke RtlZeroMemory,&ofn,sizeof ofn mov ofn.lStructSize,sizeof ofn lea eax,bufferANSI mov ofn.lpstrFile,rax mov ofn.nMaxFile,Size_of_buffer;nMaxFile mov eax,offset Filter mov ofn.lpstrFilter,rax;lpstrFilter mov ofn.Flags,OFN_FILEMUSTEXIST or OFN_PATHMUSTEXIST or OFN_LONGNAMES or \ OFN_EXPLORER or OFN_HIDEREADONLY;Flags & nFileOffset & nFileExtension ;---------------------------------------------------- invoke GetOpenFileName,&ofn;адрес OPENFILENAME test eax,eax jz Exit ; user clicks "Cancel" inc count mov qword ptr [rsp+28h],Size_of_buffer*2 lea eax,bufferUNICODE mov [rsp+20h],rax invoke MultiByteToWideChar,0,0,&bufferANSI,-1 ;AVIInit ----------------------------------------- invoke CoInitialize,0 ;// instantiate a filter graph as in-proc server ;hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC,IID_IMediaControl, (void **)&pMC); lea eax,pGraph mov [rsp+20h],rax invoke CoCreateInstance,&CLSID_FilterGraph,0, CLSCTX_INPROC_SERVER, &ID_IGraphBuilder test eax,eax jnz Exit ;Unable to create GraphBuilder inc count ;// we'll use this interface to build the graph ;hr = pMC->QueryInterface(IID_IGraphBuilder, (void **)&pGB); lea r8d,pControl mov edx,offset ID_IMediaControl mov rcx,pGraph mov eax,[rcx] call [rax].IMediaControlVtbl.QueryInterface;pMC->QueryInterface(IID_IMediaEventEx, (void **)&pME); test eax,eax jnz Exit ;Unable to get interface IMediaControl inc count ;// we'll want to wait for completion of the rendering, so we need a ;// media event interface ;hr = pMC->QueryInterface(IID_IMediaEventEx, (void **)&pME); lea r8d,pEvent mov edx,offset ID_IMediaEventEx mov rcx,pGraph mov eax,[rcx] call [rax].IMediaEventExVtbl.QueryInterface test eax,eax jnz Exit ;Unable to get interface IMediaEventEx inc count ;// now we're ready to build the filter graph based on the source file ;// data types ;hr = pGB->RenderFile(lpszMovie, NULL); lea r8d,pWindow mov edx,offset ID_IVideoWindow mov rcx,pGraph mov eax,[rcx] call [rax].IVideoWindowVtbl.QueryInterface;pMC->QueryInterface(IID_IVideoWindow, (void**)&pVW); ;AVIRenderFile---------------------------------------------- xor r8d,r8d lea rdx,bufferUNICODE mov rcx,pGraph mov eax,[rcx] call [rax].IGraphBuilderVtbl.RenderFile;pGB->RenderFile(FileNameW, NULL); test eax,eax jnz Exit ;We can not open file inc count ;AVIPlay----------------------------------- ;// play the source file ;hr = pMC->Run(); mov rcx,pControl mov eax,[rcx] call [rax].IMediaControlVtbl.Run ;pMC->Run() ;------------------------------------------ ;// block application until video rendering operations finish ;hr = pME->WaitForCompletion(INFINITE, &evCode); lea r8d,pWindow mov edx,INFINITE mov rcx,pEvent mov eax,[rcx] call [rax].IMediaEventExVtbl.WaitForCompletion ;AVIClose------------------------------------------ mov rcx,pControl mov eax,[rcx] call [rax].IMediaControlVtbl.Release mov rcx,pEvent mov eax,[rcx] call [rax].IMediaEventExVtbl.Release mov rcx,pGraph mov eax,[rcx] call [rax].IGraphBuilderVtbl.Release invoke CoUninitialize ;--------------------------------------- Exit: xor r9d,r9d xor r8d,r8d mov eax,count mov rdx,[hande+rax*8] mov mb.lpszText,rdx invoke MessageBoxIndirectA,&mb invoke RtlExitUserProcess,NULL WinMain endp ;--------------------------------------- .data CLSID_FilterGraph GUID <0E436EBB3h,524Fh,11CEh,{09Fh,053h,0,020h,0AFh,0Bh,0A7h,70h}> ;db "NB10"; dd 3031424Eh ID_IGraphBuilder GUID <56A868A9h,0AD4h,11CEh,{0B0h,03Ah,0,20h,0AFh,0Bh,0A7h,70h}>;56A868A9h, 11CE0AD4h, 20003AB0h, 70A70BAFh ID_IMediaControl GUID <56A868B1h,0AD4h,11CEh,{0B0h,03Ah,0,20h,0AFh,0Bh,0A7h,70h}>;56A868B1h, 11CE0AD4h, 20003AB0h, 70A70BAFh ID_IMediaEventEx GUID <56A868B6h,0AD4h,11CEh,{0B0h,03Ah,0,20h,0AFh,0Bh,0A7h,70h}>;56A868C0h, 11CE0AD4h, 20003AB0h, 70A70BAFh ID_IVideoWindow GUID <56A868B4h,0AD4h,11CEh,{0B0h,03Ah,0,20h,0AFh,0Bh,0A7h,70h}> Filter db "All files (*.*)",0,"*.*",0 db "Avi files (*.avi)",0,"*.avi",0 db "Wmv files (*.wmv)",0,"*.wmv",0 db "Mp4 files (*.mp4)",0,"*.mp4",0,0 szAVIOpenError db "Unable to open the video file",0 szGoodbye db "Bye-bye!",0 mb label MSGBOXPARAMS dd sizeof MSGBOXPARAMS,?;cbSize dq 0 ;hwndOwner dq IMAGE_BASE ;hInstance dq ? ;lpszText dq 0 ;lpszCaption dd MB_OK or MB_USERICON,?;dwStyle dq IDC_ICON1 ;lpszIcon dd 0,?;dwContextHelpId dq 0 ;lpfnMsgBoxCallback dd 0,?;dwLanguageId hande dq str1,str2,str3,str4,szAVIOpenError,szGoodbye str1 db "Do not select any media files!",0 str2 db "Unable to create GraphBuilder",0 str3 db "Unable to get interface IMediaControl",0 str4 db 'Unable to get interface IMEdiaEvent',0 count dd 0 end rc-файл Код (C++): #define IDC_ICON1 500 IDC_ICON1 ICON "br_Fox1.ico"
Прямого примера проигрывания mp4-файлов лично у меня нет, но возможно это поможет уменьшить пространство поиска --- Сообщение объединено, 10 дек 2023 --- Спойлер: Спойлер Отмеренное тебе время так коротко, что, потеряв секунду, ты уже теряешь всю жизнь, ибо она не длиннее, она всегда длится лишь столько же, сколько то время, которое ты теряешь. Значит, если ты начал путь, то продолжай его, при всех обстоятельствах ты можешь только выиграть, ты ничем не рискуешь, может быть, ты в конце концов сломаешь себе шею, но если бы ты уже после первых шагов повернулся и побежал вниз по лестнице, ты, может быть, сломал бы себе шею уже в самом начале, и не «может быть», а несомненно. Значит, если ты ничего не найдёшь здесь, в коридорах, открывай двери, если ничего не найдёшь за этими дверями, то ведь есть новые этажи, если ничего не найдёшь наверху, лети выше по новым лестницам. Пока ты не перестанешь подниматься, ступеньки не прекратятся, они будут расти ввысь под твоими поднимающимися ногам. Франц Кафка
На каком языке программирования надо проигрыватель? Только асм? --- Сообщение объединено, 11 дек 2023 --- Проигрыватель из исходников windows xp
Глава двадцать восьмая (часть вторая). Братец Кролик продолжает выводить картинки на экранЕще несколько способов вывести изображение на экран. Скачайте папку с картинками и asm/rc/exe-файлы и курсорLoadImage + CreateCompatibleDC + StretchBlt Код (ASM): ; GUI # include win64a.inc IMG_X equ 516 IMG_Y equ 320 .code WinMain proc local msg:MSG xor ebx,ebx mov esi,IMAGE_BASE mov edi,offset ClassName mov ecx,offset FileName invoke LoadCursorFromFileA push rax ;hIconSm push rdi ;lpszClassName push rbx ;lpszMenuName push COLOR_WINDOW;hbrBackground push rax ;hCursor push rax ;hIcon push rsi ;hInstance push rbx ;cbClsExtra & cbWndExtra pushaddr WndProc ;lpfnWndProc push sizeof WNDCLASSEX;cbSize & style invoke RegisterClassExA,esp ;addr WNDCLASSEX push rbx push rsi ;rsi=400000h shl esi,9 ;rsi=CW_USEDEFAULT push rbx push rbx push IMG_Y+20 push IMG_X push rsi push rsi sub esp,20h invoke CreateWindowExA,0,edi,edi,WS_OVERLAPPEDWINDOW or WS_VISIBLE lea edi,msg @@:invoke GetMessageA,edi,0,0,0 invoke DispatchMessageA,edi jmp @b WinMain endp ;--------------------------------------------------------------- WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM local hDC:HDC local ps:PAINTSTRUCT local rect:RECT mov hWnd,rcx cmp edx,WM_DESTROY je wmDESTROY cmp edx,WM_CREATE je wmCREATE cmp edx,WM_PAINT je wmPAINT cmp edx,WM_SIZE je wmSIZE leave jmp NtdllDefWindowProc_ wmDESTROY:invoke DeleteObject,hBitmap invoke DeleteDC,hMemDC invoke RtlExitUserProcess,NULL wmCREATE:mov edx,offset a19 invoke LoadImageA,0,,IMAGE_BITMAP,0,0,LR_LOADFROMFILE mov hBitmap,rax invoke GetDC,hWnd mov hDC,rax invoke CreateCompatibleDC,eax mov hMemDC,rax invoke SelectObject,eax,hBitmap invoke ReleaseDC,hWnd,hDC jmp wmBYE wmSIZE: lea edx,rect invoke GetClientRect lea edx,rect invoke InvalidateRect,hWnd,,TRUE jmp wmBYE wmPAINT:lea edx,ps invoke BeginPaint mov hDC,rax lea edx,rect invoke GetClientRect,hWnd invoke StretchBlt,hDC,0,0,rect.right,\ rect.bottom,hMemDC,0,0,IMG_X,IMG_Y,SRCCOPY lea edx,ps invoke EndPaint,hWnd wmBYE: leave retn WndProc endp ;--------------------------------------- .data ClassName db 'StretchBlt',0 FileName db "br_Rabbit3.cur",0 a19 db "Images\19.bmp",0 hBitmap dq ? hMemDC HDC ? end LoadImage + CreatePatternBrush + PatBlt Код (ASM): ; GUI # include win64a.inc IMG_X equ 418 IMG_Y equ 313 .code WinMain proc local msg:MSG xor ebx,ebx mov esi,IMAGE_BASE mov edi,offset ClassName mov ecx,offset FileName invoke LoadCursorFromFileA push rax ;hIconSm push rdi ;lpszClassName push rbx ;lpszMenuName push COLOR_WINDOW+1 ;hbrBackground push rax ;hCursor push rax ;hIcon push rsi ;hInstance push rbx ;cbClsExtra & cbWndExtra pushaddr WndProc ;lpfnWndProc push sizeof WNDCLASSEX;cbSize & style invoke RegisterClassExA,esp ;addr WNDCLASSEX push rbx push rsi ;rsi=400000h shl esi,9 ;rsi=CW_USEDEFAULT push rbx push rbx push IMG_Y+30 push IMG_X+15 push rsi push rsi sub esp,20h invoke CreateWindowExA,0,edi,edi,WS_OVERLAPPEDWINDOW or \ WS_VISIBLE or WS_CAPTION or WS_SYSMENU or WS_MINIMIZEBOX lea edi,msg @@: invoke GetMessageA,edi,0,0,0 invoke DispatchMessageA,edi jmp @b WinMain endp WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM local ps:PAINTSTRUCT local hDC:HWND local hOldBrush:HWND mov hWnd,rcx cmp edx,WM_DESTROY je wmDESTROY cmp edx,WM_CREATE je wmCREATE cmp edx,WM_PAINT je wmPAINT leave jmp NtdllDefWindowProc_ wmDESTROY:invoke RtlExitUserProcess,NULL wmCREATE:invoke GetDC mov hDC,rax mov edx,offset BmpName invoke LoadImageA,IMAGE_BASE,,0,0,0,LR_LOADFROMFILE invoke CreatePatternBrush,eax mov hBrush,rax invoke DeleteDC,hDC jmp wmBYE wmPAINT:lea edx,ps invoke BeginPaint mov hDC,rax invoke SelectObject,eax,hBrush mov hOldBrush,rax invoke PatBlt,hDC,0,0,IMG_X,IMG_Y,PATCOPY invoke DeleteObject,hOldBrush lea edx,ps invoke EndPaint,hWnd wmBYE: leave retn WndProc endp ;--------------------------------------- .data ClassName db 'LoadImage+CreatePatternBrush+PatBlt',0 BmpName db 'Images\18.bmp',0 FileName db "br_Rabbit3.cur",0 hBrush dq ? end GDI+: GdipCreateBitmapFromFile + GdipCreateHBITMAPFromBitmap + SendMessage(STM_SETIMAGE) Код (ASM): ; GUI # include win64a.inc IMG_X equ 450 IMG_Y equ 604 .code WinMain proc local msg:MSG mov ecx,offset graphics mov edx,offset gdii invoke GdiplusStartup,,,0 xor ebx,ebx mov esi,IMAGE_BASE mov ecx,offset FileName invoke LoadCursorFromFileA mov edi,offset ClassName push rax ;hIconSm push rdi ;lpszClassName push rbx ;lpszMenuName push COLOR_WINDOW+1;hbrBackground push rax ;hCursor push rax ;hIcon push rsi ;hInstance push rbx ;cbClsExtra & cbWndExtra pushaddr WndProc ;lpfnWndProc push sizeof WNDCLASSEX;cbSize & style invoke RegisterClassExA,esp ;addr WNDCLASSEX push rbx ;lParam push rsi ;hinstance=rsi=400000h shl esi,9 ;rsi=CW_USEDEFAULT push rbx ;hMenu push rbx ;hWmdParent push IMG_Y+20 ;nHeight push IMG_X ;nWidth push rsi ;y push rsi ;x sub esp,20h invoke CreateWindowExA,0,edi,edi,WS_OVERLAPPEDWINDOW or WS_VISIBLE lea edi,msg @@: invoke GetMessageA,edi,0,0,0 invoke DispatchMessageA,edi jmp @b WinMain endp WndProc proc hWnd:QWORD,uMsg:QWORD,wParam:QWORD,lParam:QWORD local pbmp:QWORD local hndl:QWORD local hImgBox:qword cmp edx,WM_CREATE je wmCREATE cmp edx,WM_DESTROY je wmDESTROY wmDEFAULT:leave jmp NtdllDefWindowProc_ wmDESTROY:invoke GdiplusShutdown,graphics ; cleanup on exit invoke RtlExitUserProcess,NULL wmCREATE:push rbx push IMAGE_BASE push rbx;-1 push rcx push rbx push rbx push rbx push rbx sub esp,20h mov edx,offset aStatic invoke CreateWindowExA,WS_EX_LEFT,,0,WS_CHILD or WS_VISIBLE or SS_BITMAP mov hImgBox,rax mov ecx,offset FileJPG invoke GdipCreateBitmapFromFile,,ADDR pbmp ; create a GDI+ bitmap invoke GdipCreateHBITMAPFromBitmap,pbmp,ADDR hndl,0; create normal bitmap handle from it invoke GdipDisposeImage,pbmp ; remove the GDI+ bitmap ; load disk file as bitmap handle invoke SendMessageA,hImgBox,STM_SETIMAGE,IMAGE_BITMAP,hndl; write image to static control wmBYE: leave xor eax,eax retn WndProc endp .data gdii GdiplusStartupInput <1,0,0,0> graphics dq ? aStatic db "STATIC",0 ClassName db "GDI+",0 FileName db "br_Rabbit3.cur",0 FileJPG: du <Images\26.jpg> end LoadImage + CreatePatternBrush + wc.hbrBackground Код (ASM): ; GUI # include win64a.inc IMG_X equ 520 IMG_Y equ 378 .code WinMain proc local msg:MSG local hIcon:qword xor ebx,ebx mov esi,IMAGE_BASE mov edi,offset ClassName mov ecx,offset FileName invoke LoadCursorFromFileA mov hIcon,rax mov edx,offset BmpName invoke LoadImageA,esi,,0,0,0,LR_LOADFROMFILE invoke CreatePatternBrush,eax push hIcon ;hIconSm push rdi ;lpszClassName push rbx ;lpszMenuName push rax ;hbrBackground push hIcon ;hCursor push hIcon ;hIcon push rsi ;hInstance push rbx ;cbClsExtra & cbWndExtra pushaddr WndProc ;lpfnWndProc push sizeof WNDCLASSEX;cbSize & style invoke RegisterClassExA,esp ;addr WNDCLASSEX push rbx ;lParam push rsi ;hinstance=rsi=400000h shl esi,9 ;rsi=CW_USEDEFAULT push rbx ;hMenu push rbx ;hWmdParent push IMG_Y+20 ;nHeight push IMG_X ;nWidth push rsi ;y push rsi ;x sub esp,20h invoke CreateWindowExA,0,edi,edi,WS_OVERLAPPED or \ WS_VISIBLE or WS_CAPTION or WS_SYSMENU or WS_MINIMIZEBOX lea edi,msg @@:invoke GetMessageA,edi,0,0,0 invoke DispatchMessageA,edi jmp @b WinMain endp WndProc:cmp edx,WM_DESTROY je wmDESTROY jmp NtdllDefWindowProc_ wmDESTROY:invoke RtlExitUserProcess,NULL ;--------------------------------------- .data BmpName db 'Images\12.bmp',0 ClassName db 'LoadImageA+CreatePatternBrush+wc.hbrBackground',0 FileName db "br_Rabbit3.cur",0 end OLE Код (ASM): ; GUI # include win64a.inc IDB_MYBITMAP = 105 IDC_DIALOG = 200 HIMETRIC_PER_INCH = 2540 IMG_X = 932*2/3;960 IMG_Y = 1341*2/3;540 ID_IMG equ 100 .code WinMain proc local msg:MSG xor ebx,ebx mov esi,IMAGE_BASE mov ecx,offset FileName invoke LoadCursorFromFileA mov edi,offset ClassName push rax ;hIconSm push rdi ;lpszClassName push rbx ;lpszMenuName push COLOR_WINDOW+1;hbrBackground push rax ;hCursor push rax ;hIcon push rsi ;hInstance push rbx ;cbClsExtra & cbWndExtra pushaddr WndProc ;lpfnWndProc push sizeof WNDCLASSEX;cbSize & style invoke RegisterClassExA,esp ;addr WNDCLASSEX push rbx ;lParam push rsi ;hinstance=rsi=400000h shl esi,9 ;rsi=CW_USEDEFAULT push rbx ;hMenu push rbx ;hWmdParent push IMG_Y+20 ;nHeight push IMG_X+10 ;nWidth push rsi ;y push rsi ;x sub esp,20h invoke CreateWindowExA,0,edi,edi,WS_OVERLAPPEDWINDOW or WS_VISIBLE lea edi,msg @@:invoke GetMessageA,edi,0,0,0 invoke DispatchMessageA,edi jmp @b WinMain endp ;--------------------------------------------------------------- WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM local hImgBox:qword local hResource:qword local pResource:qword local FSize:dword local rct:RECT mov hWnd,rcx cmp edx,WM_CREATE je wmCREATE cmp edx,WM_DESTROY je wmDESTROY wmDEFAULT:leave jmp NtdllDefWindowProc_ wmDESTROY:invoke RtlExitUserProcess,NULL wmCREATE:mov edx,offset aStatic invoke CreateWindowExA,WS_EX_LEFT,,0,WS_CHILD or WS_VISIBLE \ or SS_BITMAP,0,0,0,0,hWnd,ID_IMG,IMAGE_BASE,0 mov hImgBox,rax ; Инициализация OLE invoke OleInitialize,NULL ;-------------------------------------------------------------- ; Загрузить картинку из ресурсов invoke FindResource,0,IDB_MYBITMAP,RT_RCDATA mov hResource,rax invoke SizeofResource,NULL,eax mov FSize,eax invoke LoadResource,NULL,hResource mov pResource,rax ; Выделить память под картинку invoke GetProcessHeap mov hProcHeap,rax invoke RtlAllocateHeap,eax,HEAP_ZERO_MEMORY,FSize mov hLock,rax ; Скопировать картинку в выделенную память invoke LockResource,pResource mov esi,eax mov rdi,hLock mov ecx,FSize rep movsb ; Создать поток из данных mov r8d,offset iStream invoke CreateStreamOnHGlobal,hLock,TRUE ; Загрузить картинку из памяти movr qword ptr[rsp+20h],iPicture mov r9d,offset IID_IPicture invoke OleLoadPicture,iStream,0,TRUE ; Вызвать метод интерфейса IPicture->get_Handle() mov rcx,iPicture mov eax,[rcx] mov edx,offset hBitmap call qword ptr[rax].IPicture.get_Handle ; Вызвать метод интерфейса IPicture->get_Width() mov rcx,iPicture mov eax,[rcx] mov edx,offset bm.bmWidth call qword ptr[rax].IPicture.get_Width ; Количество пикселей на логический дюйм по горизонтали invoke GetDC,NULL invoke GetDeviceCaps,eax,LOGPIXELSX ; Пересчитать HIMETRIC в обычные пикселы imul bm.bmWidth xor edx,edx mov ecx,HIMETRIC_PER_INCH idiv ecx ; Ширина изображения mov bm.bmWidth,eax ; Вызвать метод интерфейса IPicture->get_Height() mov rcx,iPicture mov eax,[rcx] mov edx,offset bm.bmHeight call qword ptr[rax].IPicture.get_Height ; Количество пикселей на логический дюйм по вертикали invoke GetDC,NULL invoke GetDeviceCaps,eax,LOGPIXELSY ; Пересчитать HIMETRIC в обычные пикселы imul bm.bmHeight xor edx,edx mov ecx,HIMETRIC_PER_INCH idiv ecx ; Высота изображения mov bm.bmHeight,eax ; Создать виртуальный битмап для превью invoke GetDC,NULL invoke CreateCompatibleBitmap,eax,IMG_X,IMG_Y mov imgBitmap,rax invoke CreateCompatibleDC,NULL mov hDC1,rax invoke SelectObject,eax,imgBitmap mov hOld1,rax invoke CreateCompatibleDC,NULL mov hDC2,rax invoke SelectObject,eax,hBitmap mov hOld2,rax ; Наложить изображение в центр виртуального битмапа invoke SetStretchBltMode,hDC1,HALFTONE mov eax,bm.bmHeight mov [rsp+48h],rax mov eax,bm.bmWidth mov [rsp+40h],rax invoke StretchBlt,hDC1,0,0,IMG_X,IMG_Y, hDC2,0,0,,,SRCCOPY invoke SelectObject,hDC1,hOld1 invoke DeleteDC,hDC1 invoke SelectObject,hDC2,hOld2 invoke DeleteDC,hDC2 ; Установить виртуальный битмап на static invoke SendMessageA,hImgBox,STM_SETIMAGE,IMAGE_BITMAP,imgBitmap ; Вызвать метод интерфейса IPicture->Release() mov rcx,iPicture mov eax,[rcx] call qword ptr[rax].IPicture.Release ; Очистить память invoke HeapFree,hProcHeap,0,hLock invoke OleUninitialize wmBYE: mov eax,TRUE leave retn WndProc endp .data;--------------------------------------- align 10h bm BITMAP <> hBitmap dq ? imgBitmap dq ? hDC1 dq ? hDC2 dq ? hOld1 dq ? hOld2 dq ? iStream dq ? hProcHeap dq ? hLock dq ? iPicture dq ? ; GUID {7BF80980-BF32-101A-8BBB00AA00300CAB} IID_IPicture GUID <7BF80980h,0BF32h,101Ah,{8Bh,0BBh,0,0AAh,0,30h,0Ch,0ABh}> aStatic db "STATIC",0 ClassName db "OLE",0 FileName db "br_Rabbit3.cur",0 end Файл ресурсов Код (C): #include "resource.h" #define IDB_MYBITMAP 105 IDB_MYBITMAP RCDATA "Images\\012_028.jpg"
Глава пятьдесят третья. Видео-плеер Братца Кролика Основные идеи и основа кода для плеера взяты на сайте Manhunter'a из статей Мультимедийный плеер на Ассемблере и Управление громкостью звука в системе. В аттаче asm-/rc-/ico-/exe-файлы. Если установлены кодеки, то поддерживается воспроизведение всевозможных видео-файлов: mp4, mob, mkv, m4v, avi, flv, mts, 3gp, insv, m2ts, db, qt, mov, mpg, mpeg, m1v, vob, wmv. rc-файл Код (C++): #include "resource.h" #define ID_VIDEO 100 #define ID_DTN 101 #define ID_CUR 102 #define ID_PLAY 103 #define IDC_MENU 104 #define ID_PAUSE 105 #define ID_STOP 106 #define ID_OPEN 107 #define ID_PROGRESS 108 #define ID_SLIDER 109 #define ID_VOL 110 #define ID_UP 111 #define ID_DN 112 #define ID_MUT 113 #define ID_ABOUT 114 #define IDCANCEL 2 #define ID_DIALOG 1 #define IDM_SAYHELLO 0 #define IDM_GETTEXT 1 #define IDM_CLEAR 2 #define IDM_EXIT 3 #define IDC_ICON1 500 IDC_ICON1 ICON "br_Fox1.ico" ID_DIALOG DIALOG 0, 0, 200, 208 STYLE DS_SYSMODAL | DS_CENTER | WS_CAPTION | WS_SYSMENU EXSTYLE WS_EX_DLGMODALFRAME CAPTION "Uncle Remus tales #37k: Player Demo" FONT 10, "Arial" MENU IDC_MENU { CONTROL "", -1, BUTTON, BS_GROUPBOX | WS_CHILD | WS_VISIBLE, 3, -2, 195, 134 CONTROL "", ID_VIDEO, EDIT, ES_LEFT | ES_READONLY | WS_POPUP | WS_VISIBLE, 5, 5, 190, 125 CONTROL "00:00:00", ID_CUR, STATIC, SS_LEFT | WS_CHILD | WS_VISIBLE, 4, 134, 45, 9 CONTROL "00:00:00", ID_DTN, STATIC, SS_RIGHT | WS_CHILD | WS_VISIBLE, 151, 134, 45, 9 CONTROL "Volume +2%",ID_UP, BUTTON, BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE,3,158,46,13 CONTROL "Volume -2%",ID_DN, BUTTON, BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE,50,158,46,13 CONTROL "Mute",ID_MUT, BUTTON, BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE,97,158,25,13 CONTROL "0%", ID_VOL, STATIC, SS_RIGHT | WS_CHILD | WS_VISIBLE, 30, 178, 20, 9 CONTROL "Volume: ", -1, STATIC, SS_RIGHT | WS_CHILD | WS_VISIBLE, 3, 178, 30, 9 CONTROL "", ID_PROGRESS, "msctls_progress32", PBS_SMOOTH,2, 143, 196, 8,WS_EX_CLIENTEDGE | WS_EX_STATICEDGE CONTROL "Slider2",ID_SLIDER,"msctls_trackbar32",TBS_TOP,51, 172, 147,20 CONTROL "Open" , ID_OPEN, BUTTON, BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE, 3, 193, 39, 13 CONTROL "Play" , ID_PLAY, BUTTON, BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE, 42, 193, 39, 13 CONTROL "Pause", ID_PAUSE, BUTTON, BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE, 81, 193, 39, 13 CONTROL "Stop", ID_STOP, BUTTON, BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE, 120, 193, 39, 13 CONTROL "Exit" , IDCANCEL, BUTTON, BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE, 159, 193, 39, 13 } IDC_MENU MENU { POPUP "Файл" { MENUITEM "Открыть файл",ID_OPEN MENUITEM "Открыть URL",IDM_GETTEXT,GRAYED MENUITEM "Проиграть CD/DVD",IDM_CLEAR,GRAYED MENUITEM "Закрыть",IDM_CLEAR,GRAYED MENUITEM SEPARATOR MENUITEM "Выход",IDCANCEL } POPUP "Вид" { MENUITEM "Произвольный размер",IDM_SAYHELLO,GRAYED MENUITEM "1/2 размера",IDM_GETTEXT,GRAYED MENUITEM "Оригинальный размер",IDM_CLEAR,GRAYED MENUITEM "Двойной размер",IDM_CLEAR,GRAYED MENUITEM SEPARATOR MENUITEM "Полноэкранный режим",IDM_SAYHELLO,GRAYED MENUITEM "Компактный",IDM_GETTEXT,GRAYED MENUITEM "Всегда наверху",IDM_CLEAR,GRAYED MENUITEM "Переключит OSD",IDM_CLEAR,GRAYED } POPUP "Проигрывание" { MENUITEM "Играть",ID_PLAY MENUITEM "Приостановить",ID_PAUSE MENUITEM "Stop",ID_STOP MENUITEM SEPARATOR MENUITEM "Предыдущий трек",IDM_SAYHELLO,GRAYED MENUITEM "Следующий трек",IDM_GETTEXT,GRAYED MENUITEM "Плейлист",IDM_CLEAR,GRAYED MENUITEM SEPARATOR MENUITEM "Выключить звук",IDM_SAYHELLO,GRAYED MENUITEM SEPARATOR MENUITEM "Вперед на 10 секунд",IDM_SAYHELLO,GRAYED MENUITEM "Назад на 10 секунд",IDM_GETTEXT,GRAYED MENUITEM "Вперед на 1 минуту",IDM_SAYHELLO,GRAYED MENUITEM "Назад на 1 минуту",IDM_SAYHELLO,GRAYED MENUITEM "Вперед на 10 минут",IDM_SAYHELLO,GRAYED MENUITEM "Назад на 10 минут",IDM_CLEAR,GRAYED } POPUP "Настройки" { MENUITEM "Аудиотрек",IDM_SAYHELLO,GRAYED MENUITEM "Субтитры",IDM_GETTEXT,GRAYED MENUITEM "Соотношение сторон",IDM_CLEAR,GRAYED MENUITEM "Деинтерлейс",IDM_CLEAR,GRAYED MENUITEM SEPARATOR MENUITEM "Опции ...",IDM_SAYHELLO,GRAYED MENUITEM "Язык",IDM_GETTEXT,GRAYED MENUITEM SEPARATOR MENUITEM "Показать информацию о файле",IDM_CLEAR,GRAYED MENUITEM "Показывать вывод MPlayer",IDM_CLEAR,GRAYED } POPUP "Помощь" { MENUITEM "Помощь по клавиатуре",IDM_SAYHELLO,GRAYED MENUITEM "О программе...",ID_ABOUT } }
asm-файл Код (ASM): ; GUI # include win64a.inc include winmm.inc includelib winmm.lib IMG_X equ 332 IMG_Y equ 248 ID_VIDEO equ 100 ID_DTN equ 101 ID_CUR equ 102 ID_PLAY equ 103 IDC_MENU equ 104 ID_PAUSE equ 105 ID_STOP equ 106 ID_OPEN equ 107 ID_PROGRESS equ 108 ID_SLIDER equ 109 ID_VOL equ 110 ID_UP equ 111 ID_DN equ 112 ID_MUT equ 113 ID_ABOUT equ 114 IDC_ICON1 equ 500 ID_DIALOG equ 1 CLSCTX_INPROC_SERVER = 1 WM_APP = 8000h WM_GRAPHNOTIFY = WM_APP + 1 EC_COMPLETE = 1 AM_SEEKING_AbsolutePositioning = 1 PBM_SETBARCOLOR = 409h PBM_SETBKCOLOR = 2001h Size_of_buffer = 100 State_Stopped = 0 State_Paused = 1 State_Running = 2 TBM_SETPOS equ WM_USER+5 TBM_SETRANGEMIN equ WM_USER+7 TBM_SETRANGEMAX equ WM_USER+8 TB_THUMBPOSITION equ 4 TB_THUMBTRACK equ 5 ;------------------------------- ; IGraphBuilder virtual method table ;------------------------------- IGraphBuilderVtbl STRUCT ;IUnknown methods QueryInterface QWORD ? AddRef QWORD ? Release QWORD ? ;IGraphBuilder methods AddFilter QWORD ? RemoveFilter QWORD ? EnumFilters QWORD ? FindFilterByName QWORD ? ConnectDirect QWORD ? Reconnect QWORD ? Disconnect QWORD ? SetDefaultSyncSource QWORD ? Connect QWORD ? Render QWORD ? RenderFile QWORD ? AddSourceFilter QWORD ? SetLogFile QWORD ? Abort QWORD ? ShouldOperationContinue QWORD ? IGraphBuilderVtbl ENDS IMediaControlVtbl STRUCT ;IUnknown methods QueryInterface QWORD ? AddRef QWORD ? Release QWORD ? ;IMediaControl methods GetTypeInfoCount QWORD ? GetTypeInfo QWORD ? GetIDsOfNames QWORD ? Invoke_ QWORD ? Run QWORD ? Pause_ QWORD ? Stop QWORD ? GetState QWORD ? RenderFile QWORD ? AddSourceFilter QWORD ? get_FilterCollection QWORD ? get_RegFilterCollection QWORD ? StopWhenReady QWORD ? IMediaControlVtbl ENDS IVideoWindowVtbl STRUCT ;IUnknown methods QueryInterface QWORD ? AddRef QWORD ? Release QWORD ? ;IVideoWindow methods GetTypeInfoCount QWORD ? GetTypeInfo QWORD ? GetIDsOfNames QWORD ? Invoke_ QWORD ? put_Caption QWORD ? get_Caption QWORD ? put_WindowStyle QWORD ? get_WindowStyle QWORD ? put_WindowStyleEx QWORD ? get_WindowStyleEx QWORD ? put_AutoShow QWORD ? get_AutoShow QWORD ? put_WindowState QWORD ? get_WindowState QWORD ? put_BackgroundPalette QWORD ? get_BackgroundPalette QWORD ? put_Visible QWORD ? get_Visible QWORD ? put_Left QWORD ? get_Left QWORD ? put_Width QWORD ? get_Width QWORD ? put_Top QWORD ? get_Top QWORD ? put_Height QWORD ? get_Height QWORD ? put_Owner QWORD ? get_Owner QWORD ? put_MessageDrain QWORD ? get_MessageDrain QWORD ? get_BorderColor QWORD ? put_BorderColor QWORD ? get_FullScreenMode QWORD ? put_FullScreenMode QWORD ? SetWindowForeground QWORD ? NotifyOwnerMessage QWORD ? SetWindowPosition QWORD ? GetWindowPosition QWORD ? GetMinIdealImageSize QWORD ? GetMaxIdealImageSize QWORD ? GetRestorePosition QWORD ? HideCursor QWORD ? IsCursorHidden QWORD ? IVideoWindowVtbl ENDS IMediaSeeking struct ; IUnknown QueryInterface QWORD ? ; 000h AddRef QWORD ? ; 008h Release QWORD ? ; 010h ; IMediaSeeking GetCapabilities QWORD ? ; 00Ch CheckCapabilities QWORD ? ; 010h IsFormatSupported QWORD ? ; 014h QueryPreferredFormat QWORD ? ; 018h GetTimeFormat QWORD ? ; 01Ch IsUsingTimeFormat QWORD ? ; 020h SetTimeFormat QWORD ? ; 024h GetDuration QWORD ? ; 028h GetStopPosition QWORD ? ; 02Ch GetCurrentPosition QWORD ? ; 030h ConvertTimeFormat QWORD ? ; 034h SetPositions QWORD ? ; 038h GetPositions QWORD ? ; 03Ch GetAvailable QWORD ? ; 040h SetRate QWORD ? ; 044h GetRate QWORD ? ; 048h GetPreroll QWORD ? ; 04Ch IMediaSeeking ends ; IID_IBasicVideo Interface IBasicVideo struct ; IUnknown QueryInterface QWORD ? ; 000h AddRef QWORD ? ; 004h Release QWORD ? ; 008h ; IBasicVideo GetTypeInfoCount QWORD ? ; 00Ch GetTypeInfo QWORD ? ; 010h GetIDsOfNames QWORD ? ; 014h _Invoke QWORD ? ; 018h get_AvgTimePerFrame QWORD ? ; 01Ch get_BitRate QWORD ? ; 020h get_BitErrorRate QWORD ? ; 024h get_VideoWidth QWORD ? ; 028h get_VideoHeight QWORD ? ; 02Ch put_SourceLeft QWORD ? ; 030h get_SourceLeft QWORD ? ; 034h put_SourceWidth QWORD ? ; 038h get_SourceWidth QWORD ? ; 03Ch put_SourceTop QWORD ? ; 040h get_SourceTop QWORD ? ; 044h put_SourceHeight QWORD ? ; 048h get_SourceHeight QWORD ? ; 04Ch put_DestinationLeft QWORD ? ; 050h get_DestinationLeft QWORD ? ; 054h put_DestinationWidth QWORD ? ; 058h get_DestinationWidth QWORD ? ; 05Ch put_DestinationTop QWORD ? ; 060h get_DestinationTop QWORD ? ; 064h put_DestinationHeight QWORD ? ; 068h get_DestinationHeight QWORD ? ; 06Ch SetSourcePosition QWORD ? ; 070h GetSourcePosition QWORD ? ; 074h SetDefaultSourcePosition QWORD ? ; 078h SetDestinationPosition QWORD ? ; 07Ch GetDestinationPosition QWORD ? ; 080h SetDefaultDestinationPosition QWORD ? ; 084h GetVideoSize QWORD ? ; 088h GetVideoPaletteEntries QWORD ? ; 08Ch GetCurrentImage QWORD ? ; 090h IsUsingDefaultSource QWORD ? ; 094h IsUsingDefaultDestination QWORD ? ; 098h IBasicVideo ends ; IID_IMediaEventEx Interface IMediaEventEx struct ; IUnknown QueryInterface QWORD ? ; 000h AddRef QWORD ? ; 004h Release QWORD ? ; 008h ; IMediaEventEx GetTypeInfoCount QWORD ? ; 00Ch GetTypeInfo QWORD ? ; 010h GetIDsOfNames QWORD ? ; 014h _Invoke QWORD ? ; 018h GetEventHandle QWORD ? ; 01Ch GetEvent QWORD ? ; 020h WaitForCompletion QWORD ? ; 024h CancelDefaultHandling QWORD ? ; 028h RestoreDefaultHandling QWORD ? ; 02Ch FreeEventParams QWORD ? ; 030h SetNotifyWindow QWORD ? ; 034h SetNotifyFlags QWORD ? ; 038h GetNotifyFlags QWORD ? ; 03Ch IMediaEventEx ends ; IID_IMMDeviceEnumerator Interface IMMDeviceEnumerator struct ; IUnknown QueryInterface QWORD ? ; 000h AddRef QWORD ? ; 004h Release QWORD ? ; 008h ; IMMDeviceEnumerator EnumAudioEndpoints QWORD ? ; 00Ch GetDefaultAudioEndpoint QWORD ? ; 010h GetDevice QWORD ? ; 014h RegisterEndpointNotificationCallback QWORD ? ; 018h UnregisterEndpointNotificationCallback QWORD ? ; 01Ch IMMDeviceEnumerator ends ; IID_IMMDevice Interface IMMDevice struct ; IUnknown QueryInterface QWORD ? ; 000h AddRef QWORD ? ; 004h Release QWORD ? ; 008h ; IMMDevice Activate QWORD ? ; 00Ch OpenPropertyStore QWORD ? ; 010h GetId QWORD ? ; 014h GetState QWORD ? ; 018h IMMDevice ends ; IID_IAudioEndpointVolume Interface IAudioEndpointVolume struct ; IUnknown QueryInterface QWORD ? ; 000h AddRef QWORD ? ; 004h Release QWORD ? ; 008h ; IAudioEndpointVolume RegisterControlChangeNotify QWORD ? ; 00Ch UnregisterControlChangeNotify QWORD ? ; 010h GetChannelCount QWORD ? ; 014h SetMasterVolumeLevel QWORD ? ; 018h SetMasterVolumeLevelScalar QWORD ? ; 01Ch GetMasterVolumeLevel QWORD ? ; 020h GetMasterVolumeLevelScalar QWORD ? ; 024h SetChannelVolumeLevel QWORD ? ; 028h SetChannelVolumeLevelScalar QWORD ? ; 02Ch GetChannelVolumeLevel QWORD ? ; 030h GetChannelVolumeLevelScalar QWORD ? ; 034h SetMute QWORD ? ; 038h GetMute QWORD ? ; 03Ch GetVolumeStepInfo QWORD ? ; 040h VolumeStepUp QWORD ? ; 044h VolumeStepDown QWORD ? ; 048h QueryHardwareSupport QWORD ? ; 04Ch GetVolumeRange QWORD ? ; 050h IAudioEndpointVolume ends .code WinMain proc local dummy:qword invoke InitCommonControls ; Инициализация COM invoke CoInitialize,NULL mov r9d,offset DialogProc mov qword ptr [rsp+20h],IDC_MENU invoke DialogBoxParam,IMAGE_BASE,ID_DIALOG,HWND_DESKTOP invoke CoUninitialize Exit:: xor r9d,r9d xor r8d,r8d mov eax,count mov rdx,[hande+rax*8] mov mb.lpszText,rdx invoke MessageBoxIndirect,&mb invoke RtlExitUserProcess,NULL WinMain endp DialogProc proc hwnddlg:qword,msg:qword,wparam:qword,lparam:qword local buff[Size_of_buffer]:byte local bufferUNICODE[Size_of_buffer*2]:byte mov hwnddlg,rcx xor ebx,ebx cmp edx,WM_COMMAND je wmCOMMAND cmp edx,WM_CLOSE je wmCLOSE cmp edx,WM_GRAPHNOTIFY je wmGRAPHNOTIFY cmp edx,WM_HSCROLL je wmHSCROLL cmp edx,WM_INITDIALOG jne wmBYE wmINITDIALOG:invoke LoadIcon,IMAGE_BASE,IDC_ICON1 invoke SendMessage,hwnddlg,WM_SETICON,0,rax invoke GetDlgItem,hwnddlg,ID_PROGRESS mov hProgress,rax invoke GetDlgItem,hwnddlg,ID_OPEN mov hOpen,rax invoke GetDlgItem,hwnddlg,ID_PLAY mov hPlay,rax invoke GetDlgItem,hwnddlg,ID_STOP mov hStop,rax invoke GetDlgItem,hwnddlg,ID_PAUSE mov hPause,rax invoke EnableWindow,hPause,FALSE invoke EnableWindow,hPlay,FALSE invoke EnableWindow,hStop,FALSE mov rax,hwnddlg mov hwndDlg,rax invoke SendMessage,hProgress,PBM_SETBARCOLOR,0FF0000h invoke SendDlgItemMessage,hwnddlg,ID_SLIDER,TBM_SETRANGEMIN,FALSE,0 invoke SendDlgItemMessage,hwnddlg,ID_SLIDER,TBM_SETRANGEMAX,FALSE,100 ;--------------------------------------------------------- ; Инициализация всех интерфейсов mov eax,offset pGraphBuilder mov [rsp+20h],rax mov ecx,offset CLSID_FilterGraph xor edx,edx;NULL mov r8d,CLSCTX_INPROC_SERVER mov r9d,offset IID_IGraphBuilder invoke CoCreateInstance test eax,eax jnz Exit ;Unable to create GraphBuilder inc count ;count=1 mov rcx, pGraphBuilder mov rax, [rcx] mov edx,offset IID_IMediaControl mov r8d,offset pMediaControl invoke [rax].IGraphBuilderVtbl.QueryInterface test eax,eax jnz Exit ;Unable to get interface IMediaControl inc count;count=2 mov rcx, pGraphBuilder mov rax, [rcx] mov edx,offset IID_IVideoWindow mov r8d,offset pVideoWindow invoke [rax].IGraphBuilderVtbl.QueryInterface test eax,eax jnz Exit ;Unable to get interface VideoWindow inc count;count=3 mov rcx, pGraphBuilder mov rax, [rcx] mov edx,offset IID_IMediaSeeking mov r8d,offset pMediaSeeking invoke [rax].IGraphBuilderVtbl.QueryInterface test eax,eax jnz Exit ;Unable to get interface MediaSeeking inc count;count=4 mov rcx, pGraphBuilder mov rax, [rcx] mov edx,offset IID_IMediaEventEx mov r8d,offset pEvent invoke [rax].IGraphBuilderVtbl.QueryInterface test eax,eax jnz Exit ;Unable to get interface Event inc count;count=5 mov rcx, pGraphBuilder mov rax, [rcx] mov edx,offset IID_IBasicVideo mov r8d,offset pBasicVideo invoke [rax].IGraphBuilderVtbl.QueryInterface test eax,eax jnz Exit ;Unable to get interface BasicVideo inc count;count=6 ;------------------------------------------------------------- ; Создать объект mov ecx,offset CLSID_MMDeviceEnumerator xor edx,edx mov r8d,CLSCTX_INPROC_SERVER mov r9d,offset IID_IMMDeviceEnumerator mov eax,offset deviceEnumerator mov [rsp+20h],rax invoke CoCreateInstance ; Инициализировать объект mov rcx,deviceEnumerator mov rax, [rcx] mov r9d,offset defaultDevice invoke [rax].IMMDeviceEnumerator.GetDefaultAudioEndpoint,,eRender,eConsole mov rcx,deviceEnumerator mov rax, [rcx] invoke [rax].IMMDeviceEnumerator.Release mov eax,offset endpointVolume mov [rsp+20h],rax mov rcx,defaultDevice mov rax,[rcx] mov edx,offset IID_IAudioEndpointVolume mov r8d,CLSCTX_INPROC_SERVER xor r9,r9 invoke [rax].IMMDevice.Activate mov rcx,defaultDevice mov rax, [rcx] invoke [rax].IMMDevice.Release jmp wmBYE wmHSCROLL:mov eax,r8d and eax,0FFFFh cmp eax,TB_THUMBTRACK ; Ползунок двигают мышью jne @f shr r8d,16 mov NewPosition,r8d cvtsi2ss xmm0,r8d divss xmm0,const100 movss fLevel,xmm0 jmp @0 @@: cmp eax,TB_THUMBPOSITION ; Ползунок перемещён мышью jne @f shr r8d,16 mov NewPosition,r8d cvtsi2ss xmm0,r8d divss xmm0,const100 movss fLevel,xmm0 jmp @0 @@: cmp eax,SB_LINEUP ;Нажата стрелка вверх или вправо jne @f dec NewPosition mov r8d,NewPosition mov edx,offset mask1 lea ecx,buff invoke wsprintf lea r8d,buff mov edx,ID_VOL invoke SetDlgItemText,hwnddlg mov eax,NewPosition mov [rsp+20h],rax invoke SendDlgItemMessage,hwnddlg,ID_SLIDER,TBM_SETPOS,TRUE jmp volume_down @@: cmp eax,SB_LINEDOWN ;Нажата стрелка вниз или влево jne wmBYE inc NewPosition mov r8d,NewPosition mov edx,offset mask1 lea ecx,buff invoke wsprintf lea r8d,buff mov edx,ID_VOL invoke SetDlgItemText,hwnddlg mov eax,NewPosition mov [rsp+20h],rax invoke SendDlgItemMessage,hwnddlg,ID_SLIDER,TBM_SETPOS,TRUE jmp volume_up @0: mov r8d,NewPosition mov edx,offset mask1 lea ecx,buff invoke wsprintf lea r8d,buff mov edx,ID_VOL invoke SetDlgItemText,hwnddlg mov eax,NewPosition mov [rsp+20h],rax invoke SendDlgItemMessage,hwnddlg,ID_SLIDER,TBM_SETPOS,TRUE jmp wmBYE wmGRAPHNOTIFY:; Получить событие из очереди and qword ptr [rsp+20h],0 mov rcx,pEvent mov rax,[rcx] invoke [rax].IMediaEventEx.GetEvent,,&evCode,¶m1,¶m2 or eax,eax jnz wmBYE ; Освободить событие mov rcx,pEvent mov rax,[rcx] invoke [rax].IMediaEventEx.FreeEventParams,,&evCode,¶m1,¶m2 ; Воспроизведение завершено? cmp evCode,EC_COMPLETE jne wmGRAPHNOTIFY invoke timeKillEvent,hTimer;удаление мультимедийного таймера ; Остановить воспроизведение mov rcx,pMediaControl mov rax,[rcx] call [rax].IMediaControlVtbl.Stop ; Перемотать поток на начало and lDuration,0 and nCurTrack,0 and qword ptr[rsp+20h],0 mov edx,offset lDuration mov rcx,pMediaSeeking mov rax,[rcx] invoke [rax].IMediaSeeking.SetPositions,,,AM_SEEKING_AbsolutePositioning,edx ; Установить пустой счетчик в интерфейсе and qword ptr[rsp+20h],0 mov edx,offset mask0 invoke wsprintf,&buff,,0,0 invoke SetDlgItemText,hwnddlg,ID_CUR,&buff invoke EnableWindow,hOpen,TRUE jmp wmGRAPHNOTIFY wmCOMMAND:cmp r8d,IDCANCEL je wmCLOSE cmp r8d,ID_PLAY je wmPLAY cmp r8d,ID_OPEN je wmOPEN cmp r8d,ID_STOP je wmSTOP cmp r8d,ID_UP je volume_up cmp r8d,ID_DN je volume_down cmp r8d,ID_MUT je volume_mute cmp r8d,ID_ABOUT je ABOUT cmp r8d,ID_PAUSE jne wmBYE wmPAUSE:; Пауза mov rcx,pMediaControl mov rax,[rcx] call [rax].IMediaControlVtbl.Pause_ jmp wmBYE ABOUT: mov edx,offset ClassName mov r8d,offset AboutMsg invoke ShellAbout,hwnddlg,,,IDC_ICON1 jmp wmBYE wmPLAY:; Играть ;делаем кнопку Open неактивной invoke EnableWindow,hOpen,FALSE ;делаем кнопки Pause и Stop активными invoke EnableWindow,hPause,TRUE invoke EnableWindow,hStop,TRUE mov r8d,offset TimeProc mov qword ptr[rsp+20h],TIME_PERIODIC invoke timeSetEvent,100,1,,0;установка мультимедийного таймера ;timeSetEvent( ; UINT uDelay, - задержка события в миллисекундах. Если это значение лежит вне диапазона допустимых значений задержки, поддерживаемых таймером, функция возвращает ошибку. ; UINT uResolution, - разрешение событий таймера в миллисекундах. Разрешение увеличивается при уменьшении значений; разрешение, установленное в нуль, показывает, что периодические события будут происходить с наибольшей возможной точностью. Для уменьшения системных издержек, тем не менее, вы должны использовать максимальное значение, соответствующее вашему приложению ; LPTIMECALLBACK lpTimeProc, - указатель на функцию обратного вызова, которая вызывается по истечению одиночного события или периодически по истечению периодических событий. Если fuEvent определяет флаг TIME_CALLBACK_EVENT_SET или TIME_CALLBACK_EVENT_PULSE, то значение параметра lpTimeProc интерпретируется как дескриптор события ; DWORD_PTR dwUser, - определяемые пользователем данные ; UINT fuEvent - тип события таймера TIME_PERIODIC Событие происходит каждые uDelay миллисекунд. mov hTimer,rax ;------------------------------------------------------------------ mov rcx,pMediaControl mov rax,[rcx] call [rax].IMediaControlVtbl.Run jmp wmBYE volume_mute:; Отключить/включить звук mov rcx,endpointVolume mov rax, [rcx] mov edx,offset bMute invoke [rax].IAudioEndpointVolume.GetMute ; Поменять значение на противоположное xor edx,edx cmp bMute,0 sete dl ; Установить состояние Mute mov rcx,endpointVolume mov rax, [rcx] invoke [rax].IAudioEndpointVolume.SetMute,,,NULL jmp get_volume volume_up:; Увеличить громкость mov rcx,endpointVolume mov rax, [rcx] xor edx,edx invoke [rax].IAudioEndpointVolume.VolumeStepUp jmp get_volume volume_down:; Уменьшить громкость mov rcx,endpointVolume mov rax, [rcx] xor edx,edx invoke [rax].IAudioEndpointVolume.VolumeStepDown get_volume:; Получить значение громкости [0.0 - 1.0] mov rcx,endpointVolume mov rax,[rcx] mov edx,offset fLevel invoke [rax].IAudioEndpointVolume.GetMasterVolumeLevelScalar ; Привести значение к процентному и целочисленному movss xmm0,fLevel mulss xmm0,const100 cvtss2si r8d,xmm0 mov NewPosition,r8d mov edx,offset mask1 lea ecx,buff invoke wsprintf lea r8d,buff mov edx,ID_VOL invoke SetDlgItemText,hwnddlg mov eax,NewPosition mov [rsp+20h],rax invoke SendDlgItemMessage,hwnddlg,ID_SLIDER,TBM_SETPOS,TRUE jmp wmBYE wmOPEN:;fill OPENFILENAME lea eax,buff mov ofn.lpstrFile,rax lea eax,Filter mov ofn.lpstrFilter,rax mov rax,hwnddlg mov ofn.hwndOwner,rax lea ecx,ofn;адрес OPENFILENAME invoke GetOpenFileName test eax,eax jz wmCLOSE ; user clicks "Cancel" inc count;count=7 ;делаем кнопку Play активной invoke EnableWindow,hPlay,TRUE ;в качестве названия диалога выводим название видео lea edx,buff invoke SetWindowText,hwnddlg invoke SendMessage,hProgress,PBM_SETPOS,0,0 ;переводим название видео в UNICODE mov qword ptr [rsp+28h],Size_of_buffer*2 lea eax,bufferUNICODE mov [rsp+20h],rax invoke MultiByteToWideChar,0,0,&buff,-1 ; Загрузить файл для воспроизведения mov rcx,pGraphBuilder mov rax,[rcx] xor r8,r8 lea edx,bufferUNICODE invoke [rax].IGraphBuilderVtbl.RenderFile test eax,eax jnz Exit ;Unable to create GraphBuilder inc count ; Назначить окно для воспроизведения видео invoke GetDlgItem,hwnddlg,ID_VIDEO mov temp,rax test eax,eax jz Exit ;Unable to create GraphBuilder inc count mov edx,eax mov rcx,pVideoWindow mov rax,[rcx] invoke [rax].IVideoWindowVtbl.put_Owner test eax,eax jnz Exit ; user clicks "Cancel" inc count mov rcx,pBasicVideo mov rax,[rcx] mov edx,offset pWidth invoke [rax].IBasicVideo.get_VideoWidth test eax,eax jnz Exit ; user clicks "Cancel" inc count mov rcx,pBasicVideo mov rax,[rcx] mov edx,offset pHeight invoke [rax].IBasicVideo.get_VideoHeight test eax,eax jnz Exit ; user clicks "Cancel" inc count cmp pWidth,IMG_X ja loc_need_resize cmp pHeight,IMG_Y jbe loc_create_video loc_need_resize:; Пресчет размеров по горизонтали mov eax,pWidth;450 cmp eax,pHeight;320 jb @f mov eax,pHeight;320 imul eax,IMG_X;eax=332*320=106240=1D2E0h xor edx,edx idiv pWidth;1D2E0h/1C2h=109h mov pHeight,eax mov pWidth,IMG_X;14Ch jmp loc_create_video @@: mov eax,pWidth imul eax,IMG_Y xor edx,edx idiv pHeight mov pWidth,eax mov pHeight,IMG_Y loc_create_video:; Смещение по X mov eax,IMG_X;14Ch sub eax,pWidth jns @f neg eax @@: shr eax,1;eax=0 mov deltaX,eax ; Смещение по Y mov eax,IMG_Y;eax=0F8h sub eax,pHeight jns @f neg eax @@: shr eax,1 mov deltaY,eax ; Установить стиль окна mov rcx,pVideoWindow mov rax,[rcx] mov edx,WS_CHILD or WS_CLIPSIBLINGS invoke [rax].IVideoWindowVtbl.put_WindowStyle test eax,eax jnz Exit ;Unable to create GraphBuilder inc count ; Установить размер области воспроизведения mov eax,pHeight mov [rsp+20h],rax mov rcx,pVideoWindow mov rax,[rcx] mov r9d,pWidth mov r8d,deltaY mov edx,deltaX call [rax].IVideoWindowVtbl.SetWindowPosition test eax,eax jnz Exit ;Unable to create GraphBuilder inc count ; Назначить окно для событий плеера mov rcx,pEvent mov rax,[rcx] xor r9,r9 mov r8d,WM_GRAPHNOTIFY mov rdx,hwnddlg invoke [rax].IMediaEventEx.SetNotifyWindow test eax,eax jnz Exit ;Unable to create GraphBuilder inc count ; Заблокировать окно воспроизведения invoke EnableWindow,temp,FALSE ; Получить длительность медиафайла mov rcx,pMediaSeeking mov rax,[rcx] mov edx,offset lDuration invoke [rax].IMediaSeeking.GetDuration test eax,eax jnz Exit ;Unable to create GraphBuilder inc count ; Пересчитать в секунды xor edx,edx mov eax,dword ptr lDuration shr eax,7 mov ecx,78125;78125*128=10000000 div ecx ;в eax секунды mov DurationInSec,eax xor edx,edx mov ecx,60*60 div ecx mov r8d,eax;в r8 часы mov eax,edx;в edx секунды xor edx,edx ; Пересчитать в минуты и секунды mov ecx,60 div ecx mov [rsp+20h],rdx;в edx секунды mov r9d,eax;в r9 минуты mov edx,offset mask0 lea ecx,buff invoke wsprintf lea r8d,buff mov edx,ID_DTN mov rcx,hwnddlg invoke SetDlgItemText mov r9d,DurationInSec imul r9d,10 shl r9,16 invoke SendMessage,hProgress,PBM_SETRANGE,0 invoke SendMessage,hProgress,PBM_SETSTEP,1,0 and nCurTrack,0 jmp wmBYE wmSTOP:; Стоп mov rcx,pMediaControl mov rax,[rcx] call [rax].IMediaControlVtbl.Stop jmp wmBYE wmCLOSE:; Прибраться за собой mov rcx,pEvent mov rax,[rcx] invoke [rax].IMediaEventEx.SetNotifyWindow,,0,0,0 mov rcx,pEvent mov rax,[rcx] call [rax].IMediaEventEx.Release mov rcx,pBasicVideo mov rax,[rcx] call [rax].IBasicVideo.Release mov rcx,pVideoWindow mov rax,[rcx] call [rax].IVideoWindowVtbl.Release mov rcx,pMediaControl mov rax,[rcx] call [rax].IMediaControlVtbl.Release mov rcx,pMediaSeeking mov rax,[rcx] call [rax].IMediaSeeking.Release mov rcx,pGraphBuilder mov rax,[rcx] call [rax].IGraphBuilderVtbl.Release invoke EndDialog,hwnddlg,0 wmBYE: xor eax,eax leave retn DialogProc endp TimeProc proc uTimerID:QWORD,uMsg:QWORD,dwUser:QWORD,dw1:QWORD,dw2:QWORD local buff[Size_of_buffer]:byte ; Получить состояние воспроизведения mov r8d,offset pState xor edx,edx mov rcx,pMediaControl mov rax,[rcx] call [rax].IMediaControlVtbl.GetState cmp pState,State_Running jne exit_ ; Получить текущую позицию воспроизведения mov rcx,pMediaSeeking mov rax,[rcx] mov edx,offset lDuration mov r8d,offset pStop invoke [rax].IMediaSeeking.GetPositions ; Пересчитать в секунды xor edx,edx mov eax,dword ptr lDuration shr eax,7 mov ecx,78125;78125*128=10000000 div ecx ;в eax секунды xor edx,edx mov ecx,60*60 div ecx mov r8d,eax;в r8 часы mov eax,edx xor edx,edx ; Пересчитать в минуты и секунды mov ecx,60 div ecx mov [rsp+20h],rdx;в edx секунды mov r9d,eax;в r9 минуты mov edx,offset mask0 lea ecx,buff invoke wsprintf lea r8d,buff mov edx,ID_CUR invoke SetDlgItemText,hwndDlg ; Увеличить счетчик по системному событию inc nCurTrack mov r8d,nCurTrack invoke SendMessage,hProgress, PBM_SETPOS, , 0 exit_: leave ret TimeProc endp .data? temp dq ? pGraphBuilder dq ? pMediaControl dq ? pVideoWindow dq ? pMediaSeeking dq ? pBasicVideo dq ? pEvent dq ? pWidth dd ? pHeight dd ? deltaX dd ? deltaY dd ? evCode dd ? param1 dd ? param2 dd ? lDuration dq ? pStop dq ? ; DATA XREF: DialogProc+303o pState dd ? hProgress dq ? hOpen dq ? hPlay dq ? hStop dq ? hPause dq ? DurationInSec dd ? hTimer dq ? nCurTrack dd ? hwndDlg dq ? NewPosition dd ? deviceEnumerator dq ? eRender dq ? eConsole dq ? defaultDevice dq ? endpointVolume dq ? bMute dd ? .data fLevel dd 0.0 const100 dd 100.0 mask0 db '%.2u:%.2u:%.2u',0 mask1 db '%d%%',0 CLSID_FilterGraph GUID <0E436EBB3h,524Fh, 11CEh,{ 9Fh,53h,0,20h,0AFh,0Bh,0A7h,70h}> IID_IGraphBuilder GUID < 56A868A9h,0AD4h, 11CEh,{0B0h,3Ah,0,20h,0AFh,0Bh,0A7h,70h}> IID_IMediaControl GUID < 56A868B1h,0AD4h, 11CEh,{0B0h,3Ah,0,20h,0AFh,0Bh,0A7h,70h}> IID_IVideoWindow GUID < 56A868B4h,0AD4h, 11CEh,{0B0h,3Ah,0,20h,0AFh,0Bh,0A7h,70h}> IID_IMediaSeeking GUID < 36B73880h,0C2C8h,11CFh,{ 8Bh,46h,0,80h, 5Fh,6Ch,0EFh,60h}> IID_IMediaEventEx GUID < 56A868C0h,0AD4h, 11CEh,{0B0h,3Ah,0,20h,0AFh,0Bh,0A7h,70h}> IID_IBasicVideo GUID < 56A868B5h,0AD4h, 11CEh,{0B0h,3Ah,0,20h,0AFh,0Bh,0A7h,70h}> ; GUID {BCDE0395-E52F-467C-8E3D-C4579291692E} CLSID_MMDeviceEnumerator GUID <0BCDE0395h,0E52Fh,467Ch,{ 8Eh,3Dh,0C4h,57h,92h,91h,69h,2Eh}> ; GUID {A95664D2-9614-4F35-A746-DE8DB63617E6} IID_IMMDeviceEnumerator GUID <0A95664D2h, 9614h,4F35h,{0A7h,46h,0DEh,8Dh,0B6h,36h,17h,0E6h}> ; GUID {5CDF2C82-841E-4546-9722-0CF74078229A} IID_IAudioEndpointVolume GUID < 5CDF2C82h, 841Eh,4546h,{ 97h,22h, 0Ch,0F7h,40h,78h,22h,9Ah}> Filter db "Video files *.avi; *.qt; *.mov; *.mpg; *.mpeg; *.m1v; *.vob",0 db "*.wmv, *.flv, *.mp4",0,0 ofn label OPENFILENAME lStructSize dd sizeof OPENFILENAME,0 hwndOwner dq 0 hInstance dq IMAGE_BASE lpstrFilter dq 0 lpstrCustomFilter dq 0 nMaxCustFilter dd 0 nFilterIndex dd 0 lpstrFile dq 0 nMaxFile dd Size_of_buffer,0 lpstrFileTitle dq 0 nMaxFileTitle dd 0,0 lpstrInitialDir dq 0 lpstrTitle dq 0 Flags dd OFN_FILEMUSTEXIST or OFN_PATHMUSTEXIST or OFN_LONGNAMES or OFN_EXPLORER or OFN_HIDEREADONLY nFileOffset dw 0 nFileExtension dw 0 lpstrDefExt dq 0 lCustData dq 0 lpfnHook dq 0 lpTemplateName dq 0 count dd 0 AboutMsg db 'Mikl__ 2024',0 ;------------------------------------- mb label MSGBOXPARAMS dd sizeof MSGBOXPARAMS,?;cbSize dq 0 ;hwndOwner dq IMAGE_BASE ;hInstance dq ? ;lpszText dq 0 ;lpszCaption dd MB_OK or MB_USERICON,?;dwStyle dq IDC_ICON1 ;lpszIcon dd 0,?;dwContextHelpId dq 0 ;lpfnMsgBoxCallback dd 0,?;dwLanguageId zero db '0',0 one db 'Unable to create GraphBuilder',0 two db 'Unable to get interface IMediaControl',0 tree db 'Unable to get interface VideoWindow',0 four db 'Unable to get interface MediaSeeking',0 five db 'Unable to get interface Event',0 six db 'Unable to get interface BasicVideo',0 seven db 'Do not select any media files!',0 eight db 'Unable to open the video file',0 nine db '9',0 ten db '10',0 eleven db '11',0 twelve db '12',0 thirteen db '13',0 fourteen db '14',0 fifteen db '15',0 sixteen db 'Bye-bye!',0 seventeen db '17',0 eightteen db '18',0 nineteen db '19',0 hande dq zero,one,two,tree,four,five,six,seven,eight,nine, ten, eleven, twelve, thirteen dq fourteen,fifteen,sixteen,seventeen,eightteen,nineteen ClassName db "Uncle Remus tales #37k: Player Demo",0 end Плеер до конца не доделан, поэтому предлагаю его коллективно усовершенствовать. Буду рад любым предложениям
Mikl___, интересно, у масма есть макросы comcall/cominvk? Например в fasm'e com-интерфейсы можно объявлять так, в результате чего получаем общие структуры для х32/64, поскольку размеры указателей на методы явно не определены. Да и сам вызов становится удобней (в одной строке, как обычный invoke): Код (Text): interface IMediaSeeking QueryInterface,\ AddRef,\ Release,\ GetCapabilities,\ CheckCapabilities,\ IsFormatSupported,\ QueryPreferredFormat,\ GetTimeFormat,\ IsUsingTimeFormat,\ SetTimeFormat,\ GetDuration,\ GetStopPosition,\ GetCurrentPosition,\ ConvertTimeFormat,\ SetPositions,\ GetPositions,\ GetAvailable,\ SetRate,\ GetRate,\ GetPreroll
Marylin, размер указателей в masm64 ― QWORD. Здесь же, хорошо развитая система макросов (правда я ей давно не пользуюсь ) и comcall/cominvk с общими структурами для х32/64 можно написать под masm64 самому (по-моему готовых нет, но это не точно )
Глава пятьдесят третья. Видео-плеер Братца Кролика (версия #2) Один из промежуточных вариантов, до конца еще далеко...
Глава пятьдесят третья. Видео-плеер Братца Кролика (версия #3) Очередная недоделанная версия. Перед открытием и запуском видео-файла установите размер изображения (нормальный, половинный, удвоенный или полноэкранный) и скорость воспроизведения (Playback Rate). Во вложении asm-/rc-/ico-/exe-файлы.
Mikl___, Мир опустел… Земля остыла… А вьюга трупы замела, И ветром звёзды загасила, И бьёт во тьме в колокола Картинки скачивают чаще чем исходники, даже кэп не в силах это обьяснить
Mikl___, нормально всё идёт. Главное взять старт и создать скелет, а всевозможного рода украшательства фейса можно потом напильником подточить. Потихоньку оденешь какой-нибудь скин на основное окно, и будет всё тип-топ.
Кап, картинка считается скаченной если просто открываешь страницу, на которой эта картинка расположена. А вот вложение скачивается осознано. Тимур-ука, спасибо на добром слове катта рахмат!
Mikl___ рассинхрон между менюшками и кнопами в окошке запуск tut_37k\tut_37k.exe меню - Play -> Play - чет-то играет, ползунок бежит вперед, а что оно играет??? видиво то нету еще PS после такого мифического Play по кнопке Exit - крашиться и даже какой-то MessageBox ругается (не успеваю прочитать, прячется автоматом) Unhandled exception at 0x0000000000401729 (tut_37k.exe) in WER7026.tmp.mdmp: 0xC0000005: Access violation reading location 0x0000000004E84020. --- Сообщение объединено, 8 июн 2024 --- Playback rate как-то странно работает пару сек пашет что заказал, а потом фоллбек к 1.00 x