我想写个程序就像Windows 任务栏一样,一直是占用桌面的一个区域,比如在桌面左边分出50个像素的宽度来显示我的程序,就算Windows的其他程序最大化也不会占用到我这个50个像素,当然也不会和我的程序互相遮挡住。
请问有什么方法?谢谢

解决方案 »

  1.   

    TO FormStyle设成fsStayOnTop就行了:是肯定不行的,这不是明显会遮挡住其他程序嘛。呵呵估计是我没描述清楚。
    我是限制所有程序的最大化显示区域,比如IE,比如资源管理器..等等,让所有程序的最大化都固定在桌面的某个区域里。Windows 任务栏是最能体现这个功能的实例了,最大化都不会遮挡住任务栏吧,任务栏不会遮挡桌面图标吧,我就要写个程序同样在电脑屏幕的右边或者桌边实现这个功能。
      

  2.   

    我觉得如果要控制其它程序的调整大小过程,直接的程序是不行的,估计得对Windows的函数进行修改了,因为“最大化”类的函数是从windows的函数调用返回的数据结果(桌面的宽高等信息)。或者(如果有可能的话),对这类函数调用进行消息截获处理之后再将修改后的消息发布到相应的程序。
    这两种办法我觉得都是比较困难的。
      

  3.   

    很困难啊。学习。估计要修改windows的系统函数
      

  4.   

    用SHAppBarMessage这个API
    给你找了个代码你看看吧
      unit   AppBars;
        
      interface   
        
      uses   
          Windows,   Messages,   SysUtils,   Classes,   Graphics,   Controls,   Forms,   Dialogs,   
          ShellAPI,   StdCtrls,   Buttons,   ExtCtrls,   Menus;   
        
      type   
          TAppBarEdge   =   (abeTop,   abeBottom,   abeLeft,   abeRight);   
        
          EAppBarError   =   class(Exception);   
        
          TAppBar   =   class(TForm)   
              PopupMenu1:   TPopupMenu;   
              Top1:   TMenuItem;   
              Bottom1:   TMenuItem;   
              Left1:   TMenuItem;   
              Right1:   TMenuItem;   
              SpeedButton1:   TSpeedButton;   
              SpeedButton2:   TSpeedButton;   
              SpeedButton3:   TSpeedButton;
              SpeedButton4:   TSpeedButton;   
              SpeedButton5:   TSpeedButton;   
              OpenDialog1:   TOpenDialog;   
              N1:   TMenuItem;   
              Exit1:   TMenuItem;   
              procedure   Top1Click(Sender:   TObject);   
              procedure   SpeedButton1Click(Sender:   TObject);   
              procedure   MoveButtons;   
              procedure   SpeedButton2Click(Sender:   TObject);   
              procedure   SpeedButton4Click(Sender:   TObject);   
              procedure   SpeedButton3Click(Sender:   TObject);   
              procedure   SpeedButton5Click(Sender:   TObject);   
              procedure   Exit1Click(Sender:   TObject);   
      private   
              FABD:   TAppBarData;   
              FEdge:   TAppBarEdge;   
              FTopMost:   Boolean;   
              FLastChecked:   TMenuItem;   
              procedure   WMActivate(var   M:   TMessage);   message   WM_ACTIVATE;   
              procedure   WMWindowPosChanged(var   M:   TMessage);   message   WM_WINDOWPOSCHANGED;   
              function   SendAppBarMsg(Msg:   DWORD):   UINT;   
              procedure   SetAppBarPos(Edge:   UINT);   
              procedure   SetAppBarEdge(Value:   TAppBarEdge);   
          protected   
              procedure   CreateParams(var   Params:   TCreateParams);   override;   
              procedure   SetTopMost(TopMost:   Boolean);   
              procedure   WndProc(var   M:   TMessage);   override;   
          public   
              constructor   Create(AOwner:   TComponent);   override;   
              destructor   Destroy;   override;   
          published   
              property   Edge:   TAppBarEdge   read   FEdge   write   SetAppBarEdge;   
              property   TopMost:   Boolean   read   FTopMost   write   SetTopMost   default   True;   
          end;
        
      var
          AppBar:   TAppBar;
        
      implementation   
        
      {$R   *.DFM}
        
      uses   Main;   
        
      const   
          DEF_APPBAR_WIDTH     =   40;   
          DEF_APPBAR_HEIGHT   =   35;   
        
      var   
          AppBarMsg:   UINT   =   0;   
        
      constructor   TAppBar.Create(AOwner:   TComponent);   
      begin   
          inherited   Create(AOwner);   
          //   set   up   the   TAppBarData   record   
          with   FABD   do   
          begin   
              cbSize   :=   SizeOf(FABD);   
              hWnd   :=   Handle;   
              uCallbackMessage   :=   AppBarMsg;   
          end;   
          //   Inform   the   shell   of   the   new   AppBar   
          if   SendAppBarMsg(ABM_NEW)   =   0   then   
              raise   EAppBarError.Create('Failed   to   create   AppBar');   
          //   Initialize   the   position   
          SetAppBarPos(ABE_TOP);   
          FTopMost   :=   True;   
          FLastChecked   :=   Top1;   
      end;
        
      destructor   TAppBar.Destroy;   
      begin   
          //   Must   inform   shell   that   the   AppBar   is   going   away   
          SendAppBarMsg(ABM_REMOVE);   
          inherited   Destroy;   
      end;   
        
      procedure   TAppBar.WMWindowPosChanged(var   M:   TMessage);   
      begin   
          inherited;   
          //   Must   inform   shell   that   the   AppBar   position   has   changed   
          SendAppBarMsg(ABM_WINDOWPOSCHANGED);   
      end;   
        
      procedure   TAppBar.WMActivate(var   M:   TMessage);   
      begin   
          inherited;   
          //   Must   inform   shell   that   the   AppBar   window   was   activated   
          SendAppBarMsg(ABM_ACTIVATE);   
      end;   
        
      procedure   TAppBar.WndProc(var   M:   TMessage);   
      var   
          State:   UINT;   
      begin   
          if   M.Msg   =   AppBarMsg   then   
          begin   
              case   M.WParam   of   
                  //   Sent   when   always   on   top   or   autohide   state   has   changed.   
                  ABN_STATECHANGE:   
                      begin   
                          //   Check   to   see   whether   the   access   bar   is   still   ABS_ALWAYSONTOP.   
                          State   :=   SendAppBarMsg(ABM_GETSTATE);   
                          if   ABS_ALWAYSONTOP   and   State   =   0   then   
                              SetTopMost(False)   
                          else   
                              SetTopMost(True);   
                      end;   
                  //   A   full   screen   application   has   started,   or   the   last   
                  //   full-screen   application   has   closed.   
                  ABN_FULLSCREENAPP:   
                      begin   
                          //   Set   the   access   bar's   z-order   appropriately.   
                          State   :=   SendAppBarMsg(ABM_GETSTATE);   
                          if   M.lParam   <>   0   then   begin   
                              if   ABS_ALWAYSONTOP   and   State   =   0   then   
                                  SetTopMost(False)   
                              else   
                                  SetTopMost(True);   
                          end   
                          else   
                              if   State   and   ABS_ALWAYSONTOP   <>   0   then   
                                  SetTopMost(True);   
                      end;   
                  //   Sent   when   something   happened   which   may   effect   the   AppBar   position.       
                  ABN_POSCHANGED:   
                      begin   
                          //   The   taskbar   or   another   access   bar   
                          //   has   changed   its   size   or   position.   
                          SetAppBarPos(FABD.uEdge);   
                      end;   
              end;   
          end   
          else   
              inherited   WndProc(M);   
      end;   
        
      function   TAppBar.SendAppBarMsg(Msg:   DWORD):   UINT;   
      begin   
          Result   :=   SHAppBarMessage(Msg,   FABD);   
      end;   
        
      procedure   TAppBar.SetAppBarPos(Edge:   UINT);   
      begin   
          FABD.uEdge   :=   Edge;             //   set   edage   
          with   FABD.rc   do   
          begin   
              //   set   coordinates   to   full-scren   
              Top   :=   0;   
              Left   :=   0;   
              Right   :=   Screen.Width;   
              Bottom   :=   Screen.Height;   
              //   Send   ABM_QUERYPOS   to   obtain   proper   rect   on   edge   
              SendAppBarMsg(ABM_QUERYPOS);   
              //   re-adjust   rect   based   on   that   modified   by   ABM_QUERYPOS   
              case   Edge   of   
                  ABE_LEFT:   Right   :=   Left   +   DEF_APPBAR_WIDTH;   
                  ABE_RIGHT:   Left   :=   Right   -   DEF_APPBAR_WIDTH;   
                  ABE_TOP:   Bottom   :=   Top   +   DEF_APPBAR_HEIGHT;   
                  ABE_BOTTOM:   Top   :=   Bottom   -   DEF_APPBAR_HEIGHT;   
              end;   
              //   Set   the   app   bar   position.   
              SendAppBarMsg(ABM_SETPOS);   
          end;   
          //   Set   the   BoundsRect   property   so   that   it   conforms   to   the   
          //   bounding   rectangle   passed   to   the   system.   
          BoundsRect   :=   FABD.rc;   
      end;   
        
      procedure   TAppBar.SetTopMost(TopMost:   Boolean);   
      const   
          WndPosArray:   array[Boolean]   of   HWND   =   (HWND_BOTTOM,   HWND_TOPMOST);   
      begin   
          SetWindowPos(Handle,   WndPosArray[TopMost],   0,   0,   0,   0,   SWP_NOMOVE   or   
              SWP_NOSIZE   or   SWP_NOACTIVATE);   
      end;   
        
      procedure   TAppBar.CreateParams(var   Params:   TCreateParams);   
      begin   
          inherited   CreateParams(Params);   
          Params.ExStyle   :=   WS_EX_TOOLWINDOW   or   WS_EX_TOPMOST;   
          Params.Style   :=   WS_VISIBLE   or   WS_POPUP   or   WS_THICKFRAME   or   WS_CLIPCHILDREN;   
      end;   
        
      procedure   TAppBar.SetAppBarEdge(Value:   TAppBarEdge);   
      const   
          EdgeArray:   array[TAppBarEdge]   of   UINT   =   (ABE_TOP,   ABE_BOTTOM,   ABE_LEFT,   
              ABE_RIGHT);   
      begin   
          if   Value   <>   FEdge   then   
          begin   
              SetAppBarPos(EdgeArray[Value]);   
              FEdge   :=   Value;   
              MoveButtons;   
          end;   
      end;   
        
      procedure   TAppBar.Top1Click(Sender:   TObject);   
      begin   
          FLastChecked.Checked   :=   False;   
          (Sender   as   TMenuItem).Checked   :=   True;   
          case   TMenuItem(Sender).Caption[2]   of   
              'T':   Edge   :=   abeTop;   
              'B':   Edge   :=   abeBottom;   
              'L':   Edge   :=   abeLeft;   
              'R':   Edge   :=   abeRight;   
          end;   
          FLastChecked   :=   TMenuItem(Sender);   
      end;   
        
      

  5.   


      procedure   TAppBar.MoveButtons;   
      //   This   method   looks   complicated,   but   it   really   just   arranges   the   buttons   
      //   properly   depending   on   what   side   the   AppBar   is   docked.   
      var   
          DeltaCenter,   NewPos:   Integer;   
      begin   
          if   (FEdge   =   abeTop)   or   (FEdge   =   abeBottom)   then   
          begin   
              DeltaCenter   :=   (ClientHeight   -   SpeedButton1.Height)   div   2;   
              SpeedButton1.SetBounds(10,   DeltaCenter,   SpeedButton1.Width,   SpeedButton1.Height);   
              NewPos   :=   SpeedButton1.Width   +   20;   
              SpeedButton2.SetBounds(NewPos,   DeltaCenter,   SpeedButton1.Width,   SpeedButton1.Height);   
              NewPos   :=   NewPos   +   SpeedButton1.Width   +   10;   
              SpeedButton3.SetBounds(NewPos,   DeltaCenter,   SpeedButton1.Width,   SpeedButton1.Height);   
              NewPos   :=   NewPos   +   SpeedButton1.Width   +   10;   
              SpeedButton4.SetBounds(NewPos,   DeltaCenter,   SpeedButton1.Width,   SpeedButton1.Height);   
              NewPos   :=   NewPos   +   SpeedButton1.Width   +   10;   
              SpeedButton5.SetBounds(NewPos,   DeltaCenter,   SpeedButton1.Width,   SpeedButton1.Height);   
          end;   
          if   (FEdge   =   abeLeft)   or   (FEdge   =   abeRight)   then   
          begin   
              DeltaCenter   :=   (ClientWidth   -   SpeedButton1.Width)   div   2;   
              SpeedButton1.SetBounds(DeltaCenter,   10,   SpeedButton1.Width,   SpeedButton1.Height);   
              NewPos   :=   SpeedButton1.Height   +   20;   
              SpeedButton2.SetBounds(DeltaCenter,   NewPos,   SpeedButton1.Width,   SpeedButton1.Height);   
              NewPos   :=   NewPos   +   SpeedButton1.Height   +   10;   
              SpeedButton3.SetBounds(DeltaCenter,   NewPos,   SpeedButton1.Width,   SpeedButton1.Height);   
              NewPos   :=   NewPos   +   SpeedButton1.Height   +   10;   
              SpeedButton4.SetBounds(DeltaCenter,   NewPos,   SpeedButton1.Width,   SpeedButton1.Height);   
              NewPos   :=   NewPos   +   SpeedButton1.Height   +   10;   
              SpeedButton5.SetBounds(DeltaCenter,   NewPos,   SpeedButton1.Width,   SpeedButton1.Height);   
          end;   
      end;   
        
      procedure   TAppBar.SpeedButton1Click(Sender:   TObject);   
      begin   
          if   OpenDialog1.Execute   then   
              MainForm.FileName   :=   OpenDialog1.FileName;   
      end;   
        
      procedure   TAppBar.SpeedButton2Click(Sender:   TObject);   
      begin   
          MainForm.memEditor.Lines.SaveToFile(MainForm.FileName);   
      end;   
        
      procedure   TAppBar.SpeedButton3Click(Sender:   TObject);   
      begin   
          MainForm.memEditor.CutToClipboard;   
      end;   
        
      procedure   TAppBar.SpeedButton4Click(Sender:   TObject);   
      begin   
          MainForm.memEditor.CopyToClipboard;   
      end;   
        
      procedure   TAppBar.SpeedButton5Click(Sender:   TObject);   
      begin   
          MainForm.memEditor.PasteFromClipboard;   
      end;   
        
      procedure   TAppBar.Exit1Click(Sender:   TObject);   
      begin   
          Application.Terminate;   
      end;   
        
      initialization   
          AppBarMsg   :=   RegisterWindowMessage('DDG   AppBar   Message');   
      end.