- Modify how non-queued messages are send that originate from the Win23k subsystem. 
Non-queued messages must go directly to the windows WNDPROC and not through the message pump (previews ROS behavior). 
More importantly sending these messages must not cause the sending thread to block waiting for a reply.
- Add a messaging handling function that always sends message from Win32k to the windows thread without waiting. 
This will also allow the implementation of message call back later.
- Modify PackParam and UnpackParam to accept a BOOL value to determine whether LParam needs to be allocated from NonPagedPool. 
Use with new message handling as if message sent to another thread have any pointers they must be allocated from NonPagedPool.
- Fixed broken logic in can_active_window function and co_WinPosShowWindow.
- Fixed broken logic in co_IntSendActivateMessages. 
The WM_ACTIVATEAPP message was being sent to every window belonging to the desktop twice.
Once with flag saying window was activated and again with deactivated.
- These changes should fix bugs #969, #3171, #4501, #4676, #4677, #4948.

svn path=/trunk/; revision=47126
This commit is contained in:
Michael Martin 2010-05-08 15:49:02 +00:00
parent 4b9b7d580f
commit 5678dca446
5 changed files with 261 additions and 69 deletions

View file

@ -6,6 +6,7 @@
#define MSQ_NORMAL 0
#define MSQ_ISHOOK 1
#define MSQ_ISEVENT 2
#define MSQ_SENTNOWAIT 0x80000000
typedef struct _USER_MESSAGE
{
@ -28,6 +29,7 @@ typedef struct _USER_SENT_MESSAGE
/* entry in the dispatching list of the sender's message queue */
LIST_ENTRY DispatchingListEntry;
INT HookMessage;
BOOL HasPackedLParam;
} USER_SENT_MESSAGE, *PUSER_SENT_MESSAGE;
typedef struct _USER_SENT_MESSAGE_NOTIFY
@ -184,6 +186,20 @@ co_IntSendMessageTimeout(HWND hWnd,
UINT uFlags,
UINT uTimeout,
ULONG_PTR *uResult);
LRESULT FASTCALL co_IntSendMessageNoWait(HWND hWnd,
UINT Msg,
WPARAM wParam,
LPARAM lParam);
LRESULT FASTCALL
co_IntSendMessageWithCallBack(HWND hWnd,
UINT Msg,
WPARAM wParam,
LPARAM lParam,
SENDASYNCPROC CompletionCallback,
ULONG_PTR CompletionCallbackContext,
ULONG_PTR *uResult);
LRESULT FASTCALL
IntDispatchMessage(MSG* Msg);
BOOL FASTCALL

View file

@ -53,8 +53,8 @@ co_IntSendDeactivateMessages(HWND hWndPrev, HWND hWnd)
{
if (hWndPrev)
{
co_IntPostOrSendMessage(hWndPrev, WM_NCACTIVATE, FALSE, 0);
co_IntPostOrSendMessage(hWndPrev, WM_ACTIVATE,
co_IntSendMessageNoWait(hWndPrev, WM_NCACTIVATE, FALSE, 0);
co_IntSendMessageNoWait(hWndPrev, WM_ACTIVATE,
MAKEWPARAM(WA_INACTIVE, UserGetWindowLong(hWndPrev, GWL_STYLE, FALSE) & WS_MINIMIZE),
(LPARAM)hWnd);
}
@ -105,38 +105,19 @@ co_IntSendActivateMessages(HWND hWndPrev, HWND hWnd, BOOL MouseActivate)
if (Window && WindowPrev)
{
PWINDOW_OBJECT cWindow;
HWND *List, *phWnd;
HANDLE OldTID = IntGetWndThreadId(WindowPrev);
HANDLE NewTID = IntGetWndThreadId(Window);
DPRINT("SendActiveMessage Old -> %x, New -> %x\n", OldTID, NewTID);
DPRINT1("SendActiveMessage Old -> %x, New -> %x\n", OldTID, NewTID);
if (Window->Wnd->style & WS_MINIMIZE)
{
DPRINT1("Widow was nminimized\n");
}
if (OldTID != NewTID)
{
List = IntWinListChildren(UserGetWindowObject(IntGetDesktopWindow()));
if (List)
{
for (phWnd = List; *phWnd; ++phWnd)
{
cWindow = UserGetWindowObject(*phWnd);
if (cWindow && (IntGetWndThreadId(cWindow) == OldTID))
{ // FALSE if the window is being deactivated,
// ThreadId that owns the window being activated.
co_IntPostOrSendMessage(*phWnd, WM_ACTIVATEAPP, FALSE, (LPARAM)NewTID);
}
}
for (phWnd = List; *phWnd; ++phWnd)
{
cWindow = UserGetWindowObject(*phWnd);
if (cWindow && (IntGetWndThreadId(cWindow) == NewTID))
{ // TRUE if the window is being activated,
// ThreadId that owns the window being deactivated.
co_IntPostOrSendMessage(*phWnd, WM_ACTIVATEAPP, TRUE, (LPARAM)OldTID);
}
}
ExFreePool(List);
}
co_IntSendMessageNoWait(hWndPrev, WM_ACTIVATEAPP, FALSE, (LPARAM)NewTID);
co_IntSendMessageNoWait(hWnd, WM_ACTIVATEAPP, TRUE, (LPARAM)OldTID);
}
UserDerefObjectCo(WindowPrev); // Now allow the previous window to die.
}
@ -144,10 +125,9 @@ co_IntSendActivateMessages(HWND hWndPrev, HWND hWnd, BOOL MouseActivate)
UserDerefObjectCo(Window);
/* FIXME: IntIsWindow */
co_IntPostOrSendMessage(hWnd, WM_NCACTIVATE, (WPARAM)(hWnd == UserGetForegroundWindow()), 0);
co_IntSendMessageNoWait(hWnd, WM_NCACTIVATE, (WPARAM)(hWnd == UserGetForegroundWindow()), 0);
/* FIXME: WA_CLICKACTIVE */
co_IntPostOrSendMessage(hWnd, WM_ACTIVATE,
co_IntSendMessageNoWait(hWnd, WM_ACTIVATE,
MAKEWPARAM(MouseActivate ? WA_CLICKACTIVE : WA_ACTIVE,
UserGetWindowLong(hWnd, GWL_STYLE, FALSE) & WS_MINIMIZE),
(LPARAM)hWndPrev);
@ -241,7 +221,9 @@ co_IntSetForegroundAndFocusWindow(PWINDOW_OBJECT Window, PWINDOW_OBJECT FocusWin
co_IntSendDeactivateMessages(hWndPrev, hWnd);
co_IntSendKillFocusMessages(hWndFocusPrev, hWndFocus);
IntSetFocusMessageQueue(Window->pti->MessageQueue);
if (Window->pti->MessageQueue)
{
Window->pti->MessageQueue->ActiveWindow = hWnd;

View file

@ -165,7 +165,7 @@ MsgMemorySize(PMSGMEMORY MsgMemoryEntry, WPARAM wParam, LPARAM lParam)
}
static NTSTATUS
PackParam(LPARAM *lParamPacked, UINT Msg, WPARAM wParam, LPARAM lParam)
PackParam(LPARAM *lParamPacked, UINT Msg, WPARAM wParam, LPARAM lParam, BOOL NonPagedPoolNeeded)
{
NCCALCSIZE_PARAMS *UnpackedNcCalcsize;
NCCALCSIZE_PARAMS *PackedNcCalcsize;
@ -173,28 +173,34 @@ PackParam(LPARAM *lParamPacked, UINT Msg, WPARAM wParam, LPARAM lParam)
CREATESTRUCTW *PackedCs;
PUNICODE_STRING WindowName;
PUNICODE_STRING ClassName;
POOL_TYPE PoolType;
UINT Size;
PCHAR CsData;
*lParamPacked = lParam;
if (NonPagedPoolNeeded)
PoolType = NonPagedPool;
else
PoolType = PagedPool;
if (WM_NCCALCSIZE == Msg && wParam)
{
UnpackedNcCalcsize = (NCCALCSIZE_PARAMS *) lParam;
if (UnpackedNcCalcsize->lppos != (PWINDOWPOS) (UnpackedNcCalcsize + 1))
PackedNcCalcsize = ExAllocatePoolWithTag(PoolType,
sizeof(NCCALCSIZE_PARAMS) + sizeof(WINDOWPOS),
TAG_MSG);
if (NULL == PackedNcCalcsize)
{
PackedNcCalcsize = ExAllocatePoolWithTag(PagedPool,
sizeof(NCCALCSIZE_PARAMS) + sizeof(WINDOWPOS),
TAG_MSG);
if (NULL == PackedNcCalcsize)
{
DPRINT1("Not enough memory to pack lParam\n");
return STATUS_NO_MEMORY;
}
RtlCopyMemory(PackedNcCalcsize, UnpackedNcCalcsize, sizeof(NCCALCSIZE_PARAMS));
PackedNcCalcsize->lppos = (PWINDOWPOS) (PackedNcCalcsize + 1);
RtlCopyMemory(PackedNcCalcsize->lppos, UnpackedNcCalcsize->lppos, sizeof(WINDOWPOS));
*lParamPacked = (LPARAM) PackedNcCalcsize;
DPRINT1("Not enough memory to pack lParam\n");
return STATUS_NO_MEMORY;
}
RtlCopyMemory(PackedNcCalcsize, UnpackedNcCalcsize, sizeof(NCCALCSIZE_PARAMS));
PackedNcCalcsize->lppos = (PWINDOWPOS) (PackedNcCalcsize + 1);
RtlCopyMemory(PackedNcCalcsize->lppos, UnpackedNcCalcsize->lppos, sizeof(WINDOWPOS));
*lParamPacked = (LPARAM) PackedNcCalcsize;
}
else if (WM_CREATE == Msg || WM_NCCREATE == Msg)
{
@ -210,7 +216,7 @@ PackParam(LPARAM *lParamPacked, UINT Msg, WPARAM wParam, LPARAM lParam)
{
Size += sizeof(WCHAR) + ClassName->Length + sizeof(WCHAR);
}
PackedCs = ExAllocatePoolWithTag(PagedPool, Size, TAG_MSG);
PackedCs = ExAllocatePoolWithTag(PoolType, Size, TAG_MSG);
if (NULL == PackedCs)
{
DPRINT1("Not enough memory to pack lParam\n");
@ -244,11 +250,28 @@ PackParam(LPARAM *lParamPacked, UINT Msg, WPARAM wParam, LPARAM lParam)
*lParamPacked = (LPARAM) PackedCs;
}
else if (PoolType == NonPagedPool)
{
PMSGMEMORY MsgMemoryEntry;
PVOID PackedData;
MsgMemoryEntry = FindMsgMemory(Msg);
if ((!MsgMemoryEntry) || (MsgMemoryEntry->Size < 0))
{
/* Keep previous behavior */
return STATUS_SUCCESS;
}
PackedData = ExAllocatePoolWithTag(NonPagedPool, MsgMemorySize(MsgMemoryEntry, wParam, lParam), TAG_MSG);
RtlCopyMemory(PackedData, (PVOID)lParam, MsgMemorySize(MsgMemoryEntry, wParam, lParam));
*lParamPacked = (LPARAM)PackedData;
}
return STATUS_SUCCESS;
}
static NTSTATUS
UnpackParam(LPARAM lParamPacked, UINT Msg, WPARAM wParam, LPARAM lParam)
UnpackParam(LPARAM lParamPacked, UINT Msg, WPARAM wParam, LPARAM lParam, BOOL NonPagedPoolUsed)
{
NCCALCSIZE_PARAMS *UnpackedParams;
NCCALCSIZE_PARAMS *PackedParams;
@ -277,6 +300,23 @@ UnpackParam(LPARAM lParamPacked, UINT Msg, WPARAM wParam, LPARAM lParam)
return STATUS_SUCCESS;
}
else if (NonPagedPoolUsed)
{
PMSGMEMORY MsgMemoryEntry;
MsgMemoryEntry = FindMsgMemory(Msg);
if (MsgMemoryEntry->Size < 0)
{
/* Keep previous behavior */
return STATUS_INVALID_PARAMETER;
}
if (MsgMemory->Flags == MMS_FLAG_READWRITE)
{
//RtlCopyMemory((PVOID)lParam, (PVOID)lParamPacked, MsgMemory->Size);
}
ExFreePool((PVOID) lParamPacked);
return STATUS_SUCCESS;
}
ASSERT(FALSE);
@ -394,7 +434,7 @@ IntDispatchMessage(PMSG pMsg)
lParamBufferSize = MsgMemorySize(MsgMemoryEntry, pMsg->wParam, pMsg->lParam);
}
if (! NT_SUCCESS(PackParam(&lParamPacked, pMsg->message, pMsg->wParam, pMsg->lParam)))
if (! NT_SUCCESS(PackParam(&lParamPacked, pMsg->message, pMsg->wParam, pMsg->lParam, FALSE)))
{
DPRINT1("Failed to pack message parameters\n");
return 0;
@ -408,7 +448,7 @@ IntDispatchMessage(PMSG pMsg)
lParamPacked,
lParamBufferSize);
if (! NT_SUCCESS(UnpackParam(lParamPacked, pMsg->message, pMsg->wParam, pMsg->lParam)))
if (! NT_SUCCESS(UnpackParam(lParamPacked, pMsg->message, pMsg->wParam, pMsg->lParam, FALSE)))
{
DPRINT1("Failed to unpack message parameters\n");
}
@ -1372,7 +1412,7 @@ co_IntSendMessageTimeoutSingle( HWND hWnd,
lParamBufferSize = MsgMemorySize(MsgMemoryEntry, wParam, lParam);
}
if (! NT_SUCCESS(PackParam(&lParamPacked, Msg, wParam, lParam)))
if (! NT_SUCCESS(PackParam(&lParamPacked, Msg, wParam, lParam, FALSE)))
{
DPRINT1("Failed to pack message parameters\n");
RETURN( FALSE);
@ -1392,7 +1432,7 @@ co_IntSendMessageTimeoutSingle( HWND hWnd,
IntCallWndProcRet( Window, hWnd, Msg, wParam, lParam, (LRESULT *)uResult);
if (! NT_SUCCESS(UnpackParam(lParamPacked, Msg, wParam, lParam)))
if (! NT_SUCCESS(UnpackParam(lParamPacked, Msg, wParam, lParam, FALSE)))
{
DPRINT1("Failed to unpack message parameters\n");
RETURN( TRUE);
@ -1499,6 +1539,148 @@ co_IntSendMessageTimeout( HWND hWnd,
return (LRESULT) TRUE;
}
LRESULT FASTCALL co_IntSendMessageNoWait(HWND hWnd,
UINT Msg,
WPARAM wParam,
LPARAM lParam)
{
ULONG_PTR Result = 0;
co_IntSendMessageWithCallBack(hWnd,
Msg,
wParam,
lParam,
NULL,
0,
&Result);
return Result;
}
LRESULT FASTCALL
co_IntSendMessageWithCallBack( HWND hWnd,
UINT Msg,
WPARAM wParam,
LPARAM lParam,
SENDASYNCPROC CompletionCallback,
ULONG_PTR CompletionCallbackContext,
ULONG_PTR *uResult)
{
ULONG_PTR Result;
PWINDOW_OBJECT Window = NULL;
PMSGMEMORY MsgMemoryEntry;
INT lParamBufferSize;
LPARAM lParamPacked;
PTHREADINFO Win32Thread;
DECLARE_RETURN(LRESULT);
USER_REFERENCE_ENTRY Ref;
PUSER_SENT_MESSAGE Message;
if (!(Window = UserGetWindowObject(hWnd)))
{
RETURN(FALSE);
}
UserRefObjectCo(Window, &Ref);
if (Window->state & WINDOWSTATUS_DESTROYING)
{
/* FIXME - last error? */
DPRINT1("Attempted to send message to window 0x%x that is being destroyed!\n", hWnd);
RETURN(FALSE);
}
Win32Thread = PsGetCurrentThreadWin32Thread();
IntCallWndProc( Window, hWnd, Msg, wParam, lParam);
if (Win32Thread == NULL)
{
ASSERT(FALSE);
RETURN(FALSE);
}
if (Win32Thread->TIF_flags & TIF_INCLEANUP)
{
/* Never send messages to exiting threads */
RETURN(FALSE);
}
/* See if this message type is present in the table */
MsgMemoryEntry = FindMsgMemory(Msg);
if (NULL == MsgMemoryEntry)
{
lParamBufferSize = -1;
}
else
{
lParamBufferSize = MsgMemorySize(MsgMemoryEntry, wParam, lParam);
}
if (! NT_SUCCESS(PackParam(&lParamPacked, Msg, wParam, lParam, Window->pti->MessageQueue != Win32Thread->MessageQueue)))
{
DPRINT1("Failed to pack message parameters\n");
RETURN( FALSE);
}
/* If this is not a callback and it can be sent now, then send it. */
if ((Window->pti->MessageQueue == Win32Thread->MessageQueue) && (CompletionCallback == NULL))
{
Result = (ULONG_PTR)co_IntCallWindowProc( Window->Wnd->lpfnWndProc,
!Window->Wnd->Unicode,
hWnd,
Msg,
wParam,
lParamPacked,
lParamBufferSize );
if(uResult)
{
*uResult = Result;
}
}
IntCallWndProcRet( Window, hWnd, Msg, wParam, lParam, (LRESULT *)uResult);
if (Window->pti->MessageQueue == Win32Thread->MessageQueue)
{
if (! NT_SUCCESS(UnpackParam(lParamPacked, Msg, wParam, lParam, FALSE)))
{
DPRINT1("Failed to unpack message parameters\n");
RETURN(TRUE);
}
RETURN(TRUE);
}
if(!(Message = ExAllocatePoolWithTag(NonPagedPool, sizeof(USER_SENT_MESSAGE), TAG_USRMSG)))
{
DPRINT1("MsqSendMessage(): Not enough memory to allocate a message");
return STATUS_INSUFFICIENT_RESOURCES;
}
Message->Msg.hwnd = hWnd;
Message->Msg.message = Msg;
Message->Msg.wParam = wParam;
Message->Msg.lParam = lParamPacked;
Message->CompletionEvent = NULL;
Message->Result = 0;
Message->SenderQueue = Win32Thread->MessageQueue;
IntReferenceMessageQueue(Message->SenderQueue);
IntReferenceMessageQueue(Window->pti->MessageQueue);
Message->CompletionCallback = CompletionCallback;
Message->CompletionCallbackContext = CompletionCallbackContext;
Message->HookMessage = MSQ_NORMAL | MSQ_SENTNOWAIT;
Message->HasPackedLParam = (lParamBufferSize > 0);
InsertTailList(&Window->pti->MessageQueue->SentMessagesListHead, &Message->ListEntry);
InsertTailList(&Win32Thread->MessageQueue->DispatchingMessagesHead, &Message->DispatchingListEntry);
IntDereferenceMessageQueue(Window->pti->MessageQueue);
IntDereferenceMessageQueue(Message->SenderQueue);
RETURN(TRUE);
CLEANUP:
if (Window) UserDerefObjectCo(Window);
END_CLEANUP;
}
/* This function posts a message if the destination's message queue belongs to
another thread, otherwise it sends the message. It does not support broadcast

View file

@ -969,7 +969,7 @@ co_MsqDispatchOneSentMessage(PUSER_MESSAGE_QUEUE MessageQueue)
/* remove the message from the dispatching list, so lock the sender's message queue */
SenderReturned = (Message->DispatchingListEntry.Flink == NULL);
if(!SenderReturned)
if (!SenderReturned)
{
/* only remove it from the dispatching list if not already removed by a timeout */
RemoveEntryList(&Message->DispatchingListEntry);
@ -983,6 +983,12 @@ co_MsqDispatchOneSentMessage(PUSER_MESSAGE_QUEUE MessageQueue)
*Message->Result = Result;
}
if (Message->HasPackedLParam == TRUE)
{
if (Message->Msg.lParam)
ExFreePool((PVOID)Message->Msg.lParam);
}
/* Notify the sender. */
if (Message->CompletionEvent != NULL)
{
@ -1010,9 +1016,12 @@ co_MsqDispatchOneSentMessage(PUSER_MESSAGE_QUEUE MessageQueue)
Notified:
/* dereference both sender and our queue */
IntDereferenceMessageQueue(MessageQueue);
IntDereferenceMessageQueue(Message->SenderQueue);
/* Only if it is not a no wait message */
if (!(Message->HookMessage & MSQ_SENTNOWAIT))
{
IntDereferenceMessageQueue(Message->SenderQueue);
IntDereferenceMessageQueue(MessageQueue);
}
/* free the message */
ExFreePool(Message);
@ -1147,6 +1156,7 @@ co_MsqSendMessage(PUSER_MESSAGE_QUEUE MessageQueue,
IntReferenceMessageQueue(ThreadQueue);
Message->CompletionCallback = NULL;
Message->HookMessage = HookMessage;
Message->HasPackedLParam = FALSE;
IntReferenceMessageQueue(MessageQueue);

View file

@ -69,9 +69,6 @@ IntGetClientOrigin(PWINDOW_OBJECT Window OPTIONAL, LPPOINT Point)
return TRUE;
}
BOOL FASTCALL
UserGetClientOrigin(PWINDOW_OBJECT Window, LPPOINT Point)
{
@ -120,8 +117,13 @@ BOOL FASTCALL can_activate_window( PWINDOW_OBJECT Wnd OPTIONAL)
style = Wnd->Wnd->style;
if (!(style & WS_VISIBLE) &&
Wnd->pti->pEThread->ThreadsProcess != CsrProcess) return FALSE;
if ((style & WS_MINIMIZE) &&
Wnd->pti->pEThread->ThreadsProcess != CsrProcess) return FALSE;
if ((style & (WS_POPUP|WS_CHILD)) == WS_CHILD) return FALSE;
return !(style & WS_DISABLED);
return TRUE;
/* FIXME: This window could be disable because the child that closed
was a popup. */
//return !(style & WS_DISABLED);
}
@ -312,7 +314,7 @@ co_WinPosMinMaximize(PWINDOW_OBJECT Window, UINT ShowFlag, RECT* NewPos)
if (Wnd->style & WS_MINIMIZE)
{
if (!co_IntSendMessage(Window->hSelf, WM_QUERYOPEN, 0, 0))
if (!co_IntSendMessageNoWait(Window->hSelf, WM_QUERYOPEN, 0, 0))
{
return(SWP_NOSIZE | SWP_NOMOVE);
}
@ -531,7 +533,7 @@ co_WinPosDoNCCALCSize(PWINDOW_OBJECT Window, PWINDOWPOS WinPos,
params.lppos = &winposCopy;
winposCopy = *WinPos;
wvrFlags = co_IntSendMessage(Window->hSelf, WM_NCCALCSIZE, TRUE, (LPARAM) &params);
wvrFlags = co_IntSendMessageNoWait(Window->hSelf, WM_NCCALCSIZE, TRUE, (LPARAM) &params);
/* If the application send back garbage, ignore it */
if (params.rgrc[0].left <= params.rgrc[0].right &&
@ -590,7 +592,7 @@ co_WinPosDoWinPosChanging(PWINDOW_OBJECT Window,
if (!(WinPos->flags & SWP_NOSENDCHANGING))
{
co_IntPostOrSendMessage(Window->hSelf, WM_WINDOWPOSCHANGING, 0, (LPARAM) WinPos);
co_IntSendMessageNoWait(Window->hSelf, WM_WINDOWPOSCHANGING, 0, (LPARAM) WinPos);
}
*WindowRect = Wnd->rcWindow;
@ -1320,7 +1322,7 @@ co_WinPosSetWindowPos(
{
if ((Window->Wnd->style & (WS_CHILD | WS_POPUP)) == WS_CHILD)
{
co_IntSendMessage(WinPos.hwnd, WM_CHILDACTIVATE, 0, 0);
co_IntSendMessageNoWait(WinPos.hwnd, WM_CHILDACTIVATE, 0, 0);
}
else
{
@ -1330,7 +1332,7 @@ co_WinPosSetWindowPos(
}
if ((WinPos.flags & SWP_AGG_STATUSFLAGS) != SWP_AGG_NOPOSCHANGE)
co_IntPostOrSendMessage(WinPos.hwnd, WM_WINDOWPOSCHANGED, 0, (LPARAM) &WinPos);
co_IntSendMessageNoWait(WinPos.hwnd, WM_WINDOWPOSCHANGED, 0, (LPARAM) &WinPos);
return TRUE;
}
@ -1343,7 +1345,7 @@ co_WinPosGetNonClientSize(PWINDOW_OBJECT Window, RECT* WindowRect, RECT* ClientR
ASSERT_REFS_CO(Window);
*ClientRect = *WindowRect;
Result = co_IntSendMessage(Window->hSelf, WM_NCCALCSIZE, FALSE, (LPARAM) ClientRect);
Result = co_IntSendMessageNoWait(Window->hSelf, WM_NCCALCSIZE, FALSE, (LPARAM) ClientRect);
FixClientRect(ClientRect, WindowRect);
@ -1462,7 +1464,7 @@ co_WinPosShowWindow(PWINDOW_OBJECT Window, INT Cmd)
if (ShowFlag != WasVisible)
{
co_IntSendMessage(Window->hSelf, WM_SHOWWINDOW, ShowFlag, 0);
co_IntSendMessageNoWait(Window->hSelf, WM_SHOWWINDOW, ShowFlag, 0);
}
/* We can't activate a child window */
@ -1476,7 +1478,7 @@ co_WinPosShowWindow(PWINDOW_OBJECT Window, INT Cmd)
? HWND_TOPMOST : HWND_TOP,
NewPos.left, NewPos.top, NewPos.right, NewPos.bottom, LOWORD(Swp));
if (Cmd == SW_HIDE)
if ((Cmd == SW_HIDE) || (Cmd == SW_MINIMIZE))
{
PWINDOW_OBJECT ThreadFocusWindow;
@ -1520,12 +1522,12 @@ co_WinPosShowWindow(PWINDOW_OBJECT Window, INT Cmd)
wParam = SIZE_MINIMIZED;
}
co_IntSendMessage(Window->hSelf, WM_SIZE, wParam,
co_IntSendMessageNoWait(Window->hSelf, WM_SIZE, wParam,
MAKELONG(Wnd->rcClient.right -
Wnd->rcClient.left,
Wnd->rcClient.bottom -
Wnd->rcClient.top));
co_IntSendMessage(Window->hSelf, WM_MOVE, 0,
co_IntSendMessageNoWait(Window->hSelf, WM_MOVE, 0,
MAKELONG(Wnd->rcClient.left,
Wnd->rcClient.top));
IntEngWindowChanged(Window, WOC_RGN_CLIENT);