捐赠 | 广告 | 注册 | 发布 | 上传 | 关于我们    
  粤ICP备10103342号-1 DELPHI盒子 | 盒子文章 | 盒子问答悬赏 | 最新更新 | 盒子检索 | 下载中心 | 高级搜索    
  精品专区 | 繁體中文 | 奖励公告栏 | 直通车账号登陆 | 关闭GOOGLE广告 | 临时留言    
 
广告
评论:类似腾讯qq的自动窗体隐藏功能实现
decal 592354 2018/3/22 21:46:50
谢谢楼主的代码,timer实现可以,速度没问题,配合traycooltool很好用
delphi_fu888 40162 2010/6/3 19:00:41
cqwty 37372 的代码没有错呀,我刚试通过.
starsc 39571 2010/2/5 0:27:41
mos兄弟搞好没有呀?请发上来呀
snakejiao 37657 2009/6/5 14:56:27
mos 搞定没有啊 等着你啊
mos 37410 2009/5/6 14:54:49
可以没有问题!等我整理下!发上来,请大家多多指点下!
see8di 37381 2009/4/29 23:43:59
cqwty 的代码有错,mos朋友,麻烦你贴出你的代码来学习一下好不?
mos 37377 2009/4/29 16:55:10
功能是实现拉!可是如果在窗体中放了控件,同时窗体是在隐藏的状态下显示时,有问题!改进下就好了!我做的就不会出现这个问题!但也是有点不满意的地方!现在正在修改中!
cqwty 37372 2009/4/29 14:34:57
你这个用了timer来做的,不是很科学,贴一个别人写的控件:
{**********
  作者: dmzn dmzn@163.com 2006-02-09
  描述: 使窗体在桌面边沿停靠的组件,类似QQ自动隐藏的样式

  声明: 本单元公开源码,个人/商业可免费使用,不过请保留此处的说明文字.如果你
  对本单元作了合理修改,请邮件通知我,谢谢!
**********}
unit ZnHideForm;

interface

uses
  Classes, Controls, ExtCtrls, Forms, Windows, Messages, SysUtils;

type
  TDockPos = (dpNone, dpTop, dpLeft, dpRight);
  TDockEvent = procedure (const nDockPos: TDockPos) of Object;

  TZnHideForm = class(TComponent)
  private
    { Private declarations }
    FWnd: Hwnd;
    FIdle: Cardinal;

    FIsHide: boolean;
    FDockPos: TDockPos;

    FAutoDock: boolean;
    FEdgeSpace: integer;
    FValidSpace: integer;

    FMainForm: TForm;
    FFormRect: TRect;
    FFormProc: TWndMethod;

    FDockEvent: TDockEvent;
    FHideEvent: TDockEvent;
    FShowEvent: TDockEvent;
  protected
    { Protected declarations }
    function FindMainForm: TForm;
    procedure WndProc(var nMsg: TMessage);

    procedure SetFormShow;
    procedure SetFormHide;
    function IsMouseLeave: boolean;

    procedure CaptureMsg(var Message: TMessage);
    procedure DockFormToEdge(const nRect: PRect);

    procedure SetAutoDock(const nValue: boolean);
    procedure SetEdgeSpace(const nSpace: integer);
    procedure SetValidSpace(const nSpace: integer);
  public
    { Public declarations }
    constructor Create(AOwner: TComponent);override;
    destructor Destroy;override;
  published
    { Published declarations }
    property DockPos: TDockPos read FDockPos;
    property AutoDock: Boolean read FAutoDock write SetAutoDock;
    property EdgeSpace: integer read FEdgeSpace write SetEdgeSpace;
    property ValidSpace: integer read FValidSpace write SetValidSpace;

    property DockEvent: TDockEvent read FDockEvent write FDockEvent;
    property OnHideForm: TDockEvent read FHideEvent write FHideEvent;
    property OnShowForm: TDockEvent read FShowEvent write FShowEvent; 
  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('RunSoft',[TZnHideForm]);
end;

{**********  TZnHideForm  **********}
constructor TZnHideForm.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  FMainForm := FindMainForm;
  if not Assigned(FMainForm) then raise Exception.Create('未找到主窗体');

  FIdle := 0;
  FEdgeSpace := 3;
  FValidSpace := 10;
 
  FDockPos := dpNone;  
  FAutoDock := False;

  if not (csDesigning in ComponentState) then
  begin
     FFormRect := FMainForm.BoundsRect;
     FFormProc := FMainForm.WindowProc;
     FMainForm.WindowProc := CaptureMsg;
  end;
end;

destructor TZnHideForm.Destroy;
begin
  if Assigned(FMainForm) and
     Assigned(FFormProc) then FMainForm.WindowProc := FFormProc;

  SetAutoDock(False);
  inherited Destroy;
end;

//Desc: 搜索主窗体
function TZnHideForm.FindMainForm: TForm;
var nComponent: TComponent;
begin
  Result := nil;
  nComponent := Self.Owner;

  while Assigned(nComponent) do
  begin
     if (nComponent is TForm) then
     begin
        Result := nComponent as TForm;
        Break;
     end;
     nComponent := nComponent.GetParentComponent;
  end;
end;

//Desc: 开启/关闭Dock
procedure TZnHideForm.SetAutoDock(const nValue: boolean);
begin
  FAutoDock := nValue;

  if not (csDesigning in ComponentState) then
    if FAutoDock then
    begin
       FWnd := Classes.AllocateHWnd(WndProc);
       SetTimer(FWnd, 1, 558, nil);
    end else

    if FWnd > 0 then
    begin
       KillTimer(FWnd, 1);
       Classes.DeallocateHWnd(FWnd);
       FWnd := 0; FIdle := 0; FDockPos := dpNone;
    end;
end;

//Desc: 计数器在查数,^_^
procedure TZnHideForm.WndProc(var nMsg: TMessage);
begin
  with nMsg do
  begin
     if Msg = WM_TIMER then
          Inc(FIdle)
     else Result := DefWindowProc(FWnd, Msg, wParam, lParam);
  end;
end;

//Name: DockFormToEdge
//Parm: nRect,窗体当前所在区域
//Desc: 依据nRect判断窗口是否需要Dock到边沿
procedure TZnHideForm.DockFormToEdge(const nRect: PRect);
begin
  if (nRect.Top < FValidSpace) and (nRect.Top <= FFormRect.Top) then
  //Top
  begin
     nRect.Bottom := nRect.Bottom - nRect.Top;
     nRect.Top := 0;
  end else

  if (nRect.Left < FValidSpace) and (nRect.Left <= FFormRect.Left) then
  //Left
  begin
     nRect.Right := nRect.Right - nRect.Left;
     nRect.Left := 0;
  end else

  if (Screen.Width - nRect.Right < FValidSpace) and (nRect.Left >= FFormRect.Left) then
  //Right
  begin
     nRect.Left := Screen.Width - (nRect.Right - nRect.Left);
     nRect.Right := Screen.Width;
  end;

  if nRect.Top = 0 then
     FDockPos := dpTop else
  if nRect.Left = 0 then
     FDockPos := dpLeft else
  if nRect.Right = Screen.Width then
     FDockPos := dpRight else FDockPos := dpNone;

  FFormRect := nRect^; //Save MainForm Rects
  if (FDockPos <> dpNone) and Assigned(FDockEvent) then FDockEvent(FDockPos);
end;

//Desc: 判断鼠标是否离开主窗体
function TZnHideForm.IsMouseLeave: boolean;
var nPt: TPoint;
begin
  GetCursorPos(nPt);
  if PtInRect(FFormRect, nPt) then
       Result := False
  else Result := True;
end;

procedure TZnHideForm.SetFormHide;
begin
  if IsMouseLeave then
  begin
     FIsHide := True;
     if Assigned(FHideEvent) then
     begin
        FHideEvent(FDockPos); Exit;
     end;

     if FDockPos = dpTop then
        FMainForm.Top := -FMainForm.Height + FEdgeSpace else
     if FDockPos = dpLeft then
        FMainForm.Left := -FMainForm.Width + FEdgeSpace else
     if FDockPos = dpRight then
        FMainForm.Left := Screen.Width - FEdgeSpace;
  end;
end;

procedure TZnHideForm.SetFormShow;
begin
  FIsHide := False;
  if Assigned(FShowEvent) then
  begin
     FShowEvent(FDockPos); Exit;
  end;

  if FDockPos = dpTop then
     FMainForm.Top := 0 else
  if FDockPos = dpLeft then
     FMainForm.Left := 0 else
  if FDockPos = dpRight then
     FMainForm.Left := Screen.Width - FMainForm.Width;
end;

procedure TZnHideForm.SetEdgeSpace(const nSpace: integer);
begin
  if (nSpace > 0) and (nSpace < 51) then
       FEdgeSpace := nSpace
  else raise Exception.Create('请填写1-50以内的数字'); 
end;

procedure TZnHideForm.SetValidSpace(const nSpace: integer);
begin
  if (nSpace > 4) and (nSpace < 51) then
       FValidSpace := nSpace
  else raise Exception.Create('请填写5-50以内的数字'); 
end;

procedure TZnHideForm.CaptureMsg(var Message: TMessage);
begin
  if Assigned(FFormProc) then FFormProc(Message);
  
  if FAutoDock then
  case Message.Msg of
    CM_MOUSEENTER : if FIsHide then SetFormShow;
    CM_MOUSELEAVE : if FDockPos <> dpNone then SetFormHide;
    WM_MOVING     : DockFormToEdge(PRect(Message.lParam));
  end;
end;

end.
第一页 上一页 下一页 最后页 有 8 条纪录 共1页 1 - 8
 用户名:
 密 码:
自动登陆(30天有效)
 
  DELPHI盒子版权所有 技术支持:深圳市麟瑞科技有限公司 1999-2024 V4.01 粤ICP备10103342号-1 更新RSS列表