📄 message.c
字号:
}
}
LeaveCriticalSection(&MsgConversionCrst);
return TRUE;
}
static void FASTCALL
MsgConversionCleanup(CONST MSG *Msg, BOOL Ansi, BOOL CheckMsgContents, LRESULT *Result)
{
BOOL Found;
PMSGCONVERSION Conversion;
LRESULT Dummy;
EnterCriticalSection(&MsgConversionCrst);
for (Conversion = MsgConversions;
Conversion < MsgConversions + MsgConversionNumAlloc;
Conversion++)
{
if (Conversion->InUse &&
((Ansi && Conversion->Ansi) ||
(! Ansi && ! Conversion->Ansi)))
{
Found = (Conversion->FinalMsg == Msg);
if (! Found && CheckMsgContents)
{
if (Ansi)
{
Found = (0 == memcmp(Msg, &Conversion->AnsiMsg, sizeof(MSG)));
}
else
{
Found = (0 == memcmp(Msg, &Conversion->UnicodeMsg, sizeof(MSG)));
}
}
if (Found)
{
if (Ansi)
{
MsgiUnicodeToAnsiReply(&Conversion->AnsiMsg, &Conversion->UnicodeMsg,
NULL == Result ? &Dummy : Result);
}
MsgiKMToUMReply(&Conversion->KMMsg, &Conversion->UnicodeMsg,
NULL == Result ? &Dummy : Result);
if (0 != Conversion->LParamSize)
{
NtFreeVirtualMemory(NtCurrentProcess(), (PVOID *) &Conversion->KMMsg.lParam,
&Conversion->LParamSize, MEM_DECOMMIT);
}
Conversion->InUse = FALSE;
MsgConversionNumUsed--;
}
}
}
LeaveCriticalSection(&MsgConversionCrst);
}
/*
* @implemented
*/
LPARAM
STDCALL
GetMessageExtraInfo(VOID)
{
return (LPARAM)NtUserCallNoParam(NOPARAM_ROUTINE_GETMESSAGEEXTRAINFO);
}
/*
* @implemented
*/
DWORD
STDCALL
GetMessagePos(VOID)
{
PUSER32_THREAD_DATA ThreadData = User32GetThreadData();
return(MAKELONG(ThreadData->LastMessage.pt.x, ThreadData->LastMessage.pt.y));
}
/*
* @implemented
*/
LONG STDCALL
GetMessageTime(VOID)
{
PUSER32_THREAD_DATA ThreadData = User32GetThreadData();
return(ThreadData->LastMessage.time);
}
/*
* @unimplemented
*/
BOOL
STDCALL
InSendMessage(VOID)
{
static DWORD ShowNotImplemented = TRUE;
if (ShowNotImplemented)
{
DbgPrint("InSendMessage is unimplemented\n");
ShowNotImplemented = FALSE;
}
/* return(NtUserGetThreadState(THREADSTATE_INSENDMESSAGE) != ISMEX_NOSEND); */
return FALSE;
}
/*
* @unimplemented
*/
DWORD
STDCALL
InSendMessageEx(
LPVOID lpReserved)
{
/* return NtUserGetThreadState(THREADSTATE_INSENDMESSAGE); */
UNIMPLEMENTED;
return 0;
}
/*
* @unimplemented
*/
BOOL
STDCALL
ReplyMessage(
LRESULT lResult)
{
UNIMPLEMENTED;
return FALSE;
}
/*
* @implemented
*/
LPARAM
STDCALL
SetMessageExtraInfo(
LPARAM lParam)
{
return NtUserSetMessageExtraInfo(lParam);
}
LRESULT FASTCALL
IntCallWindowProcW(BOOL IsAnsiProc,
WNDPROC WndProc,
HWND hWnd,
UINT Msg,
WPARAM wParam,
LPARAM lParam)
{
MSG AnsiMsg;
MSG UnicodeMsg;
LRESULT Result;
if (WndProc == NULL)
{
DPRINT("IntCallWindowsProcW() called with WndProc = NULL!\n");
return FALSE;
}
if (IsAnsiProc)
{
UnicodeMsg.hwnd = hWnd;
UnicodeMsg.message = Msg;
UnicodeMsg.wParam = wParam;
UnicodeMsg.lParam = lParam;
if (! MsgiUnicodeToAnsiMessage(&AnsiMsg, &UnicodeMsg))
{
return FALSE;
}
Result = WndProc(AnsiMsg.hwnd, AnsiMsg.message, AnsiMsg.wParam, AnsiMsg.lParam);
if (! MsgiUnicodeToAnsiReply(&AnsiMsg, &UnicodeMsg, &Result))
{
return FALSE;
}
return Result;
}
else
{
return WndProc(hWnd, Msg, wParam, lParam);
}
}
static LRESULT FASTCALL
IntCallWindowProcA(BOOL IsAnsiProc,
WNDPROC WndProc,
HWND hWnd,
UINT Msg,
WPARAM wParam,
LPARAM lParam)
{
MSG AnsiMsg;
MSG UnicodeMsg;
LRESULT Result;
if (WndProc == NULL)
{
DPRINT1("IntCallWindowsProcA() called with WndProc = NULL!\n");
return FALSE;
}
if (IsAnsiProc)
{
return WndProc(hWnd, Msg, wParam, lParam);
}
else
{
AnsiMsg.hwnd = hWnd;
AnsiMsg.message = Msg;
AnsiMsg.wParam = wParam;
AnsiMsg.lParam = lParam;
if (! MsgiAnsiToUnicodeMessage(&UnicodeMsg, &AnsiMsg))
{
return FALSE;
}
Result = WndProc(UnicodeMsg.hwnd, UnicodeMsg.message,
UnicodeMsg.wParam, UnicodeMsg.lParam);
if (! MsgiAnsiToUnicodeReply(&UnicodeMsg, &AnsiMsg, &Result))
{
return FALSE;
}
return Result;
}
}
static BOOL __inline
IsCallProcHandle(IN WNDPROC lpWndProc)
{
/* FIXME - check for 64 bit architectures... */
return ((ULONG_PTR)lpWndProc & 0xFFFF0000) == 0xFFFF0000;
}
/*
* @implemented
*/
LRESULT STDCALL
CallWindowProcA(WNDPROC lpPrevWndFunc,
HWND hWnd,
UINT Msg,
WPARAM wParam,
LPARAM lParam)
{
WNDPROC_INFO wpInfo;
/* FIXME - can the first parameter be NULL? */
if (lpPrevWndFunc == NULL)
lpPrevWndFunc = (WNDPROC)NtUserGetWindowLong(hWnd, GWLP_WNDPROC, TRUE);
if (!IsCallProcHandle(lpPrevWndFunc) ||
!NtUserDereferenceWndProcHandle((HANDLE)lpPrevWndFunc,
&wpInfo))
{
return IntCallWindowProcA(TRUE, lpPrevWndFunc, hWnd, Msg, wParam, lParam);
}
else
{
return IntCallWindowProcA(!wpInfo.IsUnicode, wpInfo.WindowProc,
hWnd, Msg, wParam, lParam);
}
}
/*
* @implemented
*/
LRESULT STDCALL
CallWindowProcW(WNDPROC lpPrevWndFunc,
HWND hWnd,
UINT Msg,
WPARAM wParam,
LPARAM lParam)
{
WNDPROC_INFO wpInfo;
/* FIXME - can the first parameter be NULL? */
if (lpPrevWndFunc == NULL)
lpPrevWndFunc = (WNDPROC)NtUserGetWindowLong(hWnd, GWLP_WNDPROC, FALSE);
if (!IsCallProcHandle(lpPrevWndFunc) ||
!NtUserDereferenceWndProcHandle((HANDLE)lpPrevWndFunc,
&wpInfo))
{
return IntCallWindowProcW(FALSE, lpPrevWndFunc, hWnd, Msg, wParam, lParam);
}
else
{
return IntCallWindowProcW(!wpInfo.IsUnicode, wpInfo.WindowProc,
hWnd, Msg, wParam, lParam);
}
}
/*
* @implemented
*/
LRESULT STDCALL
DispatchMessageA(CONST MSG *lpmsg)
{
NTUSERDISPATCHMESSAGEINFO Info;
LRESULT Result;
Info.Ansi = TRUE;
Info.Msg = *lpmsg;
Result = NtUserDispatchMessage(&Info);
if (! Info.HandledByKernel)
{
/* We need to send the message ourselves */
SPY_EnterMessage(SPY_DISPATCHMESSAGE, Info.Msg.hwnd, Info.Msg.message,
Info.Msg.wParam, Info.Msg.lParam);
Result = IntCallWindowProcA(Info.Ansi, Info.Proc, Info.Msg.hwnd,
Info.Msg.message, Info.Msg.wParam, Info.Msg.lParam);
SPY_ExitMessage(SPY_RESULT_OK, Info.Msg.hwnd, Info.Msg.message, Result,
Info.Msg.wParam, Info.Msg.lParam);
}
MsgConversionCleanup(lpmsg, TRUE, TRUE, &Result);
return Result;
}
/*
* @implemented
*/
LRESULT STDCALL
DispatchMessageW(CONST MSG *lpmsg)
{
NTUSERDISPATCHMESSAGEINFO Info;
LRESULT Result;
Info.Ansi = FALSE;
Info.Msg = *lpmsg;
Result = NtUserDispatchMessage(&Info);
if (! Info.HandledByKernel)
{
/* We need to send the message ourselves */
SPY_EnterMessage(SPY_DISPATCHMESSAGE, Info.Msg.hwnd, Info.Msg.message,
Info.Msg.wParam, Info.Msg.lParam);
Result = IntCallWindowProcW(Info.Ansi, Info.Proc, Info.Msg.hwnd,
Info.Msg.message, Info.Msg.wParam, Info.Msg.lParam);
SPY_ExitMessage(SPY_RESULT_OK, Info.Msg.hwnd, Info.Msg.message, Result,
Info.Msg.wParam, Info.Msg.lParam);
}
MsgConversionCleanup(lpmsg, FALSE, TRUE, &Result);
return Result;
}
/*
* @implemented
*/
BOOL STDCALL
GetMessageA(LPMSG lpMsg,
HWND hWnd,
UINT wMsgFilterMin,
UINT wMsgFilterMax)
{
BOOL Res;
MSGCONVERSION Conversion;
NTUSERGETMESSAGEINFO Info;
PUSER32_THREAD_DATA ThreadData = User32GetThreadData();
MsgConversionCleanup(lpMsg, TRUE, FALSE, NULL);
Res = NtUserGetMessage(&Info, hWnd, wMsgFilterMin, wMsgFilterMax);
if (-1 == (int) Res)
{
return Res;
}
Conversion.LParamSize = Info.LParamSize;
Conversion.KMMsg = Info.Msg;
if (! MsgiKMToUMMessage(&Conversion.KMMsg, &Conversion.UnicodeMsg))
{
return (BOOL) -1;
}
if (! MsgiUnicodeToAnsiMessage(&Conversion.AnsiMsg, &Conversion.UnicodeMsg))
{
MsgiKMToUMCleanup(&Info.Msg, &Conversion.UnicodeMsg);
return (BOOL) -1;
}
*lpMsg = Conversion.AnsiMsg;
Conversion.Ansi = TRUE;
Conversion.FinalMsg = lpMsg;
MsgConversionAdd(&Conversion);
if (Res && lpMsg->message != WM_PAINT && lpMsg->message != WM_QUIT)
{
ThreadData->LastMessage = Info.Msg;
}
return Res;
}
/*
* @implemented
*/
BOOL STDCALL
GetMessageW(LPMSG lpMsg,
HWND hWnd,
UINT wMsgFilterMin,
UINT wMsgFilterMax)
{
BOOL Res;
MSGCONVERSION Conversion;
NTUSERGETMESSAGEINFO Info;
PUSER32_THREAD_DATA ThreadData = User32GetThreadData();
MsgConversionCleanup(lpMsg, FALSE, FALSE, NULL);
Res = NtUserGetMessage(&Info, hWnd, wMsgFilterMin, wMsgFilterMax);
if (-1 == (int) Res)
{
return Res;
}
Conversion.LParamSize = Info.LParamSize;
Conversion.KMMsg = Info.Msg;
if (! MsgiKMToUMMessage(&Conversion.KMMsg, &Conversion.UnicodeMsg))
{
return (BOOL) -1;
}
*lpMsg = Conversion.UnicodeMsg;
Conversion.Ansi = FALSE;
Conversion.FinalMsg = lpMsg;
MsgConversionAdd(&Conversion);
if (Res && lpMsg->message != WM_PAINT && lpMsg->message != WM_QUIT)
{
ThreadData->LastMessage = Info.Msg;
}
return Res;
}
/*
* @implemented
*/
BOOL STDCALL
PeekMessageA(LPMSG lpMsg,
HWND hWnd,
UINT wMsgFilterMin,
UINT wMsgFilterMax,
UINT wRemoveMsg)
{
BOOL Res;
MSGCONVERSION Conversion;
NTUSERGETMESSAGEINFO Info;
PUSER32_THREAD_DATA ThreadData = User32GetThreadData();
MsgConversionCleanup(lpMsg, TRUE, FALSE, NULL);
Res = NtUserPeekMessage(&Info, hWnd, wMsgFilterMin, wMsgFilterMax, wRemoveMsg);
if (-1 == (int) Res || ! Res)
{
return Res;
}
Conversion.LParamSize = Info.LParamSize;
Conversion.KMMsg = Info.Msg;
if (! MsgiKMToUMMessage(&Conversion.KMMsg, &Conversion.UnicodeMsg))
{
return (BOOL) -1;
}
if (! MsgiUnicodeToAnsiMessage(&Conversion.AnsiMsg, &Conversion.UnicodeMsg))
{
MsgiKMToUMCleanup(&Info.Msg, &Conversion.UnicodeMsg);
return (BOOL) -1;
}
*lpMsg = Conversion.AnsiMsg;
Conversion.Ansi = TRUE;
Conversion.FinalMsg = lpMsg;
MsgConversionAdd(&Conversion);
if (Res && lpMsg->message != WM_PAINT && lpMsg->message != WM_QUIT)
{
ThreadData->LastMessage = Info.Msg;
}
return Res;
}
/*
* @implemented
*/
BOOL
STDCALL
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -