EDIT-Feld auslesen
-
Mein Problem, wie im Titel erwähnt, ist das ich es nicht schaffe erfolgreich ein EDIT-Feld auszulesen Deswegen möchte ich hier Fragen wo mein Fehler liegt?
case WM_COMMAND: if (HIWORD(wParam) == BN_CLICKED) { if (LOWORD(wParam) == 1) { char string[255]; SendMessage(hedit, WM_GETTEXT, 2, (LPARAM) string); SetWindowText(hwnd, "Hallo"); for(int i=0; i<100000000; i++); SetWindowText (hwnd, string); } }
Das erste SetWindowText und die For-Schleife dienen nur zu überprüfung ob das Button ereigniss ausgelöst wird. Wenn ich das Beispiel ausführe erscheint in der Fensterleiste, "Hallo", und nach wenigen momenten kommt dann irgend ein zeichen. Ich glaube das er den Text von der EDIT-Box nicht richtig abspeichert, aber verstehen wieso tue ich nicht
Hier auch nochmal der gesammte Code:
#include <windows.h> /* Declare Windows procedure */ LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM); /* Make the class name into a global variable */ char szClassName[ ] = "CodeBlocksWindowsApp"; int WINAPI WinMain (HINSTANCE hThisInstance, HINSTANCE hPrevInstance, LPSTR lpszArgument, int nCmdShow) { HWND hwnd; /* This is the handle for our window */ MSG messages; /* Here messages to the application are saved */ WNDCLASSEX wincl; /* Data structure for the windowclass */ /* The Window structure */ wincl.hInstance = hThisInstance; wincl.lpszClassName = szClassName; wincl.lpfnWndProc = WindowProcedure; /* This function is called by windows */ wincl.style = CS_DBLCLKS; /* Catch double-clicks */ wincl.cbSize = sizeof (WNDCLASSEX); /* Use default icon and mouse-pointer */ wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION); wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION); wincl.hCursor = LoadCursor (NULL, IDC_ARROW); wincl.lpszMenuName = NULL; /* No menu */ wincl.cbClsExtra = 0; /* No extra bytes after the window class */ wincl.cbWndExtra = 0; /* structure or the window instance */ /* Use Windows's default colour as the background of the window */ wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND; /* Register the window class, and if it fails quit the program */ if (!RegisterClassEx (&wincl)) return 0; /* The class is registered, let's create the program*/ hwnd = CreateWindowEx ( 0, /* Extended possibilites for variation */ szClassName, /* Classname */ "Code::Blocks Template Windows App", /* Title Text */ WS_OVERLAPPEDWINDOW, /* default window */ CW_USEDEFAULT, /* Windows decides the position */ CW_USEDEFAULT, /* where the window ends up on the screen */ 544, /* The programs width */ 375, /* and height in pixels */ HWND_DESKTOP, /* The window is a child-window to desktop */ NULL, /* No menu */ hThisInstance, /* Program Instance handler */ NULL /* No Window Creation data */ ); /* Make the window visible on the screen */ ShowWindow (hwnd, nCmdShow); /* Run the message loop. It will run until GetMessage() returns 0 */ while (GetMessage (&messages, NULL, 0, 0)) { /* Translate virtual-key messages into character messages */ TranslateMessage(&messages); /* Send message to WindowProcedure */ DispatchMessage(&messages); } /* The program return-value is 0 - The value that PostQuitMessage() gave */ return messages.wParam; } /* This function is called by the Windows function DispatchMessage() */ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { HWND hedit, hbutton; switch (message) /* handle the messages */ { case WM_CREATE: hedit = CreateWindow ( "EDIT", /* Classname */ "Name", /* Title Text */ WS_CHILD | WS_VISIBLE | WS_BORDER | ES_AUTOHSCROLL, /* default window */ 50, /* Windows decides the position */ 50, /* where the window ends up on the screen */ 100, /* The programs width */ 20, /* and height in pixels */ hwnd, /* The window is a child-window to desktop */ (HMENU) 2, /* No menu */ (HINSTANCE) GetParent((HWND)lParam), /* Program Instance handler */ NULL /* No Window Creation data */ ); hbutton = CreateWindow ( "BUTTON", /* Classname */ "Save", /* Title Text */ WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, /* default window */ 150, /* Windows decides the position */ 50, /* where the window ends up on the screen */ 100, /* The programs width */ 20, /* and height in pixels */ hwnd, /* The window is a child-window to desktop */ (HMENU) 1, /* No menu */ NULL, /* Program Instance handler */ NULL /* No Window Creation data */ ); break; case WM_COMMAND: if (HIWORD(wParam) == BN_CLICKED) { if (LOWORD(wParam) == 1) { char string[255]; SendMessage(hedit, WM_GETTEXT, 2, (LPARAM) string); SetWindowText(hwnd, "Hallo"); for(int i=0; i<100000000; i++); SetWindowText (hwnd, string); } } break; case WM_DESTROY: PostQuitMessage (0); /* send a WM_QUIT to the message queue */ break; default: /* for messages that we don't deal with */ return DefWindowProc (hwnd, message, wParam, lParam); } return 0; }
Schonmal danke im Voraus für die Hilfe
-
- TCHAR verwenden
- schaun wofür der wParam bei WM_GETTEXT ist.
Alternative: GetWindowText()
-
Hab TCHAR ausprobiert, leider verändert sich dass ergebniss nicht.
WPARAM ist für die Maximal eingelesenen zeichen.
Wenn ich es mit GetWindowText versuche bleibt die Titelleiste leer. Verwende es so:GetWindowText(hedit, string, 255 );
-
Entweder die Handles statisch deklarieren oder
SendDlgItemMessage(hwnd, 2, WM_GETTEXT, 255, (LPARAM) string);
(hEdit ist so nur nach der Zuweisung im WM_CREATE-Zweig gültig).
Außerdem ist der LPARAM bei WM_CREATE ein Zeiger auf ein CREATESTRUCT, dein Code, um an die Instanz zu kommen, sieht komisch aus.
reinterpret_cast<LPCREATESTRUCT>(lParam)->hInstance
liefer im WM_CREATE-Zweig das passende Handle.
Und solltest den Vorschlag beherzigen, TCHARs zu verwenden und Stringliterale in das TEXT-Makro zu betten, so kannst du immer beide Konfigurationen (UNICODE/MBCS) kompilieren.
-
Erstmal danke, die static deklarierung hat funktioniert. Doch leider verstehe ich es nicht ganz. Ich habe hedit doch außerhalb der switch funktion deklariert, also mussten doch beide case verzweigungen darauf zugreifen können, oder ist es weil die funktion WindowProcedure bei jeder neuen nachricht neu aufgerufen wird und somit die Variable hedit nicht den Handle behält?
Der Code um an den Instance Handle zu kommen ist was ausm Internet, als ich auf der suche nach meiner Lösung war habe ich irgendwann verschiedene Sachen kopiert und in der hoffnung das irgendwas funktioniert.
-
Erstmal danke, die static deklarierung hat funktioniert. Doch leider verstehe ich es nicht ganz. Ich habe hedit doch außerhalb der switch funktion deklariert, also mussten doch beide case verzweigungen darauf zugreifen können, oder ist es weil die funktion WindowProcedure bei jeder neuen nachricht neu aufgerufen wird und somit die Variable hedit nicht den Handle behält?
Der Code um an den Instance Handle zu kommen ist was ausm Internet, als ich auf der suche nach meiner Lösung war habe ich irgendwann verschiedene Sachen kopiert und in der hoffnung das irgendwas funktioniert.
Noch eine weitere Frage hätte ich, wenn ich hedit Globaler definiere, heißt es in der Nachrichten verwaltung hedit wurde vorher nicht definiert Bsp.:
[cpp][cpp]
#include <windows.h>/* Declare Windows procedure */
LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);
HINSTANCE hInstGlobal;
HWND hEdit;/* Make the class name into a global variable */
int WINAPI WinMain (HINSTANCE hThisInstance,
HINSTANCE hPrevInstance,
LPSTR lpszArgument,
int nCmdShow)
{
...
[/cpp]
HINSTANCE hInstGlobal, eine zeile drüber, funktioniert aber...
-
zwerg91 schrieb:
oder ist es weil die funktion WindowProcedure bei jeder neuen nachricht neu aufgerufen wird und somit die Variable hedit nicht den Handle behält?
Genau so ist es.
Noch eine weitere Frage hätte ich, wenn ich hedit Globaler definiere,
Ich tippe mal darauf, dass du in deinem Code ebenfalls statt hEdit hedit geschrieben hast.
Aber globale Variablen sind eigentlich völlig unnötig, wie im letzten Post beschrieben, ist ein Zugriff auf die Handles von Kindfenstern jederzeit über die ID möglich (GetDlgItem/SendDlgItemMessage).
-
Ok habs verstanden, vielen Danke
-
Außerdem sind bei der Erzeugung der Kindfenster die Angaben des Instanz-Handles falsch.
Für das Edit-Steuerelement gibst Du das Fenster-Handle des Elternfensters an:
(HINSTANCE) GetParent((HWND)lParam), /* Program Instance handler */
und für die Schaltfläche gibst Du NULL an.
Richtig wäre:
(HINSTANCE) GetModuleHandle (NULL)
Gruß
-
Instanz-Handle schrieb:
Richtig wäre:
(HINSTANCE) GetModuleHandle (NULL)
Naja. Als richtig sehe ich was anderes:
http://blog.m-ri.de/index.php/2007/12/12/die-unsitte-immer-getmodulehandlenull-fuer-hinstance-in-createwindow-und-registerclass-zu-verwenden/
-
Na gut, einigen wir uns auf "richtiger" ...
Vielen Dank für den Link.