Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi Region vom Bitmap erstellen... (https://www.delphipraxis.net/139798-region-vom-bitmap-erstellen.html)

turboPASCAL 5. Sep 2009 16:08


Region vom Bitmap erstellen...
 
Hi,

isch möschde eine Region (HRGN) von einem Bitmap auf Basis einer bestimmten Farbe erstellen.
Soweit sogut. Das eigentliche Problem an der Sache ist das Auffinden und Zusammensetzen
der Regionen.

Ich kann ja jeden passenden Pixel zu einer Region "adden", das ist mir aber zu unoptimal™.
Nun suche ich einen Algo. der was taugt.

Hat jemand einen Vorschlag ?

( ich hatte mir schon mal vor längerer zeit was gebastelt, leider finde ich es nicht mehr... )

himitsu 5. Sep 2009 16:42

Re: Region vom Bitmap erstellen...
 
ich weiß grad nicht wie, aber man konnte auch ein (Schwarz/Weiß) BitMap irgendwie direkt zur Region hinzufügen.

turboPASCAL 5. Sep 2009 16:50

Re: Region vom Bitmap erstellen...
 
Ja, irgend wie mit ExtCreateRegion. Bin gerade am Nachforschen...

himitsu 5. Sep 2009 17:00

Re: Region vom Bitmap erstellen...
 
im Notfall wirklich Pixel für Pixel :freak:
http://www.bobpowell.net/region_from_bitmap.htm

http://www.codeguru.com/cpp/g-m/bitm...icle.php/c1751

turboPASCAL 6. Sep 2009 07:13

Re: Region vom Bitmap erstellen...
 
Liste der Anhänge anzeigen (Anzahl: 1)
Also mal von C nach D.
Delphi-Quellcode:
function BitmapToRegion(bmp: TBitmap; TransparentColor: TColor): HRGN;
const
  AllocUnit = 100;
type
  PRectArray = ^TRectArray;
  TRectArray = array[0..(MaxInt div SizeOf(TRect)) - 1] of TRect;
var
  pr: PRectArray; // used to access the rects array of RgnData by index
  h: HRGN; // Handles to regions
  RgnData: PRgnData; // Pointer to structure RGNDATA used to create regions
  x, y, x0: Integer; // coordinates of current rect of visible pixels
  maxRects: Cardinal; // Number of rects to realloc memory by chunks of AllocUnit
begin
  Result := 0;

  maxRects := AllocUnit;
  GetMem(RgnData, SizeOf(RGNDATAHEADER) + (SizeOf(TRect) * maxRects));
  try
    with RgnData^.rdh do
    begin
      dwSize := SizeOf(RGNDATAHEADER);
      iType := RDH_RECTANGLES;
      nCount := 0;
      nRgnSize := 0;
      SetRect(rcBound, MAXLONG, MAXLONG, 0, 0);
    end;

    for y := 0 to bmp.Height - 1 do
    begin
      x := 0;
      while x < bmp.Width - 1 do
      begin

        // Pixel suchen die der transp. Farbe entsprechen & x solange erhöhen
        x0 := x;
        while x < bmp.Width - 1 do
        begin
          // ohne scanline zu Testzwecken - mit (Windows.)GetPixel
          if GetPixel(bmp.Canvas.Handle, x, y) = DWORD(TransparentColor) then break;
          Inc(x);
        end;

        // test to see if we have a non-transparent area in the image
        if x > x0 then
        begin
          // increase RgnData by AllocUnit rects if we exceeds maxRects
          if RgnData^.rdh.nCount >= maxRects then
          begin
            Inc(maxRects, AllocUnit);
            ReallocMem(RgnData, SizeOf(RGNDATAHEADER) + (SizeOf(TRect) * MaxRects));
          end;

          // Add the rect (x0, y)-(x, y+1) as a new visible area in the region
          pr := @RgnData^.Buffer; // Buffer is an array of rects
          with RgnData^.rdh do
          begin
            SetRect(pr[nCount], x0, y, x, y + 1);
            // adjust the bound rectangle of the region if we are "out-of-bounds"
            if x0 < rcBound.Left then rcBound.Left := x0;
            if y < rcBound.Top then rcBound.Top := y;
            if x > rcBound.Right then rcBound.Right := x;
            if y + 1 > rcBound.Bottom then rcBound.Bottom := y + 1;
            Inc(nCount);
          end;
        end; // if x > x0

        // Need to create the region by muliple calls to ExtCreateRegion, 'cause
        // it will fail on Windows 98 if the number of rectangles is too large
        if RgnData^.rdh.nCount = 2000 then
        begin
          h := ExtCreateRegion(nil, SizeOf(RGNDATAHEADER) + (SizeOf(TRect) * maxRects), RgnData^);
          if Result > 0 then
          begin // Expand the current region
            CombineRgn(Result, Result, h, RGN_OR);
            DeleteObject(h);
          end
          else // First region, assign it to Result
            Result := h;
          RgnData^.rdh.nCount := 0;
          SetRect(RgnData^.rdh.rcBound, MAXLONG, MAXLONG, 0, 0);
        end;
        Inc(x);
      end; // scan every sample byte of the image
    end;

    // need to call ExCreateRegion one more time because we could have left
    // a RgnData with less than 2000 rects, so it wasn't yet created/combined
    h := ExtCreateRegion(nil, SizeOf(RGNDATAHEADER) + (SizeOf(TRect) * MaxRects), RgnData^);
    if Result > 0 then
    begin
      CombineRgn(Result, Result, h, RGN_OR);
      DeleteObject(h);
    end else
      Result := h;
  finally
    FreeMem(RgnData, SizeOf(RGNDATAHEADER) + (SizeOf(TRect) * MaxRects));
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
var
  ARgn: HRGN;
  ABitmap: TBitmap;
begin
  ABitmap := TBitmap.Create;
  try
    ARgn := BitmapToRegion(Image1.Picture.Bitmap, clFuchsia);
    SetWindowRgn(Form1.Handle, ARgn, True);
  finally
    ABitmap.Free;
  end;
end;
Das ist allerding (in etwa) genauso wie mein alter Code nur das ich nur mit CombineRgn() und CreateRoundRgn() arbeitete.

Irgend wie heht das sicherlich auch anders / einfacher...

himitsu 6. Sep 2009 08:44

Re: Region vom Bitmap erstellen...
 
Vorallen da ich mir etwas sichter bin, mal eine Version gesehn zu haben, wo ein Bitmap direkt einer Funktion gegeben wurde und fertig war's :nerd:

Aber ich hatte vor 'ner ganzen Weile selber nochmal danach gesucht und nix gefunden,
wobei ich mir halt sicher war das noch 'ne größere Weile vorher (ist schon bestimmt mindestens 3 Jahre her) mal gesehn zu haben :?

turboPASCAL 6. Sep 2009 09:32

Re: Region vom Bitmap erstellen...
 
Zitat:

wobei ich mir halt sicher war das noch 'ne größere Weile vorher (ist schon bestimmt mindestens 3 Jahre her) mal gesehn zu haben
Ja, das kenn ich.

Zitat:

Vorallen da ich mir etwas sichter bin, mal eine Version gesehn zu haben, wo ein Bitmap direkt einer Funktion gegeben wurde und fertig
So in etwa dachte ich auch daran.

In der TRgnData-Strucktur müsste man den "Daten"-Buffer irgend wie nutzen.

Aber erst mal muss man verstehen wie und was TRgnData-Strucktur macht usw.

Progman 6. Sep 2009 09:51

Re: Region vom Bitmap erstellen...
 
Meinst du sowas?
Delphi-Quellcode:
type
  TRGBArray = array[0..32767] of TRGBTriple;
  PRGBArray = ^TRGBArray;

type
  TfrmMain = class(TForm)
    ...
  private
    { Private-Deklarationen }
    HG: TBitmap;
    FRegion: THandle;
    function CreateRegion(Bmp: TBitmap): THandle;
  public
    ...
  end;

implementation

function TfrmMain.CreateRegion(Bmp: TBitmap): THandle;
var
  X, Y, StartX: Integer;
  Excl: THandle;
  Row: PRGBArray;
  TransparentColor: TRGBTriple;
begin
  Bmp.PixelFormat := pf24Bit;
  Result := CreateRectRGN(0, 0, Bmp.Width, Bmp.Height);
  for Y := 0 to Bmp.Height - 1 do
  begin
    Row := Bmp.Scanline[Y];
    StartX := -1;
    if Y = 0 then
      TransparentColor := Row[0];
    for X := 0 to Bmp.Width - 1 do
    begin
      if (Row[X].rgbtRed = TransparentColor.rgbtRed) and
        (Row[X].rgbtGreen = TransparentColor.rgbtGreen) and
        (Row[X].rgbtBlue = TransparentColor.rgbtBlue) then
      begin
        if StartX = -1 then StartX := X;
      end
      else
      begin
        if StartX > -1 then
        begin
          Excl := CreateRectRGN(StartX, Y, X + 1, Y + 1);
          try
            CombineRGN(Result, Result, Excl, RGN_DIFF);
            StartX := -1;
          finally
            DeleteObject(Excl);
          end;
        end;
      end;
    end;
    if StartX > -1 then
    begin
      Excl := CreateRectRGN(StartX, Y, Bmp.Width, Y + 1);
      try
        CombineRGN(Result, Result, Excl, RGN_DIFF);
      finally
        DeleteObject(Excl);
      end;
    end;
  end;
end;


//Borderstyle muss bsNone sein
procedure TfrmMain.FormCreate(Sender: TObject);
var Bmp: TBitmap;
begin
  HG:=TBitmap.Create;
  HG.LoadFromFile(ResPath+'Monitor.bmp');
  Bmp := TBitmap.Create;
  try
    bmp.Assign(HG);
    Width:=HG.Width;
    ClientHeight:=HG.Height;
    FRegion := CreateRegion(Bmp);
    SetWindowRGN(Handle, FRegion, True);
  finally
    Bmp.Free;
  end;
  ...
end;

procedure TfrmMain.FormDestroy(Sender: TObject);
begin
  DeleteObject(FRegion);
  HG.Free;
end;

procedure TfrmMain.FormPaint(Sender: TObject);
begin
  BitBlt(canvas.handle, 0, 0, Clientwidth, Clientheight,HG.Canvas.handle, 0, 0, SRCCOPY);
end;
Das erzeugt einer Region anhand eines Bitmaps. Das Fenster hat dann die Form des Bitmaps. Als transparent wird die Farbe der Pixels 0,0 festgelegt (glaub ich) ;)

EWeiss 28. Jul 2011 04:43

AW: Region vom Bitmap erstellen...
 
Ich möchte meinen Button eine region verpassen
Mit Standard Button (TButton) funktioniert das aber leider nicht mit nonvcl Button.

Habe es mal mit beiden Functionen versucht.
Diese hier..
http://www.delphipraxis.net/948896-post5.html

und

auf dieser Seite.
http://www.delphipraxis.net/404171-post7.html


beides will nicht funktionieren.
Warum ist mir schleierhaft.

jemand eine Idee?


Delphi-Quellcode:
      if Region > 0 then
      begin
        GdipCreateHBITMAPFromBitmap(pointer(img), hbmReturn, $000000);
        if hbmReturn <> 0 then
        begin
          ABitmap := TBitmap.Create;
          ABitmap.Handle := hbmReturn;
          ABitmap.Width := btW;
          ABitmap.Height:= btH;

          FHImageButton := CreateWindowEx(WS_EX_TRANSPARENT, SKIMAGEBUTTON,
            '', Style, x, y, btW, btH, hOwner, ButID, SkinEngine.skInstance, nil);
          if FHImageButton <> 0 then
          begin
            SkinEngine.SetImageProperty(FHImageButton, PROP_IMAGE_BACK, Img);
            SkinEngine.SetImageProperty(FHImageButton, PROP_STYLE, BS_BITMAP);
            SkinEngine.SetImageProperty(FHImageButton, PROP_STATEMAX, StateMax);

            ARgn := BitmapToRegion(ABitmap.Handle, imgw, imgh, RGB(255,0,255), 0);
            SetWindowRgn(FHImageButton, ARgn, True);
            ABitmap.Free;
          end else
          begin
            // Lösche das Image
            SkinEngine.DeleteResource(hOwner, Img);
          end;
        end;

gruss

EWeiss 28. Jul 2011 06:32

AW: Region vom Bitmap erstellen...
 
Push .. :duck:

Hab mal ein Button Beispiel von Luckie umgestrickt. (nonvcl)
Also der Rosa bereich des Button soll abgeschnitten werden.

Vielleicht schaut ja mal jemand in den Sample rein.

gruss

EWeiss 29. Jul 2011 00:59

AW: Region vom Bitmap erstellen...
 
Niemand eine Idee? :cry:

gruss

himitsu 29. Jul 2011 06:08

AW: Region vom Bitmap erstellen...
 
Ich dachte mal, daß ich da auch irgendwann einmal sowas gesehn hatte,
abr als ich letztens danach suchte, fand ich nur eine (etwas langsame) Funktion, welche das Bild Pixelweise auslas und dieses in eine Region eintrug. :shock:

Wäre och gespannt, ob es dennoch was Besseres gibt.

EWeiss 29. Jul 2011 07:21

AW: Region vom Bitmap erstellen...
 
Wenn du mein projekt im vorherigen Thread mal laden würdest ;)
Button.rar.

Grundsätzlich funktioniert das ja aber nur in der VCL mit einem TButton nicht in nonvcl.
Das ist was mich stutzig macht.

gruss

himitsu 29. Jul 2011 08:24

AW: Region vom Bitmap erstellen...
 
Oh komma, hier gibt es ja nocheine Seite. :shock:


Na mal sehn ... vielleicht schau ich am WE nochmal rein.

turboPASCAL 31. Jul 2011 13:37

AW: Region vom Bitmap erstellen...
 
Liste der Anhänge anzeigen (Anzahl: 2)
Zitat:

Zitat von EWeiss (Beitrag 1113906)
Ich möchte meinen Button eine region verpassen
Mit Standard Button (TButton) funktioniert das aber leider nicht mit nonvcl Button.

Doch, das tut es.


Zitat:

Zitat von EWeiss (Beitrag 1113906)
beides will nicht funktionieren.
Warum ist mir schleierhaft.

jemand eine Idee?

Ja.

Man muss die richtigen Window-Attribute setzen. ;)

EWeiss 31. Jul 2011 15:15

AW: Region vom Bitmap erstellen...
 
Zitat:

Man muss die richtigen Window-Attribute setzen.
oops .. werd es mir direkt anschauen was ich da wieder verzapft habe das es nicht ging.

EDIT:
Nur WS_CLIPSIBLINGS vergessen?

EDIT2:
Doch nicht so einfach.. hmmm
Warum wird der Button trotzdem gedrückt obwohl ich im leeren bereich klicke?

Es sieht also so aus das ich das Bitmap selbst auch noch ausschneiden muss.
Was aber eigentlich wenn der bereich Transparent ist nicht nötig sein sollte.

gruss Emil

EWeiss 1. Aug 2011 01:31

AW: Region vom Bitmap erstellen...
 
Will immer noch nicht so wie ich es will :)

Siehe Bild!

