📄 winbase.c
字号:
/* Copyright (C) 2004-2005 Li Yudong*//*** This program is free software; you can redistribute it and/or modify** it under the terms of the GNU General Public License as published by** the Free Software Foundation; either version 2 of the License, or** (at your option) any later version.**** This program is distributed in the hope that it will be useful,** but WITHOUT ANY WARRANTY; without even the implied warranty of** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the** GNU General Public License for more details.**** You should have received a copy of the GNU General Public License** along with this program; if not, write to the Free Software** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA*/#include "../include/common.h"#include "../include/blockheap.h"#include "../include/mouse.h"#include "../include/keyboard.h"#include "../include/framebuffer.h"#include "../include/rect.h"#include "../include/invalidregion.h" #include "../include/clipregion.h" #include "../include/hdc.h"#include "../include/hdcbitblt.h"#include "../include/lguiapp.h"#include "../include/ipcmsg.h"#include "../include/message.h"#include "../include/gdi.h"#include "../include/regclass.h"#include "../include/shmem.h"#include "../include/caret.h"#include "../include/winnc.h"#include "../include/winbase.h"#include "../include/window.h"#include "../include/scrollbar.h"#include "../include/button.h"#include "../include/system.h"extern PWindowsTree _lGUI_pImeWindow;extern PWindowsTree _lGUI_pSkbWindow;extern PWindowsTree _lGUI_pActiveWin;extern PWindowsTree _lGUI_pWindowsTree;extern PWindowsTree _lGUI_pFocus;extern PlGUIAppStat _lGUI_pAppStat;extern WndCaptureMouse _lGUI_wndCaptureMouse;extern int _lGUI_iBytesDataType;//semaphore for synchronization between client and serverstatic pthread_mutex_t mutex_cs;//Re-calculate clip region of a windowvoid ReCalClipRegion( const HWND hWnd){ int iWinType; iWinType=GetWinType(hWnd); switch(iWinType){ case WS_CONTROL: ReCalClipRegionControl(hWnd); break; case WS_CHILD: ReCalClipRegionChild(hWnd); break; case WS_MAIN: ReCalClipRegionMain(hWnd); break; case WS_DESKTOP: ReCalClipRegionDesktop(hWnd); break; }}//Re-calculate clip region of desktopvoid ReCalClipRegionDesktop( const HWND hWnd){ RECT rc; PlGUIAppStat pStat; PWindowsTree pControl; PWindowsTree pWin; pWin=(PWindowsTree)hWnd; SetRect(&rc,0,0,SCREEN_WIDTH-1,SCREEN_HEIGHT-1); EmptyClipRegion(pWin->pClipRgn); AddRectClipRegion (pWin->pClipRgn, &rc); CopyRect(&(pWin->pClipRgn->rcBound),&rc); //ime window if(IsVisible((HWND)_lGUI_pImeWindow)) SubtractClipRegion(pWin->pClipRgn,&_lGUI_pImeWindow->rect); //soft key window if(IsVisible((HWND)_lGUI_pSkbWindow)) SubtractClipRegion(pWin->pClipRgn,&_lGUI_pSkbWindow->rect); //clipped by all application main window pStat=_lGUI_pAppStat; while(pStat){ SubtractClipRegion(pWin->pClipRgn,&(pStat->rc)); pStat=pStat->pNext; } //clipped by all desktop control pControl=pWin->pControlHead; while(pControl){ if(!IsHideWindow((HWND)pControl)) SubtractClipRegion(pWin->pClipRgn,&(pControl->rect)); pControl=pControl->pNext; }}//Re-calculate clip region of main windowvoid ReCalClipRegionMain( const HWND hWnd){ PClipRect pRect; RECT rect,rc; PWindowsTree pChild,pControl; PWindowsTree pWin; pWin=(PWindowsTree)hWnd; //free clip region EmptyClipRegion(pWin->pClipRgn); if(IsEmptyClipRegion(_lGUI_pAppStat->pClipRgn)) return; //copy the origion clip region maintained by server CopyClipRegion (pWin->pClipRgn, _lGUI_pAppStat->pClipRgn); scrGetClientRect((HWND)pWin,&rect); //clipped by its sub window pChild=pWin->pChildHead; while(pChild){ if(!IsHideWindow((HWND)pChild)){ IntersectRect(&rc,&(pChild->rect),&rect); SubtractClipRegion(pWin->pClipRgn,&rc); } pChild=pChild->pNext; } //clipped by its control pControl=pWin->pControlHead; while(pControl){ if(!IsHideWindow((HWND)pControl)){ IntersectRect(&rc,&(pControl->rect),&rect); SubtractClipRegion(pWin->pClipRgn,&rc); } pControl=pControl->pNext; }}//Re-calculate clip region of child windowvoid ReCalClipRegionChild( const HWND hWnd){ PWindowsTree pBrother,pControl; PWindowsTree pWin; RECT rc,rect; pWin=(PWindowsTree)hWnd; //free clip region EmptyClipRegion(pWin->pClipRgn); if(IsEmptyClipRegion(_lGUI_pAppStat->pClipRgn)) return; //copy the origion clip region maintained by server CopyClipRegion (pWin->pClipRgn, _lGUI_pAppStat->pClipRgn); //clip noclient area of the mainwindow scrGetClientRect((HWND)pWin->pParent,&rect); IntersectClipRegion(pWin->pClipRgn,&rect); //intersect with the windows boundary rect IntersectClipRegion(pWin->pClipRgn,&(pWin->rect)); //clipped by brother which Z order is bigger than its. pBrother=pWin->pParent->pChildHead; while(pBrother!=pWin){ if(!IsHideWindow((HWND)pBrother)) SubtractClipRegion(pWin->pClipRgn,&(pBrother->rect)); pBrother=pBrother->pNext; } //clipped by control scrGetClientRect((HWND)pWin,&rect); pControl=pWin->pControlHead; while(pControl){ if(!IsHideWindow((HWND)pControl)) IntersectRect(&rc,&(pControl->rect),&rect); SubtractClipRegion(pWin->pClipRgn,&rc); pControl=pControl->pNext; }}//Re-calculate clip region of controlvoid ReCalClipRegionControl( const HWND hWnd){ PlGUIAppStat pStat; PWindowsTree pControl; RECT rc; PWindowsTree pWin; PWindowsTree pChild; pWin=(PWindowsTree)hWnd; EmptyClipRegion(pWin->pClipRgn); if(!IsVisible(pWin)) return; switch(GetWinType((HWND)(pWin->pParent))){ case WS_DESKTOP: AddRectClipRegion (pWin->pClipRgn, &(pWin->rect)); CopyRect(&(pWin->pClipRgn->rcBound),&(pWin->rect)); //ime Window if(IsVisible((HWND)_lGUI_pImeWindow)) SubtractClipRegion(pWin->pClipRgn,&_lGUI_pImeWindow->rect); //soft key window if(IsVisible((HWND)_lGUI_pSkbWindow)) SubtractClipRegion(pWin->pClipRgn,&_lGUI_pSkbWindow->rect); //Intersect with desktop rect IntersectClipRegion(pWin->pClipRgn,&(pWin->pParent->rect)); //clipped by all application main window pStat=_lGUI_pAppStat; while(pStat){ SubtractClipRegion(pWin->pClipRgn,&(pStat->rc)); pStat=pStat->pNext; } //clipped by brother which Z order is bigger than its pControl=pWin->pParent->pControlHead; while(pControl!=pWin){ if(!IsHideWindow((HWND)pControl)) SubtractClipRegion(pWin->pClipRgn,&(pControl->rect)); pControl=pControl->pNext; } break; case WS_MAIN: if(IsEmptyClipRegion(_lGUI_pAppStat->pClipRgn)) return; CopyClipRegion (pWin->pClipRgn, _lGUI_pAppStat->pClipRgn); //clip noclient area of the mainwindow scrGetClientRect((HWND)pWin->pParent,&rc); IntersectClipRegion(pWin->pClipRgn,&rc); IntersectClipRegion(pWin->pClipRgn,&(pWin->rect)); //clipped by all sub window pChild=pWin->pParent->pChildHead; while(pChild){ if(!IsHideWindow((HWND)pChild)) SubtractClipRegion(pWin->pClipRgn,&(pChild->rect)); pChild=pChild->pNext; } //clipped by brother which Z order is bigger than its pControl=pWin->pParent->pControlHead; while(pControl!=pWin){ if(!IsHideWindow((HWND)pControl)) SubtractClipRegion(pWin->pClipRgn,&(pControl->rect)); pControl=pControl->pNext; } break; case WS_CHILD: if(IsEmptyClipRegion(_lGUI_pAppStat->pClipRgn)) return; CopyClipRegion (pWin->pClipRgn, _lGUI_pAppStat->pClipRgn); //clip noclient area of the mainwindow scrGetClientRect((HWND)_lGUI_pWindowsTree,&rc); IntersectClipRegion(pWin->pClipRgn,&rc); //IntersectClipRegion(pWin->pClipRgn,&(pWin->pParent->rect)); scrGetClientRect((HWND)(pWin->pParent),&rc); IntersectClipRegion(pWin->pClipRgn,&rc); pChild=_lGUI_pWindowsTree->pChildHead; while(pChild!=pWin->pParent){ if(!IsHideWindow((HWND)pChild)) SubtractClipRegion(pWin->pClipRgn,&(pChild->rect)); pChild=pChild->pNext; } IntersectClipRegion(pWin->pClipRgn,&(pWin->rect)); pControl=pWin->pParent->pControlHead; while(pControl!=pWin){ if(!IsHideWindow((HWND)pControl)) SubtractClipRegion(pWin->pClipRgn,&(pControl->rect)); pControl=pControl->pNext; } break; }}//Initialize window clip and invalidate regionBOOL InitWindowRgn( const HWND hWnd){ PWindowsTree pWin; pWin=(PWindowsTree)hWnd; //clip region pWin->pClipRgn=(PClipRegion)malloc(sizeof(ClipRegion)); if(!(pWin->pClipRgn)) return false; InitClipRegion(pWin->pClipRgn); //backup clip region pWin->pBackClipRgn=(PClipRegion)malloc(sizeof(ClipRegion)); if(!(pWin->pBackClipRgn)) return false; InitClipRegion(pWin->pBackClipRgn); //invalidate regioin pWin->pInvRgn=(PInvalidRegion)malloc(sizeof(InvalidRegion)); if(!(pWin->pInvRgn)) return false; InitInvalidRegion(pWin->pInvRgn); return true;}//repaint all other windows which covered by current windowvoid RePaintCoveredWindow( const HWND hWnd){ RECT rc; PWindowsTree pCurWin; PWindowsTree pWin; PWindowsTree pControl; BOOL bChild; pWin=(PWindowsTree)hWnd; bChild = IsChildWin(hWnd); CopyRect(&rc,&(pWin->rect)); //1.parent window scrInvalidateRect((HWND)(pWin->pParent),&rc,true); //2.it's brother which Z order is small than its pCurWin=pWin->pNext; while(pCurWin){ if(IsIntersect(&(pWin->rect),&(pCurWin->rect))){ scrInvalidateRect((HWND)pCurWin,&rc,true); //controls of this window's brother should be repainted if(bChild){ pControl = pCurWin->pControlHead; while(pControl){ if(IsIntersect(&(pWin->rect),&(pCurWin->rect))) scrInvalidateRect((HWND)pControl,&rc,true); pControl = pControl->pNext; } } } pCurWin=pCurWin->pNext; } //3.if this is a child window, we should repaint the controls of its parent pCurWin = pWin->pParent->pControlHead; while(pCurWin){ if(IsIntersect(&(pWin->rect),&(pCurWin->rect))){ scrInvalidateRect((HWND)pCurWin,&rc,true); } pCurWin = pCurWin->pNext; }}//Re-calculate all windows' clip region in an applicationvoid ReCalClipRegionApp(){ RECT rect; PWindowsTree pChild,pControl; //main window ReCalClipRegionMain(_lGUI_pWindowsTree); //sub windows pChild=_lGUI_pWindowsTree->pChildHead; while(pChild){ ReCalClipRegionChild(pChild); pControl=pChild->pControlHead; while(pControl){ ReCalClipRegionControl(pControl); pControl=pControl->pNext; } pChild=pChild->pNext; } //controls pControl=_lGUI_pWindowsTree->pControlHead; while(pControl){ ReCalClipRegionControl(pControl); pControl=pControl->pNext; }}//screen coordsBOOL scrInvalidateRect( const HWND hWnd, const PRECT lpRect, BOOL bErase){ PWindowsTree pWin; pWin=(PWindowsTree)hWnd; if(!pWin) return false; if(!lpRect){ AddRectInvalidRegion(pWin->pInvRgn,&(pWin->rect),bErase); SendPaintMessage(hWnd); } else{ if(!IsIntersect (lpRect, &(pWin->rect))) return true; AddRectInvalidRegion(pWin->pInvRgn,lpRect,bErase); SendPaintMessage(hWnd); return true; } return true;}//window coordsysBOOL winInvalidateRect( const HWND hWnd, const PRECT lpRect, BOOL bErase){ PWindowsTree pWin; RECT rc; pWin=(PWindowsTree)hWnd; if(!pWin) return false; if(!lpRect){ GetWindowRect(hWnd,&rc); return scrInvalidateRect(hWnd,&rc,bErase); } else{ CopyRect(&rc,lpRect); WindowToScreenRect(hWnd,&rc); return scrInvalidateRect(hWnd,&rc,bErase); } return true;}//declare that one block of a window is invalidate//to make window redraw itselfBOOL GUIAPI InvalidateRect( const HWND hWnd, const PRECT lpRect, BOOL bErase){ RECT rc; PWindowsTree pWin; pWin=(PWindowsTree)hWnd; if(!pWin) return false; if(!lpRect){ scrGetClientRect(hWnd,&rc); return scrInvalidateRect(hWnd,&rc,bErase); } else{ CopyRect(&rc,lpRect); ClientToScreenRect(hWnd,&rc); return scrInvalidateRect(hWnd,&rc,bErase); } return true;}HDC GUIAPI BeginPaint( const HWND hWnd, LPPAINTSTRUCT lpPaint){ int iWinWidth, iWinHeight; PWindowsTree pWin; RECT rc; PClipRegion pcrExchange; PClipRect pClipRect; HDC hDC,hDCMem; HDC hDCClient, hDCClientMem; RECT rcTop,rcBottom,rcLeft,rcRight; BOOL bFlag=false; pWin=(PWindowsTree)hWnd; if(!pWin) return false; //whether the invalid region is empty if(IsEmptyInvalidRegion(pWin->pInvRgn)) return NULL; if(!IntersectRect(&rc,&(pWin->pInvRgn->rcBound), &(pWin->pClipRgn->rcBound))){ return NULL; } hDC=GetWindowDC(hWnd); if(!hDC) return NULL; if(!(lpPaint->bPaintDirect)){ hDCMem=CreateCompatibleDC(hDC); if(!hDCMem) return NULL; ReleaseDC(hWnd,hDC); hDC=hDCMem; } lpPaint->hdc=hDC; //send erase background message SendMessage(hWnd,LMSG_ERASEBKGND,(WPARAM)hDC,(LPARAM)NULL); //calculate new clip region according to invalid region if(!IsEmptyClipRegion(pWin->pBackClipRgn)) EmptyClipRegion(pWin->pBackClipRgn); ClipRgnIntersectInvRgn(pWin->pBackClipRgn,pWin->pClipRgn,pWin->pInvRgn); //exchange clip region pointer pcrExchange=pWin->pBackClipRgn; pWin->pBackClipRgn=pWin->pClipRgn; pWin->pClipRgn=pcrExchange; //Get the 4 noclient bound rect wndGetBoundRect(hWnd,&rcTop,&rcBottom,&rcLeft,&rcRight); if(!IsRectEmpty(&rcTop)){ pClipRect=pWin->pClipRgn->pHead; while(pClipRect){ if(IsIntersect(&pClipRect->rect,&rcTop)){ bFlag=true; goto okret; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -