Delphi Tokyo 10.2를 사용하여 스타일이 적용된 테마. EditTexts, ComboBoxes 등과 같이 양식의 구성 요소를 강조 표시하려고합니다. 예를 들어 사용자가 잘못된 데이터를 입력 한 경우 구성 요소를 강조 표시하고 싶습니다.테마가 적용된 강조 컨트롤 Delphi App
이전에는 색상이 빨간색이었고 색상은 일반적으로 크기 조정/이동/페인트 칠을 통해 지속되었습니다. 이제 테마를 사용하여 색상을 표시하고 유지하기 위해 더 많은 작업을 수행해야합니다.
각 구성 요소의 StyleElements [seFont, seClient, seBorder] 속성을 사용하지 않도록 설정하여 강제로 색상을 표시해 보았습니다. 이것은 효과가 있지만, 특히 많은 구성 요소의 유효성이 검증 된 경우에는 겉으로 보입니다. 또한 단순히 빨간색으로 색상을 칠하면 테마 중 일부가 제대로 표시되지 않을 수 있습니다.
또한 WinAPI SetRop2 (..)를 사용하여 구성 요소 주위에 빨간색 사각형을 그리기 만했습니다. 예를 들어, here은 영리한 코드이며 TWinControl을 가져 와서 그 주위에 레드 박스를 그리기 위해 비틀어졌으며 유사한 호출을 사용하여 레드 박스를 제거 할 수도 있습니다. 이것은
작동 ...하지만 분명히 다시 그리기를 통해 지속되지 않습니다. 그것은 사용자 정의 페인트 방법을 추가하는 것이 과잉일지도 모르는 것처럼 보입니다. 않는 한, 더 좋은 방법이 있습니까?이
모든 구성 요소가 패널에 앉아, 나는 구성 요소 주위 패널의 캔버스에 빨간색의 구형, 그러나 다시 이상의 사용자 정의 페인트 루틴을 그리는 보호 해킹을 사용하여 고려했다 :
다른 것들 나는 생각했다 ...
또한 필자는 TShapes를 필요에 따라 동적으로 그리는 것을 고려하고 있지만 이것은 어리석은 행동입니다.
델파이의 이전 버전에서는 깔끔하게 작동하지만, 테마가 적용될 때 그리 좋아 보이지 않는 데이터 입력 유효성 검사와 같은 상황에 다른 것들이 있어야합니다. 테마를 사용할 때 가장 좋은 방법은 무엇입니까? SetRop2 (..) 접근법은 가장 깨끗한 것처럼 보이지만 누군가가 색상을 유지할 수있는 간단한 방법을 제안 할 수 있습니다. 나도 다른 아이디어를 환영합니다. 고맙습니다.
EDIT 잘못된 응답 주위의 TShapes를 그리면 어쩌면 그렇게 나쁘지 않을 것입니다. 그들은 페인트 칠을 통해 지속되며 TWinControl에서 파생되지 않습니다. 즉, 강조 표시되는 컨트롤 뒤에 자동으로 표시됩니다.
이것은 꽤 잘 작동하며 다른 사람들에게 도움이되기를 바랍니다. 빨간색과 파란색 상자에 1 강조에 다음과 같이 호출
//assuming owning control will be free'd properly and
//will in turn free HI_LITE Box.
//
//tantamount to adding an instance variable, TShape, to existing Control,
//since class helpers don't allow. And I don't want to descend
//new controls just to have a hiLiteBox Instance Variable.
procedure HiLiteMe(aControl : TWinControl; HILITE_FLAG : Boolean = TRUE; aColor : TColor = clRed);
const OFFSET = 4; //specify the offset of the border size of the box.
const BOX_NAME_PREFIX = 'HI_LITE_BOX_';
var
hiLiteBox : TShape; //reference created on stack, but object created on the heap,
uniqueBoxName : String; //so use the persistent aControl's owned component list to maintain the reference.
begin
uniqueBoxName := BOX_NAME_PREFIX + aControl.Name; //uniquename for each associated HiLiteBox.
HiLiteBox := aControl.FindComponent(uniqueBoxName) as TShape; //phishing for the HiLiteBox if it was previously created.
if NOT Assigned(hiLiteBox) then //create HiLiteBox and make persist outside this proc.
begin
if NOT HILITE_FLAG then exit; //don't create a box if we're just going to hide it anyway.
hiLiteBox := TShape.Create(aControl); //Create HiLiteBox, setting aControl as owner, quicker retrieval using aControl.findComponent
hiLiteBox.Parent := aControl.Parent; //Render the box on the control's parent, eg, panel, form, etc.
hiLiteBox.Name := uniqueBoxName;
hiLiteBox.Pen.Color := aColor; //Color the Pen
hiLiteBox.Pen.Width := offset-1; //Make the Pen just slightly smaller than the offset.
hiLiteBox.Brush.Color := clWindow; //Choose a brush color, to fill the space between the pen and the Control
hiLiteBox.Left := aControl.Left - offset;
hiLiteBox.Width := aControl.Width + offset*2;
hiLiteBox.Top := aControl.Top - offset;
hiLiteBox.Height := aControl.Height + offset*2;
end;
hiLiteBox.Visible := HILITE_FLAG; //Show/Hide HiLite as appropriate.
end;
... HiLites를 제거하기 위해 다음과 같이 호출 begin
HiLiteMe(checkListBox1, TRUE, clRed); //Draw a RedBox around the CheckListBox, eg, Invalid.
HiLiteMe(bitBtn3, TRUE, clBlue); //Draw a Blue Box around the Button, eg, Required.
end;
... begin
HiLiteMe(checkListBox1, FALSE); //Draw a RedBox around the CheckListBox, eg, Invalid.
HiLiteMe(bitBtn3, FALSE); //Draw a Blue Box around the Button, eg, Required.
end;
VCL 스타일을 사용하지 마십시오. 기본 Win32 모양을 사용하십시오. –
VCL 스타일은 기술적으로 해킹과 비슷합니다.특히 프로덕션 소프트웨어에는 적합하지 않습니다. 가능한 모든 성질은 색다른 것이므로 가능하면 피해야합니다. 또 다른 말로, 다시 그리는 것이 그림 위에 그려진다는 것입니다. 물론 컨트롤의'OnPaint' 이벤트 나 윈도우 메시지 인'WM_PAINT' 내에 페인트하지 않으면됩니다. –
* "같은 상황에있는 다른 사용자가 있어야합니다."* - 아마도 ... * .. ".. 이전 버전에서는 깔끔하게 작동하는 데이터 입력 유효성 검사 .."* - 데이터 입력 유효성 검사에는 종소리와 휘파람이 필요하지 않지만, 힌트 또는 대화 상자를 통해 메시지를 띄우고 유효하지 않은 항목으로 컨트롤에 포커스를 지정할 수 있습니다. 안드레아스의 충고와 함께 그것은 쉬운 적용으로 판명 될 것입니다. –