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

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: 1 2 3 [Все]   Вниз
  Печать  
Автор Тема: доступ к элементам меню  (Прочитано 54931 раз)
0 Пользователей и 1 Гость смотрят эту тему.
Алексей++
глобальный и пушистый
Глобальный модератор

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


« : 29-12-2003 11:13 » 

всем привет

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

void CX::OnBn(CCmdUI* pCmdUI)
{
   pCmdUI->Enable(true);
}

- как по ID сделать указатель на CCmdUI , чтобы из любого места программы можно было
   pCmdUI->Enable(true);
Записан

Mouse
Молодой специалист

ru
Offline Offline

« Ответ #1 : 29-12-2003 11:28 » 

Попробуй так:

CCmdUI *pCmdUI = GetDlgItem(IDC_MYMENUITEM);

Сразу говорю - сам не пробовал, но на простых элементах управления работает.
Записан
Lex
Специалист

ru
Offline Offline

WWW
« Ответ #2 : 29-12-2003 11:31 » 

Алексей1153, никак.

pCmdUI сождается в строго определенные моменты. Сейчас не вспомню, но кажется когда входишь или выходишь из меню, ну и при входе в Idle.
Чтобы управлять из любого места с CFrameWnd есть m_bAutoMenuEnable.
(которое по идее дизаблет меню, в которых нет обработчиков и еще и включает этот механижм OnUpdate...)/ Если его поставить в false, то можно бутет нормально работать через GetMenu() и т.д.
Записан

Megabyte be with you!
Алексей++
глобальный и пушистый
Глобальный модератор

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


« Ответ #3 : 29-12-2003 17:46 » 

Цитата

CCmdUI *pCmdUI = GetDlgItem(IDC_MYMENUITEM);


так я тоже пробовал - выгоняют  Улыбаюсь

Lex, сейчас попробую.

вот ещё вопрос: вставляя в деструктор вызов exit - чего при этом происходит?
я натолкнулся на эту функцию почти наобум, но она решает некоторые проблемы при выходе из проги в неподходящие для этого моменты. Нехороших последствий не заметил - но может я что-то пропустил?

CUnBin1alfView::~CUnBin1alfView()
{
exit(0);
}
Записан

Гром
Птычк. Тьфу, птычник... Вот!
Готовлюсь к пенсии

il
Offline Offline
Пол: Мужской
Бодрый птах


« Ответ #4 : 29-12-2003 18:22 » 

Алексей1153, напиши что именно надо сделать и под чем - если MFC то работа одна - если АПИ - то другая...
Записан

А птичку нашу прошу не обижать!!!
Алексей++
глобальный и пушистый
Глобальный модератор

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


« Ответ #5 : 29-12-2003 18:50 » 

:arrow: MFC

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

 :arrow: насчёт exit

Код:
bool m_bCycling; 
//постоянное чтение из порта и вывод данных на экран
void CUnBin1alfView::MakeReading()
{
//m_bCycling - флаг разрешения выполнения чтения из порта
//переключается чеком на форме
   MSG message;
   while(m_bPortOpened)
   {
      if(m_bCycling)
      {
//читать из порта в буфер приёма
      }
      //выполняем сообщение Windows
      //там m_bCycling и m_bPortOpened могут измениться
      if(::PeekMessage(&message,NULL,0,0,PM_REMOVE))
      {
         ::TranslateMessage(&message);
         ::DispatchMessage(&message);
      }
       
   }
}

CUnBin1alfView::~CUnBin1alfView()
{
ClosePort();
//exit(0);
}


так вот, когда порт открыт и идёт выполнение этой функции, то при нажатии на крестик окна (== alt+F4) прога вроде зарывается, но остаётся в списке процессов. Если опять запустить и закрыть, то в списке будет уже две - и.т., ппока не придёт Окнам ...  Улыбаюсь

 :arrow: вообще задача такая - постоянно читать из сом-порта, и когда появляются данные - печатать их на экран. Причём есть желание чеком приостанавливать вывод на эк и продолжать его дальше. Как читать из порта я знаю, а вот как организовать цикл без ущерба для здоровья?
« Последнее редактирование: 23-11-2007 17:32 от Алексей1153++ » Записан

Anonymous
Гость
« Ответ #6 : 29-12-2003 22:02 » 

Лёха, а функция OnUpdate тебя не устроит?

ON_UPDATE_COMMAND_UI(ID_MY_MENUE_PUNKT, OnUpdateMyMenuePunkt)

void CMainFrame::OnUpdateMyMenuePunkt(CCmdUI* pCmdUI)
{
   pCmdUI->Enable( TRUE или FALSE );
}

Джон
Записан
Anonymous
Гость
« Ответ #7 : 29-12-2003 22:15 » 

А про СОМ посмотри пример MTTTY в MSDN. (просто задай в строке поиска) - самый полный пример работы с СОМмом.

Semper fidelis
Боец невидимого фронта
Джон
Записан
Гром
Птычк. Тьфу, птычник... Вот!
Готовлюсь к пенсии

il
Offline Offline
Пол: Мужской
Бодрый птах


« Ответ #8 : 29-12-2003 23:01 » 

1. Непонятно, как устроена функция ClosePort. Тут проблема с тем, что Хендл - который ты имеешь от CreateFile может быть недоступен в деструкторе.
Отсюда проблема выхода - висимс.

Вызывай ClosePort в OnClose()

2. Если нужен постоянный ввод с порта - не вешай все в поток окна, открой еще один и в нем читай из порта - перебрасывая данные по байтно в основное окно например с помощью буфера обмена, и все.

Тогда управление окном не будет пересекаться с работой четния.
См. статью Работа с СОМ портом на сайте - статья моя - надо - передам части кода.

3. При выводе на экран ты не будешь никогда зависить от СОМ порта, тут как раз и появляется проблема когда ты в одном потоке со всеми сообщениями Винды сидишь и отсюда подвисы.
Работая в разных потоках, чтению будет до лампочки, что ты с его данными потом делаешь , стираешь или на экран выводишь.

4. С меню можно работать просто.

GetMenu() запускай в InitInstance() или в InitDialog в зависимости от типа апликации.  После этого у тебя будет объект наследуемый от CMenu - и ты даже можешь его сделать глобальным.
Тогда у тебя будет доступ.

У меня где - то был код но там есть функции Enable Disable так посмотри в описании CMenu

Примерный код такой

CMenu * pMenu = GetMenu();

ПыСы: Кстати - тот фрагмент с СОМ портом - к MFC не имеет никакого отношения в MFC цикл обработки спрятан - поясни.
Записан

А птичку нашу прошу не обижать!!!
Алексей++
глобальный и пушистый
Глобальный модератор

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


« Ответ #9 : 30-12-2003 21:12 » 

1)
пробую поставить ClosePort() в OnClose() без exit(0) в  деструкторе...
результат: если при открытом порте Alt+F4, то прога остаётся в списке процессов, и пока она там, порт не открывается вновь запущеной прогой.
Добавление  exit(0) в  деструктор лечит данный спецэффект... Да, о птичках, что такое эта функция - exit?

Упс... Что бы мы делали без кнопки RESET?

2)пробую с другим потоком...
Записан

Гром
Птычк. Тьфу, птычник... Вот!
Готовлюсь к пенсии

il
Offline Offline
Пол: Мужской
Бодрый птах


« Ответ #10 : 30-12-2003 22:04 » 

Алексей1153, функция ехит - тебе не нужна - в винде ты не выйдешь таким образом из программы Жаль
Это старый способ завершения колнсольных програм и до сих пор действенный в Никсах.

Собственно и в винде - если писать консоль.

ехит в деструкторе нонсенс.
Деструктор основного класса - лобального - вызывается в момент уничтожения объекта программы - т.е. при выходе ихз нее - уже начавшемся, а ты в нем еще раз выход вызываешь  Я шокирован!

2. Не попробуй - а сделай  Отлично  - много проблем снимешь.  :!:
Записан

А птичку нашу прошу не обижать!!!
Алексей++
глобальный и пушистый
Глобальный модератор

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


« Ответ #11 : 30-12-2003 22:07 » 

Код:
//конструктор
CUnBin1alfView::CUnBin1alfView():CFormView(CUnBin1alfView::IDD)
{
...
//запускаем поток для чтения из порта
pThreadToReadData=AfxBeginThread(ReadingFromPort,GetSafeHwnd(),
                         THREAD_PRIORITY_NORMAL);
}

//поток, читающий данные из порта
UINT ReadingFromPort(LPVOID lpttt)
{
//пока не делаем ничего
return 0;
}

при компиляции:
(на строке pThreadToReadData=AfxBeginThread(...); )

error C2665: 'AfxBeginThread' : none of the 2 overloads can convert parameter 1 from type 'unsigned int (void *)'

как это сделать?
« Последнее редактирование: 23-11-2007 17:33 от Алексей1153++ » Записан

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

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


« Ответ #12 : 30-12-2003 22:38 » 

Джонни, спасибо, идею я поднял  Улыбаюсь
Код:
BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
//{{AFX_MSG_MAP(CMainFrame)
// NOTE - the ClassWizard will add and remove mapping macros here.
//    DO NOT EDIT what you see in these blocks of generated code !
ON_WM_CREATE()
ON_UPDATE_COMMAND_UI(ID_PORT_SETUP, OnUpdatePortSetupPunkt)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()

void CMainFrame::OnUpdatePortSetupPunkt(CCmdUI* pCmdUI)
{
pCmdUI->Enable(FALSE);
}



это работает - гасит пункт наглухо  Отлично

а вот теперь куча вопросов
1)это работает в MainFrame - так при кажном вызове OnUpdate будет вызываться?
2) если да, как передать туда нужный флаг(а не тольо FALSE, как в коде выше)? Как сделать глобальную переменную?
3) где лучше разместить
ON_UPDATE_COMMAND_UI(ID_PORT_SETUP, OnUpdatePortSetupPunkt)
- в скобках {{AFX_MSG_MAP}}AFX_MSG_MAP  или за ними?
Работает и там и там
« Последнее редактирование: 23-11-2007 17:34 от Алексей1153++ » Записан

Anonymous
Гость
« Ответ #13 : 31-12-2003 00:43 » 

1. Да, работает везде и всегда. OnUpdate это типа OnTimer.

2. А как хочешь. Только почему глобальную? хотя конечно можно и глобальную. Хоть функцию вызывай! Ага  напр.

pCmdUI->Enable(m_bMyFlag);
pCmdUI->Enable(g_bMyFlag);
pCmdUI->Enable(3>4);
pCmdUI->Enable(GetMyCOMPortCtrl()->IsOpen());

etc.

3.  Лучше в скобках Ага . Всё что находится в подобных скобках нужно  ТОЛЬКО студийному мастеру (wizard) классов MFC. Вообще-то я делаю это наоборот. Те сначала Ctrl+W. Потом выбираю ID менюшного пункта, а потом в окошке справа OnCommand, а под ней сразу OnUpdate. И мастер всё вставляет сам, на то он и мастер. Кстати такая же фигня прокатывает с тулбарными кнопками. Кроме .NET 2003. Там почему-то это не работает Жаль .

Semper fidelis
Боец невидимого фронта
Джон
Записан
Гром
Птычк. Тьфу, птычник... Вот!
Готовлюсь к пенсии

il
Offline Offline
Пол: Мужской
Бодрый птах


« Ответ #14 : 31-12-2003 08:08 » 

Цитата
при компиляции:
(на строке pThreadToReadData=AfxBeginThread(...); )

error C2665: 'AfxBeginThread' : none of the 2 overloads can convert parameter 1 from type 'unsigned int (void *)'

как это сделать?


Код:
UINT WINAPI ReadingFromPort(LPVOID lpttt) 
{
   //пока не делаем ничего
   return 0;
}
Вот так сделать.
« Последнее редактирование: 23-11-2007 17:35 от Алексей1153++ » Записан

А птичку нашу прошу не обижать!!!
Алексей++
глобальный и пушистый
Глобальный модератор

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


« Ответ #15 : 31-12-2003 11:20 » 

а в прототипе тоже "WINAPI" писать?

не могу запустить поток

CWinThreadpThreadToReadData=AfxBeginThread(ReadingFromPort,GetSafeHwnd(),THREAD_PRIORITY_NORMAL);

пишет

error C2665: 'AfxBeginThread' : none of the 2 overloads can convert parameter 1 from type 'unsigned int (void *)'   Ха-ха-ха
Записан

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

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


« Ответ #16 : 31-12-2003 14:13 » 

к предыдущим вопросам добавился ещё Улыбаюсь

мне нужно получить время в виде строки hh.mm.ss

1)делаю так
Код:
	
CString enter=(CString)(0x0d)+(CString)(0x0a);
_SYSTEMTIME CurrSysTime;
TIME_ZONE_INFORMATION TimeZoneInfo;

//определяем текущее время
::GetSystemTime(&CurrSysTime);
//форматируем
csTime.Format("%d.%d.%d",
CurrSysTime.wHour,
CurrSysTime.wMinute,
CurrSysTime.wSecond);
//выводим
((CEdit*)GetDlgItem(IDC_edREADDATA))->SetWindowText(csTime);

но здесь GetSystemTime() возвращает hour - Гринвича! Как сделать то время, что в трее?

2)форматирование - "%d.%d.%d" - гасит незначащие нули, как отучить?
(вместо "12.01.01" -->"12.1.1" )

3) как по-другому вставить ентер? (CString enter)
« Последнее редактирование: 23-11-2007 17:37 от Алексей1153++ » Записан

Anonymous
Гость
« Ответ #17 : 31-12-2003 16:51 » 

1.
   SYSTEMTIME lpst;
   ZeroMemory(&lpst,sizeof(lpst));
   GetLocalTime(&lpst);

