Cc++ — Проблема с MFC


Содержание

C/c++ — Проблема с MFC

1) На Раздел распространяются все Правила Форума.
2) Перед тем, как создать новый топик, убедитесь, что Вы читали Правила создания тем в Разделе.
3) Вопросы, не связанные с программированием (настройки MS Visual Studio, книги, библиотеки и т.д.),
обсуждаются в разделе C/C++: Прочее
4) Вопросы разработки .NET (Windows Form, C++/CLI и т.п.) приложений на Visual C++/C# обсуждаются в разделе .NET.
5) Нарушение Правил может повлечь наказание со стороны модераторов.

Неa, VK_LEFT и т.д. тоже не ловит. Дело в том что при нажатии на эти клавиши nChar вообще ничего не возвращает (в дебаге проверял, в отличае от wParam в WM_KEYDOWN – здесь все четко). Что за вигня, в упор понять не могу. Похоже MFC при генерации кода резервирует эти клавиши где-то у себя, так же как и при нажатии на Enter у формы срабатывает сообщение WM_DESTROY. Чудеса какие-то =)

На счет того модальное окно или нет, ответить не могу, так как не в курсе что значит модальное. Могу одно сказать – сообщения обрабатываются от того окна, которое визуально доступно при разработке.

Что бы программа не закрывалась по ENTER надо создать пустую функцию OnOK()
Для ESC тоже самое, только OnCancel()

А по поводу VK_UP, VK_DOWN. можно поробовать копать в сторону акселераторов

«»Окошко»» запускаешь по DoModal(), иль ShowWindow();

Добавлено в 16.05.04, 10:10 :
вот кусок моей проги, неважно чё он делает главное месаги ловит.

Этот код пока не пробывал, но высылаю свой:

Спасибо громадное. Все заработало, походу дела, OnKeyDown их просто мимо пропускает в отличае от PreTranslateMessage(). Теперь бы ещё избавиться от OnOK() при нажатии на Enter и будет вообще все ОК!

ЗЫ: Судя повсему окошко формируется простое, а не модальное. Правда строки CreateWindow() и ShowWindow() я здесь в упор найти не могу (черт знает где он их прописывает =)

Введение в Visual C++. MFC

Визуальное программирование на C++ возможно реализовать без использования разного рода библиотек классов, шаблонов и прочих вспомогательных инструментов. Но тот, кто уже достаточно глубоко проникся изучением этого языка, вероятно в состоянии представить, насколько непростая это задача. Даже, для создания примитивного оконного приложения понадобиться огромное количество времени и усилий. Именно тут-то нам и приходят на помощь визуальные среды разработки, например, такие как Visual C++ или C++ Builder. Они содержат специальные библиотеки классов, которые значительно облегчают процесс написания приложений.

Вероятно, что лучшей интегрированной средой разработки приложений под Windows, является Microsoft Visual C++. Именно этой программой мы и будем пользоваться в дальнейшим. Установочный образ Вы можете скачать на сайте разработчика , впрочем, думаю у вас не возникнет проблем с этой фундаментальной задачей.

Компания Microsoft разработала мощный инструмент для разработки сложных приложений — MFC. MFC (Microsoft Foundation Classes) — библиотека классов языка C++, предназначенная для создания визуальных приложений при помощи встроенных средств. MFC поддерживает современные технологии программирования, благодаря чему программы написанные с ее помощью будут обладать необходимой функциональностью и надежностью. Благодаря ей программист получает шаблонный «скелет» программы, после чего ему остается вписать код в необходимые места.

Итак, теперь стоит поговорить о более грустных вещах. Библиотека MFC достаточно сложна, так как во всю использует возможности языка C++. А это значит, что в «арсенале» начинающего изучать визуальное программирование используя этот «дар» от Microsoft должны присутствовать навыки написания кода на C++. В частности было бы неплохо изучить: рекурсию и перегрузку функций, основы классов, перегрузку операций и наследование. Но для самых отчаянных (тех кто не боится не разобраться что к чему), думаю возможно дуализировать задачи, то есть одновременно изучать как библиотеку MFC, так и базовые понятия C++.

Что касается самой Visual C++, то тут стоит добавить, что эта среда разработки обычно входит в линейку программ под общим названием Visual Studio, но вполне реально приобрести ее в отдельном экземпляре.

Форум программистов «Весельчак У»

Учимся программировать => Начинающим => Тема начата: JIeshiy от 01-07-2009 15:43

Название: [C++, MFC] проблема с написанием телефонной книги!
Отправлено: JIeshiy от 01-07-2009 15:43

Модальный диалог находится всегда поверх родительского окна , находится всегда в фокусе (вернее, не даёт поставить фокус на родительское) и получает все сообщения от мыши, направленные родителю.

В общем — пока пользователь не закроет модальное окно, он не может работать с родительским окном

1) что ты подразумеваешь тут под классом ?
2) конечная цель какая ?

Тут проблемма с пониманием, что такое класс и для чего он вообще нужен.
А будет это класс для телефонной книги или для учета жильцов не суть важно.

1. Что такое класс?

JIeshiy, покажи, где тут инкапсуляция, наследование и полиморфизм :) , вот в этом примере

а вот тип — это верно. Класс, это тип данных

Класс — это тип, описывающий объект.
Объект — нечто, что обладает определёнными свойствами и поведением.

инкапсуляция, наследование,полиморфизм, ты еще забыл абстракцию данных

Далее. Что первично? данные или методы=функциям?

Lynx_Evil, никуда мы не уходим, в сторону

проблема с составлением класса

1. разобрались, что такое класс
2. разобраться какие данные нужны и какие методы должны быть у объекта.

Вот этого пока достаточно

давай по другому
ВСЕ УСЛОВНО (языка не знаю)

char FIO;
int phone;
char address;
void inputfio()<>
void iputphone()<>

Чем не данные и чем не методы

JIeshiy, еще раз, то, что тебе уже говорили:

класс — это описание типа данных — никак не сами данные.

объект — экземпляр данного типа

Book(); //деструктор
void Serialize ( CArchive& ar ); //для сохранения в файле
public:
DECLARE_SERIAL(Book);
CString name; //ФИО
int phone; //сотовый
CString home; // адрес
int dom_phone; //домашний

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

А ты уже готов человеку дать готовый шаблон. Оно ему надо?


Lynx_Evil, ты немного не в тему завёлся, провоцируя остальных на дискуссию в этом направлении. Речь не идёт о возможных способах реализации задания. Это раздел для начинающих. Следовательно важно, чтобы человек понимал, что ему объясняют, а не просто получил готовый проект и успокоился. Это то, о чём тебе Слава намекает. Это философия данного раздела. Помочь реально понять и научиться программированию. Халявы здесь не бывает. Если человек хочет и что-то делает, то ему всегда в этом помогут. В противном случае на форуме есть раздел, в котором можно оставить заявку на выполнение работы. Между работой и помощью есть одна малюсенькая разница — оплата за первую. Тогда конечно никто не докапывается до спрашивающего, а понял ли ты? В данном случае речь пока идёт о помощи. В этом случае модератор раздела следит за качеством материала.

Я думаю на этом все междусобойные дискуссии стоит прекратить (флуд подчистить, лучше всего если каждый уберёт за собой) и дождаться (или нет) таки ответа автора темы.
Если он действительно САМ «завтра утром» набросает программку, то это будет служить отправной точкой оценки его уровня и следовательно можно уже подумать о конкретных способах как ему помочь. Действительно ли это продвинутый программер, которому просто не хватает опыта работы с MFC, ООП и тд, или же надо таки начинать с нуля.

int name;
int surname;
float age;

public:
void setcname(int mn, int pn, float c)
<
name=mn;
surname=pn;
age=c;
>
void show()
<
printf(«The Name is- %d\n», name);
printf(«The Surname is- %d\n», surname);
printf(«The Age is- %2f\n», age);
>
>;

Ура.
повторю вопросы

1. Ты устанавливаешь значения для данных-членов класса. Почему для этого не используется конструктор?
2. Почему имя-фамилия имеют целочисленный тип? (для строк в C++ есть тип std::string, включаемый заголовком если что)

3. немного опустим

зы Вад! а почему std::string? я действительно не знаю :(

О! Браво появились вопросы :)

попробу нам объяснить что такое конструктор.
почему мы о нем заговорили?

и придает значения данным-членам .

Каким образом ты передашь в конструктор значения?

зы. напоминаю, я не знаю с++, объясни мне «чайнику»

Изменения в Visual C++

Когда вы захотите обновить версию Visual C++ компилятора (например, перейти с Visual Studio с 2013 на 2015), будет не лишним узнать, почему вы можете столкнуться с тем, что код, который прежде успешно компилировался и выполнялся, теперь будет вызывать ошибки компиляции и/или ошибки времени выполнения.
Эти проблемы могут быть вызваны многочисленными изменениями компилятора для соответствия стандарту С++, изменениями в сигнатурах функций или изменениями расположения объектов в памяти.

Для того, чтобы избежать ошибок времени выполнения (их, как известно, наиболее трудно найти), мы рекомендуем никогда не делать статическое связывание с двоичными файлами, полученными другой версией компилятора. Также при обновлении своей программы (EXE или DLL), убедитесь, что используемые библиотеки тоже собраны новой версией компилятора.
Если вы используете типы из CRT (C Runtime) или STL (Standard Template Library), не передавайте их между двоичными файлами (включая DLL), которые собраны разными версиями компилятора. Более подробно этот вопрос рассмотрен в Potential Errors Passing CRT Objects Across DLL Boundaries.
И в дальнейшем мы рекомендуем не писать код, который зависит от конкретного расположения объектов в памяти (если это не COM интерфейс или POD объект). Если у вас сейчас есть такой код, после обновления компилятора вам следует убедиться, что все работает как надо. Более подробно можно почитать здесь: Portability At ABI Boundaries (Modern C++).

Ниже в статье описываются изменения в компиляторе Visual C++ (который идет с Visual Studio 2015 Preview). В статье слова «новое поведение» и «сейчас» относятся именно к этой версии, а «старое поведение» и «раньше» — к Visual Studio 2013 (и более ранним версиям).

Краткое содержание:
— Изменения в компиляторе
— Изменения в C Runtime Library (CRT)
— Изменения в STL
— Изменения в MFC и ATL

Изменения в компиляторе

    /Zc:forScope — Флаг компилятора /Zc:forScope- объявлен устаревшим (deprecated) и в будущем будет удален. Сейчас компилятор при использовании этого флага будет выкидывать предупреждение D9035.
    Данный флаг используется для использования нестандартного расширения С++ — использование переменных, объявленных в описании цикла for за пределами этого цикла. Этот флаг необходим только если установлен другой флаг — /Za (соответствовать стандарту), потому что без /Za , использование переменных из описания цикла по умолчанию разрешено. Если вам не нужно заботиться о кроссплатформенности (например, не предполагается собирать код другими компиляторами), вы можете выключить флаг /Za (установить свойству проекта «Disable Language Extensions» значение «No»). Если же вы заботитесь о кроссплатформенности и соответствия стандарту, значит такие участки кода нужно переписать, переместив объявление переменной выше цикла:

/Zg
Флаг компилятора /Zg (создание прототипов функций) больше недоступен для использования (раньше у него был атрибут deprecated)

Теперь нельзя запустить юнит-тесты, использующие C++/CLI, из командной строки используя mstest.exe, взамен нужно использовать vtest.console.exe. Более подробно можно узнать об этом здесь: VSTest.Console.exe command-line options.

Ключевое слово mutable
Теперь использование mutable , в соответствии со стандартом, допускается только применимо к именам членов класса, и не может быть применено к ссылкам, или именам, объявленным как const или static . Пример:

Раньше это компилировалось, теперь компилятор выдаст ошибку С2071. Для исправления, нужно просто убрать mutable .

char_16_t и char_32_t
Теперь нельзя использовать char_16_t и char_32_t в качестве псевдонимов пользовательских типов, потому что сейчас эти типы определяются как встроенные. Раньше было довольно распространенной практикой для авторов библиотек определять char_16_t и char_32_t в качестве псевдонимов для uint_16_t и uint_32_t, соответственно.

Для исправления нужно убрать объявление псевдонимов и переименовать любые другие идентификаторы конфликтующие со вновь введенными.

Нетиповые (non-type) параметры шаблонов
Код, включающий в себя нетиповые параметры шаблонов сейчас правильно проверяется на совместимость типов. Например, следующий код раньше компилировался без ошибок:

Сейчас компилятор выдаст ошибку, так как тип параметра шаблона не соответствует типу переданного аргумента (тип параметра — указатель на константный метод, но f не является константной).
error C2893: Failed to specialize function template ‘void S2::f(void)’
note: With the following template arguments:
note: ‘C=S1’
note: ‘Function=S1::f’

Для избавления от этой ошибки убедитесь, что тип аргумента шаблона полностью соотвествует типу параметра.

__declspec(align)
Компилятор больше не принимает __declspec(align) для функций. По правде говоря, он никогда и не принимал, но сейчас он будет выдавать ошибку С3323. Для избавления от нее просто уберите это выражение из объявления функции. Так как это и раньше не имело никакого эффекта, это не поменяет ничего в вашей программе.

Обработка исключений
В обработке исключений произошло несколько изменений. Первое — объекты-исключения должны быть копируемыми и перемещаемыми. раньше подобный код компилировался, теперь будет ошибка:

Проблема здесь в том, что конструктор копирования объявлен приватным, таким образом, объект не может быть скопирован, что обычно требуется при обработке исключения. То же самое применимо в случае, когда конструктор объявлен explicit .

Для избавления от этой проблемы убедитесь, что конструктор для объекта исключения объявлен в публичной зоне и explicit .
При ловле исключения также требуется, чтобы объект был копируемым. Следующий код скомпилируется в ранних версиях Visual Studio, но сейчас будет ошибка:

Эту ошибку можно исправить, приняв исключение по ссылке:

Строки и макросы
Сейчас компилятор поддерживает определенные пользователем литералы (user defined literals — UDL). Как следствие этого, строки (точнее строковые литералы), за которыми без пробела поставлен макрос, интерпретируются как UDL, что может явиться причиной ошибки или неожиданного результата. Например, раньше это компилировалось без проблем:

Компилятор интрепретировал возвращаемое функцией func значение как строку «hello», и макрос, который раскрывался в «there», а затем соединял два этих литерала в один. Сейчас компилятор интерпретирует это как UDL, но так как не может найти определение _х среди известных ему UDL, он выдает ошибку:
error C3688: invalid literal suffix ‘_x’; literal operator or literal operator template ‘operator «»_x’ not found
note: Did you forget a space between the string literal and the prefix of the following string literal?
Для решения этой проблемы нужно поставить пробел между строкой и макросом.


Строки, расположенные рядом
Так же, как и в предыдущем случае, из-за изменений в разборе строк, строящие рядом строковые литералы, которые не разделяет пробел, раньше интерпретировались как одна строка, а сейчас для корректной компиляции нужно добавить пробел:

Просто добавьте пробел между строками:

Размещающий new и delete
Для соответствия стандарту С++14 было изменено поведение оператора delete . Детали можно прочитать в C++ Sized Deallocation. Была добавлена форма глобального оператора delete , которая принимает размер объекта. Важность этого изменения в том, что если в вашем коде есть оператор delete с такой же сигнатурой (соответствующая размещающему оператору new ), вы получите ошибку компиляции (С2956, которая указывает на строку с использованием оператора new , так как именно в этом месте компилятор пытается определить подходящий оператор delete ).
Функция void operator delete(void*, size_t) была размещающим оператором delete , соответствующим функции размещающего оператора new — void* operator new(size_t, size_t) из С++11. В новом стандарте С++14 этот delete стал обычной функцией деаллокации (то есть глобальным оператором delete ). Стандарт требует следующего — если размещающий new ищет соответствующий delete и находит стандартную функцию, программа не скомпилируется.
Например, предположим, ваш код определяет размещающий new и delete :

Проблема здесь в следующем: совпадение описания оператора размещающего delete и описания нового глобального оператора. Для того, чтобы избежать такого совпадения, можно использовать тип, отличный от size_t, при описании размера в размещающих операторах new и delete . Здесь нужно принять во внимание, что size_t зависит от компилятора, в Visual C++ это псевдоним для unsigned int. Хорошим решением здесь будет использование перечисления:

Затем, нужно изменить объявления размещающих операторов new и delete так, чтобы вторым параметром вместо size_t они принимали my_type. Также нужно будет подправить передачу аргумента в вызов new (например, с использованием static_cast совершить преобразование из целочисленного значения в перечисление) и изменить определение размещающих операторов, совершив преобразования из перечисления в целочисленный тип. Кроме перечисления можно использовать, например, класс, у которого будет поле типа size_t.
В качестве альтернативного решения можно убрать размещающий new . Если ваш код использует размещающий new для реализации пула и передаваемый размер — это размер объекта для размещения или удаления, в этом случае новый оператор delete может вполне подойти для удаления этого пула.
Если вы не хотите изменять поведение данных операторов в своем коде прямо сейчас, вы можете пока использовать флаг /Zc:sizedDealloc-, который вернет старое поведение. То есть не будет создано двух-аргументной функции удаления, и, таким образом, не будет никакого конфликта с определенной вами функцией удаления.

Поля объединений (union data members)
Теперь ссылки не могут быть полем объединения (union). Раньше этот код компилировался, теперь — нет:

Теперь возникают следующие ошибки:
test.cpp(67): error C2625: ‘U2::i’: illegal union member; type ‘int &’ is reference type

test.cpp(70): error C2625: ‘U3::i’: illegal union member; type ‘int &’ is reference type

Для разрешения этой проблемы нужно изменить ссылку на указатель или просто обычное значение. Изменение типа на указатель потребует изменений в коде, который обращается к этому полю. Изменение типа на значение позволит менять значение в объединении, что повлияет на другие поля объединения. Также в этом случае может измениться размер объединения.

Безымянные объединения (anonymous unions)
Безымянные объединения стали больше соответствовать стандарту. Раньше для безымянных объединений генерировался явный конструктор и деструктор. Сейчас они объявляются удаленными.

В Visual Studio 2015 Preview генерируются следующие ошибки:
error C2280: ‘ :: (void)’: attempting to reference a deleted function

note: compiler has generated ‘ :: ‘ here

Для решения этой проблемы, нужно определить свой конструктор и/или деструктор

Объединения с анонимными структурами
Для того, чтобы обеспечить соответствие стандарту, было изменено поведение времени выполнения для членов анонимных структур в объединениях. Конструктор анонимных структур — членов объединений — больше не вызывается неявно при создании объединения. Также деструктор таких полей не вызывается неявно при выходе объединения из блока видимости. Пример:

Раньше вызывался и конструктор и деструктор. Сейчас они не вызываются. Компилятор выдает предупреждения:
warning C4587: ‘U::s’: behavior change: constructor is no longer implicitly called

warning C4588: ‘U::s’: behavior change: destructor is no longer implicitly called

Для восстановления старого поведения нужно дать имя анонимной структуре. Поведение времени выполнения неанонимных структур остается независимой от версии компилятора.

В качестве альтернативного решения можно попытаться перенести код конструктора и деструктора структуры в новые методы и вызывать их из конструктора и деструктора объединения:

Разрешение шаблонов (template resolution)
В разрешение имен для шаблонов также были внесены изменения. В С++, при рассмотрении кандидатов при разрешении имен, вполне возможен случай, когда одно или более имен могут быть неверными конкретизациями (invalid instantiation) шаблона. Эти неверные реализации обычно не вызывают ошибок компиляции (т.к. используется принцип, известный как SFINAE).

Сейчас, если SFINAE требует от компилятора конкретизировать шаблон класса, любые ошибки во время выполнения этой конкретизации будут считаться ошибками компилятора. Раньше эти ошибки игнорировались. Например:

Новый компилятор выдаст следующее сообщение об ошибке:
type_traits(1110): error C2139: ‘D’: an undefined class is not allowed as an argument to compiler intrinsic type trait ‘__is_base_of’

..\t331.cpp(14): note: see declaration of ‘D’

..\t331.cpp(10): note: see reference to class template instantiation ‘std::is_base_of ‘ being compiled

Причина ошибки в том, что в месте первого вызова is_base_of класс D еще не определен.
В этом случае исправление ошибки будет следующим: не нужно использовать такие проверки типов до определения классов, значит нужно перенести определение B и D d в начало файла. Если эти определения в заголовочных файлах, нужно проверить порядок включения, чтобы убедиться, что определения классов включаются раньше, чем используется проблемный шаблон.

  • Конструкторы копирования
    И в Visual Studio 2013 и в Visual Studio 2015 RC, компилятор создает конструктор копирования для класса, если в этом классе есть определенный пользователем конструктор перемещения, но нет определенного пользователем конструктора копирования. В Dev14 этот неявно генерируемый конструктор копирования помечается как «=delete».
  • Изменения в C Runtime Library (CRT)

    Общие изменения

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

    Приведение в соответствие стандарту чисел с плавающей точкой
    В математической библиотеке было сделано много изменений для приближения к соответствию стандарту IEEE-754 и Приложению F стандарта C11, основное внимание было уделено особым случаям (NaN и бесконечности). Например, при передаче в функцию библиотеки NaN раньше часто возникала ошибка, сейчас — не возникает. Более подробно узнать об этом можно здесь: IEEE 754 Standard, Annex F of the C11 Standard.
    Эти изменения не вызовут ошибок времени компиляции, однако программа может начать вести себя по другому — более соответственно стандартам.

    FLT_ROUNDS
    Раньше этот макрос разворачивался в константное выражение, что было неправильно, так как способ округления числа мог измениться во время выполнения программы (например, с помощью fesetround). Сейчас FLT_ROUNDS это учитывает.

    Исследование новых возможностей C++ и MFC в Visual Studio 2010

    Сумит Кумар

    Visual Studio 2010 предоставляет огромные возможности для разработчиков на С++ — от использования новых возможностей Windows 7 до улучшенных средств более эффективной работы с большими кодовыми базами.

    В этой статье я объясню, как Microsoft решила некоторые значимые проблемы, с которыми сталкивались разработчики на C++. Конкретнее, Visual Studio 2010 поддерживает более современную модель программирования за счет введения основных языковых средств из будущего стандарта C++0x и переработки стандартной библиотеки, чтобы она позволяла использовать новые языковые средства. Появились новые инструменты и библиотеки для создания параллельных программ. Вы также найдете более совершенные IntelliSense и средства распознавания кода, способные работать с большими кодовыми базами. Кроме того, вы получите выигрыш от повышенного быстродействия библиотек и прочей функциональности, применяемых на этапах проектирования, разработки, компилирования и связывания.

    В Visual Studio 2010 система сборки перенесена в MSBuild, чтобы повысить ее гибкость и обеспечить поддержку ориентации на разные платформы. А доработанная библиотека MFC позволит задействовать всю мощь новых Windows 7 API и писать отличные приложения для Windows 7.

    Давайте подробнее рассмотрим усовершенствования в Visual Studio 2010, ориентированные на C++.

    Основные языковые средства C++0x

    Принятие нового стандарта C++ уже не за горами. Чтобы помочь вам приступить к работе с расширениями C++0x, компилятор Visual C++ в Visual Studio 2010 поддерживает шесть основных языковых средств C++0x: лямбда-выражения, ключевое слово auto, ссылки rvalue, static_assert, nullptr и decltype.

    Лямбда-выражения неявно определяют и конструируют безымянные объекты-функции (function objects). Лямбды предоставляют упрощенный естественный синтаксис для определения объектов-функций там, где они используются, не создавая дополнительных издержек.

    Объекты-функции — очень эффективный способ настройки поведения алгоритмов Standard Template Library (STL) и могут инкапсулировать как код, так и данные (в отличие от обычных функций). Но определять объекты-функции было неудобно, потому что для этого приходилось писать целые классы. Более того, они определялись вовсе не в том месте, где использовались, и это отсутствие локальности дополнительно затрудняло их применение. В библиотеках пытались снять остроту части проблем, но это слабо помогало из-за того, что синтаксис становился еще сложнее, а сообщения компилятора об ошибках были весьма невнятными. Кроме того, использование объектов-функций из библиотек менее эффективно, так как объекты-функции, определенные как поля данных, не подставляются в строку.

    Лямбда-выражения решают эти проблемы. Следующий фрагмент кода иллюстрирует лямбда-выражение, используемое в программе для удаления целых чисел между значениями переменных x и y из целочисленного вектора:

    Во второй строке расположено лямбда-выражение. Квадратные скобки, называемые интродукторами лямбды (lambda-introducer), указывают определение лямбда-выражения. В данном случае лямбда принимает целое значение n в качестве параметра, а генерируемый лямбда-выражением объект-функция имя для поля данных:x и y. Сравните эти строки кода с эквивалентным объектом-функцией, написанным вручную, чтобы оценить, насколько удобнее и быстрее писать лямбды:

    Ключевое слово auto всегда присутствовало в C++, но им редко пользовались, потому что оно не давало особой пользы. Смысл этого ключевого слова в C++0x пересмотрен, и теперь оно автоматически определяет тип переменной по ее инициализатору. Auto делает код лаконичнее, редотвращает ошибки с типами и ошибки усечения. Оно также помогает сделать код более обобщенным, позволяя писать шаблоны, где меньше внимания уделяется типам промежуточных выражений. Следующий код показывает, как ключевое слово auto избавляет вас от указания типа шаблона в цикле for, в котором перебирается вектор:


    Ссылки rvalue — новый ссылочный тип, введенный в C++0x, который помогает решить проблему необязательного копирования и обеспечивает корректное перенаправление (perfect forwarding). Когда в правой части выражения присваивания находится rvalue, объект в левой части этого выражения может заимствовать ресурсы у объекта в правой части, не выполняя отдельную операцию выделения памяти; тем самым реализуется семантика перемещения.

    Корректное перенаправление позволяет написать единственный шаблон функции, принимающий n произвольных аргументов и прозрачно перенаправлять их другой произвольной функции. Природа аргумента (модифицируемый, const, lvalue или rvalue) в процессе перенаправления сохраняется:

    Подробное описание ссылок rvalue выходит за рамки этой статьи, поэтому дополнительные сведения приведены в документации MSDN по ссылке msdn.microsoft.com/library/dd293668(VS.100).

    Static_assert позволяет проверять контрольные выражения (assertions) при компиляции, а не в период выражения. И дает возможность инициировать ошибки компиляции с собственными, более понятными сообщениями. Ключевое слово static_assert особенно полезно для проверки допустимости параметров шаблона. Например, компиляция следующего кода приведет к ошибке «error C2338: custom assert: n should be less than 5»:

    Ключевое слово nullptr добавляет null-указателям безопасность типов в многопоточной среде и тесно связано со ссылками rvalue. В качестве null-указателя часто используются макрос NULL (определенный как 0) и литерал 0. До сих пор это не было проблемой, но они плохо работают в C++0x из-за потенциальных проблем в корректном перенаправлении (perfect forwarding). Поэтому ключевое слово nullptr отчасти было введено для того, чтобы избежать таинственных сбоев в функциях корректного перенаправления.

    Nullptr является константой типа type nullptr_t, который можно преобразовать в любой тип-указатель, но не в другие типы вроде int или char. Помимо использования в функциях корректного перенаправления, nullptr можно применять везде, где раньше в качестве null-указателя был задействован макрос NULL.

    Но будьте осторожны: NULL по-прежнему поддерживается компилятором и пока не заменен nullptr. Это сделано в основном для того, чтобы не разрушать существующий код, в котором часто используется NULL. Но в будущем nullptr должен полностью заменить NULL, и на данном этапе NULL следует рассматривать только как средство поддержания обратной совместимости.

    Наконец, decltype позволяет компилятору логически распознавать тип, возвращаемый функцией, исходя из произвольного выражения, и делать корректное перенаправление более обобщенным. В прошлых версиях для двух произвольных типов T1 и T2 нельзя было логически вычислить тип выражения, в которым эти два типа присутствовали. Так вот, decltype дает вам возможность заявлять, что, например, выражение с аргументами шаблона — такое как sum () — имеет тип T1+T2.

    Изменения в стандартной библиотеке

    Значительная часть стандартной библиотеки C++ была переписана, чтобы задействовать преимущества новых языковых средств C++0x и увеличить ее быстродействие. Кроме того, в эту библиотеку внесли много новых алгоритмов.

    Стандартная библиотека в полной мере использует ссылки rvalue. Такие типы, как vector и list, теперь имеют собственные конструкторы и операторы присваивания move. Операции повторного выделения памяти под векторы используют семантику move через эти новые конструкторы, поэтому, если в ваших типах есть конструкторы и операторы присваивания move, библиотека будет выбирать их автоматически.

    Теперь вы можете создать общий указатель (shared pointer) на объект прямо при конструировании этого объекта с помощью новой функции шаблона make_shared в C++0x:

    В Visual Studio 2008 с той же целью вам пришлось бы написать:

    Использовать make_shared удобнее (вы будете реже набирать имя типа), надежнее (новое ключевое слово предотвращает классическую утечку памяти с безымянным shared_ptr, так как указатель и объект создаются одновременно) и эффективнее (выполняется одна операция динамического выделения памяти вместо двух).

    В библиотеке также содержится новый, более «интеллектуальный» тип указателей — unique_ptr (его появление стало возможным благодаря введению ссылок rvalue). В итоге auto_ptr переведено в разряд устаревших; с unique_ptr вы не столкнетесь с такими подвохами auto_ptr, как возможность перемещения, но не копирования. Это позволяет вам реализовать строгую семантику владения, не затрагивая безопасность. Новое ключевое слово также отлично работает с контейнерами Visual C++ 2010, поддерживающими ссылки rvalue.

    В контейнерах появились новые функции-члены cbegin и cend, которые позволяют использовать const_iterator для просмотра содержимого контейнера независимо от его типа:

    В Visual Studio 2010 в стандартную библиотеку добавлено большинство алгоритмов, предложенных в различных технических документах C++0x. Теперь в ней доступно подмножество библиотеки преобразований Dinkumware, и вы можете очень легко выполнять различные преобразования, например UTF-8 в UTF-16. Стандартная библиотека поддерживает распространение исключения через exception_ptr. Много обновлений было внесено в заголовочный файл . В этом выпуске есть однонаправленный список (singly linked list) с именем forward_list. Появился заголовочный файл , улучшающий диагностику. Кроме того, многие средства TR1, которые в предыдущем выпуске находились в пространстве имен std::tr1 (например, shared_ptr и regex), теперь являются частью стандартной библиотеки в пространстве имен std.

    Усовершенствования в параллельном программировании

    В Visual Studio 2010 введена платформа параллельных вычислений (Parallel Computing Platform), которая помогает быстро писать высокопроизводительный параллельный код и в то же время предотвращает тонкие ошибки в параллельной обработке. Это позволит вам избавиться от некоторых традиционных проблем, связанных с параллельной обработкой.

    Parallel Computing Plat­form состоит из четырех основных частей: Concurrency Runtime (ConcRT), Parallel Patterns Library (PPL), Asynchronous Agents Library и средств отладки и профилирования параллельного кода.

    ConcRT — самый низкий программный уровень, взаимодействующий непосредственно с ОС, и осуществляющий арбитраж множества параллельных компонентов в их конкуренции за ресурсы. Поскольку это процесс пользовательского режима, он может отзывать ресурсы, когда используются его механизмы кооперативной блокировки. ConcRT поддерживает локальность и предотвращает переключение задач между разными процессорами. Он также использует механизм планирования пользовательского режима (User Mode Scheduling, UMS) из Windows 7, что в ряде случаев может резко повысить производительность, даже если механизм кооперативной блокировки не применяется.

    PPL предоставляет шаблоны для написания параллельного кода. Если вычисления допускают разложение на независимые операции, которые можно представить функциями или объектами-функциями, каждая из этих операций может рассматриваться как задача (task). Концепция задач намного ближе к предметной области, чем потоки, которые уводят вас от предметной области, заставляя думать об оборудовании, ОС, критических секциях и т. п. Задача может выполняться параллельно с другими задачами независимо от того, что именно делают эти другие задачи. Например, сортировку двух половин массива можно выполнять как две параллельные задачи.

    PPL включает параллельные классы (task_handle, task_group и structured_task_group), параллельные алгоритмы (parallel_invoke, parallel_for и parallel_for_each), параллельные контейнеры (combinable, concurrent_queue и concurrent_vector), а также синхронизирующие примитивы, поддерживаемые ConcRT (critical_section, event и reader_writer_lock), — все они полностью поддерживают концепцию задач. Все компоненты PPL находятся в пространстве имен concurrency.

    Группы задач позволяют выполнять наборы задач и ждать завершения их всех. В частности, в примере с сортировкой задачи, обрабатывающие две половины массива, могут быть одной группой задач. Тогда вы получите гарантию, что эти две задачи будут завершены в конце вызова функции-члена wait, как показано ниже на примере рекурсивной сортировки «quicksort», написанной с применением параллельных задач и лямбд:

    Этот код можно еще больше улучшить, используя structured_task_group, поддерживаемую алгоритмом parallel_invoke. Он принимает от двух до десяти объектов-функций и выполняет их все параллельно, используя столько ядер, сколько предоставляет ConcRT, а затем ждет их завершения:

    Каждая из задач может порождать несколько подзадач. Сопоставление между задачами и потоками (и обеспечение оптимального использования всех ядер) берет на себя ConcRT. Поэтому разложение ваших вычислений на максимально возможное количество задач поможет задействовать все доступные ядра.

    Еще один полезный параллельный алгоритм — parallel_for, применяемый для параллельного перебора в цикле:

    Здесь параллельно вызываются объекты-функции с каждым индексом, начиная с первого и заканчивая последним.

    Asynchronous Agents Library предоставляет модель программирования, основанную на потоках данных (dataflow-based programming model), где вычисления зависят от доступности необходимых данных. Эта библиотека базируется на концепциях агентов, блоков сообщений и функций передачи сообщений. Агент — это компонент приложения, выполняющий определенные вычисления и асинхронно взаимодействующий с другими агентами для решения более крупной вычислительной операции. Взаимодействие между агентами осуществляется через функции передачи сообщений и блоки сообщений.

    Агенты имеют значимый жизненный цикл, в ходе которого они проходят различные стадии. Они не предназначены для тонкого распараллеливания, достигаемого с помощью задач PPL. Агенты опираются на ConcRT-компоненты планирования и управления ресурсами и помогают избежать проблем, возникающих при использовании общей памяти в параллельных приложениях.

    Чтобы задействовать преимущества этих шаблонов, вам не нужно связывание с дополнительными компонентами, равно как не требуется и распространять какие-либо редистрибутивы. ConcRT, PPL и Asynchronous Agents Library реализованы в msvcr100.dll, msvcp100.dll и libcmt.lib/libcpmt.lib попутно со стандартной библиотекой. Реализации PPL и Asynchronous Agents Library в основном заключены только в заголовочных файлах.

    Отладчик Visual Studio теперь поддерживает ConcRT и позволяет легко отлаживать ошибки, связанные с параллельной обработкой, — в отличие от Visual Studio 2008, где отладчик ничего не знал о высокоуровневых концепциях распараллеливания. В Visual Studio 2010 имеется средство профилирования параллельного кода, с помощью которого можно визуализировать поведение параллельных приложений. В отладчик введены новые окна, визуализирующие состояние всех задач в приложении и их стеки вызовов. Рис. 1 показаны окна Parallel Tasks и Parallel Stacks.

    Рис. 1 Отладочные окна Parallel Stacks и Parallel Tasks

    IntelliSense и производительность в соотношении разработка-время

    В Visual Studio 2010 включена совершенно новая инфраструктура IntelliSense и просмотра. Она не только быстро работает в проектах с большими кодовыми базами, но и предоставляет ряд новых средств, повышающих производительность труда на этапе разработки.

    В IntelliSense содержатся такие средства, как активная система отчетов об ошибках и подсказки Quick Info; они базируются на новом клиентском интерфейсе компилятора, который «на лету» разбирает единицы трансляции и предоставляет полную и точную информацию о семантике кода даже в процессе модификации файлов исходного кода.

    Все средства просмотра кода, такие как представление классов и иерархия классов, теперь используют информацию об исходном коде, хранящуюся в базе данных SQL, которая обеспечивает индексацию и занимает фиксированный объем памяти. В отличие от предыдущих выпусков Visual Studio 2010 IDE всегда отвечает, и вам больше не придется ждать, пока не будет выполнен повторный разбор единиц компиляции из-за изменений в заголовочном файле.

    Активная система отчетов об ошибках в IntelliSense (знакомые красные волнистые линии) выделяет синтаксические и семантические ошибки при просмотре и редактировании кода. Задержав курсор мыши над одной из таких ошибок, вы получите сообщение (рис. 2). Окно со списком ошибок также показывает ошибку из текущего просматриваемого файла, равно как и ошибки, обнаруженные Intelli­Sense в любой части единицы компиляции. Вся эта информация доступна вам без выполнения процесса сборки.

    Рис. 2 Активная система отчетов об ошибках в IntelliSense

    Кроме того, при наборе директивы #include в раскрывающемся списке показываются релевантные включаемые файлы, и этот список обновляется по мере ввода новых символов.

    Новая функция Navigate To (Edit | Navigate To или Ctrl+запятая) ускорит вам поиск файла или символа. Она предоставляет результаты поиска в реальном времени, исходя из уже набранных вами частей строк (рис. 3). Эта функция также работает с файлами C# и Visual Basic и является расширяемой.

    Рис. 3 Использование функции Navigate To

    Call Hierarchy (вызывается клавишами Ctrl+K, Ctrl+T или из контекстного меню) позволяет перемещаться к любым функциям, вызываемым из конкретной функции, или к конкретной функции, вызываемой из всех интересующих вас функций. Это более совершенная версия функции Call Browser, содержавшейся в предыдущих выпусках Visual Studio. Окно Call Hierarchy организовано намного лучше и показывает вызовы из деревьев для любой функции, присутствующей в окне, а также вызовы к этим деревьям.


    Заметьте: хотя все функции просмотра кода доступны как для чистого C++, так и для C++/CLI, IntelliSense-средства вроде активной системы отчетов об ошибках и Quick Info не будут поддерживаться для C++/CLI в финальном выпуске Visual Studio 2010.

    В этом выпуске усовершенствованы и другие средства редактора. Так, популярная функция Find All References, применявшаяся для поиска ссылок на элементы кода (классы, члены класса, функции и т. д.) в рамках полного решения, стала более гибкой. Результаты поиска можно еще больше сужать, используя команду Resolve Results из контекстного меню.

    Неактивный код теперь сохраняет семантическую информацию, не теряя цветовые выделения (раньше он становился просто серым). На рис. 4 показано, как затемняется неактивный код, но при этом сохраняет все цветовые выделения, относящиеся к семантической информации.

    Рис. 4 Неактивные блоки кода сохраняют цветовые выделения

    Помимо уже описанных функций, редактор в Visual Studio 2010 просто удобнее в использовании.Новая IDE на базе Windows Presentation Foundation (WPF) основательно переработана, и из нее были убраны все нагромождения в UI. Окна документов, например редактора кода и дизайнера, можно перемещать за пределы основного окна IDE и отображать на нескольких мониторах. Стало намного проще увеличивать или уменьшать содержимое окна редактора кода, используя клавишу Ctrl и колесико мыши. IDE также обеспечивает более широкие возможности расширения.

    Системы сборки и проектов

    В Visual Studio 2010 внесены существенные изменения в систему сборки (build system) и в систему проектов (project system) для C++.

    Самое важное изменение заключается в том, что для сборки проектов на C++ теперь используется MSBuild. MSBuild является расширяемым ядром управления сборкой и базируется на XML.Оно применялось для проектов на C# и Visual Basic в предыдущих версиях Visual Studio. Теперь MSBuild — общая система сборки от Microsoft для всех языков. Ее можно использовать как в сборочной лаборатории, так и на индивидуальных компьютерах разработчиков.

    Процессы сборки проектов на C++ теперь определяются в терминах MSBuild (файлы задач и целевых платформ) и дают вам более широкие возможности в настройке, управлении и прозрачности.

    Тип файлов проектов на C++ получил новое расширение: .vcxproj. Visual Studio будет автоматически обновлять старые файлы и решения .vcproj до нового формата. Также имеется утилита командной строки vcupgrade.exe, позволяющая обновлять отдельные проекты из командной строки.

    В прошлом вы могли использовать только тот набор инструментов (компилятор, библиотеки и т. д.), который предоставлялся текущей версией Visual Studio. И начать работу с новой IDE было невозможно до перехода на новый набор инструментов. Visual Studio 2010 решает эту проблему и позволяет выполнять сборку с ориентацией на несколько разных версий наборов инструментов. Например, работая в Visual Studio 2010, вы могли бы ориентироваться на компилятор и библиотеки Visual C++ 9.0. На рис. 5 показаны соответствующие настройки, доступные на странице свойств.

    Рис. 5 Ориентация на несколько Platform Toolset

    Применение MSBuild делает систему сборки кода на C++ гораздо более расширяемой. Если система сборки по умолчанию не удовлетворяет вашим потребностям, вы можете расширить ее, добавив собственный инструмент или введя какую-либо дополнительную стадию сборки. При операциях сборки MSBuild использует задачи как повторно применяемые единицы исполняемого кода. Вы можете создавать собственные задачи и расширять систему сборки, определяя их в XML-файле. MSBuild генерирует задачи по таким XML-файлам «на лету».

    Существующие платформы и наборы инструментов можно расширять добавлением файлов .props и .targets в папки ImportBefore и Import­After. Это особенно полезно для поставщиков библиотек и инструментов, которые предназначены для расширения существующих систем сборки. Вы также можете определить собственный набор инструментов платформы (platform toolset). Кроме того, MSBuild предоставляет более полную диагностическую информацию, упрощая отладку проблем сборки и делая сборки с приращением (incremental builds) более надежными. Плюс вы можете создавать системы сборки, теснее связанные с системой контроля версий исходного кода и сборочной лабораторией и менее зависимые от конфигураций компьютеров разработчиков.

    Система проектов, размещаемая поверх системы сборки, тоже использует преимущества гибкости и расширяемости MSBuild. Система проектов распознает процессы MSBuild и позволяет Visual Studio прозрачно показывать информацию, доступную от MSBuild.

    Все изменения видны на страницах свойств и могут настраиваться в соответствии с вашими потребностями. Вы можете сконфигурировать систему проектов на использование собственной платформы (например, существующих платформ x86 или x64) или собственного отладчика. Страницы свойств позволяют писать и интегрировать компоненты, динамически обновляющие значения свойства в зависимости от контекста. Система проектов Visual Studio 2010 дает возможность даже создать собственный UI для чтения и записи свойств вместо механизма на основе страниц свойств.

    Меньшее время компиляции и более высокая производительность

    Помимо уже описанных улучшений в использовании функциональности этапа проектирования, Visual Studio 2010 также повышает скорость компиляции, качество и производительность приложений, создаваемых с помощью компилятора Visual C++, в результате множества усовершенствований, внесенных в процесс генерации кода.За счет ряда оптимизаций скорость компиляции на платформах x64 заметно увеличена.

    Производительность некоторых приложений зависит от рабочего набора (working set). Размер кода для архитектуры x64 был уменьшен на 3–10% за счет множества оптимизаций в этом выпуске, что привело к повышению скорости работы таких приложений.

    Генерация кода с применением SIMD (Single Instruction Multiple Data), важная для разработчиков игр и приложений, имеющих дело с аудио, видео и графикой, также оптимизирована для повышения качества и производительности кода. Улучшения обеспечивают, в частности, разрыв ложных зависимостей, векторизацию инициализаций векторов констант и более эффективного выделения регистров XMM для удаления лишних загрузок, сохранений и перемещений. Кроме того, было оптимизировано семейство внутренних команд __mm_set_**, __mm_setr_** и __mm_set1_**.

    Для большей производительности приложения следует компилировать с применением Link Time Code Generation (LTCG) и Profile Guided Optimization (PGO).

    За счет ряда оптимизаций скорость компиляции на платформах x64 заметно увеличена. Компиляция с LTCG, рекомендованная для более качественной оптимизации, обычно выполняется дольше, чем без LTCG, особенно в больших приложениях. В Visual Studio 2010 компиляция с LTCG ускорена вплоть до 30%. В этом выпуске введен выделенный поток для записи PDB-файлов, поэтому вы увидите ускорение процесса связывания при использовании ключа /DEBUG.

    Проходы с инструментарием PGO выполняются быстрее за счет введения поддержки версий оснащенных двоичных файлов, не содержащих блокировок. Также появился новый вариант POGO — PogoSafeMode, который позволяет указывать, какой режим следует использовать при оптимизации приложения — безопасный или быстрый. По умолчанию применяется быстрый режим. Безопасный режим медленнее быстрого, но безопасен в многопоточной среде.

    Повышено качество кода, генерируемого компилятором. Теперь полностью поддерживаются Advanced Vector Extensions (AVX), которые очень важны для приложений, выполняющих интенсивные вычисления с плавающей точкой на процессорах AMD и Intel; они включаются встроенными параметрами и /arch:AVX. Точность вычислений с плавающей точкой повышается при использовании параметра /fp:fast.

    Создание приложений для Windows 7

    В Windows 7 появился целый ряд новых потрясающих технологий и средств, а также добавлены новые API, и Visual Studio 2010 обеспечивает доступ ко всем новым Windows API. Компоненты Windows SDK, необходимые для написания кода для неуправляемых Windows API, поставляются вместе с Visual Studio 2010. Вы можете задействовать такие инновационные API, как Direct3D 11, DirectWrite, Direct2D и Windows Web Service, используя заголовочные файлы SDK и библиотеки, доступные в Visual Studio 2010.

    Этот выпуск Visual Studio не только обеспечивает доступ ко всем Windows API, но и упрощает написание Windows-приложений с помощью кардинально переработанной MFC. К значительной части функциональности Windows 7 можно получить доступ через библиотеки MFC, не обращаясь к неуправляемым API напрямую. Ваши существующие MFC-приложения заиграют «новыми красками» в Windows 7 просто за счет перекомпиляции. Ну а новые приложения смогут задействовать все преимущества новых средств.

    MFC теперь обеспечивает улучшенную интеграцию с оболочкой Windows. Интеграция вашего приложения с Windows Explorer может быть более полной за счет применения обработчиков файлов для предварительного просмотра, вывода эскизов и поиска, поддерживаемых в этом выпуске. Эти средства предоставляются как выбираемые параметры в MFC Application Wizard (рис. 6) MFC автоматически сгенерирует проект ATL DLL, реализующий эти обработчики.

    Рис. 6 MFC Application Wizard со страницей параметров обработчика файлов

    Одно из самых заметных изменений UI в Windows 7 — новая панель задач. MFC позволяет быстро задействовать преимущества таких средств, как списки переходов (jump lists), строки ярлычков эскизов (tabbed thumbnails), предварительного просмотра эскизов (thumbnail preview), полосок прогресса (progress bars), оверлейных значков (icon overlay) и т. д. На рис. 7 показаны предварительно просматриваемые эскизы и строка с ярлычками эскизов для MFC-приложения типа MDI.

    Рис. 7 Предварительный просмотр эскизов и строка с их ярлычками в MFC-приложении

    Ленточный UI теперь имеет стиль, принятый для лент в Win­dows 7, и в вашем приложении можно «на лету» менять UI в любой момент во время разработки с нескольких лент в стиле Office на ленту в стиле Windows 7, используя раскрывающийся список стилей рис. 8.

    Рис. 8 Раскрывающийся список Style в MFC-приложении

    MFC дает возможность вводить в ваши приложения мультисенсорную поддержку (multi-touch) и передает вам соответствующие сообщения для обработки при возникновении различных событий касания. Вам нужно лишь зарегистрироваться на события касания и жестов, и они будет направляться вашему приложению. Кроме того, MFC-приложения по умолчанию поддерживают высокие DPI-разрешения, поэтому они способны адаптироваться к экранам с высоким DPI, и при этом их окна не выглядят размытыми или мозаичными. MFC на внутреннем уровне масштабирует и изменяет шрифты и другие элементы, гарантируя четкость отображения вашего UI на экранах с высоким DPI.

    Кроме новых средств Windows 7, существовала и другая функциональность, введенная со времен Windows Vista, но не поддерживавшаяся в предыдущих выпусках MFC.Эта ситуация теперь исправлена. Например, Restart Manager — полезная функция Windows Vista, которая позволяет сохранять приложение перед его принудительным завершением. Приложение может вызвать эту функцию и после перезапуска восстановить свое состояние. Теперь вы можете в полной мере использовать Restart Manager в своем MFC-приложении для более элегантной обработки его краха и перезапуска. Чтобы разрешить перезапуск и восстановление в существующем приложении, просто добавьте строку кода:

    Новые MFC-приложения получают эту функциональность автоматически при использовании MFC Application Wizard. Механизм автоматического сохранения доступен приложениям, которые сохраняют документы, а пользователь может определять интервалы автоматического сохранения. В MFC Application Wizard для программы можно выбрать поддержку лишь перезапуска или только восстановления (применимо к приложениям типа Doc/View).

    Еще одно добавление — диалог Windows Task, который является улучшенным видом окна сообщения (рис. 9). В MFC теперь есть оболочка диалога Task, которую можно применять в приложениях.

    Рис. 9 Диалог Task

    MFC Class Wizard возвращается

    В библиотеку MFC не только добавлена новая функциональность — этот выпуск упрощает работу с MFC в Visual Studio IDE. Было очень много просьб вернуть MFC Class Wizard (рис. 10), и вот он возвращен и вдобавок усовершенствован. С его помощью можно добавлять классы, обработчики событий и другие элементы приложения.

    Рис. 10 MFC Class Wizard

    Другое дополнение — Ribbon Designer (дизайнер лент), который позволяет визуально проектировать ленточный UI (вместо его определения в коде, как в Visual Studio 2008) и сохранять его как XML-ресурс. Этот дизайнер, очевидно, будет полезен при разработке новых приложений, но и в существующих приложениях с его помощью можно обновить UI. XML-определение можно создать простым добавлением временной строки к существующему определению ленточного UI в коде:


    Полученный XML-файл можно использовать как файл ресурса и в дальнейшем модифицировать с помощью Ribbon Designer.

    Заключение

    Visual Studio 2010 — важный выпуск в эволюции Visual C++, и он во многих отношениях облегчает жизнь программистам. В этой статье я лишь кратко обрисовал наиболее важные усовершенствования, связанные с C++. Более подробное описание различных средств см. в документации MSDN и в блоге группы Visual C++ по ссылке blogs.msdn.com/vcblog, сообщения в котором послужили основой для некоторых разделов этой статьи.

    Сумит Кумар (Sumit Kumar) — менеджер программ в группе Visual C++ IDE. Магистр компьютерных наук (Техасский университет в Далласе).

    Благодарю следующих технических специалистов: Стефан Т. Лававей (Stephan T. Lavavej), Мариан Лупару (Marian Luparu) и Тарек Мадкур (Tarek Madkour)

    Возникли проблемы с MFC lntelliSense на C++

    Здравствуйте, у меня есть классы Microsoft Foundation, которые будут работать в основном и проверять USB-устройства и другие вещи. Проблема в том, что определенный IntelliSense не определен, поэтому большинство ошибок будет отображаться при запуске программы.

    Вот список ошибок:

    Весь код:

    ПОМОГИТЕ:

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

    1 ответ

    Макрос карты сообщений ON_BN_CLICKED ожидает указатель на функцию-член с подписью

    Тем не менее, ваш OnBnClickedButton1 возвращает bool , Эта функция-член не должна иметь возвращаемого значения ( void ) использовать его с ON_BN_CLICKED ,

    Проблема с MFC CWnd :: Метод CreateControl

    У меня проблема с методом CWnd :: CreateControl при загрузке пользовательского элемента управления ActiveX из приложения MFC.

    У меня есть список пользовательских элементов управления ActiveX, которые реализованы. Создайте метод inturn, вызывающий метод CWnd :: CreateControl.

    У меня есть диалоговое окно, в OnInitDialog, я начал таймер с помощью Settimer(). В событии OnTimer я загружаю все элементы управления, вызывая соответствующий метод Create Control. После открытия и закрытия диалогового окна более 10 раз OnTimer не может загружать конт.

    Я проверил возвращаемое значение, которое является ложным, и GetLastError, которое равно 0x0 (операция выполнена успешно). Я полностью отлаживал и проверял все возможные ошибки до этого события. Я не мог найти основную причину, из-за которой не было загрузки элементов управления.

    Создан 08 дек. 10 2010-12-08 12:34:25 Snabak Vinod

    Спасибо, друзья. Я решил эту проблему. Проблема связана с некоторыми элементами управления ActiveX, которые не реализованы с помощью правил COM. В методе InitInstance() следует вызвать метод CoInitialize() и в методе ExitInstance() следует вызвать метод CoUninitialize(). Это не сделано в некоторых методах, которые вызывают эту проблему. После его решения проблема решена. – Snabak Vinod 11 янв. 11 2011-01-11 11:39:36

    1 ответ

    Вы можете передать ниже вопрос подобного вхождению проблемы Exception while opening file

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

    В моем случае, когда я изменил способ доступа к методу, и он начал работать.

    Создан 17 дек. 10 2010-12-17 21:46:02 ckv

    C/c++ — Проблема с MFC

    После размещения этой статьи в интернете, она получила следующую критику:

    • Она написана не достаточно хорошо
    • Плохо описаны проблемы MFC
    • Нет примеров кода
    • Статья не объективна, так как Qt постоянно хвалят
    • Автор не проявляет глубоких знаний MFC и представляет все в ложном свете
    • Автор не сравнивает Qt с .NET

    Хочу ответить, что написать хорошую статью не просто. Для этого потребовалось бы очень много времени, проверенных фактов, примеров кода и сравнений. Если бы у меня была такая хорошая статья, то я, вероятно, опубликовал бы ее на более профессиональных сайтах, а не на своей домашней странице.

    В какой-то степени я признаю эту критику. Изначально эта статья задумывалась как небольшой обзор по программированию с помощью MFC. А в результате в ней отражено больше проблем, с которыми мы столкнулись при программировании с MFC, чем простого сравнения Qt и MFC. Но критика принимается, и моя следующая статья будет лучше.

    И все же, я думаю, что представленный ниже материал по-прежнему ценен. Я не встречал ни одного сравнения MFC и Qt. Поэтому это единственное.

    Philippe Fremy

    Введение Я программирую используя Qt и MFC. Поэтому мне хотелось бы поделиться с Вами своим опытом использования этих двух инструментариев.

    Я не пишу профессионально. Поэтому эта статья не так хороша и приятна как те, которые Вы найдете на профессиональных веб-сайтах или в журналах. Это всего лишь мой опыт, который я передаю Вам своими словами. Английский — не родной мне язык, поэтому мои конструкции, вероятно, немного странны и в них есть ошибки. Пожалуйста, сообщите мне о них, чтобы я мог их исправить.

    Эта статья не претендует на объективность. Она — лишь результат моего личного опыта. Я не перечисляю в ней все хорошие и плохие особенности Qt и MFC. Тот факт, что мое знакомство с Qt произошло раньше, чем я стал программировать с MFC, мог также повлиять на мою объективность.

    Эта статья написана с прагматической точки зрения: мой босс предоставляет мне спецификацию приложений, которые он хочет, а я разрабатываю их. Для разработки одних я использовал Qt, для других — MFC.

    Microsoft Foundation Class (MFC) — это графический инструментарий для операционных систем Windows. Это более или менее объектно-ориентированная обертка (wrapper) для интерфейса прикладного программирования (API) win32. Предоставляемый инструментарием MFC API имеет ужасный смешанный C/C++-интерфейс.

    Qt — это графический C++ -инструментарий, который разрабатывается с 1994 года Trolltech ( http://www.kde.ru/»http://www.trolltech.com»). Он доступен для Windows (любой версии), Unix (любой версии), MacOS X и встроенных устройств, таких как Sharp Zaurus. Несомненно, инструментарий Qt полностью объектно-ориентирован.

    Модель Document/View

    Инструментарий MFC требует от программиста использования модели Document/View и шаблонов. Почти невозможно не использовать их. Но шаблоны имеют фиксированную структуру, и поэтому очень сложно расширить их возможности. Например, невозможно разделить область и отобразить два вида двух различных документов. Вторая проблема заключается в том, что шаблон создает вид, но не имеет к нему доступа. Все должно быть сделано документом, и это иногда создает проблемы.

    Qt не ограничивает Вас какой-либо моделью дизайна. Без каких-либо ограничений Вы можете использовать модель Document/View, если сочтете это нужным. Или не использовать ее.

    Сравнение псевдо-объектной и хорошей объектной архитектур

    Главное отличие между Qt и MFC — в их дизайне.


    MFC — своего рода объектная обертка к Windows API, который написан на C. Это сложно назвать хорошим объектно-ориентированным дизайном. В различных местах Вы должны будете снабжать C-структуру 15-тью членами, из которых только один будет релевантным. Или должны будете вызывать функции с устаревшими параметрами.

    Также встречаются различного рода уловки, лишенные какой-либо логичности. Например, если Вы создаете графический объект, он не создастся, пока не будет вызван метод Create(). Для диалогов Вы должны ожидать OnInitDialog(), а для видов Вы ожидаете OnInitialUpdate(), . Также, если Вы создаете объект вручную и вызываете его методы, возникают сбои.

    Давайте для примера возьмем диалог, содержащий элемент управления CEdit. Вы не можете для него использовать метод GetWindowText() вне метода DoModal(). Это приведет к сбою. Почему текст элемента управления можно получить только тогда, когда он находится в определенном состоянии? Подобных уловок в MFC полно. К тому же, это усложняет отладку.

    Qt — полная противоположность. Ее объектно-ориентированная архитектура, очевидно, была хорошо продумана. Поэтому инструментарий имеет согласованное именование, наследование, организацию классов и методов. Количество аргументов методов ограниченно только необходимыми. Их порядок постоянен для различных классов. А возвращаемое значение логично. И в тоже время сохраняется функциональность и простота. Использовав однажды один из классов, Вы сможете использовать и другие, потому что они работают сходным образом.

    Чтобы в Qt получить элемент управления Edit, Вы должны создать объект QLineEdit с помощью оператора new, как в обычных классах C++. Тотчас же Вы получаете доступ ко всем методам объекта, независимо от того, отображен он или нет. Это работает самым простым образом, как только Вы можете себе представить.

    Цикл сообщений

    Работа MFC основана на механизме сообщений. Чтобы что-то сделать, Вы должны обработать определенное сообщение. Windows посылает программе тысячи сообщений. К сожалению, непросто узнать, как их использовать, какую информацию они передают, когда они посылаются. Некоторые из них излишни, некоторые не посылаются, некоторые не документированы. В документации эта тема не очень хорошо описана. Непросто узнать, какой объект что и когда посылает, какой объект получает или не получает, и какое действие было выполнено. Некоторые возможности, доступные через сообщения, предпочтительнее было бы реализовать через прямые вызовы. Механизм сообщений усложняет отладку и чтение листингов.

    Работа Qt базируется на механизме обратного вызова, основанном на передаче сигналов и их приеме слотами (Slots). Эта система является основным механизмом связи между объектами. Сигнал может передавать любое число аргументов. Это очень удобно. Необходимые сигналы Вы подключаете к соответствующим слотам, так что в итоге Вы всегда знаете, что происходит. Число сигналов, передаваемых классом, обычно невелико ( 4 — 5 ), и все они очень хорошо документированы. Этот процесс находится под полным Вашим контролем. Механизм использования сигналов и слотов приближенно напоминает Java listener, но он более легковесен и универсален.

    Создание интерфейса

    MFC не обеспечивает компоновку (layout) элементов управления внутри окна: это создает проблемы при желании сделать окно изменяемого размера. Вы должны вручную перемещать элементы управления при изменении размеров окна (это объясняет, почему большинство диалоговых окон Windows неизменяемого размера). Эта проблема приобретает большее значение для программ, интерфейс которых должен быть переведен на язык с более длинными словами или предложениями. Вы должны будете перекомпоновать Ваши окна для каждого такого языка.

    Редактор ресурсов Visual Studio весьма ограничен: Вы можете расположить элементы управления в фиксированных позициях и только. Некоторые свойства могут быть откорректированы, а мастер класса позволит Вам легко создать переменные и методы. Однако стоит заметить, что создать вручную цикл сообщений, функцию DDX ( Dialog Data Exchange ) или макрос IMPLEMENT_DYNCREATE будет достаточно сложно.

    С Qt все можно сделать вручную, так как это несложно. Чтобы получить кнопку, Вам достаточно написать:

    button = new QPushButton( «button text», MyParentWidget);

    Если Вы хотите, чтобы при нажатии на кнопку был выполнен метод action(),Вам следует написать следующее:

    connect( button, SIGNAL( clicked() ), SLOT( action() ) );

    Qt имеет гибкий механизм компоновки, который является настолько простым, что Вы тратите впустую время, если его не используете.

    Для создания пользовательского графического интерфейса Qt предлагает инструмент Qt Designer. С помощью него Вы можете откорректировать любые свойства используемых элементов управления. Вы не фиксируете жестко их расположение, а используете компоновщик (layout manager). Также Вы можете подключить сигналы к слотам. Это делает Qt Designer большим, нежели обычный дизайнер интерфейса. Он генерирует код, который Вы фактически можете читать и понимать. Поскольку сгенерированный код сохраняется в отдельном файле, Вы можете изменить его в любой момент.

    Qt Designer позволяет Вам делать то, что невозможно в MFC, например, создать список с предзаполненными полями или использовать различного вида вкладки (tab controls).

    Документация

    Если Вы желаете использовать богатый графический инструментарий, то его документация для Вас будет иметь большое значение. Документация MSDN (которую Вы должны будете оплатить отдельно) огромна — на 10 CD-ROM. Она охватывает множество разнообразных тематик. Однако возникает ощущение, что она плохо отобрана и этим представляет меньшую ценность. Перекрестные ссылки также очень бедны. Трудно переходить к базовым, родственным классам и классам-потомкам. Методы представлены без сигнатуры. Трудно обратиться к унаследованным методам класса. Другая проблема состоит в том, что если Вы производите поиск по ключевому слову, то получаете результат для VC++, Visual Basic, Visual J++ и InterDev, даже если используете фильтр.

    Она охватывает все области применения Qt и занимает 18 Мбайт. Каждый класс и метод подробно документирован с множеством примеров использования. Удобная навигация между классами и методами осуществима любым веб-браузером или инструментом, предлагаемым Trolltech (Qt Assistant). Вместе с документацией поставляются руководство и примеры использования. Также имеется FAQ и список рассылки, доступный через группы новостей и веб-интерфейс с возможностью поиска. Если у Вас есть лицензия, Вы поможете воспользоваться технической поддержкой, обычно реагирующей в течение одного дня.

    Хорошая продуманность Qt уменьшает потребность в посторонней помощи. Одно из заявлений Trolltech гласит: «Продукт и документация должны быть настолько хороши, чтобы не возникало потребности в технической поддержке».

    Уникод

    Чтобы отобразить уникод в MFC, Вы должны скомпилировать и собрать приложение со специальными опциями (а также сменить точку входа исполняемого модуля). Вы должны добавить _T к каждой строке, используемой в программе, и сменить тип `char` на TCHAR. Все функции, обрабатывающие строки (strcpy, strdup, strcat, . ), должны быть заменены другими. Самое досадное то, что программа, откомпилированная с поддержкой уникода, не будет работать с библиотеками DLL, откомпилированными без его поддержки. Если при разработке Вы используете сторонние библиотеки DLL, это может доставить Вам серьезные неудобства.

    Строки в Qt являются объектами класса QString, который изначально поддерживает уникод. Поэтому Вам не придется изменять свой код или использовать какие-либо опции при компиляции и сборке. Просто используйте QString. Qt изначально поддерживает уникод, поэтому здесь не будет никаких проблем.

    Сам по себе класс QString очень функционален, даже если Вы и не заботитесь об уникоде. Поэтому поддержка уникода достигается весьма просто. В случае необходимости QString может обеспечить перевод строки в char* или UTF8.

    Большое различие между строковым классом MFC CString и QString заключается в их дизайне. CString основан на типе char* с несколькими методами. Преимущество такого подхода в том, что везде, где требуется переменная типа char*, Вы можете использовать член класса CString. Однако это привлекательно только на первый взгляд. Большим недостатком такого подхода является то, что Вы можете изменить член char* класса CString без обновления самого объекта класса. Также возникают трудности при преобразовании в уникод.

    QString, напротив, содержит уникод-версию строки и обеспечивает тип char* только когда требуется. API Qt в качестве строчных аргументов всегда требует QString, поэтому Вам редко придется использовать тип char*. Класс QString также обладает некоторыми дополнительными возможностями, вроде совместного использования (или копирования по требованию) содержимого строки. Поэтому Вам наверняка захочется его использовать в своих программах. Это типичный пример хорошей архитектуры Qt и С++ -оберточной MFC.

    Локализация

    MFC-программу можно локализировать. Для этого Вы должны поместить каждую строку в строковую таблицу и повсюду в Вашем коде использовать функцию LoadString( IDENTIFIER ). Затем Вы должны поместить строковую таблицу в библиотеку DLL. Используя Visual Studio, перевести строки в желаемый язык, преобразовать графические ресурсы (потому что их текст не может быть помещен в строковую таблицу) и использовать эту библиотеку в программе. Это настолько сложно, что Вы, вероятно, не сможете доверить эту работу одному переводчику, ему нужна будет Ваша помощь. У Вас также могут возникнуть проблемы из-за фиксированного позиционирования элементов управления в MFC. Так как их расположение определялось длиной непереведенных строк, более длинные переведенные фразы будут накладываться. Если в последствии Вы поменяете некоторые строки или добавите новые, Вы должны будете убедиться, что перевод был обновлен.

    В Qt Вы всего лишь передаете ваши строки функции tr() . Это очень удобно при разработке — Вы можете изменять строки непосредственно в Вашем коде. Специальная программа Qt Linguist извлечет все требующие перевода строки и в удобном виде их отобразит. Ее интерфейс обеспечивает удобный перевод, возможность использования словаря, просмотр контекста строки, обнаружение конфликта клавиатурных сокращений, обнаружение новых непереведенных или измененных строк. Эта программа может использоваться переводчиком без познаний в области разработки программ. Редактор Qt Linguist доступен по лицензии GPL, поэтому Вы можете его модифицировать. Перевод сохраняется в формате XML, поэтому он может быть легко использован в различных целях. Задача добавления к программе нового перевода заключается в создании нового файла с помощью Qt Linguist.

    Проблемы ресурсов приложений

    Процесс разработки с помощью MFC тесно связан с созданием ресурсов приложений. Они используются во многих случаях. Это имеет следующие последствия:

    • Практически невозможно заниматься разработкой программ с помощью средств, отличных от Visual Studio.
    • Редактор ресурсов весьма ограничен в своих возможностях. Например, сделать абсолютно все с помощью редактора диалогов невозможно: некоторые свойства могут быть изменены, а некоторые нет. Так, для панелей инструментов Вы вынуждены использовать изображение, которое содержит изображения всех кнопок. Чтобы приложению дать название, Вы должны поместить некоторые строки в строковую таблицу, но Вы должны знать, что каждое поле отделяется символом ` `. Порядок и значение каждого поля не очевидны, и их нелегко определить.
    • В файле «Resource.h» идентификаторам ресурсов присваиваются значения (числа, меньшие 32768). Это создает проблемы при удалении или переименовании ресурсов, а также в случае, когда различные библиотеки DLL используют файлы «resource.h» с одинаковыми названиями ресурсов, но с различными их значениями (типичный случай при использовании DLL-компонент).
    • При использовании библиотеки DLL с ее собственными ресурсами, которая, в свою очередь, использует другие DLL-библиотеки, возникает вероятность, что программа может смешать свои ресурсы с ресурсами подключаемых библиотек, так как ресурсы могут иметь одинаковые значения идентификаторов. Поэтому Вы должны зарезервировать для своих ресурсов диапазон уникальных значений. Но это не всегда возможно, так как библиотеки могут быть для Вас неподконтрольны.

    Отсутствие концепции ресурсов в Qt решает все вышеперечисленные проблемы. Qt предлагает небольшой сценарий, позволяющий включать изображения в Ваш код. А для создаваемого интерфейса Qt Designer генерит читаемый код.

    MFC SDK Вы получаете бесплатно при покупке Visual Studio.

    UNIX-версия Qt свободна (доступна по лицензии GPL) для разработки свободного программного обеспечения. Также доступна некоммерческая версия для платформы Windows. Но для разработки коммерческого программного обеспечения Вы должны приобрести лицензию Qt. Лицензируется в отдельности каждая платформа (Unix, MacOS или Windows) и каждый разработчик. Лицензия приобретается раз и навсегда и включает в себя один год технической поддержки. Выплаты за распространение runtime-библиотеки отсутствуют. Цена составляет 1550 $, что очень дорого для небольшой компании. При покупке более одной лицензии предлагаются скидки. Заметьте, что цена меньше затрат двухнедельного содержания разработчика. Инвестиции стоят того.

    Распространение

    При распространении приложения, созданного с помощью MFC, Вы можете положиться на MFC-библиотеку, поставляемую вместе с Windows. Но это небезопасно. Под одним и тем же названием, MFC42.DLL, могут скрываться три различные версии этой библиотеки. Поэтому нужно убедиться, что пользователь имеет необходимую версию библиотеки, и, в противном случае, ее обновить. Обновление библиотеки MFC может повлиять на работу многих приложений. Это недостаточно удобно. Что, если после установки моей программы компьютер перестанет работать?

    Названия библиотек Qt недвусмысленны ( qt-mt303.dll ), поэтому нет никакого риска, что установка библиотеки qt-mt303.dll повлияет на работу приложения, использующего, скажем, qt-203.dll. Также отсутствует проблема обновления системы в целом.

    Другие преимущества Qt

    Инструментарий Qt обладает не только функциональностью MFC, доступной более простым путем, но и многими возможностями, не имеющими аналогов в MFC:


    • Элементы управления: Qt — это графический инструментарий, предлагающий богатый набор графических элементов управления: текстовые поля, раскрывающиеся списки, кнопки-переключатели, . Некоторые из них очень сложны. Например, список (listview) обладает возможностью многоколоночного представления с пиктограммами и кнопками-переключателями.
    • XML: Qt предлагает классы для работы с документами XML ( используется Sax2 или Dom ). Это простая, надежная и функциональная реализация.
    • Регулярные выражения: Qt предлагает полную поддержку для Perl-совместимых регулярных выражений. Это дальнейшее развитие простых метасимволов `?` и `*`. Регулярные выражения — это очень мощный инструмент для анализа данных, поиска образцов внутри документа, создания фильтров, определения маски для полей ввода.
    • Много-платформенность: Qt 3 доступна для Windows (любой версии), Unix (любой версии), MacOS X и встроенных устройств. Для запуска Вашего приложения на другой платформе Вам достаточно его лишь перекомпилировать. Если компилятор не имеет каких-либо особенностей или ограничений, Вам не нужно прикасаться к Вашему коду.
    • Классы шаблонов: Qt предлагает полезные классы для манипулирования списками, файлами, каталогами, строками, потоками, . Они более функциональны и удобны, чем аналогичные из STL и MFC.
    • Управление памятью: Qt обладает различными средствами, упрощающими управление памятью. Объекты Qt автоматически уничтожаются при уничтожении их родителя. Многие классы обладают возможностью неявного совместного использования, которая освобождает Вас от забот по уничтожению и копированию этих объектов.
    • Сетевой API: Qt предоставляет классы, облегчающие написание сетевых приложений: сокеты, DNS, FTP, HTTP, .
    • API баз данных: Qt предоставляет классы для работы с базами данных: специальные виджеты, подключения к базам данных, SQL-запросы, .
    • OpenGL API: Qt предлагает классы для работы с библиотекой OpenGL.
    • Двухмерная графика ( Canvas ) : Qt предлагает классы, оптимизированные для обработки быстро перемещающихся двухмерных объектов, известных как спрайты.
    • Стили: Можно полностью настроить внешний вид элементов управления. Qt может эмулировать стили всех известных инструментариев: Motiff, MFC, NextStep, .

    Что такое CodeJock ?

    Многочисленные недостатки MFC явились причиной возникновения различных MFC-оберток, которые помогают легко создавать приложения. Мы использовали библиотеку CodeJock. Как CodeJock + MFC сравнится с Qt ?

    • CodeJock — это обертка для библиотеки MFC, которая, в свою очередь, является оберткой для API Windows. Добавление большего количества оберток для скрытия проблем обычно не является хорошим решением. Все вышеперечисленные проблемы все еще существуют ( ресурсы, шаблоны, сообщения, уникод, интернационализация, . )
    • Классы, предлагаемые библиотекой CodeJock, позволяют более легко использовать MFC ( за счет дополнительных возможностей, упрощенных методов или их большего количества). Например, с ее помощью можно создать элемент управления Multi-Tab View, в то время как с MFC это принципиально невозможно. Однако библиотека весьма ограничена. Она предлагает чуть больше классов, чем MFC, а не полный набор. CodeJock больше напоминает набор исправлений, а не обертку.
    • Качество библиотеки оставляет желать лучшего. Много ошибок не исправлено, добавлены новые. На протяжении первых 6 месяцев 2002 года было выпущено 3 версии ( 1.9.2.1, 1.9.2.2, 1.9.3.0 ), в каждой из которых исправлено более 50 ошибок. Библиотека не отлажена и не протестирована. Это не инструмент профессионального качества. Ее пользователи — это альфа-тестеры. Заметьте также, что API библиотеки меняется от версии к версии, поэтому Вы должны будете изменять свой код. Это признаки плохого дизайна.
    • Чтение кода ( к сожалению, неизбежное для CodeJock, учитывая ее временами странное поведение ) раскрывает ужасную картину: методы более чем на 500 строк, избыточный код, множество переходов в середину из ниоткуда, отсутствие комментариев, различные уловки. Многочисленные методы классов объявлены общедоступными, тогда как должны быть защищенными и т.д.
    • Документация бедна, а в некоторых местах и вовсе пуста ( методы присутствуют без каких-либо объяснений ). Похоже, что на протяжении последних выпусков она не обновлялась.
    • CodeJock не обладает возможностями, которые нельзя было бы найти в Qt. Исключением является шестнадцатеричный редактор, который к сожалению имеет множество ошибок, и который Вы легко можете сделать в Qt ( примеры уже существуют ).

    У Qt отличное качество кода. Библиотека надежна и устойчива. С целью ее значительного улучшения на протяжении последних 6 лет исходная и двоичная совместимости были лишь дважды нарушены. И только один раз ( при переходе от Qt1 к Qt2 ) требовалась существенная переделка кода.

    Вывод

    Вывод, следующий из полученного нами опыта, очевиден. Qt намного лучше MFC. Вы создаете программы лучше и быстрее.

    Некоторые люди жаловались, что эта статья снисходительна к Qt и не раскрывает всех возможностей MFC. Просто это наш опыт: мы имели множество проблем с MFC, и почти не имели их с Qt. Разработка с помощью Qt всегда была простой, документированной и эффективной. Если MFC и имеет преимущества, то мы их не нашли, за исключением бесплатной поставки вместе с Visual Studio.

    Мы доступны для обратной связи: пишите нам для предложений, усовершенствований, замечаний и флейма !

    Я хотел бы включить замечания людей, использовавших MFC и Qt. Если Вы к ним относитесь, напишите мне, пожалуйста.

    Исправляем сбой в mfc120u.dll

    Ошибки динамических библиотек, увы, не редкость даже на новейших версиях Windows. Одни из наиболее частых — неполадки с компонентами пакета Microsoft Visual C++ вроде библиотеки mfc120u.dll. Наиболее часто подобный сбой появляется при запуске графического редактора Corel Draw x8 на новейших версиях Windows, начиная с «Семерки».

    Методы решения проблемы с mfc120u.dll

    Как и многие другие DLL-ошибки, связанные с библиотеками Майкрософт Вижуал Си++, проблемы с mfc120u.dll решаются установкой новейшей версии соответствующего дистрибутива. Если по каким-то причинам подобный способ для вас бесполезен, можно загрузить и установить недостающую DLL отдельно с помощью специального ПО или ручным способом.

    Способ 1: DLL-Files.com Client

    Программа ДЛЛ-Файлс.ком Клиент — одна из самых дружелюбных в отношение пользователя, предназначенная для исправления многочисленных неполадок с библиотеками. Поможет она разобраться и со сбоем в mfc120u.dll.

    1. Откройте программу. Найдите строку поиска в главном окне. Впишите в нее имя искомого файла mfc120u.dll и нажмите кнопку «Выполнить поиск DLL-файла».

    Когда приложение отобразит результаты, нажимайте на имя найденного файла.

    Проверьте подробные сведения о библиотеке, затем нажимайте «Установить» для начала загрузки и инсталляции mfc120u.dll в систему.

    По окончании этого процесса рекомендуем перезагрузить компьютер. После загрузки системы ошибка больше не возникнет.

    Способ 2: Установка пакета Microsoft Visual C++

    Динамические библиотеки, входящие в этот дистрибутив, как правило, устанавливаются вместе с системой или приложениями, для работы которых и необходимы. В ряде случаев этого не происходит, и пакет нужно скачать и установить самостоятельно.

      Запустите инсталлятор. Прочитайте и примите лицензионное соглашение для возможности установки.

    Для начала процесса инсталляции нужно нажать «Установить».
    Подождите около 2-3 минут, пока будут загружены необходимые файлы и проведена установка дистрибутива на компьютер.

  • По завершении процесса инсталляции закрывайте окно нажатием на соответствующую кнопку и перезагружайте ПК.
  • Если во время установки не произошло никаких сбоев, можете быть уверены — вы избавились от неполадки в mfc120u.dll.

    Способ 3: Ручная установка файла mfc120u.dll

    Пользователям, которым недоступны Способы 1 и 2, мы можем предложить альтернативный вариант решения проблемы. Он заключается в загрузке недостающей DLL на жесткий диск и дальнейшем перемещении скачанного файла в каталог C:\Windows\System32 .

    Обратите внимание — если вы используете x64-версию ОС от Майкрософт, то адрес будет уже C:\Windows\SysWOW64 . Есть и несколько других не самых очевидных подводных камней, так что перед началом выполнения всех процедур вам стоит ознакомиться с руководством по установке динамических библиотек.

    Скорее всего, вам также потребуется провести дополнительную манипуляцию — регистрацию DLL. Это действие необходимо для распознавания компонента — иначе ОС не сможет взять его в работу. С подробной инструкцией можно ознакомиться в этой статье.

    Отблагодарите автора, поделитесь статьей в социальных сетях.

    Проблемы с потоком MFC

    У меня есть CDialog, который позволяет пользователям перемещаться, перечислять и показывать предварительный просмотр файлов на жестком диске. В некоторых случаях может быть много тяжелых файлов, и для этих случаев требуется много времени, поэтому мы переместили операции загрузки в отдельный поток.

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

    Цукерберг рекомендует:  Адаптивный дизайн - В чем разница между отзывчивый дизайн и адаптивный
    Понравилась статья? Поделиться с друзьями:
    Все языки программирования для начинающих