win32: change handling of WM_MEASUREITEM:

- look at CtlType before searching for menu,
  - move ListBox, Combobox WM_MEASUREITEM to their window procedures
  - subclass ListBox, CheckListBox to set control ID on window creation
  - set control ID in FinishCreateWindow by SetWindowLong call (I previously removed it from CreateWindow call)

git-svn-id: trunk@30075 -
This commit is contained in:
paul 2011-03-30 01:38:00 +00:00
parent 86a71bfe1e
commit 4aefc884a2
5 changed files with 86 additions and 27 deletions

View File

@ -2149,29 +2149,28 @@ begin
end;
WM_MEASUREITEM:
begin
if WParam = 0 then begin
menuItem := TObject(PMeasureItemStruct(LParam)^.itemData);
if menuItem is TMenuItem then
case PMeasureItemStruct(LParam)^.CtlType of
ODT_MENU:
begin
menuItem := TObject(PMeasureItemStruct(LParam)^.itemData);
if menuItem is TMenuItem then
begin
menuHDC := GetDC(Window);
TmpSize := MenuItemSize(TMenuItem(menuItem), menuHDC);
PMeasureItemStruct(LParam)^.itemWidth := TmpSize.cx;
PMeasureItemStruct(LParam)^.itemHeight := TmpSize.cy;
ReleaseDC(Window, menuHDC);
Winprocess := False;
end
else
DebugLn('WM_MEASUREITEM for a menuitem catched but menuitem is not TmenuItem');
end;
else
if WParam <> 0 then
begin
menuHDC := GetDC(Window);
TmpSize := MenuItemSize(TMenuItem(menuItem), menuHDC);
PMeasureItemStruct(LParam)^.itemWidth := TmpSize.cx;
PMeasureItemStruct(LParam)^.itemHeight := TmpSize.cy;
ReleaseDC(Window, menuHDC);
Winprocess := False;
end else
DebugLn('WM_MEASUREITEM for a menuitem catched but menuitem is not TmenuItem');
end;
if LWinControl<>nil then begin
if LWinControl is TCustomCombobox then begin
LMessage.Msg := LM_MEASUREITEM;
LMessage.LParam := LParam;
LMessage.WParam := WParam;
Winprocess := False;
end else
if WParam <> 0 then begin
LWinControl := TWinControl(WParam);
if LWinControl<>nil then begin
lWinControl := TWinControl(WParam);
if Assigned(lWinControl) then
begin
LMessage.Msg := LM_MEASUREITEM;
LMessage.LParam := LParam;
LMessage.WParam := WParam;

View File

@ -221,6 +221,8 @@ const
ListViewClsName: array[0..13] of char = 'SysListView32'#0;
LCLComboboxClsName: array[0..11] of char = 'LCLComboBox'#0;
LCLListboxClsName: array[0..10] of char = 'LCLListBox'#0;
LCLCheckListboxClsName: array[0..15] of char = 'LCLCheckListBox'#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);

View File

@ -37,7 +37,7 @@ uses
Windows, Classes, Controls, CheckLst, StdCtrls, Themes, Graphics, LCLType, LCLProc,
LMessages, LCLMessageGlue,
////////////////////////////////////////////////////
WSCheckLst, WSLCLClasses, Win32Int, Win32Proc, Win32WSControls;
WSCheckLst, WSLCLClasses, Win32Int, Win32Proc, Win32WSControls, Win32WSStdCtrls;
type
@ -139,7 +139,7 @@ begin
end;
end;
Result := WindowProc(Window, Msg, WParam, LParam);
Result := ListBoxWindowProc(Window, Msg, WParam, LParam);
case Msg of
WM_LBUTTONDOWN, WM_LBUTTONDBLCLK:
@ -161,10 +161,11 @@ begin
with Params do
begin
pClassName := ListBoxClsName;
pSubClassName := LCLCheckListboxClsName;
SubClassWndProc := @CheckListBoxWndProc;
end;
// create window
FinishCreateWindow(AWinControl, Params, False);
FinishCreateWindow(AWinControl, Params, False, True);
// listbox is not a transparent control -> no need for parentpainting
Params.WindowInfo^.needParentPaint := False;
Result := Params.Window;

View File

@ -271,7 +271,7 @@ begin
with Params do
begin
if Window <> HWND(Nil) then
if Window <> 0 then
begin
// some controls (combobox) immediately send a message upon setting font
if not NCCreateParams.Handled then
@ -283,6 +283,10 @@ begin
if Assigned(SubClassWndProc) then
WindowInfo^.DefWndProc := Windows.WNDPROC(SetWindowLong(
Window, GWL_WNDPROC, PtrInt(SubClassWndProc)));
// Set control ID to map WinControl. This is required for messages that sent to parent
// to extract control from the passed ID.
// In case of subclassing this ID will be set in WM_NCCREATE message handler
SetWindowLong(Window, GWL_ID, PtrInt(AWinControl));
end;
if AWinControl.Font.IsDefault then

View File

@ -300,6 +300,9 @@ procedure EditSetSelLength(WinHandle: HWND; NewLength: integer);
{$I win32memostrings.inc}
{$UNDEF MEMOHEADER}
function ListBoxWindowProc(Window: HWnd; Msg: UInt; WParam: Windows.WParam;
LParam: Windows.LParam): LResult; stdcall;
implementation
const
@ -366,6 +369,7 @@ begin
WindowInfo^.WinControl.Handle := Window;
WindowInfo^.DefWndProc := NCCreateParams^.DefWndProc;
WindowInfo^.needParentPaint := False;
SetWindowLong(Window, GWL_ID, PtrInt(NCCreateParams^.WinControl));
NCCreateParams^.Handled := True;
end;
end;
@ -401,6 +405,15 @@ begin
WindowInfo := GetWin32WindowInfo(Window);
WindowInfo^.WinControl.Constraints.UpdateInterfaceConstraints;
end;
WM_MEASUREITEM:
begin
WindowInfo := GetWin32WindowInfo(Window);
LMessage.Msg := LM_MEASUREITEM;
LMessage.LParam := LParam;
LMessage.WParam := WParam;
LMessage.Result := 0;
Exit(DeliverMessage(WindowInfo^.WinControl, LMessage));
end;
end;
// normal processing
Result := WindowProc(Window, Msg, WParam, LParam);
@ -557,6 +570,42 @@ end;
{ TWin32WSCustomListBox }
function ListBoxWindowProc(Window: HWnd; Msg: UInt; WParam: Windows.WParam;
LParam: Windows.LParam): LResult; stdcall;
var
WindowInfo: PWin32WindowInfo;
NCCreateParams: PNCCreateParams;
LMessage: TLMessage;
begin
case Msg of
WM_NCCREATE:
begin
NCCreateParams := PCREATESTRUCT(lParam)^.lpCreateParams;
if Assigned(NCCreateParams) then
begin
WindowInfo := AllocWindowInfo(Window);
WindowInfo^.WinControl := NCCreateParams^.WinControl;
WindowInfo^.WinControl.Handle := Window;
WindowInfo^.DefWndProc := NCCreateParams^.DefWndProc;
WindowInfo^.needParentPaint := False;
SetWindowLong(Window, GWL_ID, PtrInt(NCCreateParams^.WinControl));
NCCreateParams^.Handled := True;
end;
end;
WM_MEASUREITEM:
begin
WindowInfo := GetWin32WindowInfo(Window);
LMessage.Msg := LM_MEASUREITEM;
LMessage.LParam := LParam;
LMessage.WParam := WParam;
LMessage.Result := 0;
Exit(DeliverMessage(WindowInfo^.WinControl, LMessage));
end;
end;
// normal processing
Result := WindowProc(Window, Msg, WParam, LParam);
end;
class procedure TWin32WSCustomListBox.AdaptBounds(
const AWinControl: TWinControl; var Left, Top, Width, Height: integer;
var SuppressMove: boolean);
@ -586,9 +635,13 @@ begin
// general initialization of Params
PrepareCreateWindow(AWinControl, AParams, Params);
with Params do
begin
pClassName := ListBoxClsName;
pSubClassName := LCLListboxClsName;
SubClassWndProc := @ListBoxWindowProc;
end;
// create window
FinishCreateWindow(AWinControl, Params, False);
FinishCreateWindow(AWinControl, Params, False, True);
// listbox is not a transparent control -> no need for parentpainting
Params.WindowInfo^.needParentPaint := False;
Result := Params.Window;