delphi dev 关于cxDropDownEdit 下拉记忆高度宽度的思路
TcxLookupComboBox 或者其他下拉空间,都是继承这个 cxDropDownEdit
cxDropDownEdit.pas
下拉触发流程:
procedure TcxCustomDropDownEdit.DoButtonDown(AButtonVisibleIndex: Integer); begin inherited DoButtonDown(AButtonVisibleIndex); if AButtonVisibleIndex = ActiveProperties.DropDownButtonVisibleIndex then DroppedDown := True; //这里触发 end; procedure TcxCustomDropDownEdit.SetDroppedDown(Value: Boolean); var AMsg: TMsg; begin if DroppedDown <> Value then if not Value then CloseUp(crUnknown) else if not PeekMessage(AMsg, PopupWindow.Handle, DXM_SHOWPOPUPWINDOW, DXM_SHOWPOPUPWINDOW, PM_NOREMOVE) then DropDown; end; procedure TcxCustomDropDownEdit.DropDown; begin if not IsWindowVisible(Handle) then Exit; DoInitPopup; if CanDropDown then begin SetupPopupWindow; //这里触发InitializePopupWindow; PopupWindow.HandleNeeded; PopupWindow.FocusedControl := GetPopupFocusedControl; PostMessage(PopupWindow.Handle, DXM_SHOWPOPUPWINDOW, 0, 0); end else DoFinalizePopup; end; procedure TcxCustomDropDownEdit.SetupPopupWindow; var P: TPoint; AParentForm: TCustomForm; begin PopupWindow.CaptureFocus := ActiveProperties.PopupWindowCapturesFocus; InitializeLookupData; InitializePopupWindow; //这里读取 PopupWindow.LockCheckSize; try PopupWindow.CalculateSize; P := PopupWindow.CalculatePosition; PopupWindow.CorrectBoundsWithDesktopWorkArea(P); finally PopupWindow.UnLockCheckSize; end; PopupWindow.SetBounds(P.X, P.Y, PopupWindow.Width, PopupWindow.Height); PopupWindow.RefreshPopupWindow; PositionPopupWindowChilds(PopupWindow.ViewInfo.ClientRect); SetEditPopupWindowShadowRegion(PopupWindow); if IsWinXPOrLater then // W2K bug begin AParentForm := GetParentForm(Self); if AParentForm <> nil then begin PopupWindow.AlphaBlend := TCustomFormAccess(AParentForm).AlphaBlend; PopupWindow.AlphaBlendValue := TCustomFormAccess(AParentForm).AlphaBlendValue; PopupWindow.TransparentColor := TCustomFormAccess(AParentForm).TransparentColor; PopupWindow.TransparentColorValue := TCustomFormAccess(AParentForm).TransparentColorValue; end; end; end; procedure TcxCustomDropDownEdit.InitializePopupWindow; begin PopupWindow.OwnerParent := Parent; with ActiveProperties do begin PopupWindow.Direction := PopupDirection; PopupWindow.AlignHorz := PopupHorzAlignment; PopupWindow.AlignVert := PopupVertAlignment; PopupWindow.ClientEdge := PopupClientEdge; PopupWindow.MinHeight := PopupMinHeight; PopupWindow.MinWidth := PopupMinWidth; PopupWindow.PopupAutoSize := PopupAutoSize; PopupWindow.Sizeable := PopupSizeable; PopupWindow.SysPanelStyle := PopupSysPanelStyle; end; PopupWindow.PopupWidth := GetPopupWidth; PopupWindow.PopupHeight := GetPopupHeight; PopupWindow.CloseButton := TcxCustomEditStyleAccess(ActiveStyle).PopupCloseButton; with ViewInfo do begin PopupWindow.BorderStyle := PopupBorderStyle; PopupWindow.NativeStyle := NativeStyle; PopupWindow.Shadow := Shadow; end; end; //这里如果是能改变大小的话是读取editdata的 改动后也是保存在editdata function TcxCustomDropDownEdit.GetPopupWidth: Integer; begin if IsInplace and ActiveProperties.PopupSizeable then Result := TcxCustomDropDownEditData(EditData).Width //这里控件创建成功后会读取 Properties.DropDownWidth 但也只限在创建初始化时,后续都是读取在editdata里。也可以用在同单元type一下这个类然后就可以操作editdata了 else Result := ActiveProperties.PopupWidth; end; procedure TcxCustomEditPopupWindow.ResizePopupWindow(ALeft, ATop, AWidth, AHeight: Integer); begin Edit.FPopupSizeChanged := True; SetBounds(ALeft, ATop, AWidth, AHeight); RefreshPopupWindow; Edit.StorePopupSize; end; //保存 procedure TcxCustomDropDownEdit.StorePopupSize; begin if ActiveProperties.PopupSizeable then if IsInplace then begin if EditData <> nil then with TcxCustomDropDownEditData(EditData) do begin Initialized := True; Width := PopupWindow.Width; Height := PopupWindow.Height; end end else begin with ActiveProperties do begin PopupWidth := PopupWindow.Width; PopupHeight := PopupWindow.Height; end; end; end;
整体思路:
1.控件创建后,先设置一下 Properties.DropDownWidth Properties.DropDownHeight
2.然后在closeup时写入,不要在窗口销毁或者关闭时 去循环每个控件记录这样慢。直接在closeup后保存就可以。目前选择的是下面的方案,其实哪个都可以能记忆就行
目前保存宽度信息是hook了,其实也可以hook TcxCustomDropDownEdit.CloseUp
HookProc(@TcxCustomPopupWindow.CloseUp, @cxCustomPopupWindowCloseUpCallBack, @cxCustomPopupWindowCloseUpNext);
TcxCustomDropDownEdit.CloseUp
会触发 PopupWindow.CloseUp;
hook了 TcxCustomPopupWindow.CloseUp
要全局处理的思路: 1.hook procedure TcxCustomDropDownEdit.DropDown; 设置 Properties.DropDownWidth Properties.DropDownHeight 或者修改EditData 因为EditData是 protected的,所以在目标单元里先type一下为其他的类名(同名也可以但是最好还是不要一样) 2.hook TcxCustomDropDownEdit.CloseUp 读取EditData 的Width,Height 到ini即可 // 修改EditData 的方法 uses cxEdit,cxDropDownEdit; type TcxCustomDropDownEditAccess = class(cxDropDownEdit.TcxCustomDropDownEdit) public // function EditDataAccess:TcxCustomEditData; procedure SetEditData(aWidth, aHeight: Integer); end; TcxCustomDropDownEditDataAccess = class(cxDropDownEdit.TcxCustomDropDownEditData) // public // Initialized: Boolean; // Width, Height: Integer; end; //多开放出一个修改EditData 的过程出来。 procedure TcxCustomDropDownEditAccess.SetEditData(aWidth, aHeight: Integer); begin with TcxCustomDropDownEditDataAccess(EditData) do begin Initialized := True; if aWidth > 0 then Width := aWidth; if aHeight > 0 then aHeight := Height; end; end;
不明白为啥本身不提供这种功能,设置个保存的路径,自动保存就可以。甚至可以加个开关要不要自动保存。
补充:
seteditdata还不够还要设置 Properties,不然输入时宽度会不对
cbb.Properties.DropDownWidth := PopupWindowWidth;
cbb.Properties.DropDownHeight := PopupWindowHeight;

浙公网安备 33010602011771号