Hallo.
Ich habe ein ImageGadget und natürlich ein Image darin, in dem ein Text zentriert dargestellt wird.
Nun soll das Gadget in der Grösse verändert werden und der Text auf meinem Image soll natürlich zentriert
bleiben. Also denk ich mir, ermittel ich die neue Gadgetgrösse mit GadgetWidth() und GadgetHeight(),
um das Image in der Grösse zu ändern (ResizeImage()) und zeichne dann den Text wieder zentriert drauf.
Dann ein SetGadgetState um das Gadget mit dem Image zu aktualisieren und fertig.
Das Problem dabei ist, dass das ganze zu heftig das Programm verlangsamt.
Dabei ist der schuldige nicht das ResizeImage oder ResizeGadget sondern das SetGadgetState.
Wie bekomm ich das hin, dass erst, wenn die Grössenveränderung vollzogen ist, das Setgadgetstate ausgeführt wird,
und dann auch nur einmal ...
Ich hab da irgendwie grad eine kleine Blockade...
Das Ende einer Grössenveränderung feststellen
Das Ende einer Grössenveränderung feststellen
PureBasic 6.21 (Windows x86/x64) | Windows11 Pro x64 | AsRock B850 Steel Legend Wifi | R7 9800x3D | 64GB RAM | GeForce RTX 5080 | ThermaltakeView 270 TG ARGB | build by vannicom
Re: Das Ende einer Grössenveränderung feststellen
#WM_EXITSIZEMOVE könnte helfen.
"Menschenskinder, das Niveau dieses Forums singt schon wieder!" — GronkhLP ||| "ich hogffe ihr könnt den fehle endecken" — Marvin133 ||| "Ideoten gibts ..." — computerfreak ||| "Jup, danke. Gruss" — funkheld
Re: Das Ende einer Grössenveränderung feststellen
Danke. Das wars (für eine HauptEventschleife oder WindowCallback)
Leider funktioniert das in einem "umgebogenen" CB nicht...
Da wird das Event leider nicht ausgelöst
Leider funktioniert das in einem "umgebogenen" CB nicht...
Code: Alles auswählen
Procedure TextCallBack(hWnd,uMsg,wParam,lParam)
Protected *p.text_struct = GetProp_(hwnd, "TextCB")
If uMsg = #WM_EXITSIZEMOVE
ResizeImage(*p\Image, GadgetWidth(*p\Gadget), GadgetHeight(*p\Gadget))
TextGadgetExUpdate(*p) ; <- hier wird neu gezeichnet (StartDrawing....
SetGadgetState(*p\Gadget, ImageID(*p\Image))
EndIf
ProcedureReturn CallWindowProc_(*p\OldProc,hWnd,uMsg,wParam,lParam)
EndProcedure
PureBasic 6.21 (Windows x86/x64) | Windows11 Pro x64 | AsRock B850 Steel Legend Wifi | R7 9800x3D | 64GB RAM | GeForce RTX 5080 | ThermaltakeView 270 TG ARGB | build by vannicom
Re: Das Ende einer Grössenveränderung feststellen
Achtung, Holzhammermethode!
(Zartbesaitete bitte jetzt wegschauen)
Grüße ... Kiffi
(Zartbesaitete bitte jetzt wegschauen)
Code: Alles auswählen
#MainWindow = 0
#MainWindowTimer = 0
OpenWindow(#MainWindow, #PB_Ignore, #PB_Ignore, 300, 300, "", #PB_Window_SystemMenu | #PB_Window_SizeGadget)
Repeat
WWE=WaitWindowEvent()
Select WWE
Case #PB_Event_SizeWindow
If EventWindow()=#MainWindow
If StartTimer ; Das erste Feuern des Events (nach Öffnen des Fensters) überspringen
AddWindowTimer(#MainWindow, #MainWindowTimer, 200) ; n bißchen mit dem Timeout experimentieren
EndIf
StartTimer = #True
EndIf
Case #PB_Event_Timer
If EventTimer()=#MainWindowTimer
Debug "Resize End"
RemoveWindowTimer(#MainWindow, #MainWindowTimer)
EndIf
EndSelect
Until WWE = #PB_Event_CloseWindow
a²+b²=mc²
Re: Das Ende einer Grössenveränderung feststellen
ok ... Dafür bin ich dann doch zu zartbesaitet.
Es geht ja darum, dass ich das ganze NICHT innerhalb des WindowCallbacks oder der HauptEventschleife
versuche, sondern in einer "Callback" Prozedur, die standardisiert ist. (geht um Einbau in eine Userlib)
Damit der Endnutzer sich darum nicht mehr kümmern muss...
Es geht ja darum, dass ich das ganze NICHT innerhalb des WindowCallbacks oder der HauptEventschleife
versuche, sondern in einer "Callback" Prozedur, die standardisiert ist. (geht um Einbau in eine Userlib)
Damit der Endnutzer sich darum nicht mehr kümmern muss...
PureBasic 6.21 (Windows x86/x64) | Windows11 Pro x64 | AsRock B850 Steel Legend Wifi | R7 9800x3D | 64GB RAM | GeForce RTX 5080 | ThermaltakeView 270 TG ARGB | build by vannicom
Re: Das Ende einer Grössenveränderung feststellen
Wenn die Größe des Hauptfensters vom Benutzer verändert wird, dann bekommtBisonte hat geschrieben:Es geht ja darum, dass ich das ganze NICHT innerhalb des WindowCallbacks oder der HauptEventschleife
versuche, sondern in einer "Callback" Prozedur, die standardisiert ist. (geht um Einbau in eine Userlib)
Damit der Endnutzer sich darum nicht mehr kümmern muss...
auch nur dieses Hauptfenster diese Nachricht, nicht die darauf liegenden Gadgets.
Du mußt Deinen Callback beim Hauptfenster installieren.
Eine kleine Anregung:
Code: Alles auswählen
;
; DeineLib.pbi
;
Structure myGadgetData
gadget.i
callback.i
EndStructure
Structure myGadgetCallbacks
List gadgets.myGadgetData()
EndStructure
Procedure myGadget_WindowCallback(hWnd,msg,wParam,lParam)
oldCallback = GetProp_(hWnd,"myGadget_oldCallback")
;If msg = #WM_SIZE
If msg = #WM_EXITSIZEMOVE
*s.myGadgetCallbacks = GetProp_(hWnd,"myGadget_ResizeCallbacks")
If *s
ForEach *s\gadgets()
CallFunctionFast( *s\gadgets()\callback , *s\gadgets()\gadget, hWnd )
Next
EndIf
EndIf
If oldCallback
ProcedureReturn CallWindowProc_(oldCallback,hWnd,msg,wParam,lParam)
Else
ProcedureReturn 0
EndIf
EndProcedure
Procedure drawMyGadgetPicture(gadget)
img = GetGadgetData(gadget)
w = GadgetWidth(gadget)
h = GadgetHeight(gadget)
x = w * 0.5 - ImageWidth(img) *0.5
y = h * 0.5 - ImageHeight(img)*0.5
If img And StartDrawing(CanvasOutput(gadget))
Box(0,0,w,h,GetSysColor_(#COLOR_BTNFACE))
DrawImage(ImageID(img),x,y)
StopDrawing()
EndIf
EndProcedure
Procedure myGadget_ResizeCallback(gadget, hWnd)
GetClientRect_(hWnd,@r.RECT)
ResizeGadget(gadget,GadgetX(gadget),GadgetY(gadget),r\right-20,r\bottom-20)
drawMyGadgetPicture(gadget)
EndProcedure
Procedure getCurrentGadgetWindow() ; Aktuelles Fenster ermitteln
Protected WindowID ; auf dem Gadgets angelegt werden
!extrn _PB_Gadget_Globals
!MOV eax, [_PB_Gadget_Globals]
!MOV eax, [eax]
!Mov [p.v_WindowID], eax
ProcedureReturn WindowID
EndProcedure
Procedure myGadget(gadget,x,y,w,h,img)
hWnd = getCurrentGadgetWindow()
If hWnd
result = CanvasGadget(gadget,x,y,w,h)
If gadget=#PB_Any:gadget=result:EndIf
SetGadgetData(gadget,img)
drawMyGadgetPicture(gadget)
callback = GetProp_(hWnd,"myGadgetCallback")
If Not callback ; Window Callback installieren, falls noch nicht geschehen
oldCallback = SetWindowLongPtr_(hWnd,#GWLP_WNDPROC,@myGadget_WindowCallback())
SetProp_(hWnd,"myGadget_oldCallback",oldCallback)
EndIf
*s.myGadgetCallbacks = GetProp_(hWnd,"myGadget_ResizeCallbacks")
If Not *s ; Callbackliste installieren, fall noch nicht geschehen
*s = AllocateMemory(SizeOf(myGadgetCallbacks))
If *s
InitializeStructure(*s,myGadgetCallbacks)
SetProp_(hWnd,"myGadget_ResizeCallbacks",*s)
EndIf
EndIf
If *s ; neues CallbackElement dazu
If AddElement(*s\gadgets())
*s\gadgets()\gadget = gadget
*s\gadgets()\callback = @myGadget_ResizeCallback()
EndIf
EndIf
EndIf
ProcedureReturn result
EndProcedure
;
; Ende DeineLib.pbi
;
;----------------------------------------------------------------------------------------------
;#XIncludeFile "DeineLib.pbi"
OpenWindow(0, #PB_Ignore, #PB_Ignore, 300, 300, "x", #PB_Window_SystemMenu | #PB_Window_SizeGadget)
myGadget(0,10,10,280,280,LoadImage(#PB_Any,#PB_Compiler_Home+"Examples\Sources\Data\PureBasicLogo.bmp"))
Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
cya,
...Danilo
"Ein Genie besteht zu 10% aus Inspiration und zu 90% aus Transpiration" - Max Planck
...Danilo
"Ein Genie besteht zu 10% aus Inspiration und zu 90% aus Transpiration" - Max Planck
Re: Das Ende einer Grössenveränderung feststellen
Danke.
Es hat zwar ne Weile gedauert, das zu begreifen, aber nu sitzt's.
Wobei ich anmerken muss :
Die Funktion getCurrentGadgetWindow() hat bei mir immer einen Fehler produziert (unmodifizierte Copy&Paste Aktion)
Nachdem ich verstanden hatte, was das Ding genau macht (vom Sinn her, weil bei ASM hörte es zu 64er Zeiten auf
)
hab ich das dann durch
ersetzt... unter anderem habe ich dann auch den CallFunctionFastAufruf durch einen Prototype ersetzt.
Und da du im Beispiel ein Canvas nutzt, anstelle eines ImageGadgets, kamen natürlich weitere Anpassungen
Nunja... Da stellt sich mir die Frage, ob ich nun auch noch, wie bei meinem vorherigen Versuch, einen Callback
haben kann, der nur auf das Gadget reagiert, oder ob das jetzt alles in einem "WindowCallback" landen muss,
von dem aus ich dann alles verteile...
Es hat zwar ne Weile gedauert, das zu begreifen, aber nu sitzt's.
Wobei ich anmerken muss :
Die Funktion getCurrentGadgetWindow() hat bei mir immer einen Fehler produziert (unmodifizierte Copy&Paste Aktion)
Nachdem ich verstanden hatte, was das Ding genau macht (vom Sinn her, weil bei ASM hörte es zu 64er Zeiten auf

hab ich das dann durch
Code: Alles auswählen
CompilerIf #PB_Compiler_OS = #PB_OS_Windows
Import ""
CompilerElse
ImportC ""
CompilerEndIf
PB_Object_GetThreadMemory(MemoryID)
PB_Gadget_Globals.i
EndImport
Procedure GetCurrentGadgetWindow() ; Aktuelles Fenster ermitteln
Protected *Globals = PB_Object_GetThreadMemory(PB_Gadget_Globals)
ProcedureReturn PeekI(*Globals)
EndProcedure
Und da du im Beispiel ein Canvas nutzt, anstelle eines ImageGadgets, kamen natürlich weitere Anpassungen

Nunja... Da stellt sich mir die Frage, ob ich nun auch noch, wie bei meinem vorherigen Versuch, einen Callback
haben kann, der nur auf das Gadget reagiert, oder ob das jetzt alles in einem "WindowCallback" landen muss,
von dem aus ich dann alles verteile...
PureBasic 6.21 (Windows x86/x64) | Windows11 Pro x64 | AsRock B850 Steel Legend Wifi | R7 9800x3D | 64GB RAM | GeForce RTX 5080 | ThermaltakeView 270 TG ARGB | build by vannicom