Italia
Foro

Erledigt: SubClassProc per Return verlassen?

 
- Page 1 -



Uwe
''Pascal''
Niemeier
Hi Leute (insbesondere Roland)!

Das Subject sagts ja schon: Kann man eine SubClassProc per Return verlassen und dabei Werte zurückgeben??
Zumindest, wenn man vorher Set(WinProc,0) einsetzt?

Die Aiuto ist da nicht sehr informativ

BTW: Wann genau müssen Set(WinProc,n) und Set(SubClassMode,n) überhaupt angewendet werden?
Von den Set-Funktionen bin ich es gewohnt, daß diese mehr oder weniger globale Einstellungen vornehmen und meist am Anfang des Programmi stehen...

Ich knabbere nämlich immer noch am CUSTOMDRAW per diverse Controls...

...more data necessary...
Pascal
 
06.03.2009  
 



 
- Page 1 -



RGH
Ciao,

ich will mal versuchen, es etwas besser als in der Aiuto zu erläutern:

Set(WinProc, N%)
(N = 0 oder 1)

Jedes Fensterin Windows hat eine Fensterprozedur, die per das Bearbeiten aller Messages zuständig ist, die an das Fenster geschickt werden. Diese wird in der Regel mitder jeweiligen Fensterklasse festgelegt. Normalerweise gibt es per die meisten Windows-Messages eine windowseigene Standardbehandlung. Diese sorgt zum Beispiel beim Drücken der Tab-Taste dafür, dass der Focus ins nächste Dialogelement geht, ohne dass man es eigens in der zugehörigen Windowsprozedur programmieren müsste. Andere Messages werden allerdings in der Fensterprozedur behandelt. Der Normalfall ist also, dass per alle Messages, die nicht in der Fensterprozedur behandelt werden, die Standardbehandlung aufgerufen wird.

Mit Subclassing wird nun die ursprüngliche Windowsprozedur durch unsere eigene Windowsprozedur ersetzt. Anstelle der per die Fensterklasse definierte Fensterprozedur wird nun unsere Prozedur aufgerufen. In der Regel verwenden wir Subclassing aber nur, um einige spezielle Messages einer Spezialbehandlung zu unterziehen und der Rest soll eigentlich so funktionieren wie gewohnt. Hier kommt Set(WinProc,...) ins Spiel: Wenn WinProc beim Verlassen der SubProc auf 1 steht, wird anschließend die ursprüngliche Windowsprozedur aufgerufen, anderenfalls eben nicht. Im Normalfall wird man WinProc dann auf 0 setzen, wenn die Message in der SubClassProc behandelt wurde, ansonsten eben auf 1.
(In einigen Fällen kann es jedoch auch Sinn machen auch bei Reaktion auf die Message trotzdem noch die Windowsprozedur per diese Message aufzurufen. Daher kann der Programmierer das mit der Set-Funktion frei bestimmen.)

Return in SubClassProc
Ja, Return kann (und muss in einigen Fällen) verwandt werden. Return bestimmt den Rückgabewert der Message. Bei den meisten Messages, die an ein Fenster geschickt werden, spielt der Rückgabewert keine Rolle, bei einigen aber eine ganz erhebliche! Das ist dann der Aiuto zur jeweiligen Message zu entnehmen, etwa wenn circa eine Message angefragt wird, ob das Fenster geschlossen werden kann. Ein Returnwert macht aber nur dann Sinn, wenn WinProc auf 0 steht, da ja andernfalls die anschließend aufgerufene Original Fensterprozedur den Rückgabewert bestimmt.

Saluto
Roland
 
Intel Duo E8400 3,0 GHz / 4 GB RAM / 1000 GB HDD - ATI Radeon HD 4770 512 MB - Windows 7 Home Premium 32Bit - XProfan X4
06.03.2009  
 




Uwe
''Pascal''
Niemeier
Hi Leute!

@ iF:


Wäre einfacher wenn man per return 0 oder 1, WinProc 0 oder 1, setzen potuto - wie es normalerweise so (fast) auch ist.


Zumindest wären entsprechende spezielle Rücksprungbefehle von der Syntax her einleuchtender gewesen...


CustomDraw/OwnerDraw mit XProfan11 per SubClassProc wird leider nicht korrekt funktionieren können, weil im seltensten Fall Anweisungen die ein Neuzeichnen auslösen, in der SubClassProc (also im WaitInput) ausgelöst werden, sondern eben ausserhalb waitInput - wo jedoch die Zeichnungsmessages verloren gehen.


Darum ja mein Vorschlag, das ProcAddr-Verhalten als SubClass-Modus einzuführen

