Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Sign In with Facebook Sign In with Google Sign In with OpenID

Categories

We have migrated to a new platform! Please note that you will need to reset your password to log in (your credentials are still in-tact though). Please contact lee@programmersheaven.com if you have questions.
Welcome to the new platform of Programmer's Heaven! We apologize for the inconvenience caused, if you visited us from a broken link of the previous version. The main reason to move to a new platform is to provide more effective and collaborative experience to you all. Please feel free to experience the new platform and use its exciting features. Contact us for any issue that you need to get clarified. We are more than happy to help you.

A VERY basic question about classes

red888red888 Posts: 25Member
This is Windows API code, but this is such a basic question about classes I'm posting it here.


What I am confused about concerns class definition and usage.
In the following class definition:
WinClass (WNDPROC wndProc, char const * className, HINSTANCE hInst);
If I change this to:
WinClass (WNDPROC, char const *, HINSTANCE);
The program still runs fine, so my question is what exactly is the significance of "wndProc" in "WNDPROC wndProc" to the compiler? Is this only for notation/readability purposes? Or does wndProc have any actually meaning apart from giving some clue as to what to pass WNDPROC?

Thank you for any responses.


Header:
[code]
#if !defined WINNIE_H
#define WINNIE_H
//------------------------------------
// winnie.h
// (c) Bartosz Milewski, 1995, 97
//------------------------------------

#include

// Forward declaration of our Window Procedure
LRESULT CALLBACK WindowProcedure
(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);

// We'll be creating windows of this Class in our program
class WinClass
{
public:
WinClass (WNDPROC, char const *, HINSTANCE); //(WNDPROC wndProc, char const * className, HINSTANCE hInst);
void Register ()
{
::RegisterClass (&_class);
}
private:
WNDCLASS _class;
};

// Creates a window of a given Class
class WinMaker
{
public:
WinMaker (): _hwnd (0) {}
WinMaker (WNDPROC, char const *, HINSTANCE); //(char const * caption, char const * className, HINSTANCE hInstance);
void Show (int cmdShow)
{
::ShowWindow (_hwnd, cmdShow);
::UpdateWindow (_hwnd);
}
protected:
HWND _hwnd;
};

#endif

[/code]


source file:
[code]
//------------------------------------
// winnie.cpp
// (c) Bartosz Milewski, 1995
//------------------------------------

#include "winnie.h"

// This is the entry point of every Windows program
int WINAPI WinMain
(HINSTANCE hInst, HINSTANCE hPrevInst, char * cmdParam, int cmdShow)
{
char className [] = "Winnie";

// Define a Window Class and register it under the name "Winnie"
WinClass winClass (WindowProcedure, className, hInst);
winClass.Register ();

// Create and show a window
WinMaker win ("Hello Windows!", className, hInst);
win.Show (cmdShow);

MSG msg;
int status;
// Keep pumping messages--they end up in our Window Procedure
while ((status = ::GetMessage (&msg, 0, 0, 0)) != 0)
{
if (status == -1)
return -1;
::DispatchMessage (&msg);
}

return msg.wParam;
}

WinClass::WinClass (WNDPROC wndProc, char const * className, HINSTANCE hInst)
{
_class.style = 0;
_class.lpfnWndProc = wndProc; // Window Procedure: mandatory
_class.cbClsExtra = 0;
_class.cbWndExtra = 0;
_class.hInstance = hInst; // owner of the class: mandatory
_class.hIcon = 0;
_class.hCursor = ::LoadCursor (0, IDC_ARROW); // optional
_class.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1); // optional
_class.lpszMenuName = 0;
_class.lpszClassName = className; // mandatory
}

WinMaker::WinMaker
(char const * caption, char const * className, HINSTANCE hInstance)
{
_hwnd = ::CreateWindow (
className, // name of a registered window class
caption, // window caption
WS_OVERLAPPEDWINDOW, // window style
CW_USEDEFAULT, // x position
CW_USEDEFAULT, // y position
CW_USEDEFAULT, // witdh
CW_USEDEFAULT, // height
0, // handle to parent window
0, // handle to menu
hInstance, // application instance
0 ); // window creation data
}

// Window Procedure called by Windows with all kinds of messages

LRESULT CALLBACK WindowProcedure
(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
// In this simple program, this is the only message we are processing
case WM_DESTROY:
::PostQuitMessage (0);
return 0; // return zero when processed

}
// All the unprocessed messages go there, to be dealt in some default way
return ::DefWindowProc (hwnd, message, wParam, lParam );
}


[/code]

Comments

  • red888red888 Posts: 25Member
    I have another question about this code.
    [code]WinMaker (): _hwnd (0) {}[/code] is initializing _hwnd to 0 correct? Why exactly is this necessary? Is this just like when you set variables to zero before using them so they don't start with a random or invalid value?
  • AsmGuru62AsmGuru62 Posts: 6,519Member
    [color=Blue]You are correct.
    It is the same as:[/color]
    [code]
    WinMaker::WinMaker ()
    {
    _hwnd=0;
    }
    [/code]
    [color=Blue]I am not sure how this is different from the code you posted, but I think it allows for a compiler to [b]inline[/b] the constructor code, making code execution faster. However, I may be wrong.[/color]
  • red888red888 Posts: 25Member
    Thanks for the reply. That explains one of my questions, but what about the class definitions:
    WinClass (WNDPROC wndProc, char const * className, HINSTANCE hInst);
    VS
    WinClass (WNDPROC, char const *, HINSTANCE);

    Am I right in thinking the values wndProc, className, and hInst are not mandatory in the definition and just placeholders or clues to the programmer that the compiler ignores?
  • AsmGuru62AsmGuru62 Posts: 6,519Member
    [color=Blue]You are correct again! When compiler "sees" a prototype:

    ret_type func_name (...parameters...) ;

    it only needs to detect parameter types, their names are not important, it is just more readable for a programmer if names are actually there, because proper naming can explain code better.

    C++ also can accept the omitted parameter names in a body of function - not only in prototype. Example:
    [/color]
    [code]
    void function (int a, int b)
    {
    printf ("%d", a);
    }
    [/code]
    [color=Blue]In the above code parameter [b]b[/b] is not used. Strict compiler will give a warning for that. To shut up the compiler - the name simply can be omitted:[/color]
    [code]
    void function (int a, int)
    {
    printf ("%d", a);
    }
    [/code]
  • red888red888 Posts: 25Member
    Cool. I think I remember reading somewhere in one of my books you could do that in functions. Making the comparison between them and class definitions helps me wrap my head around things a bit better, thanks.
Sign In or Register to comment.