[Last Call] Learn about multicloud storage options and how to improve your company's cloud strategy. Register Now

x
?
Solved

Determining Handle and WM_CopyData Messages...

Posted on 2006-06-11
8
Medium Priority
?
689 Views
Last Modified: 2011-10-03
This is really a two part question...

I am writing an app that interfaces with a piece of hardware through a DLL written by the manufacturer. I have no problem with the GUI or loading the DLL, etc... What I'm having issues with is the concept of communicating using WM_CopyData messages. I'm learning as fast as I can, but my deadline doesn't allow this learning curve :) Oh, I'm using VC++ Express if that makes any difference. I had a FULLY FUNCTIONAL example written in VC++ 2003, but that is another story why I'm not using that...

First question... One of the parameters the manufacturer's function is asking for is the "window handle that will receive the WM_CopyData messages." How in the world do I determine that? I'm assuming I need the handle that calls the WndProc function in my app, but don't know how to get that handle.

Secondly... This whole WM_CopyData business; is the WndProc function established by default as the message handler without any intervention by me? I have created the function with knowledge I picked up around the net and I believe it to be right or close enough... The function is as follows:

protected: void WndProc(Message* m)
               toolStripStatusLabel1->Text = "Processing incoming message.../n";
               if (m->Msg == WM_COPYDATA)
               {
                   COPYDATASTRUCT* CopyData = reinterpret_cast <COPYDATASTRUCT*> (m->LParam.ToPointer());
                   int DataType = CopyData->dwData;
                   int DataSize = CopyData->cbData;
                   switch (DataType)  // determine type of message from DLL
                   {

                   ...

              }
               else
                     {
                   Form1::WndProc(m);
                     }
           }

What I am also curious about is why do I never see the "Processing Incoming Message..." that I have being displayed on my status label? Also, the examples I'm working on show the "else" argument as __super::WndProc(m); but that will not compile. What in the world is a __super? When I switch it to Form1 it compiles nicely.

Your help would be appreciated. I'm offering 500 points here because I'm dumb and you'll have to deal with me and also I've searched all over for these answers and can't find them.
0
Comment
Question by:demilune
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 5
  • 3
8 Comments
 
LVL 48

Expert Comment

by:AlexFM
ID: 16880143
Pass form handle to manufacturer's function:

Function((HWND)this->Handle.ToPointer());

To handle WM_COPYDATA message, override FormWndProc function - you already have this code.
0
 
LVL 48

Expert Comment

by:AlexFM
ID: 16880158
Notice that form handle is valid when form is loaded (starting from Load message). Don't try to use Handle property before form is loaded.
About your second question: WndProc is form message handler which works in any Windows form. You can override this function to handle some messages, if this is necessary.
Instead of Form1::WndProc use Form::WndProc, because your class is derived from the Form calss. Form1::WndProc causes endless recursion.
0
 

Author Comment

by:demilune
ID: 16882070
When I change the Form1::WndProc to Form::WndProc I get the following error:

           error C2664: 'void System::Windows::Forms::Control::WndProc(System::Windows::Forms::Message %)' : cannot convert parameter 1
           from 'System::Windows::Forms::Message *' to 'System::Windows::Forms::Message %'

Also, I believe I'm doing the handle correctly now, but I never get any response from the WndPrc function. I have:

            toolStripStatusLabel1->Text = "Processing incoming message.../n";

at the top of WndPrc and figure if it enters that function, that will be displayed, but it never does. So, I must still have something wrong.

Here is how I'm calling the manufacturer's function...

            OmniConnect(IpAddress,Port,Timeout,BinKey,(HWND)this->Handle.ToPointer());

I know it's getting called cause I see the network traffic and a response from the device, but nada on the message handling side of things. Does the (HWND)... call have to be somewhere specific in the class? Right now, I'm calling it from a form button function which is outside the WndPrc function.

Thanks for the help...

0
Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
LVL 48

Accepted Solution

by:
AlexFM earned 2000 total points
ID: 16883371
virtual void WndProc( Message% m ) override
{
     ...
     Form::WndProc( m );
}
0
 

Author Comment

by:demilune
ID: 16883405
When changing those lines, I now get a bunch of compiler errors... Here is the code and the errors associated with it. Any ideas?

//protected: void WndProc(Message* m)
virtual void WndProc(Message% m) override
{
      toolStripStatusLabel1->Text = "Processing incoming message.../n";
               if (m->Msg == WM_COPYDATA)
               {
                   COPYDATASTRUCT* CopyData = reinterpret_cast <COPYDATASTRUCT*> (m->LParam.ToPointer());
                   int DataType = CopyData->dwData;
                   int DataSize = CopyData->cbData;
                   switch (DataType)
                   {
                   case haiCONNECTED:
                       SetConnectedState();
                       break;
                   case haiDISCONNECTED:
                       SetDisconnectedState();
                       break;
                   case haiTEXT:
                       if(DataSize > 0)
                       {
                           char* Msg = new char[DataSize];
                           memcpy(Msg, CopyData->lpData, DataSize);
                                       Memo1->AppendText(gcnew String(Msg));
                           Memo1->AppendText("\r\n");
                           delete [] Msg;
                       }
                       else
                       {
                           Memo1->AppendText("[NULL]\r\n");
                       }
                       break;
                   case haiMESSAGE_RESPONSE:
                       if(DataSize > 0)
                       {
                           if(DataSize < sizeof(R_OMNI_LINK_MESSAGE))
                           {
                               R_OMNI_LINK_MESSAGE Msg;
                               Msg.MessageLength = DataSize;
                               memcpy(&Msg.MessageType, CopyData->lpData, DataSize);
                               switch (Msg.MessageType)
                               {
                               case olmSYSTEM_INFORMATION: ProcessSystemInformation(Msg); break;
                               case olmZONE_STATUS: ProcessZoneStatus(Msg); break;
                               case olmACK: ProcessACK(); break;
                               case olmNAK: ProcessNAK(); break;
                               default:
                                   toolStripStatusLabel1->Text = Msg.MessageType.ToString();
                                   break;
                               }
                           }
                           else
                           {
                               Memo1->AppendText("<Omni-Link message too big!>\r\n");
                           }
                       }
                       else
                       {
                           Memo1->AppendText("<NULL>\r\n");
                       }
                       break;
                   default:
                       Memo1->AppendText(DataType.ToString());
                       Memo1->AppendText("\r\n");
                       break;
                   }  // switch
               }
               else
                     {
                   Form::WndProc(m);
                     }
           }

the errors...

Form1.h(384) : warning C4486: 'OmniMonitor::Form1::WndProc' : a private virtual method of a ref class or value class should be marked 'sealed'
Form1.h(384) : error C3252: 'OmniMonitor::Form1::WndProc' : cannot reduce accessibility of a virtual method in a managed type
Form1.h(387) : error C2819: type 'System::Windows::Forms::Message' does not have an overloaded member 'operator ->'
        c:\windows\microsoft.net\framework\v2.0.50727\system.windows.forms.dll : see declaration of 'System::Windows::Forms::Message'
        did you intend to use '.' instead?
Form1.h(387) : error C2232: '->System::Windows::Forms::Message::Msg' : left operand has 'class' type, use '.'
Form1.h(389) : error C2819: type 'System::Windows::Forms::Message' does not have an overloaded member 'operator ->'
        c:\windows\microsoft.net\framework\v2.0.50727\system.windows.forms.dll : see declaration of 'System::Windows::Forms::Message'
        did you intend to use '.' instead?
Form1.h(389) : error C2232: '->System::Windows::Forms::Message::LParam' : left operand has 'class' type, use '.'
Form1.h(389) : error C2228: left of '.ToPointer' must have class/struct/union

Thanks...
0
 
LVL 48

Expert Comment

by:AlexFM
ID: 16883438
Make this function protected, this must solve first two errors.
About other messages: I don't have line numbers, add notes to program text to see what lines are incorrect.
0
 
LVL 48

Expert Comment

by:AlexFM
ID: 16883443
Notice that function parameter is reference and not pointer, use "." instead of "->", this is written in the compiler messages.
0
 

Author Comment

by:demilune
ID: 16883465
THANK YOU THANK YOU THANK YOU THANK YOU THANK YOU THANK YOU THANK YOU THANK YOU THANK YOU THANK YOU THANK YOU THANK YOU THANK YOU THANK YOU THANK YOU THANK YOU THANK YOU THANK YOU THANK YOU THANK YOU

Works perfectly... Four nights up until 5am every night and it works... Thanks again!!!
0

Featured Post

Enroll in October's Free Course of the Month

Do you work with and analyze data? Enroll in October's Course of the Month for 7+ hours of SQL training, allowing you to quickly and efficiently store or retrieve data. It's free for Premium Members, Team Accounts, and Qualified Experts!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

The following diagram presents a diamond class hierarchy: As depicted, diamond inheritance denotes when two classes (e.g., CDerived1 and CDerived2), separately extending a common base class (e.g., CBase), are sub classed simultaneously by a fourt…
In Easy String Encryption Using CryptoAPI in C++ (http://www.experts-exchange.com/viewArticle.jsp?aid=1193) I described how to encrypt text and recommended that the encrypted text be stored as a series of hexadecimal digits -- because cyphertext may…
This course is ideal for IT System Administrators working with VMware vSphere and its associated products in their company infrastructure. This course teaches you how to install and maintain this virtualization technology to store data, prevent vuln…
This lesson discusses how to use a Mainform + Subforms in Microsoft Access to find and enter data for payments on orders. The sample data comes from a custom shop that builds and sells movable storage structures that are delivered to your property. …

650 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question