Читаем Программирование на Visual C++. Архив рассылки полностью

Очень подробный и интересный ответ, но к сожалению не совсем корректный. Насчет классов – действительно, они доступны только внутри зарегистрировавшего их процесса (в MSDN есть хорошая статья "Window Classes in Win32" by Kyle Marsh). Однако я не совсем согласен с логическими построениями автора (или понял их неправильно). Т.к. имя класса по идее уникально, то естественно, что ИМЕННО ЭТО приложение зарегистрировало класс. А как иначе?..

Вопросы вызывают еще два момента. Во первых, при создании объектов ядра НИ В КОЕМ СЛУЧАЕ не нужно сначала проверять, существует ли такой объект (п.1). Иначе можно нарваться на т.н. race conditions, описанные в вышеупомянутой статье – ситуация, когда два экземпляра стартуют почти одновременно. Получается, что одна копия проверяет, что объект не существует, и создает его. Но прежде чем она его создаст, вторая копия тоже убеждается в том, что объекта еще нет, и тоже собирается со спокойной совестью его создать. В результате первая копия успевает создать объект, а второй копии создать объект так и не удается, но это уже не важно, т.к. вторая копия все равно запускается.

Не стоит думать, что такая ситуация маловероятна. Представьте себе пользователя, который настроил Windows запускать программы по одному щелчку на ярлыке, но по привычке делает double-click…

Весь смысл объектов ядра как раз в том, что при их создании ГАРАНТИРУЕТСЯ, что никто другой в это же время не сможет создать такой же объект. Нужно сразу пытаться СОЗДАТЬ объект – и если эта операция не удается (возвращается ERROR_ALREADY_EXISTS или ERROR_ACCESS_DENIED) – вот тогда можно с уверенностью говорить о том, что запущена еще одна копия.

Во-вторых, мне не совсем понятны пункты 2.3 и 3. Мне кажется это очень неэфективным – постоянно проверять на наличие сигнала от второй копии (как я понимаю, по этому сигналу приложение должно себя активизировать). Есть способы гораздо лучше (читайте ниже).

Но (заметьте!) мы выяснили очень важную вещь: использование объектов ядра абсолютно необходимо для определения, запущена ли копия приложения или нет.

A2 Можно например с помощью RegisterWindowMessage.

В двух словах:

1. Регистрируем сообщение.

2. Отправляем его на HWND_BROADCAST с каким нибудь кодом в wParam, (например 1) и своим hWnd в lParam (чтобы получатель знал, куда отправлять ответ)

3. Пишем обработчик нашего зарегистрированного сообщения. Он анализирует wParam, если там 1 и lParam не равен собственному hWnd, то он отсылает в ответ такое же сообщение но с кодом 2 например.(отправителя мы получили через lParam)

4. Если мы получили сообщение с кодом 2 в wParam значит уже есть запущенная копия приложения.

Pavlik Yatsuk

Если к ответу добавить механизм объектов ядра, то получается вариант правильный… на первый взгляд. Вот что говорит об этом способе Александр Шаргин:

"Я отказался от этого подхода, и вот почему […] Посылая сообщение с параметром HWND_BROADCAST, мы теряем доступ к возвращаемому в ответ значению. А значит, уже запущенная копия нашего приложения (если таковая есть) должна ответить также посылкой сообщения. Вопрос: кому его посылать? Главное окно во второй копии приложения ещё не создано, цикла сообщений нет… Выход один: создавать невидимое окно, и ловить в нём сообщение — кривовато…

Вариант второй: не использовать HWND_BROADCAST, а сделать EnumWindows и посылать сообщение каждому окну в отдельности. А значит писать свою CALLBACK-функцию, обработчик зарегистрированного сообщения… Тоже кривовато, мне не понравилось."

(Кстати, вариант второй как раз используется в статье;) А вот и сам его ответ:

Перейти на страницу:

Похожие книги