2. sprintf(pszTime, "%s %d %s %d %02d:%02d:%02d"

3. "\r\n"

Sorry на больше времени нет. Лёха! Бросай всё! С Наступающим!

Semper fidelis
Боец невидимого фронта
Джон
Записан
kasper
Гость
« Ответ #18 : 01-01-2004 00:43 » 

Привет, друзья. Только - только начал изучать программирование, Вы уж извините за отсталость!
Цитата

С малолетства приходится побираться и попрошайничать! Поможите кто чем может

, за скудностью своей просим, извинить. А за худородство в двойне!! Земной поклон бьем, пожалейте сироток, пришлите советы "для чайников". А уж Мы в долгу не останемся!
e-mail: kasp7@msn.com
           Terechov_Terenti@mail.ru
Заранее благодарствуем, до свидания.
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

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


« Ответ #19 : 01-01-2004 18:52 » 

ВСЕХ С НОВЫМ ГОДОМ ОПЯТЬ!!!
ГРОМ, поток потёк  Улыбаюсь
Джончик, мне расслабляться сейчас не можно, нет времени. За время - спасибо, всё работает .
только "%s %d %s %d %02d:%02d:%02d" - зачем нужны
"%s %d %s %d ?

kasper, будем знакомы. Вливайся - сайт суперский. Научим чему сможем!
А какие советы? Поточнее бы.
Записан

Гром
Птычк. Тьфу, птычник... Вот!
Готовлюсь к пенсии

il
Offline Offline
Пол: Мужской
Бодрый птах


« Ответ #20 : 01-01-2004 19:07 » 

Алексей1153, обращайтесь - если что - ты кстати - не забудь синхронизацию на данные поставить Улыбаюсь
Записан

А птичку нашу прошу не обижать!!!
Алексей++
глобальный и пушистый
Глобальный модератор

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


« Ответ #21 : 01-01-2004 20:04 » 

Цитата

синхронизацию

Как это сделать?


ГРОМ,
 
Цитата

Алексей1153, обращайтесь

 - промахнулся что-ли?  Ага
Записан

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

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


« Ответ #22 : 02-01-2004 08:25 » 

Джон, как из MainFrame (то есть там, где вызывается OnUpdate) получить доступ к объекту View - чтобы узнать, зажечь или погасить-то пункт меню?

глобальную переменную тоже не могу сделать...
Записан

Anonymous
Гость
« Ответ #23 : 02-01-2004 18:59 » 

С Наступившим на нас всех! У меня печальные новости - разговаривал с шефом отпуск "продлили" ещё на неделю. Жаль

Алексей1153,  Задачка не простая, но решимая, если у тебя один View, то:
в любом месте проги:

   POSITION pos = theApp.GetFirstDocTemplatePosition();
   CDocTemplate *pDocTempl = theApp.GetNextDocTemplate(pos);
   pos = pDocTempl->GetFirstDocPosition();
   CТвойДокКласс *pDoc = (CТвойДокКласс*)(pDocTempl->GetNextDoc(pos));
   POSITION posView = pDoc->GetFirstViewPosition();
   CТвойВъюКласс *pView =  CТвойВъюКласс*)(pDoc->GetNextView(posView));
   pView - указатель на твой въю класс

Если у тебя мульти док-въю то иттерируй для каждого GetNextDoc - GetNextView.

но вообще-то так не делается, в смысле данные в View классе не капсулируются. Лучше в Доке, или в крайнем случае напрямую в MainFrame. Или используй Application класс. На него можно из любого места доступ получить.

Про "%s %d %s %d %02d:%02d:%02d" эт форматы для дня недели числа и времени - короче, что не надо - выкидывай.

Semper fidelis
Боец невидимого фронта
Джон
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

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


« Ответ #24 : 03-01-2004 16:02 » 

:arrow: Джон, а почему гость? Если ты из дома - поставь галочку авто входа - и без проблем Ага

 :arrow: Вьюха - одна.

 :arrow: А теперь начинай объяснять  :twisted: :
1)POSITION - чего за тип
2)CDocTemplate - тоже
3)GetFirstDocTemplatePosition() - чего возвращает
4)GetNextDocTemplate(pos), GetFirstDocPosition(), GetFirstViewPosition() - тоже

 :arrow: почему такой порядок вызовов (наверное станет ясно после 1,2,3,4)
 :arrow:
Цитата

Лучше в Доке, или в крайнем случае напрямую в MainFrame.

да без проблем, только доступ туда получить надо тоже
 :arrow:
Цитата

Или используй Application класс. На него можно из любого места доступ получить.

-как?  В theApp?

Пока отвечаешь, буду разбираться   Вот такой я вот ...
Записан

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

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


« Ответ #25 : 03-01-2004 17:24 » 

Джон, я сделал так (но на те вопросы ты всё равно ответь) :

1)завёл в классе CUnBin1alfApp объекта theApp переменную для флага
2)подружил MainFrame и View с CUnBin1alfApp и сказал обоим, что
extern CUnBin1alfApp theApp;
3) В любом месте MainFrame или View
theApp.флаг

И всё! Ж: )
Записан

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

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


« Ответ #26 : 06-01-2004 16:13 » 

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

Гром
Птычк. Тьфу, птычник... Вот!
Готовлюсь к пенсии

il
Offline Offline
Пол: Мужской
Бодрый птах


« Ответ #27 : 06-01-2004 17:02 » 

Алексей1153, поставь нужный тайм аут - по истечении него неблокирующий read - выдаст тебе что символа нету.
Записан

А птичку нашу прошу не обижать!!!
Алексей++
глобальный и пушистый
Глобальный модератор

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


« Ответ #28 : 06-01-2004 19:35 » 

Цитата

неблокирующий read


это как?
можно с примером?
Записан

Гром
Птычк. Тьфу, птычник... Вот!
Готовлюсь к пенсии

il
Offline Offline
Пол: Мужской
Бодрый птах


« Ответ #29 : 06-01-2004 20:21 » 

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

Я счас точно не помню...

Однако дабы не морозить себе голову , скажи - ты пытаешься синхронизовать работу потока с приходом данных , дабы он спал, пока не придет блок данных???

Если да то сделай в форуме поиск WaitCommEvent или посмотри эту функцию в MSDN - она ждет пока не придут данные с внешнего источника, и отдает управление - имеет выставляемые параметры на какие события реагировать...
Записан

А птичку нашу прошу не обижать!!!
Алексей++
глобальный и пушистый
Глобальный модератор

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


« Ответ #30 : 07-01-2004 07:38 » 

таймаут получилось сделать с помощью такого потока
Код:
//поток, отсчитывающий время
//выставляет флаг bSeconPassed по истечении времени.
//также останавливается, если в программе установится флаг bIsInTime)
UINT CheckASecond(LPVOID lpttt)
{
DWORD BegTicks,CurTicks;
BegTicks=::GetTickCount();
bool *pbSecondPassed=&(((CUnBin1alfView*)lpttt)->bSecondPassed);
bool *pbIsInTime=&(((CUnBin1alfView*)lpttt)->bIsInTime);
for(;;)
{
if(*pbSecondPassed || *pbIsInTime)
{
return 0;
}
CurTicks=::GetTickCount();
if(CurTicks-BegTicks>1000)
{
*pbSecondPassed=true;
return 0;
}
}
return 0;
}

bSecondPassed и bIsInTime определены в основной проге, там они сбрасываются перед запуском этого потока

но приходится читать по одному байту Жаль

Как можно принудительно убить поток?
« Последнее редактирование: 23-11-2007 17:39 от Алексей1153++ » Записан

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

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


« Ответ #31 : 07-01-2004 08:33 » 

CWinThread::ExitInstance() - это убьёт товарища Потока?  Улыбаюсь
Записан

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

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


« Ответ #32 : 07-01-2004 09:16 » 

ГРРРРРОМУШКА! Спасибо! Я понял! Всё ведь действительно проще чем на самом деле - нужно всего лишь в структуре

COMMTIMEOUTS portCommTimeOuts;

задать при открытии порта

portCommTimeOuts.ReadTotalTimeoutConstant = TimeOutWait;

где TimeOutWait - в миллисекундах

и, блин, проц больше не такой задумчивый, как с потоком!!!  Отлично
 Отлично  Отлично

всё, пойду прогуляюсь, вернусь ночью.   Отлично  Отлично  8)
Записан

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

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


« Ответ #33 : 09-01-2004 18:47 » 

Цитата

CWinThread::ExitInstance() - это убьёт товарища Потока?


а всё-таки?

и если нет, то как это сделать кроме как глобальными флагами?
Записан

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

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

« Ответ #34 : 12-01-2004 16:37 » 

Цитата: Алексей1153
Джон, я сделал так (но на те вопросы ты всё равно ответь) :

1)завёл в классе CUnBin1alfApp объекта theApp переменную для флага
2)подружил MainFrame и View с CUnBin1alfApp и сказал обоим, что
extern CUnBin1alfApp theApp;
3) В любом месте MainFrame или View
theApp.флаг

И всё! Ж: )


Всё правильно сделал. Только не понял зачем обоим говорил extern CUnBin1alfApp theApp; - достаточно в АРР заголовочном файле определить. Флаг у тебя public - поосторожнее с этим. Лучше через пару Get-Set.

Отвечаю на вопросы:

работает это по принципу CObList когда чтобы сделать enumeration сначала получают голову, а потом от неё и пляшут (см MSDN)

CObList list;
POSITION pos;

list.AddHead( new CAge( 21 ) );
list.AddHead( new CAge( 40 ) ); // List now contains (40, 21).
if( ( pos = list.GetHeadPosition() ) != NULL )
{
    ASSERT( *(CAge*) list.GetAt( pos ) == CAge( 40 ) );
}

первая функция возвращает позицию "головы" (первого шаблона для Док Въю пары). Для SDI она является единственной. Потом у документа может быть множество View (например данные представляются в виде графика,таблицы и тд) Отсюда иттерация по Въю  - аналогично. Конечно это всё через попу стеклорезом, но работает!
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"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."
Алексей++
глобальный и пушистый
Глобальный модератор

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


« Ответ #35 : 18-07-2004 08:52 » 

возвращаясь к пунктам меню

допустим я создаю пункт "COM порт" с ID==ID_MENU_SHOW_PORT_DIALOG

далее визардом делаю для него сообщение COMMAND, и оно появляется в CMainFrame:

MainFrm.cpp:
Код:
BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
   //{{AFX_MSG_MAP(CMainFrame)
   ...
   ON_COMMAND(ID_MENU_SHOW_PORT_DIALOG, OnMenuShowPortDialog)
   //}}AFX_MSG_MAP
END_MESSAGE_MAP()

void CMainFrame::OnMenuShowPortDialog()
{
   // TODO: Add your command handler code here
}

MainFrm.h:
Код:
protected:
   //{{AFX_MSG(CMainFrame)
   ...
   afx_msg void OnMenuShowPortDialog();
   //}}AFX_MSG
   DECLARE_MESSAGE_MAP()

почему, если я все эти три фрагмента перемещаю в CLT6View.cpp и CLT6View.h
(соответственно заменив void CMainFrame::OnMenuShowPortDialog()  на
void CLT6View::OnMenuShowPortDialog() )

то ОНО продолжает работать (во вьюхе) ?

Правильно ли я понимаю  - при нажатии на пункт генерируется сообщение "ID_MENU_SHOW_PORT_DIALOG" (как оно называется точно - не знаю), а о том, какой именно объект поймает это сообщение - говорит определение afx_msg void OnMenuShowPortDialog() этого объекта?
« Последнее редактирование: 23-11-2007 17:40 от Алексей1153++ » Записан

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

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

« Ответ #36 : 18-07-2004 21:51 » 

Цитата: Алексей1153
оно появляется в CMainFrame


оно появляется в том классе, которой ты выбираешь для обработки этой команды - (в 6ой версии такой комбобокс со списком классов)

Будет всегда работать в активном окне, если в его класс встроена функция обработки этой команды. Напр. для MDI View пункт меню не будет доступен, если у тебя все childs закрыты. Поэтому команды типичные для MainFrame встраиваются туда.
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"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."
Алексей++
глобальный и пушистый
Глобальный модератор

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


« Ответ #37 : 20-07-2004 06:35 » 

можно ли в карту сообщений (созданную визардом в VC++6, MFC, SDI ) вставлять свой код,
что-то вроде этого:

