Minimize Delphi Form to System Tray - delphi

I am a Delphi learner. I am looking for solutions so that Delphi MainForm should be minimized to the System Tray instead of Taskbar. On Right Click on the System Tray Icon there should be some menus like "Restore" and "About" and "Help" etc. System Tray Icons will be loaded from Imagelis1 and it will animate. On Clicking on "Restore" the MainForm will be restored, on clicking on "About" "Form2" will be restored and on clicking on "Help" "Foprm3" will be restored. I have found so many solutions on internet like :
Solution 01
Solution 02
but every solutions have some drawbacks. Some can be done once ony. Some have blurred icon in Windows7. Someone may tell that there is no one to write codes for me and I have to show my codes. Plaese forgive me for this regards. Please give me concrete solution sot that it can be implemented universely without version dependency of windows. It will help every one. Please help me.

This should get you going. Drop a TTrayIcon and a TApplicationEvents on your form. THe following code is from the TTrayIcon - Delphi Example from the docwiki. Use the IDE main menu, and choose Project->View Source, and the line that reads Application.ShowMainFormOnTaskbar := True; to `Application.ShowMainFormOnTaskbar := False;' to keep the application's button from appearing on the Windows Taskbar.
This example uses a tray icon and an application events component on a form. When the application runs, it loads the tray icon, the icons displayed when it is animated, and it also sets up a hint balloon. When you minimize the window, the form is hidden, a hint balloon shows up, and the tray icon is displayed and animated. Double-clicking the system tray icon restores the window.
// Add this to the `TApplicationEvents.OnMinimize` event handler
procedure TForm1.ApplicationEvents1Minimize(Sender: TObject);
begin
{ Hide the window and set its state variable to wsMinimized. }
Hide();
WindowState := wsMinimized;
{ Show the animated tray icon and also a hint balloon. }
TrayIcon1.Visible := True;
TrayIcon1.Animate := True;
TrayIcon1.ShowBalloonHint;
end;
// Add this to the `TForm.OnCreate` event handler
procedure TForm1.FormCreate(Sender: TObject);
var
MyIcon : TIcon;
begin
{ Load the tray icons. }
TrayIcon1.Icons := TImageList.Create(Self);
MyIcon := TIcon.Create;
MyIcon.LoadFromFile('icons/earth1.ico');
TrayIcon1.Icon.Assign(MyIcon);
TrayIcon1.Icons.AddIcon(MyIcon);
MyIcon.LoadFromFile('icons/earth2.ico');
TrayIcon1.Icons.AddIcon(MyIcon);
MyIcon.LoadFromFile('icons/earth3.ico');
TrayIcon1.Icons.AddIcon(MyIcon);
MyIcon.LoadFromFile('icons/earth4.ico');
TrayIcon1.Icons.AddIcon(MyIcon);
{ Set up a hint message and the animation interval. }
TrayIcon1.Hint := 'Hello World!';
TrayIcon1.AnimateInterval := 200;
{ Set up a hint balloon. }
TrayIcon1.BalloonTitle := 'Restoring the window.';
TrayIcon1.BalloonHint :=
'Double click the system tray icon to restore the window.';
TrayIcon1.BalloonFlags := bfInfo;
end;
// Add this to the `TTrayIcon.OnDoubleClick` event handler
procedure TForm1.TrayIcon1DblClick(Sender: TObject);
begin
{ Hide the tray icon and show the window,
setting its state property to wsNormal. }
TrayIcon1.Visible := False;
Show();
WindowState := wsNormal;
Application.BringToFront();
end;
For the menu you get on right-click, add a TPopupMenu to your form, add the items you want on it, write the event handlers for those items as usual, and then assign the PopupMenu to the TrayIcon.PopupMenu property.
The "blurred icons" are caused by you not using the proper icon sizes and Windows being forced to scale (stretch) them. Use an icon editor to create multiple size images for each icon (there can be multiple sizes in one icon file).

I drop a TrayIcon onto myForm, then i add this simple code:
type
TmyForm = class(TForm)
...
TrayIcon: TTrayIcon;
procedure FormCreate(Sender: TObject);
...
procedure TrayIconClick(Sender: TObject);
...
private
{ Private declarations }
procedure OnMinimize(Sender:TObject);
public
{ Public declarations }
end;
procedure TmyForm.FormCreate(Sender: TObject);
begin // When form is created
Application.OnMinimize:=OnMinimize; // Set the event handler for application minimize
end;
procedure TmyForm.OnMinimize(Sender:TObject);
begin // When application is minimized by user and/or by code
Hide; // This is to hide it from taskbar
end;
procedure TmyForm.TrayIconClick(Sender: TObject);
begin // When clicking on TrayIcon
if Visible
then begin // Application is visible, so minimize it to TrayIcon
Application.Minimize; // This is to minimize the whole application
end
else begin // Application is not visible, so show it
Show; // This is to show it from taskbar
Application.Restore; // This is to restore the whole application
end;
end;
This creates a TrayIcon allways visible, and when you click on it:
If the application is Visible, it will be Hidden form taskbar and from screen
If the application is Hidden, it will be Shown form taskbar and from screen
In other words, clicking on TrayIcon the application will change its visibility; just as minimizing it to TrayIcon bar.

...And in Delphi 6, where no TTrayIcon exists, you can use this simple code:
unit MainUnit;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ShellAPI, StdCtrls, Menus;
const WM_ICONTRAY = WM_USER+1;
type
TForm1 = class(TForm)
PopupMenu1: TPopupMenu;
ShowForm1: TMenuItem;
HideForm1: TMenuItem;
Exit1: TMenuItem;
procedure TrayMessage(var Msg: TMessage); message WM_ICONTRAY;
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure ShowForm1Click(Sender: TObject);
procedure HideForm1Click(Sender: TObject);
procedure Exit1Click(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
private
TrayIconData: TNotifyIconData;
end;
var
Form1: TForm1;
MustExit:boolean;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
begin
MustExit:=false;
TrayIconData.cbSize:=SizeOf(TrayIconData);
TrayIconData.Wnd:=Handle;
TrayIconData.uID:=0;
TrayIconData.uFlags:=NIF_MESSAGE + NIF_ICON + NIF_TIP;
TrayIconData.uCallbackMessage:=WM_ICONTRAY;
TrayIconData.hIcon:=Application.Icon.Handle;
StrPCopy(TrayIconData.szTip,Application.Title);
Shell_NotifyIcon(NIM_ADD, #TrayIconData);
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
Shell_NotifyIcon(NIM_DELETE, #TrayIconData);
end;
procedure TForm1.TrayMessage(var Msg: TMessage);
var p:TPoint;
begin
case Msg.lParam of
WM_LBUTTONDOWN: begin
Form1.Show;
Application.Restore;
end;
WM_RBUTTONDOWN: begin
GetCursorPos(p);
PopUpMenu1.Popup(p.x,p.y);
end;
end;
end;
// Popup "Form Show" menu item OnClick
procedure TForm1.ShowForm1Click(Sender: TObject);
begin
Form1.Show;
end;
// Popup "Form Hide" menu item OnClick
procedure TForm1.HideForm1Click(Sender: TObject);
begin
Form1.Hide;
end;
// Popup "Exit" menu item OnClick
procedure TForm1.Exit1Click(Sender: TObject);
begin
MustExit:=true;
Close;
end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
if MustExit then exit;
Form1.Hide;
Action:=caNone;
end;
end.

I have implemented the following codes. Here everything is fine except one. After minimizing the Form, it goes to "SystemTray" but also available in "TaskBar. For my application, the "AlphaBlend" property of "Form001" is true and "AlphaBlendValue" is "0".
unit KoushikHalder001;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.Buttons, Vcl.ExtCtrls, Vcl.Imaging.pngimage,
Vcl.AppEvnts, Vcl.ImgList, Vcl.Menus;
type
TForm001 = class(TForm)
Edit001: TEdit;
Background: TImage;
BitBtn001: TBitBtn;
BitBtn002: TBitBtn;
FadeInTimer: TTimer;
FadeOutTimer: TTimer;
FormMinimizeTimer: TTimer;
FormRestoreTimer: TTimer;
TrayIcon: TTrayIcon;
PopupMenu: TPopupMenu;
ImageList: TImageList;
ApplicationEvents: TApplicationEvents;
Form001Close: TMenuItem;
Form001Hide: TMenuItem;
Form001Show: TMenuItem;
Form002Close: TMenuItem;
Form002Hide: TMenuItem;
Form002Show: TMenuItem;
N01: TMenuItem;
N02: TMenuItem;
N03: TMenuItem;
N04: TMenuItem;
N05: TMenuItem;
N06: TMenuItem;
N07: TMenuItem;
N08: TMenuItem;
N09: TMenuItem;
N10: TMenuItem;
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
procedure FormCreate(Sender: TObject);
procedure FormHide(Sender: TObject);
procedure FormShow(Sender: TObject);
procedure BitBtn001Click(Sender: TObject);
procedure BitBtn002Click(Sender: TObject);
procedure FadeInTimerTimer(Sender: TObject);
procedure FadeOutTimerTimer(Sender: TObject);
procedure FormMinimizeTimerTimer(Sender: TObject);
procedure FormRestoreTimerTimer(Sender: TObject);
procedure ApplicationEventsMinimize(Sender: TObject);
procedure TrayIconDblClick(Sender: TObject);
procedure Form001CloseClick(Sender: TObject);
procedure Form001HideClick(Sender: TObject);
procedure Form001ShowClick(Sender: TObject);
procedure Form002CloseClick(Sender: TObject);
procedure Form002HideClick(Sender: TObject);
procedure Form002ShowClick(Sender: TObject);
private
{ Private declarations }
CrossButtonClick: Boolean;
procedure WMNCHitTest(var Msg: TWMNCHitTest) ; message WM_NCHitTest;
procedure WMSysCommand(var Msg: TWMSysCommand) ; message WM_SysCommand;
public
{ Public declarations }
end;
var
Form001: TForm001;
implementation
{$R *.dfm}
uses KoushikHalder002;
procedure TForm001.WMNCHitTest(var Msg: TWMNCHitTest);
begin
inherited;
if ControlAtPos(ScreenToClient(Msg.Pos), True, True, True)= nil
then
begin
if Msg.Result=htClient then Msg.Result := htCaption;
end;
end;
procedure TForm001.WMSysCommand(var Msg: TWMSysCommand);
begin
case Msg.CmdType of
SC_MINIMIZE:
begin
if Form001.AlphaBlendValue > 0 then
begin
Form001.FormMinimizeTimer.Enabled := true;
Exit;
end;
end;
SC_RESTORE:
begin
if Form001.AlphaBlendValue < 220 then
begin
Form001.FormRestoreTimer.Enabled := True;
end;
end;
end;
inherited;
end;
procedure TForm001.ApplicationEventsMinimize(Sender: TObject);
begin
Form001.FormMinimizeTimer.Enabled := true;
TrayIcon.Visible := True;
TrayIcon.Animate := True;
TrayIcon.ShowBalloonHint;
end;
procedure TForm001.BitBtn001Click(Sender: TObject);
begin
if Form002.WindowState = wsMinimized then
begin
Form002.Perform(WM_SYSCOMMAND, SC_RESTORE, 0);
end
else
Form002.show;
end;
procedure TForm001.BitBtn002Click(Sender: TObject);
begin
Form002.FadeOutTimer.Enabled := true;
Form001.FadeOutTimer.Enabled := true;
end;
procedure TForm001.Form001CloseClick(Sender: TObject);
begin
Form002.FadeOutTimer.Enabled := true;
Form001.FadeOutTimer.Enabled := true;
end;
procedure TForm001.Form001HideClick(Sender: TObject);
begin
Form001.FormMinimizeTimer.Enabled := true;
end;
procedure TForm001.Form001ShowClick(Sender: TObject);
begin
if Form001.WindowState = wsMinimized then
begin
Form001.Perform(WM_SYSCOMMAND, SC_RESTORE, 0);
end
else
Form001.show;
end;
procedure TForm001.Form002CloseClick(Sender: TObject);
begin
Form002.FadeOutTimer.Enabled := true;
end;
procedure TForm001.Form002HideClick(Sender: TObject);
begin
Form002.FormMinimizeTimer.Enabled := true;
end;
procedure TForm001.Form002ShowClick(Sender: TObject);
begin
if Form002.WindowState = wsMinimized then
begin
Form002.Perform(WM_SYSCOMMAND, SC_RESTORE, 0);
end
else
Form002.show;
end;
procedure TForm001.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Form001.FadeOutTimer.Enabled := true;
end;
procedure TForm001.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
if CrossButtonClick = true
then
begin
CanClose := true;
Exit;
end;
CanClose := false;
Form001.FadeOutTimer.Enabled := true;
end;
procedure TForm001.FormCreate(Sender: TObject);
begin
Form001.FadeInTimer.Enabled := true;
end;
procedure TForm001.FormHide(Sender: TObject);
begin
Form001.FadeOutTimer.Enabled := true;
end;
procedure TForm001.FormShow(Sender: TObject);
begin
Form001.FadeInTimer.Enabled := true;
end;
procedure TForm001.TrayIconDblClick(Sender: TObject);
begin
Form001.FormRestoreTimer.Enabled := true;
TrayIcon.Visible := False;
WindowState := wsNormal;
Application.BringToFront();
end;
procedure TForm001.FadeInTimerTimer(Sender: TObject);
begin
if Form001.AlphaBlendValue >= 220
then
begin
Form001.FadeInTimer.Enabled := false;
end
else
begin
Form001.AlphaBlendValue := Form001.AlphaBlendValue + 10;
CrossButtonClick := false;
end;
end;
procedure TForm001.FadeOutTimerTimer(Sender: TObject);
begin
if Form001.AlphaBlendValue <= 0
then
begin
Form001.FadeOutTimer.Enabled := false;
CrossButtonClick := true;
Self.Close;
end
else
begin
Form001.AlphaBlendValue := Form001.AlphaBlendValue - 10;
CrossButtonClick := true;
end;
end;
procedure TForm001.FormMinimizeTimerTimer(Sender: TObject);
begin
if Form001.AlphaBlendValue > 0 then
begin
Form001.AlphaBlendValue := Form001.AlphaBlendValue - 10;
end
else
begin
Form001.FormMinimizeTimer.Enabled := false;
Perform(WM_SYSCOMMAND, SC_MINIMIZE, 0);
end;
end;
procedure TForm001.FormRestoreTimerTimer(Sender: TObject);
begin
if Form001.AlphaBlendValue < 220 then
begin
Form001.AlphaBlendValue := Form001.AlphaBlendValue + 10;
end
else
begin
Form001.FormRestoreTimer.Enabled := false;
end;
end;
end.
If I do the following
Application.MainFormOnTaskbar := false;
the form is totally invissible. I think there should be one bug. But I am unable to find it.

Related

Allow multiple MDI Parent Forms on same Application

I'm trying follow what was suggested in this answer, changing this part of Vcl.Forms.pas:
procedure TCustomForm.CreateWindowHandle(const Params: TCreateParams);
var
CreateStruct: TMDICreateStruct;
NewParams: TCreateParams;
begin
if (FormStyle = fsMDIChild) and not (csDesigning in ComponentState) then
begin
{if (Application.MainForm = nil) or
(Application.MainForm.ClientHandle = 0) then
raise EInvalidOperation.Create(SNoMDIForm);}
with CreateStruct do
begin
szClass := Params.WinClassName;
szTitle := Params.Caption;
hOwner := THandle(HInstance);
X := Params.X;
Y := Params.Y;
cX := Params.Width;
cY := Params.Height;
style := Params.Style;
lParam := THandle(Params.Param);
end;
WindowHandle := SendStructMessage(Application.MainForm.ClientHandle,
WM_MDICREATE, 0, CreateStruct);
Include(FFormState, fsCreatedMDIChild);
end
else
//...
but still comes the error saying that "no MDI Form is active"
What more is need be made to this suggestion works? Thanks in advance.
Code of test with Forms:
procedure TForm1.Button1Click(Sender: TObject);
begin
Form2 := TForm2.Create(Self); // MDIForm
Form2.Show;
Form3 := TForm3.Create(Form2); // MDIChild
Form3.Show;
end;
After the help of comments above (mainly of #Remy Lebeau) follows this code working. I hope that can help someone ahead :-).
// MainForm
type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
uses
Unit2;
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
begin
Form2 := TForm2.Create(Application);
Form2.Show;
end;
// MDIForm
type
TForm2 = class(TForm)
MainMenu1: TMainMenu;
O1: TMenuItem;
procedure O1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form2: TForm2;
implementation
uses
Unit3;
{$R *.dfm}
procedure TForm2.O1Click(Sender: TObject);
begin
Form3 := TForm3.Create(Self);
Form3.Show;
end;
// MDIChild
type
TForm3 = class(TForm)
procedure FormClose(Sender: TObject; var Action: TCloseAction);
private
{ Private declarations }
procedure CreateWindowHandle(const Params: TCreateParams); override;
procedure DestroyWindowHandle; override;
protected
FMDIClientHandle: HWND;
public
{ Public declarations }
end;
var
Form3: TForm3;
implementation
uses
Unit1;
{$R *.dfm}
procedure TForm3.CreateWindowHandle(const Params: TCreateParams);
var
CreateStruct: TMDICreateStruct;
function GetMDIClientHandle: HWND;
begin
Result := 0;
if (Owner is TForm) then
Result := TForm(Owner).ClientHandle;
if (Result = 0) and (Application.MainForm <> nil) then
Result := Application.MainForm.ClientHandle;
if Result = 0 then
raise EInvalidOperation.Create('No Parent MDI Form');
end;
begin
if (FormStyle = fsMDIChild) and not (csDesigning in ComponentState) then
begin
FMDIClientHandle := GetMDIClientHandle;
with CreateStruct do
begin
szClass := Params.WinClassName;
szTitle := Params.Caption;
hOwner := HInstance;
X := Params.X;
Y := Params.Y;
cX := Params.Width;
cY := Params.Height;
style := Params.Style;
lParam := Longint(Params.Param);
end;
WindowHandle := SendMessage(FMDIClientHandle, WM_MDICREATE, 0, LongInt(#CreateStruct));
Include(FFormState, fsCreatedMDIChild);
end
else
begin
FMDIClientHandle := 0;
inherited CreateWindowHandle(Params);
Exclude(FFormState, fsCreatedMDIChild);
end;
end;
procedure TForm3.DestroyWindowHandle;
begin
if fsCreatedMDIChild in FFormState then
SendMessage(FMDIClientHandle, WM_MDIDESTROY, Handle, 0)
else
inherited DestroyWindowHandle;
FMDIClientHandle := 0;
end;
procedure TForm3.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Action := CaFree;
end;

Can not press enter in more than one twebbrowser

I have seen the below msghandler code in several places now as the solution to not being able to press Enter in a twebbrowser. This solution does work as long as you're only dealing with one twebbrowser. I've provided a complete unit here for discussion. If you take two twebbrowsers and make one of them the "active" browser (see code) and navigate them each to a site for example that has a username, password and button you can enter the data in the "active" browser and press Enter successfully. If you try to use the non "active" browser not only can you not press Enter but use of tab fails as well. Whichever browser you press Enter in first is the one that will continue to work so it seems to have nothing to do with order of creation of the browsers.
How do I make my additional browsers function?
unit Main_Form;
interface
uses
Winapi.Windows, Winapi.Messages, Vcl.Controls, Vcl.Forms,
ActiveX, Vcl.OleCtrls, SHDocVw, System.Classes, Vcl.StdCtrls;
type
TForm1 = class(TForm)
NavigateBrowsers: TButton;
WebBrowser1: TWebBrowser;
WebBrowser2: TWebBrowser;
MakeBrowser1Active: TButton;
MakeBrowser2Active: TButton;
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure FormDeactivate(Sender: TObject);
procedure NavigateBrowsersClick(Sender: TObject);
procedure MakeBrowser1ActiveClick(Sender: TObject);
procedure MakeBrowser2ActiveClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
procedure MsgHandler(var Msg: TMsg; var Handled: Boolean);
end;
var
Form1: TForm1;
ActiveBrowser: TWebBrowser;
FOleInPlaceActiveObject: IOleInPlaceActiveObject;
SaveMessageHandler: TMessageEvent;
implementation
{$R *.dfm}
procedure TForm1.MakeBrowser1ActiveClick(Sender: TObject);
begin
ActiveBrowser := WebBrowser1;
end;
procedure TForm1.MakeBrowser2ActiveClick(Sender: TObject);
begin
ActiveBrowser := WebBrowser2;
end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Application.OnMessage := SaveMessageHandler;
FOleInPlaceActiveObject := nil;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
//Handle messages
SaveMessageHandler := Application.OnMessage;
Application.OnMessage := MsgHandler;
end;
procedure TForm1.FormDeactivate(Sender: TObject);
begin
Application.OnMessage := SaveMessageHandler;
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
FOleInPlaceActiveObject := nil;
end;
procedure TForm1.NavigateBrowsersClick(Sender: TObject);
begin
WebBrowser1.Navigate(''); //supply own
WebBrowser2.Navigate(''); //supply own
end;
procedure TForm1.MsgHandler(var Msg: TMsg; var Handled: Boolean);
const
StdKeys = [VK_BACK, VK_UP, VK_DOWN, VK_LEFT, VK_RIGHT];
var
IOIPAO: IOleInPlaceActiveObject;
Dispatch: IDispatch;
begin
//Exit if webbrowser object is nil
if ActiveBrowser = nil then
begin
Handled := False;
Exit;
end;
Handled:=(IsDialogMessage(ActiveBrowser.Handle, Msg) = True);
if (Handled) and (not ActiveBrowser.Busy) then
begin
if FOleInPlaceActiveObject = nil then
begin
Dispatch := ActiveBrowser.Application;
if Dispatch <>nil then
begin
Dispatch.QueryInterface(IOleInPlaceActiveObject, iOIPAO);
if iOIPAO <>nil then
FOleInPlaceActiveObject := iOIPAO;
end;
end;
if FOleInPlaceActiveObject <>nil then
if ((Msg.message = WM_KEYDOWN) or (Msg.message = WM_KEYUP)) and
(Msg.wParam in StdKeys) then
//nothing - do not pass on StdKeys
else
FOleInPlaceActiveObject.TranslateAccelerator(Msg);
end;
end;
initialization
OleInitialize(nil);
finalization
OleUninitialize;
end.
I faced the same problem as you and I use a similar message handler, FOleInPlaceActiveObject is not really needed:
procedure TForm1.MsgHandler(var Msg: TMsg; var Handled: Boolean);
const
StdKeys = [VK_BACK, VK_UP, VK_DOWN, VK_LEFT, VK_RIGHT];
var
IOIPAO: IOleInPlaceActiveObject;
begin
try
if Assigned(ActiveBrowser) then
begin
Handled:=(IsDialogMessage(ActiveBrowser.Handle, Msg) = True);
if Handled then
begin
if ((Msg.message = WM_KEYDOWN) or (Msg.message = WM_KEYUP)) and (Msg.wParam in StdKeys) then
begin
//nothing - do not pass on Backspace, Left, Right, Up, Down arrows
end
else
begin
IOIPAO := (ActiveBrowser.Application as IOleInPlaceActiveObject);
if Assigned(IOIPAO)then
IOIPAO.TranslateAccelerator(Msg)
end;
end;
end;
except
Handled := False;
end;
end;
After days of searching for an answer it appears I have found something that works the same day I posted the question here. Go figure! For everyone's benefit, here is what worked.
All I had to do was assign the browser as the active control when either the user changed tabs or at the time of new tab creation. The reason for the count check in the pagecontrolchange procedure is to keep from getting a list index out of bounds on initial tab creation at startup. I do realize I probably need to change my ObjectLists over to Generics, ;)
procedure TForm1.PageControl1Change(Sender: TObject);
begin
if PageControl1.PageCount = MyBrowsersObjectList.Count then // Not adding a page
begin
ActiveBrowser := MyBrowsersObjectList[PageControl1.ActivePageIndex] as TWebBrowser;
ActiveControl := ActiveBrowser;
end;
end;
procedure TForm1.CreateBrowserTab(APage: TAdvOfficePage; NavigateTo: String);
begin
APage.Caption := 'Loading...';
ActiveBrowser := TWebBrowser.Create(nil);
MyBrowsersObjectList.Add(ActiveBrowser);
TControl(ActiveBrowser).Parent := APage;
ActiveBrowser.Align := alClient;
ActiveBrowser.RegisterAsBrowser := True;
ActiveBrowser.Tag := BrowserTabs.ActivePageIndex;
ActiveBrowser.Navigate(NavigateTo);
ActiveControl := ActiveBrowser;
end;

Minimize Delphi Form to System Tray using Timer

I am a Delphi learner. I am looking for solutions so that Delphi MainForm should be minimized to the System Tray instead of Taskbar using Timer. I have implemented the following codes. Here everything is fine except one. After minimizing the Form, it goes to "SystemTray" but also available in "TaskBar. For my application, the "AlphaBlend" property of "Form001" is true and "AlphaBlendValue" is "0".
unit KoushikHalder001;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.Buttons, Vcl.ExtCtrls, Vcl.Imaging.pngimage,
Vcl.AppEvnts, Vcl.ImgList, Vcl.Menus;
type
TForm001 = class(TForm)
Edit001: TEdit;
Background: TImage;
BitBtn001: TBitBtn;
BitBtn002: TBitBtn;
FadeInTimer: TTimer;
FadeOutTimer: TTimer;
FormMinimizeTimer: TTimer;
FormRestoreTimer: TTimer;
TrayIcon: TTrayIcon;
PopupMenu: TPopupMenu;
ImageList: TImageList;
ApplicationEvents: TApplicationEvents;
Form001Close: TMenuItem;
Form001Hide: TMenuItem;
Form001Show: TMenuItem;
Form002Close: TMenuItem;
Form002Hide: TMenuItem;
Form002Show: TMenuItem;
N01: TMenuItem;
N02: TMenuItem;
N03: TMenuItem;
N04: TMenuItem;
N05: TMenuItem;
N06: TMenuItem;
N07: TMenuItem;
N08: TMenuItem;
N09: TMenuItem;
N10: TMenuItem;
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
procedure FormHide(Sender: TObject);
procedure FormShow(Sender: TObject);
procedure BitBtn001Click(Sender: TObject);
procedure BitBtn002Click(Sender: TObject);
procedure FadeInTimerTimer(Sender: TObject);
procedure FadeOutTimerTimer(Sender: TObject);
procedure FormMinimizeTimerTimer(Sender: TObject);
procedure FormRestoreTimerTimer(Sender: TObject);
procedure ApplicationEventsMinimize(Sender: TObject);
procedure TrayIconDblClick(Sender: TObject);
procedure Form001CloseClick(Sender: TObject);
procedure Form001HideClick(Sender: TObject);
procedure Form001ShowClick(Sender: TObject);
procedure Form002CloseClick(Sender: TObject);
procedure Form002HideClick(Sender: TObject);
procedure Form002ShowClick(Sender: TObject);
private
{ Private declarations }
CrossButtonClick: Boolean;
procedure WMNCHitTest(var Msg: TWMNCHitTest) ; message WM_NCHitTest;
procedure WMSysCommand(var Msg: TWMSysCommand) ; message WM_SysCommand;
public
{ Public declarations }
end;
var
Form001: TForm001;
implementation
{$R *.dfm}
uses KoushikHalder002;
procedure TForm001.WMNCHitTest(var Msg: TWMNCHitTest);
begin
inherited;
if ControlAtPos(ScreenToClient(Msg.Pos), True, True, True)= nil
then
begin
if Msg.Result=htClient then Msg.Result := htCaption;
end;
end;
procedure TForm001.WMSysCommand(var Msg: TWMSysCommand);
begin
case Msg.CmdType of
SC_MINIMIZE:
begin
if Form001.AlphaBlendValue > 0 then
begin
Form001.FormMinimizeTimer.Enabled := true;
Exit;
end;
end;
SC_RESTORE:
begin
if Form001.AlphaBlendValue < 220 then
begin
Form001.FormRestoreTimer.Enabled := True;
end;
end;
end;
inherited;
end;
procedure TForm001.ApplicationEventsMinimize(Sender: TObject);
begin
Form001.FormMinimizeTimer.Enabled := true;
TrayIcon.Visible := True;
TrayIcon.Animate := True;
TrayIcon.ShowBalloonHint;
end;
procedure TForm001.BitBtn001Click(Sender: TObject);
begin
if Form002.WindowState = wsMinimized then
begin
Form002.Perform(WM_SYSCOMMAND, SC_RESTORE, 0);
end
else
Form002.show;
end;
procedure TForm001.BitBtn002Click(Sender: TObject);
begin
Form002.FadeOutTimer.Enabled := true;
Form001.FadeOutTimer.Enabled := true;
end;
procedure TForm001.Form001CloseClick(Sender: TObject);
begin
Form002.FadeOutTimer.Enabled := true;
Form001.FadeOutTimer.Enabled := true;
end;
procedure TForm001.Form001HideClick(Sender: TObject);
begin
Form001.FormMinimizeTimer.Enabled := true;
end;
procedure TForm001.Form001ShowClick(Sender: TObject);
begin
if Form001.WindowState = wsMinimized then
begin
Form001.Perform(WM_SYSCOMMAND, SC_RESTORE, 0);
end
else
Form001.show;
end;
procedure TForm001.Form002CloseClick(Sender: TObject);
begin
Form002.FadeOutTimer.Enabled := true;
end;
procedure TForm001.Form002HideClick(Sender: TObject);
begin
Form002.FormMinimizeTimer.Enabled := true;
end;
procedure TForm001.Form002ShowClick(Sender: TObject);
begin
if Form002.WindowState = wsMinimized then
begin
Form002.Perform(WM_SYSCOMMAND, SC_RESTORE, 0);
end
else
Form002.show;
end;
procedure TForm001.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Form001.FadeOutTimer.Enabled := true;
end;
procedure TForm001.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
if CrossButtonClick = true
then
begin
CanClose := true;
Exit;
end;
CanClose := false;
Form001.FadeOutTimer.Enabled := true;
end;
procedure TForm001.FormHide(Sender: TObject);
begin
Form001.FadeOutTimer.Enabled := true;
end;
procedure TForm001.FormShow(Sender: TObject);
begin
Form001.FadeInTimer.Enabled := true;
end;
procedure TForm001.TrayIconDblClick(Sender: TObject);
begin
Form001.FormRestoreTimer.Enabled := true;
TrayIcon.Visible := False;
WindowState := wsNormal;
Application.BringToFront();
end;
procedure TForm001.FadeInTimerTimer(Sender: TObject);
begin
if Form001.AlphaBlendValue >= 220
then
begin
Form001.FadeInTimer.Enabled := false;
end
else
begin
Form001.AlphaBlendValue := Form001.AlphaBlendValue + 10;
CrossButtonClick := false;
end;
end;
procedure TForm001.FadeOutTimerTimer(Sender: TObject);
begin
if Form001.AlphaBlendValue <= 0
then
begin
Form001.FadeOutTimer.Enabled := false;
CrossButtonClick := true;
Self.Close;
end
else
begin
Form001.AlphaBlendValue := Form001.AlphaBlendValue - 10;
CrossButtonClick := true;
end;
end;
procedure TForm001.FormMinimizeTimerTimer(Sender: TObject);
begin
if Form001.AlphaBlendValue > 0 then
begin
Form001.AlphaBlendValue := Form001.AlphaBlendValue - 10;
end
else
begin
Form001.FormMinimizeTimer.Enabled := false;
Perform(WM_SYSCOMMAND, SC_MINIMIZE, 0);
end;
end;
procedure TForm001.FormRestoreTimerTimer(Sender: TObject);
begin
if Form001.AlphaBlendValue < 220 then
begin
Form001.AlphaBlendValue := Form001.AlphaBlendValue + 10;
end
else
begin
Form001.FormRestoreTimer.Enabled := false;
end;
end;
end.
If I do the following
Application.MainFormOnTaskbar := false;
when the application runs the form is totally invissible. I think there should be one bug. But I am unable to find it. Please help me.
If you want to remove the form from the taskbar then you need to hide it rather than minimize it. Simply call Hide when you have finished fading out the form.
With regards removing the taskbar button, it doesn't actually matter how you configure MainFormOnTaskbar. So, what you should do is set MainFormOnTaskbar as you prefer for the application in its normal mode of operation. That property is not pertinent to whether or not the taskbar button shows.
You should HIDE application. Here is a procedure to Hide and Restore application from TaskBar and Desktop. If you have more than one form visible in your Application uncomment Application.Minimize and Application.Restore:
procedure TMainForm.ChangeApplicationVisibility;
begin
if Visible then
begin
Hide;
// Application.Minimize;
ShowWindow(Application.Handle,SW_Hide);
end
else
begin
Show;
// Application.Restore;
Application.BringToFront;
end;
end;

How to take snapshot and save to JPEG from webcam using DSPack?

Using DSPack, Delphi XE I need to take a snapshot from a webcam and allow a preview before which the user is allowed to save to JPEG file. How can this be done (code)?
Maybe this will work, but I have not tested it. You should give it a try.
unit main;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, DSPack, DSUtil, DirectShow9;
type
TMainForm = class(TForm)
CaptureGraph: TFilterGraph;
VideoWindow: TVideoWindow;
ListBox1: TListBox;
VideoSourceFilter: TFilter;
StartButton: TButton;
StopButton: TButton;
Label1: TLabel;
ListBox2: TListBox;
Label3: TLabel;
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure ListBox1Click(Sender: TObject);
procedure StartButtonClick(Sender: TObject);
procedure StopButtonClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
MainForm: TMainForm;
VideoDevice: TSysDevEnum;
VideoMediaTypes: TEnumMediaType;
implementation
{$R *.dfm}
{ TMainForm }
procedure TMainForm.FormCreate(Sender: TObject);
var i: integer;
begin
VideoDevice := TSysDevEnum.Create(CLSID_VideoInputDeviceCategory);
for i := 0 to VideoDevice.CountFilters - 1 do
ListBox1.Items.Add(VideoDevice.Filters[i].FriendlyName);
VideoMediaTypes := TEnumMediaType.Create;
end;
procedure TMainForm.FormDestroy(Sender: TObject);
begin
VideoDevice.Free;
VideoMediaTypes.Free;
end;
// Selecting of the video source
procedure TMainForm.ListBox1Click(Sender: TObject);
var
PinList: TPinList;
i: integer;
begin
VideoDevice.SelectGUIDCategory(CLSID_VideoInputDeviceCategory);
if ListBox1.ItemIndex <> -1 then
begin
// Set the device which we work with
VideoSourceFilter.BaseFilter.Moniker := VideoDevice.GetMoniker(ListBox1.ItemIndex);
VideoSourceFilter.FilterGraph := CaptureGraph;
CaptureGraph.Active := true;
PinList := TPinList.Create(VideoSourceFilter as IBaseFilter);
ListBox2.Clear;
VideoMediaTypes.Assign(PinList.First);
// Adding permission to ListBox2, which supports device
for i := 0 to VideoMediaTypes.Count - 1 do
ListBox2.Items.Add(VideoMediaTypes.MediaDescription[i]);
CaptureGraph.Active := false;
PinList.Free;
StartButton.Enabled := true;
end;
end;
procedure TMainForm.StartButtonClick(Sender: TObject);
var
PinList: TPinList;
begin
// Activating graph filter, at this stage the source filter is added to the graph
CaptureGraph.Active := true;
// The configuration of the output device
if VideoSourceFilter.FilterGraph <> nil then
begin
PinList := TPinList.Create(VideoSourceFilter as IBaseFilter);
if ListBox2.ItemIndex <> -1 then
with (PinList.First as IAMStreamConfig) do
SetFormat(VideoMediaTypes.Items[ListBox2.ItemIndex].AMMediaType^);
PinList.Free;
end;
// now render streams
with CaptureGraph as IcaptureGraphBuilder2 do
begin
// Hooking up a preview video (VideoWindow)
if VideoSourceFilter.BaseFilter.DataLength > 0 then
RenderStream(#PIN_CATEGORY_PREVIEW, nil, VideoSourceFilter as IBaseFilter,
nil , VideoWindow as IBaseFilter);
end;
// Launch video
CaptureGraph.Play;
StopButton.Enabled := true;
StartButton.Enabled := false;
ListBox2.Enabled := false;
ListBox1.Enabled := false;
end;
// Stop video
procedure TMainForm.StopButtonClick(Sender: TObject);
begin
StopButton.Enabled := false;
StartButton.Enabled := true;
CaptureGraph.Stop;
CaptureGraph.Active := False;
ListBox2.Enabled := true;
ListBox1.Enabled := true;
end;
end.

delphi component to animate show/hide controls during runtime

In Delphi I show/hide controls during runtime and it does not look good as controls suddenly appear or disappear , so any one know a component that can do the show/hide (using visible property) but with some sort of animation ?
thanks
Give it a go with AnimateWindow. Only for WinControls, well, it doesn't look stunning anyway:
procedure TForm1.Button1Click(Sender: TObject);
begin
if Button2.Visible then
AnimateWindow(Button2.Handle, 250, AW_HIDE or AW_VER_NEGATIVE or AW_SLIDE)
else
AnimateWindow(Button2.Handle, 250, AW_VER_POSITIVE or AW_SLIDE);
Button2.Visible := not Button2.Visible; // synch with VCL
end;
edit: A threaded version to hide show multiple controls simultaneously:
type
TForm1 = class(TForm)
..
private
procedure AnimateControls(Show: Boolean; Controls: array of TWinControl);
procedure OnAnimateEnd(Sender: TObject);
public
end;
implementation
..
type
TAnimateThr = class(TThread)
protected
procedure Execute; override;
public
FHWnd: HWND;
FShow: Boolean;
constructor Create(Handle: HWND; Show: Boolean);
end;
{ TAnimateThr }
constructor TAnimateThr.Create(Handle: HWND; Show: Boolean);
begin
FHWnd := Handle;
FShow := Show;
FreeOnTerminate := True;
inherited Create(True);
end;
procedure TAnimateThr.Execute;
begin
if FShow then
AnimateWindow(FHWnd, 250, AW_VER_POSITIVE or AW_SLIDE)
else
AnimateWindow(FHWnd, 250, AW_HIDE or AW_VER_NEGATIVE or AW_SLIDE);
end;
{ Form1 }
procedure TForm1.OnAnimateEnd(Sender: TObject);
begin
FindControl(TAnimateThr(Sender).FHWnd).Visible := TAnimateThr(Sender).FShow;
end;
procedure TForm1.AnimateControls(Show: Boolean; Controls: array of TWinControl);
var
i: Integer;
begin
for i := Low(Controls) to High(Controls) do
with TAnimateThr.Create(Controls[i].Handle, Show) do begin
OnTerminate := OnAnimateEnd;
Resume;
end;
end;
procedure TForm1.Button5Click(Sender: TObject);
begin
AnimateControls(not Button1.Visible,
[Button1, Button2, Button3, Edit1, CheckBox1]);
end;
 

Resources