Problem mit Fenster erstellung innerhalb einer Klasse



  • Hallo,

    Ich will eine "Fensterklasse" erstellen. Wenn ich ErsteleWindow aufrufe,soll die Klasse ein Fenster erstellen das bestimmte Aufgaben erledigt. Das Problem ist ich bekomme folgenden Fehler:
    [Linker error] undefined reference to `file_offnen::hwnd'

    #include <windows.h>
    
    class file_offnen 
    {
    	public:
    		static bool ErsteleWindow(HINSTANCE hThisInstance)
    		{
    			HWND hwnd;
    			WNDCLASSEX wincl;
    			wincl.hInstance = hThisInstance;
        		wincl.lpszClassName = "xyz";
       			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) GetSysColorBrush(COLOR_3DFACE);   			
       			wincl.lpfnWndProc = file_offnen::OpenWndProc;
    
          		if (!RegisterClassEx (&wincl))
            		return 0;
          		hwnd = CreateWindowEx (0,"xyz","Vokabel Learning",WS_OVERLAPPEDWINDOW,100,100,100,100,HWND_DESKTOP,NULL,hThisInstance,NULL);
               ShowWindow (hwnd, SW_SHOW);           	
    		}
      		static char* GetFilename()
      		{
      		}
      		static void GetVok()
      		{
      		}  		
      		static LRESULT CALLBACK OpenWndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
      		{
      			return DefWindowProc (hwnd, message, wParam, lParam);
      		}
    };
    


  • Fehlt da nicht noch was? Oder ist das wirklich die vollständige Klasse?



  • Das ist eigentlich alles



  • kann irgendwie nicht sein.

    Dein Code + main()-Funktion ergibt nämlich keinen Linkerfehler.



  • Ich benutze Dev-Cpp wenn dir das weiterhilft. Aber bei mir habe ich so einen Linker Fehler. Und das ist die Komplete Klasse beginnt mit class file_open { ... }; das ist alles.



  • Gib am besten ein *minimales*, *compilierbares* Beispiel das den Linkerfehler zeigt. Dann kann dir auch geholfen werden.



  • Da ich denn Fehler komischerweise nicht in einem anderem Programm reproduzieren kann, poste ich jetzt einfach mal die vollständige WindowProcedure von dem aus die Klasse aufgerufen wird:

    LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
    	bool ok;
     	char eingabe[255];
      	char buf[10];
      	static char datei[] = "Debugging Vokabeln";
     	static HBITMAP kasten1, kasten2, kasten3, kasten4;
     	static BITMAP bitmap1, bitmap2, bitmap3, bitmap4;
     	static VOKABEL_DATEN vok_daten[30];
     	static VOKABEL_STATS vok_stats;
     	static file_offnen filewnd;
      	PAINTSTRUCT ps ;
      	HDC hdc, hdcMem;
        switch (message)                  /* handle the messages */
        {
            case WM_DESTROY:
            	DeleteObject(kasten1);
                PostQuitMessage (0);       /* send a WM_QUIT to the message queue */
                break;
            case WM_CREATE:
            	//Intialiesierungen
            	static HINSTANCE hinstance = (HINSTANCE) GetWindowLong(hwnd,GWL_HINSTANCE);
    
           		CreateWindow("static", "Latein:", WS_VISIBLE | WS_CHILD, 60,90,100,20, hwnd, NULL, hinstance, NULL);
           		CreateWindow("static", "Deutsch:", WS_VISIBLE | WS_CHILD, 60,130,100,20, hwnd, NULL, hinstance, NULL);
           		CreateWindow("static", "Zusätze:", WS_VISIBLE | WS_CHILD, 60,170,100,20, hwnd, NULL, hinstance, NULL);
           		CreateWindow("static", "Datei:", WS_VISIBLE | WS_CHILD, 60,20,200,20, hwnd, (HMENU) TEXT_DATEI, hinstance, NULL);
           		//TODO: Mit CreateFont fette dicke Schriftart festsetzen
             	CreateWindow("static", "", WS_VISIBLE | WS_CHILD, 400,100,200,20, hwnd, (HMENU) TEXT_RFZEIGER, hinstance, NULL);
           		CreateWindow("static", "", WS_VISIBLE | WS_CHILD, 320,134,200,20, hwnd, (HMENU) TEXT_DEUTSCH, hinstance, NULL);
             	CreateWindow("edit", "", WS_VISIBLE | WS_CHILD | WS_BORDER, 140,90,160,20, hwnd, (HMENU) EDIT_LATEIN, hinstance, NULL);
           		CreateWindow("edit", "", WS_VISIBLE | WS_CHILD | WS_BORDER, 140,130,160,20, hwnd, (HMENU) EDIT_DEUTSCH, hinstance, NULL);
           		CreateWindow("edit", "", WS_VISIBLE | WS_CHILD | WS_BORDER, 140,170,160,20, hwnd, (HMENU) EDIT_ZUSATZ, hinstance, NULL);
           		CreateWindow("button", "Weiter", WS_VISIBLE | WS_CHILD, 220,210,100,30, hwnd, (HMENU) BU_WEITER, hinstance, NULL);
           		CreateWindow("button", "Lösung", WS_VISIBLE | WS_CHILD, 100,210,100,30, hwnd, (HMENU) BU_LOSUNG, hinstance, NULL);
    
           		EnumChildWindows(hwnd, EnumChildProc, 0);
             	kasten1 = (HBITMAP) LoadImage (GetModuleHandle (NULL), "kasten1.bmp",IMAGE_BITMAP,0, 0,LR_DEFAULTCOLOR | LR_LOADFROMFILE);
                kasten2 = (HBITMAP) LoadImage (GetModuleHandle (NULL), "kasten2.bmp",IMAGE_BITMAP,0, 0,LR_DEFAULTCOLOR | LR_LOADFROMFILE);
                kasten3 = (HBITMAP) LoadImage (GetModuleHandle (NULL), "kasten3.bmp",IMAGE_BITMAP,0, 0,LR_DEFAULTCOLOR | LR_LOADFROMFILE);
                kasten4 = (HBITMAP) LoadImage (GetModuleHandle (NULL), "kasten4.bmp",IMAGE_BITMAP,0, 0,LR_DEFAULTCOLOR | LR_LOADFROMFILE);
                GetObject (kasten1, sizeof (BITMAP), &bitmap1);
                GetObject (kasten2, sizeof (BITMAP), &bitmap2);
                GetObject (kasten3, sizeof (BITMAP), &bitmap3);
                GetObject (kasten4, sizeof (BITMAP), &bitmap4);
                break;     		
      		case WM_COMMAND:
      			switch(LOWORD(wParam))
      			{
    				case BU_WEITER:
    					GetDlgItemText(hwnd, EDIT_DEUTSCH, eingabe, 255);
    					ok = Uberprufen(vok_daten[i_aktvok].heimatsprache,eingabe);
    					FachSetzen(ok, &vok_daten[i_aktvok], &vok_stats);
        				if(ok)
            			{
            				//TODO: Mit CreateFont fette dicke Schriftart festsetzen
            				SetDlgItemText(hwnd, TEXT_RFZEIGER, "RICHTIG");
            				SetDlgItemText(hwnd, TEXT_DEUTSCH, "");
               			}
                  		else
                    	{
                    		//TODO: Mit CreateFont fette dicke Schriftart festsetzen
                       		SetDlgItemText(hwnd, TEXT_RFZEIGER, "FALSCH");
                       		SetDlgItemText(hwnd, TEXT_DEUTSCH, vok_daten[i_aktvok].heimatsprache);
                   		}
                   		if(vok_stats.gesamt == vok_stats.fach4)
                   		{
                   			MessageBox(0, "Sie haben die komplete Lektion geübt!", "FERTIG!", 0);               			
                   		}
                     	NachsteVokabel(vok_daten, &vok_stats);
                      	SetDlgItemText(hwnd, EDIT_LATEIN, vok_daten[i_aktvok].fremdsprache);
                       	SetDlgItemText(hwnd, EDIT_DEUTSCH, "");
                        InvalidateRect(hwnd,NULL,false);		  			        			    		
    					break;
    				case BU_LOSUNG:
    					MessageBox(0, "Lösung", 0,0); 
    					break;
    				case MENU_OFFNEN:
    					filewnd.ErsteleWindow(hinstance);
    					InitVokStruct(vok_daten, &vok_stats);
    					SetDlgItemText(hwnd, EDIT_LATEIN, vok_daten[i_aktvok].fremdsprache); 
    					InvalidateRect(hwnd,NULL,false);
    					sprintf(buf, "Datei: %s", datei);
         				SetDlgItemText(hwnd, TEXT_DATEI, buf);					
    					break;
    				case MENU_SPEICHERN:
    					MessageBox(0, "Speichern",0,0);
    					break;
    				case MENU_DRUCKEN:
    					MessageBox(0,"Drucken",0,0);
    					break;
            	}
        	case WM_PAINT:
        		hdc = BeginPaint(hwnd, &ps) ;
    			hdcMem = CreateCompatibleDC(hdc) ;
    			SelectObject(hdcMem, kasten1) ;
    			BitBlt(hdc, 100, 250, bitmap1.bmWidth, bitmap1.bmHeight,hdcMem, 0, 0, SRCCOPY);
    			SelectObject(hdcMem, kasten2) ;
    			BitBlt(hdc, 200, 250, bitmap2.bmWidth, bitmap2.bmHeight,hdcMem, 0, 0, SRCCOPY);
    			SelectObject(hdcMem, kasten3) ;
    			BitBlt(hdc, 300, 250, bitmap3.bmWidth, bitmap3.bmHeight,hdcMem, 0, 0, SRCCOPY);
    			SelectObject(hdcMem, kasten4) ;
    			BitBlt(hdc, 400, 250, bitmap4.bmWidth, bitmap4.bmHeight,hdcMem, 0, 0, SRCCOPY);
    			DeleteDC(hdcMem);
    			sprintf(buf,"%i", vok_stats.fach1);
    			TextOut(hdc, 125, 277, buf, strlen(buf));
    			sprintf(buf,"%i", vok_stats.fach2);
    			TextOut(hdc, 225, 277, buf, strlen(buf));
    			sprintf(buf,"%i", vok_stats.fach3);
    			TextOut(hdc, 325, 277, buf, strlen(buf));
    			sprintf(buf,"%i", vok_stats.fach4);
    			TextOut(hdc, 425, 277, buf, strlen(buf));
    			EndPaint(hwnd, &ps);        
    			return 0 ; 
            default:                      /* for messages that we don't deal with */
                return DefWindowProc (hwnd, message, wParam, lParam);
        }
        return 0;
    }
    


  • Tja, dann werden wir dir auch nicht helfen können. 🤡



  • In der WindowProcedure oben trit der Fehler auf! Ich habe ein zweites Programm geschrieben, in dem Funktioniert es. Ist in der WindowProcedure oben auch kein Fehler?



  • Tritt er jetzt in WindowProcedure oder in der ganz oben geposteten Klasse auf 😕



  • flammenvogel schrieb:

    [Linker error] undefined reference to `file_offnen::hwnd'

    in deiner klasse file_offnen fehlt das attribute "hwnd", allerdings sieht man nicht wo du darauf zurückgreifst 😕 .



  • Dann stell dein ganzes Projekt online. Dann haben wir den Fehler ruck zuck gefunden.



  • Nochmal für flenders:

    So wie es aussieht kriege ich in genau dem Programm zu dem auch die WindowProcedure gehört ein Fehler auf, wenn ich die Klasse benutze. Das komische ist das der Linkerfehler auf die Klasse verweißt, sich die Klasse aber in einem anderem Programm ohne Fehler benutzten lässt. Also muss der Fehler folglich in der WindowProcedure oder in einem anderem Teil des Programms bei dem es nicht funktioniert auftreten. Ich habe jetzt erstmal nur die WindowProcedure gepostet, da dort die Klasse aufgerufen wird.



  • Ich poste jetzt nochmal zusätzlich die WinMain und die globalen Deklerationen:

    #include <windows.h>
    #include <eigene/fablib.h>
    #include <time.h>
    #include <deque>
    #include "offnen.h"
    
    using namespace std;
    
    #define EDIT_ZUSATZ 1
    #define EDIT_DEUTSCH 2
    #define EDIT_LATEIN 3
    #define BU_LOSUNG 4
    #define BU_WEITER 5
    #define MENU_OFFNEN 6
    #define MENU_SPEICHERN 7
    #define MENU_DRUCKEN 8
    #define TEXT_DATEI 9
    #define TEXT_RFZEIGER 10
    #define TEXT_DEUTSCH 11
    
    #define BREITE 544
    #define HOHE 375
    
    //Initialiesierungen - Datentypen
    struct VOKABEL_DATEN {
    	int fach;
     	char fremdsprache[255];
      	char heimatsprache[255];
        char bemmerkungen[255];
    };
    
    struct VOKABEL_STATS {
    	int gesamt;
    	int fach1;
    	int fach2;
    	int fach3;
    	int fach4;
    };
    
    //Initialiesierungen - globale Variabeln
    int i_aktvok = 0;
    
    //Initialiesierungen - Funktionen
    BOOL CALLBACK EnumChildProc(HWND hwnd, LPARAM lParam);
    LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);
    bool Uberprufen(char*, char*);
    int FachSetzen(bool ok, VOKABEL_DATEN* vok, VOKABEL_STATS* stats);
    void InitVokStruct(VOKABEL_DATEN* voks, VOKABEL_STATS* stats);
    void NachsteVokabel(VOKABEL_DATEN* voks, VOKABEL_STATS* stats);
    bool OpenVocFile(char* pfad,VOKABEL_DATEN* voks, VOKABEL_STATS* stats);
    
    int WINAPI WinMain (HINSTANCE hThisInstance,
                        HINSTANCE hPrevInstance,
                        LPSTR lpszArgument,
                        int nFunsterStil)
    
    {
    	HMENU hmenu = CreateMenu();	
        HWND hwnd;               /* This is the handle for our window */
        MSG messages;            /* Here messages to the application are saved */
        WNDCLASSEX wincl;        /* Data structure for the windowclass */
        time_t t;
        int xpos, ypos;
    
        fablib::GetCenterCordinats(BREITE, HOHE, &xpos, &ypos);
    
        fablib::DefaultWindowClass(&wincl, hThisInstance);
        wincl.lpfnWndProc = WindowProcedure;      /* This function is called by windows */
    
        AppendMenu(hmenu, MF_STRING,MENU_OFFNEN,"&Öffnen");
        AppendMenu(hmenu, MF_STRING,MENU_SPEICHERN,"&Speichern");
        AppendMenu(hmenu, MF_STRING,MENU_DRUCKEN,"Wörterliste mit falschen Vokabeln &drucken");
    
        srand((unsigned) time(&t));
    
         /* Register the window class, and if it fails quit the program */
        if (!RegisterClassEx (&wincl))
            return 0;
    
        hwnd = CreateWindowEx (
               0,                   /* Extended possibilites for variation */
               "default",         /* Classname */
               "Vokabel Learning",       /* Title Text */
               WS_OVERLAPPEDWINDOW, /* default window */
               xpos,       /* Windows decides the position */
               ypos,       /* where the window ends up on the screen */
               BREITE,                 /* The programs width */
               HOHE,                 /* and height in pixels */
               HWND_DESKTOP,        /* The window is a child-window to desktop */
               hmenu,                /* No menu */
               hThisInstance,       /* Program Instance handler */
               NULL                 /* No Window Creation data */
               );
    
        ShowWindow (hwnd, nFunsterStil);
    
        while (GetMessage (&messages, NULL, 0, 0))
        {
            TranslateMessage(&messages);
            DispatchMessage(&messages);
        }
        return messages.wParam;
    }
    


  • Das nützt doch alles nichts. Der Fehler liegt woanders.



  • lade doch bitte das ganze projekt hoch auf webspace



  • Ich hasse Dev-Cpp, der Fehler liegt nirgendwo Dev-Cpp hatte mal wieder Halzuzinationen. Nach ner Weile warten und ein paar mal auf alles neu erstellen drücken gings.



  • jep, ich kann dir zustimmen!
    ist mir schon mehrmals passiert, dass mein programm während dem starten plötzlich abstürzte.
    nach "Alles erneuern" gings dann plötzlich.. naja.. (hab ja auch ne beta 4.9.9.0)



  • vielleicht ist es auch ein fehler in *deinem* programm, der zufällig auftritt.



  • 1. es gibt keinen zufall (zumindest nicht bei software)

    2. "mein" programm ist "meins": www.path-finder.ch.tt

    3. trotzdem vielen herzlichen dank für dein posting


Anmelden zum Antworten