Visual c++. Frage bez Ram Auslastung bei neuen Fenstern
-
Hallo!
Ich habe ein Programm geschrieben, funktioniert soweit, aber gewisse Dinge bringe ich nicht zum laufen.
Vielleicht könnt Ihr mir helfen.
Der Code befindet sich zu unterst. Es fehlen 3 Bilder, die kann ich nicht einfügen, sind aber nur Testbilder A, B und C mit so ca. 800x600px.
Ich hoffe jemand kann mir hier helfen.-Jedesmal wenn ich auf ein Button klicke, öffnet sich ein Fenster.
-das Fenster lässt sich nicht verschieben.
-wenn ich ein hscroll aktiviere, lässt sich dieser auch nicht verschieben.
-es lässt sich nicht schliessen mit "x" oben rechts, wenn ich ein solches aktiviere.-besonders wichtig: jedesmal, wenn ich erneut auf ein Button drücke um ein anderes Fenster zu öffnen, steigt mein RAM. Es löscht nicht
das vorherige Fenster aus dem Ram. Irgendwann einmal, wenn ich genug Buttons gedrückt habe, stürzt es ab weil es zu gross wurde.Ich habe .bmp ausgewählt. BMP sind sehr grosse Files, ich würde gerne .jpgs nehmen stattdessen. Jedoch akzeptiert es jpgs nicht.
Ich habe die .bmp files in D:\\ drin, kann ich die Bilder direkt in das .exe stecken?
PS: bei Zeichensatz habe ich in den Eigenschaften des Projekts auf "nicht festgelegt".
beim minimieren und wieder maximieren verschwinden die Buttons, ich muss das Fenster bewegen damit sie wieder kommen.Hier der Code:
#include <Windows.h> int width = 640; int height = 500; HINSTANCE hInstStatic; HINSTANCE hChildInst = 0; HWND hWndChild; HWND hButtonRemote; HWND hWndCombo; enum eButtons{ ID_BUTTON_TESTA, ID_BUTTON_TESTB, ID_BUTTON_TESTC, } MyGame; LRESULT CALLBACK WndProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam ); bool InitWndClassEx( WNDCLASSEX *WndClassEx, HINSTANCE hInstance, const char* szClassName ); const char szClassName[] = "MyClassEx"; char szTitle[] = "Project Grabit!"; int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLine, int iCmdShow ){ WNDCLASSEX WndClassEx; WNDCLASSEX WndClassEx2; HWND hWnd; MSG msg; UINT umsg; WPARAM wParam; LPARAM lParam; //======== REGISTRIERUNG ========// WndClassEx.cbSize = sizeof( WndClassEx ); WndClassEx.style = NULL; WndClassEx.lpfnWndProc = WndProc; // sehr wichtig!! WndClassEx.cbClsExtra = NULL; WndClassEx.cbWndExtra = NULL; WndClassEx.hInstance = hInstance; WndClassEx.hIcon = LoadIcon( NULL, IDI_WARNING ); // kann man auch auf NULL setzen WndClassEx.hCursor = LoadCursor( NULL, IDC_ARROW ); // kann man auch auf NULL setzen oder IDC_IBEAM ODER IDC_NO USW. WndClassEx.hbrBackground = GetSysColorBrush( COLOR_3DFACE ); // 3DFACE ist IMMER die Farbe für STATIC WINDOWS!!!!!...(HBRUSH) GetStockObject( GRAY_BRUSH ) WndClassEx.lpszMenuName = NULL; WndClassEx.lpszClassName = szClassName; // C - String WndClassEx.hIconSm = LoadIcon( NULL, IDI_APPLICATION ); // kann man auch auf NULL setzen WndClassEx2.cbSize = sizeof( WndClassEx2 ); WndClassEx2.style = NULL; WndClassEx2.lpfnWndProc = WndProc; // sehr wichtig!! WndClassEx2.cbClsExtra = NULL; WndClassEx2.cbWndExtra = NULL; WndClassEx2.hInstance = hInstance; WndClassEx2.hIcon = LoadIcon( NULL, IDI_WARNING ); // kann man auch auf NULL setzen WndClassEx2.hCursor = LoadCursor( NULL, IDC_ARROW ); // kann man auch auf NULL setzen oder IDC_IBEAM ODER IDC_NO USW. WndClassEx2.hbrBackground = GetSysColorBrush( COLOR_3DFACE ); // 3DFACE ist IMMER die Farbe für STATIC WINDOWS!!!!! WndClassEx2.lpszMenuName = NULL; WndClassEx2.lpszClassName = "WndClassEx2"; // C - String WndClassEx2.hIconSm = LoadIcon( NULL, IDI_APPLICATION ); // kann man auch auf NULL setzen if( !RegisterClassEx( &WndClassEx ) ){ MessageBox ( NULL, "Register Class Failed.", "Error", MB_OK ); return false; } if( !RegisterClassEx( &WndClassEx2 ) ){ MessageBox ( NULL, "Register Class Failed.", "Error", MB_OK ); return false; } //======== FENSTER ERSTELLEN ========// hWnd = CreateWindowEx( WS_EX_CLIENTEDGE, szClassName, szTitle, WS_OVERLAPPEDWINDOW & ~WS_THICKFRAME & ~WS_MAXIMIZEBOX, // Window Styles, hier auch WS_CHILD möglich oder nicht vergrösserbar 0, // X von oben links 0, // Y von oben links width, // FensterBreite....CW_USEDEFAULT auch möglich height, // FensterHöhe NULL, NULL, hInstance, NULL ); if( hWnd == NULL ){ MessageBox( NULL, "Create Window failed", "Error", MB_OK ); } hButtonRemote = CreateWindow( "button", "testA", WS_VISIBLE | WS_CHILD, 80, 180, 80, 40, hWnd, (HMENU) ID_BUTTON_TESTA, hInstance, NULL ); hButtonRemote = CreateWindow( "button", "testB", WS_VISIBLE | WS_CHILD, 170, 180, 80, 40, hWnd, (HMENU) ID_BUTTON_TESTB, hInstance, NULL ); hButtonRemote = CreateWindow( "button", "testC", WS_VISIBLE | WS_CHILD, 350, 225, 80, 40, hWnd, (HMENU) ID_BUTTON_TESTC, hInstance, NULL ); ShowWindow( hWnd, iCmdShow ); UpdateWindow( hWnd ); while( GetMessage( &msg, hWnd, NULL, NULL ) > NULL ){ // wenn 0 oder -1 fliegt sie raus aus der Schleife, weiter unten ist return 0, Programmende TranslateMessage( &msg ); // von Virtual msg in einen Character msg übersetzt DispatchMessage( &msg ); // character msg wird verschickt an die Callback WndProc Funktion } // WINDOW-PROCEDUR --> WNDCLASSEX -- > HWND(Fenster) --> MESSAGELOOP (GETMESSAGE) return 0; } HWND hWndTestA; HWND hWndTestB; HWND hWndTestC; LRESULT CALLBACK WndProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam ){ HDC hdcTestA, hdcMemTestA; HDC hdcTestC, hdcMemTestC; HDC hdcTestB, hdcMemTestB; static HBITMAP hTestA; static BITMAP testA; static HBITMAP hTestC; static BITMAP testC; static HBITMAP hTestB; static BITMAP testB; PAINTSTRUCT psTestA; PAINTSTRUCT psTestC; PAINTSTRUCT psTestB; char szWndText[100]; switch( msg ){ case WM_CREATE: hTestA = (HBITMAP)LoadImage(0,"D:\\testA.bmp",IMAGE_BITMAP, 0, 0, LR_DEFAULTSIZE|LR_LOADFROMFILE|LR_CREATEDIBSECTION); if(hTestA==NULL) { MessageBox(hWndTestA,"Bild konnte nicht geladen werden","Error",0); return -1; } GetObject (hTestA, sizeof (BITMAP), &testA) ; //return 0; hTestC = (HBITMAP)LoadImage(0,"D:\\testC.bmp",IMAGE_BITMAP, 0, 0, LR_DEFAULTSIZE|LR_LOADFROMFILE|LR_CREATEDIBSECTION); if(hTestC == NULL) { MessageBox(hWndTestC,"Bild konnte nicht geladen werden","Error",0); return -1; } GetObject (hTestC, sizeof (BITMAP), &testC) ; //return 0; hTestB = (HBITMAP)LoadImage(0,"D:\\testB.bmp",IMAGE_BITMAP, 0, 0, LR_DEFAULTSIZE|LR_LOADFROMFILE|LR_CREATEDIBSECTION); if(hTestB == NULL) { MessageBox(hWndTestB,"Bild konnte nicht geladen werden","Error",0); return -1; } GetObject (hTestB, sizeof (BITMAP), &testB) ; return 0; case WM_PAINT: hdcTestA = BeginPaint (hWndTestA, &psTestA) ; hdcMemTestA = CreateCompatibleDC (hdcTestA) ; SelectObject (hdcMemTestA, hTestA) ; BitBlt (hdcTestA, 0, 0, testA.bmWidth, testA.bmHeight, hdcMemTestA, 0, 0, SRCCOPY) ; DeleteDC (hdcMemTestA) ; EndPaint (hWndTestA, &psTestA) ; // return 0 ; hdcTestC = BeginPaint (hWndTestC, &psTestC) ; hdcMemTestC = CreateCompatibleDC (hdcTestC) ; SelectObject (hdcMemTestC, hTestC) ; BitBlt (hdcTestC, 0, 0, testC.bmWidth, testC.bmHeight, hdcMemTestC, 0, 0, SRCCOPY) ; DeleteDC (hdcMemTestC) ; EndPaint (hWndTestC, &psTestC) ; // return 0 ; hdcTestB = BeginPaint (hWndTestB, &psTestB) ; hdcMemTestB = CreateCompatibleDC (hdcTestB) ; SelectObject (hdcMemTestB, hTestB) ; BitBlt (hdcTestB, 0, 0, testB.bmWidth, testB.bmHeight, hdcMemTestB, 0, 0, SRCCOPY) ; DeleteDC (hdcMemTestB) ; EndPaint (hWndTestB, &psTestB) ; return 0 ; case WM_COMMAND: // kommt nach dem Create damit etwas passiert wenn man Button drückt switch ( wParam ){ // in wParam sind Parameter drin wie zB. welche Button ID....anscheinend hat lParam etwas mit Zeit zu tun case ID_BUTTON_TESTA: DestroyWindow(hWndTestA); DestroyWindow(hWndTestB); DestroyWindow(hWndTestC); hWndTestA = CreateWindowEx( WS_EX_CLIENTEDGE, "WndClassEx2", "TestA", WS_OVERLAPPED | WS_POPUP | WS_VISIBLE | WS_CLIPSIBLINGS, // Window Styles, hier auch WS_CHILD möglich oder nicht vergrösserbar 660, // X von oben links 0, // Y von oben links testA.bmWidth, // FensterBreite....CW_USEDEFAULT auch möglich testA.bmHeight, // FensterHöhe HWND_DESKTOP, NULL, hChildInst, NULL ); if( hWnd == NULL ){ MessageBox( NULL, "Create Window failed", "Error", MB_OK ); } UpdateWindow( hWndTestA ); break; case ID_BUTTON_TESTC: DestroyWindow(hWndTestA); DestroyWindow(hWndTestB); DestroyWindow(hWndTestC); hWndTestC = CreateWindowEx( WS_EX_CLIENTEDGE, "WndClassEx2", "TestC", WS_OVERLAPPED | WS_POPUP | WS_VISIBLE | WS_CLIPSIBLINGS, // Window Styles, hier auch WS_CHILD möglich oder nicht vergrösserbar 660, // X von oben links 0, // Y von oben links testC.bmWidth, // FensterBreite....CW_USEDEFAULT auch möglich testC.bmHeight, // FensterHöhe HWND_DESKTOP, NULL, hChildInst, NULL ); if( hWnd == NULL ){ MessageBox( NULL, "Create Window failed", "Error", MB_OK ); } UpdateWindow( hWndTestC ); break; case ID_BUTTON_TESTB: DestroyWindow(hWndTestA); DestroyWindow(hWndTestB); DestroyWindow(hWndTestC); hWndTestB = CreateWindowEx( WS_EX_CLIENTEDGE, "WndClassEx2", "TestB", WS_OVERLAPPED | WS_POPUP | WS_VISIBLE | WS_CLIPSIBLINGS, // Window Styles, hier auch WS_CHILD möglich oder nicht vergrösserbar 660, // X von oben links 0, // Y von oben links testB.bmWidth, // FensterBreite....CW_USEDEFAULT auch möglich testB.bmHeight, // FensterHöhe HWND_DESKTOP, NULL, hChildInst, NULL ); if( hWnd == NULL ){ MessageBox( NULL, "Create Window failed", "Error", MB_OK ); } UpdateWindow( hWndTestB ); break; } case WM_DESTROY: // Fenster-Ende PostQuitMessage(0); break; default : return DefWindowProc( hWnd, msg, wParam, lParam ); } // Ende Switch }
-
Ich verstehe Deinen Codenicht aber Du erzeugst GDI Leaks ohne Ende:
hdcMemTestB = CreateCompatibleDC (hdcTestB) ; SelectObject (hdcMemTestB, hTestB) ; BitBlt (hdcTestB, 0, 0, testB.bmWidth, testB.bmHeight, hdcMemTestB, 0, 0, SRCCOPY) ; DeleteDC (hdcMemTestB) ;
Wenn Du einen DC erzeugst, dann wird mit dem DC auch ene Bitmap erzeugt.
Diese wird ersetzt durch Dein SelectObject. Der DeleteDC kann Deine Bimtap nicht abräumen, und die andere Bitmap ist verloren, weil Du deren Handle nicht zurückselektiert hast.Richtig wäre das ssichern der Bitmap und zurücksetzen.
hdcMemTestB = CreateCompatibleDC (hdcTestB); hSave = SelectObject (hdcMemTestB, hTestB); BitBlt (hdcTestB, 0, 0, testB.bmWidth, testB.bmHeight, hdcMemTestB, 0, 0, SRCCOPY); SelectObject(hdcMemTestB, hSave); DeleteDC (hdcMemTestB);
-
Vielen Dank für Deine Antwort!
Du hast mich auf den richtigen Weg gebracht bezüglich Memory Leaks, sodass es jetzt soweit i.O. ist.Ich habe eine andere Frage.
Es ist ein Win32-Projekt wie das vorherige. Ich versuche, eine Combobox zu erstellen.
Wenn ich auf einen Wert klicke, poppt ein Fenster auf.
Die Combobox ist nun aktiv im neuen Fenster, das will ich nicht. Es sollte weiterhin im ersten Fenster aktiv sein.Zudem sollte im neuen Fenster keine Combobox mehr drin sein.
Ich versuche immer noch wie ich bmp's in eine .exe bekomme.
Ich verwende microsoft visual c++ express.Hier der Code:
[code] #include <windows.h> #define ID_LIST 1 #define ID_TEXT 2 HINSTANCE hChildInst = 0; LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM); char szClassName[ ] = "ComboBox App"; int WINAPI WinMain (HINSTANCE hThisInstance, HINSTANCE hPrevInstance, LPSTR lpszArgument, int nFunsterStil) { HWND hwnd; MSG messages; WNDCLASSEX wincl; WNDCLASSEX wincl2; wincl.hInstance = hThisInstance; wincl.lpszClassName = szClassName; wincl.lpfnWndProc = WindowProcedure; wincl.style = CS_DBLCLKS; wincl.cbSize = sizeof (WNDCLASSEX); wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION); wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION); wincl.hCursor = LoadCursor (NULL, IDC_ARROW); wincl.lpszMenuName = NULL; wincl.cbClsExtra = 0; wincl.cbWndExtra = 0; wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND; if (!RegisterClassEx (&wincl)) return 0; /* The Window structure */ wincl2.hInstance = hChildInst; wincl2.lpszClassName = "Proc2"; wincl2.lpfnWndProc = WindowProcedure; wincl2.style = CS_DBLCLKS; wincl2.cbSize = sizeof (WNDCLASSEX); /* Use default icon and mouse-pointer */ wincl2.hIcon = LoadIcon (NULL, IDI_APPLICATION); wincl2.hIconSm = LoadIcon (NULL, IDI_APPLICATION); wincl2.hCursor = LoadCursor (NULL, IDC_ARROW); wincl2.lpszMenuName = NULL; wincl2.cbClsExtra = 0; wincl2.cbWndExtra = 0; wincl2.hbrBackground = (HBRUSH) COLOR_BACKGROUND; if (!RegisterClassEx (&wincl2)) return 0; hwnd = CreateWindowEx ( 0, szClassName, "ComboBox App", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 544, 375, HWND_DESKTOP, NULL, hThisInstance, NULL ); ShowWindow (hwnd, nFunsterStil); while (GetMessage (&messages, NULL, 0, 0)) { TranslateMessage(&messages); DispatchMessage(&messages); } return messages.wParam; } void FillListBox(HWND hwndList) { CHAR *pVarName[] = {"Item1", "Item2", "Item3", "Item4", "Item5"}; for(int i=0; i<5; i++) SendMessage(hwndList, CB_ADDSTRING, 0, (LPARAM)pVarName[i]); } HWND hwndtest; LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { static HWND hwndList, hwndText, hwndComboWindow; int iIndex, iLength, cxChar, cyChar; CHAR pVarName[30]; switch (message) { case WM_CREATE: cxChar = LOWORD(GetDialogBaseUnits()); cyChar = HIWORD(GetDialogBaseUnits()); //Create Display Window hwndText = CreateWindow(TEXT("static"),NULL, WS_CHILD | WS_VISIBLE | SS_LEFT, cxChar, cyChar, GetSystemMetrics(SM_CXSCREEN), cyChar, hwnd, (HMENU)ID_TEXT, (HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE), NULL); //Create ComboBox hwndList = CreateWindow(TEXT("Combobox"), NULL, WS_CHILD | WS_VISIBLE | LBS_STANDARD, cxChar, cyChar*3, cxChar*16 + GetSystemMetrics(SM_CXVSCROLL), cyChar*5, hwnd, (HMENU)ID_LIST, (HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE), NULL); //Populate ComboBox FillListBox(hwndList); //Set a Default Selection SendMessage(hwndList, CB_SETCURSEL, 0, 0); GetWindowText(hwndList, pVarName, 30); SetWindowText(hwndText, pVarName); return 0; case WM_COMMAND: if( LOWORD(wParam)==ID_LIST && HIWORD(wParam)==CBN_SELCHANGE ) { //Get Selection from Combo Box GetWindowText(hwndList, pVarName, 30); //Show Text in Display Window SetWindowText(hwndText, pVarName); // HIER ERSTELLE ICH EIN NEUES FENSTER, ABER ES WIRD WIEDER "combobox" UND "static" IN DIESEM FENSTER ANGEZEIGT. // ZUDEM WIRD COMBOBOX HIER AKTIV, SOLLTE AUCH NICHT SEIN. if( strcmp(pVarName,"Item3") == 0 ){ CreateWindowEx( WS_EX_CLIENTEDGE, "Proc2", (LPCSTR) pVarName, WS_OVERLAPPEDWINDOW | WS_POPUP | WS_VISIBLE | WS_CLIPSIBLINGS, 760, 0, 400, 440, hwnd, NULL, hChildInst, NULL ); if( hwnd == NULL ){ MessageBox( NULL, "Create Window failed", "Error", MB_OK ); } UpdateWindow( hwndComboWindow ); } if( strcmp(pVarName,"Item4") == 0 ){ CreateWindowEx( WS_EX_CLIENTEDGE, "Proc2", (LPCSTR) pVarName, WS_OVERLAPPEDWINDOW | WS_POPUP | WS_VISIBLE | WS_CLIPSIBLINGS, 760, 0, 400, 440, hwnd, NULL, hChildInst, NULL ); if( hwnd == NULL ){ MessageBox( NULL, "Create Window failed", "Error", MB_OK ); } UpdateWindow( hwndComboWindow ); } } break; return 0; case WM_DESTROY: PostQuitMessage (0); break; default: return DefWindowProc (hwnd, message, wParam, lParam); } return 0; }
-
Und warum erzeugst Du dann bitte ein neues Fenster?
Ich verstehe nicht was Du willst.Wenn die ComboBox in dem bisherigen fenster liegen soll, dann musst Du die auch dort anlegen.
Oder Du legst ein Dialog-Child Control im aketuellen fenster an.Das wird aber vermutlich Dein Können als Newbie übersteigen....
-
Besorg Dir ein gutes Buch zur Windowsprogrammierung. Siehe unter FAQ und/oder Bücher.
Arbeite das durch und Deine jetzigen Probleme lösen sich auf.
Nein, es ist keine verschwendete Zeit.
Mit diesem Trial & Error vergeudest Du deutlich mehr Zeit.