[Delphi] Bericht bij repaint deel van het scherm

Pagina: 1
Acties:

  • FendtVario
  • Registratie: Januari 2002
  • Laatst online: 12-05-2025

FendtVario

The leader drives Vario!

Topicstarter
Ik ben al ff op zoek in de MSDN en de Delphi help files maar ik zie geen aanknopingspunten. Ik wil een plaatje op het scherm tekenen (niet op mijn formulier). Stel dat het plaatje 20x20 pixels is en op coordinaat 100, 100 getekend wordt. Het tekenen lukt wel, maar nu doet de applicatie eronder een repaint en is mijn plaatje weg. Ik zou graag een bericht krijgen als het schermdeel (100, 100, 120, 120) een repaint kreeg. Ik dacht dat ik hiervoor een hRegion moest maken en dan een message hook. Dit komt misschien erg dicht in de buurt van een scriptrequest maar een paar hints in de juiste richting zijn erg welkom.

www.fendt.com | Nikon D7100 | PS5


Verwijderd

Klein voorbeeldje van hoe ik een logo teken op een MDIForm zonder gebruik te maken van het canvas van het form.
imLogo is TImage met daarin het logo.
Delphi:
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
procedure TfrmMain.CreateWnd;
begin
  inherited CreateWnd;
  FNewClientProc := MakeObjectInstance(ClientWndProc);
  FOldClientProc := Pointer(GetWindowLong(ClientHandle, GWL_WNDPROC ));
  SetWindowLong(ClientHandle, GWL_WNDPROC, LongInt(FNewClientProc));
end;

procedure TfrmMain.DrawCentered;
var
  CR : TRect;
  l,t,w,h : Integer;
begin
  GetWindowRect(ClientHandle, CR);
  with imLogo do begin
    // Copy the image
    l := ((CR.Right - CR.Left) - Picture.Width) div 2;
    t := ((CR.Bottom - CR.Top) - Picture.Height) div 2;
    w := Picture.Bitmap.Width;
    h := Picture.Bitmap.Height;
    try
      BitBlt(FDrawDC, l, t, w, h, imLogo.Canvas.Handle, 0, 0, SrcCopy);
    except
      on E: Exception do; // BitBlt not supported
    end;
  end;
end;

procedure TfrmMain.ClientWndProc(var mesg : TMessage);
begin
  with mesg do
    case msg of
      WM_ERASEBKGND : begin
        CallWindowProc(FOldClientProc, ClientHandle, Msg, wParam, lParam);
        FDrawDC := TWMEraseBkGnd(Mesg).DC;
        DrawCentered;
        Result := 1;
      end;
      WM_VSCROLL, WM_HSCROLL : begin
        CallWindowProc(FOldClientProc, ClientHandle, Msg, wParam, lParam);
        InvalidateRect(ClientHandle, nil, True);
      end;
    else begin
      Result := CallWindowProc(FOldClientProc, ClientHandle, Msg, wParam, lParam);
    end;
  end;
end;

  • FendtVario
  • Registratie: Januari 2002
  • Laatst online: 12-05-2025

FendtVario

The leader drives Vario!

Topicstarter
Mooi stukje je code Afterlife, maar ik teken niet boven mijn eigen formulier. Wat is doe is dit:

Delphi:
1
2
3
4
5
6
7
  Desktop := TCanvas.Create;
  try
    Desktop.Handle := GetWindowDc(0);
    Desktop.Draw(X, Y, tmpImg);
  finally
    DeskTop.Free;
  end;


Waarbij tmpImg het plaatje is en X en Y de positie. Als windows (of het programma) dat er onder zit update wil ik dat graag weten, dan kan ik (als dat nodig is) het plaatje opnieuw tekenen.

www.fendt.com | Nikon D7100 | PS5


  • LordLarry
  • Registratie: Juli 2001
  • Niet online

LordLarry

Aut disce aut discede

Dan moet je zijn WM_PAINT en WM_NCPAINT afvangen.

We adore chaos because we like to restore order - M.C. Escher


  • Robbemans
  • Registratie: November 2003
  • Laatst online: 17-07-2025
2 dingen allereerst als je dit op jouw manier zou willen doen:

Delphi:
1
2
3
4
5
6
7
8
9
  Desktop := TCanvas.Create;
  try
    Desktop.Handle := GetWindowDc(GetDesktopWindow);
    Desktop.Draw(X, Y, tmpImg);
  finally
    ReleaseDC(GetDesktopWindow, Desktop.Handle);
    Desktop.Handle := 0;
    DeskTop.Free;
  end;

[ Voor 26% gewijzigd door Robbemans op 04-05-2005 11:34 ]


  • FendtVario
  • Registratie: Januari 2002
  • Laatst online: 12-05-2025

FendtVario

The leader drives Vario!

Topicstarter
Stel dat ik WM_PAINT ga afvangen, dan moet ik ook een eventuele resize of window state change afvangen want het scherm bijvoorbeeld minimaliseren. Of een ander scherm kan vergroot, verplaatst en dan weet ik het nog niet. Ik dacht ooit eens een voorbeeld gezien te hebben van een methode om een gebied te monitoren alleen kan dat niet meer terug vinden in mijn archief hier.

www.fendt.com | Nikon D7100 | PS5


  • alienfruit
  • Registratie: Maart 2003
  • Laatst online: 07-05 11:11

alienfruit

the alien you never expected

Je krijgt gewoon een nieuwe WM_PAINT-message als de gebruiker het venster minimized en/of het venster weer zichtbaar maakt. Verder zo je nog WM_SYSCOMMAND in de gaten kunnen houden omdat dit wordt gebruikt als er acties zoals sluiten (SC_CLOSE), minimizen (SC_MINIMIZE), en maximen (SC_MAXIMIZE of SC_RESTORE) wordt uitgevoerd.

Voor het alleen updaten van bepaalde stuk van je venster kun je kijken na GetUpdateRgn, InvalidateRgn, RedrawWindow etc. Maar dat weet ik zo 1-2-3 ook niet :)
Je kan trouwens ook een ShellHook-registeren (RegisterShellHookWindow) en dan krijg je ook call als je er een gedeelte van een venster opnieuw moet worden getekend. Hmm.. dat is ShellShock ik denk dat je beter misschien een message hook kan plaatsen voor desktop venster, en alle messages afvangen.

Die listview/desktop moet natuurlijk ook opnieuw wordt getekend als je er een venster onderkomt etc.

[ Voor 31% gewijzigd door alienfruit op 04-05-2005 13:33 ]


  • FendtVario
  • Registratie: Januari 2002
  • Laatst online: 12-05-2025

FendtVario

The leader drives Vario!

Topicstarter
alienfruit schreef op woensdag 04 mei 2005 @ 13:13:..... Hmm.. dat is ShellShock ik denk dat je beter misschien een message hook kan plaatsen voor desktop venster, en alle messages afvangen.

Die listview/desktop moet natuurlijk ook opnieuw wordt getekend als je er een venster onderkomt etc.
Daar was ik al een soort van bang voor dat ik toch alle berichten moet gaan afluisteren. Zal morgen eens proberen als daar tijd voor is.

www.fendt.com | Nikon D7100 | PS5

Pagina: 1