diff --git a/lcl/include/customform.inc b/lcl/include/customform.inc index 80a6f9a024..19ca4872ad 100644 --- a/lcl/include/customform.inc +++ b/lcl/include/customform.inc @@ -2881,11 +2881,8 @@ begin Application.ModalStarted; try Include(FFormState, fsModal); - if PopupMode = pmNone then - begin - RecreateWnd(Self); - HandleNeeded; - end; + if (PopupMode = pmNone) and HandleAllocated then + RecreateWnd(Self); // need to refresh handle for pmNone because ParentWindow changes if (fsModal in FFormState) - see GetRealPopupParent ActiveWindow := GetActiveWindow; SavedFocusState := SaveFocusState; SavedCursor := Screen.Cursor; @@ -2954,6 +2951,8 @@ begin if LCLIntf.IsWindow(ActiveWindow) then SetActiveWindow(ActiveWindow); Exclude(FFormState, fsModal); + if ((PopupMode = pmNone) and HandleAllocated) and not (csDestroying in ComponentState) then + RecreateWnd(Self); // need to refresh handle for pmNone because ParentWindow changes if (fsModal in FFormState) - see GetRealPopupParent end; finally Application.ModalFinished; diff --git a/lcl/include/listcolumn.inc b/lcl/include/listcolumn.inc index 331755f96c..73d8e5d5c7 100644 --- a/lcl/include/listcolumn.inc +++ b/lcl/include/listcolumn.inc @@ -163,6 +163,8 @@ begin LV := TListColumns(Collection).FOwner; TWSCustomListViewClass(LV.WidgetSetClass).ColumnSetCaption(LV, Index, Self, FCaption); + if FAutoSize then + TWSCustomListViewClass(LV.WidgetSetClass).ColumnSetAutosize(LV, Index, Self, FAutosize); end; procedure TListColumn.SetWidth(const AValue: TWidth); diff --git a/lcl/interfaces/win32/win32wscomctrls.pp b/lcl/interfaces/win32/win32wscomctrls.pp index 7da4ce095b..482f2a7426 100644 --- a/lcl/interfaces/win32/win32wscomctrls.pp +++ b/lcl/interfaces/win32/win32wscomctrls.pp @@ -114,6 +114,7 @@ type TWin32WSCustomListView = class(TWSCustomListView) private + class procedure ColumnDoAutosize(const ALV: TCustomListView; const AIndex: Integer); class function GetHeader(const AHandle: THandle): THandle; class procedure PositionHeader(const AHandle: THandle); class procedure UpdateStyle(const AHandle: THandle; const AMask, AStyle: Integer); diff --git a/lcl/interfaces/win32/win32wscustomlistview.inc b/lcl/interfaces/win32/win32wscustomlistview.inc index 7a0b2feca8..53ca469e05 100644 --- a/lcl/interfaces/win32/win32wscustomlistview.inc +++ b/lcl/interfaces/win32/win32wscustomlistview.inc @@ -10,8 +10,6 @@ } { TWin32WSCustomListView } -const - AutoSizeWidth = LVSCW_AUTOSIZE_USEHEADER; type TLVStyleType = (lsStyle, lsInvert, lsExStyle); @@ -260,6 +258,33 @@ end; // Column code //////////////////////////////////////////////////////////////////////////////// +class procedure TWin32WSCustomListView.ColumnDoAutosize(const ALV: TCustomListView; const AIndex: Integer); +var + CaptionSize: TSize; +begin + if (ALV.Items.Count > 0) then + ListView_SetColumnWidth(ALV.Handle, AIndex, LVSCW_AUTOSIZE) + else + begin + // normally, we have to use ListView_GetStringWidth, but it doesn't work with + // Unicode, so we take a universal function to get the width of the caption + if GetTextExtentPoint32W(ALV.Canvas.Handle, + PWideChar(UTF8ToUTF16(ALV.Column[AIndex].Caption)), + UTF8Length(ALV.Column[AIndex].Caption), + CaptionSize) then + begin + // to retrieve the column width that can contain the string without + // truncating it, you must add padding to the returned string width + // see msdn: ListView_GetStringWidth + // there is no way to get the needed padding size for a list view caption + // so we take the height of the current caption text, to be DPI aware + ListView_SetColumnWidth(ALV.Handle, AIndex, CaptionSize.cx + CaptionSize.cy); + end + else + ListView_SetColumnWidth(ALV.Handle, AIndex, TListColumnAccess(ALV.Column[AIndex]).GetStoredWidth); + end; +end; + class procedure TWin32WSCustomListView.ColumnDelete(const ALV: TCustomListView; const AIndex: Integer); var hHdr, hLV: THandle; @@ -387,7 +412,7 @@ begin then Exit; if AAutoSize - then ListView_SetColumnWidth(ALV.Handle, AIndex, AutoSizeWidth) + then ColumnDoAutosize(ALV, AIndex) else ListView_SetColumnWidth(ALV.Handle, AIndex, TListColumnAccess(AColumn).GetStoredWidth); end; @@ -461,7 +486,7 @@ begin then Exit; if AColumn.AutoSize - then ListView_SetColumnWidth(ALV.Handle, AIndex, AutoSizeWidth) + then ColumnDoAutosize(ALV, AIndex) else ListView_SetColumnWidth(ALV.Handle, AIndex, AWidth) end; @@ -474,7 +499,7 @@ begin if AVisible then if AColumn.AutoSize - then ListView_SetColumnWidth(ALV.Handle, AIndex, AutoSizeWidth) + then ColumnDoAutosize(ALV, AIndex) else ListView_SetColumnWidth(ALV.Handle, AIndex, TListColumnAccess(AColumn).GetStoredWidth) else ListView_SetColumnWidth(ALV.Handle, AIndex, 0); end; @@ -715,7 +740,7 @@ begin // it only once per column. if (ASubIndex >= 0) and (ASubIndex < ALV.ColumnCount) and ALV.Column[ASubIndex].AutoSize and (TCustomListViewAccess(ALV).GetUpdateCount = 0) then - ListView_SetColumnWidth(ALV.Handle, ASubIndex, AutoSizeWidth); + ColumnDoAutosize(ALV, ASubIndex); end; class procedure TWin32WSCustomListView.ItemShow(const ALV: TCustomListView; const AIndex: Integer; const AItem: TListItem; const PartialOK: Boolean); @@ -792,8 +817,8 @@ begin // so it won't flicker at all. ShowWindow(ALV.Handle, SW_HIDE); for ColIndex := 0 to TCustomListViewAccess(ALV).Columns.Count - 1 do - if ALV.Column[ColIndex].AutoSize then - ListView_SetColumnWidth(ALV.Handle, ColIndex, AutoSizeWidth); + if ALV.Column[ColIndex].AutoSize + then ColumnDoAutosize(ALV, ColIndex); SendMessage(ALV.Handle,WM_SETREDRAW,WPARAM(True),0); if ALV.Visible then diff --git a/lcl/interfaces/win32/win32wsstdctrls.pp b/lcl/interfaces/win32/win32wsstdctrls.pp index bd8c735398..48b2e3973b 100644 --- a/lcl/interfaces/win32/win32wsstdctrls.pp +++ b/lcl/interfaces/win32/win32wsstdctrls.pp @@ -1340,6 +1340,28 @@ end; { TWin32WSCustomMemo } +function MemoWndProc(Window: HWnd; Msg: UInt; WParam: Windows.WParam; + LParam: Windows.LParam): LResult; stdcall; +var + Control: TWinControl; + LMessage: TLMessage; +begin + case Msg of + // prevent flickering, Mantis #16140 + WM_ERASEBKGND: + begin + Control := GetWin32WindowInfo(Window)^.WinControl; + LMessage.msg := Msg; + LMessage.wParam := WParam; + LMessage.lParam := LParam; + LMessage.Result := 0; + Result := DeliverMessage(Control, LMessage); + end; + else + Result := WindowProc(Window, Msg, WParam, LParam); + end; +end; + class function TWin32WSCustomMemo.CreateHandle(const AWinControl: TWinControl; const AParams: TCreateParams): HWND; var @@ -1351,6 +1373,7 @@ begin with Params do begin pClassName := @EditClsName[0]; + SubClassWndProc := @MemoWndProc; WindowTitle := StrCaption; end; // create window