TBrush bitmap alignment - alignment

I have a TPaintBox control and have assigned the TPaintBox->Canvas->Brush->Bitmap to a prepared TBitmap with a grid pattern. The TPaintBox is client aligned inside it's parent (Form).
When I manually call TPaintBox->Invalidate() to redraw the control the brush is aligned perfectly at top,left (0,0 - left picture), but as soon I resize the window, the brush offset change to (20,7 - right picture) until I manually call TPaintBox->Invalidate() again.
I have tried to use one of the standard brush patterns such as bsBDiagonal and bsCross, but they all behave the same (different alignment between an Invalidate() call and form resize).
I tried to use the Win32 API SetBrushOrgEx() to manually set the brush alignment, but it has no effect on a window resize update. It does work perfectly well if I manually call Invalidate().
If I set a breakpoint in my onPaint handler and check what the brush origo is, it always answer (0,0) even when it is misaligned.
I use Canvas->RectFill() to fill the background.
Canvas->Brush->Style = bsBDiagonal;
Canvas->FillRect(Client);
Any ideas?

Related

Delphi Project with custom Style

I want to create a Delphi project with a custom Style, like the below image.
As you can see, the MainForm is transparent, and there are some components inside of it.
How can I create this transparent MainForm?
P.S:I want to create VCL project and i drawn this image by Photoshop.
Assuming you're using Firemonkey since you dont specify VCL or FMX.
You don't really need to create a style for this. Rather a simpler way would be to:
Set the form transparent property to True
Place a TRectangle on the form and make it align to Most left and adjust the color etc to your liking.
Place another TRectangle on your form and set the alignment to Client. You can then adjust the Opacity property for transparency, the fill property for color and then the stroke for the border.
I see a small space between the left and right in the photo. This can be done by setting a margin left value on the second TRectangle you placed.
Now this should look like you what want it to be provided you disabled the border of the form. There is 1 more thing we need to do to avoid having the controls show as transparent. We need to place a layout on the form. Not the rectangle. If you place the controls on the rectangle with opacity the controls will also be transparent. If you want the controls to have the same transparency value place it on the rectangle. Otherwise do the following:
Place a TLayout on the form. Not the rectangle.
Set the align property to Contents. This will make it overlap everything.
Set the margin left property of the layout to the width of the left rectangle you placed + the margin value of the client rectangle you placed to compensate for the little space.
Place your controls on the layout and they should show with default opacity.
One last thing to do is implement window drag. Assuming you disabled the border, your users will not be able to move the window at all since there is no border to drag. On the MouseDown event of the component you want the drag to start add the following code:
procedure TForm1.rctngl1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Single);
begin
StartWindowDrag;
end;
You should be all done now.
EDIT: I made an example after posting this answer: FMX Semi Transparent Form

How to resize a form past/outside of its parent's bounds?

This question applies to two scenarios.
(1)
The first is having a MDI Form and MDI Child, At runtime if I try to resize the Form either horizontally or vertically I cannot go past the edge of the main MDI Form, somewhere there must be a SetBounds or something similar that prevents this type of behavior as the mouse just snaps to the edge.
What I would like is to be able to resize past/outside the MDI Form bounds rect - which would then show the scrollbars on the main MDI Form (just like when you move a Child Form around).
(2)
The second is I find the scrolling within a MDI layout application a bit annoying and not very pleasing to use, so instead of using MDI I thought I could simulate it by setting a Form inside a TScrollBox, doing this I hoped would give more better fluid scrolling. But as with the first scenario placing a Form inside a ScrollBox still does not allow resizing outside the client - and doing this method does not even show the scrollbars when you move the Form around the ScrollBox.
You can try this very quickly by making a new MDI Application. Try resizing using the bottom right corner and dragging as far to to the right/bottom as you can, the Mouse stops at the main MDI client preventing outside resizing.
So how can I allow at runtime, a Form whether it be a MDI Child or parent to a TScrollBox to be resized outside the parent bounds?
Is there a simple property I need to set that I may have overlooked or does it require more work to do such as overriding the Form's messages maybe?
MDI children are not bound by their parent's size, but they are not visible outside their parent's boundaries and therefor cannot be resized outside of those bounds.
However, you can move them outside of the boundaries, so if you move your child form to the left, leaving only a part of the form visible, you can then resize that visible part upto the boundary of the parent. So there's no really a limit in size, but it's just a functional limitation that you cannot further size the form when it's size handles/borders would become hidden.
I think, rather than placing the MDI child on a scrollbox or resizing the MDI child, you could better put the contents of the child on a scrollbox and leave the child form itself as is.
Or, of course, you could revise the design so that you don't need the scrolling at all, but it's impossible to give a proper advise without knowing your form.

How to offset the position of the cursor in an edit control?

I'm building a custom edit control which consists of adding both an icon at the left and an icon button at the right, both inside the edit control. This requires shifting the starting point of the text (and cursor) to the right by X amount of pixels. This also means I need to 'Limit' how wide the text can be drawn too, to make room for the button on the right. The intention is to provide both a custom icon on the left, such as in a browser, as well as an 'X' button on the right to clear the contents of the edit control.
How to offset the Rect of where to draw the text and cursor in a TCustomEdit descendant?
If you are using more recent version of Delphi, there should already be a TButtonedEdit Control and can do your work.
If not, I think you can send a EM_SETMARGINS message to your TCustomEdit to set the left and right margin.
SendMessage(CustomEdit.Handle, EM_SETMARGINS, EC_LEFTMARGIN or EC_RIGHTMARGIN, MakeLong(LeftMargin, RightMargin));

Right use of setNeedsDisplayInRect: method for animation

I have some view controller, that uses my own view class and XIB interface, so the view initializes from coder. In that view controller, when I move the slider, it redraws rectangle, in initial state rectangle is on full screen and when I move the slider to the left, the size of rect become smaller proportionally (from full screen to 10x14 continuously with 4 pixel intervals).
The "slider did change a value" calls some method, that sets new rectangle size end sends "setNeedsDisplay" method. And if I change to "setNeedsDisplayInRect:" method, it not updates all what I need on screen, there is some artifacts. But with debugging it updates all like I want. Tried to send deferent rectangles to update, like:
redrawRect=CGRectUnion(oldRect, newRect);
[cView setNeedsDisplayInRect:redrawRect];
and some others, same story. My question is, which rectangle I need to send in "setNeedsDisplayInRect:" ?
And the second question, how can I accelerate/optimize all that story for smoother animation and less cost?
Already solved the problem 1. The "setNeedsDisplayInRect:" method uses points, and not pixels like I thought.

How can I change window border size?

I removed caption bar of my window so now it only has a border around it. I don't want to set BorderStyle to bsNone but I want to remove border. How can I do it?
let me explain more. I want to make sth like Photoshop GUI. If I set border style to bsNone, I'll lose lots of features on win7. I tried to use GraphicControls instead of Form Caption bar to move the window (by handling WMNCHitTest message). It works but double click doesn't maximize and restore the window when border style is bsNone but everything works well when it is bsResizable. I want to set BorderStyle to bsResizable but I want to remove the border like when it is bsNone
You can set the form's border to bsNone and then add a panel to the form. Set the panel's align property to alClient and adjust its border however you like. You have control over the inner and outer bevels and their widths to a 1 pixel granularity. Since Panel1 is a container, it should be easy to just drag everything onto it as though it were the form itself. In the designer, it would be nearly invisible.
If you are not familiar with it, you can drag all the controls from one container to another using the structure view (it's called the object treeview in older versions). This makes it so you don't have to redesign your form to do this. If the panel itself is a problem, you can always just send it to the back and leave all the other controls on the form. It will look exactly the same, but then the controls maintain a TForm parent instead of a TPanel parent. It's just a little extra thing to maintain in the designer.
Having said that, I also recommend considering Mason's comment about nonstandard UIs.
Setting the borderstyle to "bsSizeToolWin" isn't an option? It would be a thinner border, but it would be resizeable and it's still conform the Windows standard...
I haven't seen latest Photoshop, but I guess you need something like that: http://delphihaven.wordpress.com/2010/04/22/setting-up-a-custom-title-bar-reprise/

Resources