Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (WinAPI, Konsole) » Seltsamer Fehler bei eigener Window-Class

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 <
000
03.01.2007, 18:27 Uhr
Blackskyliner



Hallo ich habe ein großes Problem und nichts passendes finden können. Und zwar habe ich eine Klasse geschrieben, mit welcher ich meine Fenster verwalten möchte. Die Klasse ist in der main.h definiert und das WinMain() und die WindowProcedure() ist in der main.cpp
Ich bekomme immer den Fehler, dass eine abnormal programm termination vorgenommen wurde... bzw. passierte. Soweit so gut... Damit kann ich nichts anfangan und Fehler hab ich mit meinen C++ Kentnissen nicht entdeckt... Es kann sein dass ich beim aufrufen der Klasse einen Fehler mache aber ich habs so gelernt... So nun nimma viel drumm herum hier ist mal der Sourcecode:

main.h

C++:
#define MAX_WINDOWCOUNT 10
LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);
char szClassName[ ] = "BlackWindow";


/*
    Structures
*/

struct NEW_HWND{
       int ID;
       HWND FensterHandle; // Später vom Typ HWND      
};

/*
    Enumerations
*/

enum ERROR_TYPES{ERROR_INIT_WINDOW, ERROR_HWND_ALREADY_INITIALIZED, ERROR_ID_NOT_INITIALIZED};

/*
    Klassen
*/
    

class Window{
    public:
        Window();
        ~Window();
        
        void DeleteWindow();
        void ShowWindow(int, int);
        bool InitWindow(HINSTANCE);
        
        HWND AddWindow(int, HWND);    
        HWND MyCreateWindow(int,LPSTR,int,int);
        HWND GetHandle(int);
        
        
    protected:
        NEW_HWND WindowList[MAX_WINDOWCOUNT];
        HINSTANCE hThisInstance;
};

/*
    Functions
*/

Window::Window(){
    for(int i = 0; i < MAX_WINDOWCOUNT; i++)
    {
        this->WindowList[i].ID                 = 0;
        this->WindowList[i].FensterHandle     = NULL;
    }
}

Window::~Window(){
    delete this->WindowList;
}

void Window::ShowWindow(int ID, int nFunsterStil){
    ShowWindow((int)this->GetHandle(ID),nFunsterStil);
}

bool Window::InitWindow(HINSTANCE hThisInstance){
    this->hThisInstance = hThisInstance;
    WNDCLASSEX wincl;        /* Data structure for the windowclass */

    /* The Window structure */
    wincl.hInstance = hThisInstance;
    wincl.lpszClassName = szClassName;
    wincl.lpfnWndProc = WindowProcedure;      /* This function is called by windows */
    wincl.style = CS_DBLCLKS;                 /* Catch double-clicks */
    wincl.cbSize = sizeof (WNDCLASSEX);

    /* Use default icon and mouse-pointer */
    wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
    wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
    wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
    wincl.lpszMenuName = NULL;                 /* No menu */
    wincl.cbClsExtra = 0;                      /* No extra bytes after the window class */
    wincl.cbWndExtra = 0;                      /* structure or the window instance */
    /* Use Windows's default color as the background of the window */
    wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND;

    /* Register the window class, and if it fails quit the program */
    if (!RegisterClassEx (&wincl))
        return false;
}

HWND Window::MyCreateWindow(int ID, LPSTR Title, int width, int height){
    HWND hwnd;
    hwnd = CreateWindowEx (
           0,                   /* Extended possibilites for variation */
           szClassName,         /* Classname */
           "Windows App",       /* Title Text */
           WS_OVERLAPPEDWINDOW, /* default window */
           CW_USEDEFAULT,       /* Windows decides the position */
           CW_USEDEFAULT,       /* where the window ends up on the screen */
           544,                 /* The programs width */
           375,                 /* and height in pixels */
           HWND_DESKTOP,        /* The window is a child-window to desktop */
           NULL,                /* No menu */
           hThisInstance,       /* Program Instance handler */
           NULL                 /* No Window Creation data */
       );
    
    this->AddWindow(ID, hwnd);
    
    return NULL;
}

HWND Window::AddWindow(int ID, HWND WindowHandle){
    for(int i = 0; i < MAX_WINDOWCOUNT; i++)
    {
        if(this->WindowList[i].ID == 0 && this->WindowList[i].FensterHandle == NULL)
        {
            for(int i2; i2 < i; i2++){
                if(WindowList[i].FensterHandle == WindowHandle)
                    throw ERROR_HWND_ALREADY_INITIALIZED;
            }
            this->WindowList[i].ID                 = ID;
            this->WindowList[i].FensterHandle     = WindowHandle;
            return WindowHandle;
        }
    }
    return NULL;
}

HWND Window::GetHandle(int ID){
    for(int i = 0; i < MAX_WINDOWCOUNT; i++)
    {
        if(WindowList[i].ID == ID)
            return WindowList[i].FensterHandle;
    }
    throw ERROR_ID_NOT_INITIALIZED;
}




main.cpp

C++:
#include <windows.h>
#include "main.h"

enum WINDOWES{    WINDOW_1=1,WINDOW_2=2,WINDOW_3=3,WINDOW_4=4,WINDOW_5=5,
                WINDOW_6=6, WINDOW_7=7,WINDOW_8=8,WINDOW_9=9,WINDOW_10=10    };

int WINAPI WinMain (HINSTANCE hThisInstance,
                    HINSTANCE hPrevInstance,
                    LPSTR lpszArgument,
                    int nFunsterStil)

{
    Window Fensterklasse;
    
    //HWND hwnd;               ||MLC||
    MSG messages;            /* This is the handle for our window */
    
    Fensterklasse.InitWindow(hThisInstance);
    Fensterklasse.MyCreateWindow(WINDOW_1, "Testfenster",500,500);
    Fensterklasse.ShowWindow(WINDOW_1, nFunsterStil);
    
    /* Here messages to the application are saved */
    //ShowWindow (hwnd, nFunsterStil);

    /* Make the window visible on the screen */
    while (GetMessage (&messages, NULL, 0, 0))
    {
        /* Run the message loop. It will run until GetMessage() returns 0 */
        TranslateMessage(&messages);
        /* Translate virtual-key messages into character messages */
        DispatchMessage(&messages);
    }

    /* Send message to WindowProcedure */
    return messages.wParam;
}

LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)                  /* The program return-value is 0 - The value that PostQuitMessage() gave */
    {
        case WM_DESTROY:
            PostQuitMessage (0);       /* handle the messages */
            break;
        default:                      /* send a WM_QUIT to the message queue */
            return DefWindowProc (hwnd, message, wParam, lParam);
    }

    return 0;
}




Achja ich nutze Dev-C++ 4.9.9.2 mit der MinGW Version 3.7, der gcc Version 3.4.2 und der Winapi 3.2 (Packet versions nummern)

Ich danke allen, die sich den Mist angggen und mir helfen


Bearbeitung:

Habe gerade mitbekommen, das wenn ich das ShowWindow rauskommentiere, dann hängt das programm fest... kann man die hInstance nicht so übergeben, wie ich das gemacht habe sondern eher per Pointer übergeben?

Wenn ich das aber allerdings Per Pointer übergebe, wie greife ich dann in der Funktion so darauf zu, dass er nicht versucht HINSTANCE** in die WNDCLASS einzutragen?? Sorry für solche Fragen


Dieser Post wurde am 03.01.2007 um 18:35 Uhr von Blackskyliner editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
03.01.2007, 18:58 Uhr
Uwe
C/C++ Master
(Administrator)


Hallo,
Auf die Schnelle und überflogen: Erst einmal zwei Sachen die mir "spanisch" vorkommen.

