[gelöst] ComboBox-Problem: Stack-Overflow bei CB_SHOWDROPDOWN
-
Die habe ich so angelegt:
TCHAR szTmp[10];
-
Bei mir funktioniert das einwandfrei. Ich habe dennoch die Vermutung, dass dein Buffer zu klein gewählt ist.
wcscpy_s
setzt ein NULL-Zeichen ans Ende des Strings, so dass dein Buffer immer Stringlänge + 1 Platz haben sollte.Ist cmbTest als static bzw. global deklariert? Ich könnte mir vorstellen, dass
CB_SHOWDROPDOWN
, was du überSendMessage
beiWM_COMMAND
sendest, gar nicht ankommt.Ohne voll compilierbares Minimalbeispiel, welches immer noch diesen Fehler erzeugt, lässt sich aber sonst nur die Glaskugel befragen ...
-
Was sagt denn der Aufrufstack?
-
roflo schrieb:
Was sagt denn der Aufrufstack?
Bin mir nicht sicher, ob das die Info ist, nach der du fragst, aber die Unterbrechungsmeldung lautet:
Unbehandelte Ausnahme bei 0x77741180 (ntdll.dll) in Exporttool.exe: 0xC00000FD: Stack overflow (Parameter: 0x00000001, 0x00172FFC)
Fake oder Echt schrieb:
Bei mir funktioniert das einwandfrei. Ich habe dennoch die Vermutung, dass dein Buffer zu klein gewählt ist.
wcscpy_s
setzt ein NULL-Zeichen ans Ende des Strings, so dass dein Buffer immer Stringlänge + 1 Platz haben sollte.Den Buffer habe ich auch schon einmal von 10 auf 100 hochgeschraubt - keine Veränderung. Die Einträge sind auch keine 10 Zeichen lang.
Ist cmbTest als static bzw. global deklariert? Ich könnte mir vorstellen, dass
CB_SHOWDROPDOWN
, was du überSendMessage
beiWM_COMMAND
sendest, gar nicht ankommt.cmbTest ist als static deklariert.
Ohne voll compilierbares Minimalbeispiel, welches immer noch diesen Fehler erzeugt, lässt sich aber sonst nur die Glaskugel befragen ...
Habe den Code mal auf das Wesentlichste gekürzt - ist kompilierbar:
#include <windows.h> #define ID_CMB_VERSION 1 LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); LRESULT CALLBACK EditWndProc(HWND, UINT, WPARAM, LPARAM); int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int iCmdShow) { WNDCLASS wndClass; HWND hwnd; MSG msg; TCHAR szAppName[] = TEXT("NAV Objekt Export"); wndClass.style = CS_HREDRAW | CS_VREDRAW; wndClass.lpfnWndProc = WndProc; wndClass.cbClsExtra = 0; wndClass.cbWndExtra = 0; wndClass.hInstance = hInstance; wndClass.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH); wndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION); wndClass.hCursor = LoadCursor(NULL, IDC_ARROW); wndClass.lpszMenuName = NULL; wndClass.lpszClassName = szAppName; if(!RegisterClass(&wndClass)) { MessageBox(NULL, TEXT("Unicode fehler"), TEXT("Fehler"), MB_ICONERROR); return 1; } hwnd = CreateWindow( szAppName, szAppName, 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) { HDC hdc; PAINTSTRUCT ps; static HWND cmbVersion; TCHAR szCmbStringTmp[10], szCmbVersionStr[4][5] = { L"V602", L"V700", L"V710", L"V800" }; int i; switch(message) { case WM_CREATE: cmbVersion = CreateWindow( TEXT("combobox"), NULL, WS_VISIBLE | WS_CHILD | WS_BORDER | WS_TABSTOP | CBS_DROPDOWNLIST, 80, 125, 65, 25, hwnd, (HMENU) ID_CMB_VERSION, ((LPCREATESTRUCT) lParam)->hInstance, NULL); //*** Start: ComboBoxen füllen memset(&szCmbStringTmp, 0, sizeof(szCmbStringTmp)); for(i=0; i<4; i++) { wcscpy_s(szCmbStringTmp, sizeof(szCmbStringTmp)/sizeof(TCHAR), szCmbVersionStr[i]); SendMessage(cmbVersion, (UINT) CB_ADDSTRING, (WPARAM) 0, (LPARAM) szCmbStringTmp); } SendMessage(cmbVersion, (UINT) CB_SETCURSEL, (WPARAM) 0, (LPARAM) 0); //*** Ende: ComboBoxen füllen return 0; case WM_PAINT: hdc=BeginPaint(hwnd, &ps); EndPaint(hwnd, &ps); return 0; case WM_COMMAND: switch(LOWORD(wParam)) { case ID_CMB_VERSION: SendMessage(cmbVersion, (UINT) CB_SHOWDROPDOWN, (WPARAM) 0, (LPARAM) 0); return 0; default: return 0; } case WM_DESTROY: PostQuitMessage(0); return 0; } return DefWindowProc(hwnd, message, wParam, lParam); }
-
Der Overflow kommt glaube ich daher, dass der Code unter ID_CMB_VERSION zweimal aufgerufen wird. Demnach werden beim Klick auf die Combobox zwei WM_COMMAND-Nachrichten ans Parent-Fenster gesendet.
Aber es gibt doch sicherlich ein ganz normales Vorgehen (welcher Auslöser, welche Nachricht, ...) für das Öffnen einer ComboBox-Liste. Das ist doch eigentlich eine völlig triviale Sache.
-
Die Verwendung von SendMessage bewirkt einen rekursiven Aufruf von WndProc. Ohne näher darauf einzugehen, dass du mit den Nachrichten vermutlich Unsinn anstellst, musst du PostMessage benutzen.
-
Gibt es denn irgendwo brauchbaren Beispielcode dazu. Alles was ich bisher gefunden habe, sah so aus, wie ich es mache.
Außerdem will ich keinen Unsinn anstellen, sondern einfach nur die DropDown-Liste öffnen.
Aber verstehe ich das jetzt richtig, dass ich mit einem Aufruf von SendMessage, Nachrichten an die Aufrufende WindowProzedur schicke?
-
Warum sendest Du überhaupt CB_SHOWDROPDOWN?
Damit die Box öffnet musst Du nichts machen.Du solltest der guten Box aber etwas mehr Größe spendieren. Die Höhe, die beim Create angegeben wird, ist die Höhe der aufgeklappten Box!
-
Martin Richter schrieb:
Warum sendest Du überhaupt CB_SHOWDROPDOWN?
Damit die Box öffnet musst Du nichts machen.Du solltest der guten Box aber etwas mehr Größe spendieren. Die Höhe, die beim Create angegeben wird, ist die Höhe der aufgeklappten Box!
DAS WAR ES!!!!
Ich danke dir. Dat hab ich nit jewusst.
DANKESCHÖN
Gruß
Kai
-
Beide Änderungen waren notwendig, wie Martin gesagt hat; SendMessage löschen ...