Board index » cppbuilder » FilterComboBox's OnChange event handler called twice?

FilterComboBox's OnChange event handler called twice?

Quote
Wlodek Szafran wrote:

> Hi all,

> In one of my BCB4 projects, I have a form with, among others, a
> FilterComboBox. After setting a breakpoint inside the OnChange event
> handler, I discovered that the handler is being called twice for every
> change in that box. Does anybody know why is this happening, and how
> could this be changed?

If you are seeing this in BCB 4 it's because Borland failed to fix the
bug they confirmed in my BCB 3 Bug report.

Quote
> This behaviour introduces an unnecessary delay -
> I'm calling a lengthy procedure from that event handler and everything
> is taking twice as long as it should be.

I had a different reason for working around this problem. I think my
workaround will work for your purpose as well, with a modification.

Read on.

===================================================================
Repost (several months old)  
PS:  This bug confirmed by Borland in BCB3

Bug: TDriveComboBox OnChange gets fired twice per drive change

The call stack shows the following calls in sequence when
TDriveComboBox responds to a user's selection of a new drive.

FileCtrl::TDriveComboBox.SetDrive    <-
FileCtrl::TDriveComboBox.Click
StdCtrls::TCustomComboBox.CNCommand  <-

Each of the calls marked with an arrow call
StdCtrls::TCustomComboBox.Change.

This means the following:

1.  If the user drops down the listbox and selects the currently
selected drive, CNCommand calls Change, but SetDrive does not because
SetDrive checks to see if a change was actually made.  Thus a selection
of the same drive produces one firing of OnChange (in C++ code).  Wrong.

2.  If the user changes the drive, both CNCommand and SetDrive call
Change. This results in two firings of OnChange (in C++ code) when there
was but single change to the drive. Wrong.

Although inefficient, this action is probably not a problem in 99.9 of
applications.

There is a problem, however, when one attempts to trap an access to an
empty CD-ROM or floppy drive. Normally programmers will not trap this,
causing Builder to display an Dialog Box with the message "I/O  Error
21". Not very informative to the user. Users wishing to trap the error
can do the following in the OnChange event:

==============
char temp = ComboBoxDrive->Drive;
String Test(&temp, 1);
String Ouch = "Unable to access drive " +Test;
Test += ":\\";

try
{
   if (!DirectoryExists(Test))
         throw Exception(Ouch);

Quote
}

catch (Exception & e)
{
  Application->MessageBox(e.Message.c_str(), "Whoops", MB_OK);
Quote
}

 =============

Unfortunately, because of the double firing of OnChange, the user will
get two message boxes, one after the other.

The final workaround is to make a member variable in the form

======================
char lastDrive;

Set lastDrive to 0 in the form constructor.

try
{
    if (!DirectoryExists(Test))
           throw Exception("Ouch");

Quote
}

catch (Exception & e)
{
    // ignore spurrious OnChange calls
    if (temp != lastDrive)
        Application->MessageBox(e.Message.c_str(), "Whoops", MB_OK);
Quote
}

// update current drive
lastDrive = temp;

=================

 

Re:FilterComboBox's OnChange event handler called twice?


Hi all,

In one of my BCB4 projects, I have a form with, among others, a
FilterComboBox. After setting a breakpoint inside the OnChange event
handler, I discovered that the handler is being called twice for every
change in that box. Does anybody know why is this happening, and how
could this be changed? This behaviour introduces an unnecessary delay -
I'm calling a lengthy procedure from that event handler and everything
is taking twice as long as it should be.

Thanks in advance for your assistance.

Regards.
--
Wlodek (a.k.a. Tony) Szafran

Re:FilterComboBox's OnChange event handler called twice?


Hi Steve,

thanks for replying, but I was actually asking about the FilterComboBox,
not the DriveComboBox. It looks that both of them share the same
problem. But please read on.

Quote
Steve Rogers wrote:

> If you are seeing this in BCB 4 it's because Borland failed to fix the
> bug they confirmed in my BCB 3 Bug report.

I just checked that and, indeed, the event handler being called twice
also happens for the DriveComboBox in BCB4.

Quote
> [cut]
> There is a problem, however, when one attempts to trap an access to an
> empty CD-ROM or floppy drive. Normally programmers will not trap this,
> causing Builder to display an Dialog Box with the message "I/O  Error
> 21". Not very informative to the user. Users wishing to trap the error
> can do the following in the OnChange event:

> [cut]

Instead of using the OnChange event, you could trap the CBN_CLOSEUP
notification message from the DriveComboBox. For that, you need to
provide a handler for the WM_COMMAND Windows messages. This method was
proposed by Damon Chandler not so long ago, I'm sure you can still find
his original message using Deja.com, for example. The point here is that
before the change in the DriveComboBox really happens - you'll be able
to know which drive was selected and you can easily find out if it's a
floppy or a CD-ROM drive.

As to my twice-called event handler problem, I'm going to experiment
with setting/resetting a bool variable to only respond once to the
event.

Regards.
--
Wlodek (a.k.a. Tony) Szafran

Other Threads