[Erledigt] WinAPI und std::thread
-
Hiho,
wusste nicht, welche Überschrift ich nehmen soll - ich hoffe, dass es soweit passt. Hänge seit Tagen an der gleichen Stelle in meinem Programm. Was es werden soll, ist erstmal irrelevant denke ich, da es hier primär um folgendes Problem geht:Wenn ich eine längere While-Schleife mit einem Button-Klick auslösen möchte, kann ich das Fenster nicht bewegen o.A., da es ja auf die Beendigung der Schleife wartet. Das ist ziemlich nervig und zudem aktualisiert sich auf diese Weise nicht einmal die Progressbar bzw. der Fortschritt wird erst zum Ende der For-Schleife angezeigt. Da diese je nach Eingabe der User mehrere Minuten andauern kann, ist es m.E. durchaus wichtig, dass man das Programm während der Laufzeit der For-Schleife auch bewegen kann und den Fortschritt sieht.
Meine WinMain:
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) { HWND hWnd; MSG msg; WNDCLASS wc; /* Fensterklasse definieren */ wc.style = CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc = WndProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInstance; wc.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ICON1)); wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = HBRUSH(COLOR_WINDOW); wc.lpszMenuName = MAKEINTRESOURCE(IDR_MENU1); wc.lpszClassName = chClass; /* Fensterklasse registrieren */ RegisterClass(&wc); /* Hauptfenster erstellen */ hWnd = CreateWindow(chClass, chTitle, WS_SYSMENU, CW_USEDEFAULT, CW_USEDEFAULT, 307, 308, NULL, NULL, hInstance, NULL); ShowWindow(hWnd, iCmdShow); UpdateWindow(hWnd); /* Hauptnachrichtenschleife */ while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return msg.wParam; }Mein Meldungshandler:
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_CREATE: { /* Die GUI Elemente hab ich mal rausgelassen */ } break; /* Wenn das Programm einen Befehl erhält */ case WM_COMMAND: { /* Aktionen verarbeiten */ switch (LOWORD(wParam)) { case BTN_OLD_ID: { oldList = openFileDialog(hWnd, GetDlgItem(hWnd, EDIT_OLD_ID)); } break; case BTN_NEW_ID: { newList = saveFileDialog(hWnd, GetDlgItem(hWnd, EDIT_NEW_ID)); } break; case BTN_START_ID: { std::thread(egalWelcheFunktion, egalWelcherParameter); } break; case BTN_STOP_ID: { /* Stop Funktion noch nicht implementiert */ MessageBox(hWnd, "You have pressed the stop button.", NULL, NULL); } break; case ID_FILE_EXIT: { DestroyWindow(hWnd); } break; case ID_HELP_INFO: { MessageBox(hWnd, "Tool by X", "Info", MB_ICONINFORMATION); } break; default: { } return DefWindowProc(hWnd, message, wParam, lParam); } } break; /* Färbt Readonly Edits weiß */ case WM_CTLCOLORSTATIC: { if (GetDlgItem(hWnd, EDIT_OLD_ID) == HWND(lParam) || GetDlgItem(hWnd, EDIT_NEW_ID) == HWND(lParam)) { return LRESULT(GetStockObject(WHITE_BRUSH)); } SetBkColor(HDC(wParam), RGB(240, 240, 240)); } return LRESULT(GetStockObject(NULL_BRUSH)); case WM_DESTROY: { PostQuitMessage(0); } break; default: { } return DefWindowProc(hWnd, message, wParam, lParam); } return 0; }Das funktioniert leider nicht. Ohne std::thread funktionierts prima. Mit .join() hinten dran auch, aber ich möchte ja den Thread parallel zum Main Thread (in dem das Fenster läuft) laufen lassen. Egal welche Funktion, ob es nun nur ein MessageBeep(0); oder ähnliches ist. Irgendwer eine Idee?
Falls ich mein Problem ungenau beschrieben habe, tut's mir leid, da dass leider hier mein erster Thread ist und ich langsam verzweifel hier^^
mfg
-
Probier anstatt .join mal .detach
-
Vielen vielen Dank!
Das hat mir sehr geholfen.