Entwickler-Ecke

Windows API - Wie kann man auf ein minimized Window zeichnen


SixpointedStarsoft - Sa 09.07.11 09:30
Titel: Wie kann man auf ein minimized Window zeichnen
Hallo Zusammen

ich möchte meine minimized Window selber zeichnen oder darauf zeichnen.


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
    WM_PAINT: begin
       if (IsIconic(FSkinedForm.Handle)) then begin
         PaintIconicSkinOfWindow;
         message.Result:= 0;
         useOld:= falsE;
       end;
    end;


bei PaintIconicSkinOfWindow steht folgendes


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:
procedure PaintIconicSkinOfWindow;
var
    DC: HDC;
    ps: TPaintStruct;
    Canvas: TCanvas;
    r: TRect;

begin
  try
     // DC:= GetDCEx(FSkinedForm.Handle, 0, DCX_WINDOW);
      DC := BeginPaint(FSkinedForm.Handle, ps);
      //SendMessage(FSkinedForm.Handle, WM_ICONERASEBKGND, DC, 0);
      Canvas := TCanvas.Create;
      Canvas.Handle := DC;
      r.Left := 0;
      r.Top := 0;
      r.Right := 40;//GetSystemMetrics(SM_CXSIZE);
      r.Bottom := 10//GetSystemMetrics(SM_CYSIZE);
      Canvas.Brush.Color:= clREd;
      Canvas.Brush.Style:= graphics.bsSolid;
      Canvas.FillRect(r);
  finally
      //ReleaseDC(FSkinedForm.Handle,DC);
      Canvas.Free;
      EndPaint(FSkinedForm.Handle, ps);
  end;
end;


diese Version zeichnet gar nichts. Wenn ich es mit GetDCEx mache kommt eine Fehlermeldung: Leinwand/Bild erlaubt kein Zeichnen.

Hat jemand eine Idee wie es gehen könnte?

liebe Grüsse
Christoph


BenBE - Sa 09.07.11 12:40

Minimiert = unsichtbar. Sprich das gezeichnete sieht eh keiner.

Oder meinst du das kleine Fenster, was man manchmal unten in der Taskleiste rumschwirren hat, was nur aus ner Titelleiste besteht?


SixpointedStarsoft - Sa 09.07.11 12:44

Ja, genau das Fenster, das nur aus Titelleiste besteht.


BenBE - Sa 09.07.11 13:12

Dann brauchst Du nicht das Client DC des Fensters, sondern das NC-Handle. Dieses bekommst Du beim Verarbeiten der WM_NCPAINT-Nachricht als Parameter übergeben.


SixpointedStarsoft - Sa 09.07.11 13:37

Leider gibt mir WM_NCPAINT kein Handle nur eine Region in die gezeichnet wird.


BenBE - Sa 09.07.11 13:47

Siehe http://msdn.microsoft.com/en-us/library/dd145212%28v=vs.85%29.aspx ... Sogar mit Code ;-)


SixpointedStarsoft - Sa 09.07.11 13:59

Ja den Eintrag habe ich gelesen und den Code benutzt:


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:
  
  TWMNCPaint = packed record
    Msg: Cardinal;
    RGN: HRGN;
    Unused: Longint;
    Result: Longint;
  end;

procedure PaintIconicSkinOfWindow(var Message: TWMNCPaint);
var
  ADC,ACachedDC: HDC;
  AMemBmp: HBitmap;
  ACanvas: TCanvas;
  R: TRect;
begin
  ADC:= GetDCEx(FSkinedForm.Handle,message.RGN ,DCX_WINDOW+DCX_INTERSECTRGN);
  ACanvas:= TCanvas.Create;
  ACachedDC := CreateCompatibleDC(ADC);
  ACanvas.Handle:= ACachedDC;

  ACanvas.Draw(0,0,FFormSkinAndShape.ImageSkin.Graphic);

  DeleteDC(ACachedDC);

  ReleaseDC(FSkinedForm.Handle, ADC);
  ACanvas.Free;
end;


Leider gibt mir die Message keine HWND mit.


SixpointedStarsoft - Sa 09.07.11 14:00

Mit dem obigen Code passiert nichts.


SixpointedStarsoft - Sa 09.07.11 18:11

So, ich habs. Hier die Lösung die bei mir funktionert:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
procedure TssFormSkinAndShapeController.PaintIconicSkinOfWindow;
var
  ACanvas: TCanvas;
begin
  ACanvas := TCanvas.Create;
  try
    ACanvas.Handle := GetWindowDC(FSkinedForm.Handle);

    with ACanvas do
    begin
      Brush.Color := clBlue;
      Font.Color:= clWhite;

      FillRect(Rect(0,0, FMinimizedWidth,FMinimizedHeight));

      TextOut(22'Hallo')
    end;
     finally
    ReleaseDC(FSkinedForm.Handle, ACanvas.Handle);
    ACanvas.Free
  end;
end;




Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
    WM_NCPAINT: if (not (csDesigning in FSkinedForm.ComponentState))then begin
        if (IsIconic(FSkinedForm.Handle)) then begin
         PaintIconicSkinOfWindow;
         Message.Result:= 0;
         useOld:= false;
       end;
    end;

    WM_NCACTIVATE: if (IsIconic(FSkinedForm.Handle)) then  begin
       useOld:= false;
       Message.Result:= 1;  // ja nicht verändern sonst gibt es ein komisches Verhalten der Form?!
    end;


Vielen Dank für die Anregungen