Šta je novo?

pomoc oko C++...

rocky

Čuven
Učlanjen(a)
25.07.2003
Poruke
39
Poena
604
Problem je sledeci:
Kod funkcije glavnog dijaloga programa sadrzi sledece linije:

UpdateData(TRUE);
m_mdlg=new CDialog2(this);
m_mdlg->m_broj = m_brojtel ;
m_mdlg->Create();
GetDlgItem(IDC_EDIT1)->EnableWindow(FALSE);
GetDlgItem(IDC_EDIT2)->EnableWindow(FALSE);
CString komanda = "ATX3E0L3T\r";
Port.SendData(komanda, komanda.GetLength());
Sleep(5000); //5 SEKUNDe CEKANJA...
... i tako dalje

Problem je u tome sto se linije GetDlgItem(IDC_EDIT1)->EnableWindow(FALSE);,GetDlgItem(IDC_EDIT2)->EnableWindow(FALSE); ne izvrsavaju sve dok Sleep ne istekne. Takodje, ni linija m_mdlg->m_broj = m_brojtel ; koja ubacuje neki tekst u pomocni dijalog CDialog2 ne radi to sto treba dok ne istekne Sleep. Pri tome linija m_mdlg->Create(); radi i prikaze se dijalog bez teksta. Iste stvari se desavaju ukoliko u kodu postoji while petlja.
Samo da napomenem da ukoliko nema Sleep funkcije ili while petlje sve radi kako treba.
Pitanje je,dakle, da li postoji neko resanje ovog problema ili da li postoji neki drugi mehanizam koji radi isto sto i Sleep a da ne pravi ove *****e probleme.
Ako neko ima resenje castim pivom. :beer:
 
Ne sme tu da stoji Sleep(); ili bilo koja druga operacija koja se izvršava malo duže. Nisi napisao u kojoj tačno funkciji se ovo nalazi, ali na tom mestu se prekida izvrašavanje glavnog thread-a programa... Znači dok se ne završi Sleep() ili ta while petlja, ne izvršava se ni OnDraw() ni ostale funkcije. Dok ne istekne to Sleep() program uopšte ne reaguje (ne možeš da klikneš ni na jedno dugme, ne iscrtavaju se kontrole...).

Sve duže operacije puštaj kao odvojene thread-ove sa AfxBeginThread().
 
Poslednja izmena:
Probao sam sa AfxBeginThread na sledeci nacin:
Funkcija koja treba da se u thread-u izvrsava ima sledecu definiciju:

UINT CSerialTesterDlg::SlusanjePorta(LPVOID pParam)
{ CSerialTesterDlg* object = (CSerialTesterDlg*) pParam;
Sleep(3000);
if (Port.ReadDataWaiting() > 0)
{ Sleep(5000);
int nasao = -1;
while (nasao == -1){
char bafer[100];
CString niz;
Port.ReadData(&bafer,100);
niz=bafer;
nasao = niz.Find("CONNECT");
}
}
return 0;
}
CserialTesterDlg je klasa glavnog dijaloga cija je funkcija SlusanjePorta clanica. AfxBeginThread stavio sam u drugu funkciju clanicu glavnog dijaloga kao AfxBeginThread(SlusanjePorta, this). Medjutim kada prevodim program javlja se greska:

error C2665: 'AfxBeginThread' : none of the 2 overloads can convert parameter 1 from type 'unsigned int (void *)'
 
rocky je napisao(la):
AfxBeginThread(SlusanjePorta, this). Medjutim kada prevodim program javlja se greska:
error C2665: 'AfxBeginThread' : none of the 2 overloads can convert parameter 1 from type 'unsigned int (void *)'

AfxBeginThread(CSerialTesterDlg::SlusanjePorta, this, THREAD_PRIORITY_NORMAL);
 
******, opet mi prijavljuje istu gresku
 
Onda nisi deklarisao funkciju CSerialTesterDlg::SlusanjePorta kao static.
Funkcija mora da bude deklarisana kao static (ne pripada ni jednom objektu klase - može da se pozove pre nego što kreiraš objekat i u njoj ne postoji pokazivač this). U protivnom bi pustio funkciju koja pripada određenom objektu. Objekat možeš da uništiš pre nego što se završi thread... i eto runtime greške. :)


edit:
Znači samo u header-u (SerialTesterDlg.h) ispred UINT SlusanjePorta(LPVOID pParam); ubaciš static:
Kod:
static UINT SlusanjePorta(LPVOID pParam);
 
Poslednja izmena:
Zasto ne jednostavno ne koristis tajmere umesto novog threada ili (jos gore) sleep-a?
 
3MaJ je napisao(la):
Zasto ne jednostavno ne koristis tajmere umesto novog threada ili (jos gore) sleep-a?

Timeri mu neće pomoći ni malo. Funkcija koja se izvršava kada se primi poruka WM_TIMER (recimo OnTimer()) se izvrašava u glavnom thread-u. Znači dok se ona ne završi program ne reaguje na kontrole (već sam gore to napisao).

Probaj da napraviš običnu dialog based application, ostavi ona dva default dugmeta (OK i Cancel) i u OnInitDialog pokreni jedan timer sa intervalom od recimo 10 sekundi. U OnTimer funkciji stavi jedan AfxMessageBox da te obavesti kada se desio WM_TIMER, i posle toga stavi Sleep(5000) - da simulira neki kod kome treba 5 sekundi da se izvrši. Kada budeš kliknuo na OK na tom message box-u, program ti neće reagovati sledećih 5 sekundi - nećeš moći da klikneš ni na OK ni na Cancel (niti će se bilo šta drugo dešavati sa njim). Znači još jednom: Sve operacije koje traju duže nego što korisnik može da primeti se puštaju u odvojenim thread-ovima.
 
Deklarisao sam funkciju kao static. Program sa preveo bez greske,ali nisam stigao da istestiram jos da li sve radi kako treba. Tek cu stici sutra,daj boze da sve radi dobro pa mozemo na pivo..
 
E sta je sad problem. U mojoj thread funkciji:
UINT CSerialTesterDlg::SlusanjePorta(LPVOID pParam)
{
CSerialTesterDlg* prt = (CSerialTesterDlg*) pParam;
Sleep(15000);
if (prt->Port.ReadDataWaiting() > 0)
{ Sleep(0);
int nasao = -1;
while (nasao == -1)
{
char bafer[100];
CString niz;
prt->Port.ReadData(&bafer,100);
niz=bafer;
int nasao = niz.Find("CONNECT");
}
delete ptr->m_pDlg;
}


return 0;
}
ne radi linija delete ptr->m_pDlg; koja treba da izbrise pomocni dijalog na koji pokazuje m_pDlg. Da napomenem CDialog2* m_pDlg je public clanica promenljiva glavnog dijaloga i u funkciji clanici glavnog dijaloga u kojoj sa pokrece thread ima linija m_pDlg=new CDialog2(this); Inace thread se pokrece linijom AfxBeginThread(SlusanjePorta,this);
 
rocky je napisao(la):
ne radi linija delete ptr->m_pDlg; koja treba da izbrise pomocni dijalog na koji pokazuje m_pDlg. Da napomenem CDialog2* m_pDlg je public clanica promenljiva glavnog dijaloga i u funkciji clanici glavnog dijaloga u kojoj sa pokrece thread ima linija m_pDlg=new CDialog2(this);

:smash: Ne smeš iz thread-u da obrišeš dijalog. Dobićeš runtime error. Prebaci tu liniju negde drugde.
 
Kako da zatvorim modalni dijalog koji nema nijedno dugme?
 
rocky je napisao(la):
Kako da zatvorim modalni dijalog koji nema nijedno dugme?

Jesi ga pustio sa DoModal() ili sa Create(IDD_......, this)?
Ako si ga napravio sa Create, onda iz Thread-a možeš da ga sakriješ sa ptr->m_pDlg->ShowWindow(SW_HIDE). Najbolje bi bilo da u OnInitDialog() glavnog dijaloga kreiraš ovaj pomoćni dijalog:

m_pDlg = new CDialog2(this); // umesto CDialog2 ime tog pomoćnog dijaloga

m_pDlg->Create(IDD_DIALOG2, this); //umesto IDD_DIALOG2 IDD pom. dijaloga
dlg2->ShowWindow(SW_HIDE);

I onda kada hoćeš da ga prikažeš samo uradiš m_pDlg->ShowWindow(SW_SHOW); Uništavaš ga tek na kraju programa (WM_DESTROY glavnog dijaloga) sa delete m_pDlg;

edit:
Zaboravio sam da napišem... Ako hoćeš da ti dijalog bude "on top", u properties dijaloga System modal postavi na true.
 
Poslednja izmena:
Tooo Zeleni Zube Kralju Moj, Napokon Sve Radi Kako Treba. Dva Dana Se Mucim Sa Ovim Stvarima,da Nije Tebe Bilo Ko Zna Koliko Bi To Trajalo. Ako Si Raspolozen Da Te Castim Picem Ja Sam U Studenjaku (tel. 0113103600).drasko
 
Nazad
Vrh Dno