From: Glenn W M. <gwm...@gm...> - 2007-02-16 22:33:05
|
I think I just answered my own question :-) The parent combobox gets a CBN_EDITCHANGE event when the text in the edit control changes. That event doesn't appear to be implemented in Win32::GUI, but it can be "hooked" with the following line: $mw->cb->Hook(CBN_EDITCHANGE,\&CB_Change); Again, the CBN_EDITCHANGE constant isn't exported by Win32::GUI::Constants (maybe these are considered internal and are purposely not exported), but its value is 5. I also notice that there is a method to get the edit control handle by using the ComboboxEx control. Glenn _____ From: Glenn W Munroe [mailto:gwmunroe @ gmail.com] Sent: 16 February 2007 19:15 To: per...@li... Subject: "Smart" Combobox I've been trying to implement a "smart" combobox dropdown list. To get an idea of what I'm talking about, compare the font dropdowns in Wordpad and Word. In Wordpad, type "ar" into the control and "ar" is what you see. Tab away of the control and it gets replaced with "Arial". That is easy enough to implement and is shown in the example below. In Word, the behaviour is slightly more sophisticated. Type "ar" and you see "Arial", with the final three letters highlighted. This is what I'm trying to emulate. Again, it would be easy enough if I could get the "change" notification from the underlying edit control, but I can't see how to do that. I guess the first question is if this is a built-in behaviour of the combobox that I'm missing? Assuming it's not, I started by getting the handle of the edit control. That is easy enough, and its validity can be seen by the line in the combobox "GotFocus" event. I then tried to "hook" the change event, but it doesn't work (incidentally, should those EN_ constants be defined in Win32::GUI::Constants?) I assume the problem is that the control is not owned directly by Win32::GUI. Does anyone have any ideas? I would have thought that an ability to "hook" events for non-owned windows would be useful in other situations. Cheers, Glenn ============================================================================ ===================== #!perl -w use Win32::GUI(); use Win32::GUI::Constants qw(/^GW_/); use constant EN_CHANGE => 768; my ($hCB, $hED, $hTX); $mw = new Win32::GUI::Window( -name => "mw", -title => "ComboBox Test", -pos => [100, 100], -size => [200, 200], -dialogui => 1, ); $mw->AddCombobox( -name => "cb", -size => [170, 110], -pos => [10, 20], -vscroll => 1, -dropdown => 1, -tabstop => 1, -onGotFocus => sub { Win32::GUI::Text($hCB,"Test"); 1 }, -onLostFocus => sub { if ((my $i = $mw->cb->FindString($mw->cb->Text)) >= 0) { $mw->cb->Text($mw->cb->GetString($i)) } 1 }, ); foreach (sort qw(Red Green Blue Yellow Black White)) { $mw->cb->AddString($_) } $mw->cb->SetExtendedUI(1); # Down arrow to drop down list $mw->AddTextfield( -name => "tx", -size => [154, 24], -left => 10, -top => 50, -tabstop => 1, ); sub CB_Change { print "CB Change\n" } sub TX_Change { print "TX Change\n" } $hCB = $mw->cb->{-handle}; $hED = $mw->cb->GetWindow(GW_CHILD); $hTX = $mw->tx->{-handle}; print "Combobox control's handle is $hCB\n"; print "Combobox edit control's handle is $hED\n"; print "Textfield control's handle is $hTX\n"; $mw->tx->Hook(EN_CHANGE,\&TX_Change); Win32::GUI::Hook($hCB,EN_CHANGE,\&CB_Change); $mw->Show(); Win32::GUI::Dialog(); |
From: Glenn W M. <gwm...@gm...> - 2007-02-19 16:31:46
|
.and for the record, here is the finished example, using the Hook mentioned below. #!perl -w use Win32::GUI(); use Win32::GUI::Constants qw(:window /^GW_/); use constant CBN_EDITCHANGE => 5; $mw = new Win32::GUI::Window( -name => "mw", -title => "Smart Combobox", -pos => [100, 100], -size => [200, 200], -dialogui => 1, ); $mw->AddCombobox( -name => "cb", -size => [170, 110], -pos => [10, 20], -vscroll => 1, -dropdown => 1, -tabstop => 1, -onGotFocus => \& cbGotFocus, ); foreach (sort qw(Red Green Blue Yellow Black White Purple Orange Brown)) { $mw->cb->AddString($_) } $mw->cb->SetExtendedUI(1); # Down arrow to drop down list $mw->cb->UserData( {iLenght => 0} ); $mw->AddTextfield( -name => "tx", -size => [154, 24], -left => 10, -top => 50, -tabstop => 1, ); $mw->cb->Hook(CBN_EDITCHANGE,\&cbEditChange); $mw->Show(); Win32::GUI::Dialog(); sub cbEditChange { my ($hObject, $wParam, $lParam, $iType, $iMsgCode) = @_; return 1 unless $iType == WM_COMMAND; my $szText = $mw->cb->Text; my $bPredict = 1 if (length($szText) > $mw->cb->UserData->{iLength}); $mw->cb->UserData->{iLength} = length($szText); if ($bPredict) { my $iIndex = length($szText); if ((my $i = $mw->cb->FindString($szText)) >= 0) { $mw->cb->Text($mw->cb->GetString($i)); $mw->cb->SetEditSel($iIndex,-1); } } 1; } sub cbGotFocus { $mw->cb->UserData->{iLength} = 0; 1;} sub cbChange { $mw->cb->UserData->{iLength} = 0; 1;} _____ From: Glenn W Munroe [mailto:gwmunroe @ gmail.com] Sent: 16 February 2007 19:36 To: per...@li... Subject: RE: "Smart" Combobox I think I just answered my own question :-) The parent combobox gets a CBN_EDITCHANGE event when the text in the edit control changes. That event doesn't appear to be implemented in Win32::GUI, but it can be "hooked" with the following line: $mw->cb->Hook(CBN_EDITCHANGE,\&CB_Change); Again, the CBN_EDITCHANGE constant isn't exported by Win32::GUI::Constants (maybe these are considered internal and are purposely not exported), but its value is 5. I also notice that there is a method to get the edit control handle by using the ComboboxEx control. Glenn _____ From: Glenn W Munroe [mailto:gwmunroe @ gmail.com] Sent: 16 February 2007 19:15 To: per...@li... Subject: "Smart" Combobox I've been trying to implement a "smart" combobox dropdown list. To get an idea of what I'm talking about, compare the font dropdowns in Wordpad and Word. In Wordpad, type "ar" into the control and "ar" is what you see. Tab away of the control and it gets replaced with "Arial". That is easy enough to implement and is shown in the example below. In Word, the behaviour is slightly more sophisticated. Type "ar" and you see "Arial", with the final three letters highlighted. This is what I'm trying to emulate. Again, it would be easy enough if I could get the "change" notification from the underlying edit control, but I can't see how to do that. I guess the first question is if this is a built-in behaviour of the combobox that I'm missing? Assuming it's not, I started by getting the handle of the edit control. That is easy enough, and its validity can be seen by the line in the combobox "GotFocus" event. I then tried to "hook" the change event, but it doesn't work (incidentally, should those EN_ constants be defined in Win32::GUI::Constants?) I assume the problem is that the control is not owned directly by Win32::GUI. Does anyone have any ideas? I would have thought that an ability to "hook" events for non-owned windows would be useful in other situations. Cheers, Glenn ============================================================================ ===================== #!perl -w use Win32::GUI(); use Win32::GUI::Constants qw(/^GW_/); use constant EN_CHANGE => 768; my ($hCB, $hED, $hTX); $mw = new Win32::GUI::Window( -name => "mw", -title => "ComboBox Test", -pos => [100, 100], -size => [200, 200], -dialogui => 1, ); $mw->AddCombobox( -name => "cb", -size => [170, 110], -pos => [10, 20], -vscroll => 1, -dropdown => 1, -tabstop => 1, -onGotFocus => sub { Win32::GUI::Text($hCB,"Test"); 1 }, -onLostFocus => sub { if ((my $i = $mw->cb->FindString($mw->cb->Text)) >= 0) { $mw->cb->Text($mw->cb->GetString($i)) } 1 }, ); foreach (sort qw(Red Green Blue Yellow Black White)) { $mw->cb->AddString($_) } $mw->cb->SetExtendedUI(1); # Down arrow to drop down list $mw->AddTextfield( -name => "tx", -size => [154, 24], -left => 10, -top => 50, -tabstop => 1, ); sub CB_Change { print "CB Change\n" } sub TX_Change { print "TX Change\n" } $hCB = $mw->cb->{-handle}; $hED = $mw->cb->GetWindow(GW_CHILD); $hTX = $mw->tx->{-handle}; print "Combobox control's handle is $hCB\n"; print "Combobox edit control's handle is $hED\n"; print "Textfield control's handle is $hTX\n"; $mw->tx->Hook(EN_CHANGE,\&TX_Change); Win32::GUI::Hook($hCB,EN_CHANGE,\&CB_Change); $mw->Show(); Win32::GUI::Dialog(); |
From: Glenn W M. <gwm...@gm...> - 2007-02-19 19:43:33
|
...and thanks to you for the feedback. It's hard to know sometimes if this kind of stuff might be useful to someone, or if I'm just filling the list up with garbage. There was a slight error in the example, by the way! I forgot the line -onChange => \& cbChange, in the combobox definition. All the best, Glenn2 > -----Original Message----- > From: Glenn Linderman [mailto:perl@NevCal.com] > Sent: 19 February 2007 16:35 > To: Glenn W Munroe > Cc: per...@li... > Subject: Re: [perl-win32-gui-users] "Smart" Combobox > > On approximately 2/19/2007 8:34 AM, came the following characters from > the keyboard of Glenn W Munroe: > > > > .and for the record, here is the finished example, using the Hook > > mentioned below. > > > > Thanks for figuring this out. It looks good to me! I'm adding that to my > personal "goody box" :) > > > -- > Glenn -- http://nevcal.com/ > =========================== > A protocol is complete when there is nothing left to remove. > -- Stuart Cheshire, Apple Computer, regarding Zero Configuration > Networking |
From: Robert M. <rm...@po...> - 2007-02-26 21:16:00
|
Nice indeed. I saw your original message before I went away last week, and came up with a slightly different solution on the plane. I'll add the EN_ and CBN_ constant definitions to Win32::GUI::Constants. I also note what you say about wanting to hook the edit control and listbox control in the combobox - but I don't think it'd be trivial to add. Regards, Rob. #!perl -w use strict; use warnings; use Win32::GUI 1.05 qw(CW_USEDEFAULT WM_COMMAND VK_BACK VK_DELETE); sub CB_ERR() {-1} sub CBN_EDITUPDATE() {6} my $mw = Win32::GUI::DialogBox->new( -title => 'Drop-Down', -left => CW_USEDEFAULT, -size => [400,300], ); my $cb = $mw->AddCombobox( -dropdown => 1, -size => [100,100], ); $cb->Hook(CBN_EDITUPDATE, \&autocomplete); $cb->Add( sort qw(Red Green Blue Yellow Black White Purple Orange Brown) ); $cb->SetFocus(); $mw->Show(); Win32::GUI::Dialog(); $mw->Hide(); exit(0); sub autocomplete { my ($self, $wparam, $lparam, $type, $msgcode) = @_; return unless $type == WM_COMMAND; return unless $msgcode == CBN_EDITUPDATE; # Prevent matching for Backspace and Delete keys return if Win32::GUI::GetKeyState(VK_BACK); return if Win32::GUI::GetKeyState(VK_DELETE); # Get the text from the edit control my $edit_text = $self->Text(); my $edit_len = length($edit_text); # Get the current selection my ($start, $end) = $self->GetEditSel(); if($self->SelectString($edit_text) == CB_ERR) { # No match, restore text and selection $self->Text($edit_text); $self->SetEditSel($start, $end); } else { # Found match, SelectString changed the text for us if($end < $edit_len) { # We were editing in the middle of the string, # so keep the selection point $self->SetEditSel($start, $end); } else { # Select the added characters $self->SetEditSel($edit_len, -1); } } return 0; } __END__ Glenn W Munroe wrote: > ...and thanks to you for the feedback. It's hard to know sometimes if this > kind of stuff might be useful to someone, or if I'm just filling the list up > with garbage. > > There was a slight error in the example, by the way! I forgot the line > > -onChange => \& cbChange, > > in the combobox definition. > > All the best, > Glenn2 > >> -----Original Message----- >> From: Glenn Linderman [mailto:perl@NevCal.com] >> Sent: 19 February 2007 16:35 >> To: Glenn W Munroe >> Cc: per...@li... >> Subject: Re: [perl-win32-gui-users] "Smart" Combobox >> >> On approximately 2/19/2007 8:34 AM, came the following characters from >> the keyboard of Glenn W Munroe: >>> .and for the record, here is the finished example, using the Hook >>> mentioned below. >>> >> Thanks for figuring this out. It looks good to me! I'm adding that to my >> personal "goody box" :) >> >> >> -- >> Glenn -- http://nevcal.com/ >> =========================== >> A protocol is complete when there is nothing left to remove. >> -- Stuart Cheshire, Apple Computer, regarding Zero Configuration >> Networking > > > ------------------------------------------------------------------------- > Take Surveys. Earn Cash. Influence the Future of IT > Join SourceForge.net's Techsay panel and you'll get the chance to share your > opinions on IT & business topics through brief surveys-and earn cash > http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV > _______________________________________________ > Perl-Win32-GUI-Users mailing list > Per...@li... > https://lists.sourceforge.net/lists/listinfo/perl-win32-gui-users > http://perl-win32-gui.sourceforge.net/ > |