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

📄 message.c

📁 ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机理和API函数调用几乎相同。甚至可以兼容XP的程序。喜欢研究系统内核的人可以看一看。
💻 C
📖 第 1 页 / 共 2 页
字号:

	if (MsgQueueCtr != MAXMESSAGES)
	{
		MsgQueue[MsgQueueOnCtr].wnd = wnd;
		MsgQueue[MsgQueueOnCtr].msg = msg;
		MsgQueue[MsgQueueOnCtr].p1 = p1;
		MsgQueue[MsgQueueOnCtr].p2 = p2;
		if (++MsgQueueOnCtr == MAXMESSAGES)
			MsgQueueOnCtr = 0;
		MsgQueueCtr++;
	}
}

/* --------- send a message to a window ----------- */
int DfSendMessage(DFWINDOW wnd, DFMESSAGE msg, PARAM p1, PARAM p2)
{
    int rtn = TRUE, x, y;

#ifdef INCLUDE_LOGGING
	LogMessages(wnd, msg, p1, p2);
#endif
    if (wnd != NULL)
        switch (msg)    {
            case PAINT:
            case BORDER:
                /* ------- don't send these messages unless the
                    window is visible -------- */
                if (isVisible(wnd))
	                rtn = (*wnd->wndproc)(wnd, msg, p1, p2);
                break;
            case RIGHT_BUTTON:
            case LEFT_BUTTON:
            case DOUBLE_CLICK:
            case DFM_BUTTON_RELEASED:
                /* --- don't send these messages unless the
                    window is visible or has captured the mouse -- */
                if (isVisible(wnd) || wnd == CaptureMouse)
	                rtn = (*wnd->wndproc)(wnd, msg, p1, p2);
                break;
            case KEYBOARD:
            case SHIFT_CHANGED:
                /* ------- don't send these messages unless the
                    window is visible or has captured the keyboard -- */
                if (!(isVisible(wnd) || wnd == CaptureKeyboard))
	                break;
            default:
                rtn = (*wnd->wndproc)(wnd, msg, p1, p2);
                break;
        }
    /* ----- window processor returned true or the message was sent
        to no window at all (NULL) ----- */
    if (rtn != FALSE)    {
        /* --------- process messages that a window sends to the
            system itself ---------- */
        switch (msg)    {
            case DFM_STOP:
				StopMsg();
                break;
            /* ------- clock messages --------- */
            case CAPTURE_CLOCK:
                Cwnd = wnd;
                set_timer(clocktimer, 0);
                break;
            case RELEASE_CLOCK:
                Cwnd = NULL;
                disable_timer(clocktimer);
                break;
            /* -------- keyboard messages ------- */
            case KEYBOARD_CURSOR:
                if (wnd == NULL)
                    cursor((int)p1, (int)p2);
                else if (wnd == inFocus)
                    cursor(GetClientLeft(wnd)+(int)p1,
                                GetClientTop(wnd)+(int)p2);
                break;
            case CAPTURE_KEYBOARD:
                if (p2)
                    ((DFWINDOW)p2)->PrevKeyboard=CaptureKeyboard;
                else
                    wnd->PrevKeyboard = CaptureKeyboard;
                CaptureKeyboard = wnd;
                NoChildCaptureKeyboard = (int)p1;
                break;
			case RELEASE_KEYBOARD:
				if (wnd != NULL)
				{
					if (CaptureKeyboard == wnd || (int)p1)
						CaptureKeyboard = wnd->PrevKeyboard;
					else
					{
						DFWINDOW twnd = CaptureKeyboard;
						while (twnd != NULL)
						{
							if (twnd->PrevKeyboard == wnd)
							{
								twnd->PrevKeyboard = wnd->PrevKeyboard;
								break;
							}
							twnd = twnd->PrevKeyboard;
						}
						if (twnd == NULL)
							CaptureKeyboard = NULL;
					}
					wnd->PrevKeyboard = NULL;
				}
				else
					CaptureKeyboard = NULL;
				NoChildCaptureKeyboard = FALSE;
				break;
            case CURRENT_KEYBOARD_CURSOR:
                curr_cursor(&x, &y);
                *(int*)p1 = x;
                *(int*)p2 = y;
                break;
            case SAVE_CURSOR:
                savecursor();
                break;
            case RESTORE_CURSOR:
                restorecursor();
                break;
            case HIDE_CURSOR:
                normalcursor();
                hidecursor();
                break;
            case SHOW_CURSOR:
                if (p1)
                    set_cursor_size(100);
                else
                    set_cursor_size(5);
                unhidecursor();
                break;

			case CAPTURE_MOUSE:
				if (p2)
					((DFWINDOW)p2)->PrevMouse = CaptureMouse;
				else
					wnd->PrevMouse = CaptureMouse;
				CaptureMouse = wnd;
				NoChildCaptureMouse = (int)p1;
				break;

			case RELEASE_MOUSE:
				if (wnd != NULL)
				{
					if (CaptureMouse == wnd || (int)p1)
						CaptureMouse = wnd->PrevMouse;
					else
					{
						DFWINDOW twnd = CaptureMouse;
						while (twnd != NULL)
						{
							if (twnd->PrevMouse == wnd)
							{
								twnd->PrevMouse = wnd->PrevMouse;
								break;
							}
							twnd = twnd->PrevMouse;
						}
						if (twnd == NULL)
							CaptureMouse = NULL;
					}
					wnd->PrevMouse = NULL;
				}
				else
					CaptureMouse = NULL;
				NoChildCaptureMouse = FALSE;
				break;

			default:
				break;
		}
	}
	return rtn;
}

static DFRECT VisibleRect(DFWINDOW wnd)
{
	DFRECT rc = WindowRect(wnd);
	if (!TestAttribute(wnd, NOCLIP))
	{
		DFWINDOW pwnd = GetParent(wnd);
		DFRECT prc;
		prc = ClientRect(pwnd);
		while (pwnd != NULL)
		{
			if (TestAttribute(pwnd, NOCLIP))
				break;
			rc = subRectangle(rc, prc);
			if (!ValidRect(rc))
				break;
			if ((pwnd = GetParent(pwnd)) != NULL)
				prc = ClientRect(pwnd);
		}
	}
	return rc;
}

/* ----- find window that mouse coordinates are in --- */
static DFWINDOW inWindow(DFWINDOW wnd, int x, int y)
{
	DFWINDOW Hit = NULL;
	while (wnd != NULL)	{
		if (isVisible(wnd))	{
			DFWINDOW wnd1;
			DFRECT rc = VisibleRect(wnd);
			if (InsideRect(x, y, rc))
				Hit = wnd;
			if ((wnd1 = inWindow(LastWindow(wnd), x, y)) != NULL)
				Hit = wnd1;
			if (Hit != NULL)
				break;
		}
		wnd = PrevWindow(wnd);
	}
	return Hit;
}

static DFWINDOW MouseWindow(int x, int y)
{
	/* get the window in which a mouse event occurred */
	DFWINDOW Mwnd = inWindow(ApplicationWindow, x, y);

	/* ---- process mouse captures ----- */
	if (CaptureMouse != NULL)
	{
		if (NoChildCaptureMouse ||
		    Mwnd == NULL 	||
		    !isAncestor(Mwnd, CaptureMouse))
			Mwnd = CaptureMouse;
	}
	return Mwnd;
}


void handshake(void)
{
	handshaking++;
	DfDispatchMessage ();
	--handshaking;
}


/* ---- dispatch messages to the message proc function ---- */
BOOL DfDispatchMessage (void)
{
	DFWINDOW Mwnd, Kwnd;

	/* -------- collect mouse and keyboard events ------- */
	collect_events();

	/* --------- dequeue and process events -------- */
	while (EventQueueCtr > 0)
	{
		struct events ev;

		ev = EventQueue[EventQueueOffCtr];
		if (++EventQueueOffCtr == MAXMESSAGES)
			EventQueueOffCtr = 0;
		--EventQueueCtr;

		/* get the window in which a keyboard event occurred */
		Kwnd = inFocus;

		/* process keyboard captures */
		if (CaptureKeyboard != NULL)
		{
			if (Kwnd == NULL ||
			    NoChildCaptureKeyboard ||
			    !isAncestor(Kwnd, CaptureKeyboard))
				Kwnd = CaptureKeyboard;
		}

		/* send mouse and keyboard messages to the
		   window that should get them */
		switch (ev.event)
		{
			case SHIFT_CHANGED:
			case KEYBOARD:
				if (!handshaking)
					DfSendMessage(Kwnd, ev.event, ev.mx, ev.my);
				break;

			case LEFT_BUTTON:
				if (!handshaking)
				{
					Mwnd = MouseWindow(ev.mx, ev.my);
					if (!CaptureMouse ||
					    (!NoChildCaptureMouse &&
					     isAncestor(Mwnd, CaptureMouse)))
					{
						if (Mwnd != inFocus)
							DfSendMessage(Mwnd, SETFOCUS, TRUE, 0);
						DfSendMessage(Mwnd, LEFT_BUTTON, ev.mx, ev.my);
					}
				}
				break;

			case DFM_BUTTON_RELEASED:
			case DOUBLE_CLICK:
			case RIGHT_BUTTON:
				if (handshaking)
					break;

			case MOUSE_MOVED:
				Mwnd = MouseWindow(ev.mx, ev.my);
				DfSendMessage(Mwnd, ev.event, ev.mx, ev.my);
				break;

			case CLOCKTICK:
				DfSendMessage(Cwnd, ev.event, ev.mx, ev.my);
				break;

			default:
				break;
		}
	}

	/* ------ dequeue and process messages ----- */
	while (MsgQueueCtr > 0)
	{
		struct msgs mq;

		mq = MsgQueue[MsgQueueOffCtr];

		if (++MsgQueueOffCtr == MAXMESSAGES)
			MsgQueueOffCtr = 0;
		--MsgQueueCtr;

		DfSendMessage (mq.wnd, mq.msg, mq.p1, mq.p2);
		if (mq.msg == ENDDIALOG)
			return FALSE;

		if (mq.msg == DFM_STOP)
			return FALSE;
	}

	return TRUE;
}

/* EOF */

⌨️ 快捷键说明

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