mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-11-23 08:14:46 +01:00
win32: TCheckListBox:
- move TCheckListBox code from the general WindowProc to the private one - preserve data on ListBox item change and appropriate code for TCheckListBox git-svn-id: trunk@22039 -
This commit is contained in:
parent
a35abe991c
commit
c6ba3e76d8
@ -574,38 +574,6 @@ var
|
|||||||
MoveWindowOrgEx(ControlDC, P.X, P.Y);
|
MoveWindowOrgEx(ControlDC, P.X, P.Y);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure CheckListBoxLButtonDown;
|
|
||||||
var
|
|
||||||
I: Integer;
|
|
||||||
ItemRect: Windows.Rect;
|
|
||||||
MousePos: Windows.Point;
|
|
||||||
Message: TLMessage;
|
|
||||||
begin
|
|
||||||
MousePos.X := LMMouse.Pos.X;
|
|
||||||
MousePos.Y := LMMouse.Pos.Y;
|
|
||||||
for I := 0 to Windows.SendMessage(Window, LB_GETCOUNT, 0, 0) - 1 do
|
|
||||||
begin
|
|
||||||
Windows.SendMessage(Window, LB_GETITEMRECT, I, PtrInt(@ItemRect));
|
|
||||||
ItemRect.Right := ItemRect.Left + ItemRect.Bottom - ItemRect.Top;
|
|
||||||
if Windows.PtInRect(ItemRect, MousePos) then
|
|
||||||
begin
|
|
||||||
// item clicked: toggle
|
|
||||||
if I < TCheckListBox(lWinControl).Items.Count then
|
|
||||||
begin
|
|
||||||
if TCheckListBox(lWinControl).ItemEnabled[I] then
|
|
||||||
begin
|
|
||||||
TCheckListBox(lWinControl).Toggle(I);
|
|
||||||
Message.Msg := LM_CHANGED;
|
|
||||||
Message.WParam := I;
|
|
||||||
DeliverMessage(lWinControl, Message);
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
// can only click one item
|
|
||||||
exit;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure ClearSiblingRadioButtons(RadioButton: TRadioButton);
|
procedure ClearSiblingRadioButtons(RadioButton: TRadioButton);
|
||||||
var
|
var
|
||||||
Parent: TWinControl;
|
Parent: TWinControl;
|
||||||
@ -1844,10 +1812,6 @@ begin
|
|||||||
YPos := GET_Y_LPARAM(LParam);
|
YPos := GET_Y_LPARAM(LParam);
|
||||||
Keys := WParam;
|
Keys := WParam;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
// CheckListBox functionality
|
|
||||||
if lWinControl is TCheckListBox then
|
|
||||||
CheckListBoxLButtonDown;
|
|
||||||
end;
|
end;
|
||||||
WM_LBUTTONDOWN:
|
WM_LBUTTONDOWN:
|
||||||
begin
|
begin
|
||||||
@ -1887,10 +1851,6 @@ begin
|
|||||||
YPos := GET_Y_LPARAM(LParam);
|
YPos := GET_Y_LPARAM(LParam);
|
||||||
Keys := WParam;
|
Keys := WParam;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
// CheckListBox functionality
|
|
||||||
if lWinControl is TCheckListBox then
|
|
||||||
CheckListBoxLButtonDown;
|
|
||||||
end;
|
end;
|
||||||
WM_LBUTTONUP:
|
WM_LBUTTONUP:
|
||||||
begin
|
begin
|
||||||
|
|||||||
@ -86,6 +86,16 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TWin32ListStringList.SaveData(AIndex: Integer): Pointer;
|
||||||
|
begin
|
||||||
|
Result := GetObject(AIndex);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TWin32ListStringList.RestoreData(AIndex: Integer; AData: Pointer);
|
||||||
|
begin
|
||||||
|
PutObject(AIndex, TObject(AData));
|
||||||
|
end;
|
||||||
|
|
||||||
{------------------------------------------------------------------------------
|
{------------------------------------------------------------------------------
|
||||||
Method: TWin32ListStringList.Sort
|
Method: TWin32ListStringList.Sort
|
||||||
Params:
|
Params:
|
||||||
@ -263,8 +273,9 @@ end;
|
|||||||
|
|
||||||
procedure TWin32ListStringList.Put(Index: integer; const S: string);
|
procedure TWin32ListStringList.Put(Index: integer; const S: string);
|
||||||
var
|
var
|
||||||
lItemIndex: integer;
|
lItemIndex: Integer;
|
||||||
lSelected: boolean;
|
lSelected: Boolean;
|
||||||
|
AData: Pointer;
|
||||||
begin
|
begin
|
||||||
// remember selection
|
// remember selection
|
||||||
lItemIndex := -1;
|
lItemIndex := -1;
|
||||||
@ -280,16 +291,19 @@ begin
|
|||||||
lItemIndex := SendMessage(FWin32List, FFlagGetItemIndex, 0, 0);
|
lItemIndex := SendMessage(FWin32List, FFlagGetItemIndex, 0, 0);
|
||||||
lSelected := lItemIndex >= 0;
|
lSelected := lItemIndex >= 0;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
// preserve data
|
||||||
|
AData := SaveData(Index);
|
||||||
|
|
||||||
inherited;
|
inherited;
|
||||||
|
|
||||||
|
if AData <> nil then
|
||||||
|
RestoreData(Index, AData);
|
||||||
|
|
||||||
if lSelected then
|
if lSelected then
|
||||||
begin
|
begin
|
||||||
if (FFlagSetSelected = 0)
|
if (FFlagSetSelected = 0) or (SendMessage(FWin32List, FFlagSetSelected, Windows.WParam(true), lItemIndex) = -1) then
|
||||||
or (SendMessage(FWin32List, FFlagSetSelected, Windows.WParam(true), lItemIndex) = -1) then
|
|
||||||
begin
|
|
||||||
SendMessage(FWin32List, FFlagSetItemIndex, lItemIndex, 0);
|
SendMessage(FWin32List, FFlagSetItemIndex, lItemIndex, 0);
|
||||||
end;
|
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -435,7 +449,7 @@ end;
|
|||||||
|
|
||||||
{ TWin32CheckListBoxStrings }
|
{ TWin32CheckListBoxStrings }
|
||||||
|
|
||||||
constructor TWin32CheckListBoxStrings.Create(List : HWND; TheOwner: TWinControl);
|
constructor TWin32CheckListBoxStrings.Create(List: HWND; TheOwner: TWinControl);
|
||||||
begin
|
begin
|
||||||
inherited Create(List, TheOwner);
|
inherited Create(List, TheOwner);
|
||||||
with FDefaultItem do
|
with FDefaultItem do
|
||||||
@ -529,23 +543,51 @@ begin
|
|||||||
SetItemRecord(Index, ItemRecord);
|
SetItemRecord(Index, ItemRecord);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TWin32CheckListBoxStrings.SaveData(AIndex: Integer): Pointer;
|
||||||
|
var
|
||||||
|
ItemRecord: PWin32CheckListBoxItemRecord;
|
||||||
|
begin
|
||||||
|
ItemRecord := GetItemRecord(AIndex, False);
|
||||||
|
if ItemRecord = nil then
|
||||||
|
Result := nil
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
Result := new(PWin32CheckListBoxItemRecord);
|
||||||
|
PWin32CheckListBoxItemRecord(Result)^ := ItemRecord^;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TWin32CheckListBoxStrings.RestoreData(AIndex: Integer; AData: Pointer);
|
||||||
|
var
|
||||||
|
ItemRecord: PWin32CheckListBoxItemRecord absolute AData;
|
||||||
|
OldRecord: PWin32CheckListBoxItemRecord;
|
||||||
|
begin
|
||||||
|
if ItemRecord <> nil then
|
||||||
|
begin
|
||||||
|
OldRecord := GetItemRecord(AIndex, True);
|
||||||
|
OldRecord^ := ItemRecord^;
|
||||||
|
SetItemRecord(AIndex, OldRecord);
|
||||||
|
Dispose(ItemRecord);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
class procedure TWin32CheckListBoxStrings.DeleteItemRecords(const List: HWND);
|
class procedure TWin32CheckListBoxStrings.DeleteItemRecords(const List: HWND);
|
||||||
var
|
var
|
||||||
Index: Integer;
|
Index: Integer;
|
||||||
ItemCount: Integer;
|
ItemCount: Integer;
|
||||||
begin
|
begin
|
||||||
ItemCount := Windows.SendMessage(List, LB_GETCOUNT, 0, 0);
|
ItemCount := Windows.SendMessage(List, LB_GETCOUNT, 0, 0);
|
||||||
for Index := 0 to ItemCount-1 do
|
for Index := 0 to ItemCount - 1 do
|
||||||
DeleteItemRecord(List, Index);
|
DeleteItemRecord(List, Index);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
class procedure TWin32CheckListBoxStrings.DeleteItemRecord(const List: HWND;const Index: integer);
|
class procedure TWin32CheckListBoxStrings.DeleteItemRecord(const List: HWND; const Index: integer);
|
||||||
var
|
var
|
||||||
ItemRecord: PWin32CheckListBoxItemRecord;
|
ItemRecord: PWin32CheckListBoxItemRecord;
|
||||||
begin
|
begin
|
||||||
ItemRecord := PWin32CheckListBoxItemRecord(Windows.SendMessage(List, LB_GETITEMDATA, Index, 0));
|
ItemRecord := PWin32CheckListBoxItemRecord(Windows.SendMessage(List, LB_GETITEMDATA, Index, 0));
|
||||||
if Assigned(ItemRecord)
|
if Assigned(ItemRecord) then
|
||||||
then Dispose(ItemRecord);
|
Dispose(ItemRecord);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{$IFDEF H_PLUS}
|
{$IFDEF H_PLUS}
|
||||||
|
|||||||
@ -64,6 +64,8 @@ Type
|
|||||||
|
|
||||||
procedure InitFlags; virtual;
|
procedure InitFlags; virtual;
|
||||||
procedure SetSorted(Val: Boolean); Virtual;
|
procedure SetSorted(Val: Boolean); Virtual;
|
||||||
|
function SaveData(AIndex: Integer): Pointer; virtual;
|
||||||
|
procedure RestoreData(AIndex: Integer; AData: Pointer); virtual;
|
||||||
public
|
public
|
||||||
constructor Create(List : HWND; TheOwner: TWinControl);
|
constructor Create(List : HWND; TheOwner: TWinControl);
|
||||||
function Add(const S: string): Integer; override;
|
function Add(const S: string): Integer; override;
|
||||||
@ -118,8 +120,10 @@ Type
|
|||||||
protected
|
protected
|
||||||
function GetObject(Index: Integer): TObject; override;
|
function GetObject(Index: Integer): TObject; override;
|
||||||
procedure PutObject(Index: Integer; AObject: TObject); override;
|
procedure PutObject(Index: Integer; AObject: TObject); override;
|
||||||
|
function SaveData(AIndex: Integer): Pointer; override;
|
||||||
|
procedure RestoreData(AIndex: Integer; AData: Pointer); override;
|
||||||
public
|
public
|
||||||
constructor Create(List : HWND; TheOwner: TWinControl);
|
constructor Create(List: HWND; TheOwner: TWinControl);
|
||||||
class procedure DeleteItemRecords(const List: HWND);
|
class procedure DeleteItemRecords(const List: HWND);
|
||||||
class procedure DeleteItemRecord(const List: HWND; const Index: integer);
|
class procedure DeleteItemRecord(const List: HWND; const Index: integer);
|
||||||
procedure Clear; override;
|
procedure Clear; override;
|
||||||
|
|||||||
@ -33,9 +33,9 @@ uses
|
|||||||
// To get as little as posible circles,
|
// To get as little as posible circles,
|
||||||
// uncomment only when needed for registration
|
// uncomment only when needed for registration
|
||||||
////////////////////////////////////////////////////
|
////////////////////////////////////////////////////
|
||||||
Classes, CheckLst, StdCtrls,
|
Windows, Classes, Controls, CheckLst, StdCtrls, LCLType, LMessages, LCLMessageGlue,
|
||||||
////////////////////////////////////////////////////
|
////////////////////////////////////////////////////
|
||||||
WSCheckLst, WSLCLClasses, Win32Int, Win32Proc, Windows;
|
WSCheckLst, WSLCLClasses, Win32Int, Win32Proc, Win32WSControls, Win32WSStdCtrls;
|
||||||
|
|
||||||
type
|
type
|
||||||
|
|
||||||
@ -43,8 +43,9 @@ type
|
|||||||
|
|
||||||
TWin32WSCustomCheckListBox = class(TWSCustomCheckListBox)
|
TWin32WSCustomCheckListBox = class(TWSCustomCheckListBox)
|
||||||
published
|
published
|
||||||
class function GetStrings(const ACustomListBox: TCustomListBox): TStrings; override;
|
class function CreateHandle(const AWinControl: TWinControl;
|
||||||
|
const AParams: TCreateParams): TLCLIntfHandle; override;
|
||||||
|
class function GetStrings(const ACustomListBox: TCustomListBox): TStrings; override;
|
||||||
class function GetItemEnabled(const ACheckListBox: TCustomCheckListBox;
|
class function GetItemEnabled(const ACheckListBox: TCustomCheckListBox;
|
||||||
const AIndex: integer): Boolean; override;
|
const AIndex: integer): Boolean; override;
|
||||||
class function GetState(const ACheckListBox: TCustomCheckListBox;
|
class function GetState(const ACheckListBox: TCustomCheckListBox;
|
||||||
@ -58,6 +59,70 @@ type
|
|||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
|
function CheckListBoxWndProc(Window: HWnd; Msg: UInt; WParam: Windows.WParam;
|
||||||
|
LParam: Windows.LParam): LResult; stdcall;
|
||||||
|
var
|
||||||
|
WindowInfo: PWin32WindowInfo;
|
||||||
|
|
||||||
|
procedure CheckListBoxLButtonDown;
|
||||||
|
var
|
||||||
|
I: Integer;
|
||||||
|
ItemRect: Windows.Rect;
|
||||||
|
MousePos: Windows.Point;
|
||||||
|
Message: TLMessage;
|
||||||
|
begin
|
||||||
|
MousePos.X := GET_X_LPARAM(LParam);
|
||||||
|
MousePos.Y := GET_Y_LPARAM(LParam);
|
||||||
|
for I := 0 to Windows.SendMessage(Window, LB_GETCOUNT, 0, 0) - 1 do
|
||||||
|
begin
|
||||||
|
Windows.SendMessage(Window, LB_GETITEMRECT, I, PtrInt(@ItemRect));
|
||||||
|
ItemRect.Right := ItemRect.Left + ItemRect.Bottom - ItemRect.Top;
|
||||||
|
if Windows.PtInRect(ItemRect, MousePos) then
|
||||||
|
begin
|
||||||
|
// item clicked: toggle
|
||||||
|
if I < TCheckListBox(WindowInfo^.WinControl).Items.Count then
|
||||||
|
begin
|
||||||
|
if TCheckListBox(WindowInfo^.WinControl).ItemEnabled[I] then
|
||||||
|
begin
|
||||||
|
TCheckListBox(WindowInfo^.WinControl).Toggle(I);
|
||||||
|
Message.Msg := LM_CHANGED;
|
||||||
|
Message.WParam := I;
|
||||||
|
DeliverMessage(WindowInfo^.WinControl, Message);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
// can only click one item
|
||||||
|
Exit;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
begin
|
||||||
|
Result := WindowProc(Window, Msg, WParam, LParam);
|
||||||
|
// move groupbox specific code here
|
||||||
|
case Msg of
|
||||||
|
WM_LBUTTONDOWN, WM_LBUTTONDBLCLK:
|
||||||
|
begin
|
||||||
|
WindowInfo := GetWin32WindowInfo(Window);
|
||||||
|
if (WindowInfo <> nil) and (WindowInfo^.WinControl <> nil) then
|
||||||
|
CheckListBoxLButtonDown;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
class function TWin32WSCustomCheckListBox.CreateHandle(
|
||||||
|
const AWinControl: TWinControl; const AParams: TCreateParams): TLCLIntfHandle;
|
||||||
|
var
|
||||||
|
Params: TCreateWindowExParams;
|
||||||
|
begin
|
||||||
|
Params := GetListBoxParams(TCustomListBox(AWinControl), AParams, True);
|
||||||
|
Params.SubClassWndProc := @CheckListBoxWndProc;
|
||||||
|
// create window
|
||||||
|
FinishCreateWindow(AWinControl, Params, False);
|
||||||
|
// listbox is not a transparent control -> no need for parentpainting
|
||||||
|
Params.WindowInfo^.needParentPaint := False;
|
||||||
|
Result := Params.Window;
|
||||||
|
end;
|
||||||
|
|
||||||
class function TWin32WSCustomCheckListBox.GetStrings(const ACustomListBox: TCustomListBox): TStrings;
|
class function TWin32WSCustomCheckListBox.GetStrings(const ACustomListBox: TCustomListBox): TStrings;
|
||||||
var
|
var
|
||||||
Handle: HWND;
|
Handle: HWND;
|
||||||
|
|||||||
@ -288,6 +288,9 @@ function EditGetSelLength(WinHandle: HWND): integer;
|
|||||||
procedure EditSetSelStart(WinHandle: HWND; NewStart: integer);
|
procedure EditSetSelStart(WinHandle: HWND; NewStart: integer);
|
||||||
procedure EditSetSelLength(WinHandle: HWND; NewLength: integer);
|
procedure EditSetSelLength(WinHandle: HWND; NewLength: integer);
|
||||||
|
|
||||||
|
function GetListBoxParams(AListBox: TCustomListBox;
|
||||||
|
const AParams: TCreateParams; IsCheckList: Boolean): TCreateWindowExParams;
|
||||||
|
|
||||||
{$DEFINE MEMOHEADER}
|
{$DEFINE MEMOHEADER}
|
||||||
{$I win32memostrings.inc}
|
{$I win32memostrings.inc}
|
||||||
{$UNDEF MEMOHEADER}
|
{$UNDEF MEMOHEADER}
|
||||||
@ -554,17 +557,15 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
class function TWin32WSCustomListBox.CreateHandle(const AWinControl: TWinControl;
|
function GetListBoxParams(AListBox: TCustomListBox;
|
||||||
const AParams: TCreateParams): HWND;
|
const AParams: TCreateParams; IsCheckList: Boolean): TCreateWindowExParams;
|
||||||
var
|
|
||||||
Params: TCreateWindowExParams;
|
|
||||||
begin
|
begin
|
||||||
// general initialization of Params
|
// general initialization of Params
|
||||||
PrepareCreateWindow(AWinControl, Params);
|
PrepareCreateWindow(AListBox, Result);
|
||||||
// customization of Params
|
// customization of Params
|
||||||
with Params do
|
with Result do
|
||||||
begin
|
begin
|
||||||
with TCustomListBox(AWinControl) do
|
with AListBox do
|
||||||
begin
|
begin
|
||||||
if Sorted then
|
if Sorted then
|
||||||
Flags := Flags or LBS_SORT;
|
Flags := Flags or LBS_SORT;
|
||||||
@ -576,7 +577,7 @@ begin
|
|||||||
if Columns > 1 then
|
if Columns > 1 then
|
||||||
Flags := Flags or LBS_MULTICOLUMN;
|
Flags := Flags or LBS_MULTICOLUMN;
|
||||||
|
|
||||||
if (AWinControl.FCompStyle = csCheckListBox) and (Style = lbStandard) then
|
if IsCheckList and (Style = lbStandard) then
|
||||||
Flags := Flags or LBS_OWNERDRAWFIXED
|
Flags := Flags or LBS_OWNERDRAWFIXED
|
||||||
else
|
else
|
||||||
case Style of
|
case Style of
|
||||||
@ -591,10 +592,18 @@ begin
|
|||||||
Flags := Flags or (WS_HSCROLL or WS_VSCROLL or LBS_NOINTEGRALHEIGHT or LBS_HASSTRINGS or
|
Flags := Flags or (WS_HSCROLL or WS_VSCROLL or LBS_NOINTEGRALHEIGHT or LBS_HASSTRINGS or
|
||||||
LBS_NOTIFY);
|
LBS_NOTIFY);
|
||||||
end;
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
class function TWin32WSCustomListBox.CreateHandle(const AWinControl: TWinControl;
|
||||||
|
const AParams: TCreateParams): HWND;
|
||||||
|
var
|
||||||
|
Params: TCreateWindowExParams;
|
||||||
|
begin
|
||||||
|
Params := GetListBoxParams(TCustomListBox(AWinControl), AParams, False);
|
||||||
// create window
|
// create window
|
||||||
FinishCreateWindow(AWinControl, Params, false);
|
FinishCreateWindow(AWinControl, Params, False);
|
||||||
// listbox is not a transparent control -> no need for parentpainting
|
// listbox is not a transparent control -> no need for parentpainting
|
||||||
Params.WindowInfo^.needParentPaint := false;
|
Params.WindowInfo^.needParentPaint := False;
|
||||||
Result := Params.Window;
|
Result := Params.Window;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user