![]() |
![]() |
![]() |
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() |
![]() |
![]() |
To access the contents, click the chapter and section titles.
Cutting Edge Direct 3D Programming
Event HandlersAn event handler is a function that you write and then register with Windows. After your event handler is registered, each message that has been dispatched via DispatchMessage is sent to your event handler. A typical event handler contains a switch statement with a case for each message that is to be handled. Messages that are not handled are usually passed on to the default Windows event handler. A simple event handler looks like this: long WINAPI WndProc( HWND hWnd, UINT msg, UINT wParam, LONG lParam ) { switch( msg ) { case WM_KEYDOWN: // code to handle key presses goes here break; case WM_MOUSEMOVE: // code to handle mouse movements goes here break; default: // if we dont handle the message let Windows handle it return DefWindowProc( hWnd, msg, wParam, lParam ); } return 0; } The event handler construct is powerful because it allows you to intercept messages before Windows gets them. You can react to any event that goes through your event handler by adding a case statement to your event handler. On the other hand, the fact that every possible message is handled by one function makes for ugly code. Traditional Windows programs (including the sample programs that come with DirectX) often have massive event handlers that go on for hundreds of lines. An alternative is to write a separate event handler function for each event and then call the function from your event handler. This is often preferable because it allows you to write a set of small, reasonably sized event handlers instead of one huge, complicated event handler. MFC uses this later technique, but with one significant improvement: message maps. Message MapsRemember that MFC is designed to insulate the programmer from some of the messy details of Windows programming. MFC insulates you from the event handler by supplying its own, and then calling individual handlers that you supply. This is accomplished with message maps. A message map is a macro that tells MFC you are interested in handling a specific message. All you have to do is include a message map and an event handler in your code, and MFC takes care of the rest. A message map looks like this: BEGIN_MESSAGE_MAP(OurClass, BaseClass) ON_WM_PAINT() ON_WM_SIZE() ON_WM_LBUTTONDOWN() END_MESSAGE_MAP() This message map tells MFC that you have a class called OurClass that is derived from BaseClass. OurClass will be handling three messages: WM_PAINT, WM_SIZE, and WM_LBUTTONDOWN (these message are standard Windows messages). Now you need to supply an event handler function for each message. The WM_PAINT message handler, for example, would look this way: void OurClass::OnPaint() { // respond to the WM_PAINT message here } Finally, the event handlers must be declared within the class. The three event handlers that we are using as examples might look like this: class OurClass : public BaseClass { protected: afx_msg void OnPaint(); afx_msg void OnSize(UINT type, int cx, int cy); afx_msg void OnLButtonDown( UINT state, CPoint point ); DECLARE_MESSAGE_MAP() }; The afx_msg macro identifies the functions as event handlers, and the DECLARE_MESSAGE_MAP macro notifies MFC that this class uses message maps. ClassWizardMessage maps are great because they simplify event handling, but Visual C++ makes them even easier to use with ClassWizard. ClassWizard is a tool within the Visual C++ Developer Studio that allows you to add, remove, and edit event handlers. Figure 1.2 shows the ClassWizard dialog.
From ClassWizard, you select the message that you are interested in handling and then click the Add Function button. ClassWizard installs a do-nothing event handler that you can then modify to your own specifications. ClassWizard makes the addition of event handlers as easy as it possibly can be because the handlers that it installs are ready to compile. The only missing ingredient is your code. The code that ClassWizard adds to your project is a little different than the message map code that we discussed earlier. For example, if you installed the previous message handlers with ClassWizard, the message map would look like this: BEGIN_MESSAGE_MAP(OurClass, BaseClass) //{{AFX_MSG_MAP(OurClass) ON_WM_PAINT() ON_WM_SIZE() ON_WM_LBUTTONDOWN() //}}AFX_MSG_MAP END_MESSAGE_MAP() The difference is that ClassWizard inserts text elements that act as bookmarks. To the compiler, these bookmarks appear as comments, but to ClassWizard they indicate the location of the message maps within your source code. You can delete the marks and the code will still compile, but you will no longer be able to edit your message maps with ClassWizard. ClassWizard can also be used to remove event handlers. When you remove a handler with ClassWizard, the message map and the function declaration are removed. It is up to you to remove the actual function body. Well use ClassWizard later in this chapter. AppWizardsWhile ClassWizard makes it easy to modify projects, AppWizards make it easy to create projects in the first place. Visual C++ includes an AppWizard, for example, that allows you to create new MFC projects. If you activate this Wizard, you are presented with a series of dialogs that ask what kind of MFC application you would like. Visual C++ includes several different AppWizards: one for creating MFC applications, another for console applications, another for creating DLLs, and so on. The best thing about starting a project with an AppWizard is that the new projects are usually ready to compile. You dont have to add anything in order to compile and test it. By producing a ready-to-compile project, AppWizard saves you the frustration of finding yourself with a large body of unfamiliar code that doesnt compile.
|
![]() |
Products | Contact Us | About Us | Privacy | Ad Info | Home
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-2000 EarthWeb Inc. All rights reserved. Reproduction whole or in part in any form or medium without express written permission of EarthWeb is prohibited. |