gtk+gtk2+win32 intf: TComboBox: fixed LM_CHANGED, LM_SELCHANGED events, now LM_CHANGED are sent, whenever the text changes, from Luiz

git-svn-id: trunk@15831 -
This commit is contained in:
mattias 2008-07-21 21:29:07 +00:00
parent fc59aceece
commit b26fda5243
12 changed files with 172 additions and 117 deletions

View File

@ -204,11 +204,8 @@ end;
------------------------------------------------------------------------------}
procedure TCustomComboBox.Select;
begin
if ItemIndex>=0 then
if Assigned(FOnSelect) then
FOnSelect(Self)
else
Change;
if Assigned(FOnSelect) and (ItemIndex >= 0) then
FOnSelect(Self);
end;
{------------------------------------------------------------------------------

View File

@ -414,28 +414,16 @@ end;
function gtkchangedCB( widget: PGtkWidget; data: gPointer) : GBoolean; cdecl;
var
Mess : TLMessage;
AComboBox: TComboBox;
GtkComboWidget: PGtkCombo;
begin
Result := CallBackDefaultReturn;
if ComponentIsDestroyingHandle(TWinControl(Data))
or (LockOnChange(PgtkObject(Widget),0)>0) then exit;
if (TObject(Data) is TComboBox) then begin
AComboBox:=TComboBox(Data);
GtkComboWidget:=PGtkCombo(AComboBox.Handle);
if (GtkComboWidget^.popwin<>nil)
and (GTK_WIDGET_VISIBLE(GtkComboWidget^.popwin)) then begin
// Ignoring changed events during popup
//DebugLn(['gtkchangedCB Ignoring changed events during popup']);
exit;
end;
end;
{$IFDEF EventTrace}
EventTrace('changed', data);
{$ENDIF}
FillChar(Mess, SizeOf(Mess), 0);
Mess.Msg := LM_CHANGED;
DeliverMessage(Data, Mess);
end;
@ -453,8 +441,6 @@ begin
Mess.Msg := CM_TEXTCHANGED;
DeliverMessage(Data, Mess);
Result := CallBackDefaultReturn;
end;
function gtkdaychanged(Widget: PGtkWidget; data: gPointer) : GBoolean; cdecl;

View File

@ -564,6 +564,9 @@ end;
procedure TGtkListStringList.BeginUpdate;
begin
//NOTE: in TComboBox, event handling is done inside the 'changed' event
// of the entry widget. Here we are locking the main combo widget.
// Currently, there's no know bug origined from this flaw.
inc(FUpdateCount);
if (FUpdateCount=1) and (Owner<>nil) and (Owner.HandleAllocated) then
LockOnChange(PGtkObject(Owner.Handle),+1);
@ -830,7 +833,7 @@ begin
// change selection mode if needed
if (gtkListGetSelectionMode(FGtkList)=GTK_SELECTION_BROWSE)
and (FGtkList^.selection<>nil)
and (g_list_nth_data(FGtkList^.children, Index)=FGtkList^.selection) then begin
and (g_list_nth_data(FGtkList^.children, Index)=FGtkList^.selection^.data) then begin
// item is selected and BROWSE mode is enabled
// -> change selection mode to prevent, that gtk auto selects another child
gtk_list_set_selection_mode(FGtkList,GTK_SELECTION_SINGLE);
@ -855,6 +858,10 @@ begin
gtk_list_clear_items(FGtkList, Index, Index + 1);
Include(FStates,glsItemCacheNeedsUpdate);
//Clear the combobox text
if FOwner is TCustomComboBox then
SetComboBoxText(PGtkCombo(FOwner.Handle), '');
{$IFDEF CheckGtkList}
ConsistencyCheck;
{$ENDIF}

View File

@ -867,23 +867,22 @@ end;
Sets the text of the combobox entry.
------------------------------------------------------------------------------}
procedure SetComboBoxText(ComboWidget: PGtkCombo; NewText: PChar);
procedure SetComboBoxText(ComboWidget: PGtkCombo; const NewText: String);
begin
//DebugLn('SetComboBoxText ',DbgS(ComboWidget),' "',NewText,'"');
// lock combobox, so that no OnChange event is fired
LockOnChange(PGtkObject(ComboWidget^.entry),+1);
LockOnChange(PGtkObject(ComboWidget^.list),+1);
// lock combobox, so that no OnChange event is not fired
LockOnChange(PGtkObject(ComboWidget^.entry), +1);
// set text
if NewText = nil then NewText:=#0; // gtk expects at least a #0
gtk_entry_set_text(PGtkEntry(ComboWidget^.entry), NewText);
// The String > PChar conversion ensures at least a null terminated string
gtk_entry_set_text(PGtkEntry(ComboWidget^.entry), PChar(NewText));
// unlock combobox
LockOnChange(PGtkObject(ComboWidget^.list),-1);
LockOnChange(PGtkObject(ComboWidget^.entry),-1);
LockOnChange(PGtkObject(ComboWidget^.entry), -1);
end;
function GetComboBoxText(ComboWidget: PGtkCombo): string;
begin
Result:=StrPas(gtk_entry_get_text(PGtkEntry(ComboWidget^.entry)));
Result := String(gtk_entry_get_text(PGtkEntry(ComboWidget^.entry)));
end;
{------------------------------------------------------------------------------
@ -909,23 +908,29 @@ end;
{------------------------------------------------------------------------------
procedure SetComboBoxItemIndex(ComboBox: TCustomComboBox; Index: integer);
Returns the current ItemIndex of a TComboBox
Set the current ItemIndex of a TComboBox
------------------------------------------------------------------------------}
procedure SetComboBoxItemIndex(ComboBox: TCustomComboBox; Index: integer);
var
ComboWidget: PGtkCombo;
ComboStrings: TStrings;
WidgetInfo: PWidgetInfo;
begin
ComboWidget:=PGtkCombo(ComboBox.Handle);
LockOnChange(PGtkObject(ComboWidget),+1);
gtk_list_select_item(PGtkList(ComboWidget^.list),Index);
if Index>=0 then begin
ComboStrings:=TStrings(gtk_object_get_data(PGtkObject(ComboWidget),GtkListItemLCLListTag));
if Index < ComboStrings.Count
then SetComboBoxText(ComboWidget, PChar(ComboStrings[Index]))
else SetComboBoxText(ComboWidget, '#error#');
ComboWidget := PGtkCombo(ComboBox.Handle);
WidgetInfo := GetWidgetInfo(ComboWidget);
//Store the LCLIndex
PInteger(WidgetInfo^.UserData)^ := Index;
//Avoid calling OnChange/OnSelect events
LockOnChange(PGtkObject(ComboWidget), +1);
//gtk_list_select_item does not update the list when Index is -1
if Index > -1 then
gtk_list_select_item(PGtkList(ComboWidget^.list), Index)
else
begin
gtk_list_set_selection_mode(PGtkList(ComboWidget^.list),
GTK_SELECTION_SINGLE);
SetComboBoxText(ComboWidget, '');
end;
LockOnChange(PGtkObject(ComboWidget),-1);
LockOnChange(PGtkObject(ComboWidget), -1);
end;
procedure SetLabelAlignment(LabelWidget: PGtkLabel;
@ -6348,22 +6353,6 @@ begin
end;
end;
function gtkListSelectChild(widget: PGtkWidget; child: PGtkWidget;
data: gPointer): GBoolean; cdecl;
var
Mess: TLMessage;
begin
Result := CallBackDefaultReturn;
if LockOnChange(PgtkObject(TWinControl(Data).Handle),0) > 0 then Exit;
{$IFDEF EventTrace}
EventTrace('gtkListSelectChild', data);
{$ENDIF}
FillChar(Mess,SizeOf(Mess),0);
Mess.msg := LM_SelChange;
DeliverMessage(Data, Mess);
end;
function gtkListGetSelectionMode(list: PGtkList): TGtkSelectionMode; cdecl;
begin
Result:=TGtkSelectionMode(

View File

@ -62,7 +62,6 @@ uses
const
GtkListItemGtkListTag = 'GtkList';
GtkListItemLCLListTag = 'LCLList';
GtkComboLCLItemIndexTag = 'LCLItemIndex';
type
@ -355,7 +354,7 @@ procedure GrabMouseToForm(AForm: TCustomForm);
procedure ReleaseMouseFromForm(AForm: TCustomForm);
// combobox
procedure SetComboBoxText(ComboWidget: PGtkCombo; NewText: PChar);
procedure SetComboBoxText(ComboWidget: PGtkCombo; const NewText: String);
function GetComboBoxText(ComboWidget: PGtkCombo): string;
function GetComboBoxItemIndex(ComboBox: TCustomComboBox): integer;
procedure SetComboBoxItemIndex(ComboBox: TCustomComboBox; Index: integer);
@ -665,11 +664,8 @@ procedure UpdateStatusBarPanel(StatusBar: TObject; Index: integer;
StatusPanelWidget: PGtkWidget);
// list
function gtkListSelectChild(widget: PGtkWidget; child: PGtkWidget;
data: gPointer): GBoolean; cdecl;
function gtkListGetSelectionMode(list: PGtkList): TGtkSelectionMode;cdecl;
// sizing
procedure SaveSizeNotification(Widget: PGtkWidget);
procedure SaveClientSizeNotification(FixWidget: PGtkWidget);

View File

@ -3103,10 +3103,6 @@ begin
'value_changed', @gtkvaluechanged);
end
else
if ALCLObject is TCustomCombobox then
ConnectSenderSignal (PGtkObject(
PGtkCombo(gObject)^.entry), 'changed', @gtkchangedCB)
else
if ALCLObject is TCustomMemo then
ConnectSenderSignal(gCore, 'changed', @gtkchanged_editbox)
else if ALCLObject is TCustomCheckbox then
@ -3449,13 +3445,9 @@ begin
LM_SelChange:
begin
if ALCLObject is TCustomListBox then begin
if ALCLObject is TCustomListBox then
ConnectSenderSignalAfter(PgtkObject(gCore),
'selection_changed', @gtkListBoxSelectionChangedAfter);
end else if ALCLObject is TCustomCombobox then begin
ConnectSenderSignal (PGtkObject(PGtkCombo(gObject)^.list),
'unselect_child', @gtkListSelectChild);
end;
end;
LM_DROPFILES:
@ -3654,7 +3646,7 @@ begin
if GtkWidgetIsA(Widget,GTK_COMBO_GET_TYPE) then begin
g_signal_handlers_destroy(PGtkObject(PGtkCombo(Widget)^.Entry));
g_signal_handlers_destroy(PGtkObject(PGtkCombo(Widget)^.List));
SetComboBoxText(PGtkCombo(Widget),nil);
SetComboBoxText(PGtkCombo(Widget), '');
// MWE:
// TODO: Check: Why is there widgetinfo on subwidgets ???

View File

@ -675,7 +675,7 @@ begin
begin
//DebugLn('SetLabel: ',TComboBox(Sender).Name,':',TComboBox(Sender).ClassName,
// ' ',DbgS(TComboBox(Sender).Handle),' "',PLabel,'"');
SetComboBoxText(PGtkCombo(TComboBox(AWinControl).Handle), PLabel);
SetComboBoxText(PGtkCombo(TComboBox(AWinControl).Handle), AText)
end;
else

View File

@ -804,15 +804,64 @@ end;
{ TGtkWSCustomComboBox }
{$IFDEF GTK1}
function gtkComboBoxChanged(widget: PGtkWidget; data: gPointer) : GBoolean; cdecl;
var
Mess : TLMessage;
GtkComboWidget: PGtkCombo;
GtkListWidget: PGtkList;
LCLIndex: PInteger;
GtkIndex: Integer;
begin
Result := CallBackDefaultReturn;
if ComponentIsDestroyingHandle(TWinControl(Data)) or
(LockOnChange(PGtkObject(Widget), 0) > 0) or
(gtk_signal_n_emissions_by_name(PGtkObject(widget), 'changed') > 1)
then exit;
{$IFDEF EventTrace}
EventTrace('changed', data);
{$ENDIF}
FillChar(Mess, SizeOf(Mess), 0);
Mess.Msg := LM_CHANGED;
DeliverMessage(Data, Mess);
GtkComboWidget := PGtkCombo(TComboBox(Data).Handle);
GtkListWidget := PGtkList(GtkComboWidget^.list);
LCLIndex := PInteger(GetWidgetInfo(GtkComboWidget)^.UserData);
//Check if an item is selected
if (GtkListWidget^.selection <> nil) then
begin
GtkIndex := gtk_list_child_position(GtkListWidget,
PGtkWidget(GtkListWidget^.selection^.data));
//If the selected item index changed send a LM_SELCHANGE msg
if LCLIndex^ <> GtkIndex then
begin
gtk_list_set_selection_mode(GtkListWidget, GTK_SELECTION_BROWSE);
LCLIndex^ := GtkIndex;
Mess.Msg := LM_SELCHANGE;
DeliverMessage(Data, Mess);
end;
end
else
begin
LCLIndex^ := -1;
gtk_list_set_selection_mode(GtkListWidget, GTK_SELECTION_SINGLE);
end;
end;
class procedure TGtkWSCustomComboBox.SetCallbacks(const AGtkWidget: PGtkWidget;
const AWidgetInfo: PWidgetInfo);
begin
TGtkWSWinControl.SetCallbacks(PGtkObject(AGtkWidget), TComponent(AWidgetInfo^.LCLObject));
with TGtkWidgetset(Widgetset) do
begin
SetCallback(LM_CHANGED, PGtkObject(AGtkWidget), AWidgetInfo^.LCLObject);
//gtk1 and gtk2 have different 'changed' event handlers
ConnectSignal(PGtkObject(PGtkCombo(AGtkWidget)^.entry),
'changed', @gtkComboBoxChanged, AWidgetInfo^.LCLObject);
SetCallback(LM_COMMAND, PGtkObject(AGtkWidget), AWidgetInfo^.LCLObject);
SetCallback(LM_SELCHANGE, PGtkObject(AGtkWidget), AWidgetInfo^.LCLObject);
end;
end;
@ -826,6 +875,7 @@ var
ItemList: TGtkListStringList;
GtkList: PGtkList;
Allocation: TGtkAllocation;
LCLIndex: PInteger;
begin
Widget := gtk_combo_new();
@ -834,13 +884,19 @@ begin
gtk_combo_disable_activate(ComboWidget);
gtk_combo_set_case_sensitive(ComboWidget, GdkTrue);
// Prevents the OnSelect event be fired after inserting the first item
// or deleting the selected item
GtkList:=PGtkList(ComboWidget^.List);
if GtkList^.selection = nil then
gtk_list_set_selection_mode(GtkList, GTK_SELECTION_SINGLE)
else
gtk_list_set_selection_mode(GtkList, GTK_SELECTION_BROWSE);
// Switching the selection mode is necessary to avoid the following problems:
// - The first added item is automatically selected when mode is "BROWSE"
// - Is not possible to select the previous selected item if mode is "BROWSE"
// and current index is -1
// - The item is deselected after a second click if mode is "SINGLE"
// - The OnSelect event could be fired after add the first item when mode is
// "BROWSE". Since LM_SELCHANGE is sent in 'changed' event now, no problem.
// So basically the mode is set to BROWSE when a item is selected and
// "SINGLE" when there's no item selected
gtk_list_set_selection_mode(GtkList, GTK_SELECTION_SINGLE);
// Items
ItemList:= TGtkListStringList.Create(GtkList, ComboBox, False);
@ -848,9 +904,18 @@ begin
ItemList.Assign(ComboBox.Items);
ItemList.Sorted:= ComboBox.Sorted;
WidgetInfo := CreateWidgetInfo(Widget, AWinControl, AParams);
New(LCLIndex);
WidgetInfo^.UserData := LCLIndex;
WidgetInfo^.DataOwner := True;
// ItemIndex
if ComboBox.ItemIndex >= 0 then
begin
gtk_list_select_item(GtkList, ComboBox.ItemIndex);
LCLIndex^ := ComboBox.ItemIndex;
end
else
LCLIndex^ := -1;
// MaxLength
gtk_entry_set_max_length(PGtkEntry(ComboWidget^.entry),guint16(ComboBox.MaxLength));
@ -859,7 +924,7 @@ begin
DebugGtkWidgets.MarkCreated(Widget, dbgsName(AWinControl));
{$ENDIF}
Result := THandle(PtrUInt(Widget));
WidgetInfo := CreateWidgetInfo(Widget, AWinControl, AParams);
Allocation.X := AParams.X;
Allocation.Y := AParams.Y;

View File

@ -488,10 +488,23 @@ end;
------------------------------------------------------------------------------}
procedure TGtkListStoreStringList.Clear;
var
WidgetInfo: PWidgetInfo;
begin
//DebugLn(['TGtkListStoreStringList.Clear ']);
//while Count>0 do Delete(Count-1);
gtk_list_store_clear(FGtkListStore);
//Lock the widget to avoid trigger events
//Note: Assign/Clear is called inside CreateHandle before Handle is set
if FOwner.HandleAllocated then begin
WidgetInfo := GetWidgetInfo(Pointer(FOwner.Handle), False);
if WidgetInfo <> nil then
Inc(WidgetInfo^.ChangeLock);
gtk_list_store_clear(FGtkListStore);
if WidgetInfo <> nil then
Dec(WidgetInfo^.ChangeLock);
end;
IncreaseChangeStamp;
ReAllocMem(FCachedItems,0);
@ -511,6 +524,7 @@ end;
procedure TGtkListStoreStringList.Delete(Index : integer);
var
ListItem: TGtkTreeIter;
WidgetInfo: PWidgetInfo;
begin
if not (glsItemCacheNeedsUpdate in FStates) then
ListItem := FCachedItems[Index]
@ -518,8 +532,11 @@ begin
gtk_tree_model_iter_nth_child(FGtkListStore, @ListItem, nil, Index);
//gtk_list_store_g
WidgetInfo := GetWidgetInfo(Pointer(FOwner.Handle));
//Lock the widget to avoid trigger events
Inc(WidgetInfo^.ChangeLock);
gtk_list_store_remove(FGtkListStore, @ListItem);
Dec(WidgetInfo^.ChangeLock);
IncreaseChangeStamp;
if not (glsCountNeedsUpdate in FStates) then
@ -532,6 +549,9 @@ begin
ShrinkCache;
end else
Include(FStates, glsItemCacheNeedsUpdate);
if FOwner is TCustomComboBox then
TGtk2WSCustomComboBox.SetText(FOwner, '');
end;
function TGtkListStoreStringList.IndexOf(const S: string): Integer;

View File

@ -460,6 +460,7 @@ class procedure TGtk2WSCustomListBox.SetItemIndex(
const ACustomListBox: TCustomListBox; const AIndex: integer);
var
Widget: PGtkWidget;
WidgetInfo: PWidgetInfo;
Selection: PGtkTreeSelection;
Path: PGtkTreePath;
@ -476,12 +477,14 @@ begin
if not WSCheckHandleAllocated(ACustomListBox, 'SetItemIndex') then
Exit;
Widget := GetWidgetInfo(Pointer(ACustomListBox.Handle), True)^.CoreWidget;
WidgetInfo := GetWidgetInfo(Pointer(ACustomListBox.Handle), True);
Widget := WidgetInfo^.CoreWidget;
if not GtkWidgetIsA(Widget, gtk_tree_view_get_type) then
raise Exception.Create('');
Selection := gtk_tree_view_get_selection(PGtkTreeView(Widget));
Inc(WidgetInfo^.ChangeLock);
if (AIndex < 0) then
if (gtk_tree_selection_get_mode(Selection) <> GTK_SELECTION_SINGLE) then
Path := gtk_tree_path_new_first
@ -502,6 +505,7 @@ begin
if Path <> nil then
gtk_tree_path_free(Path);
Dec(WidgetInfo^.ChangeLock);
end;
class procedure TGtk2WSCustomListBox.SetSelectionMode(
@ -576,17 +580,19 @@ begin
end;
function gtk2ListBoxSelectionChangedAfter(Widget: PGtkWidget;
AWinControl: TWinControl): gboolean; cdecl;
WidgetInfo: PWidgetInfo): gboolean; cdecl;
var
Mess: TLMessage;
begin
Result := CallBackDefaultReturn;
if WidgetInfo^.ChangeLock > 0 then
Exit;
{$IFDEF EventTrace}
EventTrace('gtk2ListSelectionChangedAfter', dbgsName(AWinControl));
EventTrace('gtk2ListSelectionChangedAfter', WidgetInfo^.LCLObject);
{$ENDIF}
FillChar(Mess,SizeOf(Mess),0);
Mess.msg := LM_SelChange;
DeliverMessage(AWinControl, Mess);
DeliverMessage(WidgetInfo^.LCLObject, Mess);
end;
class function TGtk2WSCustomListBox.CreateHandle(const AWinControl: TWinControl;
@ -646,7 +652,7 @@ begin
end;
g_signal_connect_after(Selection, 'changed',
G_CALLBACK(@gtk2ListBoxSelectionChangedAfter), AWinControl);
G_CALLBACK(@gtk2ListBoxSelectionChangedAfter), WidgetInfo);
// Sets the callbacks
SetCallbacks(p, WidgetInfo);
@ -964,11 +970,13 @@ begin
// keep items
ItemList := ACustomComboBox.Items as TGtkListStoreStringList;
LCLIndex := gtk_object_get_data(GTK_OBJECT(ComboWidget), GtkComboLCLItemIndexTag);
LCLIndex := AWidgetInfo^.UserData;
if not Assigned(LCLIndex) then begin
//debugln('Gtk2WSCustomComboBox ReCreateCombo: LCLIndex unassigned!');
LCLIndex := New(PLongint);
LCLIndex^ := -1;
AWidgetInfo^.UserData := LCLIndex;
AWidgetInfo^.DataOwner := True;
end;
// this should work but may not in all circumstances
@ -980,7 +988,6 @@ begin
if Index = -1 then Index := GetItemIndex(ACustomComboBox);
gtk_object_set_data(PGtkObject(ComboWidget), GtkListItemLCLListTag,nil);
gtk_object_set_data(PGtkObject(ComboWidget), GtkComboLCLItemIndexTag, nil);
gtk_widget_destroy(ComboWidget);
// create the new widget with the old model
@ -990,7 +997,6 @@ begin
end;
// undone the above increase of the ref count
gtk_object_set_data(PGtkObject(ComboWidget),GtkListItemLCLListTag,ItemList);
gtk_object_set_data(PGtkObject(ComboWidget), GtkComboLCLItemIndexTag, LCLIndex);
g_object_unref (G_OBJECT(Model));
SetMainWidget(Box, GTK_BIN(ComboWidget)^.child);
@ -1070,11 +1076,11 @@ var
LCLIndex: PLongint;
Index, GtkIndex: Integer;
begin
if WidgetInfo^.UserData <> nil then Exit;
if WidgetInfo^.ChangeLock > 0 then Exit;
LCLSendChangedMsg(TControl(WidgetInfo^.LCLObject));
Index := -1;
LCLIndex := gtk_object_get_data(GTK_OBJECT(WidgetInfo^.CoreWidget), GtkComboLCLItemIndexTag);
LCLIndex := WidgetInfo^.UserData;
if Assigned(LCLIndex) then
Index := LCLIndex^
else
@ -1287,8 +1293,7 @@ begin
// if we are a fixed un-editable combo then ...
Index := GetItemIndex(TCustomComboBox(AWinControl));
if Index > -1 then AText := TCustomComboBox(AWinControl).Items.Strings[Index]
else Result := False;
if Index > -1 then AText := TCustomComboBox(AWinControl).Items.Strings[Index];
end;
class procedure TGtk2WSCustomComboBox.SetArrowKeysTraverseList(
@ -1341,17 +1346,20 @@ begin
p := WidgetInfo^.CoreWidget;
if gtk_combo_box_get_active(PGtkComboBox(p)) = NewIndex then exit;
// to be delphi compatible OnChange only fires in response to user actions not program actions
// so we use WidgetInfo^.Userdata as a flag to not signal the OnChange Event
WidgetInfo^.UserData := Pointer(1);
// so we use WidgetInfo^.ChangeLock as a flag to not signal the OnChange Event
Inc(WidgetInfo^.ChangeLock);
gtk_combo_box_set_active(PGtkComboBox(p), NewIndex);
LCLIndex := gtk_object_get_data(GTK_OBJECT(p), GtkComboLCLItemIndexTag);
LCLIndex := WidgetInfo^.UserData;
if not Assigned(LCLIndex) then
begin
LCLIndex := New(PLongint);
WidgetInfo^.UserData := LCLIndex;
WidgetInfo^.DataOwner := True;
end;
LCLIndex^ := NewIndex;
gtk_object_set_data(GTK_OBJECT(p), GtkComboLCLItemIndexTag, LCLIndex); // set LCLIndex for OnChange -> OnSelect
WidgetInfo^.UserData := Pointer(nil);
Dec(WidgetInfo^.ChangeLock);
end;
class procedure TGtk2WSCustomComboBox.SetMaxLength(
@ -1472,8 +1480,8 @@ var
Index: Integer;
begin
WidgetInfo := GetWidgetInfo(Pointer(AWinControl.Handle));
// we use user data to not signal onchange
WidgetInfo^.UserData := Pointer(1);
// we use user ChangeLock to not signal onchange
Inc(WidgetInfo^.ChangeLock);
if gtk_is_combo_box_entry(WidgetInfo^.CoreWidget) then begin
Entry := GTK_BIN(WidgetInfo^.CoreWidget)^.child;
gtk_entry_set_text(PGtkEntry(Entry), PChar(AText));
@ -1483,7 +1491,7 @@ begin
Index := TCustomComboBox(AWinControl).Items.IndexOf(AText);
SetItemIndex(TCustomComboBox(AWinControl), Index);
end;
WidgetInfo^.UserData := nil;
Dec(WidgetInfo^.ChangeLock);
end;
class function TGtk2WSCustomComboBox.CreateHandle(const AWinControl: TWinControl;
@ -1529,12 +1537,13 @@ begin
if PGtkComboBoxPrivate(PGtkComboBox(ComboWidget)^.priv)^.button <> nil then
SetMainWidget(Box, PGtkComboBoxPrivate(PGtkComboBox(ComboWidget)^.priv)^.button);
LCLIndex := New(PLongint);
//Should not set the ItemIndex value here?
LCLIndex^ := -1;
WidgetInfo^.CoreWidget := ComboWidget;
WidgetInfo^.ClientWidget := Box;
LCLIndex := New(PLongint);
LCLIndex^ := -1;
gtk_object_set_data(GTK_OBJECT(ComboWidget), GtkComboLCLItemIndexTag, LCLIndex);
WidgetInfo^.UserData := LCLIndex;
WidgetInfo^.DataOwner := True;
//gtk_widget_add_events(Box, GDK_ALL_EVENTS_MASK);
@ -1556,17 +1565,10 @@ class procedure TGtk2WSCustomComboBox.DestroyHandle(
var
Handle: HWND;
ComboWidget: PGtkWidget;
LCLIndex: PLongint;
begin
Handle := AWinControl.Handle;
ComboWidget := GetWidgetInfo(Pointer(Handle), True)^.CoreWidget;
gtk_object_set_data(PGtkObject(ComboWidget),GtkListItemLCLListTag,nil);
LCLIndex := gtk_object_get_data(PGtkObject(ComboWidget), GtkComboLCLItemIndexTag);
if Assigned(LCLIndex) then begin
gtk_object_set_data(PGtkObject(ComboWidget), GtkComboLCLItemIndexTag, nil);
Dispose(LCLIndex);
end else
debugln('Gtk2WSCustomComboBox DestroyHandle: LCLIndex unassigned!');
//DebugLn(['TGtk2WSCustomComboBox.DestroyHandle ',dbgsName(AWinControl),' ClassParent=',ClassParent.ClassName]);

View File

@ -1374,6 +1374,7 @@ begin
itemindex is updated, so set text manually }
CBN_SELCHANGE: begin
UpdateComboBoxText(TCustomComboBox(lWinControl));
SendSimpleMessage(lWinControl, LM_CHANGED);
LMessage.Msg := LM_SELCHANGE;
end;
{ closeup message is sent before text is actually changed... *sigh*

View File

@ -280,7 +280,7 @@ uses
// Win32WSToolwin,
Win32Themes,
////////////////////////////////////////////////////
Arrow, Calendar, Spin, CheckLst, Win32Extra, LclProc;
Arrow, Calendar, Spin, CheckLst, Win32Extra, LclProc, LCLMessageGlue;
type
TMouseDownFocusStatus = (mfNone, mfFocusSense, mfFocusChanged);