Код:
    //{{AFX_DATA_MAP(CLT6View)
    DDX_Radio(pDX, IDC_check1, m_check1);


        ((CEdit*)(GetDlgItem(IDC_ed1))->GetWindowText(txt);
        f(txt);
        ((CEdit*)(GetDlgItem(IDC_ed1)))->SetWindowText(txt);

        ((CEdit*)(GetDlgItem(IDC_ed2)))->GetWindowText(txt);
        f(txt);
        ((CEdit*)(GetDlgItem(IDC_ed2)))->SetWindowText(txt);

    DDX_Text(pDX, IDC_ed1, m_ed1);
    DDX_Text(pDX, IDC_ed2, m_ed2);
    //}}AFX_DATA_MAP

где процедура f() (неважно, что в ней делается) использует значение переменной m_check1 ( это группа переключателей - RadioButton);

то есть нужно чтобы сначала обновились переменные переключателей, потом меняем текст едитов (CEdit), затем только обрабатываем едиты

должна ли карта быть непрерывной или так можно делать?
« Последнее редактирование: 23-11-2007 17:41 от Алексей1153++ » Записан

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

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

« Ответ #38 : 20-07-2004 07:27 » 

Алексей1153,  Я не совсем понял, что ты имеешь ввиду под "картой сообщений" ? Насколько я вижу, ты привёл кусок тела функции DoDataExchange(CDataExchange* pDX) , подозрительный кусок -  DDX_Text(pDX, IDC_ed2, m_ed2); В этом случае m_ed1 у тебя должен быть типа CString, но его префикс говорит, что это CEdit. (кстати о птичках - хотел вставить сюда смайлик "чешущий репу", но не нашёл - если время будет сделай плз)

Если у тебя есть возможность использовать DDX функции - используй их.
Вернее это макросы, которые связывают контрол с объектом содержащим данные.
Например, ты вставляешь в ресурсы контрол типа edit и хочешь получать из него текст, те создаёшь объект типа CString m_stMyString; тогда при вызове макроса
DDX_Text(pDX, IDC_MY_EDIT, m_stMyString); в зависимости от направления, которое определено в pDX, происходит запись из m_stMyString в контрол, или наоборот.

Управление направлением с помощью UpdateData(), вернее её параметра TRUE или FALSE. Для твоего случая решение такое (ессно тебе придётся вызывать где нить UpdateData() иначе у тебя DoDataExchange не вызовется):

в .h

CString m_stEd1, m_stEd2;

в
DoDataExchange

    DDX_Text(pDX, IDC_ed1, m_stEd1);
    DDX_Text(pDX, IDC_ed2, m_stEd2;


там где необходимо действие

       UpdateData(TRUE); // из контрола в переменную
       f(m_stEd1);  // параметр ф-и должен быть ссылкой
       f(m_stEd2);
       UpdateData(FALSE); // из переменной в контрол
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"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."
Алексей++
глобальный и пушистый
Глобальный модератор

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


« Ответ #39 : 20-07-2004 09:17 » 

Цитата
Я не совсем понял, что ты имеешь ввиду под "картой сообщений" ?

Джон, да - с названиями я плаваю, да и шут с ними, подучу Улыбаюсь

(не знаю в каком порядке оправдываться Улыбаюсь , буду по тексту -> )

 :arrow:
 
Цитата
подозрительный кусок - DDX_Text(pDX, IDC_ed2, m_ed2); В этом случае m_ed1 у тебя должен быть типа CString, но его префикс говорит, что это CEdit.

эээ.. не совсем так - float m_ed2 . Префикс "ed" больше относится к ID, просто у меня так повелось, что переменные m_... , которые я добавляю контролу визардом, я называю так же, как ID, например
IDC_xxxx
m_xxxx

в чём у меня грабля  - чуть попозже.
так вот при вызове UpdateData(TRUE) , если в тексте было что-то вроде "111.111ё" произойдёт облом - ход мыслей теряется, как у программы так и у пользователя (там ещё это вредное окно выскочет)
Следовательно в DoDataExchange() мне нужно подкорректировать строку.

Кстати - если кому надо, вот функция, которая "насильно" приводит строку к виду float

Код:
//обрезает строку до float (и убирает мусор в конце).
//число float в строке - должно быть положительным
//lenbefore - длина до точки
//lenafter - длина после точки
void CLT6View::CountLensN_P_N_RemainderAndCut(CString &txt, int &lenbefore,int &lenafter)
{
    int i,txtlen;
    char lit;
    txtlen=txt.GetLength();
    lenbefore=0; lenafter=0;

    //считаем цифры до первого не циферного символа
    for(i=0;i<txtlen;i++)
    {
        lit=txt.GetAt(i);
        if(lit<'0' || lit>'9')break;
        lenbefore++;
    }
    //встретилась не цифра либо строка закончилась

    //проверяем на "точку" (".,БЮбю<>/?")
    if(i<txtlen)
    {
        lit=txt.GetAt(i);
        if(    lit=='.'||lit==','||lit=='Б'||lit=='Ю'||lit=='б'||
               lit=='ю'||lit=='<'||lit=='>'||lit=='/'||lit=='?')
        {
            //это была "точка" - заменяем на точку "." .
            txt.Delete(i);
            txt.Insert(i,'.');

            //если "точки" встречаются ещё - удаляем их
            for(++i;i<txtlen;i++)
            {
                lit=txt.GetAt(i);
                if(    !(lit=='.' || lit==',' || lit=='Б' || lit=='Ю' || lit=='б' ||
                       lit=='ю' || lit=='<' || lit=='>' || lit=='/' || lit=='?')
                        )break;
                //удаляем "точку"
                txt.Delete(i);
                txtlen--;//т.к. длина уменьшилась
                i--;//т.к. этот символ тоже надо будет проверить
            }
            //лишние точки удалены

            //считаем цифры после точки
            for(;i<txtlen;i++)
            {
                lit=txt.GetAt(i);
                if(lit<'0' || lit>'9')break;
                lenafter++;
            }
            //встретилась не цифра либо строка закончилась
        }
    }
    //начиная с i - мусор, либо строка закончилась.
    //обрезаем мусор с i по txtlen-1 (zero-based)
    if(i<txtlen)txt.Delete(i,txtlen-i);
    //txtlen=i;
}


но перед тем, как еёкорректировать, мне ещё нужно узнать положение переключателей - то есть для них UpdateData() нужно отдельно...

 :arrow:
Цитата
смайлик "чешущий репу", но не нашёл - если время будет сделай плз)
бу сде! Улыбаюсь

 :arrow:
Цитата
Если у тебя есть возможность использовать DDX функции - используй их.

в идеале нужно бы так ->
Код:

IMPLEMENT_DYNCREATE(CLT6View, CFormView)
BEGIN_MESSAGE_MAP(CLT6View, CFormView)
//{{AFX_MSG_MAP(CLT6View)
...
ON_BN_CLICKED(IDC_check1, Oncheck1)
...
//}}AFX_MSG_MAP
END_MESSAGE_MAP()


void CLT6View::Oncheck1()
{
    DDX_Radio(pDX, IDC_check1, m_check1);
}

- то есть при щёлчке по переключателю - переменная сразу бы менялась

но откуда брать pDX  - ?

или может так? ->
Код:
void CLT6View::Oncheck1() 
{
    m_check1=1;
    if(((CButton*)GetDlgItem(IDC_check1))->GetCheck() == TRUE)return;
    m_check1++;
    if(((CButton*)GetDlgItem(IDC_check2))->GetCheck() == TRUE)return;
    m_check1++;
    if(((CButton*)GetDlgItem(IDC_check3))->GetCheck() == TRUE)return;
    m_check1=-1;
}

void CLT6View::Oncheck2()
{
    Oncheck1();
}

void CLT6View::Oncheck3()
{
    Oncheck1();
}

« Последнее редактирование: 23-11-2007 17:44 от Алексей1153++ » Записан

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

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

« Ответ #40 : 20-07-2004 11:48 » 

Блин, ща времени нет подробно расписывать, если не получится - вечером распишу, а пока - всё то же самое, как я написал только сделай переменные типа double
double m_dEd1, m_dEd2;

и всё заработает и туда и обратно.

....

Типа вот набросал: есть 3 едита и два переключателя

Код:
	//{{AFX_DATA(CTestTreeDlg)
enum { IDD = IDD_TESTTREE_DIALOG };
double m_dVal1;
double m_dVal2;
double m_dRes;
BOOL m_bTest;
//}}AFX_DATA

void CTestTreeDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CTestTreeDlg)
DDX_Text(pDX, IDC_EDIT1, m_dVal1);
DDX_Text(pDX, IDC_EDIT2, m_dVal2);
DDX_Text(pDX, IDC_EDIT3, m_dRes);
DDX_Check(pDX, IDC_CHECK1, m_bTest);
//}}AFX_DATA_MAP
}

по клику на первый - в 3ий едит выводится произведение  или сумма (зависит от чекбокса) первых двух
на второй - частное или разность
Код:
void CTestTreeDlg::OnRadio1() 
{
UpdateData(TRUE);
if(m_bTest) m_dRes = m_dVal1*m_dVal2;
else m_dRes = m_dVal1+m_dVal2;
UpdateData(FALSE);
}

void CTestTreeDlg::OnRadio2()
{
UpdateData(TRUE);
if(m_bTest) m_dRes = m_dVal1/m_dVal2;
else m_dRes = m_dVal1-m_dVal2;
UpdateData(FALSE);
}
« Последнее редактирование: 23-11-2007 17:46 от Алексей1153++ » Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"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."
Алексей++
глобальный и пушистый
Глобальный модератор

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


« Ответ #41 : 20-07-2004 14:42 » 

Не, Джон, эт маленько не то...

тут ведь видишь как - когда UpdateData(TRUE), то все едиты засовывают свой текст в свой m_...
А если текст не соответствует float (например "112/xcvzxcvxcv") то будет нехорошо.

но я уже вроде поборол эти грабли...

я сделал так

Код:
void CLT6View::Oncheck1() //Первый в группе переключатель
{
    while(true)
    {
        m_check1=0;
        if(((CButton*)GetDlgItem(IDC_check1))->GetCheck() == TRUE)break;
        m_check1++;
        if(((CButton*)GetDlgItem(IDC_check2))->GetCheck() == TRUE)break;
        m_check1++;
        if(((CButton*)GetDlgItem(IDC_check3))->GetCheck() == TRUE)break;
        m_check1=-1;
    }
    UpdateData();
}
void CLT6View::Oncheck2() { Oncheck1();} //Остальные
void CLT6View::Oncheck3() { Oncheck1();} //переключатели.

void CLT6View::DoDataExchange(CDataExchange* pDX)
{
    CFormView::DoDataExchange(pDX);

    //предварительная обработка строк в CEdit перед записью в m_...
    NormalizeTextsInEditsBeforeDoDataExchange();

    //||AFX_DATA_MAP(CLT6View)
    ...
    //""AFX_DATA_MAP

}