Программист-прагматик. Путь от подмастерья к мастеру
Программист-прагматик. Путь от подмастерья к мастеру

Находясь на переднем крае программирования, книга "Программист-прагматик. Путь от подмастерья к мастеру" абстрагируется от всевозрастающей специализации и технических тонкостей разработки программ на современном уровне, чтобы исследовать суть процесса – требования к работоспособной и поддерживаемой программе, приводящей пользователей в восторг. Книга охватывает различные темы – от личной ответственности и карьерного роста до архитектурных методик, придающих программам гибкость и простоту в адаптации и повторном использовании.Прочитав эту книгу, вы научитесь:Бороться с недостатками программного обеспечения;Избегать ловушек, связанных с дублированием знания;Создавать гибкие, динамичные и адаптируемые программы;Избегать программирования в расчете на совпадение;Защищать вашу программу при помощи контрактов, утверждений и исключений;Собирать реальные требования;Осуществлять безжалостное и эффективное тестирование;Приводить в восторг ваших пользователей;Формировать команды из программистов-прагматиков и с помощью автоматизации делать ваши разработки более точными.

А. Алексашин , Дэвид Томас , Эндрю Хант

Программирование / Книги по IT
Эффективное использование C++. 55 верных способов улучшить структуру и код ваших программ
Эффективное использование C++. 55 верных способов улучшить структуру и код ваших программ

Эта книга представляет собой перевод третьего издания американского бестселлера Effective C++ и является руководством по грамотному использованию языка C++. Она поможет сделать ваши программы более понятными, простыми в сопровождении и эффективными. Помимо материала, описывающего общую стратегию проектирования, книга включает в себя главы по программированию с применением шаблонов и по управлению ресурсами, а также множество советов, которые позволят усовершенствовать ваши программы и сделать работу более интересной и творческой. Книга также включает новый материал по принципам обработки исключений, паттернам проектирования и библиотечным средствам.Издание ориентировано на программистов, знакомых с основами C++ и имеющих навыки его практического применения.

Скотт Майерс , Скотт Мейерс

Программирование, программы, базы данных / Программирование / Книги по IT
Программирование. Принципы и практика использования C++ Исправленное издание
Программирование. Принципы и практика использования C++ Исправленное издание

Специальное издание самой читаемой и содержащей наиболее достоверные сведения книги по C++. Книга написана Бьярне Страуструпом — автором языка программирования C++ — и является каноническим изложением возможностей этого языка. Помимо подробного описания собственно языка, на страницах книги вы найдете доказавшие свою эффективность подходы к решению разнообразных задач проектирования и программирования. Многочисленные примеры демонстрируют как хороший стиль программирования на С-совместимом ядре C++, так и современный -ориентированный подход к созданию программных продуктов. Третье издание бестселлера было существенно переработано автором. Результатом этой переработки стала большая доступность книги для новичков. В то же время, текст обогатился сведениями и методиками программирования, которые могут оказаться полезными даже для многоопытных специалистов по C++. Не обойдены вниманием и нововведения языка: стандартная библиотека шаблонов (STL), пространства имен (namespaces), механизм идентификации типов во время выполнения (RTTI), явные приведения типов (cast-операторы) и другие. Настоящее специальное издание отличается от третьего добавлением двух новых приложений (посвященных локализации и безопасной обработке исключений средствами стандартной библиотеки), довольно многочисленными уточнениями в остальном тексте, а также исправлением множества опечаток. Книга адресована программистам, использующим в своей повседневной работе C++. Она также будет полезна преподавателям, студентам и всем, кто хочет ознакомиться с описанием языка «из первых рук».

Бьерн Страуструп , Бьёрн Страуструп , Валерий Федорович Альмухаметов , Ирина Сергеевна Козлова

Программирование, программы, базы данных / Базы данных / Программирование / Учебная и научная литература / Образование и наука / Книги по IT