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

📄 winuser.c

📁 神龙卡开发原代码
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * Copyright (c) 1999 Greg Haerr <greg@censoft.com> * * Win32 API upper level window creation, management and msg routines */#include "windows.h"#include "wintern.h"#include "device.h"#include <stdlib.h>#include <string.h>#define PAINTONCE	1	/* =1 to queue paint msgs only once*/#define MOUSETEST	1MWLISTHEAD mwMsgHead;		/* application msg queue*/MWLISTHEAD mwClassHead;		/* register class list*/int	mwSYSMETRICS_CYCAPTION = 12;	/* Y caption height*/int	mwSYSMETRICS_CXFRAME = 3;	/* width of frame border*/int	mwSYSMETRICS_CYFRAME = 3;	/* height of frame border*/int	mwSYSMETRICS_CXBORDER = 1;	/* width of single border*/int	mwSYSMETRICS_CYBORDER = 1;	/* width of single border*/int	mwSYSMETRICS_CXVSCROLL = 13;	/* width of vertical scrollbar*/int	mwSYSMETRICS_CYHSCROLL = 13;	/* height of horizontal scrollbar*/int	mwSYSMETRICS_CXHSCROLL = 13;	/* width of arrow on horz scrollbar*/int	mwSYSMETRICS_CYVSCROLL = 13;	/* height of arrow on vert scrollbar*/int	mwSYSMETRICS_CXDOUBLECLK = 2;	/* +/- X double click position*/int	mwSYSMETRICS_CYDOUBLECLK = 2;	/* +/- Y double click position*/int	mwpaintSerial = 1;		/* experimental alphablend sequencing*/int	mwpaintNC = 1;			/* experimental NC paint handling*/BOOL 	mwforceNCpaint = FALSE;		/* force NC paint when alpha blending*/static void MwOffsetChildren(HWND hwnd, int offx, int offy);LRESULT WINAPICallWindowProc(WNDPROC lpPrevWndFunc, HWND hwnd, UINT Msg, WPARAM wParam,	LPARAM lParam){	return (*lpPrevWndFunc)(hwnd, Msg, wParam, lParam);}LRESULT WINAPISendMessage(HWND hwnd, UINT Msg,WPARAM wParam,LPARAM lParam){	if(hwnd && hwnd->pClass) {		hwnd->paintSerial = mwpaintSerial; /* assign msg sequence #*/		return (*hwnd->pClass->lpfnWndProc)(hwnd, Msg, wParam, lParam);	}	return 0;}BOOL WINAPIPostMessage(HWND hwnd, UINT Msg, WPARAM wParam, LPARAM lParam){	MSG *	pMsg;#if PAINTONCE	/* don't queue paint msgs, set window paint status instead*/	if(Msg == WM_PAINT) {		hwnd->gotPaintMsg = PAINT_NEEDSPAINT;		return TRUE;	}#endif#if MOUSETEST	/* replace multiple mouse messages with one for better mouse handling*/	if(Msg == WM_MOUSEMOVE) {		PMWLIST	p;		for(p=mwMsgHead.head; p; p=p->next) {			pMsg = GdItemAddr(p, MSG, link);			if(pMsg->hwnd == hwnd && pMsg->message == Msg) {				pMsg->wParam = wParam;				pMsg->lParam = lParam;				pMsg->time = GetTickCount();				pMsg->pt.x = cursorx;				pMsg->pt.y = cursory;				return TRUE;			}		}	}#endif	pMsg = GdItemNew(MSG);	if(!pMsg)		return FALSE;	pMsg->hwnd = hwnd;	pMsg->message = Msg;	pMsg->wParam = wParam;	pMsg->lParam = lParam;	pMsg->time = GetTickCount();	pMsg->pt.x = cursorx;	pMsg->pt.y = cursory;	GdListAdd(&mwMsgHead, &pMsg->link);	return TRUE;}/* currently, we post to the single message queue, regardless of thread*/BOOL WINAPIPostThreadMessage(DWORD dwThreadId, UINT Msg, WPARAM wParam, LPARAM lParam){	return PostMessage(NULL, Msg, wParam, lParam);}VOID WINAPIPostQuitMessage(int nExitCode){	PostMessage(NULL, WM_QUIT, nExitCode, 0L);}static BOOLchkPaintMsg(HWND wp, LPMSG lpMsg){		/*		 * Tricky: only repaint window if there		 * isn't a mouse capture (window move) in progress,		 * or the window is the moving window.		 */		if(wp->gotPaintMsg == PAINT_NEEDSPAINT &&		    (!dragwp || dragwp == wp)) {	paint:			wp->gotPaintMsg = PAINT_PAINTED;			lpMsg->hwnd = wp;			lpMsg->message = WM_PAINT;			lpMsg->wParam = 0;			lpMsg->lParam = 0;			lpMsg->time = 0;			lpMsg->pt.x = cursorx;			lpMsg->pt.y = cursory;			return TRUE;		} else if(dragwp && wp->gotPaintMsg == PAINT_NEEDSPAINT) {			/* All other windows we'll check for			 * event input first, then allow repaint.			 */			MwSelect();			if(mwMsgHead.head == NULL)				goto paint;		}	return FALSE;}BOOL WINAPIPeekMessage(LPMSG lpMsg, HWND hwnd, UINT uMsgFilterMin, UINT uMsgFilterMax,	UINT wRemoveMsg){	HWND	wp;	PMSG	pNxtMsg;	/* check if no messages in queue*/	if(mwMsgHead.head == NULL) {#if PAINTONCE		/* check all windows for pending paint messages*/		for(wp=listwp; wp; wp=wp->next) {			if(!(wp->style & WS_CHILD)) {				if(chkPaintMsg(wp, lpMsg))					return TRUE;			}		}		for(wp=listwp; wp; wp=wp->next) {			if(wp->style & WS_CHILD) {				if(chkPaintMsg(wp, lpMsg))					return TRUE;			}		}#endif		MwSelect();	}	if(mwMsgHead.head == NULL)		return FALSE;	pNxtMsg = (PMSG)mwMsgHead.head;	if(wRemoveMsg & PM_REMOVE)		GdListRemove(&mwMsgHead, &pNxtMsg->link);	*lpMsg = *pNxtMsg;	if(wRemoveMsg & PM_REMOVE)		GdItemFree(pNxtMsg);	return TRUE;}BOOL WINAPIGetMessage(LPMSG lpMsg,HWND hwnd,UINT wMsgFilterMin,UINT wMsgFilterMax){	/*	 * currently MwSelect() must poll for VT switch reasons,	 * so this code will work	 */	while(!PeekMessage(lpMsg, hwnd, wMsgFilterMin, wMsgFilterMax,PM_REMOVE))		continue;	return lpMsg->message != WM_QUIT;}BOOL WINAPI TranslateMessage(CONST MSG *lpMsg){	return FALSE;}LONG WINAPIDispatchMessage(CONST MSG *lpMsg){	return SendMessage(lpMsg->hwnd, lpMsg->message, lpMsg->wParam,		lpMsg->lParam);}/* find the registered window class struct by name*/PWNDCLASSMwFindClassByName(LPCSTR lpClassName){	PMWLIST		p;	PWNDCLASS	pClass;	for(p=mwClassHead.head; p; p=p->next) {		pClass = GdItemAddr(p, WNDCLASS, link);		if(strcmpi(pClass->szClassName, lpClassName) == 0)			return pClass;	}	return NULL;}ATOM WINAPIRegisterClass(CONST WNDCLASS *lpWndClass){	PWNDCLASS	pClass;	/* check if already present*/	pClass = MwFindClassByName(lpWndClass->lpszClassName);	if(pClass)		return 0;		/* copy class into new struct*/	pClass = GdItemNew(WNDCLASS);	if(!pClass)		return 0;	*pClass = *lpWndClass;	strcpy(pClass->szClassName, lpWndClass->lpszClassName);	GdListAdd(&mwClassHead, &pClass->link);	return 1;}BOOL WINAPIUnregisterClass(LPCSTR lpClassName, HINSTANCE hInstance){	PWNDCLASS	pClass;	pClass = MwFindClassByName(lpClassName);	if(!pClass)		return FALSE;	GdListRemove(&mwClassHead, &pClass->link);	DeleteObject(pClass->hbrBackground);	GdItemFree(pClass);	return TRUE;}HWND WINAPICreateWindowEx(DWORD dwExStyle, LPCSTR lpClassName, LPCSTR lpWindowName,	DWORD dwStyle, int x, int y, int nWidth, int nHeight,	HWND hwndParent, HMENU hMenu, HINSTANCE hInstance, LPVOID lpParam){	HWND		pwp;		/* parent window */	HWND		wp;		/* new window */	HWND		hwndOwner;	PWNDCLASS	pClass;	CREATESTRUCT	cs;	static int	nextx = 20;	static int	nexty = 20;	pClass = MwFindClassByName(lpClassName);	if(!pClass)		return NULL;	if(x == CW_USEDEFAULT || y == CW_USEDEFAULT) {		x = nextx;		nextx += 10;		y = nexty;		nexty += 10;		if(nextx > 200)			nextx = nexty = 20;	}	if(nWidth == CW_USEDEFAULT || nHeight == CW_USEDEFAULT) {		nWidth = 250;		nHeight = 250;	}	if(hwndParent == NULL) {		if(dwStyle & WS_CHILD)			return NULL;		pwp = rootwp;	} else		pwp = hwndParent;	/* WS_POPUP z-order parent is the root window (passed parent is owner)*/	if(dwStyle & WS_POPUP)		pwp = rootwp;		/* force clip to root, not z-parent*/	/* window owner is NULL for child windows, else it's the passed parent*/	if(dwStyle & WS_CHILD)		hwndOwner = NULL;	else hwndOwner = hwndParent;	wp = (HWND)GdItemAlloc(sizeof(struct hwnd) - 1 + pClass->cbWndExtra);	if(!wp)		return NULL;	/* force all clipping on by default*/	dwStyle |= WS_CLIPSIBLINGS | WS_CLIPCHILDREN;	wp->pClass = pClass;	wp->style = dwStyle;	wp->exstyle = dwExStyle;	wp->parent = pwp;	wp->owner = hwndOwner;	wp->children = NULL;	wp->siblings = pwp->children;	pwp->children = wp;	wp->next = listwp;	listwp = wp;	wp->winrect.left = pwp->clirect.left + x;	wp->winrect.top = pwp->clirect.top + y;	wp->winrect.right = wp->winrect.left + nWidth;	wp->winrect.bottom = wp->winrect.top + nHeight;	wp->cursor = pwp->cursor;	wp->cursor->usecount++;	wp->unmapcount = pwp->unmapcount + 1;	wp->id = (int)hMenu;	wp->gotPaintMsg = PAINT_PAINTED;	strzcpy(wp->szTitle, lpWindowName, sizeof(wp->szTitle));#if UPDATEREGIONS	wp->update = GdAllocRegion();#endif	wp->nextrabytes = pClass->cbWndExtra;	/* calculate client area*/	MwCalcClientRect(wp);	cs.lpCreateParams = lpParam;	cs.hInstance = hInstance;	cs.hMenu = hMenu;	cs.hwndParent = hwndParent;	cs.cy = nHeight;	cs.cx = nWidth;	cs.y = y;	cs.x = x;	cs.style = dwStyle;	cs.lpszName = lpWindowName;	cs.lpszClass = lpClassName;	cs.dwExStyle = dwExStyle;	if(SendMessage(wp, WM_CREATE, 0, (LPARAM)(LPSTR)&cs) == -1) {		MwDestroyWindow(wp, FALSE);		return NULL;	}	/* send SIZE and MOVE msgs*/	MwSendSizeMove(wp, TRUE, TRUE);	if(wp->style & WS_VISIBLE) {		MwShowWindow(wp, TRUE);		SetFocus(wp);	}	return wp;}BOOL WINAPIDestroyWindow(HWND hwnd){	MwDestroyWindow(hwnd, TRUE);	return TRUE;}/* * Destroy the specified window, and all of its children. * This is a recursive routine. */voidMwDestroyWindow(HWND hwnd,BOOL bSendMsg){	HWND	wp = hwnd;	HWND	prevwp;	PMWLIST	p;	PMSG	pmsg;	if (wp == rootwp)		return;	/*	 * Unmap the window.	 */	if (wp->unmapcount == 0)		MwHideWindow(wp, FALSE, FALSE);	if(bSendMsg)		SendMessage(hwnd, WM_DESTROY, 0, 0L);	/*	 * Disable all sendmessages to this window.	 */	wp->pClass = NULL;	/*	 * Destroy all children, sending WM_DESTROY messages.	 */	while (wp->children)		MwDestroyWindow(wp->children, bSendMsg);	/*	 * Free any cursor associated with the window.	 */	if (wp->cursor->usecount-- == 1) {		free(wp->cursor);		wp->cursor = NULL;	}	/*	 * Remove this window from the child list of its parent.	 */	prevwp = wp->parent->children;	if (prevwp == wp)		wp->parent->children = wp->siblings;	else {		while (prevwp->siblings != wp)			prevwp = prevwp->siblings;		prevwp->siblings = wp->siblings;	}	wp->siblings = NULL;	/*	 * Remove this window from the complete list of windows.	 */	prevwp = listwp;	if (prevwp == wp)		listwp = wp->next;	else {		while (prevwp->next != wp)			prevwp = prevwp->next;		prevwp->next = wp->next;	}	wp->next = NULL;	/*	 * Forget various information related to this window.	 * Then finally free the structure.	 */	/* Remove all messages from msg queue for this window*/	for(p=mwMsgHead.head; p; ) {		pmsg = GdItemAddr(p, MSG, link);		if(pmsg->hwnd == wp) {			p = p->next;			GdListRemove(&mwMsgHead, &pmsg->link);			GdItemFree(p);		} else			p = p->next;	}	/* FIXME: destroy hdc's relating to window?*/	if (wp == capturewp) {		capturewp = NULL;		MwCheckMouseWindow();	}	if (wp == MwGetTopWindow(focuswp))		SetFocus(rootwp->children? rootwp->children: rootwp);	/* destroy private DC*/	if(wp->owndc) {		HDC hdc = wp->owndc;		wp->owndc = NULL;	/* force destroy with ReleaseDC*/		ReleaseDC(wp, hdc);	}#if UPDATEREGIONS	GdDestroyRegion(wp->update);#endif	GdItemFree(wp);

⌨️ 快捷键说明

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