//предварительная обработка строк в CEdit перед записью в m_...
void CLT6View::NormalizeTextsInEditsBeforeDoDataExchange()
{
    CString txt;
    CEdit* ed;
    int lenbefore,lenafter;

    ((CEdit*)(GetDlgItem(IDC_ed1)))->GetWindowText(txt);
    if(txt=="")((CEdit*)(GetDlgItem(IDC_ed1)))->SetWindowText("0");
    ...
    ((CEdit*)(GetDlgItem(IDC_ed2)))->GetWindowText(txt);
    CountLensN_P_N_RemainderAndCut(txt,lenbefore,lenafter)//код-в посте выше
    ((CEdit*)(GetDlgItem(IDC_ed2)))->SetWindowText(txt);
    ...
    //тексты в CString m_... поменяли, но в едиты ещё не вывели
}

то есть UpdateData() теперь не сломается Улыбаюсь

зы. Всё равно спаааасибо! Улыбаюсь
__________________________
ГРОМ, а можно окно быстрого ответа сделать больше по высоте, а по ширине - точь в точь как у поста?
« Последнее редактирование: 23-11-2007 17:48 от Алексей1153++ » Записан

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

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

« Ответ #42 : 20-07-2004 15:08 » 

Лёха,  Да я понял! Ты попробуй ерунду написать в едите и посмотри что получится  Ага
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"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."
Алексей++
глобальный и пушистый
Глобальный модератор

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


« Ответ #43 : 21-07-2004 03:44 » 

а, он типа глобальный Undo делает...

а у меня он будет неправильно введённые числа превращать в правильные:

"12,3"->"12.3"
"12б3"->"12.3"
"12ю3нпт"->"12.3"
"1..2..3"->"1.2"
"//1.2"->"0"

и т.д. Улыбаюсь

 :arrow:
у меня ещё вот какая мысля возникла:

функция для обновления ОДНОГО ЛЮБОГО элемента
Код:
int IDtoUpdate;

Ctest::Ctest()
{
    IDtoUpdate=NULL;
}

void Ctest::UpdateData111(BOOL bSaveAndValidate=TRUE ,int ID=NULL)
{
    IDtoUpdate=ID;
    UpdateData(bSaveAndValidate)
}

void Ctest::DoDataExchange(CDataExchange* pDX)
{
   CDialog::DoDataExchange(pDX);
   //{{AFX_DATA_MAP(Ctest)
   if(IDtoUpdate==NULL || IDtoUpdate==IDC_EDIT1 )
         DDX_Text(pDX, IDC_EDIT1, m_dVal1);
   if(IDtoUpdate==NULL || IDtoUpdate==IDC_EDIT2 )
         DDX_Text(pDX, IDC_EDIT2, m_dVal2);
   if(IDtoUpdate==NULL || IDtoUpdate==IDC_EDIT3 )
         DDX_Text(pDX, IDC_EDIT3, m_dRes);
   if(IDtoUpdate==NULL || IDtoUpdate==IDC_CHECK1 )
         DDX_Check(pDX, IDC_CHECK1, m_bTest);
   //}}AFX_DATA_MAP

    IDtoUpdate=NULL;
}

причём если вызвать как UpdateData111() - будет работать как обычно. Даже UpdateData() можно будет напрямую вызвать
« Последнее редактирование: 23-11-2007 17:49 от Алексей1153++ » Записан

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

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

« Ответ #44 : 21-07-2004 08:04 » 

Цитата: Алексей1153
а у меня он будет неправильно введённые числа превращать в правильные:


"Не советую, гражданин...   мнэ-э...  не  советую.  Съедят" (с)

Это зачем же так распускать юзеров!!!  :new_shot: Или ты прогу для киношки делаешь? Когда при подборе пароля просто достаточно постучать по клаве и дверка открывается? Ага

"Плохо кончится, родной" (с)
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"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."
Алексей++
глобальный и пушистый
Глобальный модератор

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


« Ответ #45 : 21-07-2004 13:32 » 

Джон! Да нет тама паролев!  Отлично

тут наоборот надо баловать - иначе продукт станет быть забыт

Цитата

Или ты прогу для киношки делаешь?


какой-такой киношки? Улыбаюсь

____________________________
вот новые вопросы:

почему, если я открываю модальное окно в ПОТОКЕ, то главное окно всё равно не реагирует на мышь?

как открыть диалог не процедурой DoModal() так, чтобы он работал ПАРАЛЛЕЛЬНО с главным окном?

или - как убить запущенный поток, если указатель CWinThread* thr имеется, а поток запущен
thr=AfxBeginThread(d111,this,THREAD_PRIORITY_NORMAL);

//поток
UINT d111(LPVOID pnt)
{
   CCancelDialog dlg;
   dlg.DoModal();
   return 0;
}

?
Записан

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

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

« Ответ #46 : 22-07-2004 07:08 » 

1. Потому что окно модальное.
2. Необходимо не модальное окно:

Общая схема:

CMyDialog *pDlg = new CMyDialog();
pDlg->Create(...);

Показываем - скрываем
pDlg->ShowWindow(SW_HIDE или SW_SHOW);

Подчищаем:
pDlg->Destroy()

delete pDlg;


3. Если у тебя диалог не модальный, то его не надо запускать в отдельном thread. Или необходимо параллельное выполнение действий с синхронизацией?
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"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."
Алексей++
глобальный и пушистый
Глобальный модератор

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


« Ответ #47 : 22-07-2004 08:24 » 

мне нужно параллельно с циклом (который теоретически может стать бесконечным) вывести  диалог с кнопкой отмены. В то же время - если цикл распутается, то программа продолжается и нужно убить диалог.
А в случае с модальным - я его закрыть не могу. Просто я думал - если поток отдельный, то и модальное онкно только его заглушит, но не нашёл, как убивать поток по его указателю...
Сейчас вижу, что поток новый не надо

Цитата

CMyDialog *pDlg = new CMyDialog();
pDlg->Create(...);
Показываем - скрываем
pDlg->ShowWindow(SW_HIDE или SW_SHOW);
Подчищаем:
pDlg->Destroy()
delete pDlg;


это работает... но как-то не всё понятно:

1) в pDlg->Create(...) какой ID указывать - придумывать что-ли? Это должен быть уже существующий ID или новый? Пока что я написал ID - как у ресурса диалога. Выжило. Улыбаюсь

2) Окно появляется, но оно ЧИСТОЕ. Только заголовок есть. Как кнопки-то появить?

3) Возможно ли создать диалог один раз в конструкторе вьюхи, а потм - когда надо появлять или скрывать, не удаляя?
Записан

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

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

« Ответ #48 : 22-07-2004 09:12 » 

1. Модальный диалог закрывается EndDialog() в качестве параметра - код возврата
напр. IDOK - симулируется закрытие диалога нажатием на Ок и тд

2. Если не поможет то...

Значится так, это всё теория - я имею ввиду создание немодальных диалогов.
Те можно посмотреть. MSDN - "modeless dialog boxes, creating" etc.
Если негде - я тебе могу надёргать куски кода.

Ааааа, подожди. Твое последнее предложение. МОжет ты не так понял?
В общем у тебя есть класс в котором создаётся диалог, назовёв его управляющим. У него есть мембер - указатель на диалог. При первой необходимости - проверка на существование объекта если нет - new + Create(). если уже существует, то ShowWindow(SW_SHOW). Закрытие - необходимо сообщить управляющему классу, что закрываеся - или удаляем, или
ShowWindow(SW_HIDE) - по необходимости. Ну и по завершении работы - подчищаем всё окончательно.

А ID  у тебя в твоём классе сидит. Он получает доп. конструктор
родителей и ИД надо сохранить в мемберах:
CMyDlg::CMyDlg(CWnd* pParent /*=NULL*/)
   : CDialog(CMyDlg::IDD, pParent)
{

   ASSERT(pParent != NULL);
   m_pParent = pParent;
   m_nID = CLptStateDlg::IDD;
}

