Код (Text): interface IWebBrowser2,\ QueryInterface,AddRef,Release,GetTypeInfoCount,GetTypeInfo,GetIDsOfNames,Invoke,GoBack,GoForward,GoHome,GoSearch,Navigate,Refresh,Refresh2,Stop,get_Application,get_Parent,get_Container,get_Document,get_TopLevelContainer,\ get_Type,get_Left,put_Left,get_Top,put_Top,get_Width,put_Width,get_Height,put_Height,get_LocationName,get_LocationURL,get_Busy,Quit,ClientToWindow,PutProperty,GetProperty,get_Name,get_HWND,get_FullName,get_Path,get_Visible,\ put_Visible,get_StatusBar,put_StatusBar,get_StatusText,put_StatusText,get_ToolBar,put_ToolBar,get_MenuBar,put_MenuBar,get_FullScreen,put_FullScreen,Navigate2,QueryStatusWB,ExecWB,ShowBrowserBar,get_ReadyState,get_Offline,\ put_Offline,get_Silent,put_Silent,get_RegisterAsBrowser,put_RegisterAsBrowser,get_RegisterAsDropTarget,put_RegisterAsDropTarget,get_TheaterMode,put_TheaterMode,get_AddressBar,put_AddressBar,get_Resizable,put_Resizable Код (Text): locals iWebBrowser2 IWebBrowser2 endl pushdata pbinIID_IWebBrowser2,MIDL_INTERFACE D30C1661-CDAF-11d0-8A3E-00C04FC9E26E lea eax,[iWebBrowser2] cominvk browserObject,QueryInterface,[pbinIID_IWebBrowser2],eax popdata test eax,eax .if ZERO? lea eax,[vtUrl] invoke VariantInit,eax mov [vtUrl.vt],VT_BSTR pushdatanp du 'about:blank'\,0 invoke SysAllocString,esp popdata mov DWORD[vtUrl.value],eax cominvk iWebBrowser2,Navigate2,addr vtUrl,0,0,0,0 минус пара макросов так примерно. interface и cominvk стоковые макросы фасма. В примерах в комплекте фасма есть ddraw, там com используется, можешь это посмотреть.
От нефиг делать даже покажу. Гуглишь "IDXGISwapChain filetype:h" Находишь https://github.com/apitrace/dxsdk/blob/master/Include/dxgi.h В нем: Код (Text): #else /* C style interface */ typedef struct IDXGISwapChainVtbl { BEGIN_INTERFACE HRESULT ( STDMETHODCALLTYPE *QueryInterface )( "C style interface" удобней брать, там с учетом всех наследований начиная с IUnknown все методы: Код (Text): HRESULT ( STDMETHODCALLTYPE *QueryInterface )( IDXGISwapChain * This, /* [in] */ REFIID riid, /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); ULONG ( STDMETHODCALLTYPE *AddRef )( IDXGISwapChain * This); ULONG ( STDMETHODCALLTYPE *Release )( IDXGISwapChain * This); ... Выписываешь их внимательно: Код (Text): interface IDXGISwapChain,\ QueryInterface,\ AddRef,\ Release,\ SetPrivateData,\ SetPrivateDataInterface,\ GetPrivateData,\ GetParent,\ GetDevice,\ Present,\ GetBuffer,\ SetFullscreenState,\ GetFullscreenState,\ GetDesc,\ ResizeBuffers,\ ResizeTarget,\ GetContainingOutput,\ GetFrameStatistics,\ GetLastPresentCount А потом задумываешься тот ли ты язык выбрал Если не передумал: Код (Text): locals iDxgiSwapChain IDXGISwapChain endl mov [iDxgiSwapChain],<твой адрес объекта> ;вообще они обычно с других интерфейсов должны получаться cominvk iDxgiSwapChain,Release
Спасибо за подробное объяснение, без него я бы точно долго разбирался. Когда выбирал с какого языка начать изучать программирование оказалось что в ассемблере хоть что-то понятно, начал с него. Сейчас решил расширить свою базу знаний дополнив его C++, и мат при изучении этого языка звучит так же часто как и на работе. Частенько приходится использовать метод научного тыка, что бы всё начало компилироваться. Ну надеюсь это временное явление.
Когда я пытаюсь в студии что-то делать, у меня тот же голый апи в сишном синтаксисе получается. Асм вырабатывает вредные привычки. Что касается com - там на самом деле дофига нюансов, в которых я так и не понял как в хидерах разбираться. Где-то вариант нужно правильно инициализировать, где-то нет, где-то вариант указателем передается методу, где-то прямо в аргументы вываливается. Где-то строку можно так сунуть, где-то подойдет только строка, полученная SysAllocString. То, что в студии делается просто, на фасме будешь вымучивать. Выручает только vbs, где можно использовать нужный метод, поставить на него бряк и посмотреть правильные аргументы.
А какое отношение ко всей этой петрушке имеет GUID. Допустим я сейчас пытаюсь вызвать метод Код (Text): //Visual Studio hr = g_pSwapChain->GetBuffer( 0, __uuidof(ID3D11Texture2D), (LPVOID*)&pBackBuffer ); // Мой вызов на Fasm cominvk iDXGISwapChain,GetBuffer,0,iD3D11Texture2D,[adrBuffTargetView]; Во втором аргументе если смотреть ассемблерный листинг Visual Studio передается какой-то адрес из смещение GUID_6f15aaf2_d208_4e89_9ab4_489535d34f9c. Я знаю что GUID идентефикатор который присваивается com объекту при его создании, но он никакого участия не принимает при объявлении интерфейса на ассемблере.
Вообще-то у каждого интерфейса есть такой же ид, через CoCreateInstance или QueryInterface по нему интерфейс создается. Здесь по всей видимости может быть куча разных версий ppSurface, вот ид нужного интерфейса, с которым умеешь работать, ты и заказываешь. Макрос чтоб эти идентификаторы объявлять: Код (Text): macro MIDL_INTERFACE value { match arg1-arg2-arg3-arg4-arg5,value \{ dq 0x\#arg1 + (0x\#arg2 * 0x100000000) + (0x\#arg3 * 0x1000000000000),\ (0x\#arg4 and 0x00FF) shl 8 + (0x\#arg4 and 0xFF00) shr 8 +\ (0x\#arg5 and 0xFF0000000000) shr 24 + (0x\#arg5 and 0xFF00000000) shr 8 +\ (0x\#arg5 and 0xFF000000) shl 8 + (0x\#arg5 and 0xFF0000) shl 24 +\ (0x\#arg5 and 0xFF00) shl 40 + (0x\#arg5 and 0xFF) shl 56 \} } Этот идентификатор статичный https://github.com/apitrace/dxsdk/blob/master/Include/d3d11.h Код (Text): MIDL_INTERFACE("6f15aaf2-d208-4e89-9ab4-489535d34f9c") ID3D11Texture2D : public ID3D11Resource
Казалось бы ларчик просто открывался, но нет. Всё же я что-то не до понял. Код (Text): //функция в которой создаются объекты из неё получаю указатель на объект invoke D3D11CreateDeviceAndSwapChain,0,D3D_DRIVER_TYPE_HARDWARE,0,0,fLevels,\ 3,D3D11_SDK_VERSION,_sd,_pSwapChain,_pd3dDevice,_featureLevel,_pImmediateContext ...... mov eax,_pSwapChain; mov [iDXGISwapChain],eax cominvk iDXGISwapChain,GetBuffer, 0,IID_ID3D11Texture2D,[adrBuffTargetView] если смотреть код в отладчике в итоге происходит вызов [eax+24], но у меня там пустота, а в Visual Studio код из библиотеки dxgi.dll, т.е. com объект который находится в этой библиотеки, у меня не как не задействован. Какая же функция соединяет мои интерфейсы с их библиотекой?
Ты взял указатель на объект и сунул его в указатель. Передавай функции сразу указатель на объект. Код (Text): include 'win32ax.inc' ... invoke D3D11CreateDeviceAndSwapChain,0,D3D_DRIVER_TYPE_HARDWARE,0,0,fLevels,\ 3,D3D11_SDK_VERSION,_sd,addr iDXGISwapChain,_pd3dDevice,_featureLevel,_pImmediateContext ... cominvk iDXGISwapChain,GetBuffer, 0,IID_ID3D11Texture2D,[adrBuffTargetView]
Вроде всё уже разжовано, пережёвано, но каменный цветок всё равно не выходит. Проверял, перепроверял свою программу и ошибок вроде нет, все возвращаемые значение правильные, все аргументы функций такие как в работающем примере С++, но когда дело доходит до Render(отрисовки) в задний буфер помещаются данные, метод выдаёт исключение и связано оно с тем что когда идет обращение к [iD3D11RenderTargetView+C0h] внутри вызова в моём случае там ноль, а в примере С++ какой-то адрес. Заполнение заднего буфера цветом не работает. Вот значимый код и исходник на всякий случай, открывать в Sublime Text3 форматирование 4. Чтобы он был в удобочитаемом виде. Код (Text): ....... ;Цикл сообщений @@: cmp[_msg.message],WM_QUIT; jz .exit; ; invoke PeekMessageW,_msg,0,0,0,PM_REMOVE test eax,eax; jz .render; invoke TranslateMessage,_msg; invoke DispatchMessageW,_msg; jmp @b; .render: stdcall Render jmp @b; ........ proc InitDevice uses ebx esi edi; ;Заполнение структуры DXGI_SWAP_CHAIN_DESC :: structure filling DXGI_SWAP_CHAIN_DESC mov [_sd.BufferCount],1; mov [_sd.BufferDesc.Width],WIDTH; mov [_sd.BufferDesc.Height],HEIGHT; mov [_sd.BufferDesc._Format],DXGI_FORMAT_R8G8B8A8_UNORM; mov [_sd.BufferDesc.RefreshRate.Numerator],75; mov [_sd.BufferDesc.RefreshRate.Denominator],1; mov [_sd.BufferUsage],DXGI_USAGE_RENDER_TARGET_OUTPUT; mov eax,[_hwnd]; mov [_sd.OutputWindow],eax; mov [_sd.SampleDesk.Count],1; mov [_sd.SampleDesk.Quality],0; mov [_sd.Windowed],TRUE; ;Создаем устройства device,swapcain,contest и получаем указатели на созданные объекты ; invoke D3D11CreateDeviceAndSwapChain,0,D3D_DRIVER_TYPE_HARDWARE,0,0,fLevels,\ 3,D3D11_SDK_VERSION,_sd,iDXGISwapChain,iD3D11Device,_featureLevel,iD3D11DeviceContext ;Cоздаем объект заднего буфера cominvk iDXGISwapChain,GetBuffer,\ 0,IID_ID3D11Texture2D,iD3D11Texture2D; cominvk iD3D11Device,CreateRenderTargetView,\ [iD3D11Texture2D],0,iD3D11RenderTargetView; cominvk iD3D11Texture2D,Release; ;Подключаем объект заднего буфера к контексту cominvk iD3D11DeviceContext,OMSetRenderTargets,\ 1,iD3D11RenderTargetView,0; ;Настройка и подключение вьюпорта mov [_vp.Width], 100.0; mov [_vp.Height],100.0; mov [_vp.MinDepth],0.0; mov [_vp.MaxDepth],1.0; mov [_vp.TopLeftX],0.0; mov [_vp.TopLeftY],0.0; cominvk iD3D11DeviceContext,RSSetViewports,\ 1,_vp; xor eax,eax; ret; endp; ;_________Render________________________________________________________________4 ;Рисование кадра proc Render ; ;Очищаем задний буфер cominvk iD3D11DeviceContext,ClearRenderTargetView,\ ;<======== НЕ РАБОТАЕТ iD3D11RenderTargetView,ClearColor; ;устанавливаем задний буфер на экран cominvk iDXGISwapChain,Present,0,0; ret; endp; ..... data ClearColor dd 0.0,0.0,1.0,1.0; И ещё один момент не понятен, но возможно в будущем решится сам собой. Хочу что бы вывод directx занимал не всё окно а квадрат 100 на 100, и везде указываю этот размер. Но он в любом случае занимает всё окно.
Указатель на указатель ты обычно передаешь при создании объекта. При передаче методу значение указателя. Логика такая. Можно в отладчике было посмотреть на чем крашится. Код (Text): cominvk iD3D11DeviceContext,ClearRenderTargetView,[iD3D11RenderTargetView],ClearColor Код (Text): invoke GetModuleHandleA,0 invoke CreateWindowExA,0,szStatic,szNull,WS_VISIBLE+WS_CHILD,0,0,100,100,[hwnd],0,eax,0 mov [hChildWindow],eax ... mov eax,[hChildWindow] mov [_sd.OutputWindow],eax;