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

📄 cbtnform.pas

📁 动态提示控件
💻 PAS
📖 第 1 页 / 共 2 页
字号:

  if (Y = 0) then
  begin
    { other square }
    X := ClientWidth - 18;
    Y := btnOther.Top + ((btnOther.Height - 16) div 2);
  end else if ValidColorIndex(X, Y) then
  begin
    X := (X-1) * 18 + 1;
    Y := (Y-1) * 18 + 1;
  end else
    exit;

  Result := Rect(X-1, Y-1, X+17, Y+17);
end;

procedure TDFSColorButtonPalette.DrawSquare(X, Y: integer; AColor: TColor;
   IsFocused: boolean);
var
  R: TRect;
begin
  R := GetSquareCoords(X, Y);
  if IsRectEmpty(R) then
    exit;

  if (Y = 0) then
    AColor := FOtherColor;

  with Canvas do
  begin
    if IsFocused then
    begin
      Brush.Color := {$IFDEF DFS_WIN32} cl3DDkShadow; {$ELSE} clBlack; {$ENDIF}
      FrameRect(R);
      InflateRect(R, -1, -1);
      Brush.Color := clBtnHighlight;
      FrameRect(R);
      InflateRect(R, -1, -1);
      Brush.Color := {$IFDEF DFS_WIN32} cl3DDkShadow; {$ELSE} clBlack; {$ENDIF}
      FrameRect(R);
      InflateRect(R, -1, -1);
    end else begin
      { Get rid of any focus framing rect left over from previous paint }
      Brush.Color := Self.Color;
      FrameRect(R);
      InflateRect(R, -1, -1);
      { Draw a 3D frame }
      Frame3D(Canvas, R, clBtnShadow, clBtnHighlight, 1);
      { Frame3D reduces the rectangle size by 1 }
      Frame3D(Canvas, R, {$IFDEF DFS_WIN32} cl3DDkShadow {$ELSE} clBlack {$ENDIF},
          {$IFDEF DFS_WIN32} cl3DLight {$ELSE} clSilver {$ENDIF}, 1);
    end;
    { Paint the color }
    Brush.Color := AColor;
    FillRect(R);
  end;
end;

function ColorEnumProc(Pen : PLogPen; Colors : PColorArrayCallback): integer;
   {$IFDEF DFS_WIN32} stdcall; {$ELSE} export; {$ENDIF}
begin
  if Pen^.lopnStyle = PS_SOLID then
  begin
    if Colors^[0] < 20 then
    begin
      inc(Colors^[0]);
      Colors^[Colors^[0]] := Pen^.lopnColor;
      Result := 1;
    end else
      Result := 0;
  end else
    Result := 1;
end;

procedure TDFSColorButtonPalette.FormCreate(Sender: TObject);
var
  X, Y: integer;
  Colors: TColorArrayCallback;
  DC: HDC;
  {$IFNDEF DFS_WIN32}
  CallbackProc: TFarProc;
  {$ENDIF}
begin
  FPreventClose := FALSE;
  
  FOldAppDeactivate := Application.OnDeactivate;
  Application.OnDeactivate := AppDeactivate;
  FOldAppShowHint := Application.OnShowHint;
  Application.OnShowHint := PaletteShowHint;

  FLastFrame := Point(-1,-1);

  DC := GetDC(GetDesktopWindow);
  try
    if GetDeviceCaps(DC, NUMCOLORS) = 16 then
    begin
      { 16 color mode, enum colors to fill array }
      FillChar(Colors, SizeOf(Colors), #0);
      {$IFDEF DFS_WIN32}
      EnumObjects(DC, OBJ_PEN, @ColorEnumProc, LPARAM(@Colors));
      {$ELSE}
      CallbackProc := MakeProcInstance(@ColorEnumProc, hInstance);
      try
        EnumObjects(DC, OBJ_PEN, CallbackProc, @Colors);
      finally
        FreeProcInstance(CallbackProc);
      end;
      {$ENDIF}

      for X := 1 to 4 do
      begin
        for Y := 1 to 5 do
        begin
          FPaletteColors[X,Y] := Colors[(X-1)*5+Y];
        end;
      end;
    end else begin
      { Lots 'o colors, pick the ones we want. }
      FPaletteColors[1,1] := RGB(255,255,255);
      FPaletteColors[1,2] := RGB(255,0,0);
      FPaletteColors[1,3] := RGB(0,255,0);
      FPaletteColors[1,4] := RGB(0,0,255);
      FPaletteColors[1,5] := RGB(191,215,191);
      FPaletteColors[2,1] := RGB(0,0,0);
      FPaletteColors[2,2] := RGB(127,0,0);
      FPaletteColors[2,3] := RGB(0,127,0);
      FPaletteColors[2,4] := RGB(0,0,127);
      FPaletteColors[2,5] := RGB(159,191,239);
      FPaletteColors[3,1] := RGB(191,191,191);
      FPaletteColors[3,2] := RGB(255,255,0);
      FPaletteColors[3,3] := RGB(0,255,255);
      FPaletteColors[3,4] := RGB(255,0,255);
      FPaletteColors[3,5] := RGB(255,247,239);
      FPaletteColors[4,1] := RGB(127,127,127);
      FPaletteColors[4,2] := RGB(127,127,0);
      FPaletteColors[4,3] := RGB(0,127,127);
      FPaletteColors[4,4] := RGB(127,0,127);
      FPaletteColors[4,5] := RGB(159,159,159);
    end;
  finally
    ReleaseDC(GetDesktopWindow, DC);
  end;

  FOtherColor := clBtnFace;
  FStartColor := clBlack;

  { Oh, how I do hate large fonts. }
  ClientWidth := 72;
  btnOther.Top := 98;
  btnOther.Width := ClientWidth - 22;
  ClientHeight := btnOther.Top + btnOther.Height + 2;
end;

procedure TDFSColorButtonPalette.SetStartColor(Value: TColor);
var
  x, y: integer;
begin
  FStartColor := Value;
  { See if we have that color }
  for x := 1 to 4 do
  begin
    for y := 1 to 5 do
    begin
      if ColorToRGB(FPaletteColors[x,y]) = ColorToRGB(FStartColor) then
      begin
        FLastFrame := Point(x,y);
        DrawSquare(x, y, FStartColor, TRUE);
        exit;
      end;
    end;
  end;
  { didn't find it }
  FOtherColor := FStartColor;
end;

procedure TDFSColorButtonPalette.SetShowColorHints(Val: boolean);
begin
  FShowColorHints := Val;
  ShowHint := Val;
end;

procedure TDFSColorButtonPalette.AppDeactivate(Sender: TObject);
begin
  if FPreventClose then
    exit;

  if assigned(FOldAppDeactivate) then
    FOldAppDeactivate(Sender);

  Close;
end;

function TDFSColorButtonPalette.BuildHintText(AColor: TColor;
   X, Y: integer): string;
type
  {$IFNDEF DFS_WIN32}
  DWORD = longint;
  {$ENDIF}
  TRGBMap = packed record
    case boolean of
      TRUE:  ( RGBVal: DWORD );
      FALSE: ( Red,
               Green,
               Blue,
               Unused: byte );
  end;
var
  RGBColor: TRGBMap;
begin
  RGBColor.RGBVal := ColorToRGB(AColor);
  { for hex, you could use:
  HintStr := Format('RGB = %.2x %.2x %.2x', [AColor.Red, AColor.Green,}
  Result := Format('RGB = %.3d %.3d %.3d', [RGBColor.Red, RGBColor.Green,
     RGBColor.Blue]);

  GetColorHintText(AColor, X, Y, Result);
end;

procedure TDFSColorButtonPalette.PaletteShowHint(var HintStr: string;
   var CanShow: Boolean; var HintInfo: THintInfo);
var
  CS: TPoint;
  AColor: TColor;
begin
  if HintInfo.HintControl = Self then
  begin
    CS := GetCurrentSquare;
    if ValidColorIndex(CS.X, CS.Y) then
    begin
      { Hint is valid as long as cursor stays inside this color square }
      HintInfo.CursorRect := GetSquareCoords(CS.X, CS.Y);
      if CS.Y = 0 then
        AColor := FOtherColor
      else
        AColor := FPaletteColors[CS.X, CS.Y];

      HintStr := BuildHintText(AColor, CS.X, CS.Y);

      CanShow := HintStr <> '';

      {$IFNDEF DFS_DELPHI_3_UP}
      if CanShow then
      begin
        CS.X := HintInfo.CursorRect.Left;
        CS.Y := HintInfo.CursorRect.Bottom + 8;
        HintInfo.HintPos := ClientToScreen(CS);
      end;
      {$ENDIF}
    end else
      CanShow := FALSE;
  end;
  if assigned(FOldAppShowHint) then
    FOldAppShowHint(HintStr, CanShow, HintInfo);
end;

procedure TDFSColorButtonPalette.btnOtherClick(Sender: TObject);
var
  AColor: TColor;
  c: char;
  p: integer;
  y: integer;
  x: integer;
  z: integer;
  Dlg: TColorDialog;
  ColorPicked: boolean;
begin
  Dlg := TColorDialog.Create(Self);
  try
    FPreventClose := TRUE;
    Dlg.Color := FOtherColor;
    Dlg.Options := [cdFullOpen];
    { set custom colors here }
    for x := 1 to 8 do
    begin
      for y := 1 to 2 do
      begin
        c := Chr((y-1)*8+x + 64);
        Dlg.CustomColors.Add('Color' + c + '=' + IntToHex(CustomColors[x,y], 8));
      end;
    end;
    ColorPicked := Dlg.Execute;
    if ColorPicked then
    begin
      FOtherColor := Dlg.Color;
      { get custom colors here }
      for z := 0 to 15 do
      begin
        p := Pos('=', Dlg.CustomColors[z]);
        AColor := StrToIntDef('$'+Copy(Dlg.CustomColors[z], p+1, 9), clWhite);
        p := Ord(Dlg.CustomColors[z][p-1]) - 64;
        x := (p-1) mod 8 + 1;
        y := (p-1) div 8 + 1;
        CustomColors[x,y] := AColor;
      end;
    end;
  finally
    FPreventClose := FALSE;
    Dlg.Free;
  end;

  if ColorPicked then
  begin
    if assigned(FSetParentColor) then
      FSetParentColor(Self, TRUE, FOtherColor);
    Close;
  end;
end;

procedure TDFSColorButtonPalette.FormCloseQuery(Sender: TObject;
  var CanClose: Boolean);
begin
  CanClose := not FPreventClose;
end;

function TDFSColorButtonPalette.ValidColorIndex(X, Y: integer): boolean;
begin
  Result := ((X > 0) and (X <= 4) and (Y > 0) and (Y <= 5)) or (Y = 0);
end;

procedure TDFSColorButtonPalette.FrameCurrentSquare(NewFrame: TPoint);

  function ComparePoints(const Pt1, Pt2: TPoint): boolean;
  begin
    Result := ((Pt1.X = Pt2.X) and (Pt1.Y =Pt2.Y));
  end;

var
  AColor: TColor;
begin
  if not ComparePoints(NewFrame, FLastFrame) and
     ValidColorIndex(NewFrame.X, NewFrame.Y) then
  begin
    { Unframe the last one }
    if ValidColorIndex(FLastFrame.X, FLastFrame.Y) then
    begin
      if FLastFrame.Y = 0 then
        AColor := FOtherColor
      else
        AColor := FPaletteColors[FLastFrame.X, FLastFrame.Y];
      with FLastFrame do
        DrawSquare(X, Y, AColor, FALSE);
    end;

		if NewFrame.Y = 0 then
      AColor := FOtherColor
    else
      AColor := FPaletteColors[NewFrame.X, NewFrame.Y];
    with NewFrame do
      DrawSquare(X, Y, AColor, TRUE);
    FLastFrame := NewFrame;
  end;
end;


procedure TDFSColorButtonPalette.FormMouseMove(Sender: TObject;
  Shift: TShiftState; X, Y: Integer);
begin
  FrameCurrentSquare(GetCurrentSquare);
end;

procedure TDFSColorButtonPalette.FormClick(Sender: TObject);
var
  SelectedColorSquare: TPoint;
  AColor: TColor;
begin
  if assigned(FSetParentColor) then
  begin
    SelectedColorSquare := GetCurrentSquare;
    if ValidColorIndex(SelectedColorSquare.X, SelectedColorSquare.Y) then
    begin
      if (SelectedColorSquare.Y = 0) then
        AColor := FOtherColor
      else
        AColor := FPaletteColors[SelectedColorSquare.x, SelectedColorSquare.Y];
      FSetParentColor(Self, (SelectedColorSquare.Y = 0), AColor);
    end;
  end;
  Close;
end;

function TDFSColorButtonPalette.GetCurrentSquare: TPoint;

  function IsOtherColorSquare(Pt: TPoint): boolean;
  begin
    Result := (Pt.X >= ClientWidth-19) and (Pt.X <= ClientWidth-1) and
       (Pt.Y >= 96) and (Pt.Y <= 113);
  end;

var
  CurPos: TPoint;
begin
  GetCursorPos(CurPos);
  CurPos := ScreenToClient(CurPos);
  Result := Point((CurPos.X div 18) + 1, (CurPos.Y div 18) + 1);
  if IsOtherColorSquare(CurPos) then
    Result := Point(0,0)
  else if not ValidColorIndex(Result.X, Result.Y) then
    Result := Point(-1,-1);
end;

procedure TDFSColorButtonPalette.FormKeyPress(Sender: TObject;
  var Key: Char);
var
  SelectedColorSquare: TPoint;
  AColor: TColor;
begin
  case Key of
    #27:
      begin
        FKeyboardClose := TRUE;
        Close;
      end;
    #13:
      begin
        if assigned(FSetParentColor) then
        begin
          SelectedColorSquare := FLastFrame;
          if ValidColorIndex(SelectedColorSquare.X, SelectedColorSquare.Y) then
          begin
            if (SelectedColorSquare.Y = 0) then
              AColor := FOtherColor
            else
              AColor := FPaletteColors[SelectedColorSquare.x,
                 SelectedColorSquare.Y];
            FSetParentColor(Self, (SelectedColorSquare.Y = 0), AColor);
          end;
        end;
        FKeyboardClose := TRUE;
        Close;
      end;
  end;
end;

procedure TDFSColorButtonPalette.FormDestroy(Sender: TObject);
begin
  Application.OnDeactivate := FOldAppDeactivate;
  Application.OnShowHint := FOldAppShowHint;
end;

procedure TDFSColorButtonPalette.SetPaletteColors(Value: TPaletteColors);
begin
  FPaletteColors.Assign(Value);
end;

procedure TDFSColorButtonPalette.SetCustomColors(Value: TCustomColors);
begin
  FCustomColors.Assign(Value);
end;


procedure TDFSColorButtonPalette.FormKeyDown(Sender: TObject;
  var Key: Word; Shift: TShiftState);
var
  FrameIt: boolean;
  NewFrame: TPoint;
begin
  FrameIt := TRUE;
  NewFrame := FLastFrame;
  if ValidColorIndex(NewFrame.X, NewFrame.Y) then
  begin
    case Key of
      VK_LEFT:
        begin
          if NewFrame.Y = 0 then
            exit;
          dec(NewFrame.X);
          if NewFrame.X < 1 then
            NewFrame.X := 4
          else if NewFrame.X > 4 then
            NewFrame.X := 1;
        end;
      VK_UP:
        begin
          dec(NewFrame.Y);
          if NewFrame.Y < 0 then
            NewFrame.Y := 5
          else if NewFrame.Y > 5 then
            NewFrame.Y := 0;
        end;
      VK_RIGHT:
        begin
          if NewFrame.Y = 0 then
            exit;
          inc(NewFrame.X);
          if NewFrame.X < 1 then
            NewFrame.X := 4
          else if NewFrame.X > 4 then
            NewFrame.X := 1;
        end;
      VK_DOWN:
        begin
          inc(NewFrame.Y);
          if NewFrame.Y < 0 then
            NewFrame.Y := 5
          else if NewFrame.Y > 5 then
            NewFrame.Y := 0;
        end;
    else
      FrameIt := FALSE;
    end;
  end else
    NewFrame := Point(1, 1);

  if FrameIt then
    FrameCurrentSquare(NewFrame);
end;

end.

⌨️ 快捷键说明

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