Previews in delphi? - delphi

I am creating a project in Delphi and was wondering if it was is possible to create a preview of a tab. My idea is for a person to hover over the panel that takes you to the page and then it shows a preview in the hint, like when you hover over an icon in your task bar. if this is possible, would it also be possible to display the page instead of the panel as a preview and then click on it to go there? By this I mean almost like an image of the page, but my problem is that I don't want it to be a static screenshot of the page, I want it to be able to show the page as it is, with any changes made. The same applies to the hint(I.E Not a static image).
Any help, and explanations, would be greatly appreciated.

To get the current view of a TTabSheet, you should use a function much like this one:
procedure TForm81.CopySheet(TAB: TTabSheet);
var
bmp : TBitMap;
begin
bmp:=TBitMap.Create;
try
bmp.PixelFormat:=TPixelFormat.pf24bit;
bmp.Width:=TAB.Width; bmp.Height:=TAB.Height;
TAB.PaintTo(BMP.Canvas,0,0);
// Do what you need to with the bmp, ie. show it in a hint, a preview window, etc.
finally
bmp.Free
end
end;
The essential method is the "PaintTo" on the TAB (and most other TControls), which draws itself onto a TCanvas (f.ex. of a TBitmap, like above).
I'll leave it up to you to fill out the "Do what you need to with the bmp, ie. show it in a hint, a preview window, etc." part :-)

Related

Delphi - Changing active page's tab color and having it reset after clicking on another tab

So in the program I'm writing, I'm using a TPageControl component with multiple tab sheets. I want to change the color of the tab of the sheet that is currently the active page on the PageControl and then have the color be reset after clicking on another page (then that tab will change due to it being the active page and so on...), to make navigating the page control a bit easier. But I'm not sure how to do it? I did try using the OnChange procedure of the page control and some code like this (I know it's horribly wrong but I ran out of ideas and google searches. It didn't work anyway.):
with pgcTabs.ActivePage do
begin
brush.color:=clBlue;
font.color:=clWhite;
end;
Thanks in advance for the help!
Kind Regards
PrimeBeat
You can't. Apart from using TTabSheet.Highlighted you have no control over how the tabs are displayed.
Or you have to fully draw it yourself, as usual as for most other controls: set TPageControl.OwnerDraw to true, then use the OnDrawTab event to paint whatever you want to. It should be identical to TTabControl.OnDrawTab (see answer). The drawbacks (pun intended) of painting everything yourself is usually all the extra work to do: checking dimensions, interpreting accelerator keys, respecting system colors and settings (i.e. LTR)...
In my opinion "just adding a color" has little to no value compared to how the control by default paints already with all its advantages and features. Consider color blindness: those people might rather have problems.

how to get image from TWebBrowser into a TImage

I have a panel at the top of a form with a smallish TMemo set up as a drop target for URLs. Below that I have a Page Control with 2 tabs. I set up a TWebBrowser in one tab and some other stuff in the second tab. In the TWebBrowser, I need to login to a bug ticketing site we have, then browse tickets. Certain tickets have links to small images that clients want us to use (think something like logos). I can left-click on them and then drag-n-drop the link from the TWebBrowser to the TMemo at the top of the form. That picks up the image's URL and Title as expected.
The associated OnDrop event also switches to the 2nd tab and where I click a "Process" button. That causes the browser to navigate to the image (via Navigate2), which it loads into the browser window. That image is all that's in the browser window at this point.
So now I need the code to grab the image and load it into a TImage on the 2nd tabsheet. FWIW, the original image is a PNG.
I'm able to get the height and width of the image from the target image, but I'm not getting the image itself to show up in the TImage most of the time. Sometimes, but mostly not. I can load PNGs into these image objects just fine, so I know it displays PNGs properly.
(Maybe there's a way to do a download the image directly, but I wasn't able to get that to work. The TWebBrowser is used to login to an internal bug ticketing system where the images are being provided, and I can access that site only if it's on the same form and I've logged in. Otherwise the DL loads an HTML login page instead of the image. If there's a way to do that in the current framework, I'm open to suggestions.)
I'm finding the image file on the web page using IHTMLElement2.getelementsByTagName('img') and grabbing the first one (since I know that's all there is on the web page).
img := getFirstImage;
Image1_frame.Height := img.height+2;
Image1_frame.Width := img.width+2;
rnd := img as IHTMLElementRender ;
rnd.DrawToDC(Image1.Canvas.Handle);
Image1 is aligned to Client on a panel named Image1_frame. So I set the frame's H & W -- they get set ok.
But the image is usually not visible. It's just white.
I see that DrawToDC is deprecated, but I haven't found what to replace it with.
You can use this approach to auto login (if needed) :
Automated Log In (webBrowser)
Then you can use this to get the Image: Image from TWebBrowser to TPicture

Looking for a 3rd party tabcontrol in Delphi FireMonkey

I am looking for a alternative to Raize components' tab control.
I would like to have the ability to add close button at the top of each page and I want to use slanted tabs and colors on the tabs. Oh, and I'm using FireMonkey 2.
//I know that raize does not support firmonkey.
Firemonkey has it's own TTabControl in the Common Controls page (by default). You can style this using a TStylebook. For example, I'm quite confident it's possible to add a close button onto the tab itself.
After all, FMX is a vector-based framework and so all visual elements must exist within the style. You'll probably want to load a style into a TStylebook for this, as I'm unable to find a way to load the default style into one. Navigate down to tabitemstyle, and from there you'll be able to tweak the visual appearance of it. Simply add a close button as you'd like (alignment, layout, etc).
Back in your application code, you'll be looking to use the FindStyleResource routine in order to setup the code (XE2 uses FindBinding and as such you'd set the BindingName property instead). I'm going to assume your close button is called 'CloseButton' (without the quotes);
var
MyTab : TTabItem;
begin
MyTab := ((TabItem1 as TTabItem).FindStyleResource('CloseButton') as TButton).OnClick := TabClose;
end;
You'd want to add that code when you initially create the tab, or if creating all the tabs at design time, you'll want to run it at FormCreate. You're basically telling it that when CloseButton is clicked, that you want to call the notify event/procedure TabClose. This procedure is identical to a button click.
You could go so far as changing the StyleName property of the tab to be CloseButton+Index_of_tab.
Now, as for the code to close the tab itself, something like this untested example may work, though you'll want to iterate on it.
procedure TForm1.TabClose(Sender: TObject);
var
_mytab : Integer;
_activetab : Integer;
begin
_activetab := ((Sender as TTabItem).Parent as TTabControl).ActiveTab.Index;
_mytab := ((Sender as TTabItem).Parent as TTabControl).ActiveTab.Index;
((Sender as TTabItem).Parent as TTabControl).Tabs[_MyTab].Free;
((Sender as TTabItem).Parent as TTabControl).TabIndex := _activetab;
end;
Now, this is the clever part, and exploits the design of the framework. When you click on a style element that's inside another element, by default, it'll select the parent element. In this example, it'll select the tab that contains the close button the user clicked on. From this, it'll then close that tab (technically, it'll free it, I've not dealt with tabs much in development so you'll want to look into the proper method of 'closing' them).
There is one problem with this though; You'll probably want to find a better way of detecting the previously active tab if you wish to switch back to it. Right now, it'll simply open the tab that was after the tab you just closed (since the tabcount is now 1 less, the active tab index selects the next physical tab). You'll probably be able to do this by splitting the _activetab code off elsewhere.
I've done similar things with some of my own programs, and this is how I usually create 'hybrid' components. You're essentially exploiting the modular design of the framework to make it do what you want it to do, without having to rely on third party components.
Since FMX is a pretty young framework there aren't many 3rd party component vendors that support it yet.
I haven't seen any 3rd party TabControl component for FMX and a quick Google search suggests there aren't any. So you might be out of luck.
I know this is an old query but in case anyone is still looking for tabs with close buttons and slanted tab sides, check out TMSSoftware's TTMSFMXTabSet. I'm using it in a current development project and it is working fine.

Show help question mark button (biHelp) on non dialog Form?

Is there a way that I can force the help question mark button to be visible on a form that is not a dialog in Delphi 2010?
I want to use the help question mark so that a user can click it then go to a control, but by default it is only available if the border style is dialog, but our application does not use dialog forms
I was looking at Overriding the CreateParams procedure but I am not sure what code to put in it to force the button to show?
Paul
According to MSDN, this is not a Delphi-specific limitation, but it is imposed by WinAPI. As you may know, the help question mark is turned on by WS_EX_CONTEXTHELP style, which cannot be combined with WS_MAXIMIZEBOX and WS_MINIMIZEBOX styles. So you can have a non-dialog form and display the question mark, provided that the form does not have maximize and minimize buttons in its caption. If you need the maximize and minimize buttons as well, then I think you should subclass the window and provide custom nonclient paint (drawing the question mark on your own) and nonclient hit-test processing.
You want a help button in the top (grabber) non-client area of a non-modal window that appears beside maximize and minimize?
Use TJvCaptionButton (included in the JEDI VCL) on your form, put a help question mark bitmap on the control button, and have that open the help to a particular page, from an integer help context like this:
Application.HelpContext(aHelpContext);
Because it paints in the non-client area of the window, you might experience some strange behaviour on some Windows theme settings; I don't think Jedi JvCaptionButtons look quite native on Win7 with Aero enabled, for example.
Update The linked question below in comments mentions putting the form into help-mode like this, contributed by DavidH:
SendMessage(Handle, WM_SYSCOMMAND, SC_CONTEXTHELP, 0);
end;

Multiple form Delphi applications and dialogs

I have a Delphi 7 application that has two views of a document (e.g. a WYSIWYG HTML edit might have a WYSIWYG view and a source view - not my real application). They can be opened in separate windows, or docked into tabs in the main window.
If I open a modal dialog from one of the separate forms, the main form is brought to the front, and is shown as the selected window in the windows taskbar. Say the main form is the WYSIWYG view, and the source view is poped out. You go to a particular point in the source view and insert an image tag. A dialog appears to allow you to select and enter the properties you want for the image. If the WYSIWYG view and the source view overlap, the WYSIWYG view will be brought to the front and the source view is hidden. Once the dialog is dismissed, the source view comes back into sight.
I've tried setting the owner and the ParentWindow properties to the form it is related to:
dialog := TDialogForm.Create( parentForm );
dialog.ParentWindow := parentForm.Handle;
How can I fix this problem? What else should I be trying?
Given that people seem to be stumbling on my example, perhaps I can try with a better example: a text editor that allows you to have more than one file open at the same time. The files you have open are either in tabs (like in the Delphi IDE) or in its own window. Suppose the user brings up the spell check dialog or the find dialog. What happens, is that if the file is being editing in its own window, that window is sent to below the main form in the z-order when the modal dialog is shown; once the dialog is closed, it is returned to its original z-order.
Note: If you are using Delphi 7 and looking for a solution to this problem, see my answer lower down on the page to see what I ended up doing.
I'd use this code... (Basically what Lars said)
dialog := TDialogForm.Create( parentForm );
dialog.PopupParent := parentForm;
dialog.PopupMode := pmExplicit;
dialog.ShowModal();
I ultimately ended up finding the answer using Google Groups. In a nutshell, all the modal dialogs need to have the following added to them:
procedure TDialogForm.CreateParams(var Params: TCreateParams);
begin
inherited;
Params.Style := Params.Style or WS_POPUP;
Params.WndParent := (Owner as TWinControl).Handle;
end;
I'm guessing this does the equivalent of Lars' and Marius' answers in Delphi 7.
Is the dialog shown using ShowModal or just Show? You should probably set the PopupMode property correct of the your dialog. pmAuto would probably your best choice. Also see if you need to set the PopupParent property.
First of all, I am not completely sure I follow, you might need to provide some additional details to help us understand what is happening and what the problem is. I guess I am not sure I understand exactly what you're trying to accomplish and what the problem is.
Second, you shouldn't need to set the dialog's parent since that is essentially what is happening with the call to Create (passing the parent). The dialogs you're describing sound like they could use some "re-thinking" a bit to be honest. Is this dialog to enter the properties of the image a child of the source window, or the WYSIWYG window?
I'm not sure I quite understand what you are getting at, but here's a few things I can suggest you can try...
This behaviour changes between different versions of Delphi. I'd suggest that this is due to the hoops they jumped through to support Windows Vista in Delphi 2007.
If you are using Delphi 2007, try removing the line from the project source file that sets the Application.MainFormOnTaskBar boolean variable.
With this removed, you should be able to use the various Form's BringToFront / SendToBack methods to achieve the Z-ordering that you are after.
I suspect that what you've discovered has been discussed on this link
Of course, I may have just missed your point entirely, so apologies in advance!

Resources