Delphi-Quellcode:
      if Region > 0 then
      begin
      Style := WS_CHILD or WS_VISIBLE or WS_CLIPSIBLINGS or BS_PUSHBUTTON;
      if ButID = ID_LED then
          Style := Style or WS_DISABLED;

        GdipLoadImageFromFile(PWideChar(FullPathImageName), img);
        GdipCreateHBITMAPFromBitmap(pointer(img), hbmReturn, $000000);
        if hbmReturn <> 0 then
        begin
          ABitmap := TBitmap.Create;
          ABitmap.Handle := hbmReturn;
          ABitmap.Width := btW;
          ABitmap.Height:= btH;

          FHImageButton := CreateWindowEx(WS_EX_TRANSPARENT, SKIMAGEBUTTON,
            '', Style, x, y, btW, btH, hOwner, ButID, SkinEngine.skInstance, nil);
          if FHImageButton <> 0 then
          begin
            SkinEngine.SetImageProperty(FHImageButton, PROP_IMAGE_BACK, Img);
            SkinEngine.SetImageProperty(FHImageButton, PROP_STYLE, BS_BITMAP);
            SkinEngine.SetImageProperty(FHImageButton, PROP_STATEMAX, StateMax);

            ARgn := RegionFromBitmap(ABitmap.Handle, $FF00FF);
            SetWindowRgn(FHImageButton, ARgn, true);

            ABitmap2 := TBitmap.Create;
            ABitmap2.Width := ImgW;
            ABitmap2.Height:= ImgH;

            ARgn2 := RegionFromBitmap(hbmReturn, $FF00FF);
            SetWindowRgn(ABitmap2.Handle, ARgn2, true);

            ABitmap2.Free;
            ABitmap.Free;
          end else
          begin
            // Lösche das Image
            SkinEngine.DeleteResource(hOwner, Img);
          end;
        end;
      end
Ich erstelle ein HBitmap vom Bitmap
Danach jage ich ABitmap durch die Function RegionFromBitmap
Der Button wird dann Ordnungsgemäß ausgeschnitten.

Aber wie man sieht kann man immer noch den Bereich Magenta des Images sehen.
Ich dachte eigentlich das der ausgeschnittene Bereich des Button wenn ein Image überlagert wird nicht mehr sichtbar sein sollte.
Ist er aber...

Nun gehe ich hin und erstelle eine zusätzliche Maske vom Image selbst das als Strip abgelegt ist
und 2 Bilder in einem enthält. Down/Up Status.

Delphi-Quellcode:
function TSkinImageButton.RegionFromBitmap(hbmp: HBitmap;
  TransColor: ColorRef): HRGN;

type
  TRectArray = array[0..0] of TRect;
var
  bm:     Bitmap;
  pData:  PRgnData;
  lpRect: PRect;
  hRgn2:  HRGN;
  hRgn1:  HRGN;
  sRegionData: THandle;
  MaxRegions: integer;
  I, J, K, M: integer;
  pr:     ^TRectArray;
  p32:    PByte;
  lPixel: PRGBQuad;

