ANTIHacker А что пишет? Программа какого типа? Использует ли framework?
Часто в настройках проекта ставят
Use of MFC: Use Standart Windows Libraries
вместо
Use MFC in a Static Library
Из-за этого могут возникать проблемы. Ну и если framework используют твоя программа, то пусть тот человек тоже поставит его.
Еще ты мог использовать какие длл, которых нет на другом компьютере, или под другой процессор написать прогу .
Не могу разобраться почему вылезает hr = 0x80020008 Неверный тип переменной.
И еще зачем передавать dpNothing ? Я это подсмотрел в MSDN, я еще так с Word`ом и Excel`ем делал. Но если в Invoke передать NULL вместо &dpNothing вылетает Exception:
Member
Статус: Не в сети Регистрация: 02.02.2008 Откуда: Ростов-на-Дону Фото: 3
M9IC dpNothing - это параметры метода, структура, в которой находятся указатели на последовательности (VARIANT-ов) именованных и неименнованых аргументов и их количество. Если ничего передавать не надо, то делаем так:
DISPPARAMS dpNothing = {0, 0, 0, 0}; // не VARIANT, а DISPPARAMS
Не стоит ли воспользоваться MFC и его классом COleDispatchDriver, в ручную писать обработку IDispatch - это пытка.
Кстати, неужили интерфейс не является дуальным??? Позор 1С.
Добавлено спустя 7 минут, 50 секунд Да уж, на дату я чё-то и не глянул...
Member
Статус: Не в сети Регистрация: 31.08.2005 Откуда: Мир
Как в MFC работать с BMP картинкой? Надо её прочитать, для этого читаем заголовок.. узнаем о цвете и т.п.. и читаем побайтово ридфайлом что нужно в массив, ( например если нада кусок изображения прочесть,или для скрола) а потом выводим на экран.. но как? как вывести на экран картинку и что будет экраном? Поправьте если гдето не прав) и подскажите плз.
Есть консольная программа, она пишет что-то на консоль. Пусть для простоты она выглядит так:
Код:
#include <iostream> #include <windows.h> using namespace std; int main(void){ for(short i=1;i<=100;i++) {cout<<"*"; Sleep(10);} return 0;}
Выводит на консоль звездочку через каждые 10мс.
Есть MFC-приложение с окошечками, кнопочками и т.п, оно запускает консольное. Я хочу, чтобы была возможность видеть в нем все, что выводит консольное приложение на консоль:
Так вот в итоге f==false, т.е. не прочитано ни одного символа. Почему? На консоли все выводится.
---------------------------
Блин, сколько примеров читал в инете по этой теме + в msdn'е и ни разу не заметил, что надо прописать "si.dwFlags = STARTF_USESTDHANDLES;". А заглянул случайно в исходинки x264GUI-Lite и сразу обратил внимание. Бывает же такое...
Advanced member
Статус: Не в сети Регистрация: 09.03.2004 Откуда: Кишинёв
theone наверное раскопать там было сложно . У меня на пс есть проект попроще - avc2avi_gui .
pretorian Самое простое наверное использовать GDI+ - открытие картинки(bmp, jpg, gif, png и tiff) и вывод на контекст в несколько строчек(rdsn.ru -> статьи -> multimedia -> windows gdi/gdi+).
1) Я хочу запустить в отдельном потоке функцию. Пробовал AfxBeginThread, CreateThread, _beginthreadex - ни одна не хочет работать - не принимает точку входа (адрес запускаемой функции) - выдает ошибку. Как я понял это потому, что эта функция - член класса, и чтобы работало надо сделать ее статической. Я незнаю, чем static-функция отличается от обычной, но попробовал сделать ее статической. Тогда вылезло куча ошибок - оказалось что все переменные, исп-ые в этой функции тоже должны быть статическими + все ф-ции, вызываемые из нее тоже и т.д. Короче мне половину данных и функций класса придется сделать статическими, или даже больше. Мне все это не нравиться. Может мне тогда вообще ВСЁ в классе сделать "static"? На что это повлияет?
Но я нехочу этого делать. Можно ли как-нибудь обойти это ограничение? Я если честно не понимаю сути этой проблемы: почему обычную функцию можно запустить в отдельном потоке, а функцию-член класса - нет? Это, извините, дибилизм какой-то
2) Есть оконное MFC-приложение (исп-ю Visual Stuido 2005). Там у меня есть функция, которая делает вычисления, иногда эти вычисления могут занимать много времени. Когда она работает, окно программы как бы зависает: оно не реагирует на изменения. Точнее реагиреут, но только после того, как функция закончит вычисления. Причем прогресс-бар, например, работает нормально в реальном времени. Как мне сделать, чтобы окно не "зависало"? Я пробовал создавать для этой функции отдельный поток, но не получилось (вопрос №1).
theone 1) Статическая функция вызывается без создания экземпляра данного класса. И этот метод конечно же не привязан ни к одному из имеющихся экземпляров. Ты пытаешся передать указатель на функцию, которая является не статическим членом класса, но скажи каким ... он узнает у какого объекта следует вызвать данный метод? Тебе следует сделать, например, один статический метод класса, в который ты будешь передавать ссылку, на уже созданный объект, а там уже у объекта вызовешь нужный тебе метод.
но скажи каким ... он узнает у какого объекта следует вызвать данный метод?
Как у какого? У того, с которым я работаю и из которого я вызываю этот метод. Ну т.е. у меня есть только один экземпляр класса и я работаю только с ним.
sashar2 писал(а):
Тебе следует сделать, например, один статический метод класса, в который ты будешь передавать ссылку, на уже созданный объект, а там уже у объекта вызовешь нужный тебе метод
Да. Как только я запустил функцию в отдельном потоке, "зависания" окна сразу исчезли.
-------------------
Такой вопрос: если компилирую в debug режиме, при вызове UpdateData из функции, работающей в отдельном потоке, компилятор выдает ошибку, в файле "wincore.cpp", line 892. Там в этом месте функция "void CWnd::AssertValid() const", 892-ая строка и ее окружение выглядят так:
Код:
CObject* p=NULL; if(pMap) { ASSERT( (p = pMap->LookupPermanent(m_hWnd)) != NULL || (p = pMap->LookupTemporary(m_hWnd)) != NULL);//line 892 } ASSERT((CWnd*)p == this); // must be us
И после этого комментарий:
"Note: if either of the above asserts fire and you are writing a multithreaded application, it is likely that you have passed a C++ object from one thread to another and have used that object in a way that was not intended. (only simple inline wrapper functions should be used) In general, CWnd objects should be passed by HWND from one thread to another. The receiving thread can wrap the HWND with a CWnd object by using CWnd::FromHandle. It is dangerous to pass C++ objects from one thread to another, unless the objects are designed to be used in such a manner." Если убираю UpdateData, ошибка пропадает.
Если компилировать в release режиме, то ошибки нет и вообще все отлично работает.
Вопрос: насколько это серьезно и что это такое? Ну т.е. комментарий то я примерно перевел, но сути особо не понял, и что делать незнаю.
theone Дело в том, что ты видимо хочешь напрямую из другого потока изменить что-либо на форме, а это не потокобезопасно, о чем тебе честно и сообщила студия. Это не является критической ошибкой, но может вызвать проблемы.
Для вызова функции UpdateData создай отдельный метод класса, который и будешь вызывать в своем потоке. Это должно устранить проблему.
Я неточно выразился в прошлый раз: ошибка появляется не при компиляции (компилириется и debug и release без ошибок и без предупреждений), а в процессе работы программы, если она скомпилирована в debug.
sashar2 писал(а):
theone Дело в том, что ты видимо хочешь напрямую из другого потока изменить что-либо на форме, а это не потокобезопасно, о чем тебе честно и сообщила студия. Это не является критической ошибкой, но может вызвать проблемы.
Я вызываю UpdateData(TRUE), т.е. ничего не меняю на форме, а наоборот, считываю изменения в переменные, связанные с элементами формы. И именно в этом месте программа выдает ошибку при работе. Кстати, в других местах я действительно меняю состояние формы из потока (только там я работаю с формой с помощью GetDlgItem и еще прогресс бар меняю через объект класса CProgressCtrl (кстати, почему-то прогресс бар меняется без вызова UpdateData)), и это не вызывает никаких ошибок. Наверно придется либо забить на эту ошибку, либо попробовать вместо UpdateData работать напрямую сформой с помощтю GetDlgItem.
sashar2 писал(а):
Для вызова функции UpdateData создай отдельный метод класса, который и будешь вызывать в своем потоке. Это должно устранить проблему.
Попробовал - никаких изменений. Или может я не так делал: в классе, в "*.h" файле добавил:
theone Хм, тогда по коду, которому ты вывел могу сказать, что у тебя в карте mfc потока присутствует два разных CWnd, которые обслуживают один и тот же m_hWnd. Нужно выяснить в чем причина этого. В предыдущем посте я лишь предположил одну из причин, сейчас я изложил саму суть т.к больше ничем помочь не могу, не видя твой код.
Advanced member
Статус: Не в сети Регистрация: 09.03.2004 Откуда: Кишинёв
theone попробуй слать сообщение(WM_APP+X, и добавить в карту обработчик) окну(m_hWnd), а в обработчике уже вызывать метод UpdateData. В своё время я от DDX отказался вообще(так и не поняв прелестей), а потом и от mfc .
sashar2 Код примерно такой - мастером сгенерировано MFC Dialog based приложение, без всяких излишеств. После нескольких непонятных мне строк в "BOOL CAppMain::InitInstance()", сгенерированных мастером, открывается диалговое окно:
CcccGui *dlg1 объявлен глобально, подключен через "extern". Функция fChainFinderStarter статическая, она запускает через указатель нужную функцию (как ты советовал):
fChainFinder() вызывает в процессе работы другие функции, те вызывают другие и в одной из них в некотором месте вызывается "UpdateData(TRUE)". Вот в принципе и все, в кратце.
mein Не получилось. Т.е. ошибка пропала, но окно не обновляется (изменения с формы не считываются в переменные). Делал так: вместо "UpdateData(TRUE)" писал "SendMessage((UINT)m_hWnd,WM_APP+1)" (если не писать "(UINT)", то компилятор выдает ошибку "error C2664: 'CWnd::SendMessageW' : cannot convert parameter 1 from 'HWND' to 'UINT'"), в карте прописал "ON_MESSAGE(WM_APP+1, &CcccGui::myUpdateData)", а функцию так:
Попробовал обойтись без UpdateData - не получилось: мне надо прочитать содержимое Edit Control'а с формы, пишу "GetDlgItemText(IDC_OUTPUTFILE1,str1)" (str1 - строка CString), но все равно изменения, внесенные в этот Edit Control во время работы потока, не читаются. Т.е. я пишу имя файла, запускаю поток, пока он работает - меняю имя файла, когда в потоке доходит дело до вывода, пишу GetDlgItemText(...), а он выводит в тот файл, который был указан ДО запуска потока (имя файла беру из str1 - str1.GetBuffer()).
А состояние чекбокса, например, проверяется корректно "IsDlgButtonChecked(IDC_SAVECCCONLY1)". Короче "тут" работает, "там" не работает ... Темное дело это потоки ...
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения