[DELPHI] Znikające Canvas

0

Witam, mam problem (pewnie dosyć prosty) ale nie wiem jak sobie z nim poradzić:
Najpierw zakładam handle na okno Form (GetWindowDC), potem rysuję sobie grafikę na belce tytułowej(przez Canvas.Draw) i wszystko fajnie, ale gdy zdeaktywuję Formę (np. wybierając jakieś inne okno), naniesiona grafika znika... Co z tym zrobić?

0

canvas ma to do siebie ze znika.
musisz powtarzac malowanie za kazdym razem gdy zostanie zamazane. w przypadku paska tytulowego trzeba obsluzyc kilka komunikatow.
poszukaj pod "delphi draw caption bar" np:
http://delphi.about.com/od/adptips2006/qt/draw_captionbar.htm
generalnie nastepnym razem szukaj w googlach, tam jest prawie wszystko:P

1

Już sobie z tym poradziłem, wrzuciłem wszystko do procedury, a potem w Form1 OnPaint i działa jak trzeba :)

Mam teraz inny kłopot... Po narysowaniu nowej belki przydały by się przyciski. Oczywiście narysować przycisk to nie problem, ale jak zrobić by potem taki przycisk był aktywnym elementem a nie tylko grafiką? (np. żeby obsługiwał MouseEnter i MouseLeave, OnClick itp.)

==EDIT==
Jednak nie do końca, teraz zobaczyłem :/ Owszem malowanie się odświeża, ale upływa mniej więcej 1s zanim to nastąpi, i jest wtedy widoczny pierwotny wygląd Formy... D tego przy minimalizacji Formy (na tle niektórych okien czy aplikacji, np. IE) zostają elementy malowania Formy, jakby odciśnięte. Znika to po odświeżeniu danego okna. Da się z tym coś zrobić?

0

To może zrób coś w stylu jak poniżej. To jest kod TScrollBoxa wzbogaconego o Canvas i własność Bitmap. I
jak coś narysujesz na bitmapie i przypiszesz ją do właności Bitmap to nawet jak ruszysz formatką czy też ją
zminimalizujesz i przywrócisz to obraz namalowany zostaje na ScrollBoxie. Po prostu należy odpowiednio to
wywołanie komunikatu WM_PAINT obslużyć. A swoją drogą nie wiem dlaczego Tobie w OnPaint to źle działa.
Mam nadzieję, że mój kod się Tobie do czegoś przyda i grafika będzie się Tobie wyświetlać jak należy. Tego
scrollBoxa użyłem w jednej aplikacji w której rysowałem własny wykres z ulepszonych ProgressBarów oraz na
pozostałym obszarze wypisując legendę, bo jakoś za cholerę - nie mogłem okiełznać TChart z Delphi 3. A co
do narysowania przycisku żeby miał zdarzenia OnMouseEnter i OnMouseLeave to widziałem kiedyś jakiś kod i
to z polskimi objaśnieniami, może nawet w tym serwisie gdzieś także pogoogluj, na pewno coś znajdziesz :)

unit canvasedscrollbox;

interface

uses
  Windows, Messages, Classes, Controls, Forms, Graphics;

type
  TCanvasedScrollBox = class(TScrollBox)
  private
    FBmp: TBitmap;
    FCanvas: TCanvas;
    procedure SetBitmap(Value: TBitmap);
  protected
    procedure WMPaint(var Message: TMessage); message WM_PAINT;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    property Bitmap: TBitmap read FBmp write SetBitmap;
    property Canvas: TCanvas read FCanvas;
  end;

implementation

constructor TCanvasedScrollBox.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  ControlStyle := [csAcceptsControls, csCaptureMouse, csClickEvents,
     csSetCaption, csDoubleClicks];
  Width := 185;
  Height := 41;
  BorderStyle := bsSingle;
  FBmp := TBitmap.Create;
  FCanvas := TControlCanvas.Create;
  TControlCanvas(FCanvas).Control := Self;
end;

destructor TCanvasedScrollBox.Destroy;
begin
  FBmp.Free;
  FCanvas.Free;
  inherited Destroy;
end;

procedure TCanvasedScrollBox.SetBitmap(Value: TBitmap);
begin
  FBmp.Assign(Value);
  SendMessage(Handle, WM_PAINT, 0, 0);
