标 题: 不规则窗口VCL控件源码 (BBS 水木清华站)(0分)

  • 主题发起人 主题发起人 taozhiyu
  • 开始时间 开始时间
T

taozhiyu

Unregistered / Unconfirmed
GUEST, unregistred user!
发信人: laoduan (知耻者近乎勇), 信区: Delphi

标 题: 不规则窗口VCL控件源码

发信站: BBS 水木清华站 (Mon Jun 18 14:47:04 2001)



{ written by laoduan, you can distribute it as your wish }



unit FormShaper;

interface

uses

Windows, Messages, SysUtils, Classes, Graphics, Forms, DsgnIntf;

type

// TFormShaper

TFormShaper = class(TComponent)

private

FBkgndBitmap: TBitmap;

FOwnerHandle: HWND;

FOldBorderStyle: TBorderStyle;

FOldClientWidth: Integer;

FOldClientHeight: Integer;

FHookInstance: Pointer;

FOldWindowProc: Pointer;

FOldWindowRgn: HRGN;

procedure HookWindowProc(var Message: TMessage);

procedure BkgndBitmapChange(Sender: TObject);

procedure SetBkgndBitmap(bitmap: TBitmap);

public

constructor Create(AOwner: TComponent); override;

destructor Destroy; override;

published

property BkgndBitmap: TBitmap read FBkgndBitmap write SetBkgndBitmap;

end;

// TFormShaperEditor

TFormShaperEditor = class(TDefaultEditor)

protected

procedure EditProperty(PropertyEditor: TPropertyEditor;

var Continue, FreeEditor: Boolean); override;

public

procedure ExecuteVerb(Index: Integer); override;

function GetVerb(Index: Integer): string; override;

function GetVerbCount: Integer; override;

end;

// procedure Register

procedure Register;

implementation

// procedure TFormShaper.HookWindowProc(var Message: TMessage);

procedure TFormShaper.HookWindowProc(var Message: TMessage);

var

Canvas: TCanvas;

begin

try

with Message do

begin

if FBkgndBitmap.Empty then

Result := CallWindowProc(FOldWindowProc, FOwnerHandle, Msg, WParam,

LParam)

else

case Msg of

WM_ERASEBKGND:

begin

Canvas := TCanvas.Create;

Canvas.Handle := HDC(WParam);

Canvas.Draw(0, 0, FBkgndBitmap);

Canvas.Free;

Result := LRESULT(True);

end;

WM_LBUTTONDOWN:

begin

ReleaseCapture;

SendMessage(FOwnerHandle, WM_NCLBUTTONDOWN, HTCAPTION, 0);

Result := LRESULT(False);

end;

else

Result := CallWindowProc(FOldWindowProc, FOwnerHandle, Msg, WParam,

LParam);

end;

end;

except

Application.HandleException(Self);

end;

end;

// function CreateRgnFromBitmap(rgnBitmap: TBitmap): HRGN;

function CreateRgnFromBitmap(rgnBitmap: TBitmap): HRGN;

var

transColor: TColor;

i, j: Integer;

width, height: Integer;

left, right: Integer;

rectRgn: HRGN;

begin

Result := 0; // NULL in C/C++

width := rgnBitmap.Width;

height := rgnBitmap.Height;

transColor := rgnBitmap.Canvas.Pixels[width - 1, height - 1];

for i := 0 to height - 1 do

begin

left := -1;

for j := 0 to width - 1 do

begin

if left < 0 then

begin

if rgnBitmap.Canvas.Pixels[j, i] <> transColor then

left := j;

end

else

if rgnBitmap.Canvas.Pixels[j, i] = transColor then

begin

right := j;

rectRgn := CreateRectRgn(left, i, right, i + 1);

if Result = 0 then

Result := rectRgn

else

begin

CombineRgn(Result, Result, rectRgn, RGN_OR);

DeleteObject(rectRgn);

end;

left := -1;

end;

end;

if left >= 0 then

begin

rectRgn := CreateRectRgn(left, i, width, i + 1);

if Result = 0 then

Result := rectRgn

else

begin

CombineRgn(Result, Result, rectRgn, RGN_OR);

DeleteObject(rectRgn);

end;

end;

end;

end;

// procedure TFormShaper.BkgndBitmapChange(Sender: TObject);

procedure TFormShaper.BkgndBitmapChange(Sender: TObject);

var

form: TForm;

windowRgn: HRGN;

begin

if Owner is TForm then

begin

form := TForm(Owner);

if FBkgndBitmap.Empty then

begin

form.BorderStyle := FOldBorderStyle;

form.ClientWidth := FOldClientWidth;

form.ClientHeight := FOldClientHeight;

SetWindowRgn(FOwnerHandle, FOldWindowRgn, True);

end

else

begin

form.BorderStyle := bsNone;

form.ClientWidth := FBkgndBitmap.Width;

form.ClientHeight := FBkgndBitmap.Height;

windowRgn := CreateRgnFromBitmap(FBkgndBitmap);

SetWindowRgn(FOwnerHandle, windowRgn, True);

end;

end;

end;

// procedure TFormShaper.SetBkgndBitmap(bitmap: TBitmap);

procedure TFormShaper.SetBkgndBitmap(bitmap: TBitmap);

begin

FBkgndBitmap.Assign(bitmap);

end;

// constructor TFormShaper.Create(AOwner: TComponent);

constructor TFormShaper.Create(AOwner: TComponent);

var

form: TForm;

begin

inherited Create(AOwner);

FBkgndBitmap := TBitmap.Create;

FBkgndBitmap.OnChange := BkgndBitmapChange;

FHookInstance := MakeObjectInstance(HookWindowProc);

if AOwner is TForm then

begin

form := TForm(AOwner);

FOldBorderStyle := form.BorderStyle;

FOldClientWidth := form.ClientWidth;

FOldClientHeight := form.ClientHeight;

FOwnerHandle := form.Handle;

FOldWindowProc := Pointer(GetWindowLong(FOwnerHandle, GWL_WNDPROC));

SetWindowLong(FOwnerHandle, GWL_WNDPROC, LongInt(FHookInstance));

GetWindowRgn(FOwnerHandle, FOldWindowRgn);

end;

end;

// destructor TFormShaper.Destroy;

destructor TFormShaper.Destroy;

var

form: TForm;

begin

if Owner is TForm then

begin

SetWindowLong(FOwnerHandle, GWL_WNDPROC, LongInt(FOldWindowProc));

form := TForm(Owner);

form.ClientWidth := FOldClientWidth;

form.ClientHeight := FOldClientHeight;

form.BorderStyle := FOldBorderStyle;

SetWindowRgn(FOwnerHandle, FOldWindowRgn, True);

end;

FreeObjectInstance(FHookInstance);

FBkgndBitmap.Free;

inherited Destroy;

end;

// procedure TFormShaperEditor.EditProperty

procedure TFormShaperEditor.EditProperty(PropertyEditor: TPropertyEditor;

var Continue, FreeEditor: Boolean);

var

PropName: string;

begin

PropName := PropertyEditor.GetName;

if (CompareText(PropName, 'BkgndBitmap') = 0) then

begin

PropertyEditor.Edit;

Continue := False;

end;

end;

// function TFormShaperEditor.GetVerbCount

function TFormShaperEditor.GetVerbCount: Integer;

begin

Result := 1;

end;

// function TFormShaperEditor.GetVerb

Index: Integer): string;

begin

if Index = 0 then

Result := 'Load Background Bitmap'

else Result := '';

end;

// procedure TFormShaperEditor.ExecuteVerb

procedure TFormShaperEditor.ExecuteVerb(Index: Integer);

begin

if Index = 0 then Edit;

end;

procedure Register;

begin

RegisterComponents('Samples', [TFormShaper]);

RegisterComponentEditor(TFormShaper, TFormShaperEditor);

end;

end.

--

侠女,其实我就是东方不败的师父---西方失败

多隆,给我备一匹最快的马,我有事要走先~~~





 
Good & Useful
 
接受答案了.
 
后退
顶部