C#无框窗体的隐藏代码是啥?(类似QQ停靠桌面边缘自动隐藏)
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C#无框窗体的隐藏代码是啥?(类似QQ停靠桌面边缘自动隐藏)相关的知识,希望对你有一定的参考价值。
说明具体事件的用法
工具箱里去找 noti。。开头的控件!QQ的边缘弹下来这一步:当鼠标触及边缘后,界面整体下移到这个界面出现为止;当鼠标离开界面后,界面会上移出屏幕,就实现了“隐藏”就是利用移动他实现隐藏!
// TestDlg.cpp : implementation file
//
#include "stdafx.h"
#include "Test.h"
#include "TestDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
int ScreenX; //屏幕宽度
int ScreenY; //屏幕高度
int alignType; //全局变量,用于记录窗体停靠状态
enum
ALIGN_NONE, //不停靠
ALIGN_TOP, //停靠上边
ALIGN_LEFT, //停靠左边
ALIGN_RIGHT //停靠右边
;
#define NEAR_SIZE 5 //定义自动停靠有效距离
#define NEAR_SIDE 3 //窗体隐藏后在屏幕上保留的像素,以使鼠标可以触及
/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About
class CAboutDlg : public CDialog
public:
CAboutDlg();
// Dialog Data
//AFX_DATA(CAboutDlg)
enum IDD = IDD_ABOUTBOX ;
//AFX_DATA
// ClassWizard generated virtual function overrides
//AFX_VIRTUAL(CAboutDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//AFX_VIRTUAL
// Implementation
protected:
//AFX_MSG(CAboutDlg)
//AFX_MSG
DECLARE_MESSAGE_MAP()
;
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
//AFX_DATA_INIT(CAboutDlg)
//AFX_DATA_INIT
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
CDialog::DoDataExchange(pDX);
//AFX_DATA_MAP(CAboutDlg)
//AFX_DATA_MAP
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
//AFX_MSG_MAP(CAboutDlg)
// No message handlers
//AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CTestDlg dialog
CTestDlg::CTestDlg(CWnd* pParent /*=NULL*/)
: CDialog(CTestDlg::IDD, pParent)
//AFX_DATA_INIT(CTestDlg)
// NOTE: the ClassWizard will add member initialization here
//AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
void CTestDlg::DoDataExchange(CDataExchange* pDX)
CDialog::DoDataExchange(pDX);
//AFX_DATA_MAP(CTestDlg)
// NOTE: the ClassWizard will add DDX and DDV calls here
//AFX_DATA_MAP
BEGIN_MESSAGE_MAP(CTestDlg, CDialog)
//AFX_MSG_MAP(CTestDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_WM_MOVING()
ON_WM_TIMER()
ON_WM_NCMOUSEMOVE()
//AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CTestDlg message handlers
BOOL CTestDlg::OnInitDialog()
CDialog::OnInitDialog();
// Add "About..." menu item to system menu.
// IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
// TODO: Add extra initialization here
ScreenX = GetSystemMetrics(SM_CXSCREEN);
ScreenY = GetSystemMetrics(SM_CYSCREEN);
SetTimer(WM_TIMER,50,NULL);
NearSide(GetSafeHwnd()); //如果位置合适让窗体自动隐藏
return TRUE; // return TRUE unless you set the focus to a control
void CTestDlg::OnSysCommand(UINT nID, LPARAM lParam)
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
CAboutDlg dlgAbout;
dlgAbout.DoModal();
else
-
CDialog::OnSysCommand(nID, lParam);
// If you add a minimize button to your dialog, you will need the code below
// to draw the icon. For MFC applications using the document/view model,
// this is automatically done for you by the framework.
void CTestDlg::OnPaint()
if (IsIconic())
CPaintDC dc(this); // device context for painting
SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
else
CDialog::OnPaint();
// The system calls this to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR CTestDlg::OnQueryDragIcon()
return (HCURSOR) m_hIcon;
void CTestDlg::HideSide(HWND hWnd, BOOL hide)
RECT rc;
int moves = 2; //动画滚动窗体的步数,如果你觉得不够平滑,可以增大该值.
int xStep, yStep;
int xEnd, yEnd;
int width;
int height;
register int i;
GetWindowRect(&rc);
width = rc.right - rc.left;
height = rc.bottom - rc.top;
//下边判断窗体该如何移动,由停靠方式决定
switch (alignType)
case ALIGN_TOP:
//向上移藏
xStep = 0;
xEnd = rc.left;
if (hide)
yStep = -rc.bottom / moves;
yEnd = -height + NEAR_SIDE;
else
yStep = -rc.top / moves;
yEnd = 0;
break;
case ALIGN_LEFT:
//向左移藏
yStep = 0;
yEnd = rc.top;
if (hide)
xStep = -rc.right / moves;
xEnd = -width + NEAR_SIDE;
else
xStep = -rc.left / moves;
xEnd = 0;
break;
case ALIGN_RIGHT:
//向右移藏
yStep = 0;
yEnd = rc.top;
if (hide)
xStep = (ScreenX - rc.left) / moves;
xEnd = ScreenX - NEAR_SIDE;
else
xStep = (ScreenX - rc.right) / moves;
xEnd = ScreenX - width;
break;
default:
return;
//动画滚动窗体.
for (i = 0; i < moves; i++)
rc.left += xStep;
rc.top += yStep;
SetWindowPos(NULL, rc.left, rc.top, 0, 0,
SWP_NOSIZE | SWP_NOSENDCHANGING);
RedrawWindow(NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW);
Sleep(5);
SetWindowPos(NULL, xEnd, yEnd, 0, 0, SWP_NOSIZE);
if (!hide) //如果窗体已被显示,设置定时器.监视鼠标.
SetTimer(WM_TIMER, 50, NULL);
void CTestDlg::NearSide(HWND hWnd)
int change = 0;
RECT rect;
GetWindowRect(&rect);
alignType = ALIGN_NONE;
if (rect.left < NEAR_SIZE)
alignType = ALIGN_LEFT;
if ((rect.left != 0) && rect.right != NEAR_SIDE)
rect.right -= rect.left;
rect.left = 0;
change = 1;
else if (rect.right > ScreenX - NEAR_SIZE)
alignType = ALIGN_RIGHT;
if (rect.right != ScreenX && rect.left != ScreenX - NEAR_SIDE)
rect.left += (ScreenX - rect.right);
rect.right = ScreenX;
change = 1;
//调整上下
if (rect.top < NEAR_SIZE)
alignType = ALIGN_TOP;
if (rect.top != 0 && rect.bottom != NEAR_SIDE)
rect.bottom -= rect.top;
rect.top = 0;
change = 1;
if (change)
MoveWindow(rect.left, rect.top, rect.right - rect.left,
rect.bottom - rect.top, TRUE);
void CTestDlg::OnMoving(UINT fwSide, LPRECT pRect)
CDialog::OnMoving(fwSide, pRect);
// TODO: Add your message handler code here
//未靠边界由pRect测试
if (alignType == ALIGN_NONE)
if (pRect->top < NEAR_SIZE) //在上边有效距离内,自动靠拢。
alignType = ALIGN_TOP;
pRect->bottom -= pRect->top;
pRect->top = 0;
if (pRect->left < NEAR_SIZE) //在左边有效距离内
alignType = ALIGN_LEFT;
pRect->right -= pRect->left;
pRect->left = 0;
else if (pRect->right + NEAR_SIZE > ScreenX)
//在右边有效距离内,ScreenX为屏幕宽度,可由GetSystemMetrics(SM_CYSCREEN)得到。
alignType = ALIGN_RIGHT;
pRect->left += (ScreenX - pRect->right);
pRect->right = ScreenX;
else
//靠边界由鼠标测试
POINT pt;
GetCursorPos(&pt);
if (alignType == ALIGN_TOP)
if (pt.y > NEAR_SIZE)
//由于我们移动窗体时,鼠标在标题栏内,当鼠标位置超过有效距离后,//
//我们可以考虑用户要向下拖动鼠标。我们便解除上部停靠。
alignType = ALIGN_NONE;
pRect->bottom += (NEAR_SIZE-pRect->top);
pRect->top = NEAR_SIZE;
else
pRect->bottom -= pRect->top;
pRect->top = 0;
if (pRect->left < NEAR_SIZE)
//在上部停靠时,我们也考虑左右边角。
pRect->right -= pRect->left;
pRect->left = 0;
else if (pRect->right + NEAR_SIZE > ScreenX)
pRect->left += (ScreenX - pRect->right);
pRect->right = ScreenX;
if (alignType == ALIGN_LEFT)
if (pt.x - pRect->right > 0)
//鼠标可以在整个标题条来回移动,
//所以我们不能简单用左边界和鼠标的距离来解除停靠,
//这里我们在鼠标离开右边界时解除停靠。
alignType = ALIGN_NONE;
pRect->right += (NEAR_SIZE-pRect->left);
pRect->left = NEAR_SIZE;
else
pRect->right -= pRect->left;
pRect->left = 0;
if (pRect->top < NEAR_SIZE) //考虑左上角。
pRect->bottom -= pRect->top;
pRect->top = 0;
else if (alignType == ALIGN_RIGHT)
if (pt.x < pRect->left) //当鼠标离开左边界时,解除停靠。
alignType = ALIGN_NONE;
pRect->left -= NEAR_SIZE;
pRect->right -= NEAR_SIZE;
else
pRect->left += (ScreenX - pRect->right);
pRect->right = ScreenX;
if (pRect->top < NEAR_SIZE) //考虑右上角。
pRect->bottom -= pRect->top;
pRect->top = 0;
void CTestDlg::OnTimer(UINT nIDEvent)
// TODO: Add your message handler code here and/or call default
POINT pt;
RECT rc;
GetCursorPos(&pt);
//GetWindowRect(hWnd, &rc);
GetWindowRect(&rc);
if (!PtInRect(&rc, pt)) //若鼠标不在窗体内,隐藏窗体.
//KillTimer(hWnd, WM_TIMER);
KillTimer(WM_TIMER);
//HideSide(hWnd, TRUE);
HideSide(GetSafeHwnd(),TRUE);
CDialog::OnTimer(nIDEvent);
void CTestDlg::OnNcMouseMove(UINT nHitTest, CPoint point)
// TODO: Add your message handler code here and/or call default
RECT rc;
GetWindowRect(&rc);
if (rc.left < 0 || rc.top < 0 || rc.right > ScreenX) //未显示
HideSide(GetSafeHwnd(), FALSE);
else
HideSide(GetSafeHwnd(), FALSE);
SetTimer(WM_TIMER,50,NULL);
CDialog::OnNcMouseMove(nHitTest, point);
参考技术A 停靠隐藏,自己做控件,或者去下载停靠隐藏控件,网上有 参考技术B 没做过,不过想来应该是响应Form 的 MouseEnter,MouseLeave 事件,改变Form状态。 参考技术C 正在学习C#,不清楚
C# winform 窗体左右一部分显示 一部分隐藏
就跟以前qq的那个什么代理一样,点一下显示出来。再点一下隐藏。新手麻烦稍微详细一点。谢谢
// 采用SplitContainer容器控件,可以实现QQ聊天窗口右侧边栏伸缩展开的效果。if(splitContainer.Panel1Collapsed)
splitContainer.Panel1Collapsed=false; // 展开
else
splitContainer.Panel1Collapsed=true; // 收缩
参考技术A 在From窗体上,放2个panel控件,点击“隐藏”,将一个panel隐藏,将另一个panel显示,显示的那个panel重新设置它的大小追问
谢谢。我找到一个修改它大小的方法能用。 this.Width或者其他什么的来显示。
参考技术B Form1 frm = new Form1(); frm.Hide();窗体就隐藏以上是关于C#无框窗体的隐藏代码是啥?(类似QQ停靠桌面边缘自动隐藏)的主要内容,如果未能解决你的问题,请参考以下文章