Re: Quick question on object instantiation!
Victor Bazarov wrote:
Robby wrote:
In Windows programming, is it bad practice or uncommon to instatiate
an object outside WndProc and then using the object in WndProc.
Don't know how [un]common this is, but I've used it (or, rather, some
variation of it).
> (snip..)
Shape *pShape = new Shape; //Object instatiated outside WndProc
I usually make it 'static' and place it inside the 'WndProc' itself.
Then there is much less temptation to try to change it (or access it)
from some other function.
I use the contrary strategy. I define a class that hold all the variables
that WndProc would need to use, then the WndProc function itself becomes
the member of that class, so the function can freely use any members
inside the class.
Actually, the class is most often called MainWindow :) and it's derived from
VirWindow, I learned/copied/(stolen?) this organisation from Macrosoft's
example code came as tutorial for COM interface. Since it originally belonged
to Microsoft, I should not reluctant to post that part of code...
muchan
/*+==========================================================================
File: APPUTIL.H
This file was part of the Microsoft COM Tutorial Code Samples.
(slightly modified by muchan, promikra, Ljubljana 2001)
(heavily modified by muchan, promikra, Ljubljana 2003)
==========================================================================+*/
// Don't allow recursive includes of this file.
#ifndef APPUTIL_H
#define APPUTIL_H
/*--------------------------------------------------------------------------
The following pragma disables the C4355 warning which reads:
"'this': used in base member initializer list."
--------------------------------------------------------------------------*/
#pragma warning( disable : 4355 )
#ifdef __cplusplus
// If compiling under C++ Ensure that Windows callbacks are
// undecorated extern C calls.
extern "C" {
#endif
LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
LRESULT CALLBACK DialogProc(HWND hWndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
class VirWindow
{
public:
// Constructor
VirWindow()
{
m_hInst = NULL;
m_hWnd = NULL;
};
// Destructor
virtual ~VirWindow(){};
// Envelopes the Windows' CreateWindow function call.
HWND Create(
LPTSTR lpszClassName, // Address of registered class name
LPTSTR lpszWindowName, // Address of window name
DWORD dwStyle, // Window style
int x, // Horizontal position of window
int y, // Vertical position of window
int nWidth, // Window width
int nHeight, // Window height
HWND hWndParent, // Handle of parent or owner window
HMENU hmenu, // Handle of menu, or child window identifier
HINSTANCE hinst); // Handle of application instance
// Get the protected handle of this window.
HWND GetHwnd(void)
{
return(m_hWnd);
}
// WindowProc is a pure virtual member function and MUST be over-ridden
// in any derived classes.
virtual LRESULT WindowProc(UINT uMsg, WPARAM wParam, LPARAM lParam) = 0;
protected:
// Application instance handle.
HINSTANCE m_hInst;
// Handle of this window.
HWND m_hWnd;
// Tell the compiler that the outside WindowProc callback is a friend
// of this class and can get at its protected data members.
friend LRESULT CALLBACK ::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
};
#ifdef __cplusplus
}
#endif
// here comes another utility definitions... (sniped for this post)
#endif
================================================================================
AppUtil.cpp ====================================================================
#include "AppUtil.h"
// utility codes snipped
LRESULT CALLBACK WindowProc(
HWND hWnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam)
{
// Get a pointer to the window class object.
VirWindow* pWin = (VirWindow*) GetWindowLong(hWnd, GWL_USERDATA);
switch (uMsg)
{
case WM_NCCREATE:
// Since this is the first time that we can get ahold of
// a pointer to the window class object, all messages that might
// have been sent before this are never seen by the Windows object
// and only get passed on to the DefWindowProc
// Get the initial creation pointer to the window object
pWin = (VirWindow *) ((CREATESTRUCT *)lParam)->lpCreateParams;
// Set it's protected m_hWnd member variable to ensure that
// member functions have access to the correct window handle.
pWin->m_hWnd = hWnd;
// Set its USERDATA DWORD to point to the window object
SetWindowLong(hWnd, GWL_USERDATA, (long) pWin);
break;
case WM_DESTROY:
// This is our signal to destroy the window object.
SetWindowLong(hWnd, GWL_USERDATA, 0);
DELETE_POINTER(pWin);
break;
default:
break;
}
// Call its message proc method.
if (NULL != pWin)
return (pWin->WindowProc(uMsg, wParam, lParam));
else
return (DefWindowProc(hWnd, uMsg, wParam, lParam));
}
HWND VirWindow::Create(
LPTSTR lpszClassName,
LPTSTR lpszWindowName,
DWORD dwStyle,
int x,
int y,
int nWidth,
int nHeight,
HWND hWndParent,
HMENU hMenu,
HINSTANCE hInst)
{
// Remember the passed instance handle in a member variable of the
// C++ Window object.
m_hInst = hInst;
// Call the Win32 API to create the window.
m_hWnd = ::CreateWindow(
lpszClassName,
lpszWindowName,
dwStyle,
x,
y,
nWidth,
nHeight,
hWndParent,
hMenu,
hInst,
this);
return (m_hWnd);
}
================================================================================
And the actual WndProc of the application looks like this: (just a exapmle):
LRESULT MainWindow::WindowProc(UINT uMsg, WPARAM wParam, LPARAM lParam)
{
LRESULT lResult = FALSE;
switch (uMsg) {
case WM_CREATE:
{
m_timeron = FALSE;
m_intimer = FALSE; // semafor initialisation
WallPaperSetUp(MAIN_WINDOW_WALLPAPER);
StartTimer(TIMER_ELASPTIME); // for application with Timer, uncoment this line
// and implement the OnTimer() function
} break;
case WM_TIMER:
{
OnTimer();
} break;
case WM_PAINT:
{
PAINTSTRUCT ps;
RECT rect;
...
...
...
}