Fenster schliesst sich bei Klick auf Steuerelemente
-
So, ich habe alle Versuche mit Bibliotheken etc. entnervt aufgegeben und tatsächlich mit WinAPI begonnen, diesmal schon viel weiter gekommen (auch mit MASM32)

Nun habe ich aber ein Problem; muss sagen, ausser der MessageBox konnte ich vor einer Woche noch nichts; und nun habe ich ein Fenster mit einem Button und 2 Textfeldern, es sollte schlussendlich 2 in den Textfeldern eingegebene Zahlen addiert werden (z.B.), das wollte ich um zu testen ob die Inline Assembler-Funktion auch so funktioniert (bei .NET geht das eben nicht).So weit bin ich aber noch gar nicht; habe im Moment das Problem dass sich das Fenster sofort schliesst sobald eines der Textfelder angeklickt wird. Was habe ich denn da falsch gemacht??
-
sorry, wo ist denn mein COde geblieben? Nochmals:
#include <windows.h> #include <stdio.h> #include <stdlib.h> LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) { HWND hWnd; MSG msg; WNDCLASS wc; const char szAppName[] = "Editcontrol Tutorial"; wc.style = CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc = WndProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInstance; wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = (HBRUSH)GetStockObject(LTGRAY_BRUSH); wc.lpszMenuName = NULL; wc.lpszClassName = szAppName; RegisterClass(&wc); hWnd = CreateWindow( szAppName, "Editcontrol Tutorial", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL ); ShowWindow(hWnd, iCmdShow); UpdateWindow(hWnd); while(GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return msg.wParam; } LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { static HWND hEdit; static HWND hEdit2; static HWND hButton; switch (message) { case WM_CREATE: { char *buffer = NULL; char *buffer2 = NULL; hEdit = CreateWindowEx(WS_EX_CLIENTEDGE, "edit", buffer, // <- das ist der Inhalt der Editfelds WS_CHILD | WS_VISIBLE | WS_VSCROLL | ES_MULTILINE | ES_AUTOVSCROLL, 0, 0, 0, 0, hWnd, NULL, ((LPCREATESTRUCT) lParam) -> hInstance, NULL); free(buffer); hEdit2 = CreateWindowEx(WS_EX_CLIENTEDGE, "edit", buffer2, // <- das ist der Inhalt der Editfelds WS_CHILD | WS_VISIBLE | WS_VSCROLL | ES_MULTILINE | ES_AUTOVSCROLL, 0, 0, 0, 0, hWnd, NULL, ((LPCREATESTRUCT) lParam) -> hInstance, NULL); free(buffer); hButton = CreateWindow( "button", "los", WS_CHILD | WS_VISIBLE, 0, 0, 0, 0, hWnd, NULL, ((LPCREATESTRUCT) lParam) -> hInstance, NULL); return 0; } case WM_SIZE: { MoveWindow(hEdit, 0, 0, 90, 20, TRUE); MoveWindow(hEdit2, 100, 100, 90, 20, TRUE); MoveWindow(hButton, LOWORD(lParam) / 2 - 80, HIWORD(lParam) - 30, 160, 22, TRUE); return 0; } case WM_COMMAND: { if (lParam == (LPARAM)hButton) { if (HIWORD(wParam) == BN_CLICKED) MessageBox (0, "Hoi", "Test", 64); return 0; } } case WM_DESTROY: { PostQuitMessage(0); return 0; } } return DefWindowProc(hWnd, message, wParam, lParam); }
-
Wenn du das Textfenster anklickst wird WM_COMMAND ausgelöst und da du kein break oder return nach dem WM_COMMAND Code hast wird auch noch der Code für WM_DESTROY ausgeführt.
-
genau das, was mir noch auffaellt ist das du den button gar keine ID gibst sondern alle button klicks abfaengst - fuer diesen fall mag das gehen - aber sobald du mehr buttons dazu packst solltest du schon ID's vergeben
zudem versteh ich nicht warum du beim OnCreate mit MoveWindow arbeitest, du kannst die positionen direkt eingeben ohne das Move, wenn du die button positionen beeinflussen willst wenn das fenster skaliert wird, musst du WM_SIZE abfangen und dort dann die positionen neu setzen
create wird nur beim ersten erstellen des fensters aufgerufen dann nicht mehr - da lohnen sich die MoveWindow befehle nicht - verlaengert nur den code unnoetig
-
Antworten hast du ja schon bekommen aber eins noch.
Was ist das denn für ein Schwachsinn?char *buffer = NULL; char *buffer2 = NULL; hEdit = CreateWindowEx(WS_EX_CLIENTEDGE, "edit", buffer, // <- das ist der Inhalt der Editfelds WS_CHILD | WS_VISIBLE | WS_VSCROLL | ES_MULTILINE | ES_AUTOVSCROLL, 0, 0, 0, 0, hWnd, NULL, ((LPCREATESTRUCT) lParam) -> hInstance, NULL); free(buffer); hEdit2 = CreateWindowEx(WS_EX_CLIENTEDGE, "edit", buffer2, // <- das ist der Inhalt der Editfelds WS_CHILD | WS_VISIBLE | WS_VSCROLL | ES_MULTILINE | ES_AUTOVSCROLL, 0, 0, 0, 0, hWnd, NULL, ((LPCREATESTRUCT) lParam) -> hInstance, NULL); free(buffer);Du hast einen Zeiger der auf nix zeigt und willst das als Namen für deine Edits nutzen? Und dann gibst du Speicher Frei den du garnicht angefordert hast? Sollte das nicht sogar crashen?
Entweder so
char *buffer = malloc( sizeof(char) * 20 ); strcpy( buffer, "Name des Edit"); und dann irgendwann free(buffer);oder machst einfach
char buffer[20] = "Name des Edit"; und lässt das free(); ganz weg!oder du machst es einfach so wie bei deinem Button und fertig!
hButton = CreateWindow( "button", "los", <---- WS_CHILD | WS_VISIBLE, 0, 0, 0, 0, hWnd, NULL, ((LPCREATESTRUCT) lParam) -> hInstance, NULL);schirrmie
-
Danke! Demfall muss ich
if (HIWORD(wParam) == BN_CLICKED) MessageBox (0, "Hoi", "Test", 64); return 0; } return 0; }eingeben?
Das mit dem MoveWindow war aus einem Beispiel, habe mich schon gefragt wieso die Grösse dort angegeben war; dachte das sei vielleicht am besten. dann kann ich "WS_VSCROLL | ES_MULTILINE " durch die Koordinaten ersetzen?
Ja der Buffer bräuchte es nich so stimmt

-
japs, mit dem return gehts auch
und nein du ersetzt natuerlich nicht das style durch dir koordinate - schau mal in die MSDN was CreateWindow wo fuer parameter haben moechte - deine 0, 0, 0, 0 sind die koordinaten {o;
btw. hats ne komsiche einrueck methode #gg
-
Super jetzt hat es funktioniert

Muss ich nur noch die Funktion suchen um den String des Edit in eine Ganzzahl umzuwandeln.
-
atoi(LPCSTR string) oder _wtoi(LPCWSTR string)
-
Oder besser _ttoi(LPCTSTR string)
-
OK, habe etwas gegoogelt nach der Funktion aber schaffte es nicht; das Programm liess sich jeweils ohne Fehler kompilieren ausser wenn ich die Deklaration an den Anfang (vor WinMain) setzte, jedoch stürzte es sofort ab (Fehlermeldung ohne Speicherabbild Meldung unter Win2000).
Probiert habe ich:
char *buffer = NULL; hEdit = CreateWindowEx(WS_EX_CLIENTEDGE, "edit", buffer, // <- das ist der Inhalt der Editfelds WS_CHILD | WS_VISIBLE | WS_VSCROLL | ES_MULTILINE | ES_AUTOVSCROLL, 0, 0, 0, 0, //Koordinaten anstelle MoveWindow hWnd, NULL, ((LPCREATESTRUCT) lParam) -> hInstance, NULL); a = atoi( buffer ); free(buffer);natürlich mit der Deklaration int a; an diversen Stellen.
Habe den "Buffer-Zeiger" hier mal gelassen, der wird doch gebraucht da buffer die Variable ist mit dem String aus dem Edit oder sehe ich da etwas falsch? versuche es mal mit einem Zeiger.
-
Du initialisierst 'buffer' doch auch gar nicht (-> malloc bzw. statisch, konstant).
[Falls das woanders geschieht, stimmt evtl. etwa mit dem Gültigkeitsbereich der Variable nicht (-> static)]. CreateWindow(Ex) initalisiert Deine Variable nicht! Und free macht auch keinen Sinn.