cxshellcombobox.pas

来自「胜天进销存源码,国产优秀的进销存」· PAS 代码 · 共 1,877 行 · 第 1/5 页

PAS
1,877
字号
            else
              S1 := Copy(S2, Length(S1) + 2, Length(S2) - Length(S1) - 1);
            if (Length(S1) >= 1) and (S1[1] = '\') then
              S1 := Copy(S1, 2, Length(S1) - 1);
            ANewEditValue := S1;
          end
          else
            ANewEditValue := GetPidlName(APIDL);
        end
        else
          ANewEditValue := APidlName;
        S1 := GetPIDLDisplayName(APIDL, (ActiveProperties.ShowFullPath = sfpAlways) or
          (ActiveProperties.ShowFullPath = sfpNotFocused) and not IsFocused);
      end;
    GetShellSysIconIndex(APIDL, ViewInfo.ShellSysIconIndex,
      ViewInfo.ShellSysIconOverlayIndex);
  end;

  AIsEditValueChanged := (VarType(FEditValue) <> VarType(ANewEditValue)) or
      not VarEqualsExact(FEditValue, ANewEditValue);
  FEditValue := ANewEditValue;

  DataBinding.DisplayValue := S1;
//  SelStart := Length(S1);
  InvalidateShellIconRect;

  if AIsEditValueChanged then
    DoEditValueChanged;
end;

procedure TcxCustomShellComboBox.InvalidateShellIconRect;
begin
  with ViewInfo.ShellIconPosition do
    InvalidateRect(Rect(X, Y, X + cxShellComboBoxImageList.Width, Y +
      cxShellComboBoxImageList.Height), False);
end;

procedure TcxCustomShellComboBox.SelectedNodeChangeHandler(Sender: TObject;
  ANode: TTreeNode);
var
  ANodeIndex: Integer;
begin
  if (not HasPopupWindow) and not FNotificationFromDependentShellControls then
    Exit;

  ANodeIndex := -1;
  TraverseAllVisibleNodes(ANodeIndex, ANode);
  TcxShellComboBoxLookupData(FLookupData).InternalSetCurrentKey(ANodeIndex);

  if FIsSelectedNodeChangeEventLocked or (not FPopupWindowShowing and
    not DataBinding.Modified and not DoEditing) then
      Exit;

  DataBinding.DisplayValue :=
    GetPIDLDisplayName(FPopupShellTreeView.GetNodeAbsolutePIDL(ANode),
      ActiveProperties.ShowFullPath = sfpAlways);
  if FPopupWindowShowing then
    ModifiedAfterEnter := False
  else
    if IsFocused then
      ModifiedAfterEnter := True;
  SelStart := Length(DataBinding.DisplayValue);
  ViewInfo.ShellSysIconIndex := ANode.ImageIndex;
  ViewInfo.ShellSysIconOverlayIndex := ANode.OverlayIndex;
  InvalidateShellIconRect;

  if ActiveProperties.ImmediatePost and CanPostEditValue and ValidateEdit(True) then
    InternalPostEditValue;
end;

procedure TcxCustomShellComboBox.SynchronizeDependentShellControls;
var
  ATempPIDL: PItemIDList;
begin
  if FIsDependentShellControlsNotification or FNotificationFromDependentShellControls then
    Exit;
  FIsDependentShellControlsNotification := True;
  try
    if FAbsolutePIDL = nil then
      Exit;
    ATempPIDL := GetPidlCopy(FAbsolutePIDL);
    try
      if (FShellTreeView <> nil) and FShellTreeView.HandleAllocated then
        SendMessage(FShellTreeView.InnerTreeView.Handle, DSM_DONAVIGATE,
          Integer(ATempPIDL), 0);

      if FShellListView <> nil then
        FShellListView.ProcessTreeViewNavigate(ATempPIDL);

      SynchronizePopupShellTreeView;
    finally
      DisposePidl(ATempPIDL);
    end;
  finally
    FIsDependentShellControlsNotification := False;
  end;
end;

procedure TcxCustomShellComboBox.SynchronizePopupShellTreeView;
begin
  if FAbsolutePIDL = nil then
    Exit;

  if not IsDesigning and (FPopupShellTreeView <> nil) and (HasPopupWindow(* or not IsInplace*)) then
    with FPopupShellTreeView do
      if (Parent <> nil) and Parent.HandleAllocated and (InnerTreeView <> nil) then
      begin
        InnerTreeView.HandleNeeded;
        SendMessage(InnerTreeView.Handle, DSM_DONAVIGATE, WPARAM(FAbsolutePIDL), 0);
      end;
end;

function TcxCustomShellComboBox.TraverseAllVisibleNodes(var ANodeIndex: Integer;
  ATreeNode: TTreeNode = nil): TTreeNode;
var
  ANodeCount: Integer;

  function InternalTraverseAllVisibleNodes(ANode: TTreeNode): TTreeNode;
  var
    AChildNode: TTreeNode;
  begin
    Result := nil;
    if ANode = nil then
      Exit;
    if (ANodeCount = ANodeIndex) or (ANode = ATreeNode) then
    begin
      Result := ANode;
      Exit;
    end;
    Inc(ANodeCount);
    if not ANode.Expanded then
      Exit;
    AChildNode := ANode.GetFirstChild;
    while AChildNode <> nil do
    begin
      Result := InternalTraverseAllVisibleNodes(AChildNode);
      if Result <> nil then
        Break;
      AChildNode := ANode.GetNextChild(AChildNode);
    end;
  end;

begin
  CheckPopupShellTreeView;
  ANodeCount := 0;
  if FPopupShellTreeView = nil then
    Result := nil
  else
    with FPopupShellTreeView.InnerTreeView do
      Result := InternalTraverseAllVisibleNodes(Items.GetFirstNode);
  ANodeIndex := ANodeCount;
end;

procedure TcxCustomShellComboBox.AddFolderHandler(Sender: TObject;
  AFolder: TcxShellFolder; var ACanAdd: Boolean);

  procedure DoAddFolder(AProperties: TcxCustomShellComboBoxProperties);
  begin
    with AProperties do
      if Assigned(OnAddFolder) then
        OnAddFolder(Self, AFolder, ACanAdd);
  end;

begin
  DoAddFolder(Properties);
  if ACanAdd and (RepositoryItem <> nil) then
    DoAddFolder(ActiveProperties);
end;

function TcxCustomShellComboBox.GetAbsolutePIDL: PItemIDList;
begin
  Result := GetPidlCopy(FAbsolutePIDL);
end;

function TcxCustomShellComboBox.GetActiveProperties: TcxCustomShellComboBoxProperties;
begin
  Result := TcxCustomShellComboBoxProperties(InternalGetActiveProperties);
end;

function TcxCustomShellComboBox.GetPath: string;
begin
  if FAbsolutePIDL = nil then
    Result := ''
  else
    Result := GetPidlName(FAbsolutePIDL);
end;

function TcxCustomShellComboBox.GetProperties: TcxCustomShellComboBoxProperties;
begin
  Result := TcxCustomShellComboBoxProperties(FProperties);
end;

(*function TcxCustomShellComboBox.GetRelativePath: string;
begin
end;*)

function TcxCustomShellComboBox.GetViewInfo: TcxShellComboBoxViewInfo;
begin
  Result := TcxShellComboBoxViewInfo(FViewInfo);
end;

procedure TcxCustomShellComboBox.RootChangeHandler(Sender: TObject);
begin
  if not IsDesigning then
    FPopupShellTreeView.Root.Assign(ActiveProperties.Root);
  if not ActiveProperties.ChangedLocked and not ModifiedAfterEnter then
    SynchronizeDisplayValue;
end;

procedure TcxCustomShellComboBox.RootSettingsChanged(Sender: TObject);
begin
  if IsLoading then
    Exit;
  if (ShellListView <> nil) and ShellListView.HandleAllocated then
    SendMessage(ShellListView.InnerListView.Handle, DSM_SYNCHRONIZEROOT,
      Integer(ActiveProperties.Root), 0);
  if (ShellTreeView <> nil) and ShellTreeView.HandleAllocated then
    SendMessage(ShellTreeView.InnerTreeView.Handle, DSM_SYNCHRONIZEROOT,
      Integer(ActiveProperties.Root), 0);
end;

procedure TcxCustomShellComboBox.SetAbsolutePIDL(Value: PItemIDList);
begin
  if not CheckAbsolutePIDL(Value, True) then
    Exit;
  InternalSynchronizeEditValue(Value);
end;

procedure TcxCustomShellComboBox.SetPath(const Value: string);
begin
  InternalEditValue := Value;
end;

procedure TcxCustomShellComboBox.SetProperties(Value: TcxCustomShellComboBoxProperties);
begin
  FProperties.Assign(Value);
end;

procedure TcxCustomShellComboBox.SetRelativePIDL(Value: PItemIDList);
var
  ATempPIDL: PItemIDList;
begin
  ActiveProperties.CheckRoot;
  if Value = nil then
    InternalSynchronizeEditValue(ActiveProperties.Root.Pidl)
  else
  begin
    ATempPIDL := ConcatenatePidls(ActiveProperties.Root.Pidl, Value);
    try
      if CheckShellObjectExistence(ATempPIDL) then
        InternalSynchronizeEditValue(ATempPIDL);
    finally
      DisposePidl(ATempPIDL);
    end;
  end;
end;

(*procedure TcxCustomShellComboBox.SetRelativePath(const Value: string);
begin
end;*)

procedure TcxCustomShellComboBox.SetShellListView(Value: TcxCustomShellListView);
begin
  if Value = FShellListView then
    Exit;
  if FShellListView <> nil then
  begin
    if (FShellListView.InnerListView <> nil) and not(csDestroying in FShellListView.InnerListView.ComponentState) then
      TcxInnerShellListViewAccess(FShellListView.InnerListView).ComboBoxControl := nil;
{$IFDEF DELPHI5}
    FShellListView.RemoveFreeNotification(Self);
{$ENDIF}
  end;
  FShellListView := Value;
  if FShellListView <> nil then
  begin
    FShellListView.FreeNotification(Self);
    TcxInnerShellListViewAccess(FShellListView.InnerListView).ComboBoxControl := Self;
  end;
end;

procedure TcxCustomShellComboBox.SetShellTreeView(Value: TcxCustomShellTreeView);
begin
  if Value = FShellTreeView then
    Exit;
  if FShellTreeView <> nil then
  begin
    if (FShellTreeView.InnerTreeView <> nil) and not(csDestroying in FShellTreeView.InnerTreeView.ComponentState) then
      TcxInnerShellTreeViewAccess(FShellTreeView.InnerTreeView).ComboBoxControl := nil;
{$IFDEF DELPHI5}
    FShellTreeView.RemoveFreeNotification(Self);
{$ENDIF}
  end;
  FShellTreeView := Value;
  if FShellTreeView <> nil then
  begin
    FShellTreeView.FreeNotification(Self);
    TcxInnerShellTreeViewAccess(FShellTreeView.InnerTreeView).ComboBoxControl := Self;
  end;
end;

procedure TcxCustomShellComboBox.DSMDoNavigate(var Message: TMessage);
var
  APIDL: PItemIDList;
begin
  if FIsDependentShellControlsNotification or FNotificationFromDependentShellControls then
    Exit;
  FNotificationFromDependentShellControls := True;
  try
    if FShellTreeView <> nil then
      APIDL := FShellTreeView.AbsolutePIDL
    else if FShellListView <> nil then
      APIDL := FShellListView.AbsolutePIDL
    else
      APIDL := PItemIDList(Message.WParam);
    if not CheckAbsolutePIDL(APIDL, False) then
      Exit;
    if not IsDesigning and (FPopupShellTreeView <> nil) then
      with FPopupShellTreeView do
        if (Parent <> nil) and Parent.HandleAllocated and (InnerTreeView <> nil) then
        begin
          InnerTreeView.HandleNeeded;
          SendMessage(InnerTreeView.Handle, DSM_DONAVIGATE, WPARAM(APIDL), 0);
          SynchronizeEditValue;
          Exit;
        end;

    InternalSynchronizeEditValue(APIDL);
  finally
    FNotificationFromDependentShellControls := False;
  end;
end;

procedure TcxCustomShellComboBox.DSMSynchronizeRoot(var Message: TMessage);
begin
  if not IsLoading then
    ActiveProperties.Root.Update(TcxCustomShellRoot(Message.WParam));
end;

{ TcxShellComboBox }

class function TcxShellComboBox.GetPropertiesClass: TcxCustomEditPropertiesClass;
begin
  Result := TcxShellComboBoxProperties;
end;

function TcxShellComboBox.GetActiveProperties: TcxShellComboBoxProperties;
begin
  Result := TcxShellComboBoxProperties(InternalGetActiveProperties);
end;

function TcxShellComboBox.GetProperties: TcxShellComboBoxProperties;
begin
  Result := TcxShellComboBoxProperties(FProperties);
end;

procedure TcxShellComboBox.SetProperties(Value: TcxShellComboBoxProperties);
begin
  FProperties.Assign(Value);
end;

initialization
  GetRegisteredEditProperties.Register(TcxShellComboBoxProperties, scxSEditRepositoryShellComboBoxItem);
  FilterEditsController.Register(TcxShellComboBoxProperties, TcxFilterShellComboBoxHelper);
  PrepareShellComboBoxImageList;

finalization
  FreeAndNil(cxShellComboBoxImageList);
  FilterEditsController.Unregister(TcxShellComboBoxProperties, TcxFilterShellComboBoxHelper);
  GetRegisteredEditProperties.Unregister(TcxShellComboBoxProperties);

end.

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?