begin

  hRgn1  := 0;
  lPixel := nil;

  GetObject(hbmp, SIZEOF(bm), @bm);

  if TransColor = 0 then
    TransColor := cardinal(lPixel) and $FFFFFF;

  MaxRegions := 4000;

  sRegionData := GlobalAlloc(GMEM_MOVEABLE, SizeOf(RGNDATAHEADER) +
    SizeOf(TRECT) * MaxRegions);
  pData := GlobalLock(sRegionData);
  pData^.rdh.nCount := 0;
  pData^.rdh.dwSize := sizeof(RGNDATAHEADER);
  pData^.rdh.iType := RDH_RECTANGLES;
  pData^.rdh.nRgnSize := 0;
  pData^.rdh.rcBound.Left := 0;
  pData^.rdh.rcBound.Top := 0;
  pData^.rdh.rcBound.Right := bm.bmWidth;
  pData^.rdh.rcBound.Bottom := bm.bmHeight;

  lpRect := PRECT(@pData^.Buffer);

  p32 := PByte(integer(bm.bmBits) + (bm.bmHeight - 1) * bm.bmWidthBytes);
  for J := 0 to bm.bmHeight - 1 do
  begin
    I := 0;
    while I < bm.bmWidth do
    begin
      M := I;

      lPixel := Pointer(integer(p32) + I * SizeOf(cardinal));
      while I < bm.bmWidth do
      begin
        K := MakeColor(0, lPixel^.rgbRed, lPixel^.rgbGreen, lPixel^.rgbBlue) and
          $FFFFFF;

        if K <> integer(TransColor) then
        begin
          Inc(I);
          Inc(lPixel);
        end
        else
          Break;
      end;

      if I > M then
      begin
        if integer(pData^.rdh.nCount) >= MaxRegions then
        begin
          hRgn2 := ExtCreateRegion(nil, sizeof(RGNDATAHEADER) +
            (sizeof(TRECT) * pData^.rdh.nCount), PRGNDATA(pData)^);
          if hRgn1 = 0 then
          begin
            hRgn1 := hRgn2;
          end
          else
          begin
            CombineRgn(hRgn1, hRgn1, hRgn2, RGN_OR);
            SkinEngine.skDeleteObject(hRgn2);
          end;
          pData^.rdh.nCount := 0;
        end;

        pr := @pData^.Buffer;
        SetRect(pr^[pData^.rdh.nCount], M, J, I, J + 1);
        if M < lpRect.Left then
          lpRect.Left := M;
        if I > lpRect.Right then
          lpRect.Right := I;
        if J < lpRect.Top then
          lpRect.Top := J;
        if J > lpRect.Bottom then
          lpRect.Bottom := J + 1;
        Inc(pData^.rdh.nCount);
        Inc(lpRect);
      end;

      Inc(I);
    end;
    Dec(p32, bm.bmWidthBytes);
  end;

  hRgn2 := ExtCreateRegion(nil, sizeof(RGNDATAHEADER) +
    (sizeof(TRECT) * pData^.rdh.nCount), pData^);

  if hRgn1 = 0 then
  begin
    hRgn1 := hRgn2;
  end
  else
  begin
    CombineRgn(hRgn1, hRgn1, hRgn2, RGN_OR);
    DeleteObject(hRgn2);
  end;

  GlobalFree(sRegionData);
  DeleteObject(hbmp);

  Result := hRgn1;

end;
Jetzt jage ich ABitmap2 ebenfalls durch diese Function.
Aber der Magenta bereich wird nicht ausgeschnitten bzw. das Bitmap nicht aktualisiert.

Delphi-Quellcode:
ARgn2 := RegionFromBitmap(hbmReturn, $FF00FF);
SetWindowRgn(ABitmap2.Handle, ARgn2, true);
Ist das Handle vom ABitmap2 nicht gültig ?
Oder woran hapert es denn jetzt schon wieder.

Kann zwar den Magenta Bereich mit den Halbton Button überlagern dann tritt aber das problem hier auf.

Klicke ich die C Taste geht alles wunderbar wenn ich aber nach dem loslassen dann C# klicke und in dem Magentabereich der C Taste komme
dann werden zwei Töne gleichzeitig gespielt. C+C#

Puhh hoffe dass das noch jemand ließt.

PS:
Das Image transparent im bereich Magenta zu machen (müßte dann ein zusätzliches MaskImg anlegen um den Button auszuschneiden) bringt auch nichts.
Auch hier werden 2 Tasten betätigt wenn ich auf den Transparenten bereich klicke (Das ist der aktuelle status was weg soll).

gruss

EWeiss 3. Aug 2011 17:32

AW: Region vom Bitmap erstellen...
 
Es will einfach nicht.
Ich ersetze jetzt die Farbe mit

Delphi-Quellcode:
            if SkinEngine.GetProperty(Winhandle, PROP_REGION) = 1 then
            begin
              if GdipCreateImageAttributes(ImgAtt) = 0 then
              begin
                TransColor := SkinEngine.ColorARGB(255, RGB(255, 0, 255));
                if GdipSetImageAttributesColorKeys(ImgAtt, ColorAdjustTypeDefault, True, 0, TransColor) = 0 then
                begin
                  GdipDrawImageRectRectI(Graphics, Img,
                    x, y, ImgW, ImgH,
                    ImgW * cardinal(UseState) - ImgW, 0, ImgW, ImgH, 2,
                    ImgAtt, False, nil)
                end;
              end;
            end else
            GdipDrawImageRectRectI(Graphics, Img,
              x, y, ImgW, ImgH,
              ImgW * cardinal(UseState) - ImgW, 0, ImgW, ImgH, 2,
              nil, False, nil);
aber das Resultat ist das gleiche als wenn ich den bereich direkt Transparent mache im Bitmap selbst.
Warum läßt sich das Bitmap nicht ausschneiden?
geht doch beim Button auch.. hmmm

Oder ist es möglich das nach dem down status des Button die Region von diesen wieder auf default gesetzt wird?
Sehen kann ich das nicht.
Seltsamerweise Wenn ich noch keinen Button geklickt habe lassen sich keine zwei Button gleichzeitig drücken.

gruss

Tryer 3. Aug 2011 18:34

AW: Region vom Bitmap erstellen...
 
Warum heißt SetWindowRgn wohl SetWindowRgn?

Richtig, weil es für Fenster, sprich TWinControls funktioniert.
Ein TBitmap.Handle hat nichts damit zu tun, ist nur "leider" zuweisungskompatibel da es halt auch eine einfache "Hausnummer" ist(LongWord).

Nimm ein TWinControl (z.B. TPanel), packt das Image drauf und wende SetWindowRgn auf Panel.Handle an.

Grüsse, Dirk

EWeiss 3. Aug 2011 19:16

AW: Region vom Bitmap erstellen...
 
Zitat:

Zitat von Tryer (Beitrag 1114953)
Warum heißt SetWindowRgn wohl SetWindowRgn?

Richtig, weil es für Fenster, sprich TWinControls funktioniert.
Ein TBitmap.Handle hat nichts damit zu tun, ist nur "leider" zuweisungskompatibel da es halt auch eine einfache "Hausnummer" ist(LongWord).

Nimm ein TWinControl (z.B. TPanel), packt das Image drauf und wende SetWindowRgn auf Panel.Handle an.

Grüsse, Dirk

Vergess es! (Auch wenn du recht hast mit dem SetWindowRgn)
Zeig mal wie du in einer Nonvcl Anwendung ein TPanel oder was auch immer deiner meinung nach dafür passt einbinden willst.

Mein Problem mit dem Bitmap hab ich schon gelößt wie im vorherigen Beitrag mitgeteilt.
GdipSetImageAttributesColorKeys

Zitat:

Ich denke das mein Problem daran liegt das nach dem Down status des button der alte(original) zustand wieder hergestellt wird.
Der Button scheint dann nicht mehr ausgeschnitten zu sein.
Die frage wäre dann wie kann ich die einmal erstellte region erhalten auch nach dem klick auf den Button.
bzw.. dem Up Status zuweisen.

Der ja von WinControls abgeleitet ist ;)
Seltsamer weise funktioniert das ja beim Beispiel von turboPASCAL
Quatsch liegt immer noch am Bitmap.
Auch wenn es jetzt wieder transparent ist wird ein Klickevent auf dem Transparenten bereich ausgeführt.
Hat mit dem Ausgeschnittenen Button nix zu tun das funktioniert nach nochmaligen testen.


PS:
Ach so das Panel auf einen Button knallen würde ja auch nicht gehn.
So einfach ist es also nicht.

gruss

FredlFesl 3. Aug 2011 22:16

AW: Region vom Bitmap erstellen...
 
Zitat:

Zitat von EWeiss (Beitrag 1114958)
Vergess es!...Quatsch...

Hmmm.. Respekt? Netiquette? Weniger ist hier mehr!

Technisch und inhaltlich ist jecoh nichts einzuwenden.

EWeiss 3. Aug 2011 22:25

AW: Region vom Bitmap erstellen...
 
Zitat:

Zitat von FredlFesl (Beitrag 1114990)
Zitat:

Zitat von EWeiss (Beitrag 1114958)
Vergess es!...Quatsch...

Hmmm.. Respekt? Netiquette? Weniger ist hier mehr!

Technisch und inhaltlich ist jecoh nichts einzuwenden.

Ja.. Hast recht.
Er konnte ja nicht wissen das ich in Nonvcl arbeite.

Obwohl es nicht böse gemeint war.

gruss


Alle Zeitangaben in WEZ +1. Es ist jetzt 15:39 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz