怎样实现类似qq的窗口顶部停靠效果?

lcllcl987 2005-06-07 01:22:12
怎样实现类似qq的窗口顶部停靠效果?
当窗体在屏幕上方某个区域时,窗体上移,只留一小部分在屏幕显示
当鼠标移入这一小部分的时候,窗体下移
当鼠标移出时,窗体又上移.
我想了一下:主要有两个技术点:
1:怎么得到窗体的移动结束事件?我想应该是截获WM_MOVE消息
2:怎么得到鼠标移入,移出窗体的事件,我想应该可以用到
CM_MOUSEENTER,CM_MOUSELEAVE消息
下面是我初步实现的效果:
Unit1.h
//---------------------------------------------------------------------------

#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published: // IDE-managed Components
TEdit *Edit1;
private: // User declarations
bool in; //标识鼠标是否进入窗体
void __fastcall MouseEnter(Messages::TMessage &Message);
void __fastcall MouseLeave(Messages::TMessage &Message);
void __fastcall FormMoveEnd(Messages::TMessage &Message);

public: // User declarations
__fastcall TForm1(TComponent* Owner);
BEGIN_MESSAGE_MAP
VCL_MESSAGE_HANDLER(CM_MOUSEENTER,Messages::TMessage,MouseEnter)
VCL_MESSAGE_HANDLER(CM_MOUSELEAVE,Messages::TMessage,MouseLeave)

VCL_MESSAGE_HANDLER(WM_MOVE,Messages::TMessage,FormMoveEnd)
END_MESSAGE_MAP(TForm)
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif



Unit1.cpp
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
in = false;
}
//---------------------------------------------------------------------------


void __fastcall TForm1::MouseEnter(Messages::TMessage &Message)
{
if(in)
exit;
in = true;
Edit1->Text = "enter";
if(Form1->Top < 0)
Form1->Top = 10;
}
void __fastcall TForm1::MouseLeave(Messages::TMessage &Message)
{
in = false;
Edit1->Text = "leave";
if(Form1->Top == 10)
{
Form1->Top = -(Form1->Height -15);
}
}

//---------------------------------------------------------------------------
void __fastcall TForm1::FormMoveEnd(Messages::TMessage &Message)
{
if(Form1->Top < 10)
{
Form1->Top = -(Form1->Height - 15);
}

}

以上程序初步实现了类似效果.但有点问题,就是我的鼠标移动到屏幕最上方时候,窗体会不间断的闪烁.
好像是连续激发了鼠标离开窗体和进入窗体的事件.
有点苦恼,请高手指点一下

...全文
160 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
lcllcl987 2005-06-08
  • 打赏
  • 举报
回复
F117p 2005-06-07
  • 打赏
  • 举报
回复
不用Timer用循环
for()
{
Application->PostMessage
}
lcllcl987 2005-06-07
  • 打赏
  • 举报
回复
楼上的,谢谢,
我试一下
不过怎么要用timer啊
有点不爽
F117p 2005-06-07
  • 打赏
  • 举报
回复
改动一下:
static bool IsHide;
bool CanHide;
void __fastcall TForm1::MouseEnter(Messages::TMessage &Message)
{
if(in)
exit;
in = true;
Edit1->Text = "enter";
if(IsHide)
{
IsHide=false;
Timer1->Enable=true;
}
else
Timer1->Enable=false;
}
void __fastcall TForm1::MouseLeave(Messages::TMessage &Message)
{
in = false;
Edit1->Text = "leave";
if(!IsHide&&Top<0)
{
IsHide=true;
Timer1->Enable=true;
}
else
Timer1->Enable=false;
}

//---------------------------------------------------------------------------
void __fastcall TForm1::FormMoveEnd(Messages::TMessage &Message)
{
if(Form1->Top < 10)
{
IsHide=true;
Timer1->Enable=true;

}
else
Timer1->Enable=false;

}

Timer(...)
{
if(IsHide)
{
//向下展开
}
else
//向上隐藏
}
lcllcl987 2005-06-07
  • 打赏
  • 举报
回复
没懂,郁闷
我的程序错在哪了?
怎么鼠标在最上面的时候,要闪烁?
constantine 2005-06-07
  • 打赏
  • 举报
回复
delphi 自己看
constantine 2005-06-07
  • 打赏
  • 举报
回复
unit Main;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, ExtCtrls, StdCtrls;

type
TfrmMain = class(TForm)
lbl1: TLabel;
mmo1: TMemo;
tmrMouseOut: TTimer;
procedure MouseLeaveProc(Sender: TObject);
private
{ Private declarations }
protected
procedure WMMOVING(var Msg: TMessage); message WM_MOVING;
procedure MouseEnterProc(var Msg: TMessage); message CM_MOUSEENTER;
public
{ Public declarations }
end;

var
frmMain: TfrmMain;

implementation

{$R *.dfm}


{
****************************
* 以下为窗口效果相关过程 *
****************************
}
//限制窗口的Top不能小于0,即窗口不能被拖动到顶部以外

procedure TfrmMain.WMMOVING(var Msg: TMessage);
begin
inherited;
//当窗口被移动的时候
if PRECT(Msg.lParam).Top < 0 then
PRECT(Msg.lParam).Top := 0;
end;

//实现窗口自动弹出

procedure TfrmMain.MouseEnterProc(var Msg: TMessage);
begin
inherited;

tmrMouseOut.Enabled := True;
//如果窗口不是隐藏的,不用弹出。
if Self.Top >= 0 then
Exit;
Self.Top := 0;
Msg.Result := 0;
end;

//实现窗口自动隐藏

procedure TfrmMain.MouseLeaveProc(Sender: TObject);
var
pt: TPoint;
begin
GetCursorPos(pt);
if (not PtInRect(Self.BoundsRect, pt)) and (GetAsyncKeyState(VK_LButton) <> 0) then
Exit;
if PtInRect(Self.BoundsRect, pt) then
Exit;

tmrMouseOut.Enabled := False;

//如果窗口不在最顶部,不用隐藏。
if Self.Top > 0 then
Exit;

//将窗口上缩,只显示三个像素
Self.Top := -Self.Height + 3;
end;
{
****************************
* 以上为窗口控制相关过程 *
****************************
}


end.

13,825

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder相关内容讨论区
社区管理员
  • 基础类社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