C++:
HWND Window::AddWindow(int ID, HWND WindowHandle){
    for(int i = 0; i < MAX_WINDOWCOUNT; i++)
    {
        if(this->WindowList[i].ID == 0 && this->WindowList[i].FensterHandle == NULL)
        {
            for(int i2; i2 < i; i2++){
         .......


i2 ist (scheinbar) nicht initialisiert.

C++:
HWND Window::GetHandle(int ID){
    for(int i = 0; i < MAX_WINDOWCOUNT; i++)
    {
        if(WindowList[i].ID == ID)
            return WindowList[i].FensterHandle;
    }
    throw ERROR_ID_NOT_INITIALIZED;
}


Was bezweckst Du mit dem throw an der Stelle?
--
"Es ist schwierig, ein Programm wirklich idiotensicher zu machen, weil Idioten so genial sind."

Bis dann...
Uwe
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
03.01.2007, 19:24 Uhr
Blackskyliner



i2 ist initialisiert, es wird in der for initialisiert

Das Throw mache ich darum, weil ich, wenn ich eine ID angebe die nochnicht inizialisiert wurde durch AddWindow() einen Fehler zurück zugeben ich weiß iss Irrsinn aber ich will das halt so haben, für spätere eventualitäten . Ich glaube, ich erkenne grade mein Problem waum die Ausführung stopp aber ich kenne mich jetzt grade nicht 100%tig genau mit Ecxeptions aus... Nun meine Frage zu den Ecxeptions... Wenn ich ein throw mache obwohl ich keinen try-catch Block habe hängt dann das Programm?


Bearbeitung:

OK daran lag es nun auch
Nun meint er, dass ich kein Fenster initialisiert haben, obwohl ich das doch getan habe, jmd. ne Idee wo der Fehler noch liegen könnte?


Dieser Post wurde am 03.01.2007 um 19:30 Uhr von Blackskyliner editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
03.01.2007, 19:46 Uhr
Blackskyliner



Ich habe bemerkt, durch einige Tests, dass er bei Fensterklasse.ShowWindow(WINDOW_1, nFunsterStil); eine Endlosschleife erzeugt... und immerwieder Fensterklasse.ShowWindow(WINDOW_1, nFunsterStil); aufgerufen wird... Liegt das daran, dass ich die WinAPI funktion ShowWindow() innerhalt meiner Klasse Aufrufe, obwohl ich das dort garnicht will?


Bearbeitung:

VERDAMMT! daran lag es Danke an die Hilfe aller!

Noch eine Nachfrage, wie kann man sowas unterbinden? dass er eine KlassenMethode Callt statt die Globale, die genau so heißt.. weil ich mag nicht immer das My for meinen Funktionen haben


Dieser Post wurde am 03.01.2007 um 19:48 Uhr von Blackskyliner editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
03.01.2007, 19:48 Uhr
FloSoft
Medialer Over-Flow
(Administrator)



C++:
for(int i2; i2 < i; i2++){



i2 ist und bleibt uninitialisiert, also "ohne festen wert", d.h in i2 steht ein beliebiger startwert!

Ansonsten:

throw schmeißt eine exception, wird sie von deinem programm nicht gefangen, stürzt es ab ("unhandled exception ...")

Das es einfach hängen bleibt liegt zu 99% an der forschleife, denn wenn der wert "zufällig" so groß ist, das i2 negativ wird, läuft das erstmal ewige zeiten (vor allem weil du auch noch i2++ benutzt, nicht ++i2. Der Unterschied liegt darin das ++i2 den stack nicht belastet, i2++ jedoch schon, da es ja den vorherigen wert erstmal zum zurückgeben sichern muss)
--
class God : public ChuckNorris { };
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
03.01.2007, 19:50 Uhr
Blackskyliner



Ich weiß, dass i2 auf 0 gesetzt wird, weil ich progge das schon ne ganze Zeit so... Aber darum gehts ja jetzt nichtmehr, aber ich nehme es trotzdem zur Kentniss

Siehe den EDIT in meinem letzen Post

Dieser Post wurde am 03.01.2007 um 19:50 Uhr von Blackskyliner editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
006
03.01.2007, 19:55 Uhr
FloSoft
Medialer Over-Flow
(Administrator)


i2 wird eben nicht auf 0 gesetzt, das ist ja das problem gewesen. Es ist zufall wenn die i2 0 war, z.b dadurch das man das Programm per Debugger startet, da initialisiert er sowas meist, auch wenn z.b zufällig die speicheradresse vor dieser stelle noch unbenutzt war, ist die stelle 0 (falls preemptives system), ansonsten ist die Stelle eben irgendwas. Und "irgendwas" ist immer gefährlich.


Bearbeitung:

::ShowWindow

benutzen, also :: davor für den übergeordneten namespace, oder wenn dieser benannt ist den namen davor, z.b std::foobar


--
class God : public ChuckNorris { };

Dieser Post wurde am 03.01.2007 um 19:56 Uhr von FloSoft editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
007
03.01.2007, 20:06 Uhr
Blackskyliner



Aber ist es nicht ein Statischer aufruf, wenn ich etwas über :: Calle? Zumindest war mir grade so... aber kann mich ja auch Irren

Jetzt weis ich was du meinst bei dem i2 und ichs sehs grade ich habe vergessen ein " = 0"dahinter zu machen du hast Recht Hab aber seltsamer Art und Weise dort keine Probleme gehabt
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
008
04.01.2007, 20:36 Uhr
xXx
Devil


Hmm Strukturen können einen Konstruktor haben ...
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 <     [ C / C++ (WinAPI, Konsole) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: