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

📄 winapi.c

📁 MinGUI 可视化程序代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	  }	  PostMessage((HWND)pWnd, WM_PAINT, 0, 0);	  if(pWnd->Children)CM_InvalidateSubWindow(pWnd);    }  }}
//---------------------------------------------------------------------------
static void CM_OffsetWindow(PWND pWnd,int dx,int dy)
{  OffsetRect(&pWnd->WndRect,dx,dy);
   OffsetRect(&pWnd->ClientRect,dx,dy);
   if(pWnd->Canvas)
   { TWndCanvas *pCanvas=pWnd->Canvas;
     while(pCanvas)
	 { pCanvas->VX+=dx;
	   pCanvas->VY+=dy;
	   OffsetRect(&pCanvas->ClipRect,dx,dy);
	   pCanvas=pCanvas->Next;
	 }
   }
   if(pWnd->Children)
   { pWnd=pWnd->Children;
     while(pWnd)
	 { CM_OffsetWindow(pWnd,dx,dy);
	   pWnd=pWnd->Next;
	 }
   }
}

/////////////////////////////////////////////////////////////
//check if a window area is covered by his brother
////////////////////////////////////////////////////////////
static BOOL CM_WndAreaCoveredByBrother(PWND pWnd,TRECT *area)
{  PWND	sibwp=pWnd->Parent->Children;
   while(sibwp)
   { if(sibwp!=pWnd && !sibwp->unmapcount)
     { if(RectInRect(area,&sibwp->WndRect))return true;
	 }
     sibwp=sibwp->Next;
   }
   return false;
}
//---------------------------------------------------------------------------
/*The SetWindowPos function changes the position of the specified window. 
  For a top-level window, the position are relative to the upper-left corner of the screen. 
  For a child window, they are relative to the upper-left corner of the parent window's client area. 
  this function will not change window's z-order
*/
static void CM_SetTopWindowPos(PWND pWnd,int x,int y)
{ PWND	sibwp;
  TRECT shadowRects[2];
  int i,shadowCount,dx,dy;
  shadowCount=RectOffsetShadown(shadowRects,&pWnd->WndRect,x,y);
  if(!shadowCount)return;

  /*erase the shadown when move to new pos*/
  if(!pWnd->unmapcount)
  { /*erase background*/
    for(i=0;i<shadowCount;i++) RegionUnionRect(&g_RootWnd->Family->Vram->ExposeRegion, &shadowRects[i]);
    PostMessage((HWND)g_RootWnd, WM_EXPOSE, 0, 0);
    /*only expose low level window in z-order*/
    for(i=0;i<shadowCount;i++)
	{ sibwp = pWnd;
      while (sibwp->Next)
	  { sibwp = sibwp->Next;
        if(!sibwp->unmapcount && IsRectOverlap(&sibwp->WndRect,&shadowRects[i]))
		{ RegionUnionRect(&sibwp->Family->Vram->ExposeRegion, &shadowRects[i]);
          PostMessage((HWND)sibwp, WM_EXPOSE, 0, 0);
		}
	  }
	}
  } 

  /*calculate window offset*/
  dx=x-pWnd->WndRect.left;
  dy=y-pWnd->WndRect.top;

  /*modify window positon data*/
  CM_OffsetWindow(pWnd,dx,dy);

  /*resize vram*/
  pWnd->Family->Vram->Left=x;
  pWnd->Family->Vram->Top=y;
  ClearRegion(&pWnd->Family->Vram->ExposeRegion);

  /*re-expose window*/
  if(!pWnd->unmapcount)
  { RegionUnionRect(&pWnd->Family->Vram->ExposeRegion, &pWnd->WndRect);
    PostMessage((HWND)pWnd, WM_EXPOSE, 0, 0);
  }
}
//---------------------------------------------------------------------------
static void CM_SetSubWindowPos(PWND pWnd,int x,int y)
{ TRECT shadowRects[2];
  int i,shadowCount,dx,dy;
  shadowCount=RectOffsetShadown(shadowRects,&pWnd->WndRect,x+pWnd->Parent->ClientRect.left,y+pWnd->Parent->ClientRect.top);
  if(!shadowCount)return;

  /*erase the shadown when move to new pos*/
  if(!pWnd->unmapcount)
  { pWnd->Parent->Family->Vram->GroupOperation++;
    for(i=0;i<shadowCount;i++)
	{ if(!CM_WndAreaCoveredByBrother(pWnd,&shadowRects[i]))
	  { CM_EraseBackgroud(pWnd->Parent, &shadowRects[i]);
	  }
	}
    pWnd->Parent->Family->Vram->GroupOperation--;
  } 
    
  /*calculate window offset*/
  dx=x-(pWnd->WndRect.left-pWnd->Parent->ClientRect.left);
  dy=y-(pWnd->WndRect.top-pWnd->Parent->ClientRect.top);

  /*modify window positon data*/
  CM_OffsetWindow(pWnd,dx,dy);

  /*re-expose window*/
  if(!pWnd->unmapcount)
  { RegionUnionRect(&pWnd->Family->Vram->ExposeRegion, &pWnd->WndRect);  
	for(i=0;i<shadowCount;i++)
	{ RegionUnionRect(&pWnd->Family->Vram->ExposeRegion, &shadowRects[i]);
	  CM_InvalidateChildren(pWnd->Parent,&shadowRects[i]);
    }
    CM_InvalidateChildren(pWnd->Parent,&pWnd->WndRect);
    PostMessage((HWND)pWnd->Family->TopWnd, WM_EXPOSE, 0, 0);
  }
}
//---------------------------------------------------------------------------
void WINAPI SetWindowPos(HWND hWnd, int x,int y)
{ if(IsWnd(hWnd) && WNDPTR(hWnd)->Parent)
  { PWND parentwnd=WNDPTR(hWnd)->Parent;
    int oldx=WNDPTR(hWnd)->WndRect.left-parentwnd->ClientRect.left;
    int oldy=WNDPTR(hWnd)->WndRect.top-parentwnd->ClientRect.top;
    if(x!=oldx || y!=oldy)
	{ if(parentwnd==g_RootWnd)
	  { CM_SetTopWindowPos((PWND)hWnd,x,y);
	  }
	  else
	  { CM_SetSubWindowPos((PWND)hWnd,x,y);
	  }
	}
  }
}
//---------------------------------------------------------------------------
//re-expose window based on z-order
void WINAPI UpdateWindow(HWND hWnd)
{ if(IsWnd(hWnd) && WNDPTR(hWnd)->unmapcount==0)
  { PWND parentwnd=WNDPTR(hWnd)->Parent;
	if(parentwnd==g_RootWnd)
    { CM_ExposeWindow((PWND)hWnd);
    }
    else if(parentwnd)
	{ RegionUnionRect(&WNDPTR(hWnd)->Family->Vram->ExposeRegion, &WNDPTR(hWnd)->WndRect);  
	  CM_InvalidateChildren(parentwnd,&WNDPTR(hWnd)->WndRect);
      PostMessage((HWND)WNDPTR(hWnd)->Family->TopWnd, WM_EXPOSE, 0, 0);
	}
  }
}//---------------------------------------------------------------------------//重绘窗体客户区指定区域*/void WINAPI InvalidateClient(HWND hWnd,TRECT *prc){ if(hWnd && hWnd!=(HWND)g_RootWnd && WNDPTR(hWnd)->unmapcount==0 && prc)  { TRECT exposearea;    exposearea.left=(prc->left>=0)?prc->left:0;  	exposearea.right=(prc->right<=crWidth(hWnd))?prc->right:crWidth(hWnd);  	if(exposearea.left>=exposearea.right)return;    	exposearea.top=(prc->top>=0)?prc->top:0;  	exposearea.bottom=(prc->bottom<=crHeight(hWnd))?prc->bottom:crHeight(hWnd); 	if(exposearea.top>=exposearea.bottom)return;      	OffsetRect(&exposearea,WNDPTR(hWnd)->ClientRect.left,WNDPTR(hWnd)->ClientRect.top);	RegionUnionRect(&WNDPTR(hWnd)->Family->Vram->ExposeRegion, &exposearea);        PostMessage(hWnd, WM_PAINT, 0, 0);    if(WNDPTR(hWnd)->Children)    { CM_InvalidateSubWindow((PWND)hWnd);    }  }}//---------------------------------------------------------------------------void WINAPI InvalidateWindow(HWND hWnd,BOOL bPaintNC){ PWND pWnd=(PWND)hWnd;  if(pWnd && pWnd->unmapcount==0)  { RegionUnionRect(&pWnd->Family->Vram->ExposeRegion, &pWnd->WndRect);    PostMessage(hWnd, WM_PAINT, 0, 0);	if(bPaintNC && WndGetAttr(hWnd,WS_BORDER))	{ WndAddAttr(hWnd,WS_NCPAINT);	}    if(pWnd!=g_RootWnd && pWnd->Children)    { CM_InvalidateSubWindow(pWnd);    }  }}//---------------------------------------------------------------------------void WINAPI Invalidate(HWND hWnd){ InvalidateWindow(hWnd,false);}//---------------------------------------------------------------------------/* * Hide the window to make it and its children invisible on the screen. * This is a recursive routine which increments the unmapcount values for * this window and all of its children, and causes exposure events for * windows which are newly uncovered. */void CM_HideWindow(PWND pWnd,BOOL bChangeFocus, BOOL bSendMsg){   PWND	sibwp;		/* sibling window */  PWND	childwp;	/* child window */  pWnd->unmapcount++;     /*   * Clear the area in the parent for this window, causing an   * exposure event for it.   */  if (!pWnd->Parent->unmapcount)   { if(pWnd->Parent==g_RootWnd)    { /*erase background*/	  RegionUnionRect(&g_RootWnd->Family->Vram->ExposeRegion, &pWnd->WndRect);      PostMessage((HWND)g_RootWnd, WM_EXPOSE, 0, 0);	  /*only expose low level window in z-order*/      sibwp = pWnd;      while (sibwp->Next)      { sibwp = sibwp->Next;	    if(!sibwp->unmapcount && IsRectOverlap(&sibwp->WndRect,&pWnd->WndRect))        { RegionUnionRect(&sibwp->Family->Vram->ExposeRegion, &pWnd->WndRect);          PostMessage((HWND)sibwp, WM_EXPOSE, 0, 0);		}      }    }    else    { RegionUnionRect(&pWnd->Parent->Family->Vram->ExposeRegion, &pWnd->WndRect);	  PostMessage((HWND)pWnd->Family->TopWnd, WM_EXPOSE, 0, 0);	  pWnd->Parent->Family->Vram->GroupOperation++;      CM_EraseBackgroud(pWnd->Parent, &pWnd->WndRect);	  pWnd->Parent->Family->Vram->GroupOperation--;      	  CM_InvalidateChildren(pWnd->Parent,&pWnd->WndRect);    }  }  for (childwp = pWnd->Children; childwp; childwp = childwp->Next)  { CM_HideWindow(childwp, bChangeFocus, bSendMsg);  }  if(bSendMsg) SendMessage((HWND)pWnd, WM_SHOWWINDOW, false, 0L);  if(bChangeFocus && pWnd==g_CurrentFocus) CM_KillFocus(pWnd);}//---------------------------------------------------------------------------void InvalidateNCArea(HWND hWnd)
{ if(hWnd && WndGetAttr(hWnd,WS_NCPAINT|WS_BORDER)==WS_BORDER)
  { if(WndGetAttr(hWnd,WS_NEEDPAINT))
    { if(RectInRegion(&WNDPTR(hWnd)->Family->Vram->ExposeRegion, &WNDPTR(hWnd)->WndRect))
      { WndAddAttr(hWnd,WS_NCPAINT);
	    return;
	  }
	}
    SendMessage(hWnd,WM_NCPAINT,0,0);
  }
}/* * Map the window to possibly make it and its children visible on the screen. * This is a recursive routine which decrements the unmapcount values for * this window and all of its children, and causes exposure events for * those windows which become visible. */void  CM_ShowWindow(PWND pWnd, BOOL bSendMsg){   /*    * ShowWindow就是暴露一个窗体,暴露时会产生重绘事件    * 如果目标窗口当前在屏幕上可见,ShowWindow会使它及其子窗口再次完完重绘。    * ShowWindow不改变各窗口的层叠关系(Z-ORDER)。    */    if (pWnd->unmapcount) pWnd->unmapcount--;  	/*	 * If the window just became visible,	 * then draw its border, clear it to the background color, and	 * generate an exposure event.	 */    if (pWnd->unmapcount == 0)    {              SendMessage((HWND)pWnd, WM_SHOWWINDOW, true, 0);      	  RegionUnionRect(&pWnd->Family->Vram->ExposeRegion, &pWnd->WndRect);      PostMessage((HWND)pWnd, WM_PAINT, 0, 0);      if(WndGetAttr(pWnd,WS_BORDER))	     WndAddAttr(pWnd,WS_NCPAINT);    }	/*	 * Do the same thing for the children.	 */   for (pWnd = pWnd->Children; pWnd; pWnd = pWnd->Next)   {	CM_ShowWindow(pWnd, bSendMsg);   }}//---------------------------------------------------------------------------BOOL WINAPI ShowWindow(HWND hWnd, BOOL bShow){/*根窗口是特殊的窗口,不允许此操作*/ if(IsWnd(hWnd) && hWnd!=(HWND)g_RootWnd)  { if(bShow)    { if (WndGetAttr(hWnd,WS_HIDE))      {	WndSubAttr(hWnd,WS_HIDE);	    CM_ShowWindow((PWND)hWnd, true);	    return true;      }      else	  { SetFocus(hWnd);	    return true;	  }    }      else if ( !WndGetAttr(hWnd,WS_HIDE) )    { WndAddAttr(hWnd,WS_HIDE);	  CM_HideWindow((PWND)hWnd, true,true);      return true;    }  }  return false;}/* FUNCTION : EnableWindow * The EnableWindow function enables or disables mouse and keyboard input to the specified window or control.  * When input is disabled, the window does not receive input such as mouse clicks and key presses.  * When input is enabled, the window receives all input.  * If the window was previously disabled, the return value is nonzero. * If the window was not previously disabled, the return value is zero.  */BOOL WINAPI EnableWindow(HWND hWnd, BOOL bEnable){ if(bEnable && WndGetAttr(hWnd,WS_DISABLED))  {	/* enable window*/	WndSubAttr(hWnd,WS_DISABLED);	SendMessage(hWnd, WM_ENABLE, TRUE, 0L);  }  if(!bEnable && !(WndGetAttr(hWnd,WS_DISABLED)) )  { 	/* disable window*/	WndAddAttr(hWnd,WS_DISABLED);		/* FIXME: handle lost focus for child window of hwnd*/		/* FIXME: handle lost focus for capture window*/	if(hWnd == (HWND)g_CurrentFocus)    { CM_KillFocus(hWnd);    }	SendMessage(hWnd, WM_ENABLE, FALSE, 0L);  }  return WndGetAttr(hWnd,WS_DISABLED);}

/***************************************************************************
* FUNCTION
*   SetTabOrder
* DESCRIPTION
*   set window's tabstop order 
****************************************************************************/
void  SetTabOrder(HWND hWnd,int tabOrder)
{ if(!IsWnd(hWnd))
  { WNDPTR(hWnd)->TabOrder=tabOrder;
  }
}
/***************************************************************************
* FUNCTION
*   GetTabOrder
* DESCRIPTION
*   get window's tabstop order 
****************************************************************************/
int GetTabOrder(HWND hWnd)
{ if(!IsWnd(hWnd))
  { return WNDPTR(hWnd)->TabOrder;
  }
  return -1;
}/*---------------------------------------------------------------------------FUNCTION  GetFocusDESCRIPTION  获取键盘输入焦点  This function retrieves the handle of the window that has the keyboard focus---------------------------------------------------------------------------*/HWND WINAPI GetFocus(void){  return (HWND)g_CurrentFocus;}/*---------------------------------------------------------------------------FUNCTION  SetFocusDESCRIPTION  The SetFocus function sets the keyboard focus to the specified window.  The SetFocus function sends a WM_KILLFOCUS message to the window that

⌨️ 快捷键说明

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