Autor Beitrag
Masterhawk
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 92

Win 2000,Win XP
D6 Pers
BeitragVerfasst: Mo 11.09.06 18:10 
Servus erstmal....

Zu meiner Komponente:
CustomButton sollen eine Komponente werden, die Buttons produziert, welche nicht einem Rechteck ähneln. Es soll möglich sein ein Bitmap zu laden und die OnCLick Prozedur soll nur ausgelöst werden, wenn ein nicht transparenter Pixel getroffen wurde.

zu meinen Problemen:

#1: Immer wenn ich versuche meine Prozedur "SetBitmap" aufrufe kommt ein Zugriffsverletzung-Fehler...kann mir jemand sagen warum?

ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
unit CButtons;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  ComCtrls, ExtCtrls;

type
  TCButton = class(TGraphicControl)
  private
    FTransColor : TColor;
    FBitmap     : TBitmap;
    procedure SetTransColor(const Value: TColor);
    procedure SetBitmap(const Value: TBitmap);
    { Private declarations }
  protected
    { Protected declarations }
    procedure Paint; override;
  public
    { Public declarations }
    constructor Create(Owner: TComponent); override;
    destructor Destroy; override;
  published
    { Published declarations }
    property TransColor: TColor read FTransColor write SetTransColor;
    property Bitmap : TBitmap read FBitmap write SetBitmap default nil;
    property Constraints;
    property ParentShowHint;
    property PopupMenu;
    property ShowHint;
    property Visible;
    property Align;
    property Anchors;
    property OnClick;
    property OnMouseDown;
    property OnMouseMove;
    property OnMouseUp;
  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('Masterhawk', [TCButton]);
end;

{ TCButton }

constructor TCButton.Create(Owner: TComponent);
begin
  inherited Create(Owner);
  Width := 50;
  Height := 30;
  FTransColor := clwhite;
  //RGB(255,0,0);
end;

destructor TCButton.Destroy;
begin
  inherited Destroy;
end;

// Draw TCButton
procedure TCButton.Paint;
var Bar: TBitmap;
    I: Integer;
begin
  Bar := TBitmap.Create;
  Bar.Width := Width;
  Bar.Height := Height;
  Bar.TransparentColor:=FTransColor;
  {if FBitmap<>nil then
    Bar.Canvas.CopyRect(Rect(0,0,Width,Height),FBitmap.Canvas,Rect(0,0,Width,Height))
  else}
//<= Auskommentiert, um den Fehler hier auszuschließen
    Bar.Canvas.Brush.Color:=clblack;
  Bar.Canvas.FillRect(Rect(00, Width, Height));
  Canvas.CopyRect(Rect(0,0,Width,Height),Bar.Canvas,Rect(0,0,Width,Height));

  Bar.Free;
end;


procedure TCButton.SetTransColor(const Value: TColor);
begin
  FTransColor := Value;
  Paint
end;

procedure TCButton.SetBitmap(const Value:TBitmap);
begin
  FBitmap.Assign(Value);//<==Hier ist der Fehler...hab aber echt schon 
                        //alle möglichen Varianten probiert
  Paint
end;
        
end.


Hat jmd. ne Lösung parat? Wenn noch Infos erwünscht, dann stelle ich diese gerne bereit...

Problem #2:
Ist es möglich die OnClick Prozedur so zu überschreiben, dass sie nur auf nicht transparente Pixel anspricht?
Wie funktioniert die OnClick Prozedur überhaupt?

Thx for help
Masterhawk
Carl Johnson
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 19

Win XP
D3
BeitragVerfasst: Mo 11.09.06 21:21 
Zu #1:

Versuch es mal mit:

FBitmap := TBitmap.Create;
FBitmap.Assign(XYZ....); !


Zu #2:

Du musst das OnClick-Event einfach zuweisen:

Du musst eine eigene procedure mit sämtlichen variablen eines OnClick-Events:

procedure XYZ(XYZ : XYZ........)

schau am besten das OnClick-Event einer fertigen Komponente an und kopier dir das in deine eigene!


danach definierst du das Vorgehen im OnClick-Event:


If (bspw. Mauszeiger auf transparentem Pixel) then
begin
.
.
.
end;


Danach überschreibst du im Constructor das OnClick-Event des Button, etwa so:


...inherited(Owner)
.
.
.
OnClick := XYZ(siehe Name der procedure)


Dass sollte es eigentlich gewesen sein.Hab allerdings keine Zeit,dass jetzt zu testen!
Probier es mal, sonst muss ich selbst mal schauen..
Masterhawk Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 92

Win 2000,Win XP
D6 Pers
BeitragVerfasst: Di 12.09.06 11:31 
#1: Wie gesagt, ich hatte zwar schon fast alle Möglichkeiten ausprobiert und diese auch, aber ich habe danach nie die Komponente neu eingebunden.... :autsch:
Nun habe ich aber ein anderes Problem....wenn ich den Code auskommentiere, dann wird das Bild net auf der Form angezeigt, warum?
ausblenden Delphi-Quelltext
1:
2:
3:
4:
if FBitmap<>nil then
    Bar.Canvas.CopyRect(Rect(0,0,Width,Height),FBitmap.Canvas,Rect(0,0,Width,Height))
  else
    Bar.Canvas.Brush.Color:=clblack;


#2: Ok, du hast recht. Da hätt ich ja auch selber drauf kommen können...

Special Thx für deine Mühen

MfG Masterhawk
Carl Johnson
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 19

Win XP
D3
BeitragVerfasst: Di 12.09.06 18:13 
Du hast vielleicht CopyMode nicht gesetzt (in dem Fall sollte es etwa so aussehen:

Bar.Canvas.CopyMode := cmSrcCopy;)

Das ist vor CopyRect nötig. Kann aber auch noch an anderen Dingen liegen.

Du könntest mal die gesamt procedure posten, damit ich mal gucken kann,falls dass nicht funzt.
Masterhawk Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 92

Win 2000,Win XP
D6 Pers
BeitragVerfasst: Di 12.09.06 20:09 
ok, an Bar.Canvas.CopyMode := cmSrcCopy; bzw. Canvas.CopyMode := cmSrcCopy; lag es nicht....

Hier die Paint Prozedur.....alles komplett findest du im ersten Post
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
procedure TCButton.Paint;
var Bar: TBitmap;
    I: Integer;
begin
  Bar := TBitmap.Create;
  Bar.Width := Width;
  Bar.Height := Height;
  Bar.TransparentColor:=FTransColor;
  if FBitmap<>nil then
    Bar.Assign(FBitmap)
  else
   Bar.Canvas.Brush.Color:=clblack;
  Bar.Canvas.CopyMode := cmSrcCopy;
  Bar.Canvas.FillRect(Rect(00, Width, Height));
  Canvas.CopyMode := cmSrcCopy;
  Canvas.CopyRect(Rect(0,0,Width,Height),Bar.Canvas,Rect(0,0,Width,Height));

  Bar.Free;
end;


Ich bekomme immer wenn ich mein Projekt öffne folgende Fehlermeldung:
Zitat:
Fehler beim Lesen von CButton1.Bitmap.Data: Ungültiger Pfad für Eigenschaft. Ignore the error and continue? NOTE: Ignoring the error may cause components to be deleted or property values to be lost.


Wo ist der Denkfehler....übergebe ich die Bitmap doch falsch?

MfG Masterhawk
Masterhawk Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 92

Win 2000,Win XP
D6 Pers
BeitragVerfasst: Mi 13.09.06 19:24 
PUSH: HEEEEEELP......wo bist du CARL??? ;)
Carl Johnson
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 19

Win XP
D3
BeitragVerfasst: Mi 13.09.06 23:49 
Hab den Fehler wahrscheinlich gefunden:

Falls du die auf dem Button darstellen willst, wenn dieses eine Grafik enthält, und der Button schwarz erscheinen soll, wenn dies nicht der Fall ist, dann ist dass die Lösung.

Sonst musst du noch mit dem else hantieren.

Das eigentliche Problem ist FBitmap <> nil, da FBitmap immer <> nil ist. Was du brauchst, ist FBitmap.Empty!

Teste mal :


ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
 procedure TCButton.Paint;  
var Bar: TBitmap;  
    I: Integer;  
begin  
  Bar := TBitmap.Create;  
  Bar.Width := Width;  
  Bar.Height := Height;  
  Bar.TransparentColor:=FTransColor;  
  if FBitmap.Empty = False then  
    Bar.Assign(FBitmap)  
  else  
  begin 
  Bar.Canvas.Brush.Color:=clblack;  
  Bar.Canvas.FillRect(Rect(00, Width, Height));  
  end;
  Canvas.CopyMode := cmSrcCopy;  
  Canvas.CopyRect(Rect(0,0,Width,Height),Bar.Canvas,Rect(0,0,Width,Height));  
  Canvas.Brush.Bitmap; 
 
  Bar.Free;  
end;



Du könntest evtl. noch ne AccessViolation bekommen. Dass liegt dann aber an "Canvas.bla".

Probiers dann mal mit "TCButton.Canvas.bla" oder so.

Ansonsten viel Spaß!
Masterhawk Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 92

Win 2000,Win XP
D6 Pers
BeitragVerfasst: Do 14.09.06 12:11 
Servus.....Problem #1 ist gelöst:
Ich musste anstatt
ausblenden Delphi-Quelltext
1:
2:
3:
FBitmap:TBitmap;

procedure SetBitmap(Value:TBitmap);


es so verwenden

ausblenden Delphi-Quelltext
1:
2:
3:
FBitmap:Graphics.TBitmap;

procedure SetBitmap(Value:Graphics.TBitmap);


Aber hier mal die zwei wichtigsten Procezeduren für das Problem:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
procedure TCButton.Paint;
var 
   Bar: TBitmap;
begin
  Bar := TBitmap.Create;
  Bar.Width := Width;
  Bar.Height := Height;
  Bar.TransparentColor:=FTransColor;

  if FBitmap.Empty = False then //<= DAmit hier keine Accessviolation auftritt
                              //  muss FBitmap in TCButton.Create
    Bar.Assign(FBitmap)      //   initialisiert werden
  else  
  begin
   Canvas.Brush.Color:=clblack;
   Canvas.FillRect(Rect(00, Width, Height));
  end;
  Canvas.CopyMode := cmSrcCopy;
  Canvas.CopyRect(Rect(0,0,Width,Height),Bar.Canvas,Rect(0,0,Width,Height));
  Canvas.Brush.Bitmap;

  Bar.Free;
end;


procedure TCButton.SetBitmap(const Value:Graphics.TBitmap);
begin
  FBitmap.Assign(Value);
  Paint
end;


Jetzt werd ich mich dann wohl mal bald an Problem #2 machen.....ihr werdet mich dann wieder hier finden....:P


EDIT: PROBLEM #2 GELÖST!!!!