?
Solved

Docking form in desktop

Posted on 2005-04-30
11
Medium Priority
?
801 Views
Last Modified: 2010-04-05
Hi all..,

I'm going to make program whose form can be docking in the desktop area, is it posible to make it? What I want to do is to make my form act as just like windows taskbar done by change the windows desktop area.

Thanks.
sirro
0
Comment
Question by:sirro
  • 6
  • 4
11 Comments
 
LVL 16

Expert Comment

by:CodedK
ID: 13900236
Listening :P
0
 
LVL 34

Expert Comment

by:Slick812
ID: 13901899
hello  sirro , , what you are asking is not so easy, I would use the "App Bar" window that the system API can provide, you can see some code for this in this EE question -


http://www.experts-exchange.com/Programming/Programming_Languages/Delphi/Q_20686630.html

ask questions if you need more information
0
 

Author Comment

by:sirro
ID: 13908356

thank you.., finally someone give me soulution :)

Hello slick .., I've try your code as you've suggested, but there one thing that I don't know (doesn't make it works), what is the meaning og "MainMenu1" on the FormCreate procedure?
is it a component or  ..?

Thanks
0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
LVL 34

Expert Comment

by:Slick812
ID: 13911690
????

this is a very much used "Main Menu" on a Standard Delphi Form, which will default to the component name of  "MainMenu1"
seems like you would have seen a  "MainMenu1" before
0
 
LVL 34

Expert Comment

by:Slick812
ID: 13911719
The menu is all I have to do user interaction on the example form for the  App Bar program, just for an example to do this, and because a main menu will be thin. . . but you can leave off the main menu and place any component or display you like on your form, of course you will need to size your form for the components
0
 

Author Comment

by:sirro
ID: 13924493
Hi slick ...,
I've copy and paste the code of yours solution, and add TMainmenu on the form (whose name is MainMenu1). But the result is something that not same with what I meant, perhaps I'm wrong on transferring your code..., could you give other simple example which show a form application which is laid on the desktop area (left,right, .. whatever=ABE_TOP ..etc).

Thanks
0
 
LVL 34

Expert Comment

by:Slick812
ID: 13929606
I do NOT understand your last comment. . . Of course it does not look like whatever you may want, leave off the Main Menu and make it however you want so it looks like whatever you want, that was just example code
0
 
LVL 34

Expert Comment

by:Slick812
ID: 13945818
here is an App Bar program code, you did not give ANY info about what you did not find suitable about the other App Bar program, so in this one I have 3 TBitBtn buttons, each of these buttons are 26 width and 26 height, with a small glyph on each one.
I have included code in this to change the position of the app bar in the  SetBarDataRect  procedure, , these is code to change the 3 button positions for horizontal and vertical app bars in the SetButtonPos procedure. This code will do an App Bar on the right of the desktop, but you can just change one setting in the Form's OnCreate event, the

BarData1.uEdge := ABE_RIGHT;

to ABE_LEFT, ABE_TOP, ABE_BOTTOM, and it will change the position and buttons for that uEdge setting,
You must set RequiredWidth and RequiredHeight in your OnCreate event to the sizes you require for your controls to show, 28 in this program, because the 3 buttons are 26x26 .



unit appBar1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  Menus, ShellApi, StdCtrls, Buttons;

const
MsgNotify = WM_USER+216;

type
  TForm1 = class(TForm)
    BitBtn_Top: TBitBtn;
    BitBtn_Mid: TBitBtn;
    BitBtn_Bottom: TBitBtn;
    procedure FormCreate(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure BitBtn_TopClick(Sender: TObject);
    procedure BitBtn_MidClick(Sender: TObject);
  private
    { Private declarations }
    RequiredWidth, RequiredHeight: Integer;
    BarData1: TAppBarData;
    procedure SetBarDataRect;
    procedure SetButtonPos;
    procedure NotifyMess(var Msg : TMessage); message MsgNotify;
    procedure ActivateMess(var Msg : TMessage); message WM_ACTIVATE;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;


implementation

{$R *.DFM}

procedure TForm1.SetBarDataRect;
begin
case BarData1.uEdge of
  ABE_LEFT: BarData1.rc := Rect(0,0,RequiredWidth,Screen.Height);
  ABE_TOP: BarData1.rc := Rect(0,0,Screen.Width,RequiredHeight);
  ABE_RIGHT: BarData1.rc := Rect(Screen.Width-RequiredWidth,0,Screen.Width,Screen.Height);
  ABE_BOTTOM: BarData1.rc := Rect(0,Screen.Height-RequiredHeight,Screen.Width,Screen.Height);
  end;
end;

procedure TForm1.SetButtonPos;
begin
case BarData1.uEdge of
  ABE_LEFT, ABE_RIGHT: begin
    BitBtn_Top.Left := 1;
    BitBtn_Top.Top := 10;
    BitBtn_Mid.Left := 1;
    BitBtn_Mid.Top := 20+BitBtn_Top.Height;
    BitBtn_Bottom.Left := 1;
    BitBtn_Bottom.Top := 30+BitBtn_Top.Height+BitBtn_Mid.Height;
    end;

  ABE_TOP, ABE_BOTTOM: begin
    BitBtn_Top.Left := 10;
    BitBtn_Top.Top := 1;
    BitBtn_Mid.Left := 20+BitBtn_Top.Width;
    BitBtn_Mid.Top := 1;
    BitBtn_Bottom.Left := 30+BitBtn_Top.Width+BitBtn_Mid.Width;
    BitBtn_Bottom.Top := 1;
    end;
  end;
end;

procedure TForm1.ActivateMess(var Msg : TMessage);
begin
inherited;
SHAppBarMessage(ABM_ACTIVATE, BarData1);
end;

procedure TForm1.NotifyMess(var Msg : TMessage);
var
State: Cardinal;
begin
if Msg.WParam = ABN_POSCHANGED then // some app bar has changed
  begin
  SetBarDataRect; // set rect to ask for desktop area

  ShAppBarMessage(ABM_QUERYPOS, BarData1); // gets desktop app bar area
 
  ShAppBarMessage(ABM_SETPOS, BarData1); // asks for the Rectangle app bar area
  SetBounds(BarData1.rc.Left, BarData1.rc.Top, BarData1.rc.Right-BarData1.rc.Left,
            BarData1.rc.Bottom - BarData1.rc.Top);// set Form position to Rect area
  end;
if Msg.WParam = ABN_STATECHANGE then // Top Most has changed, maybe for screen saver
  begin
  State := SHAppBarMessage(ABM_GETSTATE, BarData1);
  if (State or ABS_ALWAYSONTOP) = State then
  SetWindowPos(Handle,HWND_TOPMOST,0, 0, 0,
               0, SWP_NOMOVE or SWP_NOSIZE or SWP_NOACTIVATE)
  else
  SetWindowPos(Handle,HWND_BOTTOM,0, 0, 0,
               0, SWP_NOMOVE or SWP_NOSIZE or SWP_NOACTIVATE);
  end;
if Msg.Wparam = ABN_FULLSCREENAPP then
  begin
  if Msg.LParam <> 0 then
    SetWindowPos(Handle,HWND_BOTTOM,0, 0, 0,
               0, SWP_NOMOVE or SWP_NOSIZE or SWP_NOACTIVATE)
    else
    begin
    State := SHAppBarMessage(ABM_GETSTATE, BarData1);
    if (State or ABS_ALWAYSONTOP) = State then
    SetWindowPos(Handle,HWND_TOPMOST,0, 0, 0,
               0, SWP_NOMOVE or SWP_NOSIZE or SWP_NOACTIVATE);
    end;
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
RequiredWidth := 28;
{my 3 buttons are all 26 width and 26 height, so I have a Required Width and
 Required Height of 28 pixels}
RequiredHeight := 28;
BorderStyle := bsNone; // set boder Style to None

BarData1.cbSize := SizeOf (TAppBarData);
BarData1.uEdge := ABE_RIGHT; // you must set the uEdge before you call SetBarDataRect
//BarData1.uEdge := ABE_TOP; // you can change to a horizontal app bar or any other uEdge

SetBarDataRect; { will use the uEdge to set the BarData1.rc for Left, Top, Right and Bottom
  using the RequiredWidth or RequiredHeight for the placement}

SetButtonPos; {SetButtonPos will change the button positions for horizontal and
 vertical App Bar position}

BarData1.lParam := 0;
BarData1.uCallbackMessage := MsgNotify;
BarData1.hWnd := Handle;

ShAppBarMessage(ABM_NEW, BarData1); // tells system of your app bar
ShAppBarMessage(ABM_QUERYPOS, BarData1); // gets the availible desktop app bar space

ShAppBarMessage(ABM_SETPOS, BarData1); // asks for system edge area for new app bar
SetBounds(BarData1.rc.Left, BarData1.rc.Top, BarData1.rc.Right-BarData1.rc.Left,
          BarData1.rc.Bottom - BarData1.rc.Top); {you need to set your Form position
          to the area the system has allotted for your new app bar}
SetWindowPos(Handle,HWND_TOPMOST,0, 0, 0,
               0, SWP_NOMOVE or SWP_NOSIZE or SWP_NOACTIVATE);
// for the most part you'll need your app bar On Top with HWND_TOPMOST above

SetWindowLong(Application.Handle,GWL_EXSTYLE, WS_EX_TOOLWINDOW);
// for the most part you will NOT need a button in the task bar, so I remove it
// with SetWindowLong  for the Application window
end;


procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
ShAppBarMessage(ABM_REMOVE, BarData1);
end;

procedure TForm1.BitBtn_TopClick(Sender: TObject);
begin
// Bit Button Click
Showmessage('Top Button Click');
end;

procedure TForm1.BitBtn_MidClick(Sender: TObject);
begin
// Bit Button Click
Close;
end;

end.

= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =

matbe this will help? ? ? ?
0
 

Author Comment

by:sirro
ID: 13956644
Hello Slick ...,
thanks for your code, I really appreciate it :)

Oke then, I've tried your code, and the result is just like this:
in right side of  desktop area, there's a space about 26 or 28 pixel, and all maximzed program which is running becoming shrink fullfilled the rest of the space(I mean the 26/28 pixel area on the right), and that is just exactly what I mean, but the problem is, the form of my application is not fullfilled the 26/28 pixel area, can you give me explanation how to make my application fullfilled the area.

thanks
0
 
LVL 34

Accepted Solution

by:
Slick812 earned 360 total points
ID: 13961241
OK, I test this in Win XP and in that system the code above did not get the correct Position, in XP I fould that it expects (demands) a Top level window for the App Bar (seems like a good way to go). .  so I had to change the Form1 (app bar form) to a Top level window, , , a technical note, The Delphi methods of Application and Forms as children does not lend it's self to this type of arrangement (Form as a Top level window) very well, but since the app bar is a stay on top it seems to work Ok for this

I had to add a  CreateParams(  ) to the Form to get it to go -


  protected
  procedure CreateParams (var Params : TCreateParams); override;
  public
    { Public declarations }
  end;


procedure TForm1.CreateParams(var Params: TCreateParams);
begin
inherited CreateParams(Params);
Params.WndParent := 0;
Params.ExStyle := WS_EX_TOOLWINDOW or WS_EX_TOPMOST;
end;

I think that was all I added, and it seems to work
0
 

Author Comment

by:sirro
ID: 13994216
It works!!!
Well then .. thanks for your solution Slick.

Sirro


0

Featured Post

Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

The uses clause is one of those things that just tends to grow and grow. Most of the time this is in the main form, as it's from this form that all others are called. If you have a big application (including many forms), the uses clause in the in…
Creating an auto free TStringList The TStringList is a basic and frequently used object in Delphi. On many occasions, you may want to create a temporary list, process some items in the list and be done with the list. In such cases, you have to…
this video summaries big data hadoop online training demo (http://onlineitguru.com/big-data-hadoop-online-training-placement.html) , and covers basics in big data hadoop .
Screencast - Getting to Know the Pipeline
Suggested Courses

840 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question