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

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1] 2 3  Все   Вниз
  Печать  
Автор Тема: доступ к элементам меню  (Прочитано 54840 раз)
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 - она ждет пока не придут данные с внешнего источника, и отдает управление - имеет выставляемые параметры на какие события реагировать...
Записан

А птичку нашу прошу не обижать!!!
Страниц: [1] 2 3  Все   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines