views:

1939

answers:

2

Using: VS2008, Win32, C/C++

I'm trying to encapsulate my entire dialog window into a class for reusability. Sort of like a custom control. In doing this, I am moving my seperate functions into a class. The following struct design though is giving me problems, with Visual Studio outputting: error C2334 '{'.

It's a simple message map layout. But I can't seem to escape this C2334 error. :(

Here is my class code snippet.

class CScrollingListDlg
{
private:

LRESULT DoCommandMain (HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam);
LRESULT DoPaintMain   (HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam);
LRESULT DoAnimationTimer (HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam);
LRESULT DoHandleTouch (HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam);
LRESULT DoDestroyMain (HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam);

//
// message maps
//
// Generic defines and data types.
struct decodeUINT {
    UINT Code;
    LRESULT (*Fxn)(HWND, UINT, WPARAM, LPARAM);
};

struct decodeCMD {
    UINT Code;
    LRESULT (*Fxn)(HWND, WORD, HWND, WORD);
};

// WM_Message dispatch table for MainWndProc.

//
// ***  error C2334 '{'  ***
//
const struct decodeUINT MainMessages[] = {
    WM_PAINT, DoPaintMain,
    WM_DESTROY, DoDestroyMain,
    WM_QUIT, DoDestroyMain,
    WM_COMMAND, DoCommandMain,
};


};

What am I missing here?

Thanks.

+5  A: 

You can't initialize an array member inside a class declaration. You should only declare MainMessages, then initialize it in the constructors of the class.

I also recommend using std::vector instead of array. This way, decodeUINT declaration becomes:

std::vector<decodeUINT> MainMessages;

and in constructor, use std::vector::push_back method to insert content.

If you need access to the memory managed by the vector, use &MainMessages[0].

Cătălin Pitiș
j_random_hacker
Especially since MainMessages is declared const, I suspect that the static array is what is needed.
Eclipse
I agree with your comments. I would do it as static array, which means that a static method for initialization is needed.
Cătălin Pitiș
+5  A: 

You cannot specify initialisers for non-static members that way -- you would normally need to declare the array and then populate it inside the constructor... Except that, in fact there is no way to initialise const member arrays in C++ (see this thread).

If you are prepared to share MainMessages amongst all instances of CScrollingListDlg (which I suspect was your intention all along), you should make it static, in which case you can declare:

static const decodeUINT MainMessages[];  // "struct" keyword unnecessary

inside the class definition of CScrollingListDlg, and then define it outside the class:

const CScrollingListDlg::decodeUINT CScrollingListDlg::MainMessages[] = {
    WM_PAINT,   DoPaintMain,
    WM_DESTROY, DoDestroyMain,
    WM_QUIT,    DoDestroyMain,
    WM_COMMAND, DoCommandMain,    // The comma *is* allowed -- thanks Josh!
};

In order for this to actually compile, you'll need to make DoPaintMain(), DoDestroyMain(), etc. static as well -- as it stands, they are all per-object methods that implicitly take a this pointer, so they can't actually be contained in a function pointer of type LRESULT (*Fxn)(HWND, UINT, WPARAM, LPARAM). (You could leave them as non-static methods and change the pointer type in decodeUINT to a pointer-to-member-function type, but that's probably not what you want.)

[EDIT: Thanks to Josh for some helpful comments!]

j_random_hacker
+1 Beat me to it, (although you do need to add [] to the array definition: const CScrollingListDlg::decodeUINT CScrollingListDlg::MainMessages[] = { ...
Eclipse
The superfluous comma is allowed (initializer-clause is defined as an initializer-list followed by an optional comma) and for good reason: when you add a new line to a list in an array like this or an enum, you only change one line. If you leave off the final comma, you'll end up changing two line in source control every time you add a new item. It's just clearer when looking at diffs if only the interesting line changes.
Eclipse
@Josh: Both good points. Didn't know about the trailing comma being allowed, thanks!
j_random_hacker