• <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>
  • 實現窗體自動隱藏

    發表于:2007-07-14來源:作者:點擊數: 標簽:
    最近寫個小程序,想讓窗體自動隱藏,到csdn搜索,發現不少網友問這個問題,可是具體實現的例子不多,我經過琢磨,實現可記錄??课恢?,可左上右三方??坎㈦[藏?,F將實現的例子拿出來供大家參考。 實現窗體自動隱藏方法有多種,可以使用定時器,不斷監視鼠標
    最近寫個小程序,想讓窗體自動隱藏,到csdn搜索,發現不少網友問這個問題,可是具體實現的例子不多,我經過琢磨,實現可記錄??课恢?,可左上右三方??坎㈦[藏?,F將實現的例子拿出來供大家參考。
    實現窗體自動隱藏方法有多種,可以使用定時器,不斷監視鼠標,當鼠標移動到窗體邊緣時,顯示窗體,當鼠標離開后隱藏窗體。也可以在鼠標收到WM_NCMOUSEMOVE或 WM_MOUSEMOVE(無邊框窗體)時激活窗體,然后在窗體消息WM_ACTIVE中設置顯示或隱藏,這種方法在窗體未失去焦點時不會隱藏。我在原本的設計中便使用這種方法,只是在設計時發現非主窗體不太合適,激活窗體時會出現兩個鍵盤焦點,而且我所需要的焦點是虛假的,可能我的設計不當,那位朋友若能完美實現,不妨交流一下。
    本代碼的流程如下:
    1. 初始化窗體時設置窗體位置,并設置依靠狀態窗體狀態。
    2. 當接收到WM_MOUSEMOVE消息時,檢查窗體是否顯示,若否,顯示,并打開定時器。
    3. 在WM_MOVING中檢測窗體位置,并自動靠攏邊界。
    4. 在定時器中檢測鼠標,當鼠標離開窗體后,關閉定時器,隱藏窗體。
    當然,在隱藏窗體時首先判斷位置,若??吭谶吘?,則隱藏,否則,不隱藏。
    現在我們一步步看代碼。
    int             alignType;   //全局變量,用于記錄窗體??繝顟B
    enum
    {
    ALIGN_NONE,          //不???br> ALIGN_TOP,          //??可线?br> ALIGN_LEFT,          //??孔筮?br> ALIGN_RIGHT          //??坑疫?br> };
    #define NEAR_SIZE 20 //定義自動??坑行Ь嚯x
    #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) //在上部??繒r,我們也考慮左右邊角。
        {
         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;
        }
       }
      }
    }
    }
    /*
    在窗體初始化是設定窗體狀態,如果可以???,便??吭谶吘?br> 我本想尋求其他方法來解決初始化,而不是為它專一尋求一個函數,可是,窗體初始化時不發送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;

    //下邊判斷窗體該如何移動,由??糠绞經Q定
    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: //處理窗體移動時消息,實現自動???br> {
    OnMoving(hWnd, (LPRECT) lParam);
    break;
    }
    case WM_MOVE:
    {
    //保存窗體位置
    }
    這些代碼是從我的程序中摘錄出來的, 我已盡量檢查它們的完整性, 但人總有犯錯的時候, 如果你發現這些代碼有問題, 或有更好的建議, 請聯系我, 我的E-Mail:ggg82@sina.com

    原文轉自:http://www.kjueaiud.com

    老湿亚洲永久精品ww47香蕉图片_日韩欧美中文字幕北美法律_国产AV永久无码天堂影院_久久婷婷综合色丁香五月

  • <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>