⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dbtreecbox.pas

📁 delphi编程控件
💻 PAS
📖 第 1 页 / 共 4 页
字号:
    if not (dtKeepDataSetConnected in Options) then
      FTreeSelect.DBTreeView.DataSource := nil;
    FFSearchText := '';
    FListVisible := True; { CanModify cannot get true if FListVisible = False }
    if (Action <> caCancel) and CanModify then
      SelectKeyValue(ListValue);
    FListVisible := False;
    if Assigned(FOnCloseUp) then
      FOnCloseUp(Action);
    FNoMouseDropDown := true;
    Invalidate;
  end;
end;

procedure TDbTreeLookupComboBox.CreateParams(var Params: TCreateParams);
begin
  inherited CreateParams(Params);
  with Params do
  begin
    if NewStyleControls and Ctl3D then
      ExStyle := ExStyle or WS_EX_CLIENTEDGE
    else
      Style := Style or WS_BORDER;
  end;
end;

function GetScreenRect: TRect;
{ Get the rect a window can use without getting hidden by the Win95-Taskbar.
  Thanks to Peter M. Jagielski (73737.1761@compuserve.com) for contributing
  an idea how to do this (procedure SizeForTaskBar in sizetask.zip). }
var
  TaskBarHandle: HWnd;   { Handle to the Win95 Taskbar }
  TaskBarCoord: TRect;   { Coordinates of the Win95 Taskbar }
  CxScreen: Integer;     { Width of screen in pixels }
  CyScreen: Integer;     { Height of screen in pixels }
  CxFullScreen: Integer; { Width of client area in pixels }
  CyFullScreen: Integer; { Heigth of client area in pixels }
  CyCaption: Integer;    { Height of a window's title bar in pixels }
begin
  result.Left := 0;
  result.Top := 0;
{ Get Win95 Taskbar handle: }
  TaskBarHandle := FindWindow('Shell_TrayWnd', nil);
  if (TaskBarHandle = 0) then
  begin
  { We're running WinNT w/o Win95 shell, so use TScreen-values: }
    result.Right := Screen.Width - 1;
    result.Bottom := Screen.Height - 1;
  end
  else { We're running Win95 or WinNT w/Win95 shell: }
  begin
  { Get coordinates of Win95 Taskbar: }
    GetWindowRect(TaskBarHandle, TaskBarCoord);
  { Get various screen dimensions: }
    CxScreen := GetSystemMetrics(SM_CXSCREEN);
    CyScreen := GetSystemMetrics(SM_CYSCREEN);
    CxFullScreen := GetSystemMetrics(SM_CXFULLSCREEN);
    CyFullScreen := GetSystemMetrics(SM_CYFULLSCREEN);
    CyCaption     := GetSystemMetrics(SM_CYCAPTION);
    result.Right  := CxScreen - (CxScreen - CxFullScreen) - 1;
    result.Bottom := CyScreen - (CyScreen - CyFullScreen) + CyCaption - 1;
  { look if Taskbar is on either top or left: }
    if (TaskBarCoord.Top = -2) and (TaskBarCoord.Left = -2) then
      if TaskBarCoord.Right > TaskBarCoord.Bottom then
      { Taskbar on top }
        result.Top  := TaskBarCoord.Bottom
      else
      { Taskbar on left }
        result.Left := TaskBarCoord.Right;
  end;
end;

procedure TDbTreeLookupComboBox.DropDown;
var
  ComboBoxOrigin: TPoint;
  X: Integer;
  Y: Integer;
  ScreenRect: TRect;
{ I: Integer; S: string; }
begin
  if not FListVisible and FFListActive then
  begin
    if Assigned(FOnDropDown) then FOnDropDown(Self);
    if FDropDownWidth > 0 then
      TreeSelect.Width := FDropDownWidth
    else
      TreeSelect.Width := Width;
    if FDropDownHeight > 0 then
      FTreeSelect.Height := FDropDownHeight;
{
    FTreeSelect.ReadOnly := not CanModify;
    FTreeSelect.KeyField := FKeyFieldName;
    for I := 0 to FListFields.Count - 1 do
      S := S + TField(FListFields[I]).FieldName + ';';
    FTreeSelect.ListField := S;
    FTreeSelect.ListFieldIndex := FListFields.IndexOf(FListField);
    FTreeSelect.ListSource := FListLink.DataSource;
    FTreeSelect.KeyValue := KeyValue;
}
    ScreenRect.TopLeft := ScreenToClient(GetScreenRect.TopLeft);
    ScreenRect.BottomRight := ScreenToClient(GetScreenRect.BottomRight);
    ScreenRect := GetScreenRect;
    ComboBoxOrigin := Parent.ClientToScreen(Point(Left, Top));
    Y := ComboBoxOrigin.Y + Height;
    if Y + FTreeSelect.Height > ScreenRect.Bottom then
    begin
      Y := ComboBoxOrigin.Y - FTreeSelect.Height;
      FTreeSelect.FPosUnderComboBox := false;
    end
    else
      FTreeSelect.FPosUnderComboBox := true;
    case FDropDownAlign of
      daRight: X := ComboBoxOrigin.X - (FTreeSelect.Width - Width);
      daCenter: X := ComboBoxOrigin.X - ((FTreeSelect.Width - Width) div 2);
      else X := ComboBoxOrigin.X;
    end;
    if ((X + FTreeSelect.Width) > ScreenRect.Right) then
      X := ScreenRect.Right - (FTreeSelect.Width - 1);
    if (X < ScreenRect.Left) then
      X := ScreenRect.Left;
    FTreeSelect.DBTreeView.Color := Color;
    FTreeSelect.DBTreeView.Font := Font;
    FTreeSelect.DBTreeView.TableTextField := FFListField.Fieldname;
  { Now, if not done already, we connect the Datasource. We will disconnect
    it at CloseUp if not dtKeepDataSetConnected in Options: }
    if (FTreeSelect.DBTreeView.DataSource = nil) then
      FTreeSelect.DBTreeView.DataSource := FFListLink.DataSource;
    LocateKey; { TTable(ListSource.DataSet).FindKey([KeyValue]); }
    with FTreeSelect.DBTreeView do
    begin
      If (Items.GetFirstNode <> nil) then
      begin
        Items.GetFirstNode.MakeVisible; { begin at top of list }
{       Selected := Items.GetFirstNode; }
      end;
      SynchronizeSelectedNodeToCurrentRecord;
    end;
    FTreeSelect.Resize;
  { Show window: }
    SetWindowPos(FTreeSelect.Handle, HWND_TOP, X, Y, 0, 0,
      SWP_NOSIZE or SWP_NOACTIVATE or SWP_SHOWWINDOW);
    FTreeSelect.Show;
    FListVisible := True;
    Repaint;
  end;
end;

procedure TDbTreeLookupComboBox.ProcessSearchKey(Key: Char);
var
  aDBTreeView: TCustomDBTreeView;
  i: Integer;
  TickCount: Integer;
  S: string;
  Accept: Boolean;
  IDList: TStringList;
begin
  case Key of
    #8, #27: FFSearchText := '';
    #32..#255:
      if CanModify and FListLink.Active then
      begin
        TickCount := GetTickCount;
        if ((TickCount - SearchTickCount) > 2000) then
          FFSearchText := '';
        SearchTickCount := TickCount;
        if (Length(FFSearchText) < 32) then
        begin
          S := FFSearchText + Key;
          aDBTreeView := DBTreeView;
          if Assigned(aDBTreeView) then
          begin
            if (aDBTreeView.DataSource = nil) then
              aDBTreeView.DataSource := FFListLink.DataSource;
            IDList := aDBTreeView.TextIDList(AnsiUpperCase(S),
              [tvftCaseInsensitive, tvftPartial]);
            if (IDList <> nil) then
            try
              for i := 0 to IDList.Count - 1 do
              begin
                Accept := true;
                AcceptNode(aDBTreeView.GetIDNode(IDList[i]), Accept);
                if Accept then
                begin
                  SelectKeyValue(IDList[i]);
                  FFSearchText := S;
                  break;
                end;
              end;
            finally
              IDList.Free;
            end;
          end;
        end;
      end;
  end;
end;

procedure TDbTreeLookupComboBox.KeyDown(var Key: Word; Shift: TShiftState);
var
  aDBTreeView: TCustomDBTreeView;
  Node: TTreeNode;
  Accept: Boolean;
begin
  inherited KeyDown(Key, Shift);
  if FFListActive and ((Key = VK_UP) or (Key = VK_DOWN)) then
    if ssAlt in Shift then
    begin
      if FListVisible then
        CloseUp(caAccept)
      else
        DropDown;
      Key := 0;
    end
    else
    begin
      if (not FListVisible) then
      begin
        aDBTreeView := DBTreeView;
        if Assigned(aDBTreeView) then
        begin
          if (aDBTreeView.DataSource = nil) then
            aDBTreeView.DataSource := FFListLink.DataSource;
          Node := aDBTreeView.GetIDNode(KeyValue);
          if (Node <> nil) then
          begin
            repeat
              if (Key = VK_UP) then
                Node := Node.GetPrev
              else
                Node := Node.GetNext;
              if (Node <> nil) then
              begin
                Accept := true;
                AcceptNode(Node, Accept);
              end;
            until (Node = nil) or Accept;
            if Accept then
              SelectKeyValue(aDBTreeView.IDOfNode(Node));
          end;
          Key := 0;
        end;
      end;
    end;
end;

procedure TDbTreeLookupComboBox.KeyPress(var Key: Char);
begin
  inherited KeyPress(Key);
  ProcessSearchKey(Key);
end;

procedure TDbTreeLookupComboBox.KeyValueChanged;
begin
  if FFLookupMode and Assigned(FFDataField) then
  begin
    FText := FFDataField.DisplayText;
    FAlignment := FFDataField.Alignment;
  end else
  if FFListActive and LocateKey then
  begin
    FText := FFListField.DisplayText;
    FAlignment := FFListField.Alignment;
  end else
  begin
    FText := '';
    FAlignment := taLeftJustify;
  end;
  Invalidate;
end;

procedure TDbTreeLookupComboBox.ListLinkActiveChanged;
begin
  inherited;
  KeyValueChanged;
  if Assigned(FTreeSelect) then
    try
      TreeSelect.DBTreeView.DataSource := FFListLink.DataSource;
    except end;
end;

procedure TDbTreeLookupComboBox.SetListTreeIDField(const Value: String);
begin
  FListTreeIDField := Value;
  if Assigned(FTreeSelect) then
    try
      TreeSelect.DBTreeView.TableIDField := Value;
    except end;
end;

procedure TDbTreeLookupComboBox.SetListTreeParentField(const Value: String);
begin
  FListTreeParentField := Value;
  if Assigned(FTreeSelect) then
    try
      TreeSelect.DBTreeView.TableParentField := Value;
    except end;
end;

procedure TDbTreeLookupComboBox.MouseDown(Button: TMouseButton; Shift: TShiftState;
  X, Y: Integer);
begin
  if Button = mbLeft then
  begin
    SetFocus;
    if not FFFocused then Exit;
    if FListVisible then CloseUp(caCancel) else
      if FFListActive and not FNoMouseDropDown then
      begin
        MouseCapture := True;
        FTracking := True;
        TrackButton(X, Y);
        DropDown;
      end;
  end;
  inherited MouseDown(Button, Shift, X, Y);
end;

procedure TDbTreeLookupComboBox.MouseMove(Shift: TShiftState; X, Y: Integer);
var
  ListPos: TPoint;
  MousePos: TSmallPoint;
  ADBTreeView: TCustomDBTreeView;
begin
  FNoMouseDropDown := false;
  if FTracking then
  begin
    TrackButton(X, Y);
    if FListVisible then
    begin
      ADBTreeView := DBTreeView;
      if Assigned(ADBTreeView) then
      begin
        ListPos := ADBTreeView.ScreenToClient(ClientToScreen(Point(X, Y)));
        if PtInRect(ADBTreeView.ClientRect, ListPos) then
        begin
          StopTracking;
          MousePos := PointToSmallPoint(ListPos);
          SendMessage(ADBTreeView.Handle, WM_LBUTTONDOWN, 0, Integer(MousePos));
          Exit;
        end;
      end;
    end;
  end;
  inherited MouseMove(Shift, X, Y);
end;

procedure TDbTreeLookupComboBox.MouseUp(Button: TMouseButton; Shift: TShiftState;
  X, Y: Integer);
begin
  FNoMouseDropDown := false;
  StopTracking;
  inherited MouseUp(Button, Shift, X, Y);
end;

procedure TDbTreeLookupComboBox.Paint;
var
  W, X, Flags: Integer;
  Text: string;
  Alignment: TAlignment;
  Selected: Boolean;
  R: TRect;
begin
  Canvas.Font := Font;
  Canvas.Brush.Color := Color;
  Selected := FFFocused and not FListVisible and
    not (csPaintCopy in ControlState);
  if Selected then
  begin
    Canvas.Font.Color := clHighlightText;
    Canvas.Brush.Color := clHighlight;
  end;
  if (csPaintCopy in ControlState) and (FFDataField <> nil) then
  begin
    Text := FFDataField.DisplayText;
    Alignment := FFDataField.Alignment;
  end else
  begin
    Text := FText;
    Alignment := FAlignment;
  end;
  W := ClientWidth - FButtonWidth;
  X := 2;
  case Alignment of
    taRightJustify: X := W - Canvas.TextWidth(Text) - 3;
    taCenter: X := (W - Canvas.TextWidth(Text)) div 2;
  end;
  SetRect(R, 1, 1, W - 1, ClientHeight - 1);
  Canvas.TextRect(R, X, 2, Text);
  if Selected then Canvas.DrawFocusRect(R);
  SetRect(R, W, 0, ClientWidth, ClientHeight);
  if not FFListActive then
    Flags := DFCS_SCROLLCOMBOBOX or DFCS_INACTIVE
  else if FPressed then

⌨️ 快捷键说明

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