[C++]Zweites Windows Fenster

Hi,

also ich beschäftige mich gerade mit der WinApi und bastel an Windows Fenstern herum.
Ich habe bereits ein Fenster hin bekommen jedoch wenn ich versuche ein weiteres zu erstellen ( evtl. nach Betätigung eines Buttons ) diese Fehlermeldung erscheint:
Code:
  [Linker error] undefined reference to `_Z15WindowProcedureP6HWND__jjl@16'

Ich muss doch ein zweites Fenster genau so erstellen wie das erste oder als child hervorrufen ?

Brauche ich für das zweite Fenster eine eigene Callback Funktion ?
Oder einfach nur die Parameterliste um ein Handle erweitern ?

Ich habe Win XP und benutze die Umgebung Dev C++

MfG
 
"Ich habe hier die Errormeldung "123". Was soll ich tun?"

Wird dir der Fehler in deiner Frage bewusst? ;-)
-> Ein Quelltext wäre schön, um zu sehen warum dein Fehler kommt und wie du das Problem angegangen bist. :)
 
OK, beginnen wir damit, uns schrittweise an die Beschreibung des Problems heranzutasten, um die Voraussetzung zu erlangen, das Problem beheben zu können...

Die Existenz einer Linker-Meldung läßt darauf schließen, daß das Problem NICHT darin besteht, daß Du eine Taste drücken willst oder das laufende Programm versuchen würde, ein zweites Fenster zu erstellen.

Was die Linker-Meldung über ein fehlendes "Ding" aussagt, ist, daß Du (immerhin) in Deinem C-Quelltext jenes "Ding" korrekt angekündigt (deklariert) hast, es aber selbst auch ausformulieren (hier den Inhalt des Funktionskörpers definieren) müßtest, was Du aber nicht getan hast.

Der Compiler ging beim Compilieren davon aus, daß Du ja vielleicht Deine "WindowProcedure" von irgendwo anders her (vom Linker) importieren lassen könntest und betrachtete das Fehlen des Dingens für aus seiner Sicht unproblematisch. Wo Du in Deinem Quelltext auf das "Ding" verweist, hat der Compiler nur Zeiger vorgesehen, deren konkrete Ausfüllung er einfach dem Linker überließ. Letzterer allerdings guckt in die Röhre, weil es tatsächlich und eigentlich ganz anders gemeint war.

Was als mögliche Ursache in Frage kommt, ist sehr vielfältig: Angefangen von allen möglichen Tippfehlern (Funktionsrumpf zwar definiert, aber in irgendeinem Detail weicht der Funktionskopf von einer davor hingestellten Deklaration ab) über schlicht vergessen hinzuschreiben bis dazu, daß Du eventuell erstmal das Grundprinzip der Funktionsweise von Compiler und Linker sowie Betriebssystemschnittstellen verstehen lernen müßtest, ehe Du mit komplexeren Anwendungen beginnst.

Was davon und gegebenenfalls in welchem Umfang zutrifft, müßten wir jetzt schrittweise eingrenzen. Dazu wäre ein Ausschnitt des Programms sinnvoll, um das es hier geht. Und zwar mindestens mit allen Vorankündigungen, Definitionen und Aufrufen jener vom Linker bemeckerten WindowProcedure...

----

P.S.: Um das Orakeln etwas zu beschleunigen: Ich vermute aus dem Umstand, daß Du bereits ein Fenster erfolgreich erzeugen lassen konntest, daß Du das mit der WindowProc vom Prinzip her erstmal verstanden hast. Und daß Du beim Erzeugen des zweiten Fensters eventuell eine andere solche einführen wolltest, diese dabei erstmal genauso deklariert hast, wie Du sie beim beim Aufruf der Funktion zur Fenstererzeugung nennst, dann aber beim Definieren der Funktion einen Tippfehler begangen hast...

Wie gesagt: Ohne Einsicht in den Quelltext geht es nicht weiter...
 
Ich habe jetzt meine erste Fenster Funktion kopiert und leicht verändert und zusätzlich eine zweite Callback Funktion geschrieben aber das Fenster Handle wird nicht erzeuugt :/

Windows Fenster Funktion:
Code:
HWND CrtWina ( HINSTANCE hThisInstance )
{
    WNDCLASSEX wincla;       
    HWND hWnda;
    
    const char szClassName[] = "WindowsApp";
    
    wincla.hInstance = hThisInstance;
    wincla.lpszClassName = szClassName;
    wincla.lpfnWndProc = WindowProcedure2;      
    wincla.style = CS_HREDRAW | CS_VREDRAW;                 
    wincla.cbSize = sizeof (WNDCLASSEX);

    
    wincla.hIcon = LoadIcon (NULL, IDI_APPLICATION);
    wincla.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
    wincla.hCursor = LoadCursor (NULL, IDC_ARROW);
    wincla.lpszMenuName = NULL;                 
    wincla.cbClsExtra = 0;                      
    wincla.cbWndExtra = 0;                      
    
    wincla.hbrBackground = (HBRUSH) COLOR_BACKGROUND;

    
    if (!RegisterClassEx (&wincla))
        return 0;

    
    hWnda = CreateWindowEx (
           0,                   
           szClassName,         
           "Windows App",       
           WS_OVERLAPPEDWINDOW,
           CW_USEDEFAULT,       
           CW_USEDEFAULT,       
           300,                 
           200,                 
           HWND_DESKTOP,        
           NULL,                
           hThisInstance,       
           NULL);
           
           return hWnda;
};

Callback Funktion:
Code:
LRESULT CALLBACK WindowProcedure2 (HWND hWnda, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)                  
    {
        .....
    }break;
    return DefWindowProc (hWnda, message, wParam, lParam);
}

main.cpp
Code:
{
    MSG messages;
    HWND hWnd;
    HWND hWnda;
    
    hWnd = CrtWin ( hThisInstance );
    hWnda = CrtWin ( hThisInstance );
    
    if ( hWnd == NULL || hWnda == NULL )
    {
         return 0;
    };
    
    // Nach der Überprüfung bricht er ab
    
    

    
    while (GetMessage (&messages, NULL, 0, 0))
    {
        
        TranslateMessage(&messages);
        
        DispatchMessage(&messages);
    };

    
    return messages.wParam;
}
 
Vielleicht hat es ja was mit der Instanz zu tun "hThisInstance" und ich denke du brauchst dann auch noch eine weitere MSG Variable.
Aber ich denke das eine Callback Funktion reicht du musst halt nur die Parameter änder bzw. erweitern.
 
Du versuchst, Deine "Window-Klasse" doppelt zu registrieren und läßt Dein Programm abbrechen, wenn dies (beim zweiten mal) nicht gelingt.

Die Window-Klasse wird über ihren Namen eindeutig global auf einem Windows-Desktop identifiziert.

Du solltest, obwohl Du dies nicht zwingend tun mußt, damit die Fensterbehandlung innerhalb der DefaultWindowProc funktioniert, die GUI-Dinge, die Du anlegst, in Deinem eigenen Programm NOTIEREN und auswerten lassen.

In diesem Fall: Notiere Dir wenigstens das Handle für Deine Window-Klasse in einer eigenen Variablen. Teste diese erst, ob sie bereits gesetzt ist, bevor Du versuchst, in einem Unterprogramm gegebenenfalls eine wiederholte Registrierung zu veranlassen.

Noch besser und systematischer: Entwerfe eigene Shell-Strukturen um die GUI-Dinge herum, mit denen Du sowas wie Handles (und gegebenenfalls Dinge, die Du zum Zeitpunkt des Erzeugens kennst und später eventuell wieder benötigst, aber nicht mehr ohne weiteres über Windows-API-Funktionen abgefragt kriegst) festhalten läßt.

Richtig angenehm wird es, wenn Du implizite Typecasts Deiner derartigen Strukturen auf die im Windows-API gebräuchlichen Handles (und Konstruktoren daraus) vorsiehst:

Code:
struct MyWindow
{
  Handle handle;
  MyWindow(Handle h) {handle = h;}
  operator Handle&() {return handle;}
};
 
Zurück
Oben