📄 winapi.c
字号:
/******************************************************************************** Copyright 2006 National ASIC Center, All right Reserved** FILE NAME: winapi.c* PROGRAMMER: ming.c* Date of Creation: 2006/08/8** DESCRIPTION:** NOTE:** FUNCTIONS LIST:* -----------------------------------------------------------------------------** -----------------------------------------------------------------------------** MODIFICATION HISTORY* LastModify 2006/11/13******************************************************************************/#include "mingui.h"//---------------------------------------------------------------------------extern TMsgQueue g_SysMsgQueue;PWND g_CurrentFocus=NULL; /*当前焦点*/PWND g_LastFocus=NULL; /*上次焦点*/PWND g_RootWnd=NULL; /* root window pointer */TBLOCKHEAP g_ClipRegionHeap;TREGION WndClipRegion;//---------------------------------------------------------------------------static TWINDOWCLASS *GUIWndClsList=NULL; /* register class list*/static DWORD g_AutoWndID=0x80000000;
BOOL SomeWndNeedPaint=false;static void CM_DestroyAllWindows(void);static void CM_KillFocus(PWND pWnd);static void CM_RaiseWindow(PWND pWnd);static void CM_LowerWindow(PWND pWnd);static void CM_DestroyWindow(PWND pWnd,BOOL bSendMsg);static void CM_HideWindow(PWND pWnd,BOOL bChangeFocus, BOOL bSendMsg);static void CM_ShowWindow(PWND pWnd, BOOL bSendMsg);static void CM_RemoveMessage(HWND hWnd);static HWND CM_GetChildTabStop(HWND pWnd);//---------------------------------------------------------------------------static void CM_ExposeWindow(PWND pWnd);static void CM_ExposeArea(PWND pWnd,TRECT *prc);//---------------------------------------------------------------------------/* when a sub window is creating,the coordinate is relative to the parent *///---------------------------------------------------------------------------HWND WINAPI CreateWindow(LPCSTR lpClassName,LPCSTR lpWindowName,DWORD dwStyle,int x,int y,int nWidth,int nHeight,HWND parent,UINT id,void *extrData){ PWND pWnd,ParenWindow=(PWND)parent; TWNDCLASS *pclass; if(nWidth<=0 || nHeight<=0) { DebugAlert("CreateWindow error!\nInvalid window size!"); return NULL; } dwStyle &= WS_STYLEMASK; if(IsWnd(parent)) { ParenWindow=WNDPTR(parent); dwStyle |= WS_CHILD; } else if(!parent) { if(!g_RootWnd) { extern BOOL GUI_Initialize(void); if(!GUI_Initialize()) { DebugAlert("GUI fail to initialize!"); return NULL; } } ParenWindow=g_RootWnd; dwStyle &= ~WS_CHILD; } else { DebugAlert("CreateWindow error!\nInvalide parent window!"); return NULL; } pclass=FindClassByName(lpClassName); if(!pclass) { DebugAlert("CreateWindow error!\nInvalid class name!\n\"%s\"",lpClassName); return NULL; } else
{ extern int ScrollBar_DataSize(void);
int WndDataSize=sizeof(TWND) + pclass->cbWndExtra;
dwStyle|=pclass->dwStyle;
if( (dwStyle&(WS_VSCROLL|WS_BORDER))==(WS_VSCROLL|WS_BORDER) )
WndDataSize+=ScrollBar_DataSize();
pWnd=(PWND)GetMem(WndDataSize); if(!pWnd) return NULL;
}
pWnd->Mark=GUI_MARK_WND; /*set window mark*/ pWnd->ID=(id)?id:g_AutoWndID++; /*set window ID number*/ pWnd->TabOrder=pWnd->ID;
pWnd->Foreground=ColorMapToPixel((RGBQUAD *)&pclass->clForeground); pWnd->Background=ColorMapToPixel((RGBQUAD *)&pclass->clBackground); pWnd->Style=dwStyle; pWnd->Parent=ParenWindow; pWnd->Children = NULL; if(ParenWindow->Children) { if(dwStyle&WS_ALWAYSONBOTTOM) { PWND lastChild=ParenWindow->Children; while(lastChild->Next) lastChild=lastChild->Next; lastChild->Next=pWnd; pWnd->Next=NULL; pWnd->Prev=lastChild; } else if(WndGetAttr(ParenWindow->Children,WS_ALWAYSONTOP) && !(dwStyle&WS_ALWAYSONTOP)) { PWND sibwp=ParenWindow->Children; while(sibwp->Next) { if(!WndGetAttr(sibwp->Next,WS_ALWAYSONTOP))break; else sibwp = sibwp->Next; } pWnd->Next=sibwp->Next; if(sibwp->Next)sibwp->Next->Prev=pWnd; sibwp->Next=pWnd; pWnd->Prev=sibwp; } else { pWnd->Prev=NULL; pWnd->Next = ParenWindow->Children; ParenWindow->Children->Prev=pWnd; ParenWindow->Children = pWnd; } } else { pWnd->TabOrder=0; pWnd->Prev=NULL; pWnd->Next=NULL; ParenWindow->Children = pWnd; } pWnd->WndRect.left = ParenWindow->ClientRect.left + x; pWnd->WndRect.top = ParenWindow->ClientRect.top + y; pWnd->WndRect.right = pWnd->WndRect.left + nWidth; pWnd->WndRect.bottom = pWnd->WndRect.top + nHeight; if(ParenWindow==g_RootWnd) { pWnd->Family=(TWndFamily *)GetMem(sizeof(TWndFamily)); pWnd->Family->TopWnd=pWnd; pWnd->Family->HisFocus=NULL; pWnd->Family->CanvasChanged=false; pWnd->Family->Vram=CreateVRAM(pWnd->WndRect.left,pWnd->WndRect.top,nWidth,nHeight,NULL,true); InitRegion(&pWnd->Family->Vram->ExposeRegion, &g_ClipRegionHeap); } else { pWnd->Family=ParenWindow->Family; } pWnd->Canvas=NULL; pWnd->unmapcount = ParenWindow->unmapcount + 1; pWnd->WinClass=pclass; pWnd->HookProc=NULL; pWnd->HookMessage=0; pWnd->Logo=NULL; pWnd->UserData=0; pWnd->ExtraLong[0]=(long)extrData; pWnd->Caption.Text[0]='\0'; CM_AllocateWindowText(pWnd,lpWindowName,pclass->cbTextHeap); /* calculate size of the client area */ /*PS: WM_NCCALCSIZE message is previous to WM_CREATE*/ pWnd->ClientRect=pWnd->WndRect; if(WndGetAttr(pWnd,WS_BORDER)) { SendMessage((HWND)pWnd,WM_NCCALCSIZE,0,(LPARAM)&(pWnd->ClientRect)); } /*notify that window is created and is to be shown*/ if(SendMessage((HWND)pWnd,WM_CREATE,0,0)==-1) { CM_DestroyWindow(pWnd,false); return NULL; } if(!WndGetAttr(pWnd,WS_HIDE)) { CM_ShowWindow(pWnd, true); /*select default focus when window is shown*/ if(!pWnd->unmapcount && !pWnd->Family->HisFocus) { HWND newfocus; if(pWnd->Children) { newfocus=CM_GetChildTabStop((HWND)pWnd); if(!newfocus) newfocus=(HWND)pWnd; } else { newfocus=(HWND)pWnd; } SetFocus(newfocus); } } return (HWND)pWnd;}/*---------------------------------------------------------------------------FUNCTION CloseWindowDESCRIPTION 以异步方式安全关闭目标窗口及其所有子系窗口 异步方式依赖消息队列,一旦退出消息循环,此调用无效。INPUTS WinNode 待关闭的窗口的句柄---------------------------------------------------------------------------*/void WINAPI CloseWindow(HWND hWnd){ PostMessage(hWnd,WM_CLOSE,0,0);}/*---------------------------------------------------------------------------FUNCTION DestroyWindowDESCRIPTION 以同步方式销毁目标窗口及其所有子系窗口 在窗体调用过程嵌套很深时,宜采用异步方式关闭窗口。INPUTS WinNode 待销毁的窗口的句柄---------------------------------------------------------------------------*/void WINAPI DestroyWindow(HWND hWnd){ if(IsWnd(hWnd) && hWnd!=(HWND)g_RootWnd) CM_DestroyWindow((PWND)hWnd, true);}//---------------------------------------------------------------------------void CM_DestroyWindow(PWND pWnd,BOOL bSendMsg){ PWND prevwp; /* Unmap the window.*/ if (pWnd->unmapcount == 0) { WndAddAttr(pWnd,WS_HIDE); CM_HideWindow(pWnd, false, false); } if (pWnd == g_CurrentFocus) { CM_KillFocus(pWnd); } if(bSendMsg) { SendMessage((HWND)pWnd, WM_DESTROY, 0, 0); } /*Disable all sendmessages to this window*/ pWnd->WinClass = NULL; pWnd->HookProc = NULL; /* Destroy all children, sending WM_DESTROY messages. */ while (pWnd->Children) { CM_DestroyWindow(pWnd->Children, bSendMsg); } /* Remove this window from the child list of its parent.*/ prevwp = pWnd->Parent->Children; if (prevwp == pWnd) { pWnd->Parent->Children = pWnd->Next; if(pWnd->Next)pWnd->Next->Prev=NULL; } else { pWnd->Prev->Next=pWnd->Next; if(pWnd->Next)pWnd->Next->Prev=pWnd->Prev; } pWnd->Next = NULL; pWnd->Prev = NULL; /* Remove all messages from msg queue for this window*/ CM_RemoveMessage((HWND)pWnd); /* * Forget various information related to this window. * Then finally free the structure. */ CM_FreeWindowText(pWnd); if(pWnd->Parent==g_RootWnd) { ClearRegion(&pWnd->Family->Vram->ExposeRegion); FreeVRAM(pWnd->Family->Vram); FreeMem(pWnd->Family); } while(pWnd->Canvas) { ReleaseDC((HDC)pWnd->Canvas); } pWnd->ID=0; /*清除窗体ID号*/ pWnd->Mark=0; /*清除窗体标志*/ FreeMem(pWnd); /*销毁窗体所占内存*/ if(!g_RootWnd->Children) { extern void GUI_Destroy(void); GUI_Destroy(); }}void CM_DestroyAllWindows(void){ g_CurrentFocus=g_RootWnd; while(g_RootWnd && g_RootWnd->Children) { CM_DestroyWindow(g_RootWnd->Children,false); }}//---------------------------------------------------------------------------void CM_EraseBackgroud(PWND pWnd,TRECT *absArea){ TRECT rc,*pClip; HDC dc=GetClientDC(pWnd); rc.left = absArea->left - pWnd->ClientRect.left; rc.right = absArea->right - pWnd->ClientRect.left; rc.top = absArea->top - pWnd->ClientRect.top; rc.bottom= absArea->bottom - pWnd->ClientRect.top; pClip=&((TWndCanvas *)dc)->ClipRect; RectIntersect(pClip ,&rc); SendMessage((HWND)pWnd,WM_ERASEBKGND,(WPARAM)dc,(LPARAM)pClip); ReleaseDC(dc);}//---------------------------------------------------------------------------/*重绘pWnd在指定区域的所有子窗口(不包括pWnd本身),pWnd不能为根窗口及主窗口 注:此过程不改变刷新域,仅作为内部函数,不能单独调用*/static void CM_InvalidateChildren(PWND pWnd,TRECT *Rect){ pWnd=pWnd->Children; while(pWnd) { if(pWnd->unmapcount==0 && IsRectOverlap(Rect,&pWnd->WndRect)) { if(WndGetAttr(pWnd,WS_BORDER)) { WndAddAttr(pWnd,WS_NCPAINT); } PostMessage((HWND)pWnd, WM_PAINT, 0, 0); if(pWnd->Children) CM_InvalidateChildren(pWnd,Rect); } pWnd=pWnd->Next; }}//---------------------------------------------------------------------------/*重绘pWnd的所有子窗口(不包括pWnd本身),pWnd不能为根窗口及主窗口 注:此过程不改变刷新域,仅作为内部函数,不能单独调用*/
static void CM_InvalidateSubWindow(PWND pWnd){ pWnd=pWnd->Children; while(pWnd) { if(pWnd->unmapcount==0) { if(WndGetAttr(pWnd,WS_BORDER)) { WndAddAttr(pWnd,WS_NCPAINT); } PostMessage((HWND)pWnd, WM_PAINT, 0, 0); if(pWnd->Children) CM_InvalidateSubWindow(pWnd); } pWnd=pWnd->Next; }}//---------------------------------------------------------------------------//曝光窗体,尽可能不重绘*/
void CM_ExposeWindow(PWND pWnd){ if(pWnd && !pWnd->unmapcount) { RegionUnionRect(&pWnd->Family->Vram->ExposeRegion, &pWnd->WndRect); if(pWnd->Parent==g_RootWnd || pWnd==g_RootWnd) { PostMessage((HWND)pWnd, WM_EXPOSE, 0, 0); } else { if(WndGetAttr(pWnd,WS_BORDER)) { WndAddAttr(pWnd,WS_NCPAINT); } PostMessage((HWND)pWnd, WM_PAINT, 0, 0); if(pWnd->Children)CM_InvalidateSubWindow(pWnd); } }}//---------------------------------------------------------------------------//曝光窗体指定区域,尽可能不重绘*/void CM_ExposeArea(PWND pWnd,TRECT *prc){ if(pWnd && !pWnd->unmapcount && prc) { TRECT exposearea=pWnd->WndRect; if(RectIntersect(&exposearea,prc)) { RegionUnionRect(&pWnd->Family->Vram->ExposeRegion, &exposearea); } else return; if(pWnd->Parent==g_RootWnd || pWnd==g_RootWnd) { PostMessage((HWND)pWnd, WM_EXPOSE, 0, 0); } else { if(WndGetAttr(pWnd,WS_BORDER)) { WndAddAttr(pWnd,WS_NCPAINT);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -