Beginner C/C++

Moderators: None (Apply to moderate this forum)
Number of threads: 5428
Number of posts: 16949

This Forum Only
Post New Thread
Single Post View       Linear View       Threaded View      f

Report
A VERY basic question about classes Posted by red888 on 2 Dec 2009 at 12:35 PM
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:
#if !defined WINNIE_H
#define WINNIE_H
//------------------------------------
//  winnie.h
//  (c) Bartosz Milewski, 1995, 97
//------------------------------------

#include <windows.h>

// 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




source file:
//------------------------------------
//  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 );
}



Report
Re: A VERY basic question about classes Posted by red888 on 2 Dec 2009 at 1:15 PM
I have another question about this code.
WinMaker (): _hwnd (0) {}
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?
Report
Re: A VERY basic question about classes Posted by AsmGuru62 on 3 Dec 2009 at 5:43 AM
You are correct.
It is the same as:

WinMaker::WinMaker ()
{
  _hwnd=0;
}

I am not sure how this is different from the code you posted, but I think it allows for a compiler to inline the constructor code, making code execution faster. However, I may be wrong.
Report
Re: A VERY basic question about classes Posted by red888 on 4 Dec 2009 at 7:49 AM
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?
Report
Re: A VERY basic question about classes Posted by AsmGuru62 on 5 Dec 2009 at 5:43 AM
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:

void function (int a, int b)
{
  printf ("%d", a);
}

In the above code parameter b is not used. Strict compiler will give a warning for that. To shut up the compiler - the name simply can be omitted:
void function (int a, int)
{
  printf ("%d", a);
}

Report
Re: A VERY basic question about classes Posted by red888 on 5 Dec 2009 at 3:33 PM
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.



 

Recent Jobs

Official Programmer's Heaven Blogs
Web Hosting | Browser and Social Games | Gadgets

Popular resources on Programmersheaven.com
Assembly | Basic | C | C# | C++ | Delphi | Flash | Java | JavaScript | Pascal | Perl | PHP | Python | Ruby | Visual Basic
© Copyright 2011 Programmersheaven.com - All rights reserved.
Reproduction in whole or in part, in any form or medium without express written permission is prohibited.
Violators of this policy may be subject to legal action. Please read our Terms Of Use and Privacy Statement for more information.
Operated by CommunityHeaven, a BootstrapLabs company.