I am looking (I think) for the Windows API that I can use in my OnDrawTab event in the TPageControl component to display gray text on tabs that I choose. I have done it in the past and from memory this is where I did (in the OnDrawTab event). Unfortunately I don't have access to the code to look back how I did it before.
I'm sure that I used something like DrawText or TextOut or something but I was able to add a flag or format style to it which gave it the appearance of grayed out. For the life of me I cannot find the command I used. ODS_DISABLED flag seems to be something like what I'm after but it is a windows message handler so I'm sure I didn't use that before. I'm not writing a component here, just handling the OnDrawTab event.
Anyone point me in the right direction?
I'm using Delphi 6.
Thanks
Jason
You can use the DrawState and GrayString functions.
procedure TForm1.FormClick(Sender: TObject);
var
s: string;
begin
s := 'testar';
DrawState(Canvas.Handle,
0,
nil,
integer(#s[1]),
length(s),
10,
10,
0,
0,
DST_TEXT or DSS_DISABLED)
end;
Related
How can I insert the text from an Edit control into any window where the mouse pointer is, without using the clipboard and/or window handle.
I am using Delphi 7.
Call GetCursorPos to find out where the cursor is.
Call WindowFromPoint to find the window under the cursor.
Send an EM_REPLACESEL message to replace the selection in that window. If nothing is selected then the text will be inserted at the caret.
Note: Be prepared for this to fail more commonly than it succeeds. Many applications don't used windowed edit controls. For a more robust solution you should look into UI Automation.
You asked for some code. Here's what it would look like:
var
Pos: TPoint;
Target: HWND;
...
if not GetCursorPos(Pos) then
RaiseLastOSError;
Target := WindowFromPoint(Pos);
if Target<>0 then
SendMessage(Target, EM_REPLACESEL, ord(True), LPARAM(PChar(Edit1.Text)));
If the window underneath the cursor is not an edit window, this will, probably, be benign.
I have searched many forums and many web sites but i didn't find the required solution.I had a requirement to show the number of notifications to buttons .When the form Loads.If the notifications are hundred there should be 100 beside the button.if nothing then no notification should be visible.
Please suggest me the required solution..
Thanks In advance.
They are asking the similar functionality as in Icons of IOS4.
If you don't mind using a component for this instead of making your own, there is one that does what you need. It will display a status and looks just like what you have shown in your image link.
You can see this page here
It is not free though.
In iOS 4 there are icons with notifications (for programm-startup) and no buttons (I think), so this is not really the same,... but maybe you can create a custom button (inherit from TButton) and use something like an onPaint Event (sorry this is too much dotnet-style,... don't know how it is called in delphi) to draw this "notification" to the button like you do it in TCanvas.
I think you can use TBalloonHint component. For example, To show the notification,
procedure TForm1.FormCreate(Sender: TObject);
var
point : TPoint;
begin
point.X := sb1.Left;
point.Y := sb1.Top;
BalloonHint1.Delay := 100;
//BalloonHint1.Description := 'This is your Notification!';
BalloonHint1.HideAfter := -1;
BalloonHint1.Style := bhsBalloon;
BalloonHint1.Title := '2';
sb1.ParentShowHint := False;
BalloonHint1.ShowHint(point);
end;
To Hide the notification
procedure TForm1.sb1Click(Sender: TObject);
begin
BalloonHint1.HideHint;
end;
It would be see like the above image
If you want to show images, you can use the BalloonHint1.Images property.
You could use a TPaintBox and draw directly to its Canvas property. TCanvas has a number of methods that would make this a fairly simple task, in my opinion. Just store the background image separately (maybe in a TImage), copy it to the canvas (using the Draw method in the OnPaint event), and then paint the circle (Ellipse method) and the number last (TextOut or TextRect). You can also use the OnClick event of the TPaintBox to manage the "button clicking" operations.
I found this question on Experts-Exchange.
Control's OnExit eats up mouseup event for new control when showing
another window
The problem can be replicated easily.
place 3 tedits on a form. write a showmessage('exit') in edit1's
onexit event run the program give edit1 focus use the mouse to give
edit3 focus, click ok to the showmessage observe how you can't write
anything in edit3 now, until you click with the mouse somewhere on the
form ! give edit2 focus, then use to the mouse to give edit3 focus
observe how you can type what you want in edit3 now !
So far I've established that the problem lies in the fact that edit3
doesn't receive a mouseup-message when the old controls onExit event
displays a window of any kind, i've tried it as well with showing a
form of my own in the onExit event, same result. In fact, windows is
under the impression that the mouse is held down over edit3 after
you've clicked Ok to the showmessage
I guess it's a bug in Delphi/Windows but how to work around it ? I
know i can force a WM_LBUTTONUP on edit3's onMouseDown event (since
its the last event called in the process) but that's more than
tedious, and not always applicable
I am trying to do something similiar:
In the onexit event I show a warningbox and then want to proceed
as normal - moving the focus to where the user in fact clicked.
Is that possible?
Once again PostMessage to the rescue! Defer your dialog just a little bit longer so that Windows can finish its focus change. Post yourself a message instead of showing the dialog directly:
const
WM_SHOWMYDIALOG = WM_APP + 321;
TForm1 = class(TForm)
Edit1: TEdit;
Edit2: TEdit;
procedure Edit1Exit(Sender: TObject);
private
procedure WMSHOWMYDIALOG(var Message: TMessage); message WM_SHOWMYDIALOG;
end;
procedure TForm1.Edit1Exit(Sender: TObject);
begin
PostMessage(Self.Handle, WM_SHOWMYDIALOG, 0, 0);
end;
procedure TForm1.WMSHOWMYDIALOG(var Message: TMessage);
begin
ShowMessage('Nice one');
end;
And everything is fine :)
I'm not so sure that the reason of the behavior is an eaten mouse message. Anyway, either that's the case or not, when you activate a window in an OnExit event of a control, what you're doing is, changing the focus while the focus is changing. That's because, the window is activated before WM_SETFOCUS for the newly focused control returns. This is discouraged, the below quote is from 'Best practices' section of 'Win32 Activation and Focus', a blog entry on MSDN:
Avoid manually changing focus when getting and/or losing focus. This
usually proves to be error prone.
The fact that the controls are disabled during focus transfer due to the modal nature of the activated window certainly would not help. If you really must do this, an approach like Heinrich's answer would at least delay the launch of the window till the focus transfer completes.
In the onexit event I show a warningbox and then want to proceed as normal - moving the focus to where the user in fact clicked. Is that possible?
Yes, (Screen.)ActiveControl will always point to Edit3: before and after the call to ShowMessage:
procedure TForm1.Edit1Exit(Sender: TObject);
begin
ShowMessage('Exit');
PostMessage(ActiveControl.Handle, WM_LBUTTONUP, 0, 0);
end;
But this is just for completeness sake to your question! And it certainly is no tip nor advice! See Sertac's answer for the reason.
Regarding Notification Area recommendations by Microsoft, I'm looking for ideas or a Delphi component to implement Notification Area Flyouts.
The first "natural" idea is to use a standard Delphi form, but I'm facing two issues with it:
I can't get the form border behavior using the standard "BorderStyle" property. Tried to "mimic" the border using the GlassFrame property along with BorderStyle set to bsNone, but there's no GlassFrame when there's no border (at least, in Delphi 2007).
I can't figure out how to make the form close when the user clicks everywhere out of the form itself. Yesterday I was trying with different messages, but no one works as expected.
I will thank any clue or component to make it happen :)
Best regards.
jachguate.
ps. There's a related question in converting notification area icon to Program icon in Win7 (Delphi).
update[0]
I'm still looking for advise. #skamradt answer looks very good, but unfortunately doesn't work well in practice.
update[1]
Finally, The auto-close behavior is working with the WM_ACTIVATE message after a calling SetForegroundWindog to force flyout "activation"
begin
FlyoutForm.Show;
SetForegroundWindow(FlyoutForm.Handle);
end;
Now, I'm looking for advise to reach the border behavior and visual style, because the closest behavior is achieved with style as WS_POPUP or WS_DLGFRAME, while the closest visual goal is achieved setting style as WS_POPUP or WS_THICKFRAME.
I believe what your after is the following:
TForm1 = class(TForm)
:
protected
procedure CreateParams(var Params: TCreateParams); override;
procedure WMActivate(Var msg:tMessage); message WM_ACTIVATE;
end;
procedure TForm1.CreateParams(var Params: TCreateParams);
begin
inherited;
Params.Style := WS_POPUP or WS_THICKFRAME;
end;
procedure TForm4.WMActivate(var msg: tMessage);
begin
if Msg.WParam = WA_INACTIVE then
Hide; // or close
end;
This will give you a sizeable popup window with a glass frame. You can't move the window without additional programming, since the standard windows caption is missing. When another window gets focus, the FormDeactivate event gets fired...but only if you switch to another form in the same application. To handle it regardless of the application switched, use the message capture method.
My application does automated screenshots of several dynamically created forms. This works perfectly under Windows XP, but doesn't work well under Vista Aero. Most of the forms appear semitransparent in the screenshots. The problem lies in the window animation of Aero.
How can I check/disable/enable this animation from inside a Delphi (2007+) program?
Or as an alternative: How can I make sure the form is displayed properly before making the screenshot?
The link in the comment from Shoban led me in the right direction. A quick check showed a wrapper for the DwmApi in the VCL and from that it went straight forward. Here is the code I successfully use now:
uses DwmApi;
...
SaveDwmCompositionEnabled := DwmCompositionEnabled;
if SaveDwmCompositionEnabled then
DwmEnableComposition(DWM_EC_DISABLECOMPOSITION);
...
if SaveDwmCompositionEnabled then
DwmEnableComposition(DWM_EC_ENABLECOMPOSITION);
Disabling Aero would be a pity - in general it's not a good idea to change the user's choice of UI style.
You may be able to draw the form another way. One thing that comes to mind is using the PaintTo method to paint it to a canvas. (In fact, if you're taking screenshots of the forms as a way of getting what it looks like you probably don't need to show the forms at all - created them with Visible set to false and paint them to a bitmap. Only show them if the user needs to interact with them.)
I was trying to solve the same problem and found this question, but came up with a completely different solution. It doesn't disable the animation, but it allows you to make the window disappear without animation effect.
var oldWidth := Self.Width;
var oldHeight := Self.Height;
try
if Visible and (Self.WindowState <> wsMinimized) then
begin
Self.BorderStyle := bsNone; // do this first
Self.Width := 0;
Self.Height := 0;
end;
//.. Do your screen capture here
finally
if Visible and (Self.WindowState <> wsMinimized) then
begin
Self.BorderStyle := bsSizeable; // or whatever it was
Width := oldWidth;
Height := oldHeight;
end;
end;
You could also move the window to -maxint for X & Y, but I like this better.
You can add a manifest resource to the exe file, to notify Vista you want that the application runs without Aero
http://www.google.be/search?q=vista+manifest+resource+delphi