Алексей++
глобальный и пушистый
Глобальный модератор
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 - она ждет пока не придут данные с внешнего источника, и отдает управление - имеет выставляемые параметры на какие события реагировать...
|
|
|
Записан
|
А птичку нашу прошу не обижать!!!
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
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++ »
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #31 : 07-01-2004 08:33 » |
|
CWinThread::ExitInstance() - это убьёт товарища Потока?
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #32 : 07-01-2004 09:16 » |
|
ГРРРРРОМУШКА! Спасибо! Я понял! Всё ведь действительно проще чем на самом деле - нужно всего лишь в структуре COMMTIMEOUTS portCommTimeOuts; задать при открытии порта portCommTimeOuts.ReadTotalTimeoutConstant = TimeOutWait; где TimeOutWait - в миллисекундах и, блин, проц больше не такой задумчивый, как с потоком!!! всё, пойду прогуляюсь, вернусь ночью. 8)
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #33 : 09-01-2004 18:47 » |
|
CWinThread::ExitInstance() - это убьёт товарища Потока?
а всё-таки? и если нет, то как это сделать кроме как глобальными флагами?
|
|
|
Записан
|
|
|
|
Джон
просто
Администратор
Offline
Пол:
|
|
« Ответ #34 : 12-01-2004 16:37 » |
|
Джон, я сделал так (но на те вопросы ты всё равно ответь) :
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."
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
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++ »
|
Записан
|
|
|
|
Джон
просто
Администратор
Offline
Пол:
|
|
« Ответ #36 : 18-07-2004 21:51 » |
|
оно появляется в 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."
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
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++ »
|
Записан
|
|
|
|
Джон
просто
Администратор
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."
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
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++ »
|
Записан
|
|
|
|
Джон
просто
Администратор
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."
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
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++ »
|
Записан
|
|
|
|
Джон
просто
Администратор
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."
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
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++ »
|
Записан
|
|
|
|
Джон
просто
Администратор
Offline
Пол:
|
|
« Ответ #44 : 21-07-2004 08:04 » |
|
а у меня он будет неправильно введённые числа превращать в правильные:
"Не советую, гражданин... мнэ-э... не советую. Съедят" (с) Это зачем же так распускать юзеров!!! :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."
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
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; } ?
|
|
|
Записан
|
|
|
|
Джон
просто
Администратор
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."
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
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) Возможно ли создать диалог один раз в конструкторе вьюхи, а потм - когда надо появлять или скрывать, не удаляя?
|
|
|
Записан
|
|
|
|
Джон
просто
Администратор
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."
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
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++ »
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #50 : 23-07-2004 18:49 » |
|
Джон, чего-то не могу ничего с диалогами... Остановился на такой схеме - LT6View.h 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++ »
|
Записан
|
|
|
|
Джон
просто
Администратор
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."
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #52 : 25-07-2004 04:47 » |
|
"садитесь, пять!" (c) Джон, практически правильно, только - надо уметь грубо прервать (а то скучно)
это надо в случае, если удовольствие растягивается слишком надолго, Пока не сделала её нельзя закрывать
ага чтоб таки закончить прогу
нет, не закончить прогу, а прервать ОПЕРАЦИЮ; прога продолжается, и особо терпеливые могут снова попытаються выполнить операцию
|
|
|
Записан
|
|
|
|
Джон
просто
Администратор
Offline
Пол:
|
|
« Ответ #53 : 25-07-2004 20:36 » |
|
"садитесь, пять!" (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."
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
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); - а это, я так понимаю, и есть "убить поток"?
|
|
|
Записан
|
|
|
|
Джон
просто
Администратор
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."
|
|
|
Джон
просто
Администратор
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."
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #57 : 27-07-2004 04:46 » |
|
Джон, спасибо то что надо
|
|
|
Записан
|
|
|
|
Джон
просто
Администратор
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."
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #59 : 28-07-2004 09:27 » |
|
Джон - я как маленький ребёнок, чем больше объясняешь, тем больше у меня вопросов вот эти: WriteProfileString("ModelessDlg","Position",stPos) GetProfileString("ModelessDlg","Position") куда они пишут - в реестр что-ли? и что значат Section и Entry ? Они создаются, когда в них первый раз пишешь или уже ранее созданы? Можно ли энто использовать вообще для сохранения настроек (допустим последние настройки порта - чтобы в следующий раз открывать с теми же настройками) ?
|
|
|
Записан
|
|
|
|
Джон
просто
Администратор
Offline
Пол:
|
|
« Ответ #60 : 28-07-2004 14:03 » |
|
Джон - я как маленький ребёнок, чем больше объясняешь, тем больше у меня вопросов Это показывает, что ты что-то понял. Не помню кто, но кто-то увольнял сотрудников, если они после получения задания не задавали вопросов. К вопросу: Это прелести 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."
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #61 : 28-07-2004 17:57 » |
|
супер :arrow: Я что-то не помню где я про " Section и Entry " написал - напомни.
ты не писал - это я про них писал Да это VC такой список параметров этоу функции показал. зы. у тебя колобайт сообщений намечается
|
|
|
Записан
|
|
|
|
Джон
просто
Администратор
Offline
Пол:
|
|
« Ответ #62 : 29-07-2004 08:16 » |
|
зы. у тебя колобайт сообщений намечается Ну дык, готовимся. Хотя в 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
А сейчас они пишут в реестр.
|
|
|
Записан
|
|
|
|
Джон
просто
Администратор
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."
|
|
|
|