Problem mit Klasse
-
Hallo,
Ich hab mal versucht mit C++ anzufangen, bin meiner Meinung nach schon weit gekommen, bleib jetzt aber bei den Klassen hängen.
Hab eine kleine Win-Anwendung geschrieben, in der es einen Button gibt, den man mit anderen Buttons verändern kann.Hier der Code:
#include <windows.h> #include <winuser.h> #include <math.h> #include "MyButton.h" LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); char* IntToChar(int); HINSTANCE hInstance; int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) { MSG msg; HWND hWnd; WNDCLASS wc; const char szAppName[] = "Tests"; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH); wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); wc.hInstance = hInstance; wc.lpfnWndProc = WndProc; wc.lpszClassName = szAppName; wc.lpszMenuName = NULL; wc.style = CS_HREDRAW | CS_VREDRAW; RegisterClass(&wc); 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) { static HWND hButton_Test; static HWND hButton_WidthBigger; static RECT WinRect; MyButton Button_Test; MyButton Button_WidthBigger; switch(message) { case WM_CREATE: { hButton_Test = Button_Test.Create(hWnd, 10, 10, 50, 50, "ENDE"); hButton_WidthBigger = Button_WidthBigger.Create(hWnd, 0, 100, 75, 20, "Breiter"); return 0; } case WM_SIZE: { WinRect.left = 100; WinRect.right = LOWORD(lParam)-20; WinRect.bottom = LOWORD(lParam); return 0; } case WM_COMMAND: { if((HWND)lParam == hButton_Test) { if(HIWORD(wParam) == BN_CLICKED) PostQuitMessage(0); return 0; } if((HWND)lParam == hButton_WidthBigger) { if(HIWORD(wParam) == BN_CLICKED) Button_Test.WidthChanging(2); return 0; } return 0; } case WM_DESTROY: { PostQuitMessage(0); return 0; } } return DefWindowProc(hWnd, message, wParam, lParam); } char* IntToChar(int zahl) { char* itoc; int n; n = log10(zahl)+1; itoc = (char*)malloc((n+1)*sizeof(char)); itoc[n] = '\0'; do { itoc[--n] = zahl%10 + 48; zahl = floor(zahl/10); }while(zahl!=0); return itoc; }und die MyButton.h datei:
class MyButton { public: HWND Create( HWND, int, int, int, int, char*); void WidthChanging(int); private: HWND hParent; HWND hButton; }; inline HWND MyButton::Create( HWND hwndParent, int iXpos, int iYpos, int iWidth, int iHeight, char* szText) { HWND hButton; hParent = hwndParent; hButton = CreateWindow( "BUTTON", szText, WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON, iXpos, iYpos, iWidth, iHeight, hwndParent, NULL, 0, NULL ); return hButton; } inline void MyButton::WidthChanging(int iWidthAdding) { RECT rectButton; WINDOWINFO pwi; GetWindowInfo(hParent, &pwi); GetWindowRect(hButton, &rectButton); MoveWindow( hButton, rectButton.left - pwi.rcClient.left, rectButton.top - pwi.rcClient.top, rectButton.right - rectButton.left + iWidthAdding, rectButton.bottom - rectButton.top, 1); }Und jetzt das Problem:
hButton und hParent werden irgendwie nicht richtig initialisiert. Hat da jemand eine Ahnung?
-
wenn du den Button mit der Aufschrift breiter drueckst.
Liegt scheinbar daran das der "hwndParent" in der Klasse nicht mehr gueltig ist dadurch deine 2 Instanzen
MyButton Button_Test; MyButton Button_WidthBigger;nicht statisch sind WM_CREATE wird eben nur einmal benutzt
wird WndProc verlassen sind die HWND dadurch nichtmher gueltig.
wurde WM_CREATE abgearbeitet und die Fensterprozedur verlassen wird der Default-Destructor aufgerufen der beiden Instanzen und die sind weg und die HWND auch!entweder Du machst es so:
static MyButton Button_Test; static MyButton Button_WidthBigger;Oder Du änderst den Prototypen von WidthChanging in deiner Klasse so
MyButton::WidthChanging(int, HWND , HWND); inline void MyButton::WidthChanging(int iWidthAdding, HWND hParent, HWND hButton) { RECT rectButton; WINDOWINFO pwi; GetWindowInfo(hParent, &pwi); GetWindowRect(hButton, &rectButton); MoveWindow( hButton, rectButton.left - pwi.rcClient.left, rectButton.top - pwi.rcClient.top, rectButton.right - rectButton.left + iWidthAdding, rectButton.bottom - rectButton.top, 1); }Nimm eine der beiden Möglichkeiten mir persoenlich gefällt die 2. besser
die habe ich auch getestet die funzt auf jeden Fall!mfg sclearscreen

-
und nimm mal bitte das naechstmal die richtigen Code-Tags liesst sich so
einfach besser so als wenn ich an meiner IDE sitzen wuerdeSchwarz/Weiss bekommt man ja nen wad weiss ich...

-
static MyButton Button_Test; static MyButton Button_WidthBigger;dies funktioniert auch wenn Du folgende kleinen Fehler bei Dir noch beseitigst!
siehe:
class MyButton { public: HWND Create( HWND, int, int, int, int, char*); void WidthChanging(int); private: HWND hParent; HWND hButton; // auchtung in der Funktion "WidthChanging" überschreibst Du diese durch eine lokale Variable gleichen Namens }; inline void MyButton::WidthChanging(int iWidthAdding) { HWND hButton; // hier der Fehler das muss weg diese Deklaration RECT rectButton; WINDOWINFO pwi; GetWindowInfo(hParent, &pwi); GetWindowRect(hButton, &rectButton); MoveWindow( hButton, rectButton.left - pwi.rcClient.left, rectButton.top - pwi.rcClient.top, rectButton.right - rectButton.left + iWidthAdding, rectButton.bottom - rectButton.top, 1); }So musses aussehen:
class MyButton { public: HWND Create( HWND, int, int, int, int, char*); void WidthChanging(int); private: HWND hParent; HWND hButton; }; inline void MyButton::WidthChanging(int iWidthAdding) { RECT rectButton; WINDOWINFO pwi; GetWindowInfo(hParent, &pwi); GetWindowRect(hButton, &rectButton); MoveWindow( hButton, rectButton.left - pwi.rcClient.left, rectButton.top - pwi.rcClient.top, rectButton.right - rectButton.left + iWidthAdding, rectButton.bottom - rectButton.top, 1); }dann machst Du die in deiner Fensterprozedur
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { static HWND hButton_Test; static HWND hButton_WidthBigger; static RECT WinRect; static MyButton Button_Test; static MyButton Button_WidthBigger; . . . }die 2 statisch und dan funktionieren beide Varianten die ich Dir auf den Weg gegeben habe!
Sind nur kleine Fehler kann jedem passieren. Wie gesagt mein Geschmack ist die 2. Variante
die beiden HWND extra an die Funktion übergeben kannst ja auch dafuer sorgen das deine Anwendung mit beiden klarkommt das fexibilsiert dein Button-Klasse
immens.siehe:
class MyButton { public: HWND Create( HWND, int, int, int, int, char*); void WidthChanging(int, HWND, HWND ); void WidthChanging(int); private: HWND hParent; HWND hButton; }; inline HWND MyButton::Create( HWND hwndParent, int iXpos, int iYpos, int iWidth, int iHeight, char* szText) { hParent = hwndParent; hButton = CreateWindow( "BUTTON", szText, WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON, iXpos, iYpos, iWidth, iHeight, hwndParent, NULL, 0, NULL ); return hButton; } inline void MyButton::WidthChanging(int iWidthAdding, HWND hParent, HWND hButton) { RECT rectButton; WINDOWINFO pwi; GetWindowInfo(hParent, &pwi); GetWindowRect(hButton, &rectButton); MoveWindow( hButton, rectButton.left - pwi.rcClient.left, rectButton.top - pwi.rcClient.top, rectButton.right - rectButton.left + iWidthAdding, rectButton.bottom - rectButton.top, 1); } inline void MyButton::WidthChanging(int iWidthAdding) { RECT rectButton; WINDOWINFO pwi; GetWindowInfo(hParent, &pwi); GetWindowRect(hButton, &rectButton); MoveWindow( hButton, rectButton.left - pwi.rcClient.left, rectButton.top - pwi.rcClient.top, rectButton.right - rectButton.left + iWidthAdding, rectButton.bottom - rectButton.top, 1); }
-
zum anderen mir isses ja eigentlich WAYNE aber dein Thema wäre im WinAPI-Forum
eigentlich an der richtigen Stelle gewesen
-
so, hab code-tags geändert.
wiesoi ins win-api-forum? klassen gehören doch zu c++ und nicht zur api?
-
weil Dein Code zu 99% aus Aufrufen aus WinAPI besteht würde ich sagen einige andere hier könnten das auch so sehen deshalb! Zum anderen der Fehler
bei eine Variable des Types HWND lag die mit Ihrer Typdefinition in Windows.h liegt und kein Standard-C++ somit ist.Aber ich sagte ja bereits mir als Mitglied ist sowas dodal Wayne aber ich habe schon oft gelesen das sich manche hier mit dem ertsen Satz gleich melden falsches Forum etc. naja
Aber mir ists Brust ich guck mir nur das Prob an überlege ob ich Senf dazu habe um diese dazuzugeben.

Ich meine ein bisschen Ordnung muss schon sein ist ja klar

-
hoffe dir geholfen zu haben! Noch ein schönes Pfingsten
ich muss mich jetzt an C# machen Grüsse

-
sclearscreen schrieb:
ich muss mich jetzt an C# machen Grüsse

Das gehört aber ins .NET Forum

-
ok. danke füre die hilfe. habs jetzt getestet, und es geht wirklich. Danke.
Achja. ich würde es trotzdem nicht ins Win-api forum reintun, weil mein Problem mit der Klasse zusammenhängt
