六月婷婷综合激情-六月婷婷综合-六月婷婷在线观看-六月婷婷在线-亚洲黄色在线网站-亚洲黄色在线观看网站

明輝手游網中心:是一個免費提供流行視頻軟件教程、在線學習分享的學習平臺!

完成窗體自動隱藏

[摘要]最近寫個小程序,想讓窗體自動隱藏,到csdn搜索,發現不少網友問這個問題,可是具體實現的例子不多,我經過琢磨,實現可記錄停靠位置,可左上右三方停靠并隱藏。現將實現的例子拿出來供大家參考。 實現窗體自動隱藏方法有多種,可以使用定時器,不斷監視鼠標,當鼠標移動到窗體邊緣時,顯示窗體,當鼠標離開后隱藏窗...
最近寫個小程序,想讓窗體自動隱藏,到csdn搜索,發現不少網友問這個問題,可是具體實現的例子不多,我經過琢磨,實現可記錄停靠位置,可左上右三方停靠并隱藏。現將實現的例子拿出來供大家參考。
實現窗體自動隱藏方法有多種,可以使用定時器,不斷監視鼠標,當鼠標移動到窗體邊緣時,顯示窗體,當鼠標離開后隱藏窗體。也可以在鼠標收到WM_NCMOUSEMOVE或 WM_MOUSEMOVE(無邊框窗體)時激活窗體,然后在窗體消息WM_ACTIVE中設置顯示或隱藏,這種方法在窗體未失去焦點時不會隱藏。我在原本的設計中便使用這種方法,只是在設計時發現非主窗體不太合適,激活窗體時會出現兩個鍵盤焦點,而且我所需要的焦點是虛假的,可能我的設計不當,那位朋友若能完美實現,不妨交流一下。
本代碼的流程如下:
1. 初始化窗體時設置窗體位置,并設置依靠狀態窗體狀態。
2. 當接收到WM_MOUSEMOVE消息時,檢查窗體是否顯示,若否,顯示,并打開定時器。
3. 在WM_MOVING中檢測窗體位置,并自動靠攏邊界。
4. 在定時器中檢測鼠標,當鼠標離開窗體后,關閉定時器,隱藏窗體。
當然,在隱藏窗體時首先判斷位置,若停靠在邊緣,則隱藏,否則,不隱藏。
現在我們一步步看代碼。
int             alignType;   //全局變量,用于記錄窗體停靠狀態
enum
{
ALIGN_NONE,          //不停靠
ALIGN_TOP,          //停靠上邊
ALIGN_LEFT,          //停靠左邊
ALIGN_RIGHT          //停靠右邊
};
#define NEAR_SIZE 20 //定義自動停靠有效距離
#define NEAR_SIDE 2 //窗體隱藏后在屏幕上保留的像素,以使鼠標可以觸及
/*
下面代碼處理窗體消息WM_MOVING,pRect是由參數lParam傳來的指針
*/
void            OnMoving(HWND hWnd, LPRECT pRect)
{
//未靠邊界由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 = 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 = 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;
    }
   }
  }
}
}
/*
在窗體初始化是設定窗體狀態,如果可以停靠,便停靠在邊緣
我本想尋求其他方法來解決初始化,而不是為它專一尋求一個函數,可是,窗體初始化時不發送WM_MOVING消息,我不得不重復類似任務.
*/
void            NearSide(HWND hWnd)
{
int             change = 0;
RECT            rect;
GetWindowRect(hWnd, &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;
  }
}
//調整上
else 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(hWnd, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, TRUE);
}

}
/*
窗體的顯示隱藏由該函數完成,參數hide決定顯示還是隱藏.
*/
void            HideSide(HWND hWnd, BOOL hide)
{
RECT            rc;
int             moves = 20;  //動畫滾動窗體的步數,如果你覺得不夠平滑,可以增大該值.
int             xStep, yStep;
int             xEnd, yEnd;
int             width;
int             height;
register int    i;
GetWindowRect(hWnd, &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(hWnd, NULL, rc.left, rc.top, 0, 0, SWP_NOSIZE SWP_NOSENDCHANGING);
  RedrawWindow(hWnd, NULL, NULL, RDW_INVALIDATE RDW_UPDATENOW);
  Sleep(5);
}
SetWindowPos(hWnd, NULL, xEnd, yEnd, 0, 0, SWP_NOSIZE);
if (!hide) //如果窗體已被顯示,設置定時器.監視鼠標.
{
  SetTimer(hWnd, WM_TIMER, 500, NULL);
}
}
//下面就是通過窗體回調函數將這些函數組織起來.
//這里僅列出使用的消息
case WM_TIMER: //定時器消息
{
POINT           pt;
RECT            rc;
GetCursorPos(&pt);
GetWindowRect(hWnd, &rc);
if (!PtInRect(&rc, pt)) //若鼠標不在窗體內,隱藏窗體.
{
  KillTimer(hWnd, WM_TIMER);
  HideSide(hWnd, TRUE);
}
break;
}
case WM_CREATE:
case WM_INITDIALOG: //初始化消息
{
SetWindowPos(...) //程序保存窗體上次靠位置,在這里恢復.  
   NearSide(hWnd);
break;
}
//這兩個消息是在窗體移動開始時和結束時產生的,我們在窗體開始移動時關閉定時器,移動結束后再打開,這樣避免窗體移動時隱藏,金山快譯的浮動條就有這種情況出現.
case WM_ENTERSIZEMOVE:
{
KillTimer(hWnd, WM_TIMER);
break;
}
case WM_EXITSIZEMOVE:
{
SetTimer(hWnd, WM_TIMER, 500, NULL);
break;
}
case WM_MOUSEMOVE: //受到窗體移動消息時,判斷窗體是否顯示,
{
RECT            rc;
GetWindowRect(hWnd, &rc);
if (rc.left < 0 rc.top < 0 rc.right > ScreenX) //未顯示
  HideSide(hWnd, FALSE);
break;
}
case WM_MOVING: //處理窗體移動時消息,實現自動停靠
{
OnMoving(hWnd, (LPRECT) lParam);
break;
}
case WM_MOVE:
{
//保存窗體位置
}
這些代碼是從我的程序中摘錄出來的, 我已盡量檢查它們的完整性, 但人總有犯錯的時候, 如果你發現這些代碼有問題, 或有更好的建議, 請聯系我, 我的E-Mail:[email protected]


主站蜘蛛池模板: 羞羞一区二区三区四区片 | 色五月在线视频 | 天天爱夜夜做 | 天天干天天射天天 | 青青色在线观看 | 日本邪恶全彩 | 欧美午夜不卡在线观看最新 | 亚洲精品中文字幕无乱码 | 日韩黄网 | 日本香蕉视频在线观看 | 欧美夜夜 | 中文字幕人成乱在线视频 | 四虎影院在线免费观看视频 | 伊人精品视频在线观看 | 欧美一级淫片免费播放40分钟 | 亚洲日本欧美日韩高观看 | 一级毛片a女人刺激视频免费 | 亚洲人成在线播放 | 亚洲欧美激情综合第一区 | 亚洲精品欧美综合 | 伊人手机在线视频 | 天天操天天草 | 欧美一级艳片视频免费观看 | 亚洲va欧美ⅴa国产va影院 | 色综合久久伊人 | 天天色啪| 四虎成年永久免费网站 | 深夜福利免费视频 | 亚洲免费一 | 伊在线视频| 亚洲日韩精品欧美一区二区一 | 天天操欧美 | 四虎影视网 | 日韩视频在线观看中字 | 四虎国产精品永免费 | 亚洲六月丁香色婷婷综合久久 | 亚洲影视天堂 | 青青青在线网站视频在线 | 人人揉人人添人人捏人人看 | 伊人手机视频 | 色悠久久久久综合网伊人男男 |