이전 기사는 간단한 힌트 적용을 소개 하며이 기사는 힌트 윈도우를 사용자 정의하는 예를 제공합니다. 이 맞춤형 힌트 창은 유리가 테두리와 그림자 효과로 좋은 효과를 갖습니다.
그러나 그 전에는 힌트의 상위 클래스를 사용자 정의하는 방법을 소개해야합니다. 몇 가지 가상 방법을 살펴보고 CreateParams는 창의 스타일을 설정하고 국경이 없도록 덮어 쓰고 싶습니다. NCPaint는 창의 경계를 그립니다. 우리는 국경이 필요하지 않기 때문에 그것을 덮어야합니다. 페인트가 더 중요하므로 힌트 윈도우 클라이언트 영역의 내용에 포함되어야합니다. 그러나 가장 중요한 것은 ActivateHint이며, 이는 창의 크기를 설정하고 유리 같은 창 효과를 사용자 정의합니다. 이 클래스의 구현은 다음과 같습니다.
단위 wdhintwnd;
인터페이스
용도
창, 클래스, 컨트롤, 그래픽, 양식, 시스템, ExtCtrls;
유형
twdhintwnd = class (thintwindow)
사적인
fwndbmp : tbitmap;
fhintbmp : tbitmap; // 프롬프트 정보 비트 맵
보호
절차 CreateParams (var params : tcreateparams);
절차 페인트; 재정의 페인트;
절차 NCPAINT (DC : HDC);
{이미지 프롬프트 그리기}
프로 시저 DrawHintimg (bmp : tbitmap; ahint : String);
{프롬프트 창에 해당하는 데스크탑 영역의 이미지 가져 오기}
절차 getDeskTopimg (bmp : tbitmap; r : trect);
{약간 그림자가있는 유리 조각처럼 보이도록 데스크탑 영역 이미지를 취급}
절차 effecthandle (wndbmp, hintbmp : tbitmap);
공공의
생성자 생성 (aowner : tcomponent);
소멸자 파괴;
절차 활성화 (rect : trect; const ahint : String);
끝;
구현
{twdhintwnd}
절차 twdhintwnd.activatehint (rect : trect; const ahint : String);
var
P : tpoint;
시작하다
// 여기에 텍스트를 표시하기 위해 적절한 크기를 가져옵니다
fhintbmp.width : = rect.right- rect.left;
fhintbmp.height : = rect.bottom- rect.top + 4;
DrawHintimg (fhintbmp, ahint);
fwndbmp.width : = rect.right- reft.left + 23;
fwndbmp.height : = rect.bottom- rect.top + 27;
Inc (rect.right, 23);
Inc (rect. Bottom, 27);
boundsRect : = rect;
<screen.desktopleft를 남겨두면
왼쪽 : = screen.desktopleft;
상단 <screen.desktoptop이면
상단 : = screen.desktoptop;
왼쪽 + 너비> screen.desktopwidth라면
왼쪽 : = screen.desktopwidth- 너비;
상단 + 높이> screen.desktopheight 인 경우
상단 : = screen.desktopheight- 높이;
getDeskTopimg (fwndbmp, boundsRect);
effecthandle (fwndbmp, fhintbmp);
p : = clientToscreen (point (0, 0));
setwindowpos (핸들, hwnd_topmost, px, py, 0, 0,
swp_showwindow 또는 swp_noactivate 또는 swp_nosize);
끝;
생성자 twdhintwnd.create (aowner : tcomponent);
시작하다
상속;
fwndbmp : = tbitmap.create;
fwndbmp.pixelformat : = pf24bit;
fhintbmp : = tbitmap.create;
끝;
절차 twdhintwnd.createparams (var params : tcreateparams);
시작하다
상속;
// 창 테두리를 제거합니다
params.style : = ws_border가 아닌 params.style;
끝;
Destructor Twdhintwnd.destroy;
시작하다
fwndbmp.free;
fhintbmp.free;
상속;
끝;
절차 twdhintwnd.getDeskTopimg (bmp : tbitmap; r : trect);
var
C : tcanvas;
시작하다
C : = tcanvas.create;
노력하다
c.handle : = getdc (0);
bmp.canvas.copyrect (rect (0, 0, bmp.width, bmp.height), c, r);
마지막으로
C. free;
끝;
끝;
절차 twdhintwnd.effecthandle (wndbmp, hintbmp : tbitmap);
var
R : Trect;
I, J : 정수;
P : pbytearray;
Transst, transstangle : 정수;
시작하다
r : = rect (0, 0, wndbmp.width -4, wndbmp.height -4);
frame3d (wndbmp.canvas, r, clmedgray, clbtnshadow, 1);
// 창에서 그림자 효과가 되십시오
transst : = 60;
j : = wndbmp.height -4 to wndbmp.height -1 do
시작하다
p : = wndbmp.scanline [j];
transstangle : = transst;
i : = 3 to wndbmp.width -1 do
시작하다
// 오른쪽 하단에있는 경우
I> wndbmp.width -5라면 그럼
시작하다
p [3*i] : = p [3*i]*transstangle div 100;
p [3*i + 1] : = p [3*i + 1]*transstangle div 100;
p [3*i + 2] : = p [3*i + 2]*transstangle div 100;
transstangle : = transstangle + 10;
transstangle> 90이면 transstangle : = 90;
끝
그렇지 않으면 시작합니다
p [3*i] : = p [3*i]*transst div 100;
p [3*i + 1] : = p [3*i + 1]*transst div 100;
p [3*i + 2] : = p [3*i + 2]*transst div 100;
끝;
끝;
Transst : = transst + 10;
끝;
// 창의 오른쪽에있는 그림자 효과
j : = 3 to wndbmp. Height -5 do
시작하다
p : = wndbmp.scanline [j];
transst : = 60;
i : = wndbmp.width -4 to wndbmp.width -1 do
시작하다
p [3*i] : = p [3*i]*transst div 100;
p [3*i + 1] : = p [3*i + 1]*transst div 100;
p [3*i + 2] : = p [3*i + 2]*transst div 100;
Transst : = transst + 10;
끝;
끝;
wndbmp.canvas.draw (10, 10, hintbmp);
끝;
절차 twdhintwnd.ncpaint;
시작하다
// Reload는 테두리 드로잉을 허용하지 않습니다
끝;
절차 twdhintwnd.paint;
시작하다
canvas.copyrect (clientrect, fwndbmp.canvas, clientrect);
끝;
절차 twdhintwnd.drawhintimg (bmp : tbitmap; ahint : String);
var
R : Trect;
시작하다
bmp.canvas.brush.color : = application.hintcolor;
bmp.canvas.pen.color : = application.hintcolor;
bmp.canvas.rectangle (0, 0, bmp.width, bmp.height);
bmp.canvas.font.color : = screen.hintfont.color;
r : = rect (0, 0, bmp.width, bmp.height);
Inc (R.Left, 2);
Inc (R.Top, 2);
DrawText (bmp.canvas.handle, pchar (ahint), -1, r, dt_left 또는 dt_noprefix 또는
dt_wordbreak 또는 drawTextBidimodeflagsreadingonly);
끝;
초기화
application.showhint : = false;
HintwindowClass : = twdhintwnd;
application.showhint : = true;
끝.
프로젝트에 장치를 추가하고 프로그램을 실행하여 효과를 확인하십시오.
프로그램의 중요한 부분은 언급되었으며 여기에는 몇 가지 중요한 점이 있습니다.
부분적으로, 여기에서, 응용 프로그램의 showhint를 false로 설정하고, VCL 소스 코드를보고, 응용 프로그램이 힌트와 윈도를 파괴했으며, 힌트 윈도 클래스의 정의는 다음과 같습니다.
thintwindowclass = thintwindow의 클래스;
HintwindowClass : thintwindowclass = thintwindow;
여기에서는 Twdhintwnd로 교체하고 Application은 힌트 윈도우를 사용하여 위의 힌트 클래스를 만듭니다.
ActiveHint 방법에서는 그 효과를 처리합니다. 원리는 데스크탑에서 프롬프트 창의 위치에 해당하는 비트 맵을 얻은 다음 프롬프트 정보의 위치를 중간에 복사하는 것입니다. 프롬프트 창의 투명성이 있도록 효과가 있습니다. 둘째, 유리의 가장자리를 그려서 마지막으로 창의 오른쪽과 바닥에 그림자 효과를 만듭니다.
Shadow Effects의 구현과 관련하여 이미지는 온라인으로 검색 할 수 있습니다.
dst.red = src.red * alpha + (1-alpha) * dst.red;
dst.green = src.green * alpha + (1-alpha) * dst.green;
dst.blue = src.blue * alpha + (1-alpha) * dst.blue;
알파의 값은 0과 1 사이이며, 이는 1 일 때 완전히 불투명하지만 혼합에 사용할 색상은 검은 색이므로 0, 위의 코드가 보는 것은 다음과 같습니다.
p [3*i] : = p [3*i]*transstangle div 100;
유리 프롬프트 창의 원리는 물론 이와 같습니다. 그러나 신속한 창으로 충분하다고 생각합니다.