I put a TLinkLabel on my form, filled it in with a caption including a valid HTML link, and got some nice blue underlined text. When I ran the program, I expected it to invoke Firefox (my default browser) and open the link automatically. Apparently that's not the case.
The helpfile says I have to code this in an OnLinkClick event handler. It doesn't say anything about how to do that, though. It'll pass in a string value called "Link". How do I say "invoke the default browser and have it open Link"?
You can call ShellExecute.
I wrote this method for generic calls, and should works in your case.
procedure ShellOpen(const Url: string; const Params: string = '');
begin
ShellAPI.ShellExecute(0, 'Open', PChar(Url), PChar(Params), nil, SW_SHOWNORMAL);
end;
In your code you should call this
procedure TForm1.LinkLabelClick(Sender: TObject);
begin
ShellOpen(LinkLabel.Caption);
end;
I have all sorts of problems with TLinkLabel that ships with delphi 2010.
a) The control does not render as a hyperlink but as a simple label text on the form. b) the cursor does not change to point out this is a link even though I set the Cursor property. c) the OnLinkClick event does not fire at all.
I am working on windows 7.
So, as far as I am concerned, TLinkLabel does nothing as it should and is useless. ShellExecute is the only solution and must be placed in the OnClick event.
TLinkLabel provides a label that looks like a link. It's your job as the programmer to make it act like a link because only you can know what links are supposed to act like in your program. You wanted the label to automatically open the user's default Web browser using the URL in the label, but that's not the only thing links do. For example:
Internet Explorer is not my default browser, but when I click a link in Internet Explorer, I do not expect the linked page to open in Firefox.
When I click a link in the help program, I expect the linked topic to appear in the help program, not in any Web browser at all.
The preference pages in Eclipse are very complicated. Settings on one page are sometimes related to settings on another page. There are links on those pages that take the user directly to the related page. There is no URL and no HTML involved in this case, and yet they're still labels with underlined text.
Some programs try to offer a choice between opening links in new windows versus re-using old windows. You can't implement that feature without knowing which browser is in use. Your program might offer the user a choice to ignore the default browser setting and always use a specific one. To do that, your UI control can't make too many assumptions about what the program is supposed to do.
I'm guessing you're referring to a TLinkLabel control that comes with Delphi. (My versions don't have such a component.) I imagine that the Delphi control is meant to mimic the one in the .Net class library. It can hold multiple links, and each link can do something different.
If you want a control that always does the shell's default action for URLs, then consider using a different TLinkLabel; the one by Alexander Bach does exactly what you expected. It's from Delphi 3, but it should work unmodified in all later versions as well, including Delphi 2009. If you look at the code, you'll see how it works. It simply calls ShellExecute, as Cesar's answer demonstrates.
LOL, it's funny. So instead of setting crHandPoint as cursor, colored and underlined font and filling the OnClick event to standard TLabel we have component that knows link tag and which at all I need to supply with same On(Link)Click event :))
Only thing it is good for is that it makes easier to embed link into some text and that it is using system style of link...
p.s.: really you have to put Some text with link into the Caption and setup OnLinkClick to that ShellExecute...
I use a control called TInternetLabel instead. It does exactly what you want: on click it opens the browser so you don't have to put code in the OnClick event.
I tried this solution but it still gave problems in Delphi XE4, probably becasue ShellOpen does not understand the HTML-code in the Caption.
What worked for me was a combination of Cesar Romero (the basic code), Adam Feistner (The HTML-code in the Caption) and an older solution:
Put the URL in the HINT field.
Change the line: ShellOpen(LinkLabel.Caption);
to
ShellOpen(LinkLabel.Hint);
This worked for me.
Related
Is it possible to use Acrobat.MenuItemExecute('Copy'); command with
AVDoc.OpenInWindowEx(FFilename, Panel1.handle, 0, True, 0,0, 2, 0, 0, 0);
in Delphi 7 and Acrobat XI Pro?
If you help me with an example I'll be glad.
I think the answer to this is probably "no" because before calling Acrobat.MenuItemExecute('Copy'), it is necessary to call BringToFront on the window containing the text you want to copy, otherwise the call to MenuItemExecute('Copy') will fail, even when the document is hosted in one of Acrobat's own windows. I don't see how you could do that successfully when the document window is hosted in your app, rather than Acrobat.
However, there are a few things you could add to your q that might assist in getting a better answer. [...]
Update Please disregard my comments in an earlier version of this answer saying that I could not reproduce the behaviour that I could not select text in the window opened using OpenInWindowEx. In fact, I can now select text fine, what I had overlooked previously is that I had set the Enabled property of my TPanel to False.
Unfortunately, I have still not been able to successfully call Acrobat.MenuItemExecute('Copy') and I am beginning to think that there is no way to do this in a hosted window. I have not found a definitive list, but various comments by Adobe staffers that google found make it clear that many MenuItemExecute strings just to not work when using OpenInWindowEx.
However that may not be the only way to retrieve the selected text back into the Delphi app.
If you look at the hosted window using a tool like WinSpy or Window Detective you will see that contained within the panel window is a whole host of Acrobat windows, including an AVL_AVView one with the Window text "AVPageView" which I imagine is the actual window displaying the PDF text.
I think the key to a possible solution is your observation, which I've confirmed, that pressing Ctrl-C in the window copies the text to the clipboard. So far I have not been able to achieve the equivalent in code, using techniques like keybd_event calls, various Delphi "SendKeys" routines and sending a WM_COPY message to the AVPageView window. I'm sure it must be possible, but I haven't yet found a way.
Since I know you guys are exceptional people with awesome talents, maybe someone might be able to help me with this.
This is the situation:
I have an Application that calls a DLL. The catch here is that I'm opening the DLL in a TAdvPanel (it belongs to a TMS library, but I believe it works for the standard Panels too), and it works perfectly fine.
Whenever I close the tab, I can always call the DLL again and recreate its Form, but when I close the Form, the tab where the DLL was stays open, with no content inside of it.
Is there a way for me to "warn" the Application that the DLL was closed and that I can close the tab where the DLL was?
(Note: whenever I write Form, I mean the DLL's Form.)
This is how I call the DLL from inside the Application:
CallCompany(<Parameters..>,Panel.Handle);
And this code below belongs to the DLL:
library Company
uses
...,
U_Form in 'U_Form.pas' {Form}, Windows,
... ;
{$R *.res}
procedure CallCompany(<Parameters..>; ParentForm: THandle); export; stdcall;
var
...
begin
... <Preparing the form to open> ...
Form.Show;
Windows.SetParent(Form.Handle, ParentForm);
end;
exports
CallCompany;
I'm new with DLL's and the way they work. I know I could just not give the user the "Exit" button inside the DLL, forcing him to close the tab, but I wanted to give him that option too.
Ah, and I don't have any code for the OnClose event of the DLL's Form.
If you need any other information in order to help, just tell me and I'll post here whatever is needed.
BTW, I'm using Delphi XE7.
Thanks for the attention.
Complementing the Question:
I have a TAdvPageControl, in which I create TAdvTabSheets, and inside this TAdvTabSheets I put a TAdvPanel (set as alClient).
The DLL I call has a Form, does that categorize as "more that a DLL" ?
I'm posting an image so that might clear things a little bit. If it's still confusing, just say it and I'll drop the question.
When I close the form, the tab where the form was stays open, with no content inside of it.
Don't ever close the form without also closing the tab. That way this situation never arises.
As for specifics, I've got none to offer since the question has no real detail, no MCVE. But it's fairly obvious that the tab and the form that it hosts must be shown and hidden in unison.
I'm showing where a file has been saved by using 'Showmessage' (in Win 7).
When the file path is long it gets truncated and elipsis get inserted.
eg
the path
C:\Users\Admin\Documents\SubFolderOne\AnotherSubFolder\MyFile.csv
gets displayed as
C:\Users\Admin\Documents\SubFolderOne\Ano...\MyFile.csv
Is there a way to make the message box wider and show all of the filename and path?
I have read this
http://zarko-gajic.iz.hr/displaying-long-non-breakable-text-file-path-in-messagedlg-truncationellipsis-issues/
which explains some of the reasoning and gives a rather unsatisfactory method for a TTaskDialog and I also I realise I could make my own form to act in the same way as Showmessage but I am wondering if there is a simpler solution using just Showmessage.
Is a simpler solution using just ShowMessage?
No there is not.
I can think of three obvious approaches, although doubtless there are more.
Create your own dialog
There's nothing particularly magical about a dialog. You can perfectly well create them yourself, and so have complete control over their appearance. The downside of course is that it can be hard to match the native platform appearance. Especially when you consider all the different Windows versions that you are typically expected to support.
Use CreateMessageDialog and customise this Delphi form
You can call the RTL function CreateMessageDialog to obtain a Delphi form that can be used to display your message dialog. You then have the opportunity to customize this dialog in any way you please.
Use the task dialog API
The task dialog API, introduced in Vista, affords control of the dialog width. Call TaskDialogIndirect, and specify a non-zero value for cxWidth.
Before ShowMessage put:
UseLatestCommonDialogs:= false;
I use Delphi 10.2 and it works.
I noticed something strange, related to the Drag&Drop component from Anders Melander, and I wonder if anybody has an idea ?
I have been looking for the reason, without much success. However the effect is 100% repeatable by simply removing: DropFileTarget->Register(ComboBox); from the project's constructor.
The other day I noticed that the drop down box on my application was not looking right:
Whereas it previously looked (correct) like this:
So I started going back to figure out at what time the look of the component broke and I have now been able to trace the change in look 100% to:
DropFileTarget->Register(ComboBox);
If this line is present, the look is good.
If I remove this line of code from the form's constructor the look of the drop box is wrong !?
I actually wanted to remove DropFileTarget completely from my project since I now use another method to catch a dragged file.
Can anybody please tell me what Register() does here to change the look of the component, so that I can set the look back to what it should be.
My gut says it has to do with theme support as well somehow ?
ADDITIONAL INFORMATION BASED ON THE COMMENTS:
I did some tests. A normal looking Combobox, with theme support, looks like this:
With theme support disabled it looks like this:
In other words, the Drag&Drop component's Register() creates a special look, that I had grown used to, and of which I thought was the correct look.
The canvas where the text is displayed is white instead of grey (default settings).
I'm now torn between going for 'how it should be' or trying to create the look I had gotten used to.
Anybody knows what properties I should change to get the component-influenced look (second screenshot from the top) ?
I'm using delphi 7 and I'm trying to make a wizard interface. I don't know if there is an easier way to make a wizard, so I was thinking of making separate forms for each step of the wizard, and when the user clicks "Next" the active form closes and the next one opens.
Here's a screen-shot of two successive forms:
I've made a procedure that take 2 forms as parameters: the form that will be closed and the next form of the wizard
class Procedure Tspad.nextForm(showForm, closeForm: TForm);
begin
closeForm.Close;
showForm.Showmodal;
end;
When I click the "Next" Button the folowing code is executed:
Tspad.nextForm(echipContractForm, clientContractForm);
When i run the program, and i press the "Next" button, the next form apeares but the curent one dosen't close.
How can i make this work, or is there another more efficient way to create a wizard?
One very common way to make a wizard is to use a page control. Each distinct page of the wizard is a different page/tabsheet in the page control. I believe that this is effectively how Windows implements wizards.
Naturally you want to hide all the tabs. Do this by setting TabVisible to False for each tabsheet. When you wish to move forwards and backwards through the wizard, e.g. when the user clicks the next or previous buttons, effect this by setting ActivePage or ActivePageIndex depending on your preference.
A good practise for the division of content being displayed on a single form is the use of Frames.
A Frame is a lot like a form, except it has no Window of its own, but rather sits inside a host Form.
When combined with (as David Heffernan has suggested) a TPageControl or even a TNotebook (which is pretty-much exactly the same as TPageControl, only it doesn't have Tabs to begin with), you end up with an easily-maintainable Wizard.
JVCL has a good control to make a wizard in a very simple and effective way (TJvWizard). See http://jvcl.delphi-jedi.org/
You can give a try to these :
Balmsoft Wizard released under LGPL.
Delphi Wizard Framework by SO member Steven R. Kamradt.
You can test some components that can help you with this task (internally using tPageControl or TNotebook). See this link.
Regards.
You may also consider TMS TAdvSmoothStepControl (not free !).
Another solution, but only 'external' to your program, is to use Inno Setup to make a Wizard, even for 'non installation setup' purposes.
In fact with Inno Setup you can make a lot of thinks ( modify .ini file and registry, start/stop programs...) that can be usefull for a wizard without 'installing' a program.