// 컴포넌트를 Install 한다음 Samples 디렉토리에 가서
// EditButton 을 한번 시험해 보는 것도 재미 있을듯..
unit ButtonEdit;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls;
type
TButtonEdit = class(TEdit)
private
//FCanvas: TCanvas; //commented out - see below!
//do you want to 'click' when the up or down arrow key pressed as well?
FClickOnArrow: boolean;
//do you want to 'click' when the Return key pressed as well?
FClickOnReturn: boolean;
//flag - is the button pressed or not
FPressed: boolean;
procedure Click; override;
procedure CreateWnd; override;
procedure WMPAINT(var Message: TMessage); message WM_PAINT;
procedure WMLBUTTONDOWN(var Message: TWMMouse); message WM_LBUTTONDOWN;
procedure WMLBUTTONUP(var Message: TWMMouse); message WM_LBUTTONUP;
procedure WMMOUSEMOVE(var Message: TWMMouse); message WM_MOUSEMOVE;
//procedure WMSETFOCUS(var Message: TMessage); message WM_SETFOCUS;
protected
procedure KeyDown(var Key: Word; Shift: TShiftState); override;
public
constructor Create(AOwner: TComponent); override;
published
property ClickOnArrow: boolean read FClickOnArrow write FClickOnArrow;
property ClickOnReturn: boolean read FClickOnReturn write FClickOnReturn;
end;
procedure Register;
implementation
const
BUTTONWIDTH = 17;
{----------------------------------------------------------------------}
{----------------------------------------------------------------------}
procedure Register;
begin
RegisterComponents('Samples', [TButtonEdit]);
end;
{----------------------------------------------------------------------}
constructor TButtonEdit.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FPressed := false;
FClickOnArrow := true;
FClickOnReturn := false;
end;
{----------------------------------------------------------------------}
procedure TButtonEdit.CreateWnd;
begin
inherited CreateWnd;
//this is crucial to stop text disappearing under the button...
perform(EM_SETMARGINS,EC_RIGHTMARGIN,(BUTTONWIDTH+2) shl 16);
end;
{----------------------------------------------------------------------}
procedure TButtonEdit.WMLBUTTONDOWN(var Message: TWMMouse);
begin
inherited;
//draw button in pressed state...
if message.xpos >= clientwidth-BUTTONWIDTH+1 then begin
FPressed := true;
Refresh;
end;
end;
{----------------------------------------------------------------------}
procedure TButtonEdit.WMLBUTTONUP(var Message: TWMMouse);
begin
inherited;
//draw button in non-pressed state...
if FPressed then begin
FPressed := false;
Refresh;
end;
end;
{----------------------------------------------------------------------}
procedure TButtonEdit.WMMOUSEMOVE(var Message: TWMMouse);
begin
inherited;
//change cursor when over the button to an arrow (not the default I-beam)...
if message.xpos >= clientwidth-BUTTONWIDTH+1 then cursor := crArrow
else cursor := crDefault;
end;
{----------------------------------------------------------------------}
procedure TButtonEdit.Click;
var
pt: TPoint;
begin
//fix a minor cosmetic problem...
if FPressed then begin
FPressed := false;
Repaint;
end;
//Only process an OnClick method if the button is clicked,
//NOT if the text is clicked!
GetCursorPos(pt);
if PtInRect(Rect(clientwidth-BUTTONWIDTH+1,0,clientwidth,clientheight),
ScreenToClient(pt)) then inherited Click;
end;
{----------------------------------------------------------------------}
procedure TButtonEdit.KeyDown(var Key: Word; Shift: TShiftState);
begin
//respond to up or down arrow keys or Return key with OnClick event if
//"ClickOnArrow" or "ClickOnReturn" property set...
inherited KeyDown(Key, Shift);
if ((Key = vk_Down) or (Key = vk_Up))
and (Shift = []) and FClickOnArrow then begin
Key := 0;
inherited Click;
end
else if (Key = vk_return) and FClickOnReturn then begin
Key := 0;
inherited Click;
end;
end;
{----------------------------------------------------------------------}
//This no longer seems to be necessary ... I've left it here just in case!
{procedure TButtonEdit.WMSETFOCUS(var Message: TMessage);
begin
inherited;
repaint;
end;}
{----------------------------------------------------------------------}
procedure TButtonEdit.WMPAINT(var Message: TMessage);
var
dc: HDC;
CntrPt: TPoint;
pic: array [0..3] of TPoint; //arrow 'picture' points
begin
// let windows draw the text!
// I don't really want to struggle with all the scrolling issues etc!
inherited;
//NOW DRAW THE BUTTON ... (not as bad as it looks if you take out the comments!)
//find the centre of the button...
CntrPt := point(clientwidth - BUTTONWIDTH div 2, clientheight div 2);
//offset CntrPt by 1 if pressed...
if FPressed then CntrPt := point(CntrPt.x+1,CntrPt.y+1);
//get button arrow drawing coordinates from CntrPt...
pic[0] := point( CntrPt.x-5,CntrPt.y);
pic[1] := point( CntrPt.x,CntrPt.y-5);
pic[2] := point( CntrPt.x+5, CntrPt.y);
pic[3] := point( CntrPt.x, CntrPt.y+5);
//Notes:
//1. As I'm calling the inherited WMPAINT method before drawing the button -
// I have to use getDC(handle) instead of beginpaint(handle,paintstruct)
// otherwise I don't see the button! (I think due to clipping.)
//2. If I wanted to draw the text as well as the button (without calling
// the inherited method) then I would have to use beginpaint(handle,paintstruct).
dc := getDC(handle);
//To make this method a little more efficient you could add a private Canvas field
// to the component and create it once only in TButtonEdit.create and free it in
//TButtonEdit.destroy. I've kept it all here for simplicity.
//(Don't use TControlCanvas instead of TCanvas in TButtonEdit.create -
//It doesn't work! - Someone might explain TControlCanvas to me.)
with TCanvas.create do begin
Handle := dc;
Brush.Color := clBtnFace;
//Brush.style := bsSolid;
//paint the button surface...
FillRect(rect(clientwidth-BUTTONWIDTH+1,0,clientwidth,clientheight));
//draw the button edges...
if FPressed then Pen.color := clBtnShadow else Pen.color := clBtnHighlight;
Moveto(clientwidth-BUTTONWIDTH+2,clientheight-1);
Lineto(clientwidth-BUTTONWIDTH+2,1);
Lineto(clientwidth-1,1);
if FPressed then Pen.color := clBtnHighlight else Pen.color := clBtnShadow;
Lineto(clientwidth-1,clientheight-1);
Lineto(clientwidth-BUTTONWIDTH+2,clientheight-1);
//draw the arrows...
Brush.Color := clGreen;
Pen.color := clBlack;
polygon(pic);
Pen.color := clBtnFace;
Moveto(CntrPt.x-5,CntrPt.y);
Lineto(CntrPt.x+6,CntrPt.y);
Handle := 0;
free; //the canvas.
end;
ReleaseDC(handle,dc);
end;
{----------------------------------------------------------------------}
(*
//Old WMPAINT Method (not using TCanvas)...
procedure TButtonEdit.WMPAINT(var Message: TMessage);
var
dc: HDC;
SilverBrush, ArrowBrush, Oldbrush: HBrush;
WhitePen, GrayPen, SilverPen, OldPen: HPen;
CntrPt: TPoint;
pic: array [0..3] of TPoint; // for arrow 'picture'.
begin
inherited;
//NOW DRAW BUTTON ...
//find the centre of the button...
CntrPt := point(clientwidth - BUTTONWIDTH div 2, clientheight div 2);
//offset by 1 if pressed...
if FPressed then CntrPt := point(CntrPt.x+1,CntrPt.y+1);
//get button arrow coordinates...
pic[0] := point( CntrPt.x-5,CntrPt.y);
pic[1] := point( CntrPt.x,CntrPt.y-5);
pic[2] := point( CntrPt.x+5, CntrPt.y);
pic[3] := point( CntrPt.x, CntrPt.y+5);
//create handles ...
dc := getDC(handle);
SilverBrush := CreateSolidBrush(GetSysColor(COLOR_BTNFACE));
ArrowBrush := CreateSolidBrush(clGreen);
WhitePen := CreatePen(PS_SOLID,1,clWhite);
GrayPen := CreatePen(PS_SOLID,1,clGray);
SilverPen := CreatePen(PS_SOLID,1,GetSysColor(COLOR_BTNFACE));
//draw button surface and outline...
OldBrush := SelectObject(dc, ArrowBrush);
FillRect(dc,rect(clientwidth-BUTTONWIDTH+1,0,clientwidth,clientheight),SilverBrush);
if FPressed then OldPen := SelectObject(dc,GrayPen)
else OldPen := SelectObject(dc,WhitePen);
MovetoEx(dc,clientwidth-BUTTONWIDTH+2,clientheight-1,nil);
Lineto(dc,clientwidth-BUTTONWIDTH+2,1);
Lineto(dc,clientwidth-1,1);
if FPressed then SelectObject(dc,WhitePen)
else SelectObject(dc,GrayPen);
Lineto(dc,clientwidth-1,clientheight-1);
Lineto(dc,clientwidth-BUTTONWIDTH+2,clientheight-1);
//draw up&down arrows...
SelectObject(dc,OldPen);
polygon(dc,pic,4);
SelectObject(dc,SilverPen);
MovetoEx(dc,CntrPt.x-5,CntrPt.y,nil);
Lineto(dc,CntrPt.x+6,CntrPt.y);
//clean up ...
SelectObject(dc,OldPen);
SelectObject(dc, OldBrush);
DeleteObject(WhitePen);
DeleteObject(SilverPen);
DeleteObject(GrayPen);
DeleteObject(SilverBrush);
DeleteObject(ArrowBrush);
ReleaseDC(handle,dc);
end;
*)
{----------------------------------------------------------------------}
end.
'DelPhi' 카테고리의 다른 글
[DelPhi] 자신의 개인 DLL 제작한 후 사용해보기 소스 (0) | 2020.04.12 |
---|---|
[DelPhi] 간단하게 dll로 값을 저장&불러오기 (0) | 2020.04.12 |
[DelPhi] 델파이 랜덤문자 만들기 두번째방법 (0) | 2020.04.12 |
[DelPhi] 델파이 랜덤문자 만들기 첫번째방법 (0) | 2020.04.12 |
[DelPhi] 델파이 캡션명 인젝터 구동하기 소스 (0) | 2020.04.12 |