и ф-ии

void CMyDlg::OnClose()
{
   ((CMainFrame*)m_pParent)->ModeLessDlgDown();
   DestroyWindow();
}

BOOL CMyDlg::Create()
{
   return CDialog::Create(m_nID, m_pParent);
}

void CMyDlg::PostNcDestroy()
{
   delete this;
}

void CMyDlg::OnDestroy()
{
   CDialog::OnDestroy();
}

тогда вызов выглядит так:

в MainFrm.h
CMyDlg *m_pMyDlg;

.срр

void CMainFrame::OnToggleMyDlg()
{
   if (m_pMyDlg == NULL)
   {
      m_pMyDlg = new CMyDlg(this);
      if (m_pMyDlg->Create() == TRUE)
      {
         // 2dos
      }
   }
   else
   {
      m_pMyDlg->DestroyWindow();
      m_pMyDlg = NULL;
   }
}

void CMainFrame::ModeLessDlgDown()
{
   if(m_pMyDlg) m_pMyDlg= NULL;
}

ну и конечно всё подчистить при завершении работы по OnClose - ну это я думаю понятно.
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"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."
Алексей++
глобальный и пушистый
Глобальный модератор

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


« Ответ #49 : 22-07-2004 11:32 » 

1)  :arrow:
Джон, продолжив мучать мдальное,  я не могу понять вот что:

сделал я во вьюхе так:
Код:
//поток 
UINT d111(LPVOID pnt)
{
CCancelDialog* dlg=(CCancelDialog*)pnt;
dlg->DoModal();
return 0;
}

void CLT6View::OnButton1()
{
CCancelDialog dlg;
CWinThread* thr;
thr=AfxBeginThread(d111,&dlg,THREAD_PRIORITY_NORMAL);

//::AfxMessageBox("вывели");

for(int i=0;i<200000000;i++);
dlg.EndDialog(IDCANCEL);
}

для начала хотел добиться просто вот чего: нажимаю на кнопу, поверх вьюхи вылазит окно с кнопкой отмены (CCancelDialog). Досчитали до 200000000 - окно закрывается и прога продолжается. (про отмену пока молчу )

а работает так: появляется НИЧЕГО. Затем возникает окно
___________________________
Debug Assertion Failed!
....
File: dlgcore.cpp
...

(стоп) (повтор) (пропустить)
___________________________

а поверх него - наш диалог, родёмый!!!

причём если, не трогая НАШ диалог, нажать на (пропустить), то всё продолжает работать, не ломается (Не понял!!!!!!) и даже НАШ закрывается, как ему и.

 а вот сначала сделать (там, где строка закрыта - //)
::AfxMessageBox("вывели");

то происходит всё так:
окно Afx открывается, поверх него СРАЗУ же появляется НАШ. А не после 200000000!!! То есть так , как надо. Но, естественно, прога останавливается, пока не закрыли Afx. И спустя 200000000 диалог исправно пропадает.


2)  :arrow: щас попробую немодальное помучить... Может к тому времени уже заглянешь, прочитаешь и скажешь в чём косяк Улыбаюсь
« Последнее редактирование: 23-11-2007 17:53 от Алексей1153++ » Записан

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

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


« Ответ #50 : 23-07-2004 18:49 » 

Джон, чего-то не могу ничего с диалогами...

Остановился на такой схеме -

LT6View.h
Код:
    bool stop;

LT6View.cpp
Код:
//нажатием - запускаем цикл
void CLT6View::OnButton1()
{
    MSG message;
    stop=false;
    while(!stop)//пока флаг сброшен
    {
        if(::PeekMessage(&message,NULL,0,0,PM_REMOVE))
        {
            ::TranslateMessage(&message);
            ::DispatchMessage(&message);
        }
    }
}

// нажатием - устанавливаем флаг
void CLT6View::OnButton2()
{
    stop=true;
}

MainFrame.cpp
Код:
//пока цикл запущен - не разрешаем закрыть прогу
//иначе процесс в памяти остаётся жить вечно
void CMainFrame::OnClose()
{
    if(((CLT6View*)GetActiveView())->stop)
    {
        CFrameWnd::OnClose();
    }
    else
    {
        return;
    }
}
   

Это вроде меня устраивает...
Если что я неправильно сделал - подскажи (я даже догадываюсь - что Улыбаюсь )
« Последнее редактирование: 23-11-2007 17:54 от Алексей1153++ » Записан

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

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

« Ответ #51 : 24-07-2004 20:36 » 

Ели честно - то теперь я ничего не понимаю. Давай ты сформулируй задачу.

Или так -  как я это понимаю:

У тебя есть прога, она что-то делает. Пока не сделала её нельзя закрывать. Но то что делается надо уметь грубо прервать (а то скучно) чтоб таки закончить прогу. Ты хотел сделать это с помощью диалога, типа "чтоб прекратить действие нажмите кнопку". Но если действие само закончилось, то диалог должен сам убраться.

Правильно?
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"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."
Алексей++
глобальный и пушистый
Глобальный модератор

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


« Ответ #52 : 25-07-2004 04:47 » 

"садитесь, пять!" (c) Ага

Джон, практически правильно, только -

Цитата

надо уметь грубо прервать (а то скучно)

это надо в случае, если удовольствие растягивается слишком надолго,

Цитата

Пока не сделала её нельзя закрывать

ага

Цитата

чтоб таки закончить прогу

нет, не закончить прогу, а прервать ОПЕРАЦИЮ; прога продолжается, и особо терпеливые могут снова попытаються выполнить операцию Улыбаюсь
Записан

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

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

« Ответ #53 : 25-07-2004 20:36 » 

Цитата: Алексей1153
"садитесь, пять!" (c) Ага


"Пъять - это есть очъень плйоха, не есть карашо"  Жжешь  По крайней мере в Германии.

Я тебе проектик на мыло кинул, если это то, то садаптируй к своим условиям и можешь выложить сюда код. Там только CMainFrame достоин внимания.
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"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."
Алексей++
глобальный и пушистый
Глобальный модератор

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


« Ответ #54 : 26-07-2004 07:23 » 

Цитата

если это то


почти, но маленько не то... С отменой я вроде разобрался Улыбаюсь

____________________

вот ещё вопросов (считай, что они не связаны с предыдущей задачей, а общие):

1) как всё-таки создать и заставить появиться диалог (или нечто похожее) , чтобы он работал ПАРАЛЛЕЛЬНО с основной программой и ни в чём её не ограничивал (пример - окно свойств в нашем любимом VC++6, когда они "приколото", или - окно поиска/замены(ctrl+F/H) в Ворде)

Цитата

2) Окно появляется, но оно ЧИСТОЕ. Только заголовок есть. Как кнопки-то появить?



1а) как сделать, чтобы этот диалог был постоянно наверху (даже без фокуса)

1б) как сделать, чтобы в отсутствие фокуса он не был наверху

2) TRACE0("...");
3) ::CreateEvent(NULL,TRUE,TRUE,NULL);
4) ::SetEvent(m_break);
5) ::ResetEvent(m_break);
6) ::WaitForSingleObject(m_hThread,100)
 - это что есть?

7) ::TerminateThread(m_hThread,0); - а это, я так понимаю, и есть "убить поток"?
Записан

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

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

« Ответ #55 : 26-07-2004 09:07 » 

2. Вывод текстового сообщения в дебаггере, окно "Out"

3.-6. Управление thread с помощью события.
3 - создание
5 -  сброс перед использованием

