Erstes Windows Fenster erstellen



  • Nabend

    ich bin neu hier und komme aus einer etwas einfacheren Programmierspache(Autoit)
    Dort habe ich schon ein Paar Grundkenntnisse Lernen können.
    Nur dort erstell ich ein Win Fester(GUI) GUICeate() und schon hab ich das teil.
    Das ist hier wohl etwas aufwendiger ^^.
    Ich habe mir zu einstiegt schon etliche TuTs Durchgelsen und auch n paar sachen schon Probiert. Aber immer in dieser Öden Console sagen auszugeben/eingeben ist mir zu langweillig. Und ich will ja auch direkt ergebnisse sehen.

    Aber nun zu meiner Frage :

    Ich habe hier ein standarcode zum erstellen eines Fensters gefunden und natürlich direkt ein bisschen drin rumgepfuscht um zu kucken was pasier wenn ich das machen usw. Also es wäre nett, wenn mir jemand diesen Code etwas aufschlüsseln könnte 😋 außerdem hab ich mir dran versucht nen button auf die GUI zu packen leider ohne erfolg.

    Aber hier mal die Source

    Ich finde leider keinen Spoiler, deshalb post ich das ganze einfach so:

    #include <windows.h>
    
    /*  Declare Windows procedure  */
    LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);
    
    /*  Make the class name into a global variable  */
    char szClassName[ ] = "WindowsApp";
    
    int WINAPI WinMain (HINSTANCE hThisInstance,
                        HINSTANCE hPrevInstance,
                        LPSTR lpszArgument,
                        int nFunsterStil)
    
    {
        HWND hwnd;               /* This is the handle for our window */
        HWND Buttonhwnd;         /* This is the handle for the button */
        MSG messages;            /* Here messages to the application are saved */
        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 0;
    
        /* The class is registered, let's create the program*/
        hwnd = CreateWindowEx (
               0,                   /* Extended possibilites for variation */
               szClassName,         /* Classname */
               "Mein fenster",       /* 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 */
               );     
    
        /* Make the window visible on the screen */
        ShowWindow (hwnd, nFunsterStil);
    
        /* Run the message loop. It will run until GetMessage() returns 0 */
        while (GetMessage (&messages, NULL, 0, 0))
        {
            /* Translate virtual-key messages into character messages */
            TranslateMessage(&messages);
            /* Send message to WindowProcedure */
            DispatchMessage(&messages);
        }
    
        /* The program return-value is 0 - The value that PostQuitMessage() gave */
        return messages.wParam;
    }
    
    /*  This function is called by the Windows function DispatchMessage()  */
    
    LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
        switch (message)                  /* handle the messages */
        {
            case WM_DESTROY:
                PostQuitMessage (0);       /* send a WM_QUIT to the message queue */
                break;
            default:                      /* for messages that we don't deal with */
                return DefWindowProc (hwnd, message, wParam, lParam);
        }
    
        return 0;
    }
    


  • Falscher Bereich, gehört zu WinAPI.

    Wenn dich das Thema interessiert kauf dir am besten das Buch von Petzold.
    Dort lernst du alles drin was wichtig ist, das Buch ist Top 👍 .

    http://www.amazon.de/Windows-Programmierung-Das-Entwicklerhandbuch-zur-WIN32-API/dp/3860631888



  • ok danke für die Antwort ich habe mir das Buch mal angeschaut, auhch die Komentare gelesen un die meinungen giben wohl in die Richtig, dass dasn ganze schon recht veraltet sei. kannst du das besätigen oder ist es deinermeining immer noch wert zu kaufen?



  • Es ist definitiv schon älter, aber viel hat sich an der eigentlichen API (zumindest aus meiner sicht) nicht getan. Es enthält immer noch Solides grundlagen wissen. Und wenn man vorher schon bisschen C++ kann weiß man auch was man ändern kann, um manche Sachen zu überarbeiten.



  • @Darter

    Der von dir angegebene Quelltext ist pure Win-API. Du solltest dich fragen ob du den Einstieg in die GUI-Programmierung wirklich so angehen willst. Das ist nämlich ein recht mühsamer Weg. Es gibt einfachere und produktivere Möglichkeiten.

    Wenn du allerdings wirklich deine GUIs direkt mit der API erstellen willst, ist der Petzold schon hervorragend geeignet. Das Alter des Buches stört dabei nich weiter. Ich würde sogar sagen das Buch ist alternativlos. Es ist aber ein dicker Schinken der sich nicht an jeder Stelle wirklich kurzweilig liest.

    Nebenbei: Die Windows-API ist C und kein C++.



  • naja indem fall würde mich mal interessieren, was es für alternativen gibt. Auf der Suche danach bin ich eben nur auf die WinApi gestoßen



  • Kannst dich mal unter WinForms schlau machen. Damit erstellst du Fenster per Mausklick, und mindestens ebenso einfach lassen sich Buttons einfügen 🙂



  • ok das durfte wohl sowas ähnliches sein wie bei Autoit der Koda Form designer damit kann man auch ganz einfach Forms erstellen und er spuckt den Code aus. Damit gehts natürlich recht einfach un schnell aber der Lernfaktor dürfte wohl erher nicht sehr groß sein. Und wie ich den Post vor dir Verstehe meinete er es gäbe andere Möglichkeiten Sorms zu erstellen ohne direkt die API zu nutzen.



  • Wenn du die WinAPI eingehender ansehen möchtest, schau dir folgende Seiten an:
    http://www.winprog.org/tutorial/

    Hab es nicht geprüft, aber da steht das der Quelltext an die aktuelleren Compiler angepasst sein soll. Man kommt zwar meist auch mit älteren Quellcodes und kleinen Anpassungen klar, aber als Neuling kann wegen der Kleinigkeiten schon mal die eine oder andere Minute für das Suchen drauf gehen.



  • Dieser Thread wurde von Moderator/in pumuckl aus dem Forum C++ in das Forum WinAPI verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.



  • ach ich bin jetzt schon am verzweifen. ich habs gesetern noch probiert und heute schin 6 stunden lang aber ich bekomm es nicht mal hin ne einfachen push button auf das Fester zu packen. ICh versteht das gazne auch nicht, es gibt immer wieder gegensätze. In den einem TuT wird erzählt ctrl seien nur Parent Fenster. In dem anderen wird wieder etwas ganz anderes erzählt.

    Ich hier gekuckt : http://msdn.microsoft.com/de-de/library/bb775949.aspx klingt anfürsich ganz logisch nur ich versteh diese Zeile nicht.

    L"BUTTON",   // Predefined class; Unicode assumed.
    

    und hier mal das ganze wie ich es Probiert hab:

    #include <windows.h>
    #include <stdio.h> 
    
    LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM); 
    //Deklaration der Windows-Nachrichten-Prozedur
    
    int WINAPI WinMain (HINSTANCE hI, HINSTANCE hPrI, PSTR szCmdLine, int iCmdShow)
    {
    char szName[] = "Fensterklasse"; // Fensterklassenname
    
    HBRUSH MyBrush = CreateSolidBrush( RGB( 0, 150, 255 ) ); //Ein brush für meine BG Farbe
    
    WNDCLASS wc; //Hier wird die Fensterklasse erstellt
    
    wc.style         = 0 ;                   // CS = "class style". Vergleichbar mit Register MSG denk ich mal ^^ CS_HREDRAW | CS_VREDRAW
    wc.lpfnWndProc   = WndProc;                                   
    wc.cbClsExtra    = 0;                                         
    wc.cbWndExtra    = 0;                                         
    wc.hInstance     = hI;                                        
    wc.hIcon         = LoadIcon (NULL, IDI_WINLOGO);              //Festlegen des Icons 
    wc.hCursor       = LoadCursor (NULL, IDC_ARROW);              //Festlegen des Fenster Mauzeiger
    wc.hbrBackground = MyBrush;                                   //Hintergrund Festlegen ; Standardbrush  (HBRUSH) GetStockObject (GRAY_BRUSH)
    wc.lpszMenuName  = NULL;
    wc.lpszClassName = szName;
    
    RegisterClass (&wc); //Hier wird die Fensterklasse Registriert
    
    /*
    char szName2[] = "Buttonklasse"; // Fensterklassenname
    
    HBRUSH MyBrush2 = CreateSolidBrush( RGB( 110, 150, 255 ) ); //Ein brush für meine BG Farbe
    
    WNDCLASS bc; //Hier wird die Fensterklasse erstellt
    
    wc.style         = 0 ;                   // CS = "class style". Vergleichbar mit Register MSG denk ich mal ^^ CS_HREDRAW | CS_VREDRAW
    wc.lpfnWndProc   = WndProc;                                   
    wc.cbClsExtra    = 0;                                         
    wc.cbWndExtra    = 0;                                         
    wc.hInstance     = hI;                                        
    wc.hIcon         = 0;              //Festlegen des Icons 
    wc.hCursor       = LoadCursor (NULL, IDC_ARROW);              //Festlegen des Fenster Mauzeiger
    wc.hbrBackground = MyBrush2;                                   //Hintergrund Festlegen ; Standardbrush  (HBRUSH) GetStockObject (GRAY_BRUSH)
    wc.lpszMenuName  = NULL;
    wc.lpszClassName = szName2;
    
    RegisterClass (&bc); //Hier wird die Fensterklasse Registriert
    */
    
    HWND hwnd = CreateWindow
    (
         szName,                                               //Fensterklasse übergeben
         "Fenstername",                                        //Fenstername
         WS_OVERLAPPEDWINDOW,                                  //Styls
         400,                                                  //Xpos
         400,                                                  //Ypos
         600,                                                  //Width      
         300,                                                  //Height
         NULL,
         NULL,
         hI,
         NULL
    );
    
    HWND hwndButton = CreateWindow( 
        szName,   // Predefined class; Unicode assumed. 
        "OK",       // Button text. 
        WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON,  // Styles. 
        10,         // x position. 
        10,         // y position. 
        100,        // Button width.
        100,        // Button height.
        hwnd,       // Parent window.
        NULL,       // No menu.
        (HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE), 
        NULL);      // Pointer not needed.
    
    ShowWindow   (hwndButton, iCmdShow);
    ShowWindow   (hwnd, iCmdShow);
    UpdateWindow (hwnd);
    
    /*
    HDC hdc;//gerätekontext Variable Deklarieren
    hdc = GetDC(hwnd); //Wert zuweisen
    PAINTSTRUCT ps; //paint Struktur Variable Deklarieren
    hdc = BeginPaint (hwnd, &ps);
        //SetTextColor( hdc, RGB( 255,   0,  0) );  // rot
        //SetBkColor  ( hdc, RGB( 255, 255,  0) );  // gelb
        SetBkMode              //Hintergrund FarbenMod setzten hier als Bsp. Tranzparent
        (
            hdc,              // hadle zum gerätekontext
            TRANSPARENT       // flag spezieleer Modus
        );        
    
        TextOut (hdc, 50, 100, "Ich bin ein Fenster.", 20); //Label Zeichnen           
    EndPaint (hwnd, &ps);
    */
    
    // Nachrichten-Schleife. Ist denke ich Vergleichbar mit unsere Hauptschleife.
    MSG msg;
        while (GetMessage (&msg, NULL, 0, 0))
        {
            TranslateMessage (&msg);
            DispatchMessage (&msg);//gibt die nachrichten an WndProc weiter   
        }
    return msg.wParam;
    }
    
    // Windows-Nachrichten-Prozedur
    LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
    HDC hdc;
    hdc = GetDC(hwnd);
    char str[50];   
    
    switch (message)
    {
    case WM_PAINT:  
         return 0;
    
    case WM_DESTROY:
        PostQuitMessage (0);
        return 0;
    
    case WM_LBUTTONDOWN:
        sprintf(str,"Fensterhandle: %i ;MSG: %i ;wParam: %i ;xPos: %i ;yPos: %i",hwnd,message,wParam,LOWORD(lParam),HIWORD(lParam));
        TextOut (hdc, 50, 100, str, strlen(str));//strlen(str)
        ReleaseDC(hwnd,hdc);
        return 0;    
    
    case WM_RBUTTONDOWN:
        sprintf(str,"Fensterhandle: %i ;MSG: %i ;wParam: %i ;xPos: %i ;yPos: %i",hwnd,message,wParam,LOWORD(lParam),HIWORD(lParam));
        TextOut (hdc, 50, 100, str, strlen(str));//strlen(str)
        ReleaseDC(hwnd,hdc);
        return 0; 
    
    }
    
    return DefWindowProc (hwnd, message, wParam, lParam);
    }
    

    Was genau mach ich denn da Falsch oder bin ich die Sache kommplet falsch angegangen?

    mfg



  • Hm, ich hab mir das mal angesehen und das sieht mir ein bisschen chaotisch aus.
    Da es mir jetzt zu lange dauert, das alles zu überblicken, poste ich mal einen Code. Das Programm macht nichts anderes, als ein Fenster mit Button zu erstellen.

    #include <windows.h>
    
        LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
    
        int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
        {
        HWND hwnd;
        MSG msg;
    
        WNDCLASS wc;
    
        wc.style         = CS_HREDRAW | CS_VREDRAW;
        wc.lpfnWndProc   = WndProc;
        wc.cbClsExtra    = 0;
        wc.cbWndExtra    = 0;
        wc.hInstance     = hInstance ;
        wc.hIcon         = LoadIcon(NULL, IDI_APPLICATION);
        wc.hCursor       = LoadCursor (NULL, IDC_ARROW);
        wc.hbrBackground = (HBRUSH) 16;
        wc.lpszMenuName  = NULL ;
        wc.lpszClassName = "Classname" ;
    
        RegisterClass(&wc);
    
        int Width  = GetSystemMetrics(SM_CXSCREEN);
        int Height = GetSystemMetrics(SM_CYSCREEN);
        int xpos = (Width  / 2)-225;
        int ypos = (Height / 2)-150;
    
        hwnd = CreateWindow(
    				 "Classname",
                   	 "Fenstertitel",
                   	 WS_SYSMENU|WS_MINIMIZEBOX,
                   	 xpos,
                   	 ypos,
                   	 450,
                   	 300,
                   	 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 Button;
    
        switch (message)
        {
    
    	case WM_CREATE:
    	{
    	    Button = CreateWindow("button",
                                  "Hier klicken",
                                  WS_CHILD | WS_VISIBLE,
                                  225-60,220,120,30,
                                  hWnd,
                                  NULL,
                                  ((LPCREATESTRUCT) lParam) -> hInstance,
                                  (HMENU)1);
    	return 0;
    	}
    
    	case WM_COMMAND:
    	{
             if (lParam == (LPARAM)Button)
                  if (HIWORD(wParam) == BN_CLICKED)
                  {
    		      MessageBoxA(hWnd,"Button geklickt","Info",MB_ICONINFORMATION);
                  return 0;
                  }
        return 0;
        }
    
    	    case WM_DESTROY:
            {
    	        DestroyWindow(hWnd);
    	        PostQuitMessage(0);
                return 0;
            }
        }
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    

    Eventuell hilft dir ja der Quelltext.

    MfG, Jochen



  • Zu dieser Zeile:

    L"BUTTON",   // Predefined class; Unicode assumed.
    

    Das L vor dem String macht diesen zu einem UNICODE-String. In einem UNICODE-String belegt jedes Zeichen 2 Bytes an Speicher. In einem ASCII-String jedoch nur 1 Byte. Wenn das Projekt mit aktiviertem UNICODE-Flag kompiliert wird, Erwarten Funktionen wie CreateWindow Unicode-Strings anstelle von ASCII-Strings. Du kannst dir ja mal die Deklaration der Funktion CreateWindow in der winuser.h ansehen. vielleicht schafft das ja Klarheit.

    MfG, Jochen



  • Mal den Quelltext von Darter mit der Brechstange bearbeitet:

    // Windows-Nachrichten-Prozedur
    LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
        static HWND Button;
        HDC hdc;
        hdc = GetDC(hwnd);
        char str[50] = "test";
    
        switch (message)
        {
        case WM_CREATE:
        {
            Button = CreateWindow("button",
                                  "Hier klicken",
                                  WS_CHILD | WS_VISIBLE,
                                  225-60,220,120,30,
                                  hwnd,
                                  NULL,
                                  ((LPCREATESTRUCT) lParam) -> hInstance,
                                  (HMENU)1);
            return 0;
        }
    
        case WM_PAINT:
            return 0;
    
        case WM_COMMAND:
        {
            if (lParam == (LPARAM)Button)
                if (HIWORD(wParam) == BN_CLICKED)
                {
                    SendMessage(Button, WM_CLOSE, 0, 0);
    
                }
            return 0;
        }
    
        case WM_DESTROY:
            DestroyWindow(Button);
            PostQuitMessage (0);
            return 0;
    
        case WM_LBUTTONDOWN:
    //    sprintf(str,"Fensterhandle: %i ;MSG: %i ;wParam: %i ;xPos: %i ;yPos: %i",hwnd,message,wParam,LOWORD(lParam),HIWORD(lParam));
            TextOut (hdc, 50, 100, str, strlen(str));//strlen(str)
            ReleaseDC(hwnd,hdc);
            return 0;
    
        case WM_RBUTTONDOWN:
    //    sprintf(str,"Fensterhandle: %i ;MSG: %i ;wParam: %i ;xPos: %i ;yPos: %i",hwnd,message,wParam,LOWORD(lParam),HIWORD(lParam));
            TextOut (hdc, 50, 100, str, strlen(str));//strlen(str)
            ReleaseDC(hwnd,hdc);
            return 0;
    
        }
    
        return DefWindowProc (hwnd, message, wParam, lParam);
    }
    

    Teste mal beide Maustasten.
    Der Rest des Quelltextes wie bei dir - überarbeiten kann bestimmt nicht schaden 😃



  • ok danke für die ANtworten, dann lag ich ja gar nicht so weit weg wie ich dachte. Also sind Button nicht anderes als auch Fenster, die mein Hauptfenster als parent haben.

    Ok soweit denke ich ist es ganz verschtändlich und ich gab natürlich gleich etwas mit den styles usw. rumgespielt nur mit den Styels bekomme ich so einen schönen Button den der nen hover effekt hat.

    Muss ich das also selber machen?

    hab das hier gefunden: http://msdn.microsoft.com/de-de/library/92fhtw0f%28VS.80%29.aspx

    bin ich da auf der Richtigen spur?

    Außerdem hab ich noch ein Buch gefunden, kann das einer empfehlen?
    http://www.amazon.de/Windows-Programmierung-Das-Entwicklerhandbuch-zur-WIN32-API/dp/3860631888



  • sorry für den doppelpost aber ich hab mir die seiten angeschaut:

    http://msdn.microsoft.com/de-de/library/bb775951.aspx
    http://msdn.microsoft.com/de-de/library/bb775943.aspx
    http://msdn.microsoft.com/de-de/library/bb775984.aspx

    bin ich da richtig um einen button mit dem hover effekt zu erstellen?


Log in to reply