Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« : 29-12-2003 11:13 » |
|
всем привет
подскажите, как получить указатель на элемент меню как это делается в обработчике юзерского сообщения
void CX::OnBn(CCmdUI* pCmdUI) { pCmdUI->Enable(true); }
- как по ID сделать указатель на CCmdUI , чтобы из любого места программы можно было pCmdUI->Enable(true);
|
|
|
Записан
|
|
|
|
Mouse
Молодой специалист
Offline
|
|
« Ответ #1 : 29-12-2003 11:28 » |
|
Попробуй так:
CCmdUI *pCmdUI = GetDlgItem(IDC_MYMENUITEM);
Сразу говорю - сам не пробовал, но на простых элементах управления работает.
|
|
|
Записан
|
|
|
|
Lex
|
|
« Ответ #2 : 29-12-2003 11:31 » |
|
Алексей1153, никак.
pCmdUI сождается в строго определенные моменты. Сейчас не вспомню, но кажется когда входишь или выходишь из меню, ну и при входе в Idle. Чтобы управлять из любого места с CFrameWnd есть m_bAutoMenuEnable. (которое по идее дизаблет меню, в которых нет обработчиков и еще и включает этот механижм OnUpdate...)/ Если его поставить в false, то можно бутет нормально работать через GetMenu() и т.д.
|
|
|
Записан
|
Megabyte be with you!
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #3 : 29-12-2003 17:46 » |
|
CCmdUI *pCmdUI = GetDlgItem(IDC_MYMENUITEM);
так я тоже пробовал - выгоняют Lex, сейчас попробую. вот ещё вопрос: вставляя в деструктор вызов exit - чего при этом происходит? я натолкнулся на эту функцию почти наобум, но она решает некоторые проблемы при выходе из проги в неподходящие для этого моменты. Нехороших последствий не заметил - но может я что-то пропустил? CUnBin1alfView::~CUnBin1alfView() { exit(0); }
|
|
|
Записан
|
|
|
|
Гром
Птычк. Тьфу, птычник... Вот!
Готовлюсь к пенсии
Offline
Пол:
Бодрый птах
|
|
« Ответ #4 : 29-12-2003 18:22 » |
|
Алексей1153, напиши что именно надо сделать и под чем - если MFC то работа одна - если АПИ - то другая...
|
|
|
Записан
|
А птичку нашу прошу не обижать!!!
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
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 Боец невидимого фронта Джон
|
|
|
Записан
|
|
|
|
Гром
Птычк. Тьфу, птычник... Вот!
Готовлюсь к пенсии
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 цикл обработки спрятан - поясни.
|
|
|
Записан
|
А птичку нашу прошу не обижать!!!
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #9 : 30-12-2003 21:12 » |
|
1) пробую поставить ClosePort() в OnClose() без exit(0) в деструкторе... результат: если при открытом порте Alt+F4, то прога остаётся в списке процессов, и пока она там, порт не открывается вновь запущеной прогой. Добавление exit(0) в деструктор лечит данный спецэффект... Да, о птичках, что такое эта функция - exit?
Упс... Что бы мы делали без кнопки RESET?
2)пробую с другим потоком...
|
|
|
Записан
|
|
|
|
Гром
Птычк. Тьфу, птычник... Вот!
Готовлюсь к пенсии
Offline
Пол:
Бодрый птах
|
|
« Ответ #10 : 30-12-2003 22:04 » |
|
Алексей1153, функция ехит - тебе не нужна - в винде ты не выйдешь таким образом из программы Это старый способ завершения колнсольных програм и до сих пор действенный в Никсах. Собственно и в винде - если писать консоль. ехит в деструкторе нонсенс. Деструктор основного класса - лобального - вызывается в момент уничтожения объекта программы - т.е. при выходе ихз нее - уже начавшемся, а ты в нем еще раз выход вызываешь 2. Не попробуй - а сделай - много проблем снимешь. :!:
|
|
|
Записан
|
А птичку нашу прошу не обижать!!!
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
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++ »
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
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 Боец невидимого фронта Джон
|
|
|
Записан
|
|
|
|
Гром
Птычк. Тьфу, птычник... Вот!
Готовлюсь к пенсии
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++ »
|
Записан
|
А птичку нашу прошу не обижать!!!
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
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 *)'
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
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Заранее благодарствуем, до свидания.
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #19 : 01-01-2004 18:52 » |
|
ВСЕХ С НОВЫМ ГОДОМ ОПЯТЬ!!! ГРОМ, поток потёк Джончик, мне расслабляться сейчас не можно, нет времени. За время - спасибо, всё работает . только "%s %d %s %d %02d:%02d:%02d" - зачем нужны "%s %d %s %d ? kasper, будем знакомы. Вливайся - сайт суперский. Научим чему сможем! А какие советы? Поточнее бы.
|
|
|
Записан
|
|
|
|
Гром
Птычк. Тьфу, птычник... Вот!
Готовлюсь к пенсии
Offline
Пол:
Бодрый птах
|
|
« Ответ #20 : 01-01-2004 19:07 » |
|
Алексей1153, обращайтесь - если что - ты кстати - не забудь синхронизацию на данные поставить
|
|
|
Записан
|
А птичку нашу прошу не обижать!!!
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #21 : 01-01-2004 20:04 » |
|
синхронизацию
Как это сделать? ГРОМ, Алексей1153, обращайтесь
- промахнулся что-ли?
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
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 Боец невидимого фронта Джон
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
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? Пока отвечаешь, буду разбираться ...
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #25 : 03-01-2004 17:24 » |
|
Джон, я сделал так (но на те вопросы ты всё равно ответь) :
1)завёл в классе CUnBin1alfApp объекта theApp переменную для флага 2)подружил MainFrame и View с CUnBin1alfApp и сказал обоим, что extern CUnBin1alfApp theApp; 3) В любом месте MainFrame или View theApp.флаг
И всё! Ж: )
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #26 : 06-01-2004 16:13 » |
|
Как сделать ожидание байта в порту в течении нек времени и как узнать что это время вышло?
|
|
|
Записан
|
|
|
|
Гром
Птычк. Тьфу, птычник... Вот!
Готовлюсь к пенсии
Offline
Пол:
Бодрый птах
|
|
« Ответ #27 : 06-01-2004 17:02 » |
|
Алексей1153, поставь нужный тайм аут - по истечении него неблокирующий read - выдаст тебе что символа нету.
|
|
|
Записан
|
А птичку нашу прошу не обижать!!!
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #28 : 06-01-2004 19:35 » |
|
неблокирующий read
это как? можно с примером?
|
|
|
Записан
|
|
|
|
Гром
Птычк. Тьфу, птычник... Вот!
Готовлюсь к пенсии
Offline
Пол:
Бодрый птах
|
|
« Ответ #29 : 06-01-2004 20:21 » |
|
Ммммм. Когда все выставлено ты читаешь функцией ReadFile() Параметры я не помню, но поскольку приход отказа - типа данных нет приходит по тайм ауту - то какое то значение эта функция будет возвращать отдавая управление потоку.
Я счас точно не помню...
Однако дабы не морозить себе голову , скажи - ты пытаешься синхронизовать работу потока с приходом данных , дабы он спал, пока не придет блок данных???
Если да то сделай в форуме поиск WaitCommEvent или посмотри эту функцию в MSDN - она ждет пока не придут данные с внешнего источника, и отдает управление - имеет выставляемые параметры на какие события реагировать...
|
|
|
Записан
|
А птичку нашу прошу не обижать!!!
|
|
|
|