Hello everyone,
I am working my way through the Forger's Win32 tutorial and am on the "Creating a Simple Application" part currently. I am using C++ (instead of C in the tutorial) and the WinGW compiler. When I compile the below code I get this error:

main.cpp: In function 'LRESULT WndProc(HWND, UINT, WPARAM, LPARAM)':
main.cpp:26:47: error: invalid conversion from 'HGDIOBJ {aka void*}' to 'HFONT'
[-fpermissive]

If I change the line to a cast:

hfDefault = (HFONT)GetStockObject(DEFAULT_GUI_FONT);

The error changes to:

undefined reference to 'GetStockObject@4'
collect2: ld returned 1 exit status

I have searched around on Google and haven't found a solution yet. Most of the answers have to do with changing a type from 'Console Application' to 'GUI Application' in an IDE. But I just use Notepad++ (just a text editor) and CMD. Here is the code, and thanks very much for your time:

#include <windows.h>
#include <wingdi.h>
#define IDC_MAIN_EDIT 101

const char g_szClassName[] = "myWindowClass";

// Step 4: the Window Procedure
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch(msg)
    {
        case WM_CREATE:
        {
            HFONT hfDefault;
            HWND hEdit;

            hEdit = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", "",
                WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_HSCROLL | ES_MULTILINE |
                ES_AUTOVSCROLL | ES_AUTOHSCROLL, 0, 0, 100, 100, hwnd, (HMENU)IDC_MAIN_EDIT, 
                GetModuleHandle(NULL), NULL);
            if(hEdit == NULL)
            {
                MessageBox(hwnd, "Could not create edit box.", "Error", MB_OK | MB_ICONERROR);
            }

            hfDefault = GetStockObject(DEFAULT_GUI_FONT);
            SendMessage(hEdit, WM_SETFONT, (WPARAM)hfDefault, MAKELPARAM(FALSE, 0));
        }
        break;
        case WM_SIZE:
        {
            HWND hEdit;
            RECT rcClient;

            GetClientRect(hwnd, &rcClient);

            hEdit = GetDlgItem(hwnd, IDC_MAIN_EDIT);
            SetWindowPos(hEdit, NULL, 0, 0, rcClient.right, rcClient.bottom, SWP_NOZORDER);
        }
        break;
        case WM_CLOSE:
            DestroyWindow(hwnd);
        break;
        case WM_DESTROY:
            PostQuitMessage(0);
        break;
        default:
            return DefWindowProc(hwnd, msg, wParam, lParam);
    }
    return 0;
}


int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    WNDCLASSEX wc;
    HWND hwnd;
    MSG Msg;

    //Step 1: Registering the Window Class
    wc.cbSize = sizeof(WNDCLASSEX);
    wc.style = 0;
    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)(COLOR_WINDOW+1);
    wc.lpszMenuName = NULL;
    wc.lpszClassName = g_szClassName;
    wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
    if(!RegisterClassEx(&wc))
    {
        MessageBox(NULL, "Window Registration Failed!", "Error!", 
        MB_ICONEXCLAMATION | MB_OK);
        return 0;
    }

    // Step 2: Creating the Window
    hwnd = CreateWindowEx(
    WS_EX_CLIENTEDGE,
    g_szClassName,
    "The title of my window",
    WS_OVERLAPPEDWINDOW,
    CW_USEDEFAULT, CW_USEDEFAULT, 240, 120,
    NULL, NULL, hInstance, NULL);
    if(hwnd == NULL)
    {
        MessageBox(NULL, "Window Creation Failed!", "Error!",
        MB_ICONEXCLAMATION | MB_OK);
        return 0;
    }
    ShowWindow(hwnd, nCmdShow);
    UpdateWindow(hwnd);

    // Step 3: The Message Loop
    while(GetMessage(&Msg, NULL, 0, 0) > 0)
    {
        TranslateMessage(&Msg);
        DispatchMessage(&Msg);
    }
    return Msg.wParam;
}

Link to gdi32.a

Whenever you get an undefined reference error, it means you don't have the right libraries linked and the linker cannot find your function.

In your case:

Library Gdi32.lib
DLL     Gdi32.dll 

Most of the time, if you do not know the library, search for the function on MSDN: http://msdn.microsoft.com/en-us/library/windows/desktop/dd144925%28v=vs.85%29.aspx

Scroll down to the bottom grey-blue part. It shows the info above. Usually you want to link to the library and not go through the hassle of loading the DLL and getting the proc address..

So again, Link to gdi32.a/libgdi32.a (Both are the same thing).

Edited 4 Years Ago by triumphost

Does #include <wingdi.h> not include those libraries?

No, only the function declarations are generally in the header file. The declarations are enough for the compiler to compile the code that is calling the function. However, when the linker (that's what the ld part of the error is referring to) tries to link the object files together, it needs to look for a definition of the function that is declared in the header. If it can't find a definition, then you get an error like the one you see. This link might help you to work out how to tell the linker which libraries you want to link to and how to specify where they are on you machine.

This article has been dead for over six months. Start a new discussion instead.