coda
Junior Member
![*](//storage.proboards.com/forum/images/stars/star.png)
Posts: 83
|
Post by coda on Jul 1, 2024 6:56:26 GMT -5
I’m not sure if anyone is going to be able to answer this other than Carl but I’ll give it a go. Here is my question: There is a type of ‘queue’ into which LB graphics commands are placed in order that the OS can redraw them when necessary. Is that a queue that is managed by the win32API or is it a queue that is managed by LB, itself? The reason I am asking is because, sometimes it is necessary to draw your graphics by using some LB commands then some API commands then maybe some more LB commands and so on. This means that when the graphics box is redrawn, the API commands are not in the queue and thus, don’t get redrawn. My motivation, thus, for this line of enquiry is that I want to be able to push the API graphics commands I use into the queue along with the LB commands and I’m wondering if that is in some way possible which, I figure it is if the API maintains said queue and not if LB maintains it… I have come up with a solution for redrawing windows with mixed LB and API graphics if it is not possible to do but it isn’t as neat as the above would be. Any light that can be shed on this issue would be most appreciated. ![:)](//storage.proboards.com/forum/images/smiley/smiley.png)
|
|
|
Post by tsh73 on Jul 1, 2024 8:00:29 GMT -5
Since I never seen such a redrawing as in LB in other Windows programs, I suppose it is LB who maintains that queue. Just a guess.
|
|
|
Post by Rod on Jul 2, 2024 1:40:32 GMT -5
The usual solution is to getbmp draw bmp. That way the app drawing visible on screen is captured into the queue. To Finnish the job you really need to delete previous segments and flush the new complete drawing as one new segment.
|
|
coda
Junior Member
![*](//storage.proboards.com/forum/images/stars/star.png)
Posts: 83
|
Post by coda on Jul 2, 2024 4:04:37 GMT -5
That's certainly a handy trick. ![:)](//storage.proboards.com/forum/images/smiley/smiley.png) The problem with that approach though, Rod, is that if your user hangs the graphical part of the window off the screen and THEN does something to update the graphics in that region, the graphical area of the screen becomes corrupted due to the fact that the area the programmer/program is trying to capture is either a) Not drawn by the OS, b) not retrieved by the LB 'getbmp' command or c) probably both. This means that when the program window is dragged back onto the screen, the graphics will appear corrupted until the user does something else to trigger an update to the graphics. As I'm sure you know, you can use direct API calls that equate to the LB 'getbmp' command but the result is unfortunately the same because the overhanging part of the graphics area appears not to be drawn by the OS. I find that interesting because I'm not sure why the OS wouldn't just draw to the control's entire DC as usual when off-screen... but it appears not to. Perhaps the API commands just don't retrieve it. Not sure but either way, it doesn't work. My current solution to this is to use API calls to detect when the user moves the window in question (which is why we have discussed detecting window movement in this forum previously). Your info was very helpful. Thankyou. ![:)](//storage.proboards.com/forum/images/smiley/smiley.png) Instead of using the 'wait' command (which I don't personally like anyway as I find it structurally confusing), you have to structure your whole program to return to a central 'do nothing' handler which does nothing but initiate the LB timer to jump to a 'detect movement' handler and check for window movement every 1 second or so. If the handler detects movement, program flow is directed to another handler or other such code to cause a forced graphics redraw. It's easy to set this up for any number of windows in a single app and only those windows which require it due to the presence of graphicsboxes or due to being graphics windows etc. This method works great but is a little messy because a) Your window/windows to which you have assigned this requirement redraw once every second while they are being dragged, b) because you have to issue a 'timer 0' command at the start of every other handler in your program to prevent your code being exited by the timer mechanism in order to re-draw the graphics and also so that you can re-purpose the timer and c) It's hard to set up and conceptualise for beginner programmers. It works super well but it could just be slightly nicer. This is why I am trying to find a neater, simpler way.
|
|
|
Post by Walt Decker on Jul 2, 2024 13:15:00 GMT -5
The queue that LB uses is actually a meta-file. That is the reason for the FLUSH instruction. Have you thought about using sprites? The LB sprite engine uses double buffering rather than a meta-file so the graphic is automatically updated without using a meta-file.
|
|
coda
Junior Member
![*](//storage.proboards.com/forum/images/stars/star.png)
Posts: 83
|
Post by coda on Jul 2, 2024 13:36:00 GMT -5
Hi Walt. ![:)](//storage.proboards.com/forum/images/smiley/smiley.png) Sprites would be a good solution for some graphics elements but there are certain aspects of graphics for which they are not a great fit. For example, one of the problems I regularly deal with is a mixture of graphics items with an opaque background and those with a transparent background. For something like the image of a flower or spaceship or similar, if you were making a game, a sprite or sprites would be the right choice. For a mixture of filled rectangles and circles, bmp backgrounds and graphics text with both opaque and transparent backgrounds, this isn't really the way to go. Turning transparency and opacity on and off using API calls cannot be pushed into this meta-file queue so, whichever state the background mode is left in when you finish drawing your graphics is the background mode that will be used for the entirety of the redraw that occurs when windows get moved about, covered and uncovered, which leads to incorrect results being rendered to screen. Another issue that causes similar problems is when you wish to mix LB graphics elements with those drawn by a dll you have written. I'm currently doing BOTH these things... which is why I was forced to come up with the solution I have mentioned above. I was hopeful (perhaps overly so) that there was some element of the win32API I had yet to meet that Carl was interacting with to manage redraws. If this were the case, I figured I could perhaps take advantage of this too and insert my API and DLL graphics into the queue in some way.
|
|
|
Post by Walt Decker on Jul 2, 2024 14:17:38 GMT -5
I understand the problem. Other than the get/drawbmp and flush instructions, I would hesitate to mix LB and API graphics instructions. The biggest problem is that the LB instructions fail when the graphic is totally or partially obscured by another window, is off the visible screen, is minimized or is moved. This entails constantly monitoring the state of the window containing the graphic.
You have mentioned using a DLL. Have you thought about using an LB callback function in conjunction with the DLL? This would allow you to monitor the window and graphic in real time and perform operations from within the LB callback function. There are several API instructions you would want to trap and pass to the LB callback function: WM_SYSCOMMAND, WM_ENTERSIZEMOVE, WM_EXITSIZEMOVE, WM_SIZE, and perhaps WM_PAINT, WM_ERASEBKGND. With those you can do a great deal of monitoring and adjusting to circumstances.
Of course I may be way off since I have no idea of the actual code or you expertise.
|
|
|
Post by Rod on Jul 3, 2024 2:32:51 GMT -5
Can we see an example of the graphic at its most complex, with an indication which element is API and which element native?
There is an add attachment button if you are viewing this thread, but you wont see it in quick reply or recent posts.
|
|
coda
Junior Member
![*](//storage.proboards.com/forum/images/stars/star.png)
Posts: 83
|
Post by coda on Jul 3, 2024 12:30:55 GMT -5
Where API is concerned, I don't have a choice as I NEED to mix transparent mode and opaque mode text graphics. Where DLLs are concerned, I don't have a choice as I have had to write one for reasons of speed.
No for two reasons. 1. I am hazy on how to employ callback functions and 2. Because it was my understanding that although LB can use callbacks, they choke the system up which is why someone developed a dll to filter system messages on LB's behalf.
I only need to trap window movement as my windows are of the non-resizable type.
No, you are not way off. This might be what I need. My expertise is around the level of 'I've been programming for decades. I understand a reasonable number of aspects of the win32API but have some ways to go. I am very comfortable with making API calls in LB and other languages. I can write dlls and call them from LB. I'm not there yet with callbacks.' I don't know if what I've just said helps.
Question: Would using callbacks be an improvement on how I'm currently handling the problem?
Totally appreciate why you want this but it comes from a program that has nearly 20,000 lines of code and growing. It's a large project I'm hoping to market. I can probably create a very small example file that demonstrates what I am trying to achieve and another that shows the current way I am handing the problem but this will have to wait as I am travelling interstate tomorrow and will have no wifi and limited internet access again... so we might have to pause this conversation until I can do that.
|
|
|
Post by Walt Decker on Jul 4, 2024 13:42:32 GMT -5
Yes you do. GDI32 and GDI+ have a wealth of functions that work much faster than LB; however, due to the meta-file character of LB the graphic does not "stick" when obscured by another window or when minimized and then restored. They do "stick" when the window is moved. Therefore, all you really need is LB's FLUSH and DELSEGMENT statements when rendering is complete.
Your dll does not have to do the rendering, all it has to do is determine whether the window is visible or not and update the graphic when required. This is done by bliting the memory bitmap to the screen. You render all graphics to the memory bitmap then display the memory bitmap in the graphic.
In this case you are actually subclassing the window, not the control. The LB CALLBACK function would look something like this:
CALLBACK CbAddr, WinSubclass(LONG, LONG, LONG, LONG), LONG
The LB callback would look something like this:
FUNCTION WinSubclass(WinHndl, Command, wParm, lParam)
SELECT CASE Command CASE WM.ENTERSIZEMOVE Moving = 1 'where Moving is a global EXIT FUNCTION
CASE WM.EXITSIZEMOVE Moving = 0 CALL RefreshGfx EXIT FUNCTION
CASE WM.SYSCOMMAND SELECT CASE wParam IF wParm = WM.MINIMIZE THEN Mini = 1 EXIT FUNCTION END IF
IF wParm = WM.MAXIMIZE THEN Mini = 0 CALL RestoreGfx EXIT FUNCTION END IF
IF wParm = WM.RESTORE THEN Mini = 0 CALL RestoreGfx EXIT FUNCTION END IF END SELECT END SELECT
LBCALLBACK = 0 END FUNCTION
To activate the dll: CALLDLL YourDll, CbAddr, RetVal
Because you are trapping specific win instructions there is practically no time hit.
With this method you can not use a timer because the callback is not re-entrant; however, you can use API function SLEEP().
I have had no problems with the method even with writing a text editor which requires a great many more traps.
I do not know. I have no knowledge of the purpose, other than displaying graphics, or user layout/interface. You mentioned that the user could do something to change the graphic, therefore I assume that the user has the ability to draw several graphic primitives and perhaps text. Those operations can be done with API functions within the LB application, they do not have to be in a dll and just as fast or faster than LB functions.
|
|
|
Post by Rod on Jul 4, 2024 14:37:50 GMT -5
Well opaque text v transparent text is just about drawing a background to the text or not. Can’t help feel we are overcomplicating the whole drawing process but as I say, can we see the graphic.
|
|
|
Post by Walt Decker on Jul 4, 2024 15:14:07 GMT -5
The way I read the question is that the background is not one color therefore a transparent text background is necessary therefore API code is required.
|
|
|
Post by Rod on Jul 5, 2024 2:06:20 GMT -5
I don’t argue the point about API I argue that drawing opaque text with transparent text is simply a case of drawing the background, so there is no mix needed just draw transparent text over whatever background you require. With the blitter it can all be done in microseconds. A screen shot would be helpful.
|
|