(Ebook - Pdf) Kick Ass Delphi Programming
.pdfstatements are then performed to complete the subclassing process. First, a pointer to the owner’s original WndProc is stored in OriginalWndProc. Next, SetWindowLong is used to tell Windows that the MsgReceiver’s WndProc (pointed to by NewWndProc) is the new place to send messages to the owner. Finally, a boolean (WndProcHooked) is set to indicate the subclassing process has succeeded. If the DLL loads correctly, the MsgReceiver’s RegisterIDStr method will be called, which will in turn call
RegisterWindowMessage and set the FMessageID field.
The MsgReceiver’s WndProc checks the incoming event to see if it matches FMessageID. If so, it attempts to call the handler specified in the OnIDMessage property. If the event doesn’t match FMessageID, WndProc calls the MsgReceiver’s Dispatch method. Since there are no special message handlers defined for the MsgReceiver, the event is automatically passed to the MsgReceiver’s DefaultHandler method, where we simply use CallWindowProc to pass the message to the owner’s original WndProc. We have accomplished exactly what is illustrated in Figure 15.4.
What has all this gained us? We’ve set up a pre-processing system for the form containing the MsgReceiver. Instead of having to know exactly what we’re looking for (the message ID) and what we’re going to do when we get it (the handler) at compile time, we have shifted the whole decision-making process to execution time. (In fact, we could even dynamically switch both the message ID string and the procedure chosen to handle it at any time during the program’s execution. A frightening concept.)
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. Read EarthWeb's privacy statement.
Using the same overall procedure as I had used for the MsgSender, I created a bitmap for the TMsgReceiver object. Done at last—well, almost.
Creating a Receiver Demo
“You’re really doing well,” Dinah said. “I haven’t seen our guests this interested in a long time. Even Mr. Bohacker wasn’t able to command such attention.”
I suppose I needed the encouragement. But I realized that this time I really was doing well. I couldn’t believe how well the code was coming together. And to be able to pull this off under such extreme pressure made it all the sweeter.
And I really was commanding respect. Most of the programmers were intently watching my every move, hanging on every syllable leaving my mouth. Of course, there were a few exceptions. Probably 20 or 25 old fogies were napping at any given time. The three women sitting in the last row who I thought were knitting were actually surfing the Web through a wireless link to their laptop PCs. But there was one guy that really bugged me.
“Psssst. Psssssssst.” I leaned away from the microphone, attempting to attract Dinah’s attention. She finally looked up from the copy of Weekly World News she was perusing.
“What’s with the guy in the leftmost seat in the front row?” I whispered. “He’s been sitting there this whole time, just staring off into space. I haven’t even seen him blink.”
“That’s Herbie,” she whispered back. “He’s a little, uh, you know… We just say he’s in Permanent Screen Saver mode.”
I pulled the candy bar out of my pocket and tore off the wrapper. I still had two applications to write, and I was in need of some extra energy. I bit off the end of the bar and nearly gagged. The Foo Bar was the candy confection universally chosen by programmers worldwide. Its delicate balance of fat calories, sugar, and caffeine made it the perfect productivity snack food. Today I had grabbed a Foo Bar++ from the machine, thinking it would have even more of the ingredients my body needed to make it through this endless afternoon. It wasn’t until I had snarfed a big bite that I realized the ingredient that had been added for extra boost was ground dried prunes. I took a gulp of water from the glass perched on the lectern and then shoved the remainder of the bar back in my pocket.
With the component design complete, I needed to create a demo application for each component—two programs that would highlight most of the features of the components.
From the several suggestions pitched at me by the audience, I chose a scenario where a sender application would send predetermined codes to a receiver, causing it to set a series of indicators. We decided to emulate the little lights on some automobile odometers that indicate when you should change your oil or filter, or rotate your tires. The receiver demo app would illuminate red or green indicators to indicate the condition, as transmitted by a sender app. In fact, we
could have multiple instances of both sender and receiver apps if we wished; the methods we had chosen for communication should support that concept.
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. Read EarthWeb's privacy statement.
{ Status codes } mdNoReply = 0; mdReady = 1; mdSuccess = 2; mdRcvChange = 3;
implementation
end.
Creating the Receiver demo was a breeze. A picture of the design version, next to the Object Inspector, is shown in Figure 15.5. The code is shown in Listing 15.8.
FIGURE 15.5 The Receiver demo at design time.
Listing 15.8 Code for the Receiver demo
{———————————————————————————————————————————————————}
{ |
Message Broadcasting in Delphi 2 |
} |
{ |
RECVMAIN.PAS : Receiver Main Form |
} |
{ |
By Ace Breakpoint, N.T.P. |
} |
{ |
Assisted by Don Taylor |
} |
{ |
|
} |
{ This demo application receives commands from |
} |
|
{ the Sender application, through the use of the |
} |
|
{ MsgSender and MsgReceiver components. |
} |
|
{ |
|
} |
{ Written for *Kick-Ass Delphi Programming* |
} |
|
{ Copyright (c) 1996 The Coriolis Group, Inc. |
} |
|
{ |
Last Updated 5/2/96 |
} |
{———————————————————————————————————————————————————}
unit RecvMain;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ExtCtrls, MsgRcvr, Constant;
type
TReceiverForm = class(TForm) ExitBtn: TButton; MsgReceiver1: TMsgReceiver; Panel2: TPanel;
HndLabel: TLabel;
Label2: TLabel; RcvNumLabel: TLabel; Label1: TLabel; Panel1: TPanel;
end;
end.
The centerpiece of the Receiver demo is the MsgReceiverIDMessage method. This is the handler specified in the OnIDMessage property of the MsgReceiver component. MsgReceiverIDMessage tests the wParam portion of the message to set the colors of the three indicators. It then returns a message result of mdSuccess, which will be returned to the MsgSender component issuing the command.
I could have simply defined a string constant for the IDString property of the MsgSender and MsgReceiver components in my Constants unit, and then assigned the string to the properties of each of the components at runtime. I guess after all this mysterious mumbo-jumbo, I was overcome by a fit of conformity to the standard way of doing things.
To demonstrate the ability of a MsgReceiver to get the index number assigned by the DLL, I displayed ReceiverNum in the top panel of the Receiver form. I also displayed the form’s handle value, the same value that would be registered by the DLL.
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. Read EarthWeb's privacy statement.
“That was Brad, our Chief of Janitors,” she explained. “He’s looking for Eddie Rivers, one of our, well, problem guests.”
“A man with a problem? Doesn’t sound at all unusual. Everybody here seems to have some problem or another.”
“Not Eddie. His is a recurring problem. Error 212: Stream registration error. It happened three times, yesterday alone.”
I turned to face the audience. The crowd had once again quieted down, and it was now time for the final piece of this whole puzzle—a demo that would transmit commands to the Receiver demo. But I wanted the Sender demo to be much more. After all, I was up against Bohacker again, and my reputation was on the line. I had to perform Big Time.
I decided to pop a timer on the form, to force a periodic query of what the DLL had registered. By monitoring that information, I could pull off some pretty cute stuff. A snapshot of the design version of the form is shown in Figure 4.6. The final version of the code is detailed in Listing 15.9.
FIGURE 15.6 The Sender demo at design time.
Listing 15.9 Code for the Sender demo
{———————————————————————————————————————————————————}
{ |
Message Broadcasting in Delphi 2 |
} |
{ |
SENDMAIN.PAS : Sender Main Form |
} |
{ |
By Ace Breakpoint, N.T.P. |
} |
{ |
Assisted by Don Taylor |
} |
{ |
|
} |
{ This demo application sends commands to the |
} |
|
{ Receiver application, through the use of the |
} |
|
{ MsgSender and MsgReceiver components. |
} |
|
{ |
|
} |
{ Written for *Kick-Ass Delphi Programming* |
} |
|
{ Copyright (c) 1996 The Coriolis Group, Inc. |
} |
|
{ |
Last Updated 3/31/96 |
} |
{———————————————————————————————————————————————————}
unit SendMain;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, MsgSendr, ExtCtrls, Constant;
type
TSenderMainForm = class(TForm) SendBtn: TButton;
ExitBtn: TButton; MsgSender1: TMsgSender; RefreshTimer: TTimer; RecipientGroup: TGroupBox; AllRB: TRadioButton; OneRB: TRadioButton;