Hintergrund in Fenstern ändern. ( C++ )
-
Also ich habe jetzt ein Fenster in der WinApi erstellt.
(der Code:)// eigenes Fenster.cpp : Definiert den Einstiegspunkt für die Konsolenanwendung. // #include "stdafx.h" #include <Windows.h> const char szClassName[] = "MyClassEx"; char szTitle[] = "Fenster NO 1. | Copyright by JaRk Producktion © 2012"; LRESULT CALLBACK WndProc ( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam ); int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance , LPSTR szCmdLine, int szCmdShow ) { WNDCLASSEX WndClassEx; HWND hWnd; MSG msg; UINT umsg; //°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°RESTRIERUNG°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°// WndClassEx.cbSize = sizeof( WndClassEx ); WndClassEx.style = NULL; WndClassEx.lpfnWndProc = WndProc; WndClassEx.cbClsExtra = NULL; WndClassEx.cbWndExtra = NULL; WndClassEx.hInstance = hInstance; WndClassEx.hIcon = LoadIcon( NULL, IDI_ERROR ); WndClassEx.hCursor = LoadCursor( NULL, IDC_HAND ); WndClassEx.hbrBackground = ( HBRUSH )(COLOR_WINDOW + 1); WndClassEx.lpszMenuName = NULL; WndClassEx.lpszClassName = szClassName; WndClassEx.hIconSm = LoadIcon( NULL, IDI_APPLICATION); if( !RegisterClassEx( &WndClassEx )) { MessageBoxA(NULL, "Registrierungs Fehler! ", "Error ", MB_OK); return false; } //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FENSTER ERSTELLEN ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^// hWnd = CreateWindowEx(WS_EX_CLIENTEDGE, szClassName, szTitle, WS_OVERLAPPEDWINDOW | WS_THICKFRAME, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL); if (hWnd == NULL) { MessageBoxA( NULL, "Fenster konnte nicht erstellt werden", "Error", MB_OK); return false; } ShowWindow( hWnd, szCmdShow ); UpdateWindow( hWnd ); while ( GetMessage ( &msg, hWnd, NULL, NULL) > NULL ) { TranslateMessage( &msg ); DispatchMessage( &msg ); } return 0; } LRESULT CALLBACK WndProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam ) { switch (msg) { case WM_RBUTTONDOWN : MessageBox( NULL, "Rechte Maustaste ;)", "Super", MB_OK); break; case WM_QUIT: MessageBoxA( NULL, "Programm wurde beendet.", "ENDE ;)", MB_OK); DestroyWindow ( hWnd ); break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hWnd, msg, wParam, lParam ); } }
Wie kann ich aber einen Anderen Hintergrund einstellen z.b. ein Jpg Bild ???
freue mich über jede Hilfe ...
-
Hm, wofür könnte dieses
WndClassEx.hbrBackground
wohl gut sein...
-
ja klar aber wie bekomme ich da ein Bild rein
ich hab nämlich mal gelesen das man da einen Loader basteln muss oder so...
kann mir dazu jemand was sagenDanke im vor raus.
-
Naja, du musst eben dein Bild laden und dann einen Brush daraus erzeugen.
Die vielleicht bessere Alternative wäre, hbrBackground auf Null zu setzen und den Hintergrund in WM_ERASEBKGND selbst zu zeichnen.
-
Ok danke ich habe es jetzt so Probiert:
// eigenes Fenster.cpp : Definiert den Einstiegspunkt für die Konsolenanwendung. // #include "stdafx.h" #include <Windows.h> const char szClassName[] = "MyClassEx"; char szTitle[] = "Fenster NO 1. | Copyright by JaRk Producktion © 2012"; LRESULT CALLBACK WndProc ( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam ); int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance , LPSTR szCmdLine, int szCmdShow ) { WNDCLASSEX WndClassEx; HWND hWnd; MSG msg; HBITMAP hBitmap = (HBITMAP)::LoadImage(NULL, "C:\\Users\TS Tim\Pictures\Wise.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE|LR_CREATEDIBSECTION); //°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°RESTRIERUNG°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°// WndClassEx.cbSize = sizeof( WndClassEx ); WndClassEx.style = NULL; WndClassEx.lpfnWndProc = WndProc; WndClassEx.cbClsExtra = NULL; WndClassEx.cbWndExtra = NULL; WndClassEx.hInstance = hInstance; WndClassEx.hIcon = LoadIcon( NULL, IDI_ERROR ); WndClassEx.hCursor = LoadCursor( NULL, IDC_HAND ); WndClassEx.hbrBackground = (HBRUSH) hBitmap; WndClassEx.lpszMenuName = NULL; WndClassEx.lpszClassName = szClassName; WndClassEx.hIconSm = LoadIcon( NULL, IDI_APPLICATION); if( !RegisterClassEx( &WndClassEx )) { MessageBoxA(NULL, "Registrierungs Fehler! ", "Error ", MB_OK); return false; } //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FENSTER ERSTELLEN ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^// hWnd = CreateWindowEx(WS_EX_CLIENTEDGE, szClassName, szTitle, WS_OVERLAPPEDWINDOW | WS_THICKFRAME, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL); if (hWnd == NULL) { MessageBoxA( NULL, "Fenster konnte nicht erstellt werden", "Error", MB_OK); return false; } ShowWindow( hWnd, szCmdShow ); UpdateWindow( hWnd ); while ( GetMessage ( &msg, hWnd, NULL, NULL) > NULL ) { TranslateMessage( &msg ); DispatchMessage( &msg ); } return 0; } LRESULT CALLBACK WndProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam ) { switch (msg) { case WM_RBUTTONDOWN : MessageBox( NULL, "Rechte Maustaste ;)", "Super", MB_OK); break; case WM_QUIT: MessageBoxA( NULL, "Programm wurde beendet.", "ENDE ;)", MB_OK); DestroyWindow ( hWnd ); break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hWnd, msg, wParam, lParam ); } }
Aber es geht nicht.
Was mache ich falsch.
-
Ich hab meinen Fehler ich hätte
HBITMAP hBitmap = (HBITMAP)::LoadImage(NULL, "C:\\Users\\TS Tim\\Pictures\\Wise.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE|LR_CREATEDIBSECTION);
schreiben müssen und auserdem wie du geschrieben hat noch
CreatePatternBrush verwenden.WndClassEx.hbrBackground = CreatePatternBrush( hBitmap );
so siet dan die zeile aus.
:p
-
Und noch danke an dot
-
sry aber ich hab ein neues problem
wie passe ich das bmp der größe des Fensters an ???bis jetzt überschneidet es sich.
::(:
-
Was genau meinst du mit "anpassen"? Ich denk jedenfalls, dass du dafür lieber den Hintergrund wie oben schonmal erwähnt in WM_ERASEBKGND mit GDI (StretchBlt()?) selbst malen solltest, anstatt das über Brushes zu lösen.
-
Ja aber das verstehe ich nicht ganz.
und ich meinte nicht überschneiden sondern wenn ich mein fenster vergrößer
setzt sich das bild neben und übereinander.z.b. wenn die bmp ein Smili ist
so wenn es normal groß ist :
|-----|
||
||
so wennich das Fenster vergrößer:
|------------|
||
||
||
|_____|Ich möchte das das Smili dan gröser wird und nicht das es sich aneinanderreit.
-
Dann darfst Du keinen Pattern Brush nehmen, sondern Du musst WM_ERASEBKGND überscheiben uns mit StretchBlt Deine Bitmap zeichnen. dot hat Dich bereits auf diese Nachricht hingewiesen.
-
Ja aber ich hab gesagt das ich das nicht so ganz verstehe.
weil MSDN auf Englisch ist und ich als 9. Klässler mit einer 3 in Englisch
da so meine Schwierigkeiten habe !!!!!!!!deswegen bitte eine Erklährung auf deutsch ( und bitte verschont mich mit Google übersetzter ) oder eine Lösungsidee
für mein Problem.
Danke im Voraus...
-
Auch mit 3 Jahren Englisch kann man die MSDN lesen...
Ansonsten stelle "konkrete" Fragen "was" Du nicht verstehst!
Es sei Dir hier schon als Übung angeraten Dich mit Englsich vertraut zu machen, denn die meisten (ergiebigen) Quellen zur Programmierung wirst Du nur in dieser Sprache finden.Es dürfte nicht schwer sein sich aus den Informationen WM_ERASEBKGND und StretchBlt etwas zusammen zu googlen.
Ich sehe hier kein Problem, dass nicht mit etwas Eigeninitiative gelöst werden kann.Just my 2 cents.
-
ja also ich komm mit dem 5. Parameter garnicht zu recht.
und auser dem versteh ich nicht wo ich hinschreiben soll in welchem Verzeichniss das Bild ist.( Link zu Msdn seite: )
http://msdn.microsoft.com/de-de/library/3k5s37a5%28v=VS.80%29.aspx
-
Da warst du bei der falschen Funktion. Richtig: http://msdn.microsoft.com/en-us/library/windows/desktop/dd145120.aspx
-
Ok Aber hier verstehe ich nicht was ich in die HDC Handel rein schreiben soll.
Und überhaupt ich möchte ein bmp in den Hintergrund einfügen dieses Bitmap
habe ich in C:\\Users\\TS Tim\\Pictures\\Wise.bmp gespeichert.Aber so langsam bin ich mir nicht sicher ob das auch mit der StretchBlt
Funktion möglich ist.könntet ihr mir vielecht ein beispiel geben
-
dot schrieb:
Da warst du bei der falschen Funktion. Richtig: http://msdn.microsoft.com/en-us/library/windows/desktop/dd145120.aspx
Wie wäre es wenn Du die benötigten Stellen einfach aus dem dort verlinkten
Beispiel übernehmen würdest ? (For an example, see Scaling an Image.)Dort findet sich z.B.
//Gets the device context for the current window hDC = GetDC(hWnd);
Oder wenn man es in WM_PAINT braucht auch:
//Begin drawing hDC = BeginPaint(hWnd, &ps); ... EndPaint(hWnd, &ps);
Die benötigte Grösse für die Bitmap findet sich ebenfalls im Beispiel:
//Draw and fill rectangles for the background GetClientRect(hWnd, &clientRect);
Wo ist denn konkret das Problem ?
-
Ist schon ewig her, dass ich was mit GDI gemacht hab, daher hab ich evtl. was vergessen, aber rein vom Prinzip her folgender Ablauf:
- hbrBackground deiner WindowClass auf Null setzen.
- Z.B. in WM_CREATE ladest du dein Bild z.B. per LoadImage(), holst dir per GetDC() einen Device Context (DC) für dein Fenster und erzeugst mit CreateCompatibleDC() einen, mit dem Fenster kompatiblen, Memory DC. Dann selektierst du per SelectObject() deine Bitmap in deinen Memory DC und merkst dir die alte Bitmap aus dem DC (Rückgabewert von SelectObject()). ReleaseDC() auf dem Fenster DC nicht vergessen.
- In WM_ERASEBKND malst du per StretchBlt() dein Bild (hDC fürs Fenster findet sich im wParam).
- Am Ende natürlich alles entsprechend freigeben, vor dem DeleteDC() des, für deine Bitmap erzeugten, Memory DC die alte Bitmap wieder rein selecten.
Siehe auch: http://msdn.microsoft.com/en-us/library/windows/desktop/dd145049.aspx
-
Ich glaub ich bin irgend wie zu blöd dafür ich hab den Code jetzt so um geändert
aber es passiert rein garnichts:
#include "stdafx.h" #include <Windows.h> const char szClassName[] = "MyClassEx"; char szTitle[] = "Fenster NO 1. | Copyright by JaRk Producktion © 2012"; LRESULT CALLBACK WndProc ( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam ); int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance , LPSTR szCmdLine, int szCmdShow ) { WNDCLASSEX WndClassEx; HWND hWnd; MSG msg; //°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°RESTRIERUNG°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°// WndClassEx.cbSize = sizeof( WndClassEx ); WndClassEx.style = NULL; WndClassEx.lpfnWndProc = WndProc; WndClassEx.cbClsExtra = NULL; WndClassEx.cbWndExtra = NULL; WndClassEx.hInstance = hInstance; WndClassEx.hIcon = LoadIcon( NULL, IDI_ERROR ); WndClassEx.hCursor = LoadCursor( NULL, IDC_HAND ); WndClassEx.hbrBackground = NULL; WndClassEx.lpszMenuName = NULL; WndClassEx.lpszClassName = szClassName; WndClassEx.hIconSm = LoadIcon( NULL, IDI_APPLICATION); if( !RegisterClassEx( &WndClassEx )) { MessageBoxA(NULL, "Registrierungs Fehler! ", "Error ", MB_OK); return false; } //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FENSTER ERSTELLEN ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^// hWnd = CreateWindowEx(WS_EX_CLIENTEDGE, szClassName, szTitle, WS_OVERLAPPEDWINDOW | WS_THICKFRAME, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL); if (hWnd == NULL) { MessageBoxA( NULL, "Fenster konnte nicht erstellt werden", "Error", MB_OK); return false; } ShowWindow( hWnd, szCmdShow ); UpdateWindow( hWnd ); while ( GetMessage ( &msg, hWnd, NULL, NULL) > NULL ) { TranslateMessage( &msg ); DispatchMessage( &msg ); } return 0; } HGDIOBJ h; HDC hdc; LRESULT CALLBACK WndProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam ) { switch (msg) { case WM_SIZE : RECT rect; GetClientRect( hWnd, &rect ); break; case WM_CREATE : h = LoadImage(NULL, "C:\\Users\\TS Tim\\Pictures\\Wise.bmp", IMAGE_BITMAP, 100, 100, LR_LOADFROMFILE); hdc = GetDC( hWnd ); CreateCompatibleDC( hdc ); SelectObject( hdc, h ); ReleaseDC( hWnd, hdc ); break; case WM_ERASEBKGND : StretchBlt( hdc, 0, 0, CW_USEDEFAULT, CW_USEDEFAULT, hdc, rect.left, rect.top, rect.right, rect.bottom, SRCINVERT ); DeleteDC( hdc ); break; case WM_RBUTTONDOWN : MessageBox( NULL, "Rechte Maustaste ;)", "Super", MB_OK); break; case WM_QUIT: MessageBoxA( NULL, "Programm wurde beendet.", "ENDE ;)", MB_OK); DestroyWindow ( hWnd ); break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hWnd, msg, wParam, lParam ); } }
irgent wie ist das für meine C++ kenntnisse zu hoch::(:...
-
Du stocherst doch nur im Nebel rum.
StretchBlt benutzt zwei DCs einen Source DC und einen Target DC.
Du benutzt zweimal den gleichen.
Wie wäre es einfach mit Lesen, anstatt mit Try&Error.Zudem wurde Dir bereits gesagt, dass Du in WM_ERASEBKGND in wParam den entsprechenden Bildschirm DC bekommst.
-
ja logisch ich hab mir mal so ein bischen was zusammen gelesen und wollte nur so
neben bei wissen wie ich den hintergrund ändere aber das scheint ja für euch kein
problem zu sein und deshalb wolte ich auch nur ein kleines beispiel wie ich den Code verändern muss, um dann mit diesem Code zu lernen.