Recent

Author Topic: More Resize Questions on TBGRAGraphicCtrl  (Read 1646 times)

SandyG

  • Jr. Member
  • **
  • Posts: 92
More Resize Questions on TBGRAGraphicCtrl
« on: June 12, 2024, 01:46:23 am »
Working on a a Gauge component  and started to try to optimize some of the redrawing. Got really far but ran into an issue where I can't find a property that will allow me to catch the Resize event property.

Resize seems to fire on any repaint of the component, not resize. Spent a while in the debugger and that's what it seems to do.

I'm trying to catch is when the component is resized either at design time or at run time.

The only way that I can find to see if the Width or Height has changed is looking at the previous saved values of Width or Height and comparing it to what it is in the Paint call. Works but sure seems like a hack to be able to invalidate a bunch of drawings that must be done. Basically I'm keeping the last state of Width and Height saved for later comparison in the Paint event to see if I need to invalidate everything.

Hope this make sense, what is the 'Right' or a 'Good' way to do this since Resize does not seem to work as needed.

This is on a component where  MyComponent <-TBGRAGraphicCtrl <-TGraphicControl this is the hierarchy  (Basically the BGRAThemedGauge)

Sandy


jamie

  • Hero Member
  • *****
  • Posts: 6734
Re: More Resize Questions on TBGRAGraphicCtrl
« Reply #1 on: June 12, 2024, 02:47:32 am »
by your description you may be suffering from flickering?

when changing a size of some child control it most likely propagates down though the stack of resizes.

Since a TGraphicControl is pure graphics sitting on top of a needed Windows Parent control, sizing the window control will also
go down through the list to ensure the child controls get fully drawn.

  You can try blocking the WM_EraseBkGnd message.


 
The only true wisdom is knowing you know nothing

SandyG

  • Jr. Member
  • **
  • Posts: 92
Re: More Resize Questions on TBGRAGraphicCtrl
« Reply #2 on: June 12, 2024, 07:32:20 am »
Not an issue of flickering more trying to know if a resize happens so I can know to reset a 'dirty' flag in each of the graphic elements that builds the component.

The component is an analog gauge, it has a border, face, scale, and a pointer. Each has a bitmap generated only when first painted or something changes.

For example if the color of the scale is changed, the scale object is marked as 'dirty" and recreated. Same for each visual component of the Gauge. Increases performance significantly only regenerating a specific part of the gauge. This works really well. 3 to 4 times speed as only really the pointer changes frequently, the rest of the gauge elements are effectively cached unless something specifically changes in any of the parts.

The problem now is design time. If the size of the component is changed, how do you catch that event to force all parts of the Gauge to be dirty so the resize happens with a regenertion of all parts?

At run time it's less of a problem  as I think I could overload Width and Height and mark everything as 'dirty'. But not while in design mode. I do need to check if I can override Width and Height and possibly the designer calls these properties, more testing needed...

Hope this makes sense.

This might be better moved to LCL section, I posted in general by mistake.

Sandy
« Last Edit: June 12, 2024, 07:38:04 am by SandyG »

jamie

  • Hero Member
  • *****
  • Posts: 6734
Re: More Resize Questions on TBGRAGraphicCtrl
« Reply #3 on: June 12, 2024, 11:29:33 pm »
Normally you insert code in your control that monitors the editing session of being in the IDE so the code does not get executed.

IN any case, if you use the WM_WindowChangingPOS message, you can inspect the new values and reset them before they get applied.

The WM_WindowChangedPos is after the fact .
The only true wisdom is knowing you know nothing

SandyG

  • Jr. Member
  • **
  • Posts: 92
Re: More Resize Questions on TBGRAGraphicCtrl
« Reply #4 on: June 13, 2024, 12:15:44 am »
Watching windows message could work, only need to do resize, but could just be fine. Odd no existing event can catch the resize properly. After the WM_WindowChangedPos happens may work work if it seen before a paint message happens, otherwise won't work. You mentioned it's after the fact which I assume may be the paint.

Will have to create a listener for the WM_WindowChangedPos, I'll guess it's as easy as pie in LCL 😉

Thanks for your help, trying to get all the code working so I can clean it all up and commit it!

Sandy

jamie

  • Hero Member
  • *****
  • Posts: 6734
Re: More Resize Questions on TBGRAGraphicCtrl
« Reply #5 on: June 13, 2024, 12:25:05 am »
There are two messages.

LM_WindowChangingPos and LM_WindowChangedPOS.

The first will report what is about to be changed but has not yet been changed, you can detour it there.

The second is when it has already happened. If You make changes there, things may repeat itself.

I use the first one where I maintain the aspect ration of an image while dragging the size of the window, it will adjust the opposite corner to keep the aspect, there is no flickering or redrawing done.

« Last Edit: June 13, 2024, 12:26:37 am by jamie »
The only true wisdom is knowing you know nothing

SandyG

  • Jr. Member
  • **
  • Posts: 92
Re: More Resize Questions on TBGRAGraphicCtrl
« Reply #6 on: June 13, 2024, 02:14:24 am »
Jamie -

Ugg, just thought about this, is this a Windows specific message? Or does Lazarus LCL abstract that? If Windows only won't work.

Sandy

jamie

  • Hero Member
  • *****
  • Posts: 6734
Re: More Resize Questions on TBGRAGraphicCtrl
« Reply #7 on: June 13, 2024, 11:50:23 pm »
It appears you may be using a Graphics control; this limits your choices.

If you haven't already, you can override the "DoSetBounds(x,y,xx,yy:integer)" so you can examine the values before it gets set
The only true wisdom is knowing you know nothing

SandyG

  • Jr. Member
  • **
  • Posts: 92
Re: More Resize Questions on TBGRAGraphicCtrl
« Reply #8 on: June 14, 2024, 12:42:55 am »
Jamie -

You hit it!!

This worked perfectly. I have the base class on up with the added DoSetBounds() override and it works like a champ. It gets called on ONLY when resized, unlike resize().

Tested in design and runtime, works like a charm.

Thanks again for all your help on this tricky issue. Onto the last bit of performance optimization which hopefully also reduces CPU and increases performance.

Sandy

jamie

  • Hero Member
  • *****
  • Posts: 6734
Re: More Resize Questions on TBGRAGraphicCtrl
« Reply #9 on: June 14, 2024, 12:49:33 am »
reduced bit count is always my goal.!
Now where's that 4 bit Cpu/...

 :D
The only true wisdom is knowing you know nothing

SandyG

  • Jr. Member
  • **
  • Posts: 92
Re: More Resize Questions on TBGRAGraphicCtrl
« Reply #10 on: June 14, 2024, 01:50:00 am »
Nice! I still have an Intel Spec Card for a 4004 processor, found it in a box of old parts at some point. I'm not quite 4004 old but close :)

Thanks again!

Sandy

 

TinyPortal © 2005-2018