Sign in to follow this  
Drakkcon

Help with getting a window to display

Recommended Posts

Drakkcon    612
I was going through the forger's win32 API tutorial, and I thought "hey, I'll be clever and put all this stuff into special functions", well it doesn't work and I think knowing why would help with my C skills. Main.cpp
#define WIN32_LEAN_AND_MEAN //Cuts the crap
//Includes//////////////////////////////////////////////////////////////////////
#include "Functions.h"
//WinMain///////////////////////////////////////////////////////////////////////
int WINAPI WinMain(HINSTANCE hInstance,
                   HINSTANCE hPrevInstance,
                   LPSTR lpCmdLine,
                   int nCmdShow)
{
    MSG Msg;
    
    CreateMyWindClass();
    CreateMyWindow();
    
    while(GetMessage(&Msg, NULL, 0, 0) > 0)
    {
        TranslateMessage(&Msg);
        DispatchMessage(&Msg);
    }
    return Msg.wParam;
}


Functions.cpp
//FunctionDefinitions///////////////////////////////////////////////////////////
//Main Window Procedure/////////////////////////////////////////////////////////
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch(msg)
    {
        case WM_CLOSE:
        {
            DestroyWindow(hwnd);
            break;
        }
        
        case WM_DESTROY:
        {
            PostQuitMessage(0);
            break;
        }
        
        default:
            return DefWindowProc(hwnd, msg, wParam, lParam);
    }
    return 0;
}

//CreateWindClass///////////////////////////////////////////////////////////////
int CreateMyWindClass()
{
    //wc is static, so there's no need for a return value, just use wc
    static WNDCLASSEX wc;
    extern HINSTANCE hInstance;
    extern char g_szClassName[];

    //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;
    }
    return 1;
}

int CreateMyWindow()
{
    extern HINSTANCE hInstance;
    extern int nCmdShow;
    extern char g_szClassName[];

    static HWND hwnd;
    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 1;
    }

    ShowWindow(hwnd, nCmdShow);
    UpdateWindow(hwnd);
}



and Functions.h
#ifndef FUNCTIONS_H
#define FUNCTIONS_H
////////////////////////////////////////////////////////////////////////////////
#include <windows.h>
#include "Functions.cpp"
//Consts////////////////////////////////////////////////////////////////////////
const char g_szClassName[] = "myWindowClass";
//FunctionDeclarations//////////////////////////////////////////////////////////
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
int CreateMyWindClass();
int CreateMyWindow();

#endif


the linker says:
Functions.o(.text+0x0):Functions.cpp: multiple definition of `_Z7WndProcP6HWND__jjl@16'
main.o(.text+0x0):main.cpp: first defined here
Functions.o(.text+0x80):Functions.cpp: multiple definition of `CreateMyWindClass()'
main.o(.text+0x80):main.cpp: first defined here
Functions.o(.text+0x192):Functions.cpp: multiple definition of `CreateMyWindow()'
main.o(.text+0x192):main.cpp: first defined here
main.o(.text+0xb9):main.cpp: undefined reference to `hInstance'
main.o(.text+0x19c):main.cpp: undefined reference to `hInstance'
main.o(.text+0x1ff):main.cpp: undefined reference to `nCmdShow'
Functions.o(.text+0xb9):Functions.cpp: undefined reference to `hInstance'
Functions.o(.text+0x19c):Functions.cpp: undefined reference to `hInstance'
Functions.o(.text+0x1ff):Functions.cpp: undefined reference to `nCmdShow'
I don't redefine anythng at all, and I don't know where my undefined references are coming from. I thought I defined everything. And yes, I chose Win32 GUI project, not console. [Edited by - Drakkcon on August 3, 2004 1:00:20 AM]

Share this post


Link to post
Share on other sites
Sneftel    1788
Quote:

#include "Functions.cpp"

You should never need to #include a source file in another source file. Just include a header which declares the function.

Share this post


Link to post
Share on other sites
Drakkcon    612
You see, this is something that you'd think after all of the tutorials that I've read, I would pick up on this. Thank you for stating this. As I've stated before my knowledge is incrediably spotty.

Share this post


Link to post
Share on other sites
Drakkcon    612
This doesn't make any sense, look at all the errors I get now:

Functions.cpp:3: parse error before `(' token
Functions.cpp: In function `int CreateMyWindClass()':
Functions.cpp:29: ISO C++ forbids declaration of `WNDCLASSEX' with no type
Functions.cpp:29: parse error before `;' token
Functions.cpp:30: ISO C++ forbids declaration of `HINSTANCE' with no type
Functions.cpp:30: parse error before `;' token
Functions.cpp:34: `wc' undeclared (first use this function)
Functions.cpp:34: (Each undeclared identifier is reported only once for each
function it appears in.)
Functions.cpp:36: `WndProc' undeclared (first use this function)
Functions.cpp:39: `hInstance' undeclared (first use this function)
Functions.cpp:40: `NULL' undeclared (first use this function)
Functions.cpp:40: `IDI_APPLICATION' undeclared (first use this function)
Functions.cpp:40: `LoadIcon' undeclared (first use this function)
Functions.cpp:41: `IDC_ARROW' undeclared (first use this function)
Functions.cpp:41: `LoadCursor' undeclared (first use this function)
Functions.cpp:42: `HBRUSH' undeclared (first use this function)
Functions.cpp:42: `COLOR_WINDOW' undeclared (first use this function)
Functions.cpp:47: `RegisterClassEx' undeclared (first use this function)
Functions.cpp:50: `MB_ICONEXCLAMATION' undeclared (first use this function)

Functions.cpp:50: `MB_OK' undeclared (first use this function)

Functions.cpp:50: `MessageBox' undeclared (first use this function)

Functions.cpp: In function `int CreateMyWindow()':
Functions.cpp:58: ISO C++ forbids declaration of `HINSTANCE' with no type
Functions.cpp:58: parse error before `;' token
Functions.cpp:62: ISO C++ forbids declaration of `HWND' with no type
Functions.cpp:62: parse error before `;' token
Functions.cpp:63: `hwnd' undeclared (first use this function)
Functions.cpp:64: `WS_EX_CLIENTEDGE' undeclared (first use this function)
Functions.cpp:67: `WS_OVERLAPPEDWINDOW' undeclared (first use this function)
Functions.cpp:68: `CW_USEDEFAULT' undeclared (first use this function)
Functions.cpp:69: `CreateWindowEx' undeclared (first use this function)
Functions.cpp:78: `ShowWindow' undeclared (first use this function)
Functions.cpp:79: `UpdateWindow' undeclared (first use this function)

I see no parse error.

EDIT: Updated code to reflect changes.

Share this post


Link to post
Share on other sites
Scheermesje    169
You are not including "functions.h" in functions.cpp so you are also not including windows.h

You need to add to following code also to your functions.cpp

//Includes//////////////////////////////////////////////////////////////////////
#include "Functions.h"



And Sneftel pointed out remove the include ***.cpp line from your header file :)

The cpp file should include the header file not the other way around.

Share this post


Link to post
Share on other sites
Drakkcon    612
I'm still getting the same errors.
Main.cpp includes functions.h, functions.h includes windows.h, and functions.cpp includes functions.h (which I don't understand).

Share this post


Link to post
Share on other sites
Scheermesje    169
I've changed your code.. the following code works in VC++.NET 2003.

Main.cpp:


#define WIN32_LEAN_AND_MEAN //Cuts the crap
//Includes//////////////////////////////////////////////////////////////////////
#include "Functions.h"
//WinMain///////////////////////////////////////////////////////////////////////

HINSTANCE g_hInstance;
int g_nCmdShow;

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

g_nCmdShow = nCmdShow;
g_hInstance = hInstance;

CreateMyWindClass();
CreateMyWindow();

while(GetMessage(&Msg, NULL, 0, 0) > 0)
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
return Msg.wParam;
}



Functions.cpp

#include "Functions.h"

//FunctionDefinitions///////////////////////////////////////////////////////////
//Main Window Procedure/////////////////////////////////////////////////////////
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_CLOSE:
{
DestroyWindow(hwnd);
break;
}

case WM_DESTROY:
{
PostQuitMessage(0);
break;
}

default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}

//CreateWindClass///////////////////////////////////////////////////////////////
int CreateMyWindClass()
{
//wc is static, so there's no need for a return value, just use wc
WNDCLASSEX wc;

//Registering the Window Class
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = 0;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = g_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;
}
return 1;
}

int CreateMyWindow()
{
HWND hwnd;
hwnd = CreateWindowEx(
WS_EX_CLIENTEDGE,
g_szClassName,
"The title of my window",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, 240, 120,
NULL, NULL, g_hInstance, NULL);

if(hwnd == NULL)
{
MessageBox(NULL, "Window Creation Failed!", "Error!",
MB_ICONEXCLAMATION | MB_OK);
return 1;
}

ShowWindow(hwnd, g_nCmdShow);
UpdateWindow(hwnd);
}



Functions.h

#ifndef FUNCTIONS_H
#define FUNCTIONS_H
////////////////////////////////////////////////////////////////////////////////
#include <windows.h>

//Consts////////////////////////////////////////////////////////////////////////
const char g_szClassName[] = "myWindowClass";

//FunctionDeclarations//////////////////////////////////////////////////////////
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
int CreateMyWindClass();
int CreateMyWindow();

extern HINSTANCE g_hInstance;
extern int g_nCmdShow;

#endif



I think you need to do some research on the following subjects:

the scope of a variable
the meaning of 'extern'
when and how to include header files

Good luck with it :) Let me hear it if you got any questions.

Share this post


Link to post
Share on other sites
Drakkcon    612
Oh, you put external devclarations in the header files. That explains it. Thanks.

BUT. If WNDCLASSX isn't static, doesn't that mean it will fall out of scope after the function call?

OH, but the class is registered. I gotcha now.

Share this post


Link to post
Share on other sites
Scheermesje    169
wndclassx will fal out of function scope but as you said it doesn't matter because you used it :)

If you would be calling a function every frame and you need to keep the value the same between all the function calls you need to declare it static. Otherwise you won't need it :)

As a practice.. try to encapsulate your functions in a class. Give the class an init function(or how you want to name it) and give the hinstance and nCmdShow as parameters.

Write the class once and use it often :)

You could also give it a boolean value for fullscreen yes/no.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this