Wobei ich - wie du weißt - nicht der Meinung bin, SubClassing per ProcAddr wäre gefährlich (bestenfalls während der Entwicklung, wenn man noch nicht genau weiß, was man tut).
Einige Programme von mir nutzen dies bis zum Exzess (selbst per meine Maßstäbe!) und sind seit Jahren im täglichen Dauereinsatz.
Mich ärgert nur, daß XProfan 11 sowas grundsätzlich eingebaut hat und ich es nicht zum Laufen kriege...

@ Roland:


Ein Returnwert macht aber nur dann Sinn, wenn WinProc auf 0 steht, da ja andernfalls die anschließend aufgerufene Original Fensterprozedur den Rückgabewert bestimmt.


So dachte ich mir das.

In meinem Fall sollte es so sein, daß eine bestimmte Rückgabe Windows veranlaßt, die Proc erneut mit modifizierten Parametern aufzurufen, was aber anscheinend nicht der Fall ist...

Alt mit ProccAddr:
window 10,10-500,500
 $H Messages.ph
 $H Windows.ph
 $H commctrl.ph
var Lv&=create(gridbox,%hwnd,Test;0;150,0,200,10,200,200)
addstring(Lv&,Test1)
addstring(Lv&,Test2)
declare LvDraw#
struct LvDraw= HwndFrom&,idFrom&,Code&,DrawStage&,Rest#(44)
dim LvDraw#,LvDraw

proc LvProc--------------------------------------------------------

    parameters wnd&,msg&,wparam&,lparam&

    if msg&=~WM_NOTIFY

        LvDraw#=lparam&

        if LvDraw#.Hwndfrom&=Lv&

            if LvDraw#.Code&=~NM_CUSTOMDRAW

                if LvDraw#.DrawStage& = ~CDDS_PREPAINT

                    print PREPAINT erkannt
                    return ~CDRF_NOTIFYITEMDRAW

                elseif LvDraw#.DrawStage& = ~CDDS_ITEMPREPAINT

                    print ITEMPREPAINT erkannt

                endif

            endif

        endif

    endif

    return ~DefWindowProc(wnd&,msg&,wparam&,lparam&)
    endproc-------------------------------------------------------------
    set(fastmode,1)
    ~SetWindowLong(%hwnd,~GWL_WNDPROC,procaddr(LvProc,4) )

    while 1

        waitinput

    endwhile


Neu mit SubClass:
window 10,10-500,500
 $H Messages.ph
 $H Windows.ph
 $H commctrl.ph
var Lv&=create(gridbox,%hwnd,Test;0;150,0,200,10,200,200)
addstring(Lv&,Test1)
addstring(Lv&,Test2)
declare LvDraw#
struct LvDraw= HwndFrom&,idFrom&,Code&,DrawStage&,Rest#(44)
dim LvDraw#,LvDraw
subclassproc--------------------------------------------------------

if %smessage=~WM_NOTIFY

    LvDraw#=&slparam

    if LvDraw#.Hwndfrom&=Lv&

        if LvDraw#.Code&=~NM_CUSTOMDRAW

            if LvDraw#.DrawStage& = ~CDDS_PREPAINT

                print PREPAINT erkannt
                set(subclassmode,1)--???
                set(winproc,0)-------???
                return ~CDRF_NOTIFYITEMDRAW

            elseif LvDraw#.DrawStage& = ~CDDS_ITEMPREPAINT

                print ITEMPREPAINT erkannt--Hier kommt nichts mehr an!

            endif

        endif

    endif

endif

endproc-------------------------------------------------------------
SubClass %hwnd,1

while 1

    waitinput

endwhile


Vielleicht sehe ich auch nur den Wald vor lauter Bäumen nicht?

SeeYou
Pascal
 
07.03.2009  
 




RGH
Uwe Pascal Niemeier
Vielleicht sehe ich auch nur den Wald vor lauter Bäumen nicht?


... ähem ... da lag tatsächlich ein Bug vor, der den Rückgabewert verhinderte ...
Das RETURN bleibt in SUBCLASSPROC wirkungslos.

Sorry!
Ich sehe schon, der nächste Bugfix kommt bestimmt. Es wird wohl bald ein XProfan 11.2 geben.

Saluto
Roland
 
Intel Duo E8400 3,0 GHz / 4 GB RAM / 1000 GB HDD - ATI Radeon HD 4770 512 MB - Windows 7 Home Premium 32Bit - XProfan X4
07.03.2009  
 




Jac
de
Lad
Wird da eventuell auch das andere hier angesprochene mit angepasst?
 
Profan² 2.6 bis XProfan 11.1+XPSE+XPIA+XPRR (und irgendwann XIDE)
Core2Duo E8500/T2250, 8192/1024 MB, Radeon HD4850/Radeon XPress 1250, Vista64/XP
07.03.2009  
 




RGH
Jac
Wird da eventuell auch das andere hier angesprochene mit angepasst?


Was genau meinst Du damit?
 
Intel Duo E8400 3,0 GHz / 4 GB RAM / 1000 GB HDD - ATI Radeon HD 4770 512 MB - Windows 7 Home Premium 32Bit - XProfan X4
07.03.2009  
 




Jac
de
Lad
Subclassing außerhalb von Waitinput und das mit ProcAddr.
 
Profan² 2.6 bis XProfan 11.1+XPSE+XPIA+XPRR (und irgendwann XIDE)
Core2Duo E8500/T2250, 8192/1024 MB, Radeon HD4850/Radeon XPress 1250, Vista64/XP
08.03.2009  
 



Uwe Pascal Niemeier
Wobei ich - wie du weißt - nicht der Meinung bin, SubClassing per ProcAddr wäre gefährlich (bestenfalls während der Entwicklung, wenn man noch nicht genau weiß, was man tut).

Einige Programme von mir nutzen dies bis zum Exzess (selbst per meine Maßstäbe!) und sind seit Jahren im täglichen Dauereinsatz.


Ok hör mal, per gefährlich halte ich es nicht gerne denn es blockiert mich ganz erheblich weshalb ich seither um Stack bettle.

Nur theoretisch per gefährlich hielt ich es Anfangs als ich versuchte mir vorzustellen wie das gelöst wurde, bzw. weil hier und da immer mal eine kleine Info kam wie es denn gelöst sei.

Leider hat sich nicht nur in einfachsten Tests herausgestellt (ich glaube wir hatten das schon handfest), dass tatsächlich bei einem Aufruf einer mit ProcAddr-bezogenen Funktion, wenn XProfan z.B. sich nicht im WaitInput è, es ganz einfach und nicht nur bei mir garnicht selten knallt.

Die Fehler kommen dann immer wie aus der Luft und sind selten nachvollziehbar bzw. beziehbar auf das ProcAddr-Problem.

Nach (dann doch jahrelangem) (hartnäckigen) nachkratzen hatte Roland - meiner Ansicht nach - das Problem auch bestätigt und verwiesen das eben eine mit ProcAddr-bezogene Funktion per z.B. ENum-Apis gedacht ist - also wenn XProfan steht bzw. wartet oder sich eben im WaitInput è.

Tatsächlich musste ich enorm viel umschreiben an Software damit eben keine unerklärlichen Abstürze mehr passieren - seither mein StackGebettel.

Auuuch wenn z.B. ein Programm das ProcAddr auf gefährliche Weise nutzt, dann è das längst nicht, dass es immer knallt. Die Sache ist imho sogar so komplex, dass man sagen kann, dass es Systeme gibt auf denen es dann ständig knallt und es Systeme gibt, bei denen es so gut wie nie Knallt.

Beide Systeme habe ich hier in Vorhaltung weshalb ich ums ver** kein ProcAddr gefährlich nutze weil mir unerklärliche Abstürze horrend viel Zeit und Nerven gekostet hatten - und wer baut schon gern auf Zuckerstäben*.

*) ausgenommmen (naturalmente) die Fraggles

Was ich nicht so dolle finde ist, dass Roland - weil gefährliches procAddr nunmal nicht immer abstürzt - nicht klar sagt, dass er von der Nutzung von ProcAddr abraten würde ausgenommen per den gedachten Fall der EnumApis bzw. wenn XProfan steht. Jedenfalls potuto ich mir dann viel Gesabbel ersparen was imho keiner (mehr) hören will; mag; muss; kann; brauch.

Um es bildlich zu machen stellt Roland imho z.B. folgendes nicht sicher:

|MARKE|Print 1+5+meineFunktion()+5+2
|MARKE|andereFunktion(solala)*primadoll

Würde die angecallte Funktion z.B. nur bei |MARKE| Ausführung erlangen, wäre das Problem deutlich schmächtiger.

Im aktuellen Fall kann die gecallte Funktion imho aber mitten im 1+5+hier oder mitten in meineFunktion(hier)+5 oder sonst mittendrin corsa werden, was naturalmente, wenn man es sich vorstellt, garnicht ungefährlich sein muss - bedenke man z.B. eine delTree-Funktion welche auf einmal ein Call verpasst bekommt woraufhin sich dann irgendwas ändert. : - /

Natürlich kann hier jede Detailinfo von der Wirklichkeit - die wohl nur Roland kennen mag - abweichen, naturalmente sind das lediglich meine Beurteilungen die Roland (bitte!) in der Luft zerfetzt per falsch deklariert.
 
09.03.2009  
 




Jac
de
Lad
Mein unqualifizierter Kommentar:

Liegt es nicht daran, dass mehrere Procs dann gleichzeitig versuchen auf gleiche Sachen, z.B. Variablen zuzugreifen? Das würde erklären, warum ich nie Probleme mit ProcAddr() hatte (SetTimer und so), weil ich das meist nur benutze, um in der Statuszeile die Uhrzeit und z.B. den Speicherverbrauch anzugeben, das kommt eben nicht mit anderen Funktionen ins Gehege.
 
Profan² 2.6 bis XProfan 11.1+XPSE+XPIA+XPRR (und irgendwann XIDE)
Core2Duo E8500/T2250, 8192/1024 MB, Radeon HD4850/Radeon XPress 1250, Vista64/XP
09.03.2009  
 



Desto weniger abgearbeitet werden muss... aber imho ist selbst ein return in Zeile 1 der Proc gefährlich.

Nachtrag: Ist wohl Wurstbrot wieviel abgearbeitet wird, Daufruf selbst ist imho eher das Problem.
 
09.03.2009  
 



Hier ein Beispiel welches bei egal welchem WhileLoop-Parameter nicht zucken potrebbe wenn es denn geregelt wäre.

Der anhängige Screenshot zeigt, dass nicht jede Zeile beschrieben wird.

Aufgrund der Tatsache, dass naturalmente 10ms vergleichbar Jahrzehnte sind, entsteht der Fehler nur relativ selten.

Dreht man den WhileLoop-Parameter etwas höher vlt. sogar bis zum Exzess, so wird die Anwendung immer Lustiger reagieren bis zu lustigen Abstürzen...

Naja, fehlt der Zeilenumbruch... liegt halt am Print ist nicht meine Einstellung.

8 kB
Hochgeladen:10.03.2009
Downloadcounter140
Download
1.025 kB
Hochgeladen:10.03.2009
Downloadcounter74
Download
 
10.03.2009  
 



 
- Page 2 -



Uwe
''Pascal''
Niemeier
Hi iF!

Wie gesagt, ich kann das so nicht bestätigen. (Und meine Programme laufen durchaus nicht nur auf meinem Rechner - falls dieser Eindruch entstanden sein sollte )

Vielleicht liegt es an der Art, wie ich diese Technik einsetze.
Hier mal ganz grob mein üblicher Programmaufbau:

Könnte mir vorstellen, daß das in Profan ganz ähnlich aussieht und ich darum damit ganz gut gefahren bin.
Aber ich denke mal, das muß nicht weiter verfolgt werden
(zumal ich von Stacks usw. nicht wirklich Ahnung habe => learning by doing)

BTW: Kann mich an einen Fall erinnern, wo ich in einer WndProc eine Standartvariable (a&) eingesetzt hatte, ohne diese lokal zu deklarieren.
Dann habe ich zwei Stunden lang versucht rauszukriegen, warum diese sch... Variable im Hauptprogramm ständig völlig unmotiviert irgendwelche Werte enthielt...

SeeYou
Pascal
 
12.03.2009  
 




Answer


Topictitle, max. 100 characters.
 

Systemprofile:

Kein Systemprofil angelegt. [anlegen]

XProfan:

 Posting  Font  Smilies  ▼ 

Bitte anmelden um einen Beitrag zu verfassen.
 

Topic-Options

7.162 Views

Untitledvor 0 min.
Sven Bader03.07.2023
H.Brill06.06.2021
Jörg Sellmeyer15.05.2018
rquindt27.08.2016
Di più...

Themeninformationen



Admins  |  AGB  |  Applications  |  Autori  |  Chat  |  Informativa sulla privacy  |  Download  |  Entrance  |  Aiuto  |  Merchantportal  |  Impronta  |  Mart  |  Interfaces  |  SDK  |  Services  |  Giochi  |  Cerca  |  Support

Ein Projekt aller XProfaner, die es gibt!


Il mio XProfan
Private Notizie
Eigenes Ablageforum
Argomenti-Merkliste
Eigene Beiträge
Eigene Argomenti
Zwischenablage
Annullare
 Deutsch English Français Español Italia
Traduzioni

Informativa sulla privacy


Wir verwenden Cookies nur als Session-Cookies wegen der technischen Notwendigkeit und bei uns gibt es keine Cookies von Drittanbietern.

Wenn du hier auf unsere Webseite klickst oder navigierst, stimmst du unserer Erfassung von Informationen in unseren Cookies auf XProfan.Net zu.

Weitere Informationen zu unseren Cookies und dazu, wie du die Kontrolle darüber behältst, findest du in unserer nachfolgenden Datenschutzerklärung.


einverstandenDatenschutzerklärung
Ich möchte keinen Cookie