• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1598
  • Last Modified:

Posting user defined message - MFC

Hi Experts,
I have in my MFC dialog application (VS 2008) a function named OnSaveImages which is defined as follow:

void CBitmap::OnSaveImages()
{
   CString x1;
  x1.Format (_T("C:\\Images\\08-05-09\\Img%d.bmp"), ImageNumber);
  m_Img.SaveImg(x1);
}
where the function SaveImg is an operation of the (.OCX) Image Control declared as:
BOOL SaveImg(LPCTSTR Filename)

My question is how could I define a user defined message WM_APP that will call OnSaveImages and how could I post that message so that I could call the function OnSaveImages?
I've already read similar questions here so that I know I need to do the followings:

//In the Bitmap.h file
afx_msg LRESULT OnSaveImages (WPARAM, LPARAM);

//In te CBitmap.cpp file
#define WM_SAVEIMAGES  WM_APP+2
//BEGIN_MESSAGE_MAP(CBitmapDlg, CDialog)
...
ON_MESSAGE(WM_SAVEIMAGES,OnSaveImages)
...

but I still don't get how I could handle with LPARAM and WPARAM in the definition of:
LRESULT OnSaveImages (WPARAM, LPARAM);
and in PostMessage(WM_SAVEIMAGES,?,?)

Thank you

0
andy06
Asked:
andy06
  • 4
  • 4
  • 4
  • +1
3 Solutions
 
ZoppoCommented:
Hi andy06,

what you wrote is correct - you don't need to take care of WPARAM and LPARAM as long as you don't want to pass some data with the posted message. Just declare a message caller function like this and call the OnSaveImages there:

#define WM_SAVEIMAGES  WM_APP+2

...
ON_MESSAGE( WM_SAVEIMAGES,OnMsgSaveImages )
...

LRESULT
CBitmapDlg::OnMsgSaveImages (WPARAM, LPARAM)
{
 OnSaveImages();
}

Hope that helps,

ZOPPO
0
 
alb66Commented:
pYourWnd->PostMessage( WM_SAVEIMAGES, 123, 456 );

LRESULT CYourWnd::OnSaveImages( WPARAM wParam, LPARAM lParam )
{
  ASSERT( wParam == 123 );
  ASSERT( lParam == 456 );

  return 0;
}
0
 
andy06Author Commented:
Unfortunatelly I can not  managed to save the image...
I have a function called Calculate():
void CBitmap::Calculate(Image Img)
{    .....
   // do something  
   ...
 //display the image
 PostMessage(WM_DISPLAYIMAGE, 0, 0);
//save the image
PostMessage(WM_SAVEIMAGES, 0, 0);
//and then I should do some calculating with the image
...
}
 In Calculate(Image Img) before saving the image with  PostMessage(WM_SAVEIMAGES,0,0) I displayed it and after saving it I proceed some calculations with the image.This process should occur many times...

Before adding the saving message every thing was fine and but now my application just crashes...
0
The new generation of project management tools

With monday.com’s project management tool, you can see what everyone on your team is working in a single glance. Its intuitive dashboards are customizable, so you can create systems that work for you.

 
alb66Commented:
Keep in mind that using PostMessage, your function Calculate() is executed without waiting for the end of save function.
If you want to perform the operations in sequence you can use SendMessage instead.
http://www.experts-exchange.com/Programming/Languages/.NET/Visual_CPP/Q_21325004.html
0
 
itsmeandnobodyelseCommented:
>>>> PostMessage(WM_SAVEIMAGES, 0, 0);

PostMessage puts the message at end of message queue. Hence, the saving would occur some time *after* CBitmap::Calculate(Image Img) returned.

You could call SendMessage instead of PostMessage to have the message processed immediately. But, you should pass a handle or pointer with the message and not use shared or global data.


0
 
andy06Author Commented:
>>you should pass a handle or pointer with the message and not use shared or global data
why do you mean by: not use shared or global data?
As handle to passed with  the message should I use hWnd=GetSafeHwnd(); or is that unnecessary?
SendMessage will still  be called with 3 parameters because it is used within a function of a class derived from CWnd right?

0
 
alb66Commented:
The first parameter is the message code and, of course, it is mandatory.
The second and the third are optional parameters and they depends by the message; in the case of user defined message you can decide to use one, both or none of them.
0
 
itsmeandnobodyelseCommented:
>>>> why do you mean by: not use shared or global data?
You currently pass 0, 0 with the message. Hence the message handler has no additional information but the window and the message id. If it needs some more information it currently must get them from global or shared data (re)sources. It is better to use the WPARAM and LPARAM arguments to pass individual information with the message rather than to retrieve all in the message handler.
0
 
itsmeandnobodyelseCommented:
>>>> As handle to passed with  the message should I use hWnd=GetSafeHwnd();
You also could use CWnd::PostMessage as in most samples above. The CWnd::PostMessage makes the call GetSafeHwnd() before it calls the ::PostMessage(hwnd, ...) from WINAPI.
0
 
itsmeandnobodyelseCommented:
>>>> SendMessage will still  be called with 3 parameters because it is used within a function of a class derived from CWnd right?


Yes, the same applies for PostMessage. But SendMessage is dangerous cause it could deadlock. Better always use PostMessage if you don't need immediately return.
0
 
andy06Author Commented:
>>Better always use PostMessage if you don't need immediately return.
After saving the image I have to perform some calculations with the image.Hence it's maybe better to use SendMessage.
There's something strange. ..I'm calling SendMessage many times in the void CBitmap::Calculate(Image Img) (see above). For example to refresh the image I will be using  SendMessage(WM_DISPLAYIMAGE, 0, 0);and since I  don't write afterwards  the following satements:

if (::PeekMessage(&message, NULL, 0, 0, PM_REMOVE)) {
            ::TranslateMessage(&message);
            ::DispatchMessage(&message);
      }
my image won't be refreshed at all... Is  that normal ???

0
 
andy06Author Commented:
I wanted to say it doesn't matter if I use SendMessage(WM_DISPLAYIMAGE, 0, 0) or  PostMessage(WM_DISPLAYIMAGE, 0, 0) I will still have to add the statements above...
0
 
alb66Commented:
Yes, it is normal. Windows need to handle the WM_PAINT message in order to draw something.
http://msdn.microsoft.com/en-us/library/dd145193(VS.85).aspx

If you must do some heavy functions you should use a worker thread
http://www.codeproject.com/KB/threads/usingworkerthreads.aspx
0

Featured Post

The 14th Annual Expert Award Winners

The results are in! Meet the top members of our 2017 Expert Awards. Congratulations to all who qualified!

  • 4
  • 4
  • 4
  • +1
Tackle projects and never again get stuck behind a technical roadblock.
Join Now