Fehler beim kompilieren (C, WinAPI, GCC)



  • Hallo,

    ich möchte ein kleines Programm in C schreiben. Es soll ein Fenster geben mit ein paar Buttons, die beim Betätigen eine Grafik im Fenster auswechseln.
    Ich wollte anfangen mit Fenster und Buttons.
    Ich bin neu in WinAPI und wollte mir ein kleines Beispiel, das ich im Netz gefunden habe, anschauen.
    Hier der Code:

    #include <windows.h>
    #include <commctrl.h>
    #include <string>
    #include <iostream>
    
    #include "main.h"
    #include "resource.h"
    
    /* Declare WindowsProcedure */
    LRESULT CALLBACK WindowProcedure(HWND, UINT, WPARAM, LPARAM);
    /* Make the classname into a global variable */
    char szClassName[] = "Windows Example";
    char szMessageName[] = "Info";
    
    char *string = new char[30];
    
    HINSTANCE hInstance;
    
    const UINT IDTimer1 = 1;
    UINT nTimerDelay = 2000;
    bool timerFlag = true;
    
    #define IDC_RADIOBUTTON1 10
    
    BOOL GetFileName(HWND hwnd, LPSTR pszFileName, BOOL bSave)
    {
    OPENFILENAME ofn;
    
    ZeroMemory(&ofn, sizeof(ofn));
    pszFileName[0] = 0;
    
    ofn.lStructSize = sizeof(ofn);
    ofn.hwndOwner = hwnd;
    ofn.lpstrFilter = "Text Files (*.txt)*.txtAll Files (*.*)*.*";
    ofn.lpstrFile = pszFileName;
    ofn.nMaxFile = MAX_PATH;
    ofn.lpstrDefExt = "txt";
    
    if(bSave)
    {
    ofn.Flags = OFN_EXPLORER | OFN_PATHMUSTEXIST | OFN_HIDEREADONLY |
    OFN_OVERWRITEPROMPT;
    if(!GetSaveFileName(&ofn))
    return FALSE;
    }
    else
    {
    ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;
    if(!GetOpenFileName(&ofn))
    return FALSE;
    }
    return TRUE;
    }
    
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszArgument, int nFensterStil)
    
    {
    HWND hwnd; /* This is the handle for our window */
    MSG messages; /* Here messages to the application is saved */
    WNDCLASSEX wincl; /* Datastructure for the windowclass */
    HMENU menu; /* Handle of the menu */
    
    /* The Window structure */
    wincl.hInstance = hInstance;
    wincl.lpszClassName = szClassName;
    wincl.lpfnWndProc = WindowProcedure; /* This function is called by windows */
    wincl.style = CS_DBLCLKS; /* Ctach double-clicks */
    wincl.cbSize = sizeof(WNDCLASSEX);
    
    /* Use default icon and mousepointer */
    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 */
    // Hintergrundfarbe des Main-Fensters
    wincl.hbrBackground = (HBRUSH) GetStockObject(10);
    
    /* Register the window class, if fail quit the program */
    if(!RegisterClassEx(&wincl)) return 0;
    
    /* The class is registered, lets create the program*/
    hwnd = CreateWindowEx(
    0, /* Extended possibilites for variation */
    szClassName, /* Classname */
    "Windows Example", /* Title Text */
    WS_OVERLAPPEDWINDOW, /* defaultwindow */
    CW_USEDEFAULT, /* Windows decides the position */
    CW_USEDEFAULT, /* where the window end up on the screen */
    600, /* The programs width */
    400, /* and height in pixels */
    HWND_DESKTOP, /* The window is a childwindow to desktop */
    NULL, /* No menu */
    hInstance, /* Program Instance handler */
    NULL /* No Window Creation data */
    );
    
    /* Make the window visible on the screen */
    ShowWindow(hwnd, nFensterStil);
    UpdateWindow(hwnd);
    menu = LoadMenu(hInstance, MAKEINTRESOURCE(ID_MENU));
    SetMenu(hwnd, menu);
    
    /* Run the nessageloop. It will run until GetMessage( ) returns 0 */
    while(GetMessage(&messages, NULL, 0, 0))
    {
    /* Send message to WindowProcedure */
    DispatchMessage(&messages);
    }
    return messages.wParam;
    }
    
    /* This function is called by the Windowsfunction DispatchMessage( ) */
    LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
    int i=0;
    // Höhe und Breite des Buttons
    static int bx=100, by=30; 
    static HWND hwndButtonStart = 0;
    static HWND hwndButtonEnde = 0;
    static HWND RadioButton1 = 0;
    static HWND RadioButton2 = 0;
    static HWND Test = 0;
    static HWND Test1 = 0;
    
    HDC hdc;/* A device context used for drawing */
    PAINTSTRUCT ps;/* Also used during window drawing */
    RECT rc;/* A rectangle used during drawing */
    
    switch (message) /* handle the messages */
    {
    case WM_COMMAND:
    
    //Button Kommandos
    if ((HWND) lParam == hwndButtonStart)
    {
    //Ausführen Button Start
    
    MessageBox( hwnd, (LPSTR) "Keine Funktion Implementiert!",
    (LPSTR) szMessageName,
    MB_ICONINFORMATION | MB_OK );
    
    return 0;
    }
    if((HWND) lParam == hwndButtonEnde)
    {
    //Ausführen Button Ende
    DestroyWindow (hwnd);
    }
    if((HWND) lParam == RadioButton1) {
    
    return 0;
    } 
    //Ende Button Kommandos
    switch( wParam )
    {
    case IDM_FILENEW:
    
    case IDM_FILEOPEN:
    char szFileName[MAX_PATH];
    GetFileName( hwnd, szFileName, FALSE);
    break;
    
    case IDM_EDITUNDO:
    case IDM_EDITCUT:
    case IDM_EDITCOPY:
    case IDM_EDITPASTE:
    case IDM_EDITDELETE:
    MessageBox( hwnd, (LPSTR) "Keine Funktion Implementiert!",
    (LPSTR) szClassName,
    MB_ICONINFORMATION | MB_OK );
    break;
    
    case IDM_HELPCONTENTS:
    WinHelp( hwnd, (LPSTR) "HELPFILE.HLP",
    HELP_CONTENTS, 0L );
    return 0;
    
    case IDM_HELPSEARCH:
    WinHelp( hwnd, (LPSTR) "HELPFILE.HLP",
    HELP_PARTIALKEY, 0L );
    return 0;
    
    case IDM_HELPHELP:
    WinHelp( hwnd, (LPSTR) "HELPFILE.HLP",
    HELP_HELPONHELP, 0L );
    return 0;
    
    case IDM_FILEEXIT:
    SendMessage( hwnd, WM_CLOSE, 0, 0L );
    return 0;
    
    case IDM_HELPABOUT:
    MessageBox (NULL, "About..." , "Windows example version 0.01", 1);
    return 0;
    
    } //Ende WM_Command
    break;
    
    case WM_CLOSE:
    DestroyWindow( hwnd );
    return 0;
    
    case WM_DESTROY:
    PostQuitMessage (0);
    return 0;
    
    case WM_CREATE:
    //Timer initialisieren
    SetTimer(hwnd, IDTimer1,nTimerDelay, NULL);
    // Buttons werden erstellt
    hwndButtonStart = CreateWindow ("button","Start",WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON,100, 250, bx, by,
    hwnd,(HMENU) 1,((LPCREATESTRUCT) lParam)->hInstance,NULL);
    
    hwndButtonEnde = CreateWindow ("button","Ende",WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON,400, 250, bx, by,
    hwnd,(HMENU) 2,((LPCREATESTRUCT) lParam)->hInstance,NULL);
    
    /*
    RadioButton1 = CreateWindow ("button","Radio1",WS_CHILD | WS_VISIBLE | BS_RADIOBUTTON,100, 130, 70, 20,
    hwnd,(HMENU) IDC_RADIOBUTTON1,((LPCREATESTRUCT) lParam)->hInstance,NULL);
    
    RadioButton2 = CreateWindow ("button","Radio2",WS_CHILD | WS_VISIBLE | BS_RADIOBUTTON,200, 130, 70, 18,
    hwnd,(HMENU) 4,((LPCREATESTRUCT) lParam)->hInstance,NULL);
    */
    
    Test = CreateWindow ("button","",WS_CHILD | WS_VISIBLE | BS_GROUPBOX,50, 50, 500, 250,
    hwnd,(HMENU) 5,((LPCREATESTRUCT) lParam)->hInstance,NULL);
    
    Test1 = CreateWindow ("edit","Feld", WS_CHILD | WS_VISIBLE | BS_TEXT,100, 130, 70, 20,
    hwnd,(HMENU) 5,((LPCREATESTRUCT) lParam)->hInstance,NULL);
    
    break;
    
    case WM_PAINT:
    hdc = BeginPaint (hwnd, &ps);
    GetClientRect (hwnd, &rc);
    rc.bottom = 50;
    DrawText(hdc, "Die neue Version von WorkClock!", -1,&rc,
    DT_SINGLELINE | DT_CENTER | DT_VCENTER);
    
    EndPaint (hwnd, &ps);
    break;
    
    return 0; //Ende WM_Paint
    
    case WM_TIMER:
    if(timerFlag==true){
    i++;
    
    timerFlag = false;
    int id = MessageBox( hwnd, (LPSTR) "Timer!",
    (LPSTR) szClassName,
    MB_ICONINFORMATION | MB_OKCANCEL);
    
    // Button Cancel liefert 2 zurück
    // Button OK liefert 1 zurück 
    if(id == 1) {
    timerFlag = true;
    }
    
    SendMessage( hwnd, WM_PAINT, 0, 0L );
    } 
    
    break;
    //Für nicht beachtete Nachrichten
    default:
    return DefWindowProc(hwnd, message, wParam, lParam);
    }
    return 0;
    }
    

    Ich weiß nicht was der Code genau macht, aber in der Beschreibung stand, dass das ein Fenster mit zwei Butons ist.

    Das Problem ist: wenn ich mit "gcc win.c" kompiliere kommt die Fehlermeldung:
    "C:/DOKUME1/rolly/LOKALE1/Temp/ccuCbaa.o(.text+0x81):win.c: undefined reference to `GetStockObject@4'"

    Was könnte das sein? Fehler im Code? Falsch kompiliert?
    Ich habe nur eine "win.c", brauche ich auch eine "resource.h" und eine "main.h"?
    Benutze MinGW auf WinXP.

    Dank und Grüße,
    rolly



  • Du musst die GDI32.lib mitlinken...



  • Danke, und wie mache ich das (in GCC)?

    Grüße,
    *totalerNewbee*



  • Oh mann, sorry, hab oben falschen code gepostet.
    Hier der richtige:

    #include <windows.h>
    
    LRESULT CALLBACK WndProc(HWND hwnd, UINT uMsg, WPARAM wParam,
    LPARAM lParam);
    
    HDC dc;
    HWND button1, button2;
    
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
    LPSTR lpszCmdLine, int nCmdShow)
    
    {
    WNDCLASS wc;
    HWND hWnd;
    MSG msg;
    wc.style = CS_HREDRAW|CS_VREDRAW|CS_BYTEALIGNCLIENT;
    wc.lpfnWndProc = WndProc;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;
    wc.hInstance = hInstance;
    wc.hIcon = NULL;
    wc.hCursor = LoadCursor(NULL,IDC_ARROW);
    wc.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
    wc.lpszMenuName = NULL;
    wc.lpszClassName = "ButtonExample";
    RegisterClass(&wc);
    
    hWnd = CreateWindow(wc.lpszClassName,"Using A Button",
    WS_OVERLAPPEDWINDOW,100,100,300,200,
    NULL,NULL,hInstance,NULL);
    
    button1 = CreateWindow("BUTTON","Hit Me",WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON,
    10,10,120,40,hWnd,NULL,hInstance,NULL);
    button2 = CreateWindow("BUTTON","Hit Me, too",WS_CHILD |WS_VISIBLE| BS_PUSHBUTTON,
    90,50,120,40,hWnd,NULL,hInstance,NULL);
    
    ShowWindow(hWnd,nCmdShow);
    UpdateWindow(hWnd);
    while (GetMessage(&msg,NULL,0,0))
    {
    TranslateMessage(&msg);
    DispatchMessage(&msg);
    }
    return msg.wParam;
    }
    
    LRESULT CALLBACK WndProc(HWND hwnd, UINT uMsg, WPARAM wParam,
    LPARAM lParam)
    {
    switch(uMsg)
    {
    case WM_COMMAND:
    {
    if ((HWND)lParam==button1)
    MessageBox(hwnd,"Clicked!","Ooohhh",MB_OK);
    return 0;
    }
    
    case WM_DESTROY:
    {
    PostQuitMessage(0);
    break;
    }
    default:
    {
    return DefWindowProc(hwnd,uMsg,wParam,lParam);
    }
    }
    return 0;
    }
    

    Grüße,
    rolly



  • rolly schrieb:

    Danke, und wie mache ich das (in GCC)?

    an die kommandozeile ein

    -lgdi32
    

    mit dranhängen


Anmelden zum Antworten