end;

procedure TCanvasedScrollBox.WMPaint(var Message: TMessage);
begin
  if Assigned(FBmp) then
    Canvas.Draw(0, 0, FBmp);
  inherited;
end;

end
0

ostatecznie mozesz w ogole pozbyc sie belki i napisac cos co bedzie ja zastepowac.

0

Misiekd - widziałem już ten pierwszy artykuł (sam znalazłem), ale nie za bardzo wiem co z tym zrobić...

Wrzucam do programu, kompiluje, odpadal... i nic się nie dzieje.

0
Crow napisał(a)

Miśked - widziałem już ten pierwszy artykuł (sam znalazłem), ale nie za bardzo wiem co z tym zrobić...

Wrzucam do programu, kompiluje, odpadal... i nic się nie dzieje.

u mnie dziala.

0

Udalo się - działa! Dzięki wielkie wam obu :)

Mam jeszcze pytanko, da się zrobić handle na przyciski belki? Wtedy nie musiał bym się bawić w rysowanie nowych i ich obsługę, po prostu przerobił bym stare...

Bo z tym robieniem własnego to za dużo dla mnie, nie jestem na tyle zaawansowany :/

Nalpiej było by gdyby ktoś doradził mi jak wrzucić (może być dynamicznie) komponent TImage na belkę... Ja bym go sobie już bez problemu przerobił na przycisk, jedyny problem - jak go tam umieścić. Da się?

0
Crow napisał(a)

Bo z tym robieniem własnego to za dużo dla mnie, nie jestem na tyle zaawansowany :/

wlasciwie to prostsze niz Ci sie wydaje, choc to zalezy od tego co chcesz dokladnie osiagnac.
na ogol wlasnorecznie rysowana belka nie zawsze współgra (chodzi mi o wyglad) z ramka (brzegami) okna. tak najprosciej to ustaw borderStyle na bsNone zeby pozbyc sie belki i brzegow okna, nastepnie mozesz dac panele wzdłuż wszystkich krawedzi okna (align na altop,left,right,bottom), na tym gornym panelu dac przyciski odpowiadajace za minimalizacje itd... a na koniec obsluzyc komunikaty, tak, zeby dalo sie okno przenosic czy rozciagac "lapiac" za odpowiednie krawedzie.
jesli nie zalezy Ci na tej ramce to mozsz sie pozbyc samej belki w ten sposob:

  private
    procedure CreateParams(VAR Params: TCreateParams); override;
 end;
{...}
procedure TForm1.CreateParams(VAR Params: TCreateParams);
begin
  Inherited CreateParams(Params);
  WITH Params DO
    Style := (Style OR WS_POPUP) AND (NOT WS_DLGFRAME);
    {or... Style := Style + WS_POPUP - WS_DLGFRAME; which is the 
     equivalent to the above statement}
 end;

generalnie rzeczy ktore Ci sie przydadza:
http://www.latiumsoftware.com/en/articles/00002.php
http://www.delphicorner.f9.co.uk/articles/forms2.htm
ogolnie szukaj w googlach pod: delphi window without title bar

0

Wiem że belka może nie pasować, ale ja rysuję całe okno (tak jakby skin dla programu, więc wszystko jest OK :P). Do tego skinu nie pasują przyciski z XP (chce zrobić własne), więc szukam na to sposobu. Wiem że mógłbym pozbyć się belki oraz ramek i narysować je w "tle", ale powstrzymuje mnie jedna rzecz - TMainMenu. Komponent ten ZAWSZE trzyma się bezpośrednio pod belką programu (nie da się inaczej), więc nie zadziała poprawnie z tym rozwiązaniem, a jest mi on bardzo potrzebny.

0

jak caly skin to moze poszukaj darmowych komponentow do tego... www.torry.net
a co do main menu, to chyba da sie przesunac ;]

0

Wiem że są komponenty, ale one mają swoje skiny, a ja zrobiłem własny :) Poza tym chce to zrobić samemu, choćby dla treningu. Z resztą to nie problem - skin mam gotowy, ładnie działa, tylko te przyciski...

1 użytkowników online, w tym zalogowanych: 0, gości: 1