Text-Strings aus Thread in den Dialog bringen...
-
Bitte schlagt mich nicht, ich habe hier wirklich erstmal gesucht, aber ich finde nichts dazu:
Ich möchte über eine User-definierte Message Text-Meldungen von einem Thread an meinen Dialog senden und sie dort weiterverarbeiten.
Aber wie genau kann ich in meiner Nachricht Text unterbringen?::PostMessage(hWnd, WM_USER_THREAD_INFO, (WPARAM)[HIER ZEIGER ODER REFENZ AUF TEXT?], 0);Thx schonmal für Eure Hinweise

Gruß T.
-
Wenn's nur an ein edit/static oder so gehen soll:
LPCTSTR str = _T("Hallo Welt!"); PostMessage(hwnd_of_Control, WM_SETTEXT, 0, (LPARAM) str);- Text geht ins LPARAM
- Zeiger auf text nach LPARAM gecastet
- Die Win32 API stellt bei WM_SETTEXT sicher, daß der String kopiert wird
(ist wichtig!! der String könnte ja temporär sein: z.B.
[cpp]
if (foo)
{
CString s = ....;
PostMessage(hwnd,WM_MY_MESSAGE, 0, (LPARAM) (LPCTSTR) s);
// < hier wird s freigegeben
// kann aber sein der message-handler wurde noch gar nicht aufgerufen -
// lParam enthält ungültigen Zeiger
}
Wenn du den String in der Dialog-Klasse noch nachbearbeiten willst, wird es etwas komplizierter:
a) entweder SendMessage, das wartet bis die message abgearbeitet wurde (bremst aber evtl.)
b) allozierst den string im thread und gibst iihn im message-Handler frei (musst aber sicherstellen, daß der Handler auch wirklich aufgerufen wird, und nicht z.B. der Dialog zwischendrin freigegeben wird)
c) String in einem geshareten Puffer / CString-Variable (mit Critical Section schützen!)
d) ein Mechanismus wie die MFC Temp Maps (allozierte objekte werden in einem Container gespeichert und im OnIdle-Handler freigegeben)
-
OK, das waren schonmal gute Tipps!
Jetzt habe ich sinngemäß folgenden Code geschrieben:UINT CMyDlg::thrFunction(LPVOID pParam) { CMyDlg* pDlg = (CMyDlg*)pParam; HWND hWnd = pDlg->m_hWnd; HWND hCtrl = ::GetDlgItem(hWnd,IDC_INFO_DISPLAY); ASSERT(IsWindow(hWnd)); ASSERT(IsWindow(hCtrl)); CString strInfo = _T("BlaBla..."); //Funzt nicht: //::PostMessage(hCtrl,WM_SETTEXT ,0,(LPARAM)(LPCTSTR)strInfo); //Funzt: pDlg->GetDlgItem(IDC_INFO_DISPLAY)->SetWindowText(strInfo); return (UINT)0; }Fragen:
1.Wieso kommt bei Postmessage nichts in meinem Static an?
2.Wäre die Variante mit SetWindowText wirklich threadsafe? SetWindowText basiert ja auf WM_SETTEXT, im Prinzip sollte es ja OK sein, oder?Thx schonmal + Gruß

-
so, nun habe ich's mit einem API-Aufruf gemacht:
::SetDlgItemText(hWnd, IDC_INFO_DISPLAY, strInfo);Bis dann!

-
Mag sein das ich mich mit dem "PostMessage behandelt WM_SETTEXT speziell" irre - ich kann jedenfalls nix dazu in der MSDN finden.

Die WindowProc wird immer in dem Thread ausgefuehrt, der das Fenster erzeugt hat. SendMessage wartet immer, bis die WIndowProc abgearbeitet ist, damit ist das SetWindowText (bzw. ein SendMessage(WM_SETTEXT) threadsicher.
PostMessage wäre effektiver, da der Threadswitch nicht sofort erzwungen wird. Wenn du den Thread nur hast, damit das Userinterface "aktiv" bleibt, macht das ueberhaupt nix. Wenn du allerdings prozessorintensives Background-Prozessing hast, das wirklich so schnell wie möglich gehen soll, und die Textupdates recht haeufig kommen, würde ich zu einem mit einer Critical Section geschützten geshareten CString greifen.
WM_SETTEXT usw. an einen anderen PROZESS werden korrekt behandelt.