Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Как создать кнопку на форме по клику на другой кнопке?  (Прочитано 16690 раз)
0 Пользователей и 1 Гость смотрят эту тему.
beginner_in_C++
Гость
« : 01-07-2006 11:33 » 


Люди! Осваиваю VC++6.0....
У меня такой вопрос,  пишу(пытаюсь) SDI приложение, в котором по FILE->New  открывается PropertySheet из пяти закладок, на второй закладке пытаюсь по ::On_Ok() создать на этой же закладке кнопку, самую обычную, идентификатор - 108 - предварительно забил в таблицу ресурсов...вылетаю с ошибкой(отправить отчет...) что я делаю не так? Вот обработчик:

void CMyPropertyPage2::OnOK()
{
   CRect rect;
   GetClientRect(&rect);      
   
   CMyPropertyPage2* pCpp2;
   CButton   But1;
   rect.OffsetRect(50,50);
   But1.Create(NULL,BS_PUSHBUTTON, rect,pCpp2,108);
   //CPropertyPage::OnOK();
}
Записан
Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #1 : 01-07-2006 17:04 » 

Код:
 CMyPropertyPage2* pCpp2;
Ты только создал ссылку на структуру, но не саму структуру. В But1.Create ты подсовываеш ссылку на не сушествуюшую структуру. Вот и у тебя вылетает ошибка вылета за пределы допустимой памяти.
Записан

Не будите спашяго дракона.
             Джаффар (Коша)
beginner_in_C++
Гость
« Ответ #2 : 01-07-2006 17:43 » 

Так определена функция в файле  AFXWIN.H:

BOOL Create(LPCTSTR lpszCaption, DWORD dwStyle,const RECT& rect, CWnd* pParentWnd, UINT nID);
4-й параметр - указатель на класс производный от CWnd, а не "структура кнопки"(!), структура вкладки определена и вкладка нормально создается в процессе работы приложения, а вообще если знаешь то научи,а?
Записан
Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #3 : 01-07-2006 18:37 » 

beginner_in_C++, Тебе нужно давать ссылку на родительский объект. Я в MFC не силен. Но так понял, что ты создаеш компонент из дочернего компонента. У этого компонента должно быть свойство-ссылка на родительский компонент. По логике должен называться по типу Parent. Поиши в хелпе как точно называется. И подставляй в 4 параметр данные из свойства.
Записан

Не будите спашяго дракона.
             Джаффар (Коша)
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #4 : 02-07-2006 08:05 » 

попробуй так

void CMyPropertyPage2::OnOK()
{
   RECT rect={0,0,50,100};
   CButton   But1;
   rect.OffsetRect(50,50);
   But1.Create(NULL,BS_PUSHBUTTON, rect, this ,108);
   //CPropertyPage::OnOK();
}
Записан

beginner_in_C++
Гость
« Ответ #5 : 03-07-2006 06:44 » 

Не работает.
Может есть у кого рабочий пример создания контрола (любого, не обязательно кнопки) по обработке сообщения от другого контрола, но не отображения созданного заранее в коде, и не активации "серого", а с выделением памяти в процессе работы, назначением нового не используемого ID,так сказать динамического создания?
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #6 : 03-07-2006 14:59 » 

beginner_in_C++, ты не все свойства задаёшь.

(WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON) - как минимум надо


если WS_VISIBLE не указывать - то невидимая будет
« Последнее редактирование: 03-07-2006 15:02 от Алексей1153 » Записан

Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #7 : 03-07-2006 16:11 » 

Ууууу как всё запущено. Ага

Не работает.

Нууу дык, надо внимательно не торопясь разобраться и всё заработает.

Давай разбираться:

2. Параметр CWnd* pParentWnd указывает на то, что окну надо передать указатель на  родительский объект. А не просто какой-нибудь указатель. (Finch сказал, что надо делать, а Лёшка тебе показал как именно передаётся указатель на родительское окно в подобных случаях - указатель this)

3. Обычно для оконных объектов используются темплейты ресурсов. Если их нет, то необходимо детально указывать все необходимые стили. (то про что Лёшка сказал)

4.  Но не главное - ты хочешь сделать кнопку размером с диалог? Ведь именно это ты и делаешь. Лучше использовать какой-нибудь более разумный алгоритм.

А вот это САМОЕ ГЛАВНОЕ:

1. Всё, что ты хочешь сделать - исчезнет сразу же, не успев зародится. Вот в этом месте.
Код:
}
Перменная  But1 у тебя локальная, создаёшь ты её в стеке, следовательно объект будет уничтожен сразу же после выхода их ф-ции. Так что сначала определись, что именно ты хочешь сделать. Кстати от VS 6 или  MFC это не зависит - в любом компиляторе будет так. Тут уж ничего не поделаешь.



Итак правильное решение.
Код:
{
CRect rect(0,0,100,30); // сделаем кнопочку размером 100 на 30
rect.OffsetRect(50,50);
CButton   *pBut1 = new CButton();
pBut1->Create(_T("My Button"), WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON, rect, this, 108);
}

И любуйся своей кнопочкой Ага

Конечно будет происходить утечка памяти, если не принять меры (например сделать указатель-член и удалять объект в деструкторе). Но окончательное решение зависит от концепции.
« Последнее редактирование: 03-07-2006 16:16 от Джон » Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
beginner_in_C++
Гость
« Ответ #8 : 04-07-2006 10:04 » 

"Ууууу как всё запущено." Блин, ребят, спасибо огромное - "приласкали"!!! Яж грю, я не волшебник, я еще учусь...Интуитивно понимаю что надо резервировать память под объект, уж коли он runtime, просто не хватает навыков на С++, хотя про свойства мог бы и доехать, щас еще книгу купил, читать буду, спасибо за фрагмент, буду изучать, и тогда чтоб окончательно прояснить ситуацию по этому вопросу: хочу создать на диалоге N объектов, не обязательно кнопок, ну по старинке циклом от 1 до Б, причем Б, будет определено по ходу работы риложения, как контролировать чтоб ID-шники создаваемых контролов не пересеклись с уже созданными, и что будет если они совпадут? и вопрос 2 - уничтожаю объект с ID - 28, после delete ID-шник 28 - свободен?
Записан
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #9 : 04-07-2006 11:29 » 

Нуууу вообще-то "запущено" относилось ко всем, а не только к тебе. Ведь дело не в MFC, Borland, окнах и тд. Попытка доступа к объекту, который будет уничтожен при выходе их ф-ции, понимаешь. Это можно сказать азы - область видимости, глобальные и локальные переменные.

щас еще книгу купил, читать буду

Вот это правильно, это всегда приветствуется. Именно с этого и надо начинать. А вот когда после прочтения вопросы появятся - милости просим.

Цитата
спасибо за фрагмент, буду изучать

Дык, да я ж написал то же, что и ты. Практически...

Цитата
как контролировать чтоб ID-шники создаваемых контролов не пересеклись с уже созданными, и что будет если они совпадут? и вопрос 2 - уничтожаю объект с ID - 28, после delete ID-шник 28 - свободен?

Если ты хочешь просто создать контролы, то ID практического значения не имеет. Ты можешь их всех сделать с одним ID. Проблемы возникнут при доступе к этим контролам и при получении сообщений от них. Тогда тебе нужно однозначно идентифицировать контролл, чтобы от кого пришло сообщение, захотел пользователь изментиь данные о своём росте, или весе? Причём у тебя в программе может быть куча контроллов с одинаковым ID главное, чтобы они не находились на одной (ненавижу это слово) форме, диалоге. Например кнопка IDOK, имеет всегда один ID, но на каждом диалоге есть только одна.
Для использования одновременно имеет смысл создать массив идентификаторов. Насчёт "безразмерности" - тут могут быть проблемы с картой сообщений. Есть конечно макросы типа ON RANGE, но всё-равно надо задавать граничные условия. Но принципиально это возможно, всё зависит от концепции, или другими словвами - как ты собираешься эти контроллы использовать.

2. Собственно из выше сказанного - ID не может быть занятым, или свободным. Использовать можно многократно при соблюдении выше указанных условий.

зы У нас Лёшка большой специалист по многочисленным контроллам, недавно даже что-то было по этому поводу. Поищи.
« Последнее редактирование: 04-07-2006 11:31 от Джон » Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
beginner_in_C++
Гость
« Ответ #10 : 04-07-2006 12:36 » 

respect, буду осмысливать...
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #11 : 04-07-2006 16:18 » new

ой, меня специалистом обозвали Улыбаюсь

Кстати, карта сообщений не потребуется
« Последнее редактирование: 04-07-2006 16:22 от Алексей1153 » Записан

Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines