- The simple solution. Each ComboBox can be configured as either
- -dropdown, which allow edits, or
- -dropdownlist, which does not allow edits.
Of the two, only -dropdown has the split focus issue. So, if you can just use -dropdownlist, then your problem is solved.
- The less-simple solution.
You can use Win32::API to call GetComboBoxInfo, which will give you the handles to the component controls. You can do this with straight-forward procedural code, but I chose to create a sub-class that provides the new methods GetEditControl and GetDropDownControl.
Working, tested code:
package Win32::GUI::Combobox_improved;
use strict;
use warnings;
use Win32::GUI;
use Win32::API;
our @ISA = qw( Win32::GUI::Combobox );
# API GetComboBoxInfo:
# http://msdn.microsoft.com/library/en-us/shellcc/platform/commctls/
+comboboxes/comboboxreference/comboboxfunctions/getcomboboxinfo.asp
# Struct COMBOINFO:
# http://msdn.microsoft.com/library/en-us/shellcc/platform/commctls/
+comboboxes/comboboxreference/comboboxstructures/comboboxinfo.asp
# Struct RECT:
# http://msdn.microsoft.com/library/en-us/gdi/rectangl_6cqa.asp
# Note: I have flattened the rcItem and rcButton RECT structs,
# because of bugs in Win32::API and Win32::API::Struct's
# handling of nested structs, or in my own understanding of it.
Win32::API::Struct->typedef( 'COMBOBOXINFO', qw(
DWORD cbSize;
LONG rcItem_left;
LONG rcItem_top;
LONG rcItem_right;
LONG rcItem_bottom;
LONG rcButton_left;
LONG rcButton_top;
LONG rcButton_right;
LONG rcButton_bottom;
DWORD stateButton;
HWND hwndCombo;
HWND hwndItem;
HWND hwndList;
));
Win32::API->Import("user32", <<'END_API') or die;
BOOL GetComboBoxInfo(
HWND hwndCombo,
COMBOBOXINFO * pcbi
);
END_API
sub _GetComboBoxInfo {
my ($self) = @_;
my $hwndCombo = $self->{-handle};
my $pcbi = Win32::API::Struct->new('COMBOBOXINFO');
$pcbi->{cbSize} = $pcbi->sizeof();
my $rc = GetComboBoxInfo(
$hwndCombo,
$pcbi,
);
return unless $rc;
warn unless $hwndCombo == $pcbi->{hwndCombo};
return $pcbi;
}
# Retrieves the handle to the child edit control
# portion of a ComboBox control.
sub GetEditControl {
my ($self) = @_;
my $combo_box_info = $self->_GetComboBoxInfo()
or return;
return $combo_box_info->{hwndItem};
}
# Retrieves the handle to the child drop-down control
# portion of a ComboBox control.
sub GetDropDownControl {
my ($self) = @_;
my $combo_box_info = $self->_GetComboBoxInfo()
or return;
return $combo_box_info->{hwndList};
}
package main;
use strict;
use warnings;
use Win32::GUI;
$| = 1; # Important! - Turn off buffering
my $W1 = Win32::GUI::Window->new(
-name => 'W1',
-title => 'PerlMonks_494615',
-pos => [ 100, 100 ],
-size => [ 300, 200 ],
);
my $combo_style = '-dropdown'; # Allows edits
#my $combo_style = '-dropdownlist'; # Does not allow edits
my $cb1 = Win32::GUI::Combobox_improved->new(
$W1, # Parent
-name => 'CB1',
-left => 10,
-top => 10,
-width => 125,
-height => 100,
-tabstop => 1,
$combo_style => 1,
);
my $cb2 = Win32::GUI::Combobox_improved->new(
$W1, # Parent
-name => 'CB2',
-left => 140,
-top => 10,
-width => 125,
-height => 100,
-tabstop => 1,
$combo_style => 1,
);
{
my %handle_to_parent;
foreach my $cb ( $cb1, $cb2 ) {
my $handle_cb = $cb->{-handle};
my $handle_edit = $cb->GetEditControl();
my $handle_dd = $cb->GetDropDownControl();
$handle_to_parent{ $handle_cb } = $handle_cb;
$handle_to_parent{ $handle_edit } = $handle_cb;
$handle_to_parent{ $handle_dd } = $handle_cb;
}
my %handle_to_name = (
$cb1->{-handle} => 'CB1',
$cb2->{-handle} => 'CB2',
);
sub dump_it {
my $event = (caller(1))[3];
my $focus = $W1->GetFocus();
my $true_focus = $handle_to_parent{$focus} || $focus;
my $name = $handle_to_name{$true_focus};
print "$event: focus going to $name\n";
}
}
$cb1->InsertItem($_) foreach qw(Able Baker Charlie);
$cb2->InsertItem($_) foreach qw(Roger Fox Dog);
$cb1->Select(0);
$cb2->Select(0);
$W1->Show();
Win32::GUI::Dialog();
sub CB1_GotFocus { dump_it() }
sub CB2_GotFocus { dump_it() }
sub CB1_LostFocus { dump_it() }
sub CB2_LostFocus { dump_it() }
| [reply] [d/l] [select] |
Thanks!! That is the perfect solution to my problem and even included references for the internals. Again, thanks a lot! ++
| [reply] |