Алексей++
глобальный и пушистый
Глобальный модератор
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 ? Они создаются, когда в них первый раз пишешь или уже ранее созданы? Можно ли энто использовать вообще для сохранения настроек (допустим последние настройки порта - чтобы в следующий раз открывать с теми же настройками) ?
|
|
|
Записан
|
|
|
|
|