Cum pot trimite un CString prin PostMessage ?
-
- Membru++
- Posts: 687
- Joined: 10 Sep 2008, 21:40
- Judet: Cluj
Cum pot trimite un CString prin PostMessage ?
Cum se poate trimite un CString prin ::PostMessage(...) ? Si apoi cum se poate "recupera" ? Eu l-am trimis ca lParam , dar nu am reusit sa-l recuperez pentru a-l folosi ...
Nu cred ca are rost sa pun codul pe care l-am incercat eu de vreme ce nu functioneaza ...
Nu cred ca are rost sa pun codul pe care l-am incercat eu de vreme ce nu functioneaza ...
- Marius Bancila
- Fondator
- Posts: 2344
- Joined: 11 Jul 2007, 11:45
- Judet: Timiş
- Location: Timisoara
- Contact:
Re: Cum pot trimite un CString prin PostMessage ?
Atentie, PostMessage pune mesajul in coada ferestrei si revine. Apelantul continua ruleze, nu e cu blocare ca la SendMessage. Din aceasta cauza, nu sti cand este tratat mesajul trimis. Probabil tu folosesti o variabila locala, care iese din scop si se distruge inainte ca destinatarul sa trateze mesajul tau. Ar fi mai multe optiuni. Prima ar fi sa folosesti SendMessage, dar asta depinde de ce faci tu exact. Alta optiune e sa folosesti o variabila CString care nu e distrusa in momentul in care se trateaza mesajul; poate fi de exemplu membra a unei clase, stiu eu. Si o a treia ar fi sa aloci variabila CString pe heap, sa pasezi pointerul la ea odata cu PostMessage, iar in handlerul mesajului dupa ce ai folosit-o sa o stergi. Atentie, aici ai o problema daca trimiti acelasi mesaj la mai multe ferestre si fiecare vrea sa stearga acelasi obiect de pe heap.
-
- Membru++
- Posts: 687
- Joined: 10 Sep 2008, 21:40
- Judet: Cluj
Re: Cum pot trimite un CString prin PostMessage ?
Acel mesaj il trimit dintr-un thread , deci nu pot folosi SendMessage ... asta inseamna ca nu am nici o solutie sigura ? ( Ultima solutie propusa de tine are o rezerva )
- Silviu Ardelean
- Senior
- Posts: 1175
- Joined: 12 Jul 2007, 09:22
- Contact:
Re: Cum pot trimite un CString prin PostMessage ?
Cum sa nu poti?
O faci ca si cu PostMessage() si in plus ai avantajul ca sti cand mesajul a fost trata in thread-ul destinatie... spre deosebire de situatia in care folosesti PostMessage(). In threadul curent se opreste executia pana iti vine raspunsul ca s-a tratat mesajul tau.
O faci ca si cu PostMessage() si in plus ai avantajul ca sti cand mesajul a fost trata in thread-ul destinatie... spre deosebire de situatia in care folosesti PostMessage(). In threadul curent se opreste executia pana iti vine raspunsul ca s-a tratat mesajul tau.
- Silviu Ardelean
- Senior
- Posts: 1175
- Joined: 12 Jul 2007, 09:22
- Contact:
Re: Cum pot trimite un CString prin PostMessage ?
Iti recomand ideea sa folosesti SendMessage() si alocarea temporara pe heap.
Iata un exemplu:
Iar in threadul principal ai o metoda de tratare a mesajului tau:
Daca vrei sa trimiti mesajul intre mai multe thread-uri secundare (nu thread-ul principal) atunci trebuie sa intrii la sincronizari.
Iata un exemplu:
Code: Select all
// in threadul tau de unde vrei sa trimiti mesajul
CString* sOutMsg = new CString();
*sOutLog = _T("your message");
pThis->SendMessage(MYMSG_UpdateData, 0, (LPARAM) sOutMsg);
Code: Select all
LRESULT CYourMainThreadClass::OnYourMessagehandler(WPARAM wParam, LPARAM lParam)
{
CString* pobject = (CString*)lParam;
if(pobject != NULL)
{
UpdateData(TRUE);
m_sData += *pobject;
m_sData += L" \r\n";
delete pobject;
UpdateData(FALSE);
}
return 0;
}
Last edited by Silviu Ardelean on 26 Nov 2010, 17:58, edited 1 time in total.
- cristianamarie
- Membru++
- Posts: 480
- Joined: 12 Mar 2009, 18:47
- Judet: Iaşi
- Location: Iasi
Re: Cum pot trimite un CString prin PostMessage ?
Nu ai cum sa trimiti nici un pointer direct prin PostMessage.mesajflaviu wrote:Cum se poate trimite un CString prin ::PostMessage(...) ? Si apoi cum se poate "recupera" ? Eu l-am trimis ca lParam , dar nu am reusit sa-l recuperez pentru a-l folosi ...
Nu cred ca are rost sa pun codul pe care l-am incercat eu de vreme ce nu functioneaza ...
1. Poti sa il aloci cu un new CString si faci post (dar mai bine LPTSTR alocat decit CString), dar exista riscul sa nu fie procesat si ramine leak.
2. Poti sa il pui intr-o tabela globala de CString, il inserezi, iei indexul, si trimiti indexul in LPARAM in PostMessage. Trebuie sa rezolvi concurenta aici, dar fiind doar insert de unde faci post si read de unde vine mesajul, nu prea sint mari probleme.
3. IPC (dar WM_COPYDATA nu merge cu post, doar send) - ce mecanism vrei tu, dar e o variatiune a punctului 2.
Nuclear launch detected
- Marius Bancila
- Fondator
- Posts: 2344
- Joined: 11 Jul 2007, 11:45
- Judet: Timiş
- Location: Timisoara
- Contact:
Re: Cum pot trimite un CString prin PostMessage ?
Ce vrei sa zici? Poti sa trimiti un pointer, dar trebuie sa fie clar ca obiectul pointat nu poate sa fie distrus inaintea tratarii mesajului. Daca conditia asta se indeplineste nu sunt probleme. Altfel da, sigur ca nu merge.Nu ai cum sa trimiti nici un pointer direct prin PostMessage.
Silviu, in cazul folosirii lui SendMessage nu vad de ce ai mai aloca obiectul CString pe heap, si cu atat mai putin de ce handlerul distruge obiectul, ar putea s-o faca cel care trimite mesajul.
- Silviu Ardelean
- Senior
- Posts: 1175
- Joined: 12 Jul 2007, 09:22
- Contact:
Re: Cum pot trimite un CString prin PostMessage ?
Intr-adevar , aceasta abordare se preteaza obligatoriu pentru PostMessage(). Pentru SendMessage() nu mai e neaparat necesara alocarea pe heap.Marius Bancila wrote:Silviu, in cazul folosirii lui SendMessage nu vad de ce ai mai aloca obiectul CString pe heap, si cu atat mai putin de ce handlerul distruge obiectul, ar putea s-o faca cel care trimite mesajul.
- cristianamarie
- Membru++
- Posts: 480
- Joined: 12 Mar 2009, 18:47
- Judet: Iaşi
- Location: Iasi
Re: Cum pot trimite un CString prin PostMessage ?
Da, evident. Nu m-am exprimat fericit - normal ca se poate, dar trebuie rezolvate lifetime+owner+access, da.Marius Bancila wrote:Ce vrei sa zici? Poti sa trimiti un pointer, dar trebuie sa fie clar ca obiectul pointat nu poate sa fie distrus inaintea tratarii mesajului.Nu ai cum sa trimiti nici un pointer direct prin PostMessage.
Nuclear launch detected
- Ovidiu Cucu
- Fondator
- Posts: 3778
- Joined: 11 Jul 2007, 16:10
- Judet: Iaşi
- Location: Iasi
- Contact:
Re: Cum pot trimite un CString prin PostMessage ?
- Daca mesajul este postat la un singur thread aflat in acelasi proces, de obicei schema aloca si posteaza -> proceseaza si elibereaza, merge fara prea multe batai cap, sincronizari, si alte briz-brizuri; se poate spune: coada de mesaje asigura "sincronizrea".
La cazul asta ar mai trebui totusi adaugat: string-ul / bufferul este transmis cu o frecventa rezonabila si este procesat intr-un timp rezonabl in asa fel incat sa nu "dea-n foc"coada de mesaje.
- Daca mesajul este postat la mai multe threaduri, atunci da, trebuie sa ma asigur ca nu se sterge pointerul pasat inainte ca mesajul sa fie procesat in toate thread-urile.
- Daca mesajul este pentru un thread din alt proces, atunci Post(Thread)Message sare din schema si trebuie folosita o alta metoda de IPC.
Pun pariu ca probema lui mesajflaviu se incadreaza in cazul 1.

Am atasat un exemplu in care se posteaza un pointer la CString din N thread-uri worker la fereastra principala a aplicatiei.
E totusi o mica sincronizare acolo, nu pentru a nu se incurca thread-urile intre ele, ci pentru a a asigura ca fiecare thread isi termina treaba si a evita astfel problema memory leaks de care amintea Cristian.
- Attachments
-
- TestMsg.zip
- (8.89 KiB) Downloaded 367 times
Ovidiu
Follow http://twitter.com/#!/ovidiucucu
Weblog: http://codexpert.ro/blog/author/ovidiu-cucu/
Visit FAQ, Tips & Tricks
Follow http://twitter.com/#!/ovidiucucu
Weblog: http://codexpert.ro/blog/author/ovidiu-cucu/
Visit FAQ, Tips & Tricks
-
- Membru++
- Posts: 687
- Joined: 10 Sep 2008, 21:40
- Judet: Cluj
Re: Cum pot trimite un CString prin PostMessage ?
Va multumesc tuturor pentru solutii , ( Ovidiu , e didactic exemplul , multumesc ) .
Si eu am rezolvat intr-un mod similar problema :
In thread am :
iar in evenimentul care trateaza mesajul :
Si eu am rezolvat intr-un mod similar problema :
In thread am :
Code: Select all
CString sTemp = "Unknown error";
CString* sError = new CString(sTemp);
::PostMessage(m_hwndView,WM_USER_WORK_ERROR,(WPARAM)0,(LPARAM)(LPCSTR)sError);
Code: Select all
LRESULT CRegistruCoView::OnWorkError(WPARAM wParam, LPARAM lParam)
{
CString* sError = (CString*)lParam;
CString& sTemp = *sError;
GetDocument()->DoSomething(sTemp);
delete sError;
return 0;
}
- Ovidiu Cucu
- Fondator
- Posts: 3778
- Joined: 11 Jul 2007, 16:10
- Judet: Iaşi
- Location: Iasi
- Contact:
Re: Cum pot trimite un CString prin PostMessage ?
O mica observatie: acel sTemp n-are nici un rost. Mai mult incurca decat ajuta.
Este suficient:
respectiv

Este suficient:
Code: Select all
CString* pError = new CString(_T("Unknown error"));
::PostMessage(...(LPARAM)pError);
Code: Select all
CString* pError = (CString*)lParam;
GetDocument()->DoSomething(*pError);
delete pError;
Ovidiu
Follow http://twitter.com/#!/ovidiucucu
Weblog: http://codexpert.ro/blog/author/ovidiu-cucu/
Visit FAQ, Tips & Tricks
Follow http://twitter.com/#!/ovidiucucu
Weblog: http://codexpert.ro/blog/author/ovidiu-cucu/
Visit FAQ, Tips & Tricks