Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Про CString и CMenu

5.7K
15 октября 2004 года
Andrdandr
29 / / 17.09.2004
Два вопроса:
1) Можно ли изменять отдельные символы в строке типа CString? Такой вариант как
CString s = "abcdef";
s[1] = "r"; // Error:left operand must be l-value
не проходит.

2) у меня в для диалогового приложения используются классы:
CMyApp: public CWinApp
CMyDlg: public CWnd
CPage1: public CPropertyPage
CPage2: public CPropertyPage
CPropertySheet

В главном окне есть меню:
... CMyDlg::OnInitDialog()
{
...
CMenu menu;
menu.LoadMenu(IDR_MENU1);
this->SetMenu(&menu);
menu.Detach();
...
}
Вопрос: можно ли сообщения меню обрабатывать классами CPage1 и CPage2, как? Волшебник добавляет, все компилицццца, но код обработчика никогда не вызывается. Есть мнение,что это из-за того,что клас меню объявлен в CMyDlg.
527
16 октября 2004 года
pavor
275 / / 28.09.2003
Цитата:
Originally posted by Andrdandr
Два вопроса:
1) Можно ли изменять отдельные символы в строке типа CString? Такой вариант как
CString s = "abcdef";
s[1] = "r"; // Error:left operand must be l-value
не проходит.

2) у меня в для диалогового приложения используются классы:
CMyApp: public CWinApp
CMyDlg: public CWnd
CPage1: public CPropertyPage
CPage2: public CPropertyPage
CPropertySheet

В главном окне есть меню:
... CMyDlg::OnInitDialog()
{
...
CMenu menu;
menu.LoadMenu(IDR_MENU1);
this->SetMenu(&menu);
menu.Detach();
...
}
Вопрос: можно ли сообщения меню обрабатывать классами CPage1 и CPage2, как? Волшебник добавляет, все компилицццца, но код обработчика никогда не вызывается. Есть мнение,что это из-за того,что клас меню объявлен в CMyDlg.


Исправь ковычки двойные на одинарные у символа!
Насчет сообщений - попробуй вызывать нужные функции непосредственно и диалога или пересылать сообщения

430
16 октября 2004 года
craftyfox
157 / / 20.02.2000
Цитата:
Originally posted by pavor

Исправь ковычки двойные на одинарные у символа!


Это вообще-то уже другая ошибка.
В CString определен оператор LPCTSTR(), но преобразования по умолчанию к неконстантному char* (TCHAR*) нет, поэтому:

Compiler Error C2166
l-value specifies const object

An attempt was made to modify an item declared with const type.


для этих целей есть GetBuffer()(всего 5 "buffer access functions"), т.е. можно

(s.GetBuffer(s.GetLength()))[1]='r';

пройдет и
((char*)((LPCTSTR)s))[1] = 'r';
но тут есть подводные камни,

например:

 
Код:
CString s = "ага";
CString s1=s;
((char*)((LPCTSTR)s))[0] = 'я';
(s.GetBuffer(s.GetLength()))[1]='м';


чему равно теперь s и s1?
430
16 октября 2004 года
craftyfox
157 / / 20.02.2000
Цитата:
Originally posted by craftyfox

(s.GetBuffer(s.GetLength()))[1]='r';


Полагаться на то, что GetBuffer вернет не ноль
тоже нельзя (на всякий случай).

430
16 октября 2004 года
craftyfox
157 / / 20.02.2000
в CString, кстати, есть для символов функции
GetAt и SetAt
3
16 октября 2004 года
Green
4.8K / / 20.01.2000
Цитата:
Originally posted by craftyfox

Это вообще-то уже другая ошибка.
В CString определен оператор LPCTSTR(), но преобразования по умолчанию к неконстантному char* (TCHAR*) нет, поэтому:

Compiler Error C2166
l-value specifies const object

An attempt was made to modify an item declared with const type.


для этих целей есть GetBuffer()(всего 5 "buffer access functions"), т.е. можно

(s.GetBuffer(s.GetLength()))[1]='r';

пройдет и
((char*)((LPCTSTR)s))[1] = 'r';
но тут есть подводные камни,

например:
 
Код:
CString s = "ага";
CString s1=s;
((char*)((LPCTSTR)s))[0] = 'я';
(s.GetBuffer(s.GetLength()))[1]='м';


чему равно теперь s и s1?


И правильно, что нет неявного приведения к неконстантному типу.
В записи
((char*)((LPCTSTR)s))[1] = 'r';
кроется не просто подводный камень, а большой риф.
А все из-за смешивания стилей С и С++ (привет pavor) :)
Если записать эту строку по правилам С++, то все становится явным:
(const_cast<char*>( static_cast<LPCTSTR>(s) ))[1] = 'r';

Конечно, лучше использовать GetAt/SetAt и GetBuffer.
После GetBuffer нужно вызвать ReleaseBuffer:

 
Код:
If you use the pointer returned by GetBuffer to change the string contents, you must call ReleaseBuffer before using any other CString member functions.
527
16 октября 2004 года
pavor
275 / / 28.09.2003
Цитата:
Originally posted by Green

И правильно, что нет неявного приведения к неконстантному типу.
В записи
((char*)((LPCTSTR)s))[1] = 'r';
кроется не просто подводный камень, а большой риф.
А все из-за смешивания стилей С и С++ (привет pavor) :)
Если записать эту строку по правилам С++, то все становится явным:
(const_cast<char*>( static_cast<LPCTSTR>(s) ))[1] = 'r';

Конечно, лучше использовать GetAt/SetAt и GetBuffer.
После GetBuffer нужно вызвать ReleaseBuffer:
 
Код:
If you use the pointer returned by GetBuffer to change the string contents, you must call ReleaseBuffer before using any other CString member functions.


А интересно кстати, почему не сделали
XCHAR &operator[](int i);
const XCHAR &operator(int i) const;
а сделали
XCHAR operator[](int i);
Непонятки. с std::string все нормально.

430
16 октября 2004 года
craftyfox
157 / / 20.02.2000
Цитата:
Originally posted by Green

Если записать эту строку по правилам С++, то все становится явным:
(const_cast<char*>( static_cast<LPCTSTR>(s) ))[1] = 'r';
[/CODE]



Нет не все.От того камушка, что в примере, это не спасает.
Под "рифом" ты имел ввиду указатель "неизвестно куда" - я правильно понял?
И такой момент. Что дает static_cast? - ведь оператор определен в классе и как бы ни был он реализован, он заведомо вернет "нужный тип", т.е.
никаких ошибок компиляции не будет?
Ваще, конечно, не стоило разбирать такие способы - на то он и const,чтоб не быть l-value,и на то он и класс, чтобы вызывать методы, тем более, не так уж много в MFC по настоящему удобных для использования классов...

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог