Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Excel and COM, помогите разобраться 
:(
    Опции темы
SlimSlot
Дата 27.7.2009, 22:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 15
Регистрация: 27.7.2009

Репутация: нет
Всего: нет



Доброго времени суток.

Впервые на Вашем форуме, надеюсь задержусь и мне здесь помогут.

Я только недавно стал изучать COM. И вот в то время как мне показалось я могу делать практические вещи я попробовал пообщаться посредством COM с Excel.

Все вроде бы получается но есть таки несколько проблем. 
Во-первых все на практике оказалось не совсем так как писалось в книжках. Сейчас я затормозился на том, что после создания компонента и сразу его уничтожения, программа как бы не завершается.
Такое ощущение что я что-то не так делаю с COM, да даже не ощущение, а уверенность.

Вот код. Подскажите, что же все-таки не так?
Код

....
_ApplicationPtr ex;
....
....

    case WM_COMMAND:
        
        if (LOWORD(wParam)==ID_40002)
        {
            MessageBox(hWnd,TEXT("клик"),TEXT("Slim"),MB_OK);
        }

        if ((HWND)lParam==hButtomParse)
        {
            ex.CreateInstance(L"Excel.Application"); 
            ex->Visible[0]=true;
            ex->Quit(); 
            ex.Release();
        }


В WinProc сначала выбирается пространство имен Excel, инициализируется библиотека COM - CoInitialize(NULL); 
После обработки этого сообщения вызывается CoUninitialize(); 

Все работает корректно, пока не доходит до return 0; оконной процедуры.

Если запускать в обычном режиме, то после закрытия окна (WM_CLOSE) - окно таки разрушается, но программа не оканчивает свою работу.

Я попробовал продебажить по шагам. Так вот после return происходит ошибка There is no source code available for the current location.

О чем она говорит я так и не понял.

Скажите, что можно сделать? Что я не так делаю?


Это сообщение отредактировал(а) SlimSlot - 27.7.2009, 23:11
PM MAIL   Вверх
jonie
Дата 28.7.2009, 06:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 5613
Регистрация: 21.8.2005
Где: Владимир

Репутация: 5
Всего: 118



Цитата
Все работает корректно, пока не доходит до return 0; оконной процедуры.

у оуонной процедуры нужно вызывать DefWindowProc() , а не ноль возращать.


--------------------
Что-то не поняли? -> Напейтесь до зеленых человечков... эта сверхцивилизация Вам поможет...
PM MAIL Jabber   Вверх
SlimSlot
Дата 29.7.2009, 20:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 15
Регистрация: 27.7.2009

Репутация: нет
Всего: нет



Просто проект делал по шаблону...
Ну да ладно.
Какова причина то? Ноль я не возвращаю, ничего не изменилось.

Вообще существует ли какой-то нормальный суперклассический способ создания компонентов? Так как написано в книгах?
PM MAIL   Вверх
jonie
Дата 29.7.2009, 22:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 5613
Регистрация: 21.8.2005
Где: Владимир

Репутация: 5
Всего: 118



Цитата
Если запускать в обычном режиме, то после закрытия окна (WM_CLOSE) - окно таки разрушается, но программа не оканчивает свою работу.

код WM_CLOSE метки покажи.
а вообще выложи минимальный проект - поглядим.

Цитата
После обработки этого сообщения вызывается CoUninitialize(); 

можно не вызывать (будут проблемы с умными указателями). Система гарантирует что деинициализация COM для процесса будет выполнена, после того как процесс умрет.

Цитата
Я попробовал продебажить по шагам. Так вот после return происходит ошибка There is no source code available for the current location.

все правильно - функцию вызывает user32.dll библиотека (если вы работаете в win32), а pdb файла или исходника майкрософт не дает (хотя на самом деле я видел SP3 для winXP как раз для программеров, но оно нам обычно не надо, если совсем не "вилы").



--------------------
Что-то не поняли? -> Напейтесь до зеленых человечков... эта сверхцивилизация Вам поможет...
PM MAIL Jabber   Вверх
SlimSlot
Дата 29.7.2009, 22:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 15
Регистрация: 27.7.2009

Репутация: нет
Всего: нет



В общем ситуация такая.

CoInitialize и CoUninitialize я вызываю в Main.

Попробовал опять продебажить.
Когда я создаю компонент IDE меня в какой-то сторонни хедер.
Там, после вызова OleRun создаются дополнительные потоки. В итоге получается что после возврата из main у меня остатется подвисшими еще четыре потока. 
Соответственно я попробовал ExitProcess - все заработало. Но причину я так и не познал.

Во-первых если компонент сам создает какие-то потоки, почему он их не уничтожает?
Я, как программист, знать не знаю что там делает сервер, почему я должен беспокоиться о потоках? 
Ок, допустим я должен. Каким образом я должен корректно уничтожить потоки, если они создавались сервером? Еслтественно с COM-компонентом я могу обзаться только с помощью интерфейсов. Покажите, что за ф-я-член уничтожает эти самые потоки.


Мне очень интересно добить эту ситуацию, и не хочется тупо прнудительно завершать процесс в main.
У кого какие мысли.




Цитата(jonie @  29.7.2009,  22:21 Найти цитируемый пост)
а вообще выложи минимальный проект - поглядим.


Да тут проекта то. Ну представленный код в оконной процедуре. В main-е - цикл обработки сообщений и CoInitialize с CoUninitialize.

Вот пожалуй и все.



Цитата(jonie @  29.7.2009,  22:21 Найти цитируемый пост)
код WM_CLOSE метки покажи.


вот
Код

    case WM_CLOSE:
        DestroyWindow(hWnd);
        break;



PM MAIL   Вверх
jonie
Дата 30.7.2009, 08:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 5613
Регистрация: 21.8.2005
Где: Владимир

Репутация: 5
Всего: 118



Цитата
  case WM_CLOSE:
        DestroyWindow(hWnd);
        break;


так ты и не завершаешь работу, ты уничтожаешь окно.
PostQuitMessage(0) делай вместо DestroyWindow


--------------------
Что-то не поняли? -> Напейтесь до зеленых человечков... эта сверхцивилизация Вам поможет...
PM MAIL Jabber   Вверх
SlimSlot
Дата 30.7.2009, 22:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 15
Регистрация: 27.7.2009

Репутация: нет
Всего: нет



Да в этом косяк, но у меня еще есть сообщение WM_DESTROY, я немного попутал где вызвать PostQuitMessage, но да ладно. Мелочи. В общем и целом у меня таки есть PostQuitMessage.

Как я сказал, приложение не завершает свою работу потому не все потоки уничтожены. Проблема в этом и только в этом.  Но почему COM-компонент так себя ведет? 

И почему таки я не могу создать наконец интерфейс обычным классическим способом. Может все косяки из-за этих чертовых умных указателей? И где вообще документация к COM-компоненту. 

Странно все это
PM MAIL   Вверх
xvr
Дата 31.7.2009, 12:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 8
Всего: 223



Цитата(SlimSlot @ 30.7.2009,  22:11)
Как я сказал, приложение не завершает свою работу потому не все потоки уничтожены. 

Приложение завершит свою работу при завершении main функции (main или WinMain), сколько бы там потоков не оставалось (при выходе из main стоит exit)

PM MAIL   Вверх
SlimSlot
Дата 31.7.2009, 20:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 15
Регистрация: 27.7.2009

Репутация: нет
Всего: нет



Цитата(xvr @  31.7.2009,  12:00 Найти цитируемый пост)
Приложение завершит свою работу при завершении main функции (main или WinMain), сколько бы там потоков не оставалось (при выходе из main стоит exit)


Приложение (читай процесс) завершит свою работу, если 
1. Будут уничтожены все потоки
2. Закрыты все хендлы процесса

Только при соблюдении этих двух пунктов может быть корректный выход.
В некоторых случаях этим может заниматься ExitProcess. Она начисто уничтожает все потоки процесса и закрывает хендлы.

Если использовать сишный рантайм, по после возврата из WinMain будет вызвана та самая ExitProcess, поэтому процесс завершится в любом случае. 

Но я не использую сишный рантайм, поэтому по умолчанию у меня не вызывается ExitProcess, вместо этого WinMain завершает работу return-ом. Процесс остается жить пока он имеет хотя бы один поток. За уничтожением потока следует соответственно уничтожение процесса. Но если после уничтожения основного потока будет жить хоть один параллельный - процесс будет жить. Поэтому мой процесс и живет - после завершения основного потока, остается еще 4.


PM MAIL   Вверх
xvr
Дата 2.8.2009, 08:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 8
Всего: 223



Эти 4 потока создает COM инфраструктура. Они должны помереть при вызове CoUninitialize. Если этого не происходит, то что то не вызывается (например тот самый CoUninitialize)

PM MAIL   Вверх
SlimSlot
Дата 2.8.2009, 21:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 15
Регистрация: 27.7.2009

Репутация: нет
Всего: нет



CoUninitialize вызывается в WinMain перед return
CoInitialize тоже в Main
PM MAIL   Вверх
xvr
Дата 3.8.2009, 08:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 8
Всего: 223



Так, давайте рубить руку по частям - сотрите кусок
Код

            ex.CreateInstance(L"Excel.Application"); 
            ex->Visible[0]=true;
            ex->Quit(); 
            ex.Release();
и проверьте, что программа стала выходить

PM MAIL   Вверх
SlimSlot
Дата 3.8.2009, 20:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 15
Регистрация: 27.7.2009

Репутация: нет
Всего: нет



Я это в первую очередь сделал.
Я же говорю, если не трогать создание компонента - то все работает как часы.
Как только создается компонент, сразу выскакивает еще четыре потока.

Следовательно CoUninitialize и CoInitialize  работает нормально. 
Что-то внутри компонента
PM MAIL   Вверх
xvr
Дата 3.8.2009, 20:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 8
Всего: 223



Создание 4х потоков - это нормально. Кстати, Excel в невидимом режиме - это что то  smile Несмотря на невидимость он продолжает спрашивать у пользователя всякую всячину (например предлагает сохранить файл при выходе). При этом собственно диалога на экране нет, но он ждет нажатия кнопки на нем (ждет до бесконечности). Это тоже может быть причиной  smile 
Рекомендую позвать ExitProcess в конце  smile 
PM MAIL   Вверх
SlimSlot
Дата 4.8.2009, 20:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 15
Регистрация: 27.7.2009

Репутация: нет
Всего: нет



Ну только это и остается.

А кто-нибудь может потестировать создание компонента Excel без сишного рантайма и без ExitProcess?

Цитата(xvr @  3.8.2009,  20:41 Найти цитируемый пост)
Кстати, Excel в невидимом режиме - это что то  smile Несмотря на невидимость он продолжает спрашивать у пользователя всякую всячину (например предлагает сохранить файл при выходе).

Это да, как-то такое встречалось. Но представь обработку 150 файлов в видимом режиме, я однажды делал

PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: COM/DCOM/ActiveX/ATL/CORBA | Следующая тема »


 




[ Время генерации скрипта: 0.0859 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.