WaitForSingleObject(m_break,0)
 ф-я ждёт в течении 0 мс события (event) и возвращает TIME_OUT если оно не пришло. Устанавливается событие 4 - SetEvent. После этого WaitForSingleObject возвращает другую константу - (не соврать) WAIT_OBJECT_0.

6 - 7 - именно это она и делает - те сначала мы даём треаду шанс самому закончить работу - собсно это окончание ф-ии - если этого не происходит в течении 100 мс, то мы его "грубо" прерываем.

Если тебе нужен элементы упарвления типа тулбаров, то посмотри CDialogBar в MSDN.

Про остальное вечером - работы дофига.
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"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."
Джон
просто
Администратор

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

« Ответ #56 : 26-07-2004 21:02 » 

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

ЗЫ
Во прикол - у меня всего десятое сообщение - 1010   Жжешь
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"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."
Алексей++
глобальный и пушистый
Глобальный модератор

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


« Ответ #57 : 27-07-2004 04:46 » 

Джон, спасибо Улыбаюсь

то что надо Улыбаюсь
Записан

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

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

« Ответ #58 : 27-07-2004 10:57 » 

Ну дык не за что. Я ещё про порядок окон не сказал

"1а) как сделать, чтобы этот диалог был постоянно наверху (даже без фокуса)
1б) как сделать, чтобы в отсутствие фокуса он не был наверху "

- ты что имел ввиду? Z- порядок? Тогда это можно с помощью ф-ии SetWindowPos делать.

А если про модальность, то ты можешь посмотреть стиль DS_SYSMODAL хотя это тоже самое что WS_EX_TOPMOST, только для диалога. Его можно в свойствах задать.
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"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."
Алексей++
глобальный и пушистый
Глобальный модератор

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


« Ответ #59 : 28-07-2004 09:27 » 

Джон - я как маленький ребёнок, чем больше объясняешь, тем больше у меня вопросов Улыбаюсь

вот эти:
WriteProfileString("ModelessDlg","Position",stPos)
GetProfileString("ModelessDlg","Position")

куда они пишут - в реестр что-ли?
и что значат Section и Entry ?
Они создаются, когда в них первый раз пишешь или уже ранее созданы?
Можно ли энто использовать вообще для сохранения настроек (допустим последние настройки порта - чтобы в следующий раз открывать с теми же настройками) ?
Записан

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

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

« Ответ #60 : 28-07-2004 14:03 » 

Цитата: Алексей1153
Джон - я как маленький ребёнок, чем больше объясняешь, тем больше у меня вопросов Улыбаюсь


Это показывает, что ты что-то понял. Не помню кто, но кто-то увольнял сотрудников, если они после получения задания не задавали вопросов.

К вопросу:

Это прелести MFC. Посмотри application class, короче который public CWinApp. Там есть такая ф-я OnInitInstance в ней найдёшь SetRegistryKey() - параметр можешь установить сам например

SetRegistryKey(_T("MyFirstProg"));

После этого в registry будет создан след. ключ
HKEY_CURRENT_USER\Software\MyFirstProg

Эта инфа будет сохранена во внутренней структуре CWinApp.

Вызов ф-ии
WriteProfileString("ModelessDlg","Position",stPos)
создаст ключ
HKEY_CURRENT_USER\Software\MyFirstProg\ModelessDlg
с полем

Position = stPos
а ф-я

GetProfileString("ModelessDlg","Position")
соответсвенно вернёт строку, содержащую значение этого поля.

Можно использовать для всего чего угодно.

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

Я что-то не помню где я про " Section и Entry " написал - напомни.

Вообще-то, Section - это путь, а Entry - это поле данных.
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"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."
Алексей++
глобальный и пушистый
Глобальный модератор

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


« Ответ #61 : 28-07-2004 17:57 » 

супер Улыбаюсь


 :arrow:
Цитата

Я что-то не помню где я про " Section и Entry " написал - напомни.

ты не писал - это я про них писал Ага
Да это VC такой список параметров этоу функции показал.

зы. у тебя колобайт сообщений намечается Ага
Записан

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

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

« Ответ #62 : 29-07-2004 08:16 » 

Цитата: Алексей1153
зы. у тебя колобайт сообщений намечается Ага


Ну дык, готовимся.  Ага  Хотя в HEX, уже за 4 тысячи перевалило.
Так и хочется сказать "А в хексах я гораздо ддиннее!"
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"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."
Anti_G
Гость
« Ответ #63 : 29-07-2004 11:34 » 

Алексей1153,
WriteProfileString и GetProfileString - это воспоминания от старых времен. Дело в том, что эти функции в Win95 и Win3.x работают с файлом WIN.INI.

Например,
[MySection]
MyEntry = somevalue

А сейчас  они пишут в реестр.
Записан
Джон
просто
Администратор

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

« Ответ #64 : 29-07-2004 13:17 » 

Anti_G,  Не совсем так. Это функции - враперы для соответствующих ф-ий API. Рассмотрим в качестве примера WriteProfileString  - её код:

Код:
BOOL CWinApp::WriteProfileString(LPCTSTR lpszSection, LPCTSTR lpszEntry,
LPCTSTR lpszValue)
{
ASSERT(lpszSection != NULL);
if (m_pszRegistryKey != NULL)
{
LONG lResult;
if (lpszEntry == NULL) //delete whole section
{
HKEY hAppKey = GetAppRegistryKey();
if (hAppKey == NULL)
return FALSE;
lResult = ::RegDeleteKey(hAppKey, lpszSection);
RegCloseKey(hAppKey);
}
else if (lpszValue == NULL)
{
HKEY hSecKey = GetSectionKey(lpszSection);
if (hSecKey == NULL)
return FALSE;
// necessary to cast away const below
lResult = ::RegDeleteValue(hSecKey, (LPTSTR)lpszEntry);
RegCloseKey(hSecKey);
}
else
{
HKEY hSecKey = GetSectionKey(lpszSection);
if (hSecKey == NULL)
return FALSE;
lResult = RegSetValueEx(hSecKey, lpszEntry, NULL, REG_SZ,
(LPBYTE)lpszValue, (lstrlen(lpszValue)+1)*sizeof(TCHAR));
RegCloseKey(hSecKey);
}
return lResult == ERROR_SUCCESS;
}
else
{
ASSERT(m_pszProfileName != NULL);
ASSERT(lstrlen(m_pszProfileName) < 4095); // can't read in bigger
return ::WritePrivateProfileString(lpszSection, lpszEntry, lpszValue,
m_pszProfileName);
}
}

Если переменная m_pszRegistryKey не установлена (вызов SetRegistryKey() )
то вызывается API ф-я:
::WritePrivateProfileString(lpszSection, lpszEntry, lpszValue,m_pszProfileName);

Последний параметр - имя INI файла, который можно использовать и сейчас.

Для этого достаточно - выключить вызов SetRegistryKey()  и проиннициаллизировать переменную m_pszProfileName :  

в конструкторе:
free((void*)m_pszProfileName);
m_pszProfileName=_tcsdup(_T("d:\\MyFirstProg.ini"));

деструктор позаботится об освобождении памяти

тогда вызов
WriteProfileString("ModelessDlg","Position",stPos)

создаст файл d:\\MyFirstProg.ini и запишет в него

[ModelessDlg ]
Position="Содержимое переменной stPos"

Иногда удобнее пользоватся файлами вместо реестра. Но размер INI файлов ограничен по-моему до 64К, или это было под 95 виндой? Точно не помню.
« Последнее редактирование: 23-11-2007 17:58 от Алексей1153++ » Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"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."
Страниц: 1 2 3 [Все]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines