|
-
March 4th, 2015, 08:59 AM
#1
MFC: PostMessage and Handling it without the hassle (and a question).
Something interesting I came up with while working on a project.
In a particular dialog I needed a lot of different PostMessage() cases, so that would typically have meant:
adding a message ID, Doing the postmessage which involved wrapping parameters into structs, adding a handlerfunction to the .h file, adding the handler function to the .cpp, adding an entry to the messagemap.
Then it hit me.. Why not have a single generic handler, and post a lambda instead of parameters. All our dialogs are derived from our own dialog class which derives from CDialog, so adding the handler once, I could have an easy way out of simple "do the following in a posted message" things.
In CxDialog.h, in the class definition:
Code:
public:
typedef std::function<void()> PostedFunction_type;
void PostedFunction(PostedFunction_type func) const;
protected:
LRESULT OnPostedFunction(WPARAM wParam, LPARAM lParam);
In CxDialog.cpp (derives from CDialog)
somewhere near the top:
Code:
#define WM_POSTEDFUNCTION (WM_USER_INTF+8)
and in the messagemap
Code:
ON_MESSAGE(WM_POSTEDFUNCTION, OnPostedFunction)
and add
Code:
class PostedFunctionWrapper // Helper class, since we can't directly cast std::function to wParam.
{
public:
PostedFunctionWrapper(ClInput::PostedFunction_type func) :
func(func)
{
}
void call() const {
func();
}
private:
ClInput::PostedFunction_type func;
};
void CxDialog::PostedFunction(PostedFunction_type func) const
{
PostMessage(WM_POSTEDFUNCTION, reinterpret_cast<WPARAM>(new PostedFunctionWrapper(func)), 0);
}
LRESULT CxDialog::OnPostedFunction(WPARAM wParam, LPARAM /*lParam*/)
{
std::auto_ptr<PostedFunctionWrapper> pPFW (reinterpret_cast<PostedFunctionWrapper*>(wParam));
pPFW->call();
return 0;
}
So now in our derived dialogs, we can do something like (for example in OnInitDialog()):
Code:
PostedFunction([](){ AfxMessageBox("Hello"); });
Which will then show the hello messagebox when the dialog has been properly initialized and made visible
It works, you do need to be careful if you pass stuff by reference ofc since you can't post references to local variables (they'll be gone by the time the message is processed).
Feel free to use this in your own projects, makes life for me and others on the team a lot easier at least.
I'm not entirely happy about the need for the wrapper class though, but attempts at casting the std::function to WPARAM directly failed. Is there a way to avoid the wrapper or to make this approach "better" ?
Tags for this Thread
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|