Double-clicking a TStaticText on a form copies the caption of that TStaticText to the clipboard. No double-click event is needed.
Steps to reproduce:
Using Win 64 and Delphi XE2 update 4.
Create a VCL Forms app.
Place a TEdit on the form.
Place a TStaticText on the form. Change caption to "TStaticText1Caption"
Place a second TStaticText on the form. Change caption to "TStaticText2Caption"
Run program(F9)
Type some text into the TEdit. Select it all and copy it via CTRL+C.
Delete the text in the TEdit. Paste it in to verify the text is what you copied.
Delete the text in the TEdit.
Double-click either TStaticText.
Paste text into TEdit. Notice it is not the original copied text but the caption of the TStaticText.
I have already submitted a bug report to Embarcadero.
I tried assigning a double-click event to the TStaticTexts. It still copies the caption to the clipboard even though it executes the double-click event.
procedure TForm1.StaticText1DblClick(Sender: TObject);
begin
Edit1.Text := 'Hello';
end;
procedure TForm1.StaticText2DblClick(Sender: TObject);
begin
Edit1.Text := 'World';
end;
This does not happen with TLabel or any other VCL control I have tried.
We have lots of TStaticTexts on our forms for visual design purposes and changing to TLabels is not an option.
Anybody have any ideas on how to prevent this from happening?
This is not a delphi bug, this behaviour is caused by the Windows Static Control which is created by the TStaticText VCL component.
Starting in Windows Vista, the Static text controls automatically copy their contents to the clipboard when you double-click them if you set the SS_NOTIFY style (the SS_NOTIFY style is set by the CreateParams method of the TCustomStaticText component)
Recomended lecture How do I make it so that users can copy static text on a dialog box to the clipboard easily?
As workaround you can remove the SS_NOTIFY style overriding the CreateParams method like so
type
TStaticText = class(Vcl.StdCtrls.TStaticText)
protected
procedure CreateParams(var Params: TCreateParams); override;
end;
TForm1 = class(TForm)
StaticText1: TStaticText;
private
public
end;
var
Form1: TForm42;
implementation
{$R *.dfm}
{ TStaticText }
procedure TStaticText.CreateParams(var Params: TCreateParams);
begin
inherited;
with Params do
Style := Style and not SS_NOTIFY;
end;
Note : you must be aware if you remove this style from the control you will no receive the STN_CLICKED, STN_DBLCLK, STN_DISABLE, and STN_ENABLE notification codes when the user clicks or double-clicks the control.
Related
When use TEdit control on the right side stay small icon 'x'. How after click on icon clear TEdit box.
Tnx all!
Delphi provide TClearEditButton to clear the TEdit content. It can be added by right clicking and selecting AddItem - TClearEditButton from the popup menu. It also has a Click procedure overriden in FMX.Edit unit like:
procedure TClearEditButton.Click;
var
EditTmp: TCustomEdit;
begin
inherited Click;
EditTmp := GetEdit;
if EditTmp <> nil then
begin
if EditTmp.Observers.IsObserving(TObserverMapping.EditLinkID) then
if not TLinkObservers.EditLinkEdit(EditTmp.Observers) then
Exit; // Can't change
EditTmp.Text := string.Empty;
if EditTmp.Observers.IsObserving(TObserverMapping.EditLinkID) then
TLinkObservers.EditLinkModified(EditTmp.Observers);
if EditTmp.Observers.IsObserving(TObserverMapping.ControlValueID) then
TLinkObservers.ControlValueModified(EditTmp.Observers);
end;
end;
Which make you don't need to write OnClick event handler for the TClearEditButton unless you want to do some other job along side with clearing the edit.
If you are using a TEditButton then you should write the OnClick event handler like:
procedure TForm1.EditButton1Click(Sender: TObject);
begin
Edit1.Text:= EmptyStr;
end;
The problem is that when I try to set the TBitBtn.Enabled to False (when it is focused, like in the onClick event, and with VCL Styles enabled), it does not change the visual state, looking like it is stil enabled.
procedure TForm1.BitBtn1Click(Sender: TObject);
begin
BitBtn1.Enabled := False;
end;
In the image, I just clicked in the bitbtn1
I'm using a inherited component from TBitBtn in my project, so I override the setEnabled setter and used the workaround posted by #RepeatUntil:
procedure TCustomBitBtn.SetEnabled(Value: Boolean);
begin
if Focused then
Winapi.Windows.SetFocus(0);
inherited;
end;
This solved my problem, but this looks like a bug from Seattle Update 1, because in Berlin Update 2 and Seattle without Update 1 (according to #Zam) the problem does not happen.
I faced a redrawing bug that is not very pleasant to see (Delphi 5, Windows 7 64 bit, Classic theme)
If one creates resizable dialog with client-aligned RichEdit in it and provide the function
procedure TQueryDlg.ShowDialog(const Txt: string);
begin
RichEdit.Text:=Txt;
ShowModal;
end;
then at least on Windows 7 when resizing the dialog, the lines are not re-wrapped, but rather the pixels from the chars keeps filling the space and it looks like the whole area is never invalidated. The richedit starts working correctly when the control is activated with the mouse.
I suppose it has something to do with message queue of forms and dialogs in Delphi, but probably is specific to RichEdits of particular version. My
System32/Richedit32.dll - v6.1.7601.17514
System32/RichEdit20.dll - v3.1, 5.31.23.1230
Probably some workaround information would be great.
I had a similar problem with the TRichEdit control. I found it wouldn't paint itself unless it was visible (which wasn't always the case in my app). And I found times that it rendered incorrectly until the user set focus to it. Both very irritating.
What worked for me was to create my own class and add a Render() method to it. This way I could tell it to paint whenever I wanted (e.g., when resizing a form, or when the component wasn't visible).
Here is a very stripped down version of what I did:
interface
uses
Winapi.Messages, Vcl.ComCtrls;
type
TMyRichEdit = class(TRichEdit)
private
procedure WMPaint(var Message: TMessage); message WM_PAINT;
public
procedure DoExit; override;
procedure DoEnter; override;
procedure Render;
end;
var
PaintMsg: TMessage;
implementation
procedure TMyRichEdit.DoEnter;
begin
inherited;
WMPaint(PaintMsg);
end;
procedure TMyRichEdit.DoExit;
begin
inherited;
WMPaint(PaintMsg);
end;
procedure TMyRichEdit.Render;
begin
WMPaint(PaintMsg);
end;
procedure TMyRichEdit.WMPaint(var Message: TMessage);
begin
// eliminated custom code to tweak the text content...
inherited;
end;
initialization
PaintMsg.Msg := WM_PAINT;
PaintMsg.WParam := 0;
PaintMsg.LParam := 0;
PaintMsg.Result := 0;
end.
I added WMPaint() because I needed to tweak how the text content before it was rendered. But none of that code is needed for what you are doing. So, instead of declaring WMPaint() and handling the WM_PAINT message, you could probably just post the PaintMsg from the DoExit(), DoEnter() and Render() methods. Sorry I don't have time to compile the code or try eliminating WMPaint() and using PostMessage()...
I would like to hide an application from the Windows 7 taskbar.
I want to make something like a toolbar on the edge of the screen which does certain things when the user clicks on it, but I don't want it to show in the taskbar, since its a thing that i want to stay in the background.
I tried the instructions in the following post, but it did not work on my application:
How to hide a taskbar entry but keep the window form
Then i tried it on a new empty VCL Forms Application and it still did not work. I searched for other solutions, but they all do very much the same like in the linked post.
Has something changed, that makes that impossible in windows 7? Or is there anything you
could think of, that could prevent it from working?
You can override the main form's CreateParam to remove the flag that forces the taskbar button (WS_EX_APPWINDOW) and additionally make the form owned by the application window. That's doing the opposite of the requirement for the shell to place a taskbar button for a window. From "Managing Taskbar Buttons":
[..] To ensure that the window button is placed on the taskbar, create an
unowned window with the WS_EX_APPWINDOW extended style. [..]
Sample:
type
TForm1 = class(TForm)
protected
procedure CreateParams(var Params: TCreateParams); override;
end;
procedure TForm1.CreateParams(var Params: TCreateParams);
begin
inherited;
Params.ExStyle := Params.ExStyle and not WS_EX_APPWINDOW;
Params.WndParent := Application.Handle;
end;
Don't change the state of MainFormOnTaskbar property of the 'Application' from its default 'True' if you use this method.
You can also remove the second line (..WndParent := ..) and instead set PopupMode of the form to pmExplicit in the object inspector to same effect.
BTW, here's the documentation quote from the same topic for the solution TLama posted:
To prevent the window button from being placed on the taskbar, [...]
As an alternative, you can create a hidden window and make this hidden
window the owner of your visible window.
When you set MainFormOnTaskbar to false, the main form is owned by the application window by VCL design. And if you hide the application window, the requirement is fulfilled.
Try to use a tricky way described in this article:
Set the MainFormOnTaskBar to False in your project file. Then try to hide the application window from the main form's OnShow and OnActivate event handlers. So your project might look like follows:
Project1.dpr:
program Project1;
uses
Forms,
Unit1 in 'Unit1.pas' {Form1};
{$R *.res}
begin
Application.Initialize;
Application.MainFormOnTaskbar := False;
Application.CreateForm(TForm1, Form1);
Application.Run;
end.
Unit1.pas:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs;
type
TForm1 = class(TForm)
procedure FormShow(Sender: TObject);
procedure FormActivate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.FormShow(Sender: TObject);
begin
ShowWindow(Application.Handle, SW_HIDE);
end;
procedure TForm1.FormActivate(Sender: TObject);
begin
ShowWindow(Application.Handle, SW_HIDE);
end;
end.
your application main form is normally created in the dpr so open the dpr and look for the line that creates the main form.
// add this line first
// blank app title will prevent app from showing in the applications list in task manager
Application.Title := '';
// this line is already in the dpr and creates the main form, the class will differ
Application.CreateForm(TMainForm, Result);
// make the main form invisible to windows taskbar/task switcher
i := GetWindowLong(Application.Handle, GWL_EXSTYLE);
SetWindowLong(Application.Handle, GWL_EXSTYLE, i OR WS_EX_TOOLWINDOW AND NOT WS_EX_APPWINDOW);
i know this works on XP and 7. i'm guessing it's good for 8 as well. this adds the tool window flag and removes the appwindow flag so i guess if you're not interested in the toolwindow flag you can leave out the following part
i OR WS_EX_TOOLWINDOW
This seems to only happen in IE6
I have an activex form written in Delphi 7. A dialogue window opened from within the activex control in IE6 gets displayed on the taskbar - the users (for some reason) do not want the dialogue to show in the taskbar.
So I set the dialogue's borderStyle to bsToolwindow. This hides the dialogue from the taskbar but also has the (side-) effect of hiding IE from the task list in windows, which means that you cannot <alt>Tab back to IE if you tabbed away.
Question: How to hide the activex pop-up dialogue from the taskbar but still have IE6 listed in the tasklist?
Set the owner window of your form to be the activex form (or perhaps the ie window). You can achieve this f.i. by passing the activex form as the owner component while you're creating your form and overriding CreateParams of the instantiated form:
// in the activex form's unit
procedure TActiveFormX.Button1Click(Sender: TObject);
var
f: TForm;
begin
f := TForm1.Create(Self);
f.BorderStyle := bsToolWindow;
f.Show;
end;
// in the dialog unit
type
TForm1 = class(TForm)
private
protected
procedure CreateParams(var Params: TCreateParams); override;
[...]
[...]
procedure TForm1.CreateParams(var Params: TCreateParams);
begin
inherited;
Params.WndParent := TCustomForm(Owner).Handle;
end;