LANGUAGE 25, 1
#pragma code_page(1251)
После этого проект можно собирать.
В статье из KB сказано, что в том же меню "View" – "Resource Includes" можно указать измененные маршруты заголовочных файлов, например, #include "l.rus/afxprint.rc" вместо #include "afxprint.rc". Вероятно, если это сделать, отпадет необходимость в указании маршрута каталога с русифицированными ресурсами на вкладке "Resources" свойств проекта. Кроме того, в той же статье рекомендуется с помощью редактора ресурсов удалить из раздела "String Table" все неспецифичные для конкретного приложения строки, сгенерериванные AppWizard. Полагаю, это можно не делать. В крайнем случае, на необходимость такой операции укажет компилятор.
Таким образом, нужно один раз перевести на русский язык содержимое нескольких файлов ресурсов, а затем лишь указывать в проектах нужный язык и маршрут каталога с русифицированными файлами.
Андрей Шуклин
Большое спасибо, Андрей.
Это все на сегодня. Пока!
Алекс Jenter jenter@rsdn.ru Красноярск, 2001. Рассылка является частью проекта RSDN.
Программирование на Visual C++
Выпуск №46 от 27 мая 2001 г.
Приветствую вас, уважаемые подписчики!
Мой коллега Александр Шаргин решил присоединиться к дисскуссии по поводу свойств в C++:
ОБРАТНАЯ СВЯЗЬ
Свойства "в стиле VB" невозможно заменить перегрузкой оператора присваивания и приведения типа. Если в классе содержится 10 свойств типа int, мы неизбежно заходим в тупик. Что касается полезности этой концепции, она признана многими разработчиками компонентно-ориентированных средств разработки (кроме VB есть Delphi и BCB, в которые свойства вводились отнюдь не только для поддержки COM, свойства есть в новом языке C# от Микрософт и т. д.). Конечно, свойства – не революция. Вместо них можно использовать пару методов Set/Get. Но они делают смысл происходящего в программе понятнее:
wnd.style |= WS_VISIBLE;
вместо
wnd.SetStyle(wnd.GetStyle() | WS_VISIBLE);
Кроме того, они развивают концепцию сокрытия деталей реализации от пользователя класса: для него свойство выглядит как обычная переменная-член, и он даже не догадывается, что для её реализации используются функции. Не секрет, что многие программисты не любят методы Set/Get и продолжают использовать открытые члены, несмотря на все призывы Страуструпа и иже с ним. Даже в книгах по программированию этот "неправильный" подход встречается сплошь и рядом. Свойства позволяют найти компромисс между этим чисто человеческим нежеланием и важными принципами ООП. В выигрыше оказываются все.
Что касается реализации свойств с C++, здесь перед нами встают проблемы. Если вопрос портирования прграммы для нас не актуален, и мы ограничиваемся VC, я не вижу смысла игнорировать его расширенные возможности. Использование deсlspec(property) в этом случае является исключительно делом вкуса программиста. Принципиальных возражений против его использования нет.
А вот "самодельные" свойства приносят в жертву эффективность программы, и поэтому мы должны или отказаться от них, или улучшить, убрав лишние затраты. Вот пример возможного улучшения.
#include
//***************************
// Макрос для свойства
#define PROPERTY(ownertype, proptype, prop, getfunc, setfunc) \
class class __property##prop \
{ \
public: \
operator proptype() \
{ \
return ((ownertype*)((char*)this - offsetof(ownertype, prop)))->getfunc(); \
} \
void operator=(proptype data) \
{ \
((ownertype*)((char*)this - offsetof(ownertype, prop)))->setfunc(data); \
} \
}; \
friend __property##prop; \
__property##prop prop
//***************************
// Пример использования
class CValue {
private:
char m_value;
public:
int get_Value() {
return m_value; // Или более сложная логика
}
void put_Value(int value) {
m_value = value; // Или более сложная логика
}
// Свойство Value типа int, использующее функции
// get_Value и put_Value класса CValue
PROPERTY(CValue, int, Value, get_Value, put_Value);
};
int main(int argc, char* argv[]) {
CValue val;
/* Здесь вызывается оператор присваивания переменной-члена val.Value,
и, следовательно, функция val.put_Value() */
val.Value = 50;
/* Здесь вызывается оператор приведения типа переменной-члена val.Value,
и, следовательно, функция val.get_Value() */
int z = val.Value;
return 0;
}
В этом случае ликвидируются как временные затраты (все функции класса property##prop являются встроенными), так и затраты по памяти (к сожалению, только теоретически, так как VC "не умеет" создавать объекты класса нулевой длины). Кроме того, следует заметить, что полученное свойство не является полным эквивалентом declspec. Например, нельзя написать
Читать дальше