Брался за эту технологию раза 4. Каждый раз мозг вскипает и я отступаю. Как можно осилить эту технологию, при условии, что я не знаю ООП и С++? Свои компоненты я писать не планирую, мне бы просто понять, как юзать те, что уже есть в винде. Ну вот пример https://docs.microsoft.com/en-us/wi...core/nf-shobjidl_core-ifileoperation-copyitem Делаю копипаст оттуда, собираю Код (Text): cannot convert from 'const CLSID' to 'const IID *const ' too few arguments for call Release' : is not a member of 'IFileOperation' Как такое может быть, что код с мсдн не собирается в 2008 студии? Настройки все по дефолту. Причем последние две ошибки вообще удивили - это какой-то новый компонент, или с версии в версию винды меняется к-тво аргументов и методы объекта? В общем, еще раз попробую, если не пойдет, значит не судьба.
Лично я понимаю технологию com с сугубо практической точки зрения, так: - объявляешь тип объекта - получаешь указатель на этот объект из какой либо функции создания этого объекта, присваиваешь полученный указатель объекту - подставляешь к объекту(полученному указателю) методы(т.е. функции) и пользуешься. Но это всё в С++, на ассемблере всё немного сложнее.
Какие заголовки подключены? Собираешь в C или C++, поскольку эта ошибка обычно появляется когда собираешь на C (код в мсдн на C++). В C нужно напрямую через виртуальную таблицу вызывать вместе с передачей объекта, также там нет __uuidof: Код (C): HRESULT CopyItem(__in PCWSTR pszSrcItem, __in PCWSTR pszDest, PCWSTR pszNewName) { // // Initialize COM as STA. // HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE); if (SUCCEEDED(hr)) { IFileOperation *pfo; // // Create the IFileOperation interface // hr = CoCreateInstance(&CLSID_FileOperation, NULL, CLSCTX_ALL, &IID_IFileOperation, &pfo); if (SUCCEEDED(hr)) { // // Set the operation flags. Turn off all UI from being shown to the // user during the operation. This includes error, confirmation, // and progress dialogs. // hr = pfo->lpVtbl->SetOperationFlags(pfo, FOF_NO_UI); if (SUCCEEDED(hr)) { // // Create an IShellItem from the supplied source path. // IShellItem *psiFrom = NULL; hr = SHCreateItemFromParsingName(pszSrcItem, NULL, &IID_IShellItem, &psiFrom); if (SUCCEEDED(hr)) { IShellItem *psiTo = NULL; if (NULL != pszDest) { // // Create an IShellItem from the supplied // destination path. // hr = SHCreateItemFromParsingName(pszDest, NULL, &IID_IShellItem, &psiTo); } if (SUCCEEDED(hr)) { // // Add the operation // hr = pfo->lpVtbl->CopyItem(pfo, psiFrom, psiTo, pszNewName, NULL); if (NULL != psiTo) { psiTo->lpVtbl->Release(psiTo); } } psiFrom->lpVtbl->Release(psiFrom); } if (SUCCEEDED(hr)) { // // Perform the operation to copy the file. // hr = pfo->lpVtbl->PerformOperations(pfo); } } // // Release the IFileOperation interface. // pfo->lpVtbl->Release(pfo); } CoUninitialize(); } return hr; } В COM первым аргументом передается ссылка на объект, а сама таблица методов содержится по этому адресу (указатель на интерфейс). Ты вызываешь метод напрямую - так не пойдет, т.к. тут нет ООП - нужно все делать руками. Получаешь указатель на таблицу методов lpVtbl и затем уже вызываешь нужный метод, передавая первым параметром указатель на объект (интерфейсный указатель). Вот еще по теме создание COM библиотеки на чистом C без каких-либо зависимостей и вызов из VB6. Также в той теме есть примеры работы на ассемблере и вообще там целая дискуссия на эту тему.
M0rg0t, WASM.IN → "Публикации" → "COM и OOP" 3 кита COM. Кит первый: реестр статья Roustem Galeev 3 кита COM. Кит второй: dll статья Roustem Galeev COM повсюду. Или как использовать регулярные выражения при программировании на ассемблере статья W4FhLF COM в Ассемблере - Часть I статья Bill T., перевод Aquila COM в Ассемблере - Часть II статья Bill T., перевод Aquila Как получить доступ к COM-объекту, используя ассемблер статья Ernie, перевод Aquila Взгляд на ООП из низкого уровня статья vid, перевод DarkWanderer Win x64 Tutorial #37f: video-player and Component Object Model Глава 4. Объектно-ориентированное программирование глава из "Турбо Ассемблер 3.0/tasm/#1-2. Руководство пользователя" Object-Oriented Programming example (Win32 Asm) статья с сайта AsmGuru62 Reversing Microsoft Visual C++ Part II: Classes, Methods and RTTI статья igorsk Методы реализации ООП на низком уровне топик на wasm.in Win32 OOP ASM Source Code Generator 47k Generates Object-Oriented ASM source code for: Base class. Derived class. Object Oriented Programming In Assembly статья Martyn.Rae Object-Oriented Programming in Assembly Language статья Randall Hyde RSDN.ORG → COM/DCOM/COM+ Сборник статей Основы Исследования Практика Проблемы COM и Script
Почему иногда нужно объявлять эти GUID самому? Вот пример ( взято со статьи Rel ) Код (Text): static const GUID IID_IDirectDraw = { 0x6c14db80, 0xa733 , 0x11ce,{ 0xA5, 0x21, 0x00, 0x20, 0xAF, 0x0B, 0xE5, 0x60 } }; хотя есть инклуды Код (Text): #include <ddraw.h> #include <uuids.h> Но все равно пишет ошибку линкера. В чем прикол? или эти инклуды для плюсов? Также интересно, почему функция DirectDrawCreate не требует CoInitilize , хотя там создаются СОМ объекты.. Не могу разобраться в этой бредотехнологии и все, вроде чето получилось и дальше куча вопросов.
Ну чисто формально GUID - это 16 байт статических константных данных, они должны располагаться в какой-то единице трансляции (объектном файле или библиотеке). Если бы их объявляли в хедере и ты подключал этот хедер в образно в двух сишных файлах, то получал бы ошибку редифинишена. Поэтому например в MinGW есть такой хак, как подключение initguid.h, который говорит компилятору, мол в этом сишном файле объяви эти гуиды, а не объяви ссылку на них. Не-не, ты попутал, Рел никогда про директдро не писал.
Rel, ну ты приводил пример , как объявлять guid, там про дебаг были, но не суть, просто пример; в кодеблокс вообще ошибки пишет, там даже не хочу пробовать, если честно. Там многие либы еще с ХР не обновлялись походу.
А, понял, о чем ты, окей. Ну с кодблоксом ты можешь использовать любой компилятор и студийный тоже, с любыми подходящими под компилятор библиотеками.
Нужно просто знать как работает DEFINE_GUID (секция How does the DEFINE_GUID macro work?) Словом если нужно использовать определение из хидера достаточно включить Initguid.h в один из cpp файлов перед хидером. Альтернативно можно использовать определение из статической библиотеки. Для DirectDraw нужно подключать ddraw.lib и dxguid.lib. Потому что объект создается не напрямую. В MSDN так и написано:
Подскажите, как эмулировать нажатие на кнопку на странице? Представим, что есть хтмл код вида Код (Text): <textarea cols="40" rows="4" id="txtdata" name="send1"></textarea> <input type="button" id="subm1"> и JS код, который отслеживает ONCHANGE событие текстового поля и что-то там делает. Код (C++): IDispatch* pDispatch = NULL; hr = WebBrowser->lpVtbl->get_Document(WebBrowser,&pDispatch); // объект браузера if (FAILED(hr) && !pDispatch) ExitProcess(EXIT_FAILURE); // объект документа IHTMLDocument3* pDocument3 = NULL; hr = pDispatch->lpVtbl->QueryInterface(pDispatch, &IID_IHTMLDocument3, &pDocument3); //элемент IHTMLElement *pElementSend = NULL; //textarea - получаем элемент hr = pDocument3->lpVtbl->getElementById(pDocument3, L"txtdata", &pElementSend); if (FAILED(hr) && !pElementSend) ExitProcess(EXIT_FAILURE); //вписываю туда текст hr = pElementSend->lpVtbl->put_innerText(pElementSend, L"data123"); if (FAILED(hr)) ExitProcess(EXIT_FAILURE); IHTMLElement *pButton; //получаю кнопку, нажимаю на нее hr = pDocument3->lpVtbl->getElementById(pDocument3, L"subm1", &pButton); if (FAILED(hr) && !pButton) ExitProcess(EXIT_FAILURE); hr = pButton->lpVtbl->click(pButton); if (FAILED(hr)) ExitProcess(EXIT_FAILURE); Не работает, никаких ошибок нет.тупо не работает. Ес-но вручную в браузере работает. ну вот который раз берусь и нет слов, кроме матов в адрес этой наркоманской технологии
Технически работать должно. Если проблема в жаваскрипте, который не со скоростью светы исполняется, то: Код (ASM): @@: cominvk iWebBrowser2,get_Busy,addr isBusy test eax,eax .if ~ZERO? mov [nErrorCode1],5 mov [nErrorCode2],eax .else .if [isBusy] <> 0 invoke Sleep,10 jmp @B .endif по идее должно помочь. Кстати вместо put_innerText такое можно делать: Код (ASM): pushdatanp du 'value'\,0 invoke SysAllocString,esp mov [pValueAttributeName],eax popdata cominvk iFilenameField,setAttribute,[pValueAttributeName],VT_BSTR,0,[pszuActualRomFilename],0,0
f13nd, написал так, вроде верно? Все равно не идет Код (C++): VARIANT_BOOL vb; WebBrowser->lpVtbl->get_Busy(WebBrowser, &vb); while (vb != 0) { WebBrowser->lpVtbl->get_Busy(WebBrowser, &vb); } может, дело в ajax ? Т.е. для аякс нужны какие-то особые события, хз. Там по кнопке идет аякс запрос с содержимым, но по идее какая разница. спасибо. там фиг поймешь в этом всем. с мсдн убрали большую часть документации как депрекейдет.
isBusy не VARIANT, это WORD. Не знаю, вряд ли. Это же интерфейс для элементов страницы в браузере, уровень выше, чем все особенности ее устройства.
f13nd, да, все сработало, когда навесил событие и на клик по кнопке. видимо, он не реагировал на onchange, ну в яваскрипт, тем более текущем, я не особо силен. Короче, работает все и норм. Спасибо!