![]() |
AW: wndproc geht nicht
ja, ich habe die case in readkm kurz nach dem forum
in die schleife getan und es hat auch nicht funktioniert. wm_popup: ich wollte nicht so mit zwei fenstern arbeiten sondern ein fenster das ich (border,...) gestalten kann. derzeit habe ich community10.4 und möchte win 64bit programme schreiben auch wenn es akzeptabel ist wenn sie vor win10 noch laufen (32bit,16bit). ich möchte erzählen dass ich später nicht nur keydown haben will, sondern auch den letter von der tastatur, aber wenn nicht mal das ging sollte ich das warum machen? himitsu, was ist #3 und #8 bei dir da? mein debugger überspringt in readkm $100 zu $101 und von dort zu getmessage. wenn ich call readkm weglasse werden die drei vierecke gezeichnet, ansonsten nur das grosse graue. deine webseiten haben nichts gebracht. |
AW: wndproc geht nicht
Zitat:
Wenn neues Delphi, dann schmeiß die uralten Units raus und verwende die Aktuellen, denn wintypes und winproc gibt es schon seit Jahrzehnten nicht mehr. (du kannst froh sein, dass standardmäßig in Projektoptionen > Delphi-Compiler > Unit-Aliase etwas drin steht) Zitat:
Oder wenn es durch GetMessage nicht in der Schleife hinge und deine Rechtecke aus draw4 nicht öfters gelöscht/üermalt würden, als du sie neu zeichnen lässt. WM_POPUP hat nichts hat nichts direkt mit der Fenstergestaltung zu tun. Dafür gibr es andere Attribute. Es steuert wird das Fenster reagiert ... eben wie ein POPUP, also was selbstgebautes ähnlich einem PopupMenü, MainMenü oder dem DropDown einer ComboBox. Zitat:
und fände raus, dass dort die Taste ebenfalls in der Message drin steckt und wie man da dran kommt. ![]() ![]() Zitat:
Mit PostMessage rannte es immer in der schleife und dadurch wurden auch die Rechtecke "immer wieder" neu gemalt. Fällt nicht kaum auf, wenn Windows das Fenster neu malt und damit deine Rechtecke übermalt. (sie dann ganz kurz weg sind, bis zum nächsten Malen der Rechtecke) Eigentlich gehört das Malen der Rechtecke besser ins WM_PAINT (ala OnPaint bei TForm oder TPaintBox) und beim Ändern des Status, durch Taste/Maus, löst man ein Repaint aus. In aktuellen Windowsen hast du noch Grlück, dass der WindowsDesktoManager mehr zwischenspeichert ... bei älteren Windows hättest du noch mehr Probleme, weil dort noch öfters das Fenster neu gemalt würde (es deine Rechtecke übermalt). Zitat:
Für eine Suche bezüglich Delphi, da nennen wir sowas gern mal NonVCL (also "ohne die VCL" und somit ohne so Zeugs wie TForm und TPaintBox/TImage oder TShape und OnKeyDown/OnKeyPress/OnMouseMove, was man hierfür verwenden könnte) |
AW: wndproc geht nicht
sind wintypes,winprocs jetzt 16bit obwohl ich
nur 1x C:\windows habe, das 64bit ist? öfter übermalt: ich errinnere mich, das ich die reaktion früher anders gemacht habe und nur auf keydn ohne keyup zeichnete. wenn getmessage auf eingabe wartet, soll ich also doch wieder wndproc benutzen? wenn man wm_popup macht, heisst das also das ich wndproc keydn nicht mehr nutzen kann? ich habe schon verstanden, dass nach keydn man wparam braucht, wollte aber es nicht programmieren. denn da war so viel von shiftstate-read die rede und die taste liest man doch von wndproc, die nicht window-style heisst. "Wenn man mit der WinAPI (GDI) arbeiten will": willst du sagen ich kann setpixel nicht gebrauchen? mein problem sind doch keyboard und mouse. |
AW: wndproc geht nicht
Zitat:
![]() |
AW: wndproc geht nicht
Genau, das sind die Anfänge/Grundlagen, wenn man sich mit sowas beschäftigen will. (bzw. was man für die Suche im Forum, beim G oder sonstwo nutzen kann)
Nja, entweder man nutzt die passendere API (WM_CHAR vs. WM_KEYUP/DOWN) oder man nutzt APIs zum Umrechnen der Werte oder man verwendet direkt die gegebenen Werte. ScanCode (der Tastencode von der Tastatur) -> Virtual Key Code (der Key Code in den KEY-Events) -> Character (im Char-Event) ![]() Klar darf man SetPixel verwenden, genauso wie man in der VCL Canvas.Pixels nutzen kann. Aber sinnlos in Massen ist es nicht empfehlungswert, vorallem da Pixels in der VCL extrem langsam ist. Man kann ein Rechteck aber auch direkt zeichnen. Rechtangle bzw. FillRect (was "zufällig" jeweils in der WinAPI/GDI und im TCanvas gleich heißt) Wichtiger ist aber, wo/wann man zeichnet und nicht womit. (siehe nachfolgend) Klar, damals bei Delphi 2006 gab es eine schöne Demo, welche zeigte, dass man selbst extrem uralten Code, aus Zeiten von TurboPascal, immernoch kompiliert und ausgeführt bekommt. Aber gerade wenn man etwas neu scheibt, sollte man dringend die Finger von uralten Schnittstellen lassen und stattdessen gleich das Aktuelle benutzen. Für ein paar uralte Units gibt es zwar Aliase, damit man solche alte Units/Programme noch kompilieren könnte, aber diese sind mehr für alten "vorhandenen" Code als Fallback gedacht und nicht damit man sie jetzt "neu" verwendet. Malen auf ein Canvas/DeviceContext (HDC) tut man am Besten nur im Paint-Ereignis (WM_PAINT bzw. OnPaint). Selbst wenn man wo anders malt, sollte man immer eine "Wiederherstellung" im Paint-Ereignis haben, damit das nach dem Übermalen direkt neu gezeichnet wird. z.B. in einem Button-Click etwas malen, dann die Form minimieren oder die Form teilweise kurz aus dem Bildschirm rausschieben und weg ist alles, wenn man es im OnPaint nicht erneut malt. Früher reichte es sogar schon, ein anderes Fenster/Menü vor das eigene Fenster zu schieben und weg war es. (das geht heute nur zufällig, weil der DWM sich alle sichtbaren Fenster merkt, wegen der Berechnung von Transparenzen, den Vorschaubildern und Dergleichen)
Delphi-Quellcode:
Tipp: rate mal, was dieser Code macht und was du demnach mit dieser Form und deiner Maus machen kannst. :angle:
type
// OnMouseDown, OnMouseUp und OnMouseMove TForm5 = class(TForm) procedure FormMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure FormMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); private FDoPaint: Boolean; end; var Form5: TForm5; implementation {$R *.dfm} procedure TForm5.FormMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin if Button = mbLeft then FDoPaint := True; end; procedure TForm5.FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); begin if FDoPaint then Canvas.Pixels[X, Y] := clMaroon; end; procedure TForm5.FormMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin FDoPaint := False; end; |
AW: wndproc geht nicht
Hallo,
also ich würde erstmal eine ganz einfache VCL Anwendung mit einer einzelnen Form erstellen. Auf dieses würde ich eine TPaintBox platzieren. Anchors passend setzen, damit diese beim Ändern der Fenstergröße mit angepasst wird. In der Paintbox (z. B. Paintbox1 oder ein besserer Name) kann man dann nach belieben Line, Rectangle, Arc etc. zeichnen. Jeweils vorher Paintbox1.Brush.Color auf die gewünschte Farbe setzen wenn es um ausgefüllte Dinge geht und Paintbox1.Pen.Color für Linien/Ränder. Wenn du mit diesen Zeichenmethoden (Line hat übrigens nur 2 Koordinaten, die anderen beiden kommen durch MoveTo oder wie das heißt um den virtuellen Cursor zu platzieren zustande) mal ein paar Minuten rumgespielt hat, kannst du dich um das Maushandlink kümmern, die Paintbox hat dafür bestimmt events. Zum Thema Tastaturhandling: keine Ahnung ob die Paintbox ein Event dafür hat, die Form hat aber m.W. ein OnKeyPressed Event. Grüße TurboMagic |
AW: wndproc geht nicht
ich habe es geschafft, danke.
|
AW: wndproc geht nicht
Zitat:
Magst du verhindern, dass wir diesbezüglich dumm sterben? ;-) |
AW: wndproc geht nicht
Zitat:
Denn bekanntlich sterben wir alle dumm andernfalls würden wir ewig leben. |
AW: wndproc geht nicht
so ging es, vielleicht haben himitsu und ich bei weiteren gesprächen peekmessage vergessen.
wndproc braucht man schon weil regwin sie pointet.
Code:
program bspforum01chg2me2;
uses wintypes, Winprocs; Var Cls:WNDCLASSEX; dk,db,dm:ShortInt; Function wndproc(hwnd1:HWND;m,w:word;l:longint):LongInt;stdcall; Begin wndproc:=DefWindowProc(hwnd1,m,w,l); End; Function regwin:Integer; Begin cls.cbSize:=sizeof(cls); cls.style:=CS_HREDRAW Or CS_VREDRAW; cls.lpfnWndProc:=Addr(wndproc); cls.cbClsExtra:=0; cls.cbWndExtra:=0; cls.hInstance:=GetModuleHandle(nil);; {IH} cls.hIcon:=winprocs.LoadIcon(0, IDI_APPLICATION); cls.hCursor:=0; cls.hCursor:=0; cls.hbrBackground:=(14 + 1); cls.lpszMenuName:=NiL; cls.lpszClassName:='Win here'#0; cls.hIconSm:=LoadIcon(cls.hInstance, IDI_APPLICATION); regwin:=winprocs.RegisterClassEx(cls); End; Function creWin:word; Var s2,s1:pchar; wndparent:hwnd; menu:hmenu; instance:thandle; param:pointer; Begin S1:='STATIC'#0; S2:='Win here'#0; wndparent:=0; menu:=0; instance:=0; param:=NiL; creWin:=winprocs.createwindow(s2,s1,ws_popup,60,40,300,200, wndparent,menu,instance,param); End; Var hwnd1:hwnd; procedure draw4(hwnd1:hwnd;x,y,wid,hei:word;r,g,b:byte); Var DC,bp:HDC; xx,yy:LongInt; PaintStrc:wintypes.TPAINTSTRUCT; Begin DC:=winprocs.getdc(hwnd1); {device context of window} PaintStrc.hdc:=DC; PaintStrc.ferase:=false; PaintStrc.rcpaint.left:=0; PaintStrc.rcpaint.top:=0; PaintStrc.rcpaint.right:=X+wid; PaintStrc.rcpaint.bottom:=Y+hei; bp:=winprocs.BeginPaint(hwnd1,PaintStrc); for yy:=1 To hei Do For xx:=1 To wid Do Begin winprocs.SetPixel(dc,x+xx,y+yy,(((r*256)+g)*256)+b); End; winprocs.EndPaint(hwnd1,PaintStrc); releasedc(hwnd1,dc); end; var msg:tagmsg; procedure readkm; begin while PeekMessage(msg, hwnd1, 0, 0, PM_REMOVE) do begin if msg.message=$100 then dk:=+1; if msg.message=$101 then dk:=-1; if msg.message=$201 then db:=+1; if msg.message=$200 then db:=-1; if msg.message=$200 then dm:=-1*dm; if msg.message=$204 then db:=2; end; end; Begin dk:=-1;db:=-1;dm:=-1; regwin; hwnd1:=crewin; msg.hwnd:=hwnd1; showwindow(hwnd1,sw_show); updatewindow(hwnd1); draw4(hwnd1,00,00,70,30,$40,$40,$40); Repeat readkm; if dk=-1 Then draw4(hwnd1,02,02,20,20,$C0,$00,$00) else draw4(hwnd1,02,02,20,20,$80,$80,$00); if db=-1 Then draw4(hwnd1,24,02,20,20,$00,$C0,$00) else draw4(hwnd1,24,02,20,20,$00,$80,$80); if dm=-1 Then draw4(hwnd1,46,02,20,20,$00,$00,$C0) else draw4(hwnd1,46,02,20,20,$80,$00,$80); Until db=2; end. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 23:03 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz