Deutsch
Forum

Erledigt: SubClassProc per Return verlassen?

 

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 Hilfe 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 Programmes stehen...

Ich knabbere nämlich immer noch am CUSTOMDRAW für diverse Controls...

...more data necessary...
Pascal
 
06.03.2009  
 



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

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.

Beispiel:
cls
addstring(meineListBox,sabim)//ausserhalb des WaitInput - Message erreicht eher das Nirvana statt die subClassProc
...

while 1

    waitInput

wend

end

subClassProc

    meineListBox.zeichne()

endProc


Braucht mal solch eine Message etwas länger und kann nicht sofort vom XProfan-Prozess aufgenommen werden - erreicht sie tatsächlich (aber nur unsicher und von Sys zu Sys anders je nach Performance) das waitInput und damit die SubClassproc - um zu (Owner)-Zeichnen.

Ich fürchte damit, dass solange Roland kein gestacktes ProcAddr bastelt, alle diese Probleme bestehen bleiben. Um so erfreulicher aber ists wiederum, dass imho damit nur durch das Fixen des ProcAddr-Problemes auch die gestackten UserMessages und die SubClassProc unnötig werden und es dann auch kein gefährliches Subclassing mehr gibt.

AddString in der SubClassProc aufrufen oder das ganze Programm nur in der SubClassProc ausführen hat wieder andere Nachteile, wobei das auch Sinnfrei ist solange kein Stack...

Bitmap(-Controls)s könnte man nehmen, ich glaube ich mache das so in der knobcontrol.inc.

Übrigens, dass was ich Stack nenne kann leider kein einfacher Stack sein, weil eigentlich garnichts gestackt werden kann, z.B. Adressen von Speichern welche als Rückgabewert dienten welche bei späterem Abruf (wg. Stack) sicherlich garnicht mehr vorhanden sein müssen.

Unter folgender Konstellation wäre es vielleicht Möglich, dem Problem der Runtime-Synchonisation auf die Schliche zu kommen - wobei ich davon ausgehe, dass eine Umsetzung auf XProfan einen gewissen Aufwandt bedeutet:

Thread1, welcher die Messages empfängt, darf nicht der Thread sein, der den Quellcode interpretiert und ausführt.

Somit kann Thread1 warten, bis Thread 2 an Stelle X ist (subClassProc bzw. procaddr-Bereit), Stelle X ausführen und Thread 1 nur die Rückgabe zurückliefern. Thread 1 wartet dann solange, und alle Programme welche Thread 1 eine Nachricht gesandt haben eben auch - wie es sonst ja normalerweise auch in der Windowswelt von Statten geht.

Eine Idee, selbst Thread1 bereitzustellen und die Runtime sozusagen nachzuladen in Thread2 ist gescheitert, da ich nicht meinen Thread1 mit dem (danach) Runtime-Thread2 synchonisieren konnte, weil ich keine vom XProfan-Code dafür bereitgestellten Mutexe o.Ä. auffinden konnte.
 
06.03.2009  
 




RGH
Hallo,

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

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

Jedes Fensterin Windows hat eine Fensterprozedur, die für 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 für 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 für 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 für 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 für 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 Hilfe zur jeweiligen Message zu entnehmen, etwa wenn über 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.

Gruß
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 könnte - 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 für 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.

Gruß
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 für meine Maßstäbe!) und sind seit Jahren im täglichen Dauereinsatz.


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

Nur theoretisch für 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 befindet, 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 für z.B. ENum-Apis gedacht ist - also wenn XProfan steht bzw. wartet oder sich eben im WaitInput befindet.

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 heißt 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 (natürlich) 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 für den gedachten Fall der EnumApis bzw. wenn XProfan steht. Jedenfalls könnte 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 ausgeführt werden, was natürlich, 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, natürlich sind das lediglich meine Beurteilungen die Roland (bitte!) in der Luft zerfetzt für 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 dürfte wenn es denn geregelt wäre.

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

Aufgrund der Tatsache, dass natürlich 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
Ladeanzahl140
Herunterladen
1.025 kB
Hochgeladen:10.03.2009
Ladeanzahl74
Herunterladen
 
10.03.2009  
 




Antworten


Thementitel, max. 100 Zeichen.
 

Systemprofile:

Kein Systemprofil angelegt. [anlegen]

XProfan:

 Beitrag  Schrift  Smilies  ▼ 

Bitte anmelden um einen Beitrag zu verfassen.
 

Themenoptionen

7.141 Betrachtungen

Unbenanntvor 0 min.
Sven Bader03.07.2023
H.Brill06.06.2021
Jörg Sellmeyer15.05.2018
rquindt27.08.2016
Mehr...

Themeninformationen



Admins  |  AGB  |  Anwendungen  |  Autoren  |  Chat  |  Datenschutz  |  Download  |  Eingangshalle  |  Hilfe  |  Händlerportal  |  Impressum  |  Mart  |  Schnittstellen  |  SDK  |  Services  |  Spiele  |  Suche  |  Support

Ein Projekt aller XProfaner, die es gibt!


Mein XProfan
Private Nachrichten
Eigenes Ablageforum
Themen-Merkliste
Eigene Beiträge
Eigene Themen
Zwischenablage
Abmelden
 Deutsch English Français Español Italia
Übersetzungen

Datenschutz


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