⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wm.c

📁 ucgui的3.98版本的源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
/*********************************************************************
*
*       WM__Client2Screen
*/
void WM__Client2Screen(const WM_Obj* pWin, GUI_RECT *pRect) {
  GUI_MoveRect(pRect, pWin->Rect.x0, pWin->Rect.y0);
}

/*********************************************************************
*
*       WM__IsWindow
*/
int WM__IsWindow(WM_HWIN hWin) {
  WM_HWIN iWin;
  for (iWin = WM__FirstWin; iWin; iWin = WM_H2P(iWin)->hNextLin) {
    if (iWin == hWin) {
      return 1;
    }
  }
  return 0;
}

/*********************************************************************
*
*       WM_InvalidateWindowAndDescs
*
* Parameters
*   pInvalidRect  Rectangle to invalidate in desktop coordinates
*
* Function description
*  Invalidate window and all descendents (children and grandchildren and ...
*/
void WM_InvalidateWindowAndDescsEx(WM_HWIN hWin, const GUI_RECT * pInvalidRect) {
  GUI_RECT Rect;
  WM_Obj*  pWin;
  WM_Obj* pChild;
  WM_HWIN hChild;
  int Status;

  if (hWin) {
    pWin = WM_H2P(hWin);
    Status  = pWin->Status;
    if ((Status & WM_SF_ISVIS) == 0) {
      return;                                                            /* Window is not visible... we are done */
    }
    if (GUI__IntersectRects(&Rect, pInvalidRect, &pWin->Rect) == 0) {  /* Limit the given rect to the area of the parent window */
      return;                                                            /* No intersection, nothing to do */
    }
    WM__Invalidate1Abs(hWin, &Rect);    /* Invalidate window itself */
    for (hChild = WM_GetFirstChild(hWin); hChild; hChild = pChild->hNext) {
      WM_InvalidateWindowAndDescsEx(hChild, &Rect);
      pChild = WM_H2P(hChild);
    }
  }
}

/*********************************************************************
*
*         WM__InvalidateRectEx
*
* Parameters
*   pInvalidRect  Rectangle to invalidate in desktop coordinates
*   hWin          Handle of window to be invalidated.
*   hParent       Handle of parent window.
*                 Can be a valid window handle, 0 or WM_UNATTACHED
*   hStop         Handle of window to stop invalidation at.
*                 Can be a valid window handle or 0.
*                 If valid, hParent needs to be the parent of hStop
*
* Function description
*   Invalidates a window (hParent) as well as its children up to the
*   hStop window.
*   If the Parent is transparent, the function calls it self (recursively)
*   to move up one level in the hierarchy and invalidate the "older generation"
*   
*/
void WM__InvalidateRectEx(const GUI_RECT* pInvalidRect, WM_HWIN hParent, WM_HWIN hStop) {
  GUI_RECT Rect;
  WM_Obj*  pParent;
  WM_Obj*  pi;
  WM_HWIN  hi;
  int Status;

  /* Perform some parameter checks and check for "early out" conditions. */
  if (hParent == 0) {
    return;                                                            /* Desktop window or unattached wind. Nothing to do. */
  }
  pParent = WM_H2P(hParent);
  Status  = pParent->Status;
  if ((Status & WM_SF_ISVIS) == 0) {
    return;                                                            /* Window is not visible... we are done */
  }
  if (GUI__IntersectRects(&Rect, pInvalidRect, &pParent->Rect) == 0) {  /* Limit the given rect to the area of the parent window */
    return;                                                            /* No intersection, nothing to do */
  }
  /* Invalidate the rectangle in the parent */
  /* If the parent is (partially) transparent, we need to move up in the hierarchy */
  if ((Status & (WM_SF_HASTRANS | WM_SF_CONST_OUTLINE)) == WM_SF_HASTRANS) {
    WM__InvalidateRectEx(&Rect, pParent->hParent, pParent->hNext);
  } else {
    WM__Invalidate1Abs(hParent, &Rect);
  }
  /* Invalidate siblings up to hStop */
  for (hi = pParent->hFirstChild; hi; hi = pi->hNext) {
    if (hi == hStop) {
      break;
    }
    WM_InvalidateWindowAndDescsEx(hi, &Rect);
    pi = WM_H2P(hi);
  }
}

/*********************************************************************
*
*       WM_RemoveFromLinList
*/
void WM__RemoveFromLinList(WM_HWIN hWin) {
  WM_Obj* piWin;
  WM_HWIN hiWin;
  WM_HWIN hNext;
  for (hiWin = WM__FirstWin; hiWin; ) {
    piWin = WM_H2P(hiWin);
    hNext = piWin->hNextLin;
    if (hNext == hWin) {
      piWin->hNextLin = WM_H2P(hWin)->hNextLin;
      break;
    }
    hiWin = hNext;
  }
}

/*********************************************************************
*
*       _AddToLinList
*/
static void _AddToLinList(WM_HWIN hNew) {
  WM_Obj* pFirst;
  WM_Obj* pNew;
  if (WM__FirstWin) {
    pFirst = WM_H2P(WM__FirstWin);
    pNew   = WM_H2P(hNew);
    pNew->hNextLin = pFirst->hNextLin;
    pFirst->hNextLin = hNew;
  } else {
    WM__FirstWin = hNew;
  }
}

/*********************************************************************
*
*       WM__RectIsNZ
*
   Check if the rectangle has some content (is non-zero)
   Returns 0 if the Rectangle has no content, else 1.
*/
int WM__RectIsNZ(const GUI_RECT* pr) {
  if (pr->x0 > pr->x1)
    return 0;
  if (pr->y0 > pr->y1)
    return 0;
  return 1;
}

/*********************************************************************
*
*        _Findy1
*
*/
static void _Findy1(WM_HWIN iWin, GUI_RECT* pRect, GUI_RECT* pParentRect) {
  WM_Obj* pWin;
  for (; iWin; iWin = pWin->hNext) { 
    int Status = (pWin = WM_H2P(iWin))->Status;
    /* Check if this window affects us at all */    
    if (Status & WM_SF_ISVIS) {
      GUI_RECT rWinClipped;               /* Window rect, clipped to part inside of ancestors */
      if (pParentRect) {
        GUI__IntersectRects(&rWinClipped, &pWin->Rect, pParentRect);
      } else {
        rWinClipped = pWin->Rect;
      }
      /* Check if this window affects us at all */    
      if (GUI_RectsIntersect(pRect, &rWinClipped)) {
        if ((Status & WM_SF_HASTRANS) == 0) {
          if (pWin->Rect.y0 > pRect->y0) {
            ASSIGN_IF_LESS(pRect->y1, rWinClipped.y0 - 1);      /* Check upper border of window */
          } else {
            ASSIGN_IF_LESS(pRect->y1, rWinClipped.y1);        /* Check lower border of window */
          }
        } else {
          /* Check all children*/ 
          WM_HWIN hChild;
          WM_Obj* pChild;
          for (hChild = pWin->hFirstChild; hChild; hChild = pChild->hNext) {
            pChild = WM_H2P(hChild);
            _Findy1(hChild, pRect, &rWinClipped);
          }
        }
      }
    }
  }
}

/*********************************************************************
*
*        _Findx0
*/
static int _Findx0(WM_HWIN hWin, GUI_RECT* pRect, GUI_RECT* pParentRect) {
  WM_Obj* pWin;
  int r = 0;
  for (; hWin; hWin = pWin->hNext) { 
    int Status = (pWin = WM_H2P(hWin))->Status;
    if (Status & WM_SF_ISVIS) {           /* If window is not visible, it can be safely ignored */
      GUI_RECT rWinClipped;               /* Window rect, clipped to part inside of ancestors */
      if (pParentRect) {
        GUI__IntersectRects(&rWinClipped, &pWin->Rect, pParentRect);
      } else {
        rWinClipped = pWin->Rect;
      }
      /* Check if this window affects us at all */    
      if (GUI_RectsIntersect(pRect, &rWinClipped)) {
        if ((Status & WM_SF_HASTRANS) == 0) {
          pRect->x0 = rWinClipped.x1+1;
          r = 1;
        } else {
          /* Check all children */
          WM_HWIN hChild;
          WM_Obj* pChild;
          for (hChild = pWin->hFirstChild; hChild; hChild = pChild->hNext) {
            pChild = WM_H2P(hChild);
            if (_Findx0(hChild, pRect, &rWinClipped)) {
              r = 1;
            }
          }
        }
      }
    }
  }
  return r;
}

/*********************************************************************
*
*        _Findx1
*/
static void _Findx1(WM_HWIN hWin, GUI_RECT* pRect, GUI_RECT* pParentRect) {
  WM_Obj* pWin;
  for (; hWin; hWin = pWin->hNext) { 
    int Status = (pWin = WM_H2P(hWin))->Status;
    if (Status & WM_SF_ISVIS) {           /* If window is not visible, it can be safely ignored */
      GUI_RECT rWinClipped;               /* Window rect, clipped to part inside of ancestors */
      if (pParentRect) {
        GUI__IntersectRects(&rWinClipped, &pWin->Rect, pParentRect);
      } else {
        rWinClipped = pWin->Rect;
      }
      /* Check if this window affects us at all */    
      if (GUI_RectsIntersect(pRect, &rWinClipped)) {
        if ((Status & WM_SF_HASTRANS) == 0) {
          pRect->x1 = rWinClipped.x0-1;
        } else {
          /* Check all children */
          WM_HWIN hChild;
          WM_Obj* pChild;
          for (hChild = pWin->hFirstChild; hChild; hChild = pChild->hNext) {
            pChild = WM_H2P(hChild);
            _Findx1(hChild, pRect, &rWinClipped);
          }
        }
      }
    }
  }
}

/*********************************************************************
*
*       Sending messages
*
**********************************************************************
*/
/*********************************************************************
*
*       WM_SendMessage
*/
void WM_SendMessage(WM_HWIN hWin, WM_MESSAGE* pMsg) {
  if (hWin) {
    WM_LOCK();
    WM__SendMessage(hWin, pMsg);
    WM_UNLOCK();
  }  
}

/*********************************************************************
*
*       WM__SendMsgNoData
*/
void WM__SendMsgNoData(WM_HWIN hWin, U8 MsgId) {
  WM_MESSAGE Msg;
  Msg.hWin  = hWin;
  Msg.MsgId = MsgId;
  WM__SendMessage(hWin, &Msg);
}

/*********************************************************************
*
*       WM__GetClientRectWin
*
  Get client rectangle in windows coordinates. This means that the
  upper left corner is always at (0,0). 
*/
void WM__GetClientRectWin(const WM_Obj* pWin, GUI_RECT* pRect) {
  pRect->x0 = pRect->y0 = 0;
  pRect->x1 = pWin->Rect.x1 - pWin->Rect.x0;
  pRect->y1 = pWin->Rect.y1 - pWin->Rect.y0;
}

/*********************************************************************
*
*       WM__GetInvalidRectAbs
*/
static void WM__GetInvalidRectAbs(WM_Obj* pWin, GUI_RECT* pRect) {
  *pRect = pWin->InvalidRect;
}

/*********************************************************************
*
*       Invalidation functions
*
**********************************************************************
*/
/*********************************************************************
*
*       WM_InvalidateRect
*
*  Invalidate a section of the window. The optional rectangle
*  contains client coordinates, which are independent of the
*  position of the window on the logical desktop area.
*/
void WM_InvalidateRect(WM_HWIN hWin, const GUI_RECT*pRect) {
  GUI_RECT r;
  WM_Obj* pWin;
  int Status;
  if (hWin) {
    WM_LOCK();
    pWin = WM_H2P(hWin);
    Status = pWin->Status;
    if (Status & WM_SF_ISVIS) {
      r = pWin->Rect;
      if (pRect) {
        GUI_RECT rPara;
        rPara = *pRect;
        WM__Client2Screen(pWin, &rPara);
        GUI__IntersectRect(&r, &rPara);
      }
      if (WM__ClipAtParentBorders(&r, hWin)) {      /* Optimization that saves invalidation if window area is not visible ... Not required */
        if ((Status & (WM_SF_HASTRANS | WM_SF_CONST_OUTLINE)) == WM_SF_HASTRANS) {
          WM__InvalidateRectEx(&r, pWin->hParent, pWin->hNext);
        } else {
          WM__Invalidate1Abs(hWin, &r);
        }
      }
    }
    WM_UNLOCK();
  }
}

/*********************************************************************
*
*        WM_InvalidateWindow
*
  Invalidates an entire window.
*/
void WM_InvalidateWindow(WM_HWIN hWin) {
  WM_InvalidateRect(hWin, NULL);
}

/*********************************************************************
*
*       manage windows stack
*
**********************************************************************
*/
/*********************************************************************
*
*       WM_CreateWindowAsChild
*/
WM_HWIN WM_CreateWindowAsChild( int x0, int y0, int width, int height
                               ,WM_HWIN hParent, U16 Style, WM_CALLBACK* cb
                               ,int NumExtraBytes) {
  WM_Obj* pWin;
  WM_HWIN hWin;
  WM_ASSERT_NOT_IN_PAINT();
  WM_LOCK();
  Style |= WM__CreateFlags;
  /* Default parent is Desktop 0 */
  if (!hParent) {
    if (WM__NumWindows) {
    #if GUI_NUM_LAYERS == 1
      hParent = WM__ahDesktopWin[0];
    #else
      hParent = WM__ahDesktopWin[GUI_Context.SelLayer];
    #endif
    }
  }
  if (hParent == WM_UNATTACHED) {
    hParent = WM_HWIN_NULL;
  }  
  if (hParent) {
    WM_Obj* pParent = WM_H2P(hParent);
    x0 += pParent->Rect.x0;
    y0 += pParent->Rect.y0;
    if (width==0) {
      width = pParent->Rect.x1 - pParent->Rect.x0+1;
    }
    if (height==0) {
      height = pParent->Rect.y1 - pParent->Rect.y0+1;
    }
  }
  if ((hWin = (WM_HWIN) GUI_ALLOC_AllocZero(NumExtraBytes + sizeof(WM_Obj))) == 0) {
    GUI_DEBUG_ERROROUT("WM_CreateWindow: No memory to create window");
  } else {
    WM__NumWindows++;
    pWin = WM_H2P(hWin);
    pWin->Rect.x0 = x0;
    pWin->Rect.y0 = y0;
    pWin->Rect.x1 = x0 + width - 1;
    pWin->Rect.y1 = y0 + height - 1;
    pWin->cb = cb;
    /* Copy the flags which can simply be accepted */
    pWin->Status |= (Style & (WM_CF_SHOW |
                              WM_SF_MEMDEV |
                              WM_CF_MEMDEV_ON_REDRAW |
                              WM_SF_STAYONTOP |
                              WM_CF_DISABLED |
                              WM_SF_CONST_OUTLINE |
                              WM_SF_HASTRANS |
                              WM_CF_ANCHOR_RIGHT |
                              WM_CF_ANCHOR_BOTTOM |
                              WM_CF_ANCHOR_LEFT |
                              WM_CF_ANCHOR_TOP |
                              WM_CF_LATE_CLIP));
    /* Add to linked lists */
    _AddToLinList(hWin);
    WM__InsertWindowIntoList(hWin, hParent);
    /* Activate window if WM_CF_ACTIVATE is specified */
    if (Style & WM_CF_ACTIVATE) {
      WM_SelectWindow(hWin);  /* This is not needed if callbacks are being used, but it does not cost a lot and makes life easier ... */
    }
    /* Handle the Style flags, one at a time */
    #if WM_SUPPORT_TRANSPARENCY
      if (Style & WM_SF_HASTRANS) {
        WM__TransWindowCnt++;          /* Increment counter for transparency windows */
      }
    #endif
    if (Style & WM_CF_BGND) {
      WM_BringToBottom(hWin);
    }
    if (Style & WM_CF_SHOW) {
      pWin->Status |= WM_SF_ISVIS;  /* Set Visibility flag */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -