mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-06 01:26:24 +02:00
win32:
- redo FinishCreateWindow to allow window subclassing, - subclass combobox to get access to the first messages that control receives ideintf: remove workaround with ValueComboBox handle check in MeasureItem git-svn-id: trunk@24686 -
This commit is contained in:
parent
3fce5af5cc
commit
f95b2f63d5
@ -1468,7 +1468,7 @@ procedure TOICustomPropertyGrid.ValueComboBoxMeasureItem(Control: TWinControl;
|
|||||||
var
|
var
|
||||||
CurRow: TOIPropertyGridRow;
|
CurRow: TOIPropertyGridRow;
|
||||||
begin
|
begin
|
||||||
if (FItemIndex >= 0) and (FItemIndex < FRows.Count) and (ValueComboBox.HandleAllocated) then
|
if (FItemIndex >= 0) and (FItemIndex < FRows.Count) then
|
||||||
begin
|
begin
|
||||||
CurRow := Rows[FItemIndex];
|
CurRow := Rows[FItemIndex];
|
||||||
CurRow.Editor.ListMeasureHeight('Fj', Index, ValueComboBox.Canvas, AHeight);
|
CurRow.Editor.ListMeasureHeight('Fj', Index, ValueComboBox.Canvas, AHeight);
|
||||||
|
@ -85,7 +85,7 @@ function CallDefaultWindowProc(Window: HWnd; Msg: UInt; WParam: Windows.WParam;
|
|||||||
var
|
var
|
||||||
Info: TComboboxInfo;
|
Info: TComboboxInfo;
|
||||||
begin
|
begin
|
||||||
Result := WndClassName(Window) = ComboboxClsName;
|
Result := WndClassName(Window) = LCLComboboxClsName;
|
||||||
if not Result then
|
if not Result then
|
||||||
Exit;
|
Exit;
|
||||||
Info.cbSize := SizeOf(Info);
|
Info.cbSize := SizeOf(Info);
|
||||||
|
@ -221,6 +221,7 @@ const
|
|||||||
TabControlClsName: array[0..15] of char = 'SysTabControl32'#0;
|
TabControlClsName: array[0..15] of char = 'SysTabControl32'#0;
|
||||||
ListViewClsName: array[0..13] of char = 'SysListView32'#0;
|
ListViewClsName: array[0..13] of char = 'SysListView32'#0;
|
||||||
|
|
||||||
|
LCLComboboxClsName: array[0..11] of char = 'LCLComboBox'#0;
|
||||||
ClsNameW: array[0..6] of WideChar = ('W', 'i', 'n', 'd', 'o', 'w', #0);
|
ClsNameW: array[0..6] of WideChar = ('W', 'i', 'n', 'd', 'o', 'w', #0);
|
||||||
ClsHintNameW: array[0..10] of WideChar = ('H', 'i', 'n', 't', 'W', 'i', 'n', 'd', 'o', 'w', #0);
|
ClsHintNameW: array[0..10] of WideChar = ('H', 'i', 'n', 't', 'W', 'i', 'n', 'd', 'o', 'w', #0);
|
||||||
|
|
||||||
|
@ -117,15 +117,23 @@ type
|
|||||||
SubClassWndProc: pointer;
|
SubClassWndProc: pointer;
|
||||||
StrCaption, WindowTitle: String;
|
StrCaption, WindowTitle: String;
|
||||||
pClassName: PChar;
|
pClassName: PChar;
|
||||||
|
pSubClassName: PChar;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
TNCCreateParams = record
|
||||||
|
WinControl: TWinControl;
|
||||||
|
DefWndProc: WNDPROC;
|
||||||
|
Handled: Boolean;
|
||||||
|
end;
|
||||||
|
PNCCreateParams = ^TNCCreateParams;
|
||||||
|
|
||||||
|
|
||||||
// TODO: better names?
|
// TODO: better names?
|
||||||
|
|
||||||
procedure PrepareCreateWindow(const AWinControl: TWinControl;
|
procedure PrepareCreateWindow(const AWinControl: TWinControl;
|
||||||
const CreateParams: TCreateParams; var Params: TCreateWindowExParams);
|
const CreateParams: TCreateParams; var Params: TCreateWindowExParams);
|
||||||
procedure FinishCreateWindow(const AWinControl: TWinControl; var Params: TCreateWindowExParams;
|
procedure FinishCreateWindow(const AWinControl: TWinControl; var Params: TCreateWindowExParams;
|
||||||
const AlternateCreateWindow: boolean);
|
const AlternateCreateWindow: boolean; SubClass: Boolean = False);
|
||||||
procedure WindowCreateInitBuddy(const AWinControl: TWinControl;
|
procedure WindowCreateInitBuddy(const AWinControl: TWinControl;
|
||||||
var Params: TCreateWindowExParams);
|
var Params: TCreateWindowExParams);
|
||||||
|
|
||||||
@ -186,36 +194,84 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
procedure FinishCreateWindow(const AWinControl: TWinControl; var Params: TCreateWindowExParams;
|
procedure FinishCreateWindow(const AWinControl: TWinControl; var Params: TCreateWindowExParams;
|
||||||
const AlternateCreateWindow: boolean);
|
const AlternateCreateWindow: boolean; SubClass: Boolean = False);
|
||||||
var
|
var
|
||||||
lhFont: HFONT;
|
lhFont: HFONT;
|
||||||
AErrorCode: Cardinal;
|
AErrorCode: Cardinal;
|
||||||
|
NCCreateParams: TNCCreateParams;
|
||||||
|
WindowClass, DummyClass: WndClass;
|
||||||
|
{$ifdef WindowsUnicodeSupport}
|
||||||
|
WindowClassW, DummyClassW: WndClassW;
|
||||||
|
{$endif}
|
||||||
begin
|
begin
|
||||||
|
NCCreateParams.DefWndProc := nil;
|
||||||
|
NCCreateParams.WinControl := AWinControl;
|
||||||
|
NCCreateParams.Handled := False;
|
||||||
|
|
||||||
if not AlternateCreateWindow then
|
if not AlternateCreateWindow then
|
||||||
begin
|
begin
|
||||||
with Params do
|
with Params do
|
||||||
begin
|
begin
|
||||||
if (Flags and WS_CHILD) <> 0 then
|
if SubClass then
|
||||||
begin
|
begin
|
||||||
// menu handle is also for specifying a control id if this is a child
|
{$ifdef WindowsUnicodeSupport}
|
||||||
MenuHandle := HMENU(AWinControl);
|
if UnicodeEnabledOS then
|
||||||
end else begin
|
begin
|
||||||
MenuHandle := HMENU(nil);
|
if GetClassInfoW(System.HInstance, PWideChar(WideString(pClassName)), @WindowClassW) then
|
||||||
|
begin
|
||||||
|
NCCreateParams.DefWndProc := WndProc(WindowClassW.lpfnWndProc);
|
||||||
|
if not GetClassInfoW(System.HInstance, PWideChar(WideString(pSubClassName)), @DummyClassW) then
|
||||||
|
begin
|
||||||
|
with WindowClassW do
|
||||||
|
begin
|
||||||
|
LPFnWndProc := SubClassWndProc;
|
||||||
|
hInstance := System.HInstance;
|
||||||
|
lpszClassName := PWideChar(WideString(pSubClassName));
|
||||||
|
end;
|
||||||
|
Windows.RegisterClassW(@WindowClassW);
|
||||||
|
end;
|
||||||
|
pClassName := pSubClassName;
|
||||||
|
end;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
{$endif}
|
||||||
|
begin
|
||||||
|
if GetClassInfo(System.HInstance, pClassName, @WindowClass) then
|
||||||
|
begin
|
||||||
|
NCCreateParams.DefWndProc := WndProc(WindowClass.lpfnWndProc);
|
||||||
|
if not GetClassInfo(System.HInstance, pSubClassName, @DummyClass) then
|
||||||
|
begin
|
||||||
|
with WindowClass do
|
||||||
|
begin
|
||||||
|
LPFnWndProc := SubClassWndProc;
|
||||||
|
hInstance := System.HInstance;
|
||||||
|
lpszClassName := pSubClassName;
|
||||||
|
end;
|
||||||
|
Windows.RegisterClass(@WindowClass);
|
||||||
|
end;
|
||||||
|
pClassName := pSubClassName;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
|
if (Flags and WS_CHILD) <> 0 then
|
||||||
|
// menu handle is also for specifying a control id if this is a child
|
||||||
|
MenuHandle := HMENU(AWinControl)
|
||||||
|
else
|
||||||
|
MenuHandle := HMENU(nil);
|
||||||
|
|
||||||
{$ifdef WindowsUnicodeSupport}
|
{$ifdef WindowsUnicodeSupport}
|
||||||
if UnicodeEnabledOS then
|
if UnicodeEnabledOS then
|
||||||
Window := CreateWindowExW(FlagsEx, PWideChar(WideString(pClassName)),
|
Window := CreateWindowExW(FlagsEx, PWideChar(WideString(pClassName)),
|
||||||
PWideChar(UTF8ToUTF16(WindowTitle)), Flags,
|
PWideChar(UTF8ToUTF16(WindowTitle)), Flags,
|
||||||
Left, Top, Width, Height, Parent, MenuHandle, HInstance, nil)
|
Left, Top, Width, Height, Parent, MenuHandle, HInstance, @NCCreateParams)
|
||||||
else
|
else
|
||||||
Window := CreateWindowEx(FlagsEx, pClassName,
|
Window := CreateWindowEx(FlagsEx, pClassName,
|
||||||
PChar(Utf8ToAnsi(WindowTitle)), Flags,
|
PChar(Utf8ToAnsi(WindowTitle)), Flags,
|
||||||
Left, Top, Width, Height, Parent, MenuHandle, HInstance, nil);
|
Left, Top, Width, Height, Parent, MenuHandle, HInstance, @NCCreateParams);
|
||||||
{$else}
|
{$else}
|
||||||
Window := CreateWindowEx(FlagsEx, pClassName,
|
Window := CreateWindowEx(FlagsEx, pClassName,
|
||||||
PChar(WindowTitle), Flags,
|
PChar(WindowTitle), Flags,
|
||||||
Left, Top, Width, Height, Parent, MenuHandle, HInstance, nil);
|
Left, Top, Width, Height, Parent, MenuHandle, HInstance, @NCCreateParams);
|
||||||
{$endif}
|
{$endif}
|
||||||
|
|
||||||
if Window = 0 then
|
if Window = 0 then
|
||||||
@ -240,14 +296,18 @@ begin
|
|||||||
if Window <> HWND(Nil) then
|
if Window <> HWND(Nil) then
|
||||||
begin
|
begin
|
||||||
// some controls (combobox) immediately send a message upon setting font
|
// some controls (combobox) immediately send a message upon setting font
|
||||||
WindowInfo := AllocWindowInfo(Window);
|
if not NCCreateParams.Handled then
|
||||||
if GetWin32WindowInfo(Parent)^.needParentPaint then
|
begin
|
||||||
WindowInfo^.needParentPaint := true;
|
WindowInfo := AllocWindowInfo(Window);
|
||||||
WindowInfo^.WinControl := AWinControl;
|
if GetWin32WindowInfo(Parent)^.needParentPaint then
|
||||||
AWinControl.Handle := Window;
|
WindowInfo^.needParentPaint := true;
|
||||||
if SubClassWndProc <> nil then
|
WindowInfo^.WinControl := AWinControl;
|
||||||
WindowInfo^.DefWndProc := Windows.WNDPROC(SetWindowLong(
|
AWinControl.Handle := Window;
|
||||||
Window, GWL_WNDPROC, PtrInt(SubClassWndProc)));
|
if Assigned(SubClassWndProc) then
|
||||||
|
WindowInfo^.DefWndProc := Windows.WNDPROC(SetWindowLong(
|
||||||
|
Window, GWL_WNDPROC, PtrInt(SubClassWndProc)));
|
||||||
|
end;
|
||||||
|
|
||||||
if AWinControl.Font.IsDefault then
|
if AWinControl.Font.IsDefault then
|
||||||
lhFont := Win32WidgetSet.DefaultFont
|
lhFont := Win32WidgetSet.DefaultFont
|
||||||
else
|
else
|
||||||
|
@ -350,21 +350,38 @@ function ComboBoxWindowProc(Window: HWnd; Msg: UInt; WParam: Windows.WParam;
|
|||||||
LParam: Windows.LParam): LResult; stdcall;
|
LParam: Windows.LParam): LResult; stdcall;
|
||||||
var
|
var
|
||||||
Info: TComboboxInfo;
|
Info: TComboboxInfo;
|
||||||
|
WindowInfo: PWin32WindowInfo;
|
||||||
|
NCCreateParams: PNCCreateParams;
|
||||||
begin
|
begin
|
||||||
// darn MS: if combobox has edit control, and combobox receives focus, it
|
// darn MS: if combobox has edit control, and combobox receives focus, it
|
||||||
// passes it on to the edit, so it will send a WM_KILLFOCUS; inhibit
|
// passes it on to the edit, so it will send a WM_KILLFOCUS; inhibit
|
||||||
// also don't pass WM_SETFOCUS to the lcl,
|
// also don't pass WM_SETFOCUS to the lcl,
|
||||||
// it will get one from the edit control
|
// it will get one from the edit control
|
||||||
if ((Msg = WM_KILLFOCUS) or (Msg = WM_SETFOCUS)) then
|
case Msg of
|
||||||
begin
|
WM_NCCREATE:
|
||||||
Info.cbSize := SizeOf(Info);
|
begin
|
||||||
Win32Extra.GetComboBoxInfo(Window, @Info);
|
NCCreateParams := PCREATESTRUCT(lParam)^.lpCreateParams;
|
||||||
if (HWND(WParam) = Info.hwndItem) or (HWND(WParam) = Info.hwndList) then
|
if Assigned(NCCreateParams) then
|
||||||
begin
|
begin
|
||||||
// continue normal processing, don't send to lcl
|
WindowInfo := AllocWindowInfo(Window);
|
||||||
Result := CallDefaultWindowProc(Window, Msg, WParam, LParam);
|
WindowInfo^.WinControl := NCCreateParams^.WinControl;
|
||||||
Exit;
|
WindowInfo^.WinControl.Handle := Window;
|
||||||
end;
|
WindowInfo^.DefWndProc := NCCreateParams^.DefWndProc;
|
||||||
|
WindowInfo^.needParentPaint := False;
|
||||||
|
NCCreateParams^.Handled := True;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
WM_KILLFOCUS, WM_SETFOCUS:
|
||||||
|
begin
|
||||||
|
Info.cbSize := SizeOf(Info);
|
||||||
|
Win32Extra.GetComboBoxInfo(Window, @Info);
|
||||||
|
if (HWND(WParam) = Info.hwndItem) or (HWND(WParam) = Info.hwndList) then
|
||||||
|
begin
|
||||||
|
// continue normal processing, don't send to lcl
|
||||||
|
Result := CallDefaultWindowProc(Window, Msg, WParam, LParam);
|
||||||
|
Exit;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
// normal processing
|
// normal processing
|
||||||
Result := WindowProc(Window, Msg, WParam, LParam);
|
Result := WindowProc(Window, Msg, WParam, LParam);
|
||||||
@ -799,13 +816,12 @@ begin
|
|||||||
if TComboBox(AWinControl).Sorted Then
|
if TComboBox(AWinControl).Sorted Then
|
||||||
Flags:= Flags or CBS_SORT;
|
Flags:= Flags or CBS_SORT;
|
||||||
pClassName := ComboboxClsName;
|
pClassName := ComboboxClsName;
|
||||||
|
pSubClassName := LCLComboboxClsName;
|
||||||
Flags := Flags or (WS_VSCROLL or CBS_AUTOHSCROLL or CBS_HASSTRINGS);
|
Flags := Flags or (WS_VSCROLL or CBS_AUTOHSCROLL or CBS_HASSTRINGS);
|
||||||
SubClassWndProc := @ComboBoxWindowProc;
|
SubClassWndProc := @ComboBoxWindowProc;
|
||||||
end;
|
end;
|
||||||
// create window
|
// create window
|
||||||
FinishCreateWindow(AWinControl, Params, false);
|
FinishCreateWindow(AWinControl, Params, False, True);
|
||||||
// combobox is not a transparent control -> no need for parentpainting
|
|
||||||
Params.WindowInfo^.needParentPaint := false;
|
|
||||||
|
|
||||||
Info.cbSize:= SizeOf(Info);
|
Info.cbSize:= SizeOf(Info);
|
||||||
Win32Extra.GetComboBoxInfo(Params.Window, @Info);
|
Win32Extra.GetComboBoxInfo(Params.Window, @Info);
|
||||||
|
Loading…
Reference in New Issue
Block a user