|
Post by Walt Decker on Sept 27, 2021 10:48:27 GMT -5
Error 16r57 occurs on resize of the window by draging the border. Code and Error log follow.
EDIT: I can get around the error by eliminating the resize handler and monitoring the client size of the window using a timer event. But that is cludgy.
' OPEN "User32.dll" FOR DLL AS #USER OPEN "gdi32.dll" FOR DLL AS #GDI
OPEN "DMO" FOR WINDOW AS #DMO PRINT #DMO, "TRAPCLOSE DMO.DONE" PRINT #DMO, "RESIZEHANDLER REFRESH.WIN" Hndl = HWND(#DMO) GfxDc = FN.GetDc(Hndl)
A = FN.GradientFill(Hndl, GfxDc) A = FN.DetachDc(Hndl, GfxDc)
WAIT
'------------------------------------------------------------- '-------------------------------------------------------------
SUB DMO.DONE WinHndl$
CLOSE #USER CLOSE #GDI CLOSE #DMO END
END SUB
'------------------------------------------------------------- '-------------------------------------------------------------
SUB REFRESH.WIN WinHndl$
GfxDc = 0 Hndl = 0
Hndl = HWND(#WinHndl$) GfxDc = FN.GetDc(Hndl)
A = FN.GradientFill(Hndl, GfxDc) A = FN.DetachDc(Hndl, GfxDc) END SUB
'------------------------------------------------------------- '-------------------------------------------------------------
FUNCTION FN.GetDc(WinHndl)
GfxDc = 0 CALLDLL #USER, "GetDC", WinHndl AS ULONG, GfxDc AS ULONG
FN.GetDc = GfxDc END FUNCTION
'-------------------------------------------------------------------------- '--------------------------------------------------------------------------
FUNCTION FN.AttachObj(WinDc, ThisObject) '########################################################### ' Attaches the object to the device context ' A device context may have more than one object attached ' to it '###########################################################
OrigObj = 0 CALLDLL #GDI, "SelectObject", WinDc AS ULONG, ThisObject AS ULONG, _ OrigObj AS ULONG
FN.Attach = OrigObj END FUNCTION
'------------------------------------------------------------------------ '------------------------------------------------------------------------
FUNCTION FN.DetachDc(WinHndl, WinDc) '########################################################### ' Dereference the device context '###########################################################
RetVal = 0
CALLDLL #USER, "ReleaseDC", WinHndl AS ULONG, WinDc AS ULONG, RetVal AS LONG
END FUNCTION
'-------------------------------------------------------------------------- '--------------------------------------------------------------------------
FUNCTION FN.DetachObj(WinDc, OldObj) '########################################################### ' Replace the current object with the previous object '###########################################################
RetVal = FN.AttachObj(WinDc, OldObj)
END FUNCTION
'--------------------------------------------------------------------- '---------------------------------------------------------------------
FUNCTION FN.Pen(Pstyle, Wide, Pcolor) '########################################################### ' Creates a pen of the specied style, width and color. ' If the Pstyle parameter is not PS.SOLID and the ' Wide parmeter is greather than one, the style will ' be PS.SOLID regardless of the style specified by ' Pstyle '###########################################################
PenHndl = 0 CALLDLL #GDI, "CreatePen", Pstyle AS LONG, Wide AS LONG, _ Pcolor AS ULONG, PenHndl AS ULONG
FN.Pen = PenHndl END FUNCTION
'------------------------------------------------------------------------- '-------------------------------------------------------------------------
'-------------------------------------------------------------------- '--------------------------------------------------------------------
FUNCTION FN.GradientFill(WinHndl, WinDc)
PS.SOLID = 0
STRUCT tRect, _ X AS LONG, _ Y AS LONG, _ X1 AS LONG, _ Y1 AS LONG
Pen = 0 Red = 0 Flg = 0 RetVal = 0 OldPen = 0 GfxDc = 0 Y1 = 0 I = 0
CALLDLL #USER, "GetClientRect", WinHndl AS ULONG, tRect AS STRUCT, RetVal AS VOID Y1 = tRect.Y1.struct
FOR I = 0 TO tRect.X1.struct STEP 2 Pen = FN.Pen(PS.SOLID, 2, Red) OldPen = FN.AttachObj(WinDc, Pen)
CALLDLL #GDI, "MoveToEx", WinDc AS ULONG, I AS LONG, 0 AS LONG, _ 0 AS ULONG, RetVal AS LONG CALLDLL #GDI, "LineTo", WinDc AS ULONG, I AS LONG, Y1 AS LONG, _ RetVal AS LONG OldPen = FN.DetachObj(WinDc, OldPen)
IF Flg = 0 THEN Red = Red + 2 IF Red > 255 THEN Red = Red - 2 Flg = 1 END IF ELSE Red = Red - 2 IF Red <= 0 THEN Flg = 0 Red = Red + 2 END IF END IF NEXT I END FUNCTION '
ERROR LOG: Error log timestamp Monday 09/27/21 08:33:00 AM
Runtime error: The parameter is incorrect. ( OS error 16r57 )
Error(Exception)>>defaultAction Error(Exception)>>activateHandler: <anUndefinedObject> Error(Exception)>>handle Error(Exception)>>signal Error class(Exception class)>>signal: <'The parameter is inc...'> BasicProgram(Object)>>error: <'The parameter is inc...'> BasicProgram>>terminateRun: <anError> [] in BasicProgram>>errorHandlerBlock ExceptionHandler>>evaluateResponseBlock: <aBlockClosure> for: <anError> [] in ExceptionHandler>>handle: ProtectedFrameMarker(BlockClosure)>>setUnwind: <aBlockClosure> BlockClosure>>invisibleEnsure: <aBlockClosure> ExceptionHandler>>handle: <anError> ExceptionHandler>>findHandler: <anError> Error(Exception)>>activateHandler: <anExceptionHandler> Error(Exception)>>handle Error(Exception)>>signal Error class(Exception class)>>signal: <'The parameter is inc...'> Font(Object)>>osError: <87> Font(Object)>>osError Font>>stringWidth: <'2163798'> withDC: <anUndefinedObject> Pen(TextTool)>>stringWidthOf: <'2163798'> at: <7> [] in TextPane>>makeVisible: ProtectedFrameMarker(BlockClosure)>>setUnwind: <aBlockClosure> BlockClosure>>ensure: <aBlockClosure> BasicTextPane(Window)>>doGraphics: <aBlockClosure> BasicTextPane(TextPane)>>makeVisible: <aPoint> BasicTextPane(TextPane)>>makeSelectionVisible BasicTextPane(TextPane)>>forceSelectionOntoDisplay BasicTextPane>>pasteString: <'2163798'> BasicTextPane>>nextPutAll: <'2163798'> BasicTextWindow(TextWindow)>>nextPutAll: <'2163798'> BasicProgram>>nextPutAll: <'2163798'> [] in PrintCommand>>text: BasicDoubleParameterContextHolder>>value [] in BasicProgram>>begin ExceptionHandler>>evaluateProtectedBlock: <aBlockClosure> [] in ExceptionHandler>>activateDuring: ProtectedFrameMarker(BlockClosure)>>setUnwind: <aBlockClosure> BlockClosure>>invisibleEnsure: <aBlockClosure> ExceptionHandler>>activateDuring: <aBlockClosure> ExceptionHandler class>>handle: <anError class> with: <aBlockClosure> during: <aBlockClosure> BlockClosure>>on: <anError class> do: <aBlockClosure> BasicProgram>>begin BasicProgram>>beginIfStopped BasicProgram>>beginFunction: <'REFRESH.WIN'> BasicProgram>>breakCallbackForSubName: <'REFRESH.WIN'> arguments: <anOrderedCollection> BasicProgram>>callbackForSubName: <'REFRESH.WIN'> arguments: <anOrderedCollection> BasicProgram>>handlerName: <'REFRESH.WIN'> evaluate: <aBlockClosure> callParameters: <anOrderedCollection> BasicProgram>>submitHandlerName: <'REFRESH.WIN'> evaluate: <aBlockClosure> callParameters: <anOrderedCollection>
|
|
|
Post by Brandon Parker on Sept 27, 2021 14:55:14 GMT -5
I've just started looking at this, but the first thing I noticed is that the "GetClientRect" DLL call return type is "void," but it should actually be "long" in LB's case.
So far I have changed that, moved the definition of the tRect structure to the beginning of the program, and also added a flag to prevent any resize subroutine activations if one is currently active (just in case). It is still failing, and a quick search might point to some underlying Smalltalk bitmat thing...
My first instinct is that I do not see any calls to "DeleteObject" in your code.
{:0)
Brandon Parker
|
|
|
Post by Brandon Parker on Sept 27, 2021 15:11:47 GMT -5
It looks like my suspicions mike be correct.
I replaced the call to the user function FN.DetachObj() inside the FN.GradientFill() function call with the following and the program is no longer crashing for me.
result = DeleteObject(Pen) result = DeleteObject(OldPen)
Here is the DeleteObject() function I used...
Function DeleteObject(hObj) CallDLL #gdi32, "DeleteObject", hObj As ulong, _ DeleteObject As long End Function
Also, there is no need for this zeroing section within the FN.GradienFill() function. Since these are all within the function and none are set a Global, they are locally scoped and their initial values when instantiated are all zeros.
Pen = 0 Red = 0 Flg = 0 RetVal = 0 OldPen = 0 GfxDc = 0 Y1 = 0 I = 0
{:0)
Brandon Parker
|
|
|
Post by Walt Decker on Sept 27, 2021 15:16:28 GMT -5
In function FN.GradientFill() OldPen = FN.AttachObj(WinDc, Pen) .... .... OldPen = FN.DetachObj(WinDc, OldPen) FN.DetachObj() calls FN.AttachObj() I am careful about that. In other languages in the past I had problems with that producing errors, mostly with memory bitmaps.
Pen = 0 Red = 0 Flg = 0 RetVal = 0 OldPen = 0 GfxDc = 0 Y1 = 0 I = 0
I know that; I come from an environment that requires declaration of variables and that is my way of doing so in LB.
You are correct. I have detached the object, but not deleted it. That may be the problem. I will check it out.
|
|
|
Post by Brandon Parker on Sept 27, 2021 15:49:16 GMT -5
Yeah, but it looks like the call to FN>AttachObj() is not really needed since all it does is call FN.AttachObj() on the next loop.
{:0)
Brandon Parker
|
|
|
Post by Walt Decker on Sept 27, 2021 15:49:38 GMT -5
I am now deleting the pen; however I am getting two errors:
OSERR 16r6 Invalid handle OSERR 16rB7 Cannot create a file when that file already exists. This one is strange. There is no file creation routine in the code.
ERROR LOG:
Error log timestamp Monday 09/27/21 01:33:30 PM
Runtime error: The handle is invalid. ( OS error 16r6 )
Error(Exception)>>defaultAction Error(Exception)>>activateHandler: <anUndefinedObject> Error(Exception)>>handle Error(Exception)>>signal Error class(Exception class)>>signal: <'The handle is invali...'> Pen(Object)>>osError: <6> Pen(Object)>>osError [] in GraphicsTool>>backColor: Array(IndexedCollection)>>do: <aBlockClosure> Pen(GraphicsTool)>>backColor: <aRGBColor> Pen>>backColor: <aRGBColor> BasicApplicationWindow(ApplicationWindow)>>wmErasebkgnd: <0> with: <0> NotificationManager>>notify: <aWinMessage> NotificationManager>>notifyRecursive NotificationManager>>recursiveMessage SystemDictionary>>recursiveMessage SystemDictionary>>launch NotificationManager>>readWinQueue NotificationManager>>runEventLoop Message>>perform Message>>evaluate Process>>safelyEvaluate: <aMessage> Process>>evaluate: <aMessage>
Error log timestamp Monday 09/27/21 01:33:30 PM
Runtime error: Cannot create a file when that file already exists. ( OS error 16rB7 )
Error(Exception)>>defaultAction Error(Exception)>>activateHandler: <anUndefinedObject> Error(Exception)>>handle Error(Exception)>>signal Error class(Exception class)>>signal: <'Cannot create a file...'> MessageBox(Object)>>osError: <183> MessageBox(Object)>>osError MessageBox>>openPrivate MessageBox>>open MessageBox class>>notify: <'Warning'> withText: <'Runtime Error: The h...'> MessageBox class>>warning: <'Runtime Error: The h...'> Warning>>defaultAction Warning(Exception)>>activateHandler: <anUndefinedObject> Warning(Exception)>>handle Warning(Exception)>>signal Warning class(Exception class)>>signal: <'Runtime Error: The h...'> Process>>runTimeError: <'The handle is invali...'> resume: <1> Process class>>queueWalkback: <'The handle is invali...'> makeUserIF: <aTrue> resumable: <1> Error(Exception)>>defaultAction Error(Exception)>>activateHandler: <anUndefinedObject> Error(Exception)>>handle Error(Exception)>>signal Error class(Exception class)>>signal: <'The handle is invali...'> Pen(Object)>>osError: <6> Pen(Object)>>osError [] in GraphicsTool>>backColor: Array(IndexedCollection)>>do: <aBlockClosure> Pen(GraphicsTool)>>backColor: <aRGBColor> Pen>>backColor: <aRGBColor> BasicApplicationWindow(ApplicationWindow)>>wmErasebkgnd: <0> with: <0> NotificationManager>>notify: <aWinMessage> NotificationManager>>notifyRecursive NotificationManager>>recursiveMessage SystemDictionary>>recursiveMessage SystemDictionary>>launch NotificationManager>>readWinQueue NotificationManager>>runEventLoop Message>>perform Message>>evaluate Process>>safelyEvaluate: <aMessage> Process>>evaluate: <aMessage>
Error log timestamp Monday 09/27/21 01:33:30 PM
Runtime error: Cannot create a file when that file already exists. ( OS error 16rB7 )
Error(Exception)>>defaultAction Error(Exception)>>activateHandler: <anUndefinedObject> Error(Exception)>>handle Error(Exception)>>signal Error class(Exception class)>>signal: <'Cannot create a file...'> MessageBox(Object)>>osError: <183> MessageBox(Object)>>osError MessageBox>>openPrivate MessageBox>>open MessageBox class>>notify: <'Warning'> withText: <'Runtime Error: Canno...'> MessageBox class>>warning: <'Runtime Error: Canno...'> Warning>>defaultAction Warning(Exception)>>activateHandler: <anUndefinedObject> Warning(Exception)>>handle Warning(Exception)>>signal Warning class(Exception class)>>signal: <'Runtime Error: Canno...'> Process>>runTimeError: <'Cannot create a file...'> resume: <1> Process class>>queueWalkback: <'Cannot create a file...'> makeUserIF: <aTrue> resumable: <1> Error(Exception)>>defaultAction Error(Exception)>>activateHandler: <anUndefinedObject> Error(Exception)>>handle Error(Exception)>>signal Error class(Exception class)>>signal: <'Cannot create a file...'> MessageBox(Object)>>osError: <183> MessageBox(Object)>>osError MessageBox>>openPrivate MessageBox>>open MessageBox class>>notify: <'Warning'> withText: <'Runtime Error: The h...'> MessageBox class>>warning: <'Runtime Error: The h...'> Warning>>defaultAction Warning(Exception)>>activateHandler: <anUndefinedObject> Warning(Exception)>>handle Warning(Exception)>>signal Warning class(Exception class)>>signal: <'Runtime Error: The h...'> Process>>runTimeError: <'The handle is invali...'> resume: <1> Process class>>queueWalkback: <'The handle is invali...'> makeUserIF: <aTrue> resumable: <1> Error(Exception)>>defaultAction Error(Exception)>>activateHandler: <anUndefinedObject> Error(Exception)>>handle Error(Exception)>>signal Error class(Exception class)>>signal: <'The handle is invali...'> Pen(Object)>>osError: <6> Pen(Object)>>osError [] in GraphicsTool>>backColor: Array(IndexedCollection)>>do: <aBlockClosure> Pen(GraphicsTool)>>backColor: <aRGBColor> Pen>>backColor: <aRGBColor> BasicApplicationWindow(ApplicationWindow)>>wmErasebkgnd: <0> with: <0> NotificationManager>>notify: <aWinMessage> NotificationManager>>notifyRecursive
Error log timestamp Monday 09/27/21 01:33:30 PM
Runtime error: Cannot create a file when that file already exists. ( OS error 16rB7 )
Error(Exception)>>defaultAction Error(Exception)>>activateHandler: <anUndefinedObject> Error(Exception)>>handle Error(Exception)>>signal Error class(Exception class)>>signal: <'Cannot create a file...'> MessageBox(Object)>>osError: <183> MessageBox(Object)>>osError MessageBox>>openPrivate MessageBox>>open MessageBox class>>notify: <'Warning'> withText: <'Runtime Error: Canno...'> MessageBox class>>warning: <'Runtime Error: Canno...'> Warning>>defaultAction Warning(Exception)>>activateHandler: <anUndefinedObject> Warning(Exception)>>handle Warning(Exception)>>signal Warning class(Exception class)>>signal: <'Runtime Error: Canno...'> Process>>runTimeError: <'Cannot create a file...'> resume: <1> Process class>>queueWalkback: <'Cannot create a file...'> makeUserIF: <aTrue> resumable: <1> Error(Exception)>>defaultAction Error(Exception)>>activateHandler: <anUndefinedObject> Error(Exception)>>handle Error(Exception)>>signal Error class(Exception class)>>signal: <'Cannot create a file...'> MessageBox(Object)>>osError: <183> MessageBox(Object)>>osError MessageBox>>openPrivate MessageBox>>open MessageBox class>>notify: <'Warning'> withText: <'Runtime Error: Canno...'> MessageBox class>>warning: <'Runtime Error: Canno...'> Warning>>defaultAction Warning(Exception)>>activateHandler: <anUndefinedObject> Warning(Exception)>>handle Warning(Exception)>>signal Warning class(Exception class)>>signal: <'Runtime Error: Canno...'> Process>>runTimeError: <'Cannot create a file...'> resume: <1> Process class>>queueWalkback: <'Cannot create a file...'> makeUserIF: <aTrue> resumable: <1> Error(Exception)>>defaultAction Error(Exception)>>activateHandler: <anUndefinedObject> Error(Exception)>>handle Error(Exception)>>signal Error class(Exception class)>>signal: <'Cannot create a file...'> MessageBox(Object)>>osError: <183> MessageBox(Object)>>osError MessageBox>>openPrivate MessageBox>>open MessageBox class>>notify: <'Warning'> withText: <'Runtime Error: The h...'> MessageBox class>>warning: <'Runtime Error: The h...'> Warning>>defaultAction Warning(Exception)>>activateHandler: <anUndefinedObject> Warning(Exception)>>handle
Error log timestamp Monday 09/27/21 01:33:30 PM
Runtime error: Cannot create a file when that file already exists. ( OS error 16rB7 )
Error(Exception)>>defaultAction Error(Exception)>>activateHandler: <anUndefinedObject> Error(Exception)>>handle Error(Exception)>>signal Error class(Exception class)>>signal: <'Cannot create a file...'> MessageBox(Object)>>osError: <183> MessageBox(Object)>>osError MessageBox>>openPrivate MessageBox>>open MessageBox class>>notify: <'Warning'> withText: <'Runtime Error: Canno...'> MessageBox class>>warning: <'Runtime Error: Canno...'> Warning>>defaultAction Warning(Exception)>>activateHandler: <anUndefinedObject> Warning(Exception)>>handle Warning(Exception)>>signal Warning class(Exception class)>>signal: <'Runtime Error: Canno...'> Process>>runTimeError: <'Cannot create a file...'> resume: <1> Process class>>queueWalkback: <'Cannot create a file...'> makeUserIF: <aTrue> resumable: <1> Error(Exception)>>defaultAction Error(Exception)>>activateHandler: <anUndefinedObject> Error(Exception)>>handle Error(Exception)>>signal Error class(Exception class)>>signal: <'Cannot create a file...'> MessageBox(Object)>>osError: <183> MessageBox(Object)>>osError MessageBox>>openPrivate MessageBox>>open MessageBox class>>notify: <'Warning'> withText: <'Runtime Error: Canno...'> MessageBox class>>warning: <'Runtime Error: Canno...'> Warning>>defaultAction Warning(Exception)>>activateHandler: <anUndefinedObject> Warning(Exception)>>handle Warning(Exception)>>signal Warning class(Exception class)>>signal: <'Runtime Error: Canno...'> Process>>runTimeError: <'Cannot create a file...'> resume: <1> Process class>>queueWalkback: <'Cannot create a file...'> makeUserIF: <aTrue> resumable: <1> Error(Exception)>>defaultAction Error(Exception)>>activateHandler: <anUndefinedObject> Error(Exception)>>handle Error(Exception)>>signal Error class(Exception class)>>signal: <'Cannot create a file...'> MessageBox(Object)>>osError: <183> MessageBox(Object)>>osError MessageBox>>openPrivate MessageBox>>open MessageBox class>>notify: <'Warning'> withText: <'Runtime Error: Canno...'> MessageBox class>>warning: <'Runtime Error: Canno...'> Warning>>defaultAction Warning(Exception)>>activateHandler: <anUndefinedObject> Warning(Exception)>>handle
Error log timestamp Monday 09/27/21 01:33:30 PM
|
|
|
Post by Brandon Parker on Sept 27, 2021 15:58:32 GMT -5
This code below seems to work for me...
The following changes were made from your original code: 1. Move the tRect struct definition to the top of the code. 2. Added the two calls to the DeleteObj() function. 3. Commented out the call to the FN.DetachObj() function.
STRUCT tRect, _ X AS LONG, _ Y AS LONG, _ X1 AS LONG, _ Y1 AS LONG
OPEN "User32.dll" FOR DLL AS #USER OPEN "gdi32.dll" FOR DLL AS #GDI
OPEN "DMO" FOR WINDOW AS #DMO PRINT #DMO, "TRAPCLOSE DMO.DONE" PRINT #DMO, "RESIZEHANDLER REFRESH.WIN" Hndl = HWND(#DMO) GfxDc = FN.GetDc(Hndl)
A = FN.GradientFill(Hndl, GfxDc) A = FN.DetachDc(Hndl, GfxDc)
WAIT
'------------------------------------------------------------- '-------------------------------------------------------------
SUB DMO.DONE WinHndl$
CLOSE #USER CLOSE #GDI CLOSE #DMO END
END SUB
'------------------------------------------------------------- '-------------------------------------------------------------
SUB REFRESH.WIN WinHndl$
GfxDc = 0 Hndl = 0
Hndl = HWND(#WinHndl$) GfxDc = FN.GetDc(Hndl)
A = FN.GradientFill(Hndl, GfxDc) A = FN.DetachDc(Hndl, GfxDc) END SUB
'------------------------------------------------------------- '-------------------------------------------------------------
FUNCTION FN.GetDc(WinHndl)
GfxDc = 0 CALLDLL #USER, "GetDC", WinHndl AS ULONG, GfxDc AS ULONG
FN.GetDc = GfxDc END FUNCTION
'-------------------------------------------------------------------------- '--------------------------------------------------------------------------
FUNCTION FN.AttachObj(WinDc, ThisObject) '########################################################### ' Attaches the object to the device context ' A device context may have more than one object attached ' to it '###########################################################
OrigObj = 0 CALLDLL #GDI, "SelectObject", WinDc AS ULONG, ThisObject AS ULONG, _ OrigObj AS ULONG
FN.Attach = OrigObj END FUNCTION
'------------------------------------------------------------------------ '------------------------------------------------------------------------
FUNCTION FN.DetachDc(WinHndl, WinDc) '########################################################### ' Dereference the device context '###########################################################
RetVal = 0
CALLDLL #USER, "ReleaseDC", WinHndl AS ULONG, WinDc AS ULONG, RetVal AS LONG
END FUNCTION
'-------------------------------------------------------------------------- '--------------------------------------------------------------------------
FUNCTION FN.DetachObj(WinDc, OldObj) '########################################################### ' Replace the current object with the previous object '###########################################################
RetVal = FN.AttachObj(WinDc, OldObj)
END FUNCTION
'--------------------------------------------------------------------- '---------------------------------------------------------------------
FUNCTION FN.Pen(Pstyle, Wide, Pcolor) '########################################################### ' Creates a pen of the specied style, width and color. ' If the Pstyle parameter is not PS.SOLID and the ' Wide parmeter is greather than one, the style will ' be PS.SOLID regardless of the style specified by ' Pstyle '###########################################################
PenHndl = 0 CALLDLL #GDI, "CreatePen", Pstyle AS LONG, Wide AS LONG, _ Pcolor AS ULONG, PenHndl AS ULONG
FN.Pen = PenHndl END FUNCTION
'------------------------------------------------------------------------- '-------------------------------------------------------------------------
'-------------------------------------------------------------------- '--------------------------------------------------------------------
FUNCTION FN.GradientFill(WinHndl, WinDc)
PS.SOLID = 0
Pen = 0 Red = 0 Flg = 0 RetVal = 0 OldPen = 0 GfxDc = 0 Y1 = 0 I = 0
CALLDLL #USER, "GetClientRect", WinHndl AS ULONG, tRect AS STRUCT, RetVal AS VOID Y1 = tRect.Y1.struct
FOR I = 0 TO tRect.X1.struct STEP 2 Pen = FN.Pen(PS.SOLID, 2, Red) OldPen = FN.AttachObj(WinDc, Pen)
CALLDLL #GDI, "MoveToEx", WinDc AS ULONG, I AS LONG, 0 AS LONG, _ 0 AS ULONG, RetVal AS LONG CALLDLL #GDI, "LineTo", WinDc AS ULONG, I AS LONG, Y1 AS LONG, _ RetVal AS LONG 'OldPen = FN.DetachObj(WinDc, OldPen) result = DeleteObject(Pen) result = DeleteObject(OldPen) IF Flg = 0 THEN Red = Red + 2 IF Red > 255 THEN Red = Red - 2 Flg = 1 END IF ELSE Red = Red - 2 IF Red <= 0 THEN Flg = 0 Red = Red + 2 END IF END IF NEXT I END FUNCTION '
Function DeleteObject(hObj) CallDLL #gdi32, "DeleteObject", hObj As ulong, _ DeleteObject As long End Function
{:0)
Brandon Parker
|
|
|
Post by Walt Decker on Sept 27, 2021 16:08:35 GMT -5
Yeah, but it looks like the call to FN>AttachObj() is not really needed since all it does is call FN.AttachObj() on the next loop. Another thing to think about is whether LB is keeping track of what you are drawing. I saw some of the interim drawings get redrawn when I was testing it. If that is the case, you would want to take care of that. {:0) Brandon Parker
A. Detaching an object uses the same function as attaching. If the new object is the same type as the default object the sequence is: - Select new object and save default object
- Use new object
- Select default object
- Delete used object
B. How am I supposed to know what LB is keeping track of during a resize event? I have no control over the number of times LB calls the event handler. I am drawing directly to a the window, not to a control.
|
|
|
Post by Walt Decker on Sept 27, 2021 16:41:57 GMT -5
Well, that took care of one problem. Now it takes 4 or more clicks on the kill button to active the destroy event.
|
|
|
Post by Brandon Parker on Sept 27, 2021 21:29:49 GMT -5
Well, that took care of one problem. Now it takes 4 or more clicks on the kill button to active the destroy event. I am not certain that you will be able to overcome this issue. There is an issue with the resize handler setup internal to LB. No matter what you do, you can add a flag, or even turn off the handler when it is activated and turn it back on when it exits, the handler is fired multiple times from the LB side. It might be that there is an actual issue or it could just be that the underlying event in LB is tracking WM_SIZING instead of WM_SIZE. That would make sense because it would be pushed into the queue many, many times as the window is resizing. Then, the resize handler would be triggered for each one that LB processes internally. This would delay the closing of the window while the backlog of events is taken care of. This makes sense because I can hit the close button one time and wait; eventually, the window closes. Note that LB does this exact same thing when I run my LB ONLY gradient code for a GraphicBox. This is one reason why people lean on WMLiberty.dll and msghook.dll for event-type handling. {:0) Brandon Parker
|
|
|
Post by Brandon Parker on Sept 28, 2021 7:25:07 GMT -5
Ok, here is some updated code that helps prevent the issue with the massive amount of calls to the resize handler. Don't get me wrong, it still gets called, but it is simply not acted on. In my testing this morning, the resize handler was activated an additional 12 times on a very small resize of the window. The code below prevents any drawing activities from occurring which speeds up the processing of these 12 events tremendously and should prevent the backlog of events from building up in the queue.
Hopefully, this will help with what you are trying to achieve.
NoMainWin
Global refreshActive : refreshActive = 0 Global prevWindowWidth, prevWindowHeight
STRUCT tRect, _ X AS LONG, _ Y AS LONG, _ X1 AS LONG, _ Y1 AS LONG
OPEN "User32.dll" FOR DLL AS #USER OPEN "gdi32.dll" FOR DLL AS #GDI
OPEN "DMO" FOR WINDOW AS #DMO PRINT #DMO, "TRAPCLOSE DMO.DONE" PRINT #DMO, "RESIZEHANDLER REFRESH.WIN" Hndl = HWND(#DMO) GfxDc = FN.GetDc(Hndl)
A = FN.GradientFill(Hndl, GfxDc) A = FN.DetachDc(Hndl, GfxDc) prevWindowWidth = WindowWidth prevWindowHeight = WindowHeight WAIT
'------------------------------------------------------------- '-------------------------------------------------------------
SUB DMO.DONE WinHndl$
CLOSE #USER CLOSE #GDI CLOSE #DMO END
END SUB
'------------------------------------------------------------- '-------------------------------------------------------------
SUB REFRESH.WIN WinHndl$ If (prevWindowWidth <> WindowWidth) And (prevWindowHeight <> WindowHeight) Then If refreshActive = 1 Then #DMO "REFRESH.WIN" : Exit Sub GfxDc = 0 Hndl = 0 refreshActive = 1 prevWindowWidth = WindowWidth prevWindowHeight = WindowHeight Hndl = HWND(#WinHndl$) GfxDc = FN.GetDc(Hndl)
A = FN.GradientFill(Hndl, GfxDc) A = FN.DetachDc(Hndl, GfxDc) refreshActive = 0 #DMO "ResizeHandler REFRESH.WIN" End If
END SUB
'------------------------------------------------------------- '-------------------------------------------------------------
FUNCTION FN.GetDc(WinHndl)
GfxDc = 0 CALLDLL #USER, "GetDC", WinHndl AS ULONG, GfxDc AS ULONG
FN.GetDc = GfxDc END FUNCTION
'-------------------------------------------------------------------------- '--------------------------------------------------------------------------
FUNCTION FN.AttachObj(WinDc, ThisObject) '########################################################### ' Attaches the object to the device context ' A device context may have more than one object attached ' to it '###########################################################
OrigObj = 0 CALLDLL #GDI, "SelectObject", WinDc AS ULONG, ThisObject AS ULONG, _ OrigObj AS ULONG
FN.Attach = OrigObj END FUNCTION
'------------------------------------------------------------------------ '------------------------------------------------------------------------
FUNCTION FN.DetachDc(WinHndl, WinDc) '########################################################### ' Dereference the device context '###########################################################
RetVal = 0
CALLDLL #USER, "ReleaseDC", WinHndl AS ULONG, WinDc AS ULONG, RetVal AS LONG
END FUNCTION
'-------------------------------------------------------------------------- '--------------------------------------------------------------------------
FUNCTION FN.DetachObj(WinDc, OldObj) '########################################################### ' Replace the current object with the previous object '###########################################################
RetVal = FN.AttachObj(WinDc, OldObj)
END FUNCTION
'--------------------------------------------------------------------- '---------------------------------------------------------------------
FUNCTION FN.Pen(Pstyle, Wide, Pcolor) '########################################################### ' Creates a pen of the specied style, width and color. ' If the Pstyle parameter is not PS.SOLID and the ' Wide parmeter is greather than one, the style will ' be PS.SOLID regardless of the style specified by ' Pstyle '###########################################################
PenHndl = 0 CALLDLL #GDI, "CreatePen", Pstyle AS LONG, Wide AS LONG, _ Pcolor AS ULONG, PenHndl AS ULONG
FN.Pen = PenHndl END FUNCTION
'------------------------------------------------------------------------- '-------------------------------------------------------------------------
'-------------------------------------------------------------------- '--------------------------------------------------------------------
FUNCTION FN.GradientFill(WinHndl, WinDc)
PS.SOLID = 0
Pen = 0 Red = 0 Flg = 0 RetVal = 0 OldPen = 0 GfxDc = 0 Y1 = 0 I = 0
CALLDLL #USER, "GetClientRect", WinHndl AS ULONG, tRect AS STRUCT, RetVal AS VOID Y1 = tRect.Y1.struct
FOR I = 0 TO tRect.X1.struct STEP 2 Pen = FN.Pen(PS.SOLID, 2, Red) OldPen = FN.AttachObj(WinDc, Pen)
CALLDLL #GDI, "MoveToEx", WinDc AS ULONG, I AS LONG, 0 AS LONG, _ 0 AS ULONG, RetVal AS LONG CALLDLL #GDI, "LineTo", WinDc AS ULONG, I AS LONG, Y1 AS LONG, _ RetVal AS LONG 'OldPen = FN.DetachObj(WinDc, OldPen) result = DeleteObject(Pen) result = DeleteObject(OldPen) IF Flg = 0 THEN Red = Red + 2 IF Red > 255 THEN Red = Red - 2 Flg = 1 END IF ELSE Red = Red - 2 IF Red <= 0 THEN Flg = 0 Red = Red + 2 END IF END IF NEXT I END FUNCTION '
Function DeleteObject(hObj) CallDLL #gdi32, "DeleteObject", hObj As ulong, _ DeleteObject As long End Function
{:0)
Brandon Parker
|
|
|
Post by Walt Decker on Sept 28, 2021 15:45:01 GMT -5
Thank you Mr. Parker, for your effort. I suspected that WM_SIZING is the culprit.
I did something similar last night and this morning I found that it worked except on minimize. On minimize no sizing event occurred. The sizing event occured only on SC_RESTORE and SC_MAXIMIZE after a minimize. So I had to add code to account for that.
I am working on this for the next round in "Things You Do Not Want to Know...". I could write a DLL to handle this, but knowing how many here just "love" API and DLLs I decided against it.
Thank you for your help.
|
|