AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Code-Bibliothek Library: Windows API / MS.NET Framework API Delphi OffScreenBitmap realisieren ohne VCL
Thema durchsuchen
Ansicht
Themen-Optionen

OffScreenBitmap realisieren ohne VCL

Ein Thema von Luckie · begonnen am 16. Jan 2004
Antwort Antwort
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#1

OffScreenBitmap realisieren ohne VCL

  Alt 16. Jan 2004, 07:29
Man steht immer wieder vor dem Problem, wenn man auf den Canvas des Fensters oder der Paintbox zeichnet, dass das Gezeichnete verloren geht, so bald das Fenster von Windows neugezeichnet werden muss. Hier nun eine Lösung für die nonVCL-Programmierung. Die Kommentare im Code sollten, das Vorgehen erklären. Man zeichent nicht auf den Canvas, sondern auf ein Bitmap im Speicher und kopiert das Bitmap im Speicher bei Bedarf (WM_PAINT / OnPaint) auf den Canvas. Ohne VCL ist es etwas aufwendiger aber dennoch mit relativ wenig Code realisierbar.

Startet man das Programm, wird das Fenster rot gefüllt. Zieht man mit gedrücklter rechter Maustaste ein Rechteck auf, wird selbiges weiß mit schwarzem Rand gezeichnet.

Delphi-Quellcode:
{******************************************************************************}
{                                                                              }
{                              Offscreen-Bitmap                                }
{                                                                              }
{                  Copyright (c) 2004 Michael .:Luckie:. Puff                  }
{                          [url]www.luckie-online.de[/url]                                }
{                                                                              }
{******************************************************************************}

program OffScreenBmp;

uses
  Windows, Messages;

const
  CLASSNAME = 'WndClass';
  APPNAME = 'OffScreen-Bitmap';
  WINDOWWIDTH = 500;
  WINDOWHEIGHT = 350;

var
  hdcMem: HDC;
  hBmp: THandle;
  hBmpOld: THandle;

function WndProc(hWnd: HWND; uMsg: UINT; wParam: wParam; lParam: LParam):
  lresult; stdcall;
var
  rect: TRect;
  RedBrush: HBRUSH;
  ps: TPaintStruct;
  dc: HDC;
  ptStart, ptEnd: TPoint;
begin
  Result := 0;
  case uMsg of
    WM_CREATE:
      begin
        // Create a screen compatible DC in memory
        hdcMem := CreateCompatibleDC(0);
        // Create a Bitmap compatible to the window
        hBmp := CreateCompatibleBitmap(GetDC(hWnd), WINDOWWIDTH, WINDOWHEIGHT);
        // Select Bitmap into the memory DC and saving the old one
        hBmpOld := SelectObject(hdcMem, hBmp);
        // Release the Bitmap
        DeleteObject(hBmp);

        rect.Left := 0;
        rect.Top := 0;
        rect.Right := WINDOWWIDTH;
        rect.Bottom := WINDOWHEIGHT;
        RedBrush := CreateSolidBrush(RGB(255, 0, 0));
        // paint red rectangle on the Bitmap in memory
        FillRect(hdcMem, rect, RedBrush);
        DeleteObject(RedBrush);
      end;
    WM_PAINT:
      begin
        dc := BeginPaint(hWnd, ps);
        // everytime window needs to be painted, copy the Bitmap in memory
        // onto the window
        BitBlt(dc, 0, 0, WINDOWWIDTH, WINDOWHEIGHT, hdcMem, 0, 0, SRCCOPY);
        EndPaint(hWnd, ps);
      end;
    WM_LBUTTONDOWN:
      begin
        // starting coordinates
        ptStart.X := LoWord(lParam);
        ptStart.Y := HiWord(lParam);
      end;
    WM_LBUTTONUP:
      begin
        // ending coordinates
        ptEnd.X := LoWord(lParam);
        ptEnd.Y := HiWord(lParam);
        // paint rectangle on Bitmap in memory
        Rectangle(hdcMem, ptStart.X, ptStart.Y, ptEnd.X, ptEnd.Y);
        // declare window invalide, force WM_PAINT
        InvalidateRect(hWnd, nil, False);
      end;
    WM_DESTROY:
      begin
        SelectObject(hdcMem, hBmpOld);
        DeleteObject(hdcMem);
        PostQuitMessage(0);
      end;
  else
    Result := DefWindowProc(hWnd, uMsg, wParam, lParam);
  end;
end;

var
  wc: TWndClassEx = (
    cbSize: SizeOf(TWndClassEx);
    Style: CS_HREDRAW or CS_VREDRAW;
    lpfnWndProc: @WndProc;
    cbClsExtra: 0;
    cbWndExtra: 0;
    lpszMenuName: nil;
    lpszClassName: ClassName;
    hIconSm: 0;
    );
  msg: TMsg;
begin
  wc.hInstance := hInstance;
  wc.hbrBackground := GetStockObject(WHITE_BRUSH);
  wc.hIcon := LoadIcon(0, IDI_APPLICATION);
  wc.hCursor := LoadCursor(0, IDC_ARROW);

  RegisterClassEx(wc);
  CreateWindowEx(0, ClassName, AppName, WS_OVERLAPPEDWINDOW or
    WS_VISIBLE or WS_SYSMENU or WS_MINIMIZEBOX or WS_MAXIMIZEBOX or WS_SIZEBOX,
    Integer(CW_USEDEFAULT), Integer(CW_USEDEFAULT), WINDOWWIDTH, WINDOWHEIGHT,
    0, 0, hInstance, nil);

  while true do
  begin
    if not GetMessage(msg, 0, 0, 0) then
      break;
    begin
      TranslateMessage(msg);
      DispatchMessage(msg);
    end;
  end;
  ExitCode := msg.wParam;
end.
Miniaturansicht angehängter Grafiken
offscreenbitmap.png  
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Antwort Antwort

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 07:22 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