Seite 2 von 3
Verfasst: 20.05.2007 22:41
von legion
Fehler einzugestehen ist eine der grössten Tugenden !
Danke !
Lg.Legion
Verfasst: 20.05.2007 23:00
von ts-soft
Du kannst SetWindowSubclass() aus PBOSL verwenden, für das Callback in
der DLL, bzw. den Source findeste im Tipps & Tricks Forum (Autor: Edel)
Einfach mal die Beispiele von PBOSL Examples ansehen.
Für die Ereignisse, die die Hauptanwendung benötigt, kannste nachrichten
verschicken mit SendMessage_(hWnd, #WM_USER + 1, 100, 100), oder so
ähnlich.
PS: echte Gadgetereignisse lassen sich auch erzeugen, wenn nötig.
Verfasst: 20.05.2007 23:24
von legion
@ts-soft
He ! Echt super ! Danke !
Den Stoff werde ich mir gleich reinziehen !
@Ligatur
Den CallBack in der Dll mit
ProcedureReturn DefWindowProc_(hwnd,msg,wParam,lParam) hab
ich bis jetzt noch nicht zum Laufen gebracht !
Oder hab ich da wo einen Denkfehler ?
Code: Alles auswählen
Procedure WndProc(hwnd,msg,wParam,lParam)
*mymsg.MSG = lParam
myRect.RECT
GetWindowRect_(*mymsg\hwnd,myRect.RECT)
Weite = myRect\right - myRect\left
Select msg
Case #WM_MOUSEMOVE
SelectObject_(TempDC,ImageID(#Image_0))
StretchBlt_(WinHDC,0,0,Weite,ImageHeight(#Image_0),TempDC,0,0,ImageWidth(#Image_0),ImageHeight(#Image_0),#SRCCOPY)
Case #WM_ERASEBKGND
SelectObject_(TempDC,ImageID(#Image_0))
StretchBlt_(WinHDC,0,0,Weite,ImageHeight(#Image_0),TempDC,0,0,ImageWidth(#Image_0),ImageHeight(#Image_0),#SRCCOPY)
Case #WM_PAINT
SelectObject_(TempDC,ImageID(#Image_0))
StretchBlt_(WinHDC,0,0,Weite,ImageHeight(#Image_0),TempDC,0,0,ImageWidth(#Image_0),ImageHeight(#Image_0),#SRCCOPY)
EndSelect
ProcedureReturn DefWindowProc_(hwnd,msg,wParam,lParam)
EndProcedure
ProcedureDLL AddToolBarStretch(WindowHandle)
WinHDC = GetDC_(WindowHandle)
TempDC = CreateCompatibleDC_(WinHDC)
SelectObject_(TempDC,ImageID(#Image_0))
StretchBlt_(WinHDC,0,0,Weite,ImageHeight(#Image_0),TempDC,0,0,ImageHeight(#Image_0),ImageWidth(#Image_0),#SRCCOPY)
SetWindowCallback(@WndProc())
EndProcedure
Verfasst: 21.05.2007 00:32
von Ligatur
Da habe ich wohl nicht genau genug gelesen. SetWindowCallback funktioniert nur, wenn das Fenster innerhalb der DLL erzeugt wird. So must du wie edel schon schrieb SetWindowCallback... mit
Code: Alles auswählen
*OldCallb = SetWindowLong_(WindowHandle, #GWL_WNDPROC, @WndProc())
ersetzen (*OldCallb muss global sein) und im Callback ProcdureReturn DefWindowProc_ ... durch
Code: Alles auswählen
ProcedureReturn CallWindowProc_(*OldCallb, hwnd, msg, wParam, lParam)
ersetzen, dann sollte es funktionieren.
Verfasst: 21.05.2007 09:54
von legion
@Ligatur
Herzlichen Dank für die Info !
Hab ich gleich mal getestet.
Das Problem dabei ist allerdings, dass durch SetWindowLong_(WindowHandle, #GWL_WNDPROC, @WndProc())
das Fenster eine neu Proceduradresse bekommt. Somit funktioniert auch im
Programm das die DLL aufruft die Ereignisschleife nicht mehr.
Die DLL sollte in jedes PB-Progi eingebunden werden können.
Wer möchte da schon auf sein gutes altes
"Repeat Until Event = #PB_Event_CloseWindow"
verzichten.
Lg. Legion
Verfasst: 21.05.2007 10:52
von Ligatur
Die PB Ereignisschleife funktioniert so natürlich nicht mehr, aber das dürfte denke ich bei der Lösung von TS Soft auch der Fall sein

da die angegebene Funktion auf dieser Technik beruhen dürfte (den Namen der Funktion nach zu urteilen.
In deinen Code mit dem Windowhook behandelst du übrigens die Devicecontexte falsch. Was WinHDC betrifft, das wird bei Aufruf der Funktion gesperrt und dann erst irgendwann wieder freigegeben wenn die DLL wieder aus den Speicher entfernt wird. Besser ist es, den Devicekontext vor jeder Befehlsfolge, die einen Devicekontext braucht, zu besorgen und gleich darauf wieder freizugeben, nachdem er nicht mehr gebraucht wird.
Beim TempDC gilt prinzipiell das gleiche, nur kommt hier noch hinzu, das du ihn mit CreateCompatibleDC selber erzeugst, ihn dann aber nur freigiebst, du musst ihn aber löschen mit DeleteDC_(HDC), und das am besten auch gleich nach benutzung, sonst hast du nachher viele Speicherleichen.
Dazu kommt noch, ruft jemand die Funktion AddToolbarStretch mehrfach auf werden jedesmal neue Devicekontexte erzeugt und der Wert der alten geht verloren, diese können dann weder freigegeben werden noch gelöscht.
Verfasst: 21.05.2007 11:13
von legion
Herzlichen Dank für die genaue Auflistung meiner Fehler!
Das mit dem Devicecontex und den Speicherleichen wusste ich nicht.
Dachte "freigeben" und die Sache hat sich.
Bin eben nur ein Amateur, der sich immer hohe Ziele steckt.

Werde die Sache berichtigen.
Die Callbacks in der DLL werd ich mal vergessen.
Der Hook funktioniert und da werd ich weiterarbeiten.
Danke !
Lg. Legion
Berichtigt:
Code: Alles auswählen
Procedure GetMsgProc(code, wParam, lParam)
*mymsg.MSG = lParam
myRect.RECT
GetWindowRect_(*mymsg\hwnd,myRect.RECT)
Weite = myRect\right - myRect\left
If *mymsg\message = #WM_MOUSEMOVE
WinHDC = GetDC_(WindowHandle) : TempDC = CreateCompatibleDC_(WinHDC)
SelectObject_(TempDC,ImageID(#Image_0))
StretchBlt_(WinHDC,0,0,Weite,ImageHeight(#Image_0),TempDC,0,0,ImageWidth(#Image_0),ImageHeight(#Image_0),#SRCCOPY)
DeleteDC_(WinHDC) : DeleteDC_(TempDC)
ElseIf *mymsg\message = #WM_ERASEBKGND
WinHDC = GetDC_(WindowHandle) : TempDC = CreateCompatibleDC_(WinHDC)
SelectObject_(TempDC,ImageID(#Image_0))
StretchBlt_(WinHDC,0,0,Weite,ImageHeight(#Image_0),TempDC,0,0,ImageWidth(#Image_0),ImageHeight(#Image_0),#SRCCOPY)
DeleteDC_(WinHDC) : DeleteDC_(TempDC)
ElseIf *mymsg\message = #WM_PAINT
WinHDC = GetDC_(WindowHandle) : TempDC = CreateCompatibleDC_(WinHDC)
SelectObject_(TempDC,ImageID(#Image_0))
StretchBlt_(WinHDC,0,0,Weite,ImageHeight(#Image_0),TempDC,0,0,ImageWidth(#Image_0),ImageHeight(#Image_0),#SRCCOPY)
DeleteDC_(WinHDC) : DeleteDC_(TempDC)
EndIf
ProcedureReturn CallNextHookEx_(@GetMsgProc(), code, wParam, lParam)
EndProcedure
ProcedureDLL AddToolBarStretch(WHandle)
WindowHandle = WHandle
WinHDC = GetDC_(WindowHandle)
TempDC = CreateCompatibleDC_(WinHDC)
SelectObject_(TempDC,ImageID(#Image_0))
StretchBlt_(WinHDC,0,0,Weite,ImageHeight(#Image_0),TempDC,0,0,ImageHeight(#Image_0),ImageWidth(#Image_0),#SRCCOPY)
SetWindowsHookEx_(#WH_GETMESSAGE ,@GetMsgProc(),0,GetWindowThreadProcessId_(WindowHandle,#False))
DeleteDC_(WinHDC)
DeleteDC_(TempDC)
EndProcedure
ProcedureDLL DetachProcess(Instance)
UnhookWindowsHookEx_(@GetMsgProc())
EndProcedure
Verfasst: 21.05.2007 18:24
von Ligatur
Das ist so noch nicht ganz richtig, DeleteDC darf man nur auf mit Create...DC selbsterstellte Devicekontexte anwenden nicht aber auf mit GetDC erhaltene, bei diesen war das ReleaseDC schon richtig.
Verfasst: 21.05.2007 19:07
von edel
Wenn man ein Callback mit SetWindowLong oder SetWindowSubclass erstellt,
laeuft alles so weiter wie bisher, nur das man eben noch die Moeglichkeit hat,
die Events selbst zu verarbeiten.
So sieht der Funktionsaufruf in pb aus :
Schaltet man nun sein eigenen dazu :
Vorausetzung fuer den eigenen Callback ist natuerlich das man die Nachricht
auch an den alten Calback weiterleitet (callwndproc oder defsubclassproc).
Muss man zwar nicht, aber dann darf man sich nicht wundern wenn die PB
schleife nicht mehr funktioniert.
Verfasst: 21.05.2007 21:19
von legion
@Ligatur
Das mit dem DeviceContext hab ich jetzt verstanden !
Danke !
@edel
Erstmal danke für deine Hilfe !
Wie man die Nachricht neuerlich an den alten Callback weiterleitet durchblicke ich leider nicht. Ich verstehe zwar was du meinst, kann es aber nicht realisieren. Über "DefSubclassproc und SetWindowSubclass konnt ich in der W32API-Referenz nichts finden. Und mit SetWindowLong bin ich bis jetzt
gescheitert.

Vielleicht könntest du mir das anhand eines kleinen Beispiels erklären.
Danke !
Lg. Legion