Nachricht von Hauptfenster an Dialog
-
hi Leute,
ich möchte vom Hauptfenster aus (hWnd) ein Dialogfeld (hDlg) Öffnen.
Das ist ja kein Problem.Doch nachdem ich den Button zum Öffnen drücke möchte ich das der Dialog sich öffnet und Daten die in einer globalen Variable gespeichert sind in
Editfensten in diesem Dialog ausgeben.Problem:
ich kann ja nicht einfach SetDlgItemText(hDlg, .....) eingeben,
da ich mich in hWnd befinde.Wie mach ich das?
-
metapoint2011 schrieb:
da ich mich in hWnd befinde.
Versteh ich nicht.
Und klar kannst du damit den Text des Edit Controlls setzen. Du behandelst die Nachricht WM_INITDIALOG im Eventhandler deines Dialogs und rufst SetDlgItemText(...) auf.
-
aba ich ich öffne das fenster mit WM_COMMAND aus meinem Hauptfenster.
und wenn ich dort SetDlgItemText(hDlg,..) eingebe gehts das nicht.
weil hDlg sich in einem neuen Thread befindet.die so aussieht
BOOL CALLBACK NeuerEintrag(HWND hDlg, ......)
{}
-
metapoint2011 schrieb:
aba ich ich öffne das fenster mit WM_COMMAND aus meinem Hauptfenster.
und wenn ich dort SetDlgItemText(hDlg,..) eingebe gehts das nicht.
weil hDlg sich in einem neuen Thread befindet.die so aussieht
BOOL CALLBACK NeuerEintrag(HWND hDlg, ......)
{}
Nun, irgendwie scheint mir das ganze Konstrukt nicht ganz geheuer....
Wieviele Threads hat Deine Applikation?
Das Hauptfenster hat Deine App erzeugt? Mit CreateWindowEx()?
Das zweite Fenster hat auch Deine App erzeugt? Mit CreateWindowEx()? Im selben Thread?Und Du versuchst von einem anderen Thread (aus Deiner App!) aus das zweite Fenster zu öffnen?
Nun das macht man entweder
a) wieder mit CreateWindowEx() (nachdem das Fenster zerstört wurde)
b) oder mit ShowWindow( SW_SHOW ) (nachdem das erzeugte Fenster mit ShowWindow( SW_HIDE ) unsichtbar gemacht wurde.Ist es so?
Martin
-
also hier mal der code, gekürzt. Das du verstehst wies ausgebaut ist.
#include "stdafx.h" #include "Kundendatenbank 1.5.h" #include "stdio.h" ............... ATOM MyRegisterClass(HINSTANCE hInstance); BOOL InitInstance(HINSTANCE, int); LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); BOOL CALLBACK NeuerEintrag(HWND, UINT, WPARAM, LPARAM); int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) { ...................... ATOM MyRegisterClass(HINSTANCE hInstance) { WNDCLASSEX wcex; wcex.cbSize = sizeof(WNDCLASSEX); wcex.style = CS_HREDRAW | CS_VREDRAW; ............................ return RegisterClassEx(&wcex); } BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) { HWND hWnd; hInst = hInstance; hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 300, 520, NULL, NULL, hInst, NULL); if (!hWnd) { return FALSE; } ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); return TRUE; } LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { static HWND hWndBtn1, hWndBtn2, hWndBtn3, hWndBtn4, hWndBtn5, hWndBtn6; static HWND hWndEdit1; static HWND hWndList1; static HINSTANCE hInstance; PAINTSTRUCT ps; HBRUSH hBrush; HDC hdc; FILE *datei; switch (message) { case WM_CREATE: /////Hauptfenster hWndList1 = CreateWindow( _T("listbox"), NULL, WS_CHILD | WS_VISIBLE | WS_BORDER | LBS_NOTIFY | LBS_SORT | WS_VSCROLL, 10, 30, 260, 350, hWnd, (HMENU) 1, hInst, NULL); hWndEdit1 = CreateWindow( _T("edit"), NULL, WS_CHILD | WS_VISIBLE | WS_BORDER, 15, 382, 150, 21, hWnd, (HMENU) 2, hInst, NULL); hWndBtn1 = CreateWindow( _T("button"), _T("Suchen"), WS_CHILD | WS_VISIBLE | WS_BORDER, 181, 382, 80, 21, hWnd, (HMENU) 3, hInst, NULL); ................................. hInstance = ((LPCREATESTRUCT) lParam)->hInstance; break; case WM_COMMAND: switch (LOWORD(wParam)) { case 6: /////Neuer Eintrag DialogBox(hInst, MAKEINTRESOURCE(IDD_NEUEREINTRAG), break; case 4: /////Öffnen { .............. .......................... DialogBox(hInst, MAKEINTRESOURCE(IDD_NEUEREINTRAG), hWnd, NeuerEintrag); //////////////////////////HIER Soll der Inhalt einer variable (TCHAR BUffer[500]) ////////////////// ///////////////in die Enditfenster geschrieben werden die im Dialog sind ///////////// } } break; case WM_PAINT: hdc = BeginPaint(hWnd, &ps); SetBkMode(hdc, TRANSPARENT); TextOut(hdc, 13, 10, _T("Nr - Name, Vorname: "), 20); ......... EndPaint(hWnd, &ps); break; case WM_LBUTTONDOWN: SendMessage(hWnd, WM_NCLBUTTONDOWN, HTCAPTION, 0); break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } return 0; } //////////////////////////////////////// // //Dialog // BOOL CALLBACK NeuerEintrag(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_INITDIALOG: return TRUE; case WM_COMMAND: switch(LOWORD(wParam)) { case 14: ............... return TRUE; case IDCANCEL: EndDialog(hDlg, LOWORD(wParam)); return TRUE; } break; } return FALSE; }
-
Das geht an der Stelle nicht, weil DialogBox erst zurückkehrt, wenn der Dialog geschlossen wird.
Du hast doch schon den Hinweis bekommen, daß Du das in der Dialogprozedur bei der Behandlung von WM_INITDIALOG machen sollst!
-
das is ja echt doof das sowas nicht funktioniert. kann ich mir garnicht vorstellen.
muss doch irgentwie mit nem handle oda so gehn.
-
Du kannst auch DialogBoxParam aufrufen und der Dialogbox einen Parameter mit auf den Weg geben. Dieser kann bei WM_INITDIALOG ausgewertet werden.
-
Ich verstehe das Problem nicht. Hauptfenster und Dialogfenster teilen sich denselben Datenbereich. Es ist also jederzeit möglich, mit globalen Daten zu arbeiten, die z.B. in einer Headerdatei beiden bereitgestellt werden. Ansonsten kann man immer noch über benutzerdefinierte Messages zwischen allen offenen Fenstern beliebiges hin- und her schicken.
-
asdwww schrieb:
das is ja echt doof das sowas nicht funktioniert. kann ich mir garnicht vorstellen.
muss doch irgentwie mit nem handle oda so gehn.
Jaja, muss doch irgentwie ...
-
Weil du mit der WinApi und wohl auch C noch wenig vertraut bist, hier einige weitere Hinweise.
1. Global definiert, z.B. char myString[20];
2. Im Hauptfenster Zuweisung auf myString mit z.B. strcpy(myString,"Hallo, du da!)"
3. Im Dialog im Case-Zweig WM_INITDIALOG SetDialogItemText(hDlg,IDD_xxx,myString) einsetzen
Das wäre für deinen Zweck schon alles! Dazu brauchst du keine weiteren Handles! Läuft so und wurde dir bereits so mitgeteilt.

-
berniebutt schrieb:
Weil du mit der WinApi und wohl auch C noch wenig vertraut bist, hier einige weitere Hinweise.
1. Global definiert, z.B. char myString[20];
2. Im Hauptfenster Zuweisung auf myString mit z.B. strcpy(myString,"Hallo, du da!)"
3. Im Dialog im Case-Zweig WM_INITDIALOG SetDialogItemText(hDlg,IDD_xxx,myString) einsetzen
Das wäre für deinen Zweck schon alles! Dazu brauchst du keine weiteren Handles! Läuft so und wurde dir bereits so mitgeteilt.

ja das wusste ich auch selber schon. nur muss der anwender dann nach dem öffnen der box nochmal einen knopf drücken um den inhalt auszugeben.
was zwar nicht schlimm ist aba die bedienung des programms einfach nur komplizierter macht.also seit ihr der Meinung das das nicht funktionieren würde?
-
Also gut, in diesem speziellen Fall brauchst du global benutzerdefinierte Messages mit IDD_XXXX WM_USER+1 und natülich ebenfalls global die beiden FensterHandles hwndMain und hwndDlg. Dann schickst du gezielt aus dem Dialog eine Nachricht an das Hauptfenster eine Nachricht über wParam und oder lParam, was der Anwender gerade gemacht hat. Im Hauptfenster musst du nur einen Case-Zweig für IDD_XXXX einrichten und dort veranlassen, was du willst. Oder du schickst im Dialog die Nachricht IDD_XXXX an den Dialog selbst und veranlasst dort das gewünschte. Es geht alles!
-
berniebutt schrieb:
. Dann schickst du gezielt aus dem Dialog eine Nachricht an das Hauptfenster eine Nachricht über wParam und oder lParam, was der Anwender gerade gemacht hat.
so kommt doch auch die erste nachricht vom dialog.
aber die erste Nachricht komm doch vom Hauptfenster (drücken auf einen button),
das öffnet den dialog (und sollte ja auch gleich den inhalt wieder geben)oda muss dann die erste nachricht trozdem vom dialog kommen?
also sozusagen ein befehl das wartet der dialog auf den knopfdruck wartet?
oda so ähnlich?
-
Du möchtest doch nur einen bestimmten String, den du im Hauptnachrichtenfenster erzeugst, in dem Dialog anzeigen:
// statt DialogBox(...) nun TCHAR text[500]; // mit text arbeiten DialogBoxParam(// HINSTANCE, template, HWND und DlgProc wie DialogBox reinterpret_cast<LPARAM>(text)); .. //In der DlgProc case WM_INITDIALOG: { TCHAR* pText = reinterpret_cast<TCHAR*> lParam; //.. mit pText arbeiten break; }Globale Variablen sind in diesem Fall wie eigentlich immer total überflüssig und sollten vermieden werden.
Die Doku dazu steht hier.Edit: Kommentar verrutscht
-
Vicious Falcon schrieb:
Du möchtest doch nur einen bestimmten String, den du im Hauptnachrichtenfenster erzeugst, in dem Dialog anzeigen
ganz genau das möchte ich

und mit den befehlen muss dann kein knopf mehr im dialog getrückt werden um den inhalt anzuzeigen?
der string wir ja dann auchnoch natürlich zerteilt und in auf die jeweiligen fenster aufgeteilt, das is dann auch kein problem?
-
Nein, natürlich nicht. WM_INITDIALOG wird aufgerufen und dort kannst du alle Initialisierungen vornehmen.
Einen Tipp habe ich auch noch dazu. Du kannst jederzeit structs selber definieren:struct MyData { // irgendwelche Daten, die irgendwo benötigt werden }; ... My data d; // die Member von d setzten DialogBoxParam(.......,reinterpret_cast<LPARAM>(&d).Oder eben den C-Stil-Cast. Globale Daten sind somit überflüssig.
-
stimmt, strukturen sind da echt hilfreich

habe ich garnicht dran gedacht.nur eine kleine frage noch.
was kommt denn bei reininterpret_cast rein?

-
ich werde das später oder morgen alles versuchen und bescheid sagen obs klappt.
-
metapoint2011 schrieb:
was kommt denn bei reininterpret_cast rein?

Der reinterpret_cast ist ein C++-Cast. Anders als bei C gibt es in C++ verschiedene Casts. Der reinterpret_cast erzeugt allgemein einen Wert eines neuen Typs, der dasselbe Bitmuster wie das Argument hat.
In C gibt es einen Cast für alle Fälle:(Typ)Argument, also in dem Fall(LPARAM)text.
Es wird ausgenutzt, dass LPARAM immer so breit wie ein Zeiger ist, also unter 32 Bit Windows 4 Byte, unter Win64 8 Byte.metapoint2011 schrieb:
ich werde das später oder morgen alles versuchen und bescheid sagen obs klappt.
Mach das, aber warum sollte das nicht klappen?
:xmas1: