Jump to content
  • Advertisement

Archived

This topic is now archived and is closed to further replies.

daerid

std::map issues, and pointer-to-function question

This topic is 6086 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Question 1: Whenever I use a std::map in my project, I always get the "Identifier truncated to 255 characters in Debug information" warning, even if I''m just doing a std::map. How do I fix that? Or do I just have to use the #pragma warning(disable:####) method? (Using VC++ 6 SP5 btw) Question 2: I''m basically writing my own c++ object library for Win32 API. What I''d like to do is use pointer-to-member-functions as the callbacks for windows messages, and use a std::map to link up the WM_*** message ( an unsigned integer ) with the pointer to the function. However, I can''t seem to get it quite right. Here''s some code for example:
  

class Window;

// Pointer to a member function of the Window class

// that returns an LRESULT and takes a WPARAM and 

// a LPARAM as arguments

typedef LRESULT (Window::*MSGCALLBACK)(WPARAM,LPARAM);

class Window
{
  // ... some code

public:
  Window(); 

  // Add a message handler

  void AddMsgHandler(UINT msg,MSGCALLBACK pfn);
  
  // Handle the WM_CHAR message

  LRESULT OnChar(WPARAM wparam,LPARAM lparam);

  // ... some more code

protected:
  std::map<UINT,MSGCALLBACK> _msgmap;
};

// Implementation

Window::Window
{
  // Add the WM_CHAR msg handler

  AddMsgHandler(WM_CHAR,reinterpret_cast<MSGCALLBACK>(Window::OnChar));
}

void Window::AddMsgHandler(UINT msg,MSGCALLBACK pfn)
{
  _msgmap.insert(std::pair<UINT,MSGCALLBACK>(msg,pfn));
}

LRESULT Window::OnChar(WPARAM wparam,LPARAM lparam)
{
  // process and display char message here

  ...
  ...
}

  
Am I missing something? Whenever I try to compile the code above, I get "Error: reinterpret_cast, cannot convert '''' to ''__thiscall long (Window::*)(WPARAM,LPARAM);'' or something to that effect. What am I doing wrong? Thanks in advance!

Share this post


Link to post
Share on other sites
Advertisement

Question 1:

You basically can two options:

1. Ignore the warning (duh)
2. Put a #pragma warning(disable:4786) at the top

It''s a well-known "problem" with VC++.

Question 2:

Just two comments:

You don''t need the reinterpret_cast.

  

AddMsgHandler(WM_CHAR,OnChar);



Using a switch statement may actually be MORE desirable.
(or until hash table becomes standard)

Why?

You can put the most often-used cases at the top of the
switch. You can''t control how the map is laid out.


Premature optimizations can only slow down your project even more.

Share this post


Link to post
Share on other sites
Herm... kewl.

Thanks

I don''t want to use a switch statement because I want to be able to dynamically add and remove message handlers at run time.

Share this post


Link to post
Share on other sites
I used a slightly different mapping method:

  
typedef void (*tyMessageHandler)(Window *wnd, /* other args */);
typedef std::map<long, tyMessageHandler> tyMessageMap;
.
class Window
{
//...

tyMessageMap m_MessageMap;
};


You can now insert simple functions into the message map without having to derive from or reimplement the Window class.

I wanna work for Microsoft!
[ GDNet Start Here | GDNet Search Tool | GDNet FAQ | MS RTFM [MSDN] | SGI STL Docs | Google! ]
Thanks to Kylotan for the idea!

Share this post


Link to post
Share on other sites

Just like in another thread, it begs the question,
why would you want to "be able to dynamically add and
remove message handlers at run time"?

IMHO, Message handlers should be "static".

Maybe an example of why you "need" it to be dynamic
would help.


Premature optimizations can only slow down your project even more.

Share this post


Link to post
Share on other sites
quote:
Original post by tangentz

Just like in another thread, it begs the question,
why would you want to "be able to dynamically add and
remove message handlers at run time"?

IMHO, Message handlers should be "static".

Maybe an example of why you "need" it to be dynamic
would help.

See the reply in the other thread. I write general-purpose Windows UI code, and being able to manage certain objects using this one lightweight class (and only as much code as I need) is an advantage for me.

I wanna work for Microsoft!
[ GDNet Start Here | GDNet Search Tool | GDNet FAQ | MS RTFM [MSDN] | SGI STL Docs | Google! ]
Thanks to Kylotan for the idea!

Share this post


Link to post
Share on other sites
Interesting approach Olesuyi, but I fail to see why you would pass a pointer to a window object.

here''s a sample of what my WNDPROC would be ( pseudo-code ):

  
LRESULT CALLBACK WinProc(HWND hwnd,UINT msg,WPARAM wparam,LPARAM lparam)
{
Window *win;
bool doDef;
LRESULT res;

win = g_pApp->GetWindow(hwnd);
res = win->DispatchMsg(msg,wparam,lparam,doDef);
return doDef?::DefWindowProc(hwnd,msg,wparam,lparam):res;
}


// The DispatchMsg function

LRESULT Window::DispatchMsg(UINT msg,WPARAM wparam,LPARAM lparam, bool &doDef)
{
std::map<UINT,MSGCALLBACK>::iterator pos;
pos = _msgmap.find(msg);
if(pos!=_msgmap.end())
{
doDef = false;
return (*pos)(wparam,lparam);
}
else
{
doDef = true;
return 0;
}
}


Share this post


Link to post
Share on other sites
quote:
Original post by tangentz
Just like in another thread, it begs the question,
why would you want to "be able to dynamically add and
remove message handlers at run time"?



Several reasons, I guess. It''s not too hard to imagine implementing a state machine using this sort of technique - i.e. you could modify the runtime behaviour of an event according to the current state.

--
The Dilbert Principle: People are idiots.

Share this post


Link to post
Share on other sites
quote:
Original post by Oluseyi
O L U S E Y I. It's not that hard to spell.



:o

sorry.. it's just not a word I'm used to typing

edit: I just understood. That's pretty nifty

Edited by - daerid on February 18, 2002 1:38:30 PM

Share this post


Link to post
Share on other sites

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!