Resolved: why selecting a combobox on editor options and pressing Escape raises an exception?
repair memory leak in tComboBox
Darek
Index: interfaces/gtk/gtkproc.inc =================================================================== --- interfaces/gtk/gtkproc.inc (wersja 8985) +++ interfaces/gtk/gtkproc.inc (kopia robocza) @@ -995,7 +995,7 @@ if not ComboBox.HandleAllocated then RaiseGDBException(''); ComboWidget:=PGtkCombo(ComboBox.Handle); - ComboStrings:=TStrings(gtk_object_get_data(PGtkObject(ComboWidget),'LCLList')); + ComboStrings:=TStrings(gtk_object_get_data(PGtkObject(ComboWidget),GtkListItemLCLListTag)); CurText:=GetComboBoxText(ComboWidget); Result:=ComboStrings.IndexOf(CurText); end; @@ -1014,7 +1014,7 @@ 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),'LCLList')); + ComboStrings:=TStrings(gtk_object_get_data(PGtkObject(ComboWidget),GtkListItemLCLListTag)); if Index < ComboStrings.Count then SetComboBoxText(ComboWidget, PChar(ComboStrings[Index])) else SetComboBoxText(ComboWidget, '#error#'); @@ -2375,7 +2375,9 @@ if (not EventStopped) {and (not BeforeEvent)} and CanSendChar then begin + {$IFDEF EventTrace} EventTrace('char', data); + {$ENDIF} KeyPressesChar:=#0; if Event^.Length = 1 then begin @@ -3448,7 +3450,11 @@ begin if Target=nil then DebugLn('[DeliverMessage] Target = nil'); {$IFDEF VerboseDeliverMessage} - if TLMessage(AMessage).Msg<>LM_MOUSEMOVE then + if (TLMessage(AMessage).Msg <>LM_MOUSEMOVE) + and (TLMessage(AMessage).Msg <>LM_PAINT) + and (TLMessage(AMessage).Msg <>LM_KEYDOWN) + and (TLMessage(AMessage).Msg <>LM_KEYUP) + and (TLMessage(AMessage).Msg < CN_KEYDOWN ) then DebugLn('DeliverMessage ',DbgS(Target), ' ',TComponent(Target).Name,':',TObject(Target).ClassName, ' Message=',GetMessageName(TLMessage(AMessage).Msg)); Index: interfaces/gtk/gtklistsl.inc =================================================================== --- interfaces/gtk/gtklistsl.inc (wersja 8985) +++ interfaces/gtk/gtklistsl.inc (kopia robocza) @@ -19,9 +19,6 @@ ***************************************************************************** } -const - GtkListItemGtkListTag = 'GtkList'; - GtkListItemLCLListTag = 'LCLList'; {*************************************************************} { Default compare functions } @@ -394,6 +391,9 @@ var ChildWidget: Pointer; begin + {$IFDEF EventTrace} + Debugln('connect itemCallback'); + {$ENDIF} gtk_object_set_data(PGtkObject(AItem), GtkListItemLCLListTag, nil); gtk_object_set_data(PGtkObject(AItem), GtkListItemGtkListTag, nil); {$ifdef GTK2} @@ -624,7 +624,7 @@ {$IFDEF CheckGtkList} ConsistencyCheck; {$ENDIF} -//DebugLn('[TGtkListStringList.Assign] END ',Source.Classname); + //DebugLn('[TGtkListStringList.Assign] END ',Source.Classname); end; {------------------------------------------------------------------------------ Index: interfaces/gtk/gtkwsstdctrls.pp =================================================================== --- interfaces/gtk/gtkwsstdctrls.pp (wersja 8985) +++ interfaces/gtk/gtkwsstdctrls.pp (kopia robocza) @@ -76,6 +76,7 @@ class function GetSelLength(const ACustomComboBox: TCustomComboBox): integer; override; class function GetItemIndex(const ACustomComboBox: TCustomComboBox): integer; override; class function GetMaxLength(const ACustomComboBox: TCustomComboBox): integer; override; + class function GetText(const AWinControl: TWinControl; var AText: String): Boolean; override; class procedure SetArrowKeysTraverseList(const ACustomComboBox: TCustomComboBox; NewTraverseList: boolean); override; @@ -429,6 +430,7 @@ Widget: PGtkWidget;// pointer to gtk-widget Handle: HWND; begin + Handle := ACustomListBox.Handle; case ACustomListBox.fCompStyle of csCListBox: @@ -617,10 +619,25 @@ end; end; +function TGtkWSCustomComboBox.GetText(const AWinControl: TWinControl; var AText: String): Boolean; +begin +// DebugLn('TGtkWSCustomComboBox.Gettext ',DbgSName(ACustomComboBox),' ',GetWidgetDebugReport(PGtkWidget(ACustomComboBox.Handle))); + + Atext:=GetComboBoxText(PGtkCombo(AWinControl.handle)); + result:=true; +end; + function TGtkWSCustomComboBox.GetItemIndex( const ACustomComboBox: TCustomComboBox): integer; +var + CurText : string; begin - //DebugLn('TGtkWSCustomComboBox.GetItemIndex ',DbgSName(ACustomComboBox),' ',DebugGtkWidgets.GetInfo(Pointer(ACustomComboBox.Handle),true)); + DebugLn('TGtkWSCustomComboBox.GetItemIndex ',DbgSName(ACustomComboBox),' ',GetWidgetDebugReport(PGtkWidget(ACustomComboBox.Handle))); +// GetText(ACustomComboBox,CurText); +// if (ACustomComboBox.fItemIndex>=0) and (ACustomComboBox.Items[ACustomComboBox.ItemIndex]=CurText) then result:=ACustomComboBox.ItemIndex +// else +// Result:=ACustomComboBox.Items.IndexOf(CurText); + Result:=GetComboBoxItemIndex(ACustomComboBox); end; @@ -711,7 +728,7 @@ const ACustomComboBox: TCustomComboBox): TStrings; begin Result := TStrings(gtk_object_get_data(PGtkObject(ACustomComboBox.Handle), - 'LCLList')); + GtkListItemLCLListTag)); end; procedure TGtkWSCustomComboBox.Sort(const ACustomComboBox: TCustomComboBox; Index: interfaces/gtk/gtkcallback.inc =================================================================== --- interfaces/gtk/gtkcallback.inc (wersja 8985) +++ interfaces/gtk/gtkcallback.inc (kopia robocza) @@ -580,7 +580,9 @@ CurFocusWidget: PGtkWidget; {$ENDIF} begin + {$IFDEF EventTrace} EventTrace('focus', data); + {$ENDIF} if (Widget=nil) or (Event=nil) then ; //DebugLn('GTKFocusCB ',DbgSName(TObject(Data)),' ',GetWidgetDebugReport(Widget)); {$IFDEF VerboseFocus} @@ -625,7 +627,9 @@ CurFocusWidget: PGtkWidget; {$ENDIF} begin + {$IFDEF EventTrace} EventTrace('focus', data); + {$ENDIF} if (Widget=nil) or (Event=nil) then ; //DebugLn('GTKFocusCBAfter ',DbgSName(TObject(Data)),' ',GetWidgetDebugReport(Widget)); {$IFDEF VerboseFocus} @@ -2533,7 +2537,9 @@ begin Result := CallBackDefaultReturn; //DebugLn('[gtkFocusInNotifyCB] ',TControl(data).Name,':',TObject(data).ClassName); + {$IFDEF EventTrace} EventTrace ('FocusInNotify (alias Enter)', data); + {$ENDIF} if (Event=nil) then ; if csDesigning in TControl(Data).ComponentState then begin @@ -2552,7 +2558,9 @@ begin Result := CallBackDefaultReturn; //DebugLn('[gtkFocusOutNotifyCB] ',TControl(data).Name,':',TObject(data).ClassName); + {$IFDEF EventTrace} EventTrace ('FocusOutNotify (alias Exit)', data); + {$ENDIF} if (Event=nil) then ; if csDesigning in TControl(Data).ComponentState then begin @@ -3119,7 +3127,7 @@ begin Result := CallBackDefaultReturn; {$IFDEF EventTrace} - EventTrace('gtkListBoxSelectionChangedAfter', data); + EventTrace('gtkListSelectionChangedAfter', data); {$ENDIF} FillChar(Mess,SizeOf(Mess),0); Mess.msg := LM_SelChange; Index: interfaces/gtk/gtkobject.inc =================================================================== --- interfaces/gtk/gtkobject.inc (wersja 8985) +++ interfaces/gtk/gtkobject.inc (kopia robocza) @@ -4770,8 +4770,9 @@ gtk_combo_set_case_sensitive(Widget, GdkTrue); // Items + writeln('initializecomboitems'); ItemList:= TGtkListStringList.Create(PGtkList(Widget^.List),ComboBox,False); - gtk_object_set_data(PGtkObject(Widget), 'LCLList', ItemList); + gtk_object_set_data(PGtkObject(Widget), GtkListItemLCLListTag, ItemList); ItemList.Assign(ComboBox.Items); ItemList.Sorted:= ComboBox.Sorted; Index: interfaces/gtk/gtkproc.pp =================================================================== --- interfaces/gtk/gtkproc.pp (wersja 8985) +++ interfaces/gtk/gtkproc.pp (kopia robocza) @@ -57,6 +57,12 @@ FileUtil, ImgList, GTKGlobals, gtkDef; + +const + GtkListItemGtkListTag = 'GtkList'; + GtkListItemLCLListTag = 'LCLList'; + + type PPWaitHandleEventHandler = ^PWaitHandleEventHandler; PWaitHandleEventHandler = ^TWaitHandleEventHandler; Index: include/customcombobox.inc =================================================================== --- include/customcombobox.inc (wersja 8985) +++ include/customcombobox.inc (kopia robocza) @@ -33,16 +33,6 @@ begin inherited InitializeWnd; - // get the interface based item list - NewStrings:= TWSCustomComboBoxClass(WidgetSetClass).GetItems(Self); - // then delete internal list - if (FItems<>NewStrings) and (FItems<>nil) then begin - NewStrings.Assign(FItems); - FItems.Free; - end; - // and use the interface based list - FItems:= NewStrings; - if FItemIndex <> -1 then TWSCustomComboBoxClass(WidgetSetClass).SetItemIndex(Self, FItemIndex); TWSCustomComboBoxClass(WidgetSetClass).SetStyle(Self, FStyle); @@ -57,6 +47,36 @@ end; end; +{------------------------------------------------------------------------------} +{ procedure TCustomComboBox.FinalizeWnd } +{------------------------------------------------------------------------------} +procedure TCustomComboBox.FinalizeWnd; +var + NewStrings: TStrings; + i, Cnt: integer; +begin +// LockSelectionChange; + + // save ItemIndex on destroy handle + if ([csDestroying,csLoading]*ComponentState=[]) then + GetItemIndex; + //DebugLn('[TCustomComboBox.FinalizeWnd] A ',FItems.ClassName); + // create internal item list + NewStrings:= TWSCustomComboBoxClass(WidgetSetClass).GetItems(Self); + if Assigned(NewStrings) then NewStrings.free; + + // copy items (text+objects) from the interface items list +// NewStrings.Assign(Items); + // copy items attributes +// FItems.Free; +// FItems:= NewStrings; + + inherited FinalizeWnd; + //DebugLn('[TCustomListBox.FinalizeWnd] END ',FItems.ClassName); +// UnlockSelectionChange; +end; + + {------------------------------------------------------------------------------ Method: TCustomComboBox.DestroyWnd Params: --- @@ -753,7 +773,7 @@ ------------------------------------------------------------------------------} function TCustomComboBox.GetItemIndex : integer; begin - if HandleAllocated then + if not (csDestroying in ComponentState) and HandleAllocated then FItemIndex:= TWSCustomComboBoxClass(WidgetSetClass).GetItemIndex(Self); Result:=FItemIndex; end; Index: stdctrls.pp =================================================================== --- stdctrls.pp (wersja 8985) +++ stdctrls.pp (kopia robocza) @@ -273,6 +273,7 @@ procedure WMChar(var Message: TLMChar); message LM_CHAR; protected procedure InitializeWnd; override; + procedure FinalizeWnd; override; procedure DestroyWnd; override; procedure DrawItem(Index: Integer; ARect: TRect; State: TOwnerDrawState); virtual;