Release 960818
Sun Aug 18 12:17:54 1996 Alexandre Julliard <julliard@lrc.epfl.ch>
* [files/drive.c]
Added 'Filesystem' option in drives configuration.
* [files/dos_fs.c]
Added handling of case-insensitive filesystems.
* [memory/selector.c] [include/stackframe.h]
Removed MAKE_SEGPTR.
* [misc/commdlg.c] [multimedia/mcistring.c]
Replaced MAKE_SEGPTR by the SEGPTR_* macros.
* [objects/bitblt.c] [windows/graphics.c]
Use an intermediary pixmap to avoid some BadMatch errors on
XGetImage().
Sun Aug 18 09:21:27 1996 Albrecht Kleine <kleine@ak.sax.de>
* [windows/message.c]
Added handling of WM_NC...mouse messages in JOURNALRECORD hook.
* [misc/ver.c]
Fixed a bad string result in VerQueryValue[16|32A|32W].
Fri Aug 16 19:55:04 1996 Marcus Meissner <msmeissn@cip.informatik.uni-erlangen.de>
* [if1632/crtdll.spec] [misc/crtdll.c]
More additions to get win95 programs further down the road.
* [if1632/kernel.spec] [loader/module.c]
GetModuleName() added.
LoadModule(): params->showCmd can be NULL.
* [if1632/kernel32.spec] [if1632/thunk.c]
ThunkConnect32() stub added.
* [loader/resource.c]
Entries include lastentry.
* [misc/shell.c] [files/file.c]
Made progman work again.
Fri Aug 16 09:00:00 1996 Alex Korobka <alex@phm30.pharm.sunysb.edu>
* [windows/defwnd.c] [windows/winpos.c] [windows/painting.c]
Icon painting fixes.
* [windows/winpos.c] [windows/painting.c]
Enforce and follow hrgnUpdate more closely to cut down on
redundant RedrawWindow() calls.
* [windows/event.c]
Process ConfigureNotify only for managed windows.
* [windows/winpos.c]
Do not redraw parent if the window was hidden before SetWindowPos().
* [windows/nonclient.c]
Omit some nonclient decoration painting for managed windows.
* [controls/menu.c] [windows/mdi.c] [windows/nonclient.c]
Implemented WM_NEXTMENU.
* [controls/listbox.c]
Multicolumn listboxes return WVR_VREDRAW on WM_NCCALCSIZE.
* [misc/shell.c]
Added .ICO file handling to ExtractIcon().
diff --git a/windows/defwnd.c b/windows/defwnd.c
index 43b4ddc..f67c44c 100644
--- a/windows/defwnd.c
+++ b/windows/defwnd.c
@@ -14,6 +14,7 @@
#include "winpos.h"
#include "string32.h"
#include "syscolor.h"
+#include "sysmetrics.h"
#include "stddebug.h"
#include "debug.h"
#include "spy.h"
@@ -101,7 +102,6 @@
{
switch(msg)
{
- case WM_PAINTICON:
case WM_NCPAINT:
return NC_HandleNCPaint( wndPtr->hwndSelf, (HRGN)wParam );
@@ -116,7 +116,7 @@
return NC_HandleNCLButtonDblClk( wndPtr, wParam, lParam );
case WM_NCACTIVATE:
- return NC_HandleNCActivate( wndPtr->hwndSelf, wParam );
+ return NC_HandleNCActivate( wndPtr, wParam );
case WM_NCDESTROY:
if (wndPtr->text) HeapFree( SystemHeap, 0, wndPtr->text );
@@ -125,12 +125,26 @@
if (wndPtr->pHScroll) HeapFree( SystemHeap, 0, wndPtr->pHScroll );
wndPtr->pVScroll = wndPtr->pHScroll = NULL;
return 0;
-
+
+ case WM_PAINTICON:
case WM_PAINT:
{
- PAINTSTRUCT16 paintstruct;
- BeginPaint16( wndPtr->hwndSelf, &paintstruct );
- EndPaint16( wndPtr->hwndSelf, &paintstruct );
+ PAINTSTRUCT16 ps;
+ HDC hdc = BeginPaint16( wndPtr->hwndSelf, &ps );
+ if( hdc )
+ {
+ if( (wndPtr->dwStyle & WS_MINIMIZE) && wndPtr->class->hIcon )
+ {
+ int x = (wndPtr->rectWindow.right - wndPtr->rectWindow.left -
+ SYSMETRICS_CXICON)/2;
+ int y = (wndPtr->rectWindow.bottom - wndPtr->rectWindow.top -
+ SYSMETRICS_CYICON)/2;
+ dprintf_win(stddeb,"Painting class icon: vis rect=(%i,%i - %i,%i)\n",
+ ps.rcPaint.left, ps.rcPaint.top, ps.rcPaint.right, ps.rcPaint.bottom );
+ DrawIcon( hdc, x, y, wndPtr->class->hIcon );
+ }
+ EndPaint16( wndPtr->hwndSelf, &ps );
+ }
return 0;
}
@@ -164,18 +178,33 @@
case WM_ICONERASEBKGND:
{
if (!wndPtr->class->hbrBackground) return 0;
- if (wndPtr->class->hbrBackground <= (HBRUSH)(COLOR_MAX+1))
+
+ /* FIXME: should fill icon text with hbrushActiveCaption
+ instead of this */
+
+ if (wndPtr->dwStyle & WS_MINIMIZE )
+ {
+ if( wndPtr->flags & WIN_NCACTIVATED )
+ {
+ FillWindow( GetParent(wndPtr->hwndSelf), wndPtr->hwndSelf,
+ (HDC)wParam, sysColorObjects.hbrushActiveCaption );
+ return 1;
+ }
+
+ /* FIXME: should draw parent' background somehow
+ (e.g for textured desktop) ? */
+ }
+
+ if (wndPtr->class->hbrBackground <= (HBRUSH)(COLOR_MAX+1))
{
- HBRUSH hbrush;
- hbrush = CreateSolidBrush(
- GetSysColor(((DWORD)wndPtr->class->hbrBackground)-1));
+ HBRUSH hbrush = CreateSolidBrush(
+ GetSysColor(((DWORD)wndPtr->class->hbrBackground)-1));
FillWindow( GetParent(wndPtr->hwndSelf), wndPtr->hwndSelf,
(HDC)wParam, hbrush);
DeleteObject (hbrush);
}
- else
- FillWindow( GetParent(wndPtr->hwndSelf), wndPtr->hwndSelf,
- (HDC)wParam, wndPtr->class->hbrBackground );
+ else FillWindow( GetParent(wndPtr->hwndSelf), wndPtr->hwndSelf,
+ (HDC)wParam, wndPtr->class->hbrBackground );
return 1;
}
diff --git a/windows/dialog.c b/windows/dialog.c
index 21ff837..3f3bace 100644
--- a/windows/dialog.c
+++ b/windows/dialog.c
@@ -12,7 +12,6 @@
#include "heap.h"
#include "win.h"
#include "ldt.h"
-#include "stackframe.h"
#include "string32.h"
#include "user.h"
#include "winproc.h"
@@ -724,33 +723,28 @@
{
WND * wndPtr;
DIALOGINFO * dlgInfo;
- HANDLE msgHandle;
- MSG16* lpmsg;
+ MSG16 msg;
INT32 retval;
/* Owner must be a top-level window */
owner = WIN_GetTopParent( owner );
if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return -1;
- if (!(msgHandle = USER_HEAP_ALLOC( sizeof(MSG16) ))) return -1;
- lpmsg = (MSG16 *) USER_HEAP_LIN_ADDR( msgHandle );
dlgInfo = (DIALOGINFO *)wndPtr->wExtra;
EnableWindow( owner, FALSE );
ShowWindow( hwnd, SW_SHOW );
- while (MSG_InternalGetMessage( (SEGPTR)USER_HEAP_SEG_ADDR(msgHandle), hwnd, owner,
- MSGF_DIALOGBOX, PM_REMOVE,
- !(wndPtr->dwStyle & DS_NOIDLEMSG) ))
+ while (MSG_InternalGetMessage(&msg, hwnd, owner, MSGF_DIALOGBOX, PM_REMOVE,
+ !(wndPtr->dwStyle & DS_NOIDLEMSG) ))
{
- if (!IsDialogMessage( hwnd, lpmsg))
+ if (!IsDialogMessage( hwnd, &msg))
{
- TranslateMessage( lpmsg );
- DispatchMessage( lpmsg );
+ TranslateMessage( &msg );
+ DispatchMessage( &msg );
}
if (dlgInfo->fEnd) break;
}
retval = dlgInfo->msgResult;
DestroyWindow( hwnd );
- USER_HEAP_FREE( msgHandle );
EnableWindow( owner, TRUE );
return retval;
}
diff --git a/windows/event.c b/windows/event.c
index 9ea4349..c59b378 100644
--- a/windows/event.c
+++ b/windows/event.c
@@ -398,9 +398,9 @@
rect.right = rect.left + event->width;
rect.bottom = rect.top + event->height;
- RedrawWindow32( pWnd->hwndSelf, &rect, 0,
- RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN | RDW_ERASE |
- (event->count ? 0 : RDW_ERASENOW) );
+ PAINT_RedrawWindow( pWnd->hwndSelf, &rect, 0,
+ RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN | RDW_ERASE |
+ (event->count ? 0 : RDW_ERASENOW), 0 );
}
@@ -420,9 +420,9 @@
rect.right = rect.left + event->width;
rect.bottom = rect.top + event->height;
- RedrawWindow32( pWnd->hwndSelf, &rect, 0,
- RDW_INVALIDATE | RDW_ALLCHILDREN | RDW_ERASE |
- (event->count ? 0 : RDW_ERASENOW) );
+ PAINT_RedrawWindow( pWnd->hwndSelf, &rect, 0,
+ RDW_INVALIDATE | RDW_ALLCHILDREN | RDW_ERASE |
+ (event->count ? 0 : RDW_ERASENOW), 0 );
}
@@ -683,26 +683,17 @@
}
else
{
- /* Managed window; most of this code is shamelessly
- * stolen from SetWindowPos - FIXME: outdated
- */
-
WND *wndPtr;
WINDOWPOS16 *winpos;
RECT16 newWindowRect, newClientRect;
HRGN hrgnOldPos, hrgnNewPos;
- if (!(wndPtr = WIN_FindWndPtr( hwnd )))
- {
- dprintf_event(stddeb,"ConfigureNotify: invalid HWND %04x\n",hwnd);
+ if (!(wndPtr = WIN_FindWndPtr( hwnd )) ||
+ !(wndPtr->flags & WIN_MANAGED) )
return;
- }
if (!(winpos = SEGPTR_NEW(WINDOWPOS16))) return;
- /* Artificial messages - what is this for? */
- SendMessage16(hwnd, WM_ENTERSIZEMOVE, 0, 0);
- SendMessage16(hwnd, WM_EXITSIZEMOVE, 0, 0);
/* Fill WINDOWPOS struct */
winpos->flags = SWP_NOACTIVATE | SWP_NOZORDER;
@@ -744,8 +735,9 @@
SEGPTR_FREE(winpos);
/* full window drag leaves unrepainted garbage without this */
- RedrawWindow32( 0, NULL, hrgnOldPos, RDW_INVALIDATE |
- RDW_ALLCHILDREN | RDW_ERASE | RDW_ERASENOW );
+ PAINT_RedrawWindow( 0, NULL, hrgnOldPos, RDW_INVALIDATE |
+ RDW_ALLCHILDREN | RDW_ERASE | RDW_ERASENOW,
+ RDW_C_USEHRGN );
DeleteObject(hrgnOldPos);
DeleteObject(hrgnNewPos);
}
diff --git a/windows/graphics.c b/windows/graphics.c
index 221bc02..e64aa2f 100644
--- a/windows/graphics.c
+++ b/windows/graphics.c
@@ -581,6 +581,7 @@
*/
COLORREF GetPixel( HDC hdc, short x, short y )
{
+ static Pixmap pixmap = 0;
XImage * image;
int pixel;
@@ -595,8 +596,21 @@
x = dc->w.DCOrgX + XLPTODP( dc, x );
y = dc->w.DCOrgY + YLPTODP( dc, y );
- image = XGetImage( display, dc->u.x.drawable, x, y,
- 1, 1, AllPlanes, ZPixmap );
+ if (dc->w.flags & DC_MEMORY)
+ {
+ image = XGetImage( display, dc->u.x.drawable, x, y, 1, 1,
+ AllPlanes, ZPixmap );
+ }
+ else
+ {
+ /* If we are reading from the screen, use a temporary copy */
+ /* to avoid a BadMatch error */
+ if (!pixmap) pixmap = XCreatePixmap( display, rootWindow,
+ 1, 1, dc->w.bitsPerPixel );
+ XCopyArea( display, dc->u.x.drawable, pixmap, BITMAP_colorGC,
+ x, y, 1, 1, 0, 0 );
+ image = XGetImage( display, pixmap, 0, 0, 1, 1, AllPlanes, ZPixmap );
+ }
pixel = XGetPixel( image, 0, 0 );
XDestroyImage( image );
diff --git a/windows/mdi.c b/windows/mdi.c
index 3d1984c..96307bf 100644
--- a/windows/mdi.c
+++ b/windows/mdi.c
@@ -25,7 +25,6 @@
#include "user.h"
#include "menu.h"
#include "resource.h"
-#include "stackframe.h"
#include "struct32.h"
#include "sysmetrics.h"
#include "stddebug.h"
@@ -129,8 +128,7 @@
DeleteMenu(clientInfo->hWindowMenu,id,MF_BYCOMMAND);
/* walk the rest of MDI children to prevent gaps in the id
- * sequence and in the menu child list
- */
+ * sequence and in the menu child list */
for( index = id+1; index <= clientInfo->nActiveChildren +
clientInfo->idFirstChild; index++ )
@@ -1223,6 +1221,29 @@
MoveWindow(hwndMDIClient, 0, 0,
LOWORD(lParam), HIWORD(lParam), TRUE);
break;
+
+ case WM_NEXTMENU:
+
+ wndPtr = WIN_FindWndPtr(hwndMDIClient);
+ ci = (MDICLIENTINFO*)wndPtr->wExtra;
+
+ if( !(wndPtr->parent->dwStyle & WS_MINIMIZE)
+ && ci->hwndActiveChild && !ci->hwndChildMaximized )
+ {
+ /* control menu is between the frame system menu and
+ * the first entry of menu bar */
+
+ if( wParam == VK_LEFT )
+ { if( wndPtr->parent->wIDmenu != LOWORD(lParam) ) break; }
+ else if( wParam == VK_RIGHT )
+ { if( GetSystemMenu( wndPtr->parent->hwndSelf, 0)
+ != LOWORD(lParam) ) break; }
+ else break;
+
+ return MAKELONG( GetSystemMenu(ci->hwndActiveChild, 0),
+ ci->hwndActiveChild );
+ }
+ break;
}
}
@@ -1420,13 +1441,19 @@
case WM_MENUCHAR:
- /* MDI children don't have menus */
+ /* MDI children don't have menu bars */
PostMessage( clientWnd->parent->hwndSelf, WM_SYSCOMMAND,
(WPARAM)SC_KEYMENU, (LPARAM)wParam);
return 0x00010000L;
case WM_NEXTMENU:
- /* set current menu to child system menu */
+
+ if( wParam == VK_LEFT ) /* switch to frame system menu */
+ return MAKELONG( GetSystemMenu(clientWnd->parent->hwndSelf, 0),
+ clientWnd->parent->hwndSelf );
+ if( wParam == VK_RIGHT ) /* to frame menu bar */
+ return MAKELONG( clientWnd->parent->wIDmenu,
+ clientWnd->parent->hwndSelf );
break;
}
@@ -1468,7 +1495,7 @@
case WM_MENUCHAR:
- /* MDI children don't have menus */
+ /* MDI children don't have menu bars */
PostMessage( clientWnd->parent->hwndSelf, WM_SYSCOMMAND,
(WPARAM)SC_KEYMENU, (LPARAM)LOWORD(wParam) );
return 0x00010000L;
diff --git a/windows/message.c b/windows/message.c
index 82870e4..4d5b558 100644
--- a/windows/message.c
+++ b/windows/message.c
@@ -16,7 +16,6 @@
#include "heap.h"
#include "hook.h"
#include "spy.h"
-#include "stackframe.h"
#include "winpos.h"
#include "atom.h"
#include "dde.h"
@@ -59,11 +58,12 @@
WND *pWnd;
BOOL eatMsg = FALSE;
INT16 hittest;
+ MOUSEHOOKSTRUCT16 *hook;
+ BOOL32 ret;
static DWORD lastClickTime = 0;
static WORD lastClickMsg = 0;
static POINT16 lastClickPos = { 0, 0 };
POINT16 pt = msg->pt;
- MOUSEHOOKSTRUCT16 hook = { msg->pt, 0, HTCLIENT, 0 };
BOOL mouseClick = ((msg->message == WM_LBUTTONDOWN) ||
(msg->message == WM_RBUTTONDOWN) ||
@@ -73,12 +73,23 @@
if ((msg->hwnd = GetCapture()) != 0)
{
+ BOOL32 ret;
+
ScreenToClient16( msg->hwnd, &pt );
msg->lParam = MAKELONG( pt.x, pt.y );
/* No need to further process the message */
- hook.hwnd = msg->hwnd;
- return !HOOK_CallHooks( WH_MOUSE, remove ? HC_ACTION : HC_NOREMOVE,
- msg->message, (LPARAM)MAKE_SEGPTR(&hook));
+
+ if (!HOOK_GetHook( WH_MOUSE, GetTaskQueue(0)) ||
+ !(hook = SEGPTR_NEW(MOUSEHOOKSTRUCT16)))
+ return TRUE;
+ hook->pt = msg->pt;
+ hook->hwnd = msg->hwnd;
+ hook->wHitTestCode = HTCLIENT;
+ hook->dwExtraInfo = 0;
+ ret = !HOOK_CallHooks( WH_MOUSE, remove ? HC_ACTION : HC_NOREMOVE,
+ msg->message, (LPARAM)SEGPTR_GET(hook));
+ SEGPTR_FREE(hook);
+ return ret;
}
hittest = WINPOS_WindowFromPoint( msg->pt, &pWnd );
@@ -100,7 +111,7 @@
/* Send the WM_PARENTNOTIFY message */
WIN_SendParentNotify( msg->hwnd, msg->message, 0,
- MAKELONG( msg->pt.x, msg->pt.y ) );
+ MAKELPARAM( msg->pt.x, msg->pt.y ) );
/* Activate the window if needed */
@@ -167,11 +178,21 @@
msg->message += WM_NCLBUTTONDOWN - WM_LBUTTONDOWN;
}
msg->lParam = MAKELONG( pt.x, pt.y );
-
- hook.hwnd = msg->hwnd;
- hook.wHitTestCode = hittest;
- return !HOOK_CallHooks( WH_MOUSE, remove ? HC_ACTION : HC_NOREMOVE,
- msg->message, (LPARAM)MAKE_SEGPTR(&hook));
+
+ /* Call the WH_MOUSE hook */
+
+ if (!HOOK_GetHook( WH_MOUSE, GetTaskQueue(0)) ||
+ !(hook = SEGPTR_NEW(MOUSEHOOKSTRUCT16)))
+ return TRUE;
+
+ hook->pt = msg->pt;
+ hook->hwnd = msg->hwnd;
+ hook->wHitTestCode = hittest;
+ hook->dwExtraInfo = 0;
+ ret = !HOOK_CallHooks( WH_MOUSE, remove ? HC_ACTION : HC_NOREMOVE,
+ msg->message, (LPARAM)SEGPTR_GET(hook) );
+ SEGPTR_FREE(hook);
+ return ret;
}
@@ -214,6 +235,46 @@
msg->wParam, msg->lParam );
}
+/***********************************************************************
+ * MSG_JournalRecordMsg
+ *
+ * Build an EVENTMSG structure and call JOURNALRECORD hook
+ */
+static void MSG_JournalRecordMsg( MSG16 *msg )
+{
+ EVENTMSG16 *event = SEGPTR_NEW(EVENTMSG16);
+ if (!event) return;
+ event->message = msg->message;
+ event->time = msg->time;
+ if ((msg->message >= WM_KEYFIRST) && (msg->message <= WM_KEYLAST))
+ {
+ event->paramL = (msg->wParam & 0xFF) | (HIWORD(msg->lParam) << 8);
+ event->paramH = msg->lParam & 0x7FFF;
+ if (HIWORD(msg->lParam) & 0x0100)
+ event->paramH |= 0x8000; /* special_key - bit */
+ HOOK_CallHooks( WH_JOURNALRECORD, HC_ACTION, 0,
+ (LPARAM)SEGPTR_GET(event) );
+ }
+ else if ((msg->message >= WM_MOUSEFIRST) && (msg->message <= WM_MOUSELAST))
+ {
+ event->paramL = LOWORD(msg->lParam); /* X pos */
+ event->paramH = HIWORD(msg->lParam); /* Y pos */
+ ClientToScreen16( msg->hwnd, (LPPOINT16)&event->paramL );
+ HOOK_CallHooks( WH_JOURNALRECORD, HC_ACTION, 0,
+ (LPARAM)SEGPTR_GET(event) );
+ }
+ else if ((msg->message >= WM_NCMOUSEMOVE) &&
+ (msg->message <= WM_NCMBUTTONDBLCLK))
+ {
+ event->paramL = LOWORD(msg->lParam); /* X pos */
+ event->paramH = HIWORD(msg->lParam); /* Y pos */
+ event->message += WM_MOUSEMOVE-WM_NCMOUSEMOVE;/* give no info about NC area */
+ HOOK_CallHooks( WH_JOURNALRECORD, HC_ACTION, 0,
+ (LPARAM)SEGPTR_GET(event) );
+ }
+ SEGPTR_FREE(event);
+}
+
/***********************************************************************
* MSG_PeekHardwareMsg
@@ -246,10 +307,20 @@
}
else /* Non-standard hardware event */
{
- HARDWAREHOOKSTRUCT16 hook = { msg->hwnd, msg->message,
- msg->wParam, msg->lParam };
- if (HOOK_CallHooks( WH_HARDWARE, remove ? HC_ACTION : HC_NOREMOVE,
- 0, (LPARAM)MAKE_SEGPTR(&hook) )) continue;
+ HARDWAREHOOKSTRUCT16 *hook;
+ if ((hook = SEGPTR_NEW(HARDWAREHOOKSTRUCT16)))
+ {
+ BOOL32 ret;
+ hook->hWnd = msg->hwnd;
+ hook->wMessage = msg->message;
+ hook->wParam = msg->wParam;
+ hook->lParam = msg->lParam;
+ ret = HOOK_CallHooks( WH_HARDWARE,
+ remove ? HC_ACTION : HC_NOREMOVE,
+ 0, (LPARAM)SEGPTR_GET(hook) );
+ SEGPTR_FREE(hook);
+ if (ret) continue;
+ }
}
/* Check message against filters */
@@ -261,35 +332,7 @@
(GetWindowTask16(msg->hwnd) != GetCurrentTask()))
continue; /* Not for this task */
if (remove && HOOK_GetHook( WH_JOURNALRECORD, GetTaskQueue(0) ))
- {
- EVENTMSG16 *event = SEGPTR_NEW(EVENTMSG16);
- if (event)
- {
- event->message = msg->message;
- event->time = msg->time;
- if ((msg->message >= WM_KEYFIRST) &&
- (msg->message <= WM_KEYLAST))
- {
- event->paramL = (msg->wParam & 0xFF) |
- (HIWORD(msg->lParam) << 8);
- event->paramH = msg->lParam & 0x7FFF;
- if (HIWORD(msg->lParam) & 0x0100)
- event->paramH |= 0x8000; /* special_key - bit */
- HOOK_CallHooks( WH_JOURNALRECORD, HC_ACTION,
- 0, (LPARAM)SEGPTR_GET(event) );
- }
- else if ((msg->message >= WM_MOUSEFIRST) &&
- (msg->message <= WM_MOUSELAST))
- {
- event->paramL = LOWORD(msg->lParam); /* X pos */
- event->paramH = HIWORD(msg->lParam); /* Y pos */
- ClientToScreen16( msg->hwnd, (LPPOINT16)&event->paramL );
- HOOK_CallHooks( WH_JOURNALRECORD, HC_ACTION,
- 0, (LPARAM)SEGPTR_GET(event) );
- }
- SEGPTR_FREE(event);
- }
- }
+ MSG_JournalRecordMsg( msg );
if (remove) QUEUE_RemoveMsg( sysMsgQueue, pos );
return TRUE;
}
@@ -336,7 +379,7 @@
if (queue->hWnd)
{
- fprintf( stderr, "Nested SendMessage() not supported\n" );
+ fprintf( stderr, "Nested SendMessage(), msg %04x skipped\n", msg );
return 0;
}
queue->hWnd = hwnd;
@@ -479,24 +522,31 @@
if ((msgQueue->wakeBits & mask) & QS_PAINT)
{
+ WND* wndPtr;
msg->hwnd = WIN_FindWinToRepaint( hwnd , hQueue );
msg->message = WM_PAINT;
msg->wParam = 0;
msg->lParam = 0;
- if( msg->hwnd &&
- (!hwnd || msg->hwnd == hwnd || IsChild(hwnd,msg->hwnd)) )
- {
- WND* wndPtr = WIN_FindWndPtr(msg->hwnd);
- /* FIXME: WM_PAINTICON should be sent sometimes */
+ if ((wndPtr = WIN_FindWndPtr(msg->hwnd)))
+ {
+ if( wndPtr->dwStyle & WS_MINIMIZE &&
+ wndPtr->class->hIcon )
+ {
+ msg->message = WM_PAINTICON;
+ msg->wParam = 1;
+ }
- if( wndPtr->flags & WIN_INTERNAL_PAINT && !wndPtr->hrgnUpdate)
- {
- wndPtr->flags &= ~WIN_INTERNAL_PAINT;
- QUEUE_DecPaintCount( hQueue );
- }
- break;
- }
+ if( !hwnd || msg->hwnd == hwnd || IsChild(hwnd,msg->hwnd) )
+ {
+ if( wndPtr->flags & WIN_INTERNAL_PAINT && !wndPtr->hrgnUpdate)
+ {
+ wndPtr->flags &= ~WIN_INTERNAL_PAINT;
+ QUEUE_DecPaintCount( hQueue );
+ }
+ break;
+ }
+ }
}
/* Check for timer messages, but yield first */
@@ -535,36 +585,52 @@
* 'hwnd' must be the handle of the dialog or menu window.
* 'code' is the message filter value (MSGF_??? codes).
*/
-BOOL MSG_InternalGetMessage( SEGPTR msg, HWND hwnd, HWND hwndOwner, short code,
+BOOL MSG_InternalGetMessage( MSG16 *msg, HWND hwnd, HWND hwndOwner, short code,
WORD flags, BOOL sendIdle )
{
for (;;)
{
if (sendIdle)
{
- if (!MSG_PeekMessage( (MSG16 *)PTR_SEG_TO_LIN(msg),
- 0, 0, 0, flags, TRUE ))
+ if (!MSG_PeekMessage( msg, 0, 0, 0, flags, TRUE ))
{
/* No message present -> send ENTERIDLE and wait */
if (IsWindow(hwndOwner))
SendMessage16( hwndOwner, WM_ENTERIDLE,
code, (LPARAM)hwnd );
- MSG_PeekMessage( (MSG16 *)PTR_SEG_TO_LIN(msg),
- 0, 0, 0, flags, FALSE );
+ MSG_PeekMessage( msg, 0, 0, 0, flags, FALSE );
}
}
else /* Always wait for a message */
- MSG_PeekMessage( (MSG16 *)PTR_SEG_TO_LIN(msg),
- 0, 0, 0, flags, FALSE );
+ MSG_PeekMessage( msg, 0, 0, 0, flags, FALSE );
- if (!CallMsgFilter( msg, code ))
- return (((MSG16 *)PTR_SEG_TO_LIN(msg))->message != WM_QUIT);
+ /* Call message filters */
- /* Message filtered -> remove it from the queue */
- /* if it's still there. */
- if (!(flags & PM_REMOVE))
- MSG_PeekMessage( (MSG16 *)PTR_SEG_TO_LIN(msg),
- 0, 0, 0, PM_REMOVE, TRUE );
+ if (HOOK_GetHook( WH_SYSMSGFILTER, GetTaskQueue(0) ) ||
+ HOOK_GetHook( WH_MSGFILTER, GetTaskQueue(0) ))
+ {
+ MSG16 *pmsg = SEGPTR_NEW(MSG16);
+ if (pmsg)
+ {
+ BOOL32 ret;
+ *pmsg = *msg;
+ ret = (HOOK_CallHooks( WH_SYSMSGFILTER, code, 0,
+ (LPARAM)SEGPTR_GET(pmsg) ) ||
+ HOOK_CallHooks( WH_MSGFILTER, code, 0,
+ (LPARAM)SEGPTR_GET(pmsg) ));
+ SEGPTR_FREE(pmsg);
+ if (ret)
+ {
+ /* Message filtered -> remove it from the queue */
+ /* if it's still there. */
+ if (!(flags & PM_REMOVE))
+ MSG_PeekMessage( msg, 0, 0, 0, PM_REMOVE, TRUE );
+ continue;
+ }
+ }
+ }
+
+ return (msg->message != WM_QUIT);
}
}
@@ -665,13 +731,6 @@
{
WND * wndPtr;
LRESULT ret;
- struct
- {
- LPARAM lParam;
- WPARAM16 wParam;
- UINT16 wMsg;
- HWND16 hWnd;
- } msgstruct = { lParam, wParam, msg, hwnd };
#ifdef CONFIG_IPC
MSG16 DDE_msg = { hwnd, msg, wParam, lParam };
@@ -694,19 +753,37 @@
return TRUE;
}
- HOOK_CallHooks( WH_CALLWNDPROC, HC_ACTION, 1,
- (LPARAM)MAKE_SEGPTR(&msgstruct) );
- hwnd = msgstruct.hWnd;
- msg = msgstruct.wMsg;
- wParam = msgstruct.wParam;
- lParam = msgstruct.lParam;
+ if (HOOK_GetHook( WH_CALLWNDPROC, GetTaskQueue(0) ))
+ {
+ struct msgstruct
+ {
+ LPARAM lParam;
+ WPARAM16 wParam;
+ UINT16 wMsg;
+ HWND16 hWnd;
+ } *pmsg;
+
+ if ((pmsg = SEGPTR_NEW(struct msgstruct)))
+ {
+ pmsg->hWnd = hwnd;
+ pmsg->wMsg = msg;
+ pmsg->wParam = wParam;
+ pmsg->lParam = lParam;
+ HOOK_CallHooks( WH_CALLWNDPROC, HC_ACTION, 1,
+ (LPARAM)SEGPTR_GET(pmsg) );
+ hwnd = pmsg->hWnd;
+ msg = pmsg->wMsg;
+ wParam = pmsg->wParam;
+ lParam = pmsg->lParam;
+ }
+ }
if (!(wndPtr = WIN_FindWndPtr( hwnd )))
{
fprintf( stderr, "SendMessage16: invalid hwnd %04x\n", hwnd );
return 0;
}
- if (wndPtr->hmemTaskQ == QUEUE_GetDoomedQueue())
+ if (QUEUE_IsDoomedQueue(wndPtr->hmemTaskQ))
return 0; /* Don't send anything if the task is dying */
if (wndPtr->hmemTaskQ != GetTaskQueue(0))
return MSG_SendMessage( wndPtr->hmemTaskQ, hwnd, msg, wParam, lParam );
@@ -758,8 +835,9 @@
return ret;
}
- if (wndPtr->hmemTaskQ == QUEUE_GetDoomedQueue())
+ if (QUEUE_IsDoomedQueue(wndPtr->hmemTaskQ))
return 0; /* Don't send anything if the task is dying */
+
if (wndPtr->hmemTaskQ != GetTaskQueue(0))
{
fprintf( stderr, "SendMessage32A: intertask message not supported\n" );
@@ -800,7 +878,7 @@
fprintf( stderr, "SendMessage32W: invalid hwnd %08x\n", hwnd );
return 0;
}
- if (wndPtr->hmemTaskQ == QUEUE_GetDoomedQueue())
+ if (QUEUE_IsDoomedQueue(wndPtr->hmemTaskQ))
return 0; /* Don't send anything if the task is dying */
if (wndPtr->hmemTaskQ != GetTaskQueue(0))
{
diff --git a/windows/nonclient.c b/windows/nonclient.c
index 0846325..64de6c0 100644
--- a/windows/nonclient.c
+++ b/windows/nonclient.c
@@ -16,7 +16,6 @@
#include "menu.h"
#include "winpos.h"
#include "scroll.h"
-#include "stackframe.h"
#include "nonclient.h"
#include "graphics.h"
#include "queue.h"
@@ -235,17 +234,20 @@
{
RECT16 tmpRect = { 0, 0, 0, 0 };
- NC_AdjustRect( &tmpRect, pWnd->dwStyle, FALSE, pWnd->dwExStyle );
- winRect->left -= tmpRect.left;
- winRect->top -= tmpRect.top;
- winRect->right -= tmpRect.right;
- winRect->bottom -= tmpRect.bottom;
-
- if (HAS_MENU(pWnd))
+ if( !( pWnd->dwStyle & WS_MINIMIZE ) )
{
+ NC_AdjustRect( &tmpRect, pWnd->dwStyle, FALSE, pWnd->dwExStyle );
+ winRect->left -= tmpRect.left;
+ winRect->top -= tmpRect.top;
+ winRect->right -= tmpRect.right;
+ winRect->bottom -= tmpRect.bottom;
+
+ if (HAS_MENU(pWnd))
+ {
winRect->top += MENU_GetMenuBarHeight( pWnd->hwndSelf,
winRect->right - winRect->left,
- -tmpRect.left, -tmpRect.top ) + 1;
+ -tmpRect.left, -tmpRect.top ) + 1;
+ }
}
return 0;
}
@@ -430,14 +432,17 @@
HBITMAP hbitmap;
WND *wndPtr = WIN_FindWndPtr( hwnd );
- NC_GetInsideRect( hwnd, &rect );
- hdcMem = CreateCompatibleDC( hdc );
- hbitmap = SelectObject( hdcMem, hbitmapClose );
- BitBlt( hdc, rect.left, rect.top, SYSMETRICS_CXSIZE, SYSMETRICS_CYSIZE,
- hdcMem, (wndPtr->dwStyle & WS_CHILD) ? SYSMETRICS_CXSIZE : 0, 0,
- down ? NOTSRCCOPY : SRCCOPY );
- SelectObject( hdcMem, hbitmap );
- DeleteDC( hdcMem );
+ if( !(wndPtr->flags & WIN_MANAGED) )
+ {
+ NC_GetInsideRect( hwnd, &rect );
+ hdcMem = CreateCompatibleDC( hdc );
+ hbitmap = SelectObject( hdcMem, hbitmapClose );
+ BitBlt( hdc, rect.left, rect.top, SYSMETRICS_CXSIZE, SYSMETRICS_CYSIZE,
+ hdcMem, (wndPtr->dwStyle & WS_CHILD) ? SYSMETRICS_CXSIZE : 0, 0,
+ down ? NOTSRCCOPY : SRCCOPY );
+ SelectObject( hdcMem, hbitmap );
+ DeleteDC( hdcMem );
+ }
}
@@ -447,12 +452,17 @@
static void NC_DrawMaxButton( HWND hwnd, HDC hdc, BOOL down )
{
RECT16 rect;
- NC_GetInsideRect( hwnd, &rect );
- GRAPH_DrawBitmap( hdc, (IsZoomed(hwnd) ?
- (down ? hbitmapRestoreD : hbitmapRestore) :
- (down ? hbitmapMaximizeD : hbitmapMaximize)),
- rect.right - SYSMETRICS_CXSIZE - 1, rect.top,
- 0, 0, SYSMETRICS_CXSIZE+1, SYSMETRICS_CYSIZE );
+ WND *wndPtr = WIN_FindWndPtr( hwnd );
+
+ if( !(wndPtr->flags & WIN_MANAGED) )
+ {
+ NC_GetInsideRect( hwnd, &rect );
+ GRAPH_DrawBitmap( hdc, (IsZoomed(hwnd) ?
+ (down ? hbitmapRestoreD : hbitmapRestore) :
+ (down ? hbitmapMaximizeD : hbitmapMaximize)),
+ rect.right - SYSMETRICS_CXSIZE - 1, rect.top,
+ 0, 0, SYSMETRICS_CXSIZE+1, SYSMETRICS_CYSIZE );
+ }
}
@@ -463,11 +473,15 @@
{
RECT16 rect;
WND *wndPtr = WIN_FindWndPtr( hwnd );
- NC_GetInsideRect( hwnd, &rect );
- if (wndPtr->dwStyle & WS_MAXIMIZEBOX) rect.right -= SYSMETRICS_CXSIZE + 1;
- GRAPH_DrawBitmap( hdc, (down ? hbitmapMinimizeD : hbitmapMinimize),
- rect.right - SYSMETRICS_CXSIZE - 1, rect.top,
- 0, 0, SYSMETRICS_CXSIZE+1, SYSMETRICS_CYSIZE );
+
+ if( !(wndPtr->flags & WIN_MANAGED) )
+ {
+ NC_GetInsideRect( hwnd, &rect );
+ if (wndPtr->dwStyle & WS_MAXIMIZEBOX) rect.right -= SYSMETRICS_CXSIZE + 1;
+ GRAPH_DrawBitmap( hdc, (down ? hbitmapMinimizeD : hbitmapMinimize),
+ rect.right - SYSMETRICS_CXSIZE - 1, rect.top,
+ 0, 0, SYSMETRICS_CXSIZE+1, SYSMETRICS_CYSIZE );
+ }
}
@@ -587,6 +601,8 @@
WND * wndPtr = WIN_FindWndPtr( hwnd );
char buffer[256];
+ if (wndPtr->flags & WIN_MANAGED) return;
+
if (!hbitmapClose)
{
if (!(hbitmapClose = LoadBitmap16( 0, MAKEINTRESOURCE(OBM_CLOSE) )))
@@ -658,7 +674,8 @@
WND *wndPtr = WIN_FindWndPtr( hwnd );
- if (!wndPtr || !(wndPtr->dwStyle & WS_VISIBLE)) return; /* Nothing to do */
+ if (!wndPtr || wndPtr->dwStyle & WS_MINIMIZE ||
+ !WIN_IsWindowDrawable( wndPtr, 0 )) return; /* Nothing to do */
active = wndPtr->flags & WIN_NCACTIVATED;
@@ -666,29 +683,6 @@
if (!(hdc = GetDCEx( hwnd, 0, DCX_USESTYLE | DCX_WINDOW ))) return;
- /*
- * If this is an icon, we don't want to do any more nonclient painting
- * of the window manager.
- * If there is a class icon to draw, draw it
- */
- if (IsIconic(hwnd))
- {
- if (wndPtr->class->hIcon)
- {
- SendMessage16(hwnd, WM_ICONERASEBKGND, (WPARAM)hdc, 0);
- DrawIcon( hdc, 0, 0, wndPtr->class->hIcon );
- }
- ReleaseDC(hwnd, hdc);
- wndPtr->flags &= ~WIN_INTERNAL_PAINT;
- if( wndPtr->hrgnUpdate )
- {
- DeleteObject( wndPtr->hrgnUpdate );
- QUEUE_DecPaintCount( wndPtr->hmemTaskQ );
- wndPtr->hrgnUpdate = 0;
- }
- return;
- }
-
if (ExcludeVisRect( hdc, wndPtr->rectClient.left-wndPtr->rectWindow.left,
wndPtr->rectClient.top-wndPtr->rectWindow.top,
wndPtr->rectClient.right-wndPtr->rectWindow.left,
@@ -776,14 +770,23 @@
*
* Handle a WM_NCACTIVATE message. Called from DefWindowProc().
*/
-LONG NC_HandleNCActivate( HWND hwnd, WPARAM wParam )
+LONG NC_HandleNCActivate( WND *wndPtr, WPARAM wParam )
{
- WND *wndPtr = WIN_FindWndPtr(hwnd);
+ WORD wStateChange;
- if (wParam != 0) wndPtr->flags |= WIN_NCACTIVATED;
- else wndPtr->flags &= ~WIN_NCACTIVATED;
+ if( wParam ) wStateChange = !(wndPtr->flags & WIN_NCACTIVATED);
+ else wStateChange = wndPtr->flags & WIN_NCACTIVATED;
- NC_DoNCPaint( hwnd, (HRGN)1, FALSE );
+ if( wStateChange )
+ {
+ if (wParam) wndPtr->flags |= WIN_NCACTIVATED;
+ else wndPtr->flags &= ~WIN_NCACTIVATED;
+
+ if( wndPtr->dwStyle & WS_MINIMIZE )
+ PAINT_RedrawWindow( wndPtr->hwndSelf, NULL, 0, RDW_INVALIDATE | RDW_ERASE | RDW_ERASENOW, 0 );
+ else
+ NC_DoNCPaint( wndPtr->hwndSelf, (HRGN)1, FALSE );
+ }
return TRUE;
}
@@ -841,6 +844,21 @@
return (LONG)SetCursor( LoadCursor16( 0, IDC_ARROW ) );
}
+/***********************************************************************
+ * NC_GetSysPopupPos
+ */
+BOOL NC_GetSysPopupPos( WND* wndPtr, RECT16* rect )
+{
+ if( !wndPtr->hSysMenu ) return FALSE;
+
+ NC_GetInsideRect( wndPtr->hwndSelf, rect );
+ OffsetRect16( rect, wndPtr->rectWindow.left, wndPtr->rectWindow.top );
+ if (wndPtr->dwStyle & WS_CHILD)
+ ClientToScreen16( wndPtr->parent->hwndSelf, (POINT16 *)rect );
+ rect->right = rect->left + SYSMETRICS_CXSIZE;
+ rect->bottom = rect->top + SYSMETRICS_CYSIZE;
+ return TRUE;
+}
/***********************************************************************
* NC_TrackSysMenu
@@ -854,19 +872,16 @@
int iconic = wndPtr->dwStyle & WS_MINIMIZE;
if (!(wndPtr->dwStyle & WS_SYSMENU)) return;
+
/* If window has a menu, track the menu bar normally if it not minimized */
if (HAS_MENU(wndPtr) && !iconic) MENU_TrackMouseMenuBar( hwnd, pt );
else
{
/* Otherwise track the system menu like a normal popup menu */
- NC_GetInsideRect( hwnd, &rect );
- OffsetRect16( &rect, wndPtr->rectWindow.left, wndPtr->rectWindow.top );
- if (wndPtr->dwStyle & WS_CHILD)
- ClientToScreen16( wndPtr->parent->hwndSelf, (POINT16 *)&rect );
- rect.right = rect.left + SYSMETRICS_CXSIZE;
- rect.bottom = rect.top + SYSMETRICS_CYSIZE;
+
+ NC_GetSysPopupPos( wndPtr, &rect );
if (!iconic) NC_DrawSysButton( hwnd, hdc, TRUE );
- TrackPopupMenu16( wndPtr->hSysMenu, TPM_LEFTALIGN | TPM_LEFTBUTTON,
+ TrackPopupMenu16( GetSystemMenu(hwnd, 0), TPM_LEFTALIGN | TPM_LEFTBUTTON,
rect.left, rect.bottom, 0, hwnd, &rect );
if (!iconic) NC_DrawSysButton( hwnd, hdc, FALSE );
}
@@ -908,8 +923,7 @@
SetCapture(hwnd);
while(!hittest)
{
- MSG_InternalGetMessage( MAKE_SEGPTR(&msg), 0, 0, MSGF_SIZE,
- PM_REMOVE, FALSE );
+ MSG_InternalGetMessage( &msg, 0, 0, MSGF_SIZE, PM_REMOVE, FALSE );
switch(msg.message)
{
case WM_MOUSEMOVE:
@@ -1048,8 +1062,7 @@
{
int dx = 0, dy = 0;
- MSG_InternalGetMessage( MAKE_SEGPTR(&msg), 0, 0, MSGF_SIZE,
- PM_REMOVE, FALSE );
+ MSG_InternalGetMessage( &msg, 0, 0, MSGF_SIZE, PM_REMOVE, FALSE );
/* Exit on button-up, Return, or Esc */
if ((msg.message == WM_LBUTTONUP) ||
@@ -1151,7 +1164,7 @@
do
{
BOOL oldstate = pressed;
- MSG_InternalGetMessage( MAKE_SEGPTR(&msg), 0, 0, 0, PM_REMOVE, FALSE );
+ MSG_InternalGetMessage( &msg, 0, 0, 0, PM_REMOVE, FALSE );
pressed = (NC_HandleNCHitTest( hwnd, msg.pt ) == wParam);
if (pressed != oldstate)
diff --git a/windows/painting.c b/windows/painting.c
index 29a58cb..40f5dff 100644
--- a/windows/painting.c
+++ b/windows/painting.c
@@ -88,10 +88,13 @@
*/
HDC16 BeginPaint16( HWND16 hwnd, LPPAINTSTRUCT16 lps )
{
+ BOOL32 bIcon;
HRGN hrgnUpdate;
- WND * wndPtr = WIN_FindWndPtr( hwnd );
+ WND *wndPtr = WIN_FindWndPtr( hwnd );
if (!wndPtr) return 0;
+ bIcon = (wndPtr->dwStyle & WS_MINIMIZE && wndPtr->class->hIcon);
+
wndPtr->flags &= ~WIN_NEEDS_BEGINPAINT;
if (wndPtr->flags & WIN_NEEDS_NCPAINT) WIN_UpdateNCArea( wndPtr, TRUE );
@@ -107,13 +110,15 @@
dprintf_win(stddeb,"hrgnUpdate = %04x, ", hrgnUpdate);
- lps->hdc = GetDCEx( hwnd, hrgnUpdate, DCX_INTERSECTRGN | DCX_WINDOWPAINT | DCX_USESTYLE );
+ /* When bIcon is TRUE hrgnUpdate is automatically in window coordinates
+ * (because rectClient == rectWindow for WS_MINIMIZE windows).
+ */
+
+ lps->hdc = GetDCEx( hwnd, hrgnUpdate, DCX_INTERSECTRGN | DCX_WINDOWPAINT |
+ DCX_USESTYLE | (bIcon ? DCX_WINDOW : 0) );
dprintf_win(stddeb,"hdc = %04x\n", lps->hdc);
- /* pseudocode from "Internals" doesn't delete hrgnUpdate - yet another clue
- that ReleaseDC should take care of it (hence DCX_KEEPCLIPRGN) */
-
if (!lps->hdc)
{
fprintf(stderr, "GetDCEx() failed in BeginPaint(), hwnd=%04x\n", hwnd);
@@ -126,7 +131,9 @@
if (wndPtr->flags & WIN_NEEDS_ERASEBKGND)
{
wndPtr->flags &= ~WIN_NEEDS_ERASEBKGND;
- lps->fErase = !SendMessage16(hwnd, WM_ERASEBKGND, (WPARAM)lps->hdc, 0);
+ lps->fErase = !SendMessage16(hwnd, (bIcon) ? WM_ICONERASEBKGND
+ : WM_ERASEBKGND,
+ (WPARAM)lps->hdc, 0 );
}
else lps->fErase = TRUE;
@@ -218,20 +225,32 @@
/***********************************************************************
- * RedrawWindow32 (USER32.425)
+ * PAINT_RedrawWindow
+ *
+ * Note: Windows uses WM_SYNCPAINT to cut down the number of intertask
+ * SendMessage() calls. From SDK:
+ * This message avoids lots of inter-app message traffic
+ * by switching to the other task and continuing the
+ * recursion there.
+ *
+ * wParam = flags
+ * LOWORD(lParam) = hrgnClip
+ * HIWORD(lParam) = hwndSkip (not used; always NULL)
*/
-BOOL32 RedrawWindow32( HWND32 hwnd, const RECT32 *rectUpdate,
- HRGN32 hrgnUpdate, UINT32 flags )
+BOOL32 PAINT_RedrawWindow( HWND32 hwnd, const RECT32 *rectUpdate,
+ HRGN32 hrgnUpdate, UINT32 flags, UINT32 control )
{
+ BOOL32 bIcon;
HRGN hrgn;
RECT32 rectClient;
- WND * wndPtr;
+ WND* wndPtr;
if (!hwnd) hwnd = GetDesktopWindow();
if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
if (!IsWindowVisible(hwnd) || (wndPtr->flags & WIN_NO_REDRAW))
return TRUE; /* No redraw needed */
+ bIcon = (wndPtr->dwStyle & WS_MINIMIZE && wndPtr->class->hIcon);
if (rectUpdate)
{
dprintf_win(stddeb, "RedrawWindow: %04x %d,%d-%d,%d %04x flags=%04x\n",
@@ -283,7 +302,7 @@
}
else
if (flags & RDW_ERASE) wndPtr->flags |= WIN_NEEDS_ERASEBKGND;
- flags |= RDW_FRAME; /* Force invalidating the frame of children */
+ flags |= RDW_FRAME; /* Force children frame invalidation */
}
else if (flags & RDW_VALIDATE) /* Validate */
{
@@ -335,7 +354,8 @@
if (flags & RDW_UPDATENOW)
{
- if (wndPtr->hrgnUpdate) SendMessage16( hwnd, WM_PAINT, 0, 0 );
+ if (wndPtr->hrgnUpdate) /* wm_painticon wparam is 1 */
+ SendMessage16( hwnd, (bIcon) ? WM_PAINTICON : WM_PAINT, bIcon, 0 );
}
else if (flags & RDW_ERASENOW)
{
@@ -345,18 +365,16 @@
if (wndPtr->flags & WIN_NEEDS_ERASEBKGND)
{
HDC hdc = GetDCEx( hwnd, wndPtr->hrgnUpdate,
- DCX_INTERSECTRGN | DCX_USESTYLE | DCX_KEEPCLIPRGN | DCX_WINDOWPAINT);
+ DCX_INTERSECTRGN | DCX_USESTYLE |
+ DCX_KEEPCLIPRGN | DCX_WINDOWPAINT |
+ (bIcon ? DCX_WINDOW : 0) );
if (hdc)
{
- /* Don't send WM_ERASEBKGND to icons */
- /* (WM_ICONERASEBKGND is sent during processing of WM_NCPAINT) */
- if (!(wndPtr->dwStyle & WS_MINIMIZE) ||
- !wndPtr->class->hIcon)
- {
- if (SendMessage16( hwnd, WM_ERASEBKGND, (WPARAM)hdc, 0 ))
- wndPtr->flags &= ~WIN_NEEDS_ERASEBKGND;
- }
- ReleaseDC( hwnd, hdc );
+ if (SendMessage16( hwnd, (bIcon) ? WM_ICONERASEBKGND
+ : WM_ERASEBKGND,
+ (WPARAM)hdc, 0 ))
+ wndPtr->flags &= ~WIN_NEEDS_ERASEBKGND;
+ ReleaseDC( hwnd, hdc );
}
}
}
@@ -364,42 +382,65 @@
/* Recursively process children */
if (!(flags & RDW_NOCHILDREN) &&
- ((flags & RDW_ALLCHILDREN) || !(wndPtr->dwStyle & WS_CLIPCHILDREN)))
+ ((flags & RDW_ALLCHILDREN) || !(wndPtr->dwStyle & WS_CLIPCHILDREN)) &&
+ !(wndPtr->dwStyle & WS_MINIMIZE) )
{
- if (hrgnUpdate)
+ if ( hrgnUpdate || rectUpdate )
{
- HRGN hrgn = CreateRectRgn( 0, 0, 0, 0 );
- if (!hrgn) return TRUE;
- for (wndPtr = wndPtr->child; wndPtr; wndPtr = wndPtr->next)
- {
- CombineRgn( hrgn, hrgnUpdate, 0, RGN_COPY );
- OffsetRgn( hrgn, -wndPtr->rectClient.left,
- -wndPtr->rectClient.top );
- RedrawWindow32( wndPtr->hwndSelf, NULL, hrgn, flags );
- }
- DeleteObject( hrgn );
+ if( !(hrgn = CreateRectRgn( 0, 0, 0, 0 )) ) return TRUE;
+ if( !hrgnUpdate )
+ {
+ control |= (RDW_C_DELETEHRGN | RDW_C_USEHRGN);
+ if( !(hrgnUpdate = CreateRectRgnIndirect32( rectUpdate )) )
+ {
+ DeleteObject( hrgn );
+ return TRUE;
+ }
+ }
+ for (wndPtr = wndPtr->child; wndPtr; wndPtr = wndPtr->next)
+ if( wndPtr->dwStyle & WS_VISIBLE )
+ {
+ SetRectRgn( hrgn, wndPtr->rectWindow.left, wndPtr->rectWindow.top,
+ wndPtr->rectWindow.right, wndPtr->rectWindow.bottom);
+ if( CombineRgn( hrgn, hrgn, hrgnUpdate, RGN_AND ) != NULLREGION )
+ {
+ if( control & RDW_C_USEHRGN &&
+ wndPtr->dwStyle & WS_CLIPSIBLINGS )
+ CombineRgn( hrgnUpdate, hrgnUpdate, hrgn, RGN_DIFF );
+
+ OffsetRgn( hrgn, -wndPtr->rectClient.left,
+ -wndPtr->rectClient.top );
+ PAINT_RedrawWindow( wndPtr->hwndSelf, NULL, hrgn, flags, RDW_C_USEHRGN );
+ }
+ }
+ DeleteObject( hrgn );
+ if( control & RDW_C_DELETEHRGN ) DeleteObject( hrgnUpdate );
}
- else
- {
- RECT32 rect;
- for (wndPtr = wndPtr->child; wndPtr; wndPtr = wndPtr->next)
- {
- if (rectUpdate)
- {
- rect = *rectUpdate;
- OffsetRect32( &rect, -wndPtr->rectClient.left,
- -wndPtr->rectClient.top );
- RedrawWindow32( wndPtr->hwndSelf, &rect, 0, flags );
- }
- else RedrawWindow32( wndPtr->hwndSelf, NULL, 0, flags );
- }
- }
+ else for (wndPtr = wndPtr->child; wndPtr; wndPtr = wndPtr->next)
+ PAINT_RedrawWindow( wndPtr->hwndSelf, NULL, 0, flags, 0 );
+
}
return TRUE;
}
/***********************************************************************
+ * RedrawWindow32 (USER32.425)
+ */
+BOOL32 RedrawWindow32( HWND32 hwnd, const RECT32 *rectUpdate,
+ HRGN32 hrgnUpdate, UINT32 flags )
+{
+ WND* wnd = WIN_FindWndPtr( hwnd );
+
+ /* check if there is something to redraw */
+
+ return ( wnd && WIN_IsWindowDrawable( wnd, !(flags & RDW_FRAME) ) )
+ ? PAINT_RedrawWindow( hwnd, rectUpdate, hrgnUpdate, flags, 0 )
+ : 1;
+}
+
+
+/***********************************************************************
* RedrawWindow16 (USER.290)
*/
BOOL16 RedrawWindow16( HWND16 hwnd, const RECT16 *rectUpdate,
@@ -429,7 +470,7 @@
*/
void InvalidateRgn( HWND32 hwnd, HRGN32 hrgn, BOOL32 erase )
{
- RedrawWindow32(hwnd, NULL, hrgn, RDW_INVALIDATE | (erase ? RDW_ERASE : 0));
+ RedrawWindow32(hwnd, NULL, hrgn, RDW_INVALIDATE | (erase ? RDW_ERASE : 0) );
}
diff --git a/windows/queue.c b/windows/queue.c
index 3ae6306..b827727 100644
--- a/windows/queue.c
+++ b/windows/queue.c
@@ -84,11 +84,11 @@
/***********************************************************************
- * QUEUE_GetDoomedQueue/QUEUE_SetDoomedQueue
+ * QUEUE_IsDoomedQueue
*/
-HQUEUE16 QUEUE_GetDoomedQueue()
+BOOL32 QUEUE_IsDoomedQueue( HQUEUE16 hQueue )
{
- return hDoomedQueue;
+ return (hDoomedQueue && (hQueue == hDoomedQueue));
}
diff --git a/windows/scroll.c b/windows/scroll.c
index 7c11953..9b8d699 100644
--- a/windows/scroll.c
+++ b/windows/scroll.c
@@ -41,6 +41,8 @@
(int)((clipRect)?clipRect->right:0),
(int)((clipRect)?clipRect->bottom:0));
+ if ( !wndScroll || !WIN_IsWindowDrawable( wndScroll, TRUE ) ) return;
+
if ( !rect ) /* do not clip children */
{
GetClientRect16(hwnd, &rc);
@@ -87,10 +89,8 @@
SWP_DEFERERASE );
}
- /* RDW_ALLCHILDREN is to account for dialog controls */
-
- RedrawWindow32( hwnd, NULL, hrgnUpdate, RDW_ALLCHILDREN |
- RDW_INVALIDATE | RDW_ERASE | RDW_ERASENOW);
+ PAINT_RedrawWindow( hwnd, NULL, hrgnUpdate, RDW_ALLCHILDREN |
+ RDW_INVALIDATE | RDW_ERASE | RDW_ERASENOW, RDW_C_USEHRGN );
DeleteObject(hrgnUpdate);
if( hCaretWnd ) ShowCaret(hCaretWnd);
@@ -250,8 +250,8 @@
if (flags | SW_INVALIDATE)
{
- RedrawWindow32( hwnd, NULL, hrgnUpdate, RDW_INVALIDATE | RDW_ERASE |
- ((flags & SW_ERASE) ? RDW_ERASENOW : 0));
+ PAINT_RedrawWindow( hwnd, NULL, hrgnUpdate, RDW_INVALIDATE | RDW_ERASE |
+ ((flags & SW_ERASE) ? RDW_ERASENOW : 0), 0 );
}
ReleaseDC(hwnd, hdc);
diff --git a/windows/win.c b/windows/win.c
index 63e8564..95e7923 100644
--- a/windows/win.c
+++ b/windows/win.c
@@ -224,7 +224,11 @@
HWND hwndRet;
WND *pWnd = pWndDesktop;
- /* Note: the desktop window never gets WM_PAINT messages */
+ /* Note: the desktop window never gets WM_PAINT messages
+ * The real reason why is because Windows DesktopWndProc
+ * does ValidateRgn inside WM_ERASEBKGND handler.
+ */
+
pWnd = hwnd ? WIN_FindWndPtr( hwnd ) : pWndDesktop->child;
for ( ; pWnd ; pWnd = pWnd->next )
@@ -265,7 +269,7 @@
* Send a WM_PARENTNOTIFY to all ancestors of the given window, unless
* the window has the WS_EX_NOPARENTNOTIFY style.
*/
-void WIN_SendParentNotify( HWND32 hwnd, WORD event, WORD idChild, LONG lValue )
+void WIN_SendParentNotify(HWND32 hwnd, WORD event, WORD idChild, LPARAM lValue)
{
LPPOINT16 lppt = (LPPOINT16)&lValue;
WND *wndPtr = WIN_FindWndPtr( hwnd );
@@ -274,10 +278,7 @@
/* if lValue contains cursor coordinates they have to be
* mapped to the client area of parent window */
- if (bMouse) MapWindowPoints16(0, hwnd, lppt, 1);
-#ifndef WINELIB32
- else lValue = MAKELONG( LOWORD(lValue), idChild );
-#endif
+ if (bMouse) MapWindowPoints16( 0, hwnd, lppt, 1 );
while (wndPtr)
{
@@ -291,12 +292,8 @@
}
wndPtr = wndPtr->parent;
-#ifdef WINELIB32
SendMessage32A( wndPtr->hwndSelf, WM_PARENTNOTIFY,
MAKEWPARAM( event, idChild ), lValue );
-#else
- SendMessage16( wndPtr->hwndSelf, WM_PARENTNOTIFY, event, (LPARAM)lValue);
-#endif
}
}
@@ -364,7 +361,6 @@
BOOL32 WIN_CreateDesktopWindow(void)
{
CLASS *class;
- HDC hdc;
HWND hwndDesktop;
dprintf_win(stddeb,"Creating desktop window\n");
@@ -415,11 +411,7 @@
WINPROC_SetProc( &pWndDesktop->winproc, (WNDPROC16)class->winproc, 0 );
EVENT_RegisterWindow( pWndDesktop );
SendMessage32A( hwndDesktop, WM_NCCREATE, 0, 0 );
- if ((hdc = GetDC( hwndDesktop )) != 0)
- {
- SendMessage32A( hwndDesktop, WM_ERASEBKGND, hdc, 0 );
- ReleaseDC( hwndDesktop, hdc );
- }
+ pWndDesktop->flags |= WIN_NEEDS_ERASEBKGND;
return TRUE;
}
@@ -705,7 +697,7 @@
wndPtr->rectClient.top ));
}
- WIN_SendParentNotify( hwnd, WM_CREATE, wndPtr->wIDmenu, (LONG)hwnd );
+ WIN_SendParentNotify( hwnd, WM_CREATE, wndPtr->wIDmenu, (LPARAM)hwnd );
if (!IsWindow(hwnd)) return 0;
/* Show the window, maximizing or minimizing if needed */
@@ -904,7 +896,7 @@
SWP_NOZORDER | SWP_NOMOVE | SWP_NOSIZE );
if ((hwnd == GetCapture()) || IsChild( hwnd, GetCapture() ))
ReleaseCapture();
- WIN_SendParentNotify( hwnd, WM_DESTROY, wndPtr->wIDmenu, (LONG)hwnd );
+ WIN_SendParentNotify( hwnd, WM_DESTROY, wndPtr->wIDmenu, (LPARAM)hwnd );
CLIPBOARD_DisOwn( hwnd );
@@ -1543,8 +1535,29 @@
return (wndPtr && (wndPtr->dwStyle & WS_VISIBLE));
}
-
-
+/***********************************************************************
+ * WIN_IsWindowDrawable
+ *
+ * hwnd is drawable when it is visible, all parents are not
+ * minimized, and it is itself not minimized unless we are
+ * trying to draw icon and the default class icon is set.
+ */
+BOOL32 WIN_IsWindowDrawable( WND* wnd , BOOL32 icon )
+{
+ HWND hwnd= wnd->hwndSelf;
+ BOOL32 yes = TRUE;
+
+ while(wnd && yes)
+ {
+ if( wnd->dwStyle & WS_MINIMIZE )
+ if( wnd->hwndSelf != hwnd ) break;
+ else if( icon && wnd->class->hIcon ) break;
+
+ yes = yes && (wnd->dwStyle & WS_VISIBLE);
+ wnd = wnd->parent; }
+ return (!wnd && yes);
+}
+
/*******************************************************************
* GetTopWindow (USER.229)
*/
@@ -1824,8 +1837,8 @@
}
else
{
- RedrawWindow32( hWnd, 0, 0, RDW_INVALIDATE | RDW_ERASE |
- RDW_UPDATENOW | RDW_FRAME );
+ PAINT_RedrawWindow( hWnd, 0, 0, RDW_INVALIDATE | RDW_ERASE |
+ RDW_UPDATENOW | RDW_FRAME, 0 );
wndPtr->flags &= ~WIN_NCACTIVATED;
}
return TRUE;
diff --git a/windows/winpos.c b/windows/winpos.c
index c6132bb..cfbb72e 100644
--- a/windows/winpos.c
+++ b/windows/winpos.c
@@ -16,7 +16,6 @@
#include "hook.h"
#include "message.h"
#include "queue.h"
-#include "stackframe.h"
#include "options.h"
#include "winpos.h"
#include "dce.h"
@@ -32,6 +31,11 @@
#define SWP_AGG_STATUSFLAGS \
(SWP_AGG_NOPOSCHANGE | SWP_FRAMECHANGED | SWP_HIDEWINDOW | SWP_SHOWWINDOW)
+#define SMC_NOCOPY 0x0001
+#define SMC_NOPARENTERASE 0x0002
+#define SMC_DRAWFRAME 0x0004
+#define SMC_SETXPOS 0x0008
+
/* ----- external functions ----- */
extern void FOCUS_SwitchFocus( HWND , HWND );
@@ -574,6 +578,7 @@
y = wndPtr->ptIconPos.y;
cx = SYSMETRICS_CXICON;
cy = SYSMETRICS_CYICON;
+ swpflags |= SWP_NOCOPYBITS;
}
else swpflags |= SWP_NOSIZE | SWP_NOMOVE;
break;
@@ -597,6 +602,7 @@
swpflags |= SWP_NOSIZE | SWP_NOMOVE;
break;
}
+ else swpflags |= SWP_NOCOPYBITS;
cx = maxSize.x;
cy = maxSize.y;
@@ -650,6 +656,7 @@
cx = wndPtr->rectNormal.right - wndPtr->rectNormal.left;
cy = wndPtr->rectNormal.bottom - wndPtr->rectNormal.top;
}
+ swpflags |= SWP_NOCOPYBITS;
}
else if (wndPtr->dwStyle & WS_MAXIMIZE)
{
@@ -1179,11 +1186,14 @@
pWndCur = wndPtr->next;
while (pWndCur != pWndPrevAfter)
{
- RECT16 rect = pWndCur->rectWindow;
- OffsetRect16( &rect, -wndPtr->rectClient.left,
+ RECT32 rect = { pWndCur->rectWindow.left,
+ pWndCur->rectWindow.top,
+ pWndCur->rectWindow.right,
+ pWndCur->rectWindow.bottom };
+ OffsetRect32( &rect, -wndPtr->rectClient.left,
-wndPtr->rectClient.top );
- RedrawWindow16( hwnd, &rect, 0, RDW_INVALIDATE | RDW_ALLCHILDREN |
- RDW_FRAME | RDW_ERASE );
+ PAINT_RedrawWindow( hwnd, &rect, 0, RDW_INVALIDATE | RDW_ALLCHILDREN |
+ RDW_FRAME | RDW_ERASE, 0 );
pWndCur = pWndCur->next;
}
}
@@ -1194,11 +1204,14 @@
WIN_LinkWindow( hwnd, hwndAfter );
while (pWndCur != wndPtr)
{
- RECT16 rect = wndPtr->rectWindow;
- OffsetRect16( &rect, -pWndCur->rectClient.left,
+ RECT32 rect = { pWndCur->rectWindow.left,
+ pWndCur->rectWindow.top,
+ pWndCur->rectWindow.right,
+ pWndCur->rectWindow.bottom };
+ OffsetRect32( &rect, -pWndCur->rectClient.left,
-pWndCur->rectClient.top );
- RedrawWindow16( pWndCur->hwndSelf, &rect, 0, RDW_INVALIDATE |
- RDW_ALLCHILDREN | RDW_FRAME | RDW_ERASE );
+ PAINT_RedrawWindow( pWndCur->hwndSelf, &rect, 0, RDW_INVALIDATE |
+ RDW_ALLCHILDREN | RDW_FRAME | RDW_ERASE, 0 );
pWndCur = pWndCur->next;
}
}
@@ -1288,7 +1301,7 @@
* update regions are in window client coordinates
* client and window rectangles are in parent client coordinates
*/
-static void WINPOS_SizeMoveClean(WND* Wnd, HRGN oldVisRgn, LPRECT16 lpOldWndRect, LPRECT16 lpOldClientRect, BOOL bNoCopy )
+static UINT WINPOS_SizeMoveClean(WND* Wnd, HRGN oldVisRgn, LPRECT16 lpOldWndRect, LPRECT16 lpOldClientRect, UINT uFlags )
{
HRGN newVisRgn = DCE_GetVisRgn(Wnd->hwndSelf, DCX_WINDOW | DCX_CLIPSIBLINGS );
HRGN dirtyRgn = CreateRectRgn(0,0,0,0);
@@ -1301,16 +1314,14 @@
Wnd->rectClient.left,Wnd->rectClient.top,Wnd->rectClient.right,Wnd->rectClient.bottom,
lpOldClientRect->left,lpOldClientRect->top,lpOldClientRect->right,lpOldClientRect->bottom);
+ if( (lpOldWndRect->right - lpOldWndRect->left) != (Wnd->rectWindow.right - Wnd->rectWindow.left) ||
+ (lpOldWndRect->bottom - lpOldWndRect->top) != (Wnd->rectWindow.bottom - Wnd->rectWindow.top) )
+ uFlags |= SMC_DRAWFRAME;
+
CombineRgn( dirtyRgn, newVisRgn, 0, RGN_COPY);
- if( !bNoCopy )
- {
- HRGN hRgn = CreateRectRgn( lpOldClientRect->left - lpOldWndRect->left, lpOldClientRect->top - lpOldWndRect->top,
- lpOldClientRect->right - lpOldWndRect->left, lpOldClientRect->bottom - lpOldWndRect->top);
- CombineRgn( newVisRgn, newVisRgn, oldVisRgn, RGN_AND );
- CombineRgn( newVisRgn, newVisRgn, hRgn, RGN_AND );
- DeleteObject(hRgn);
- }
+ if( !(uFlags & SMC_NOCOPY) )
+ CombineRgn( newVisRgn, newVisRgn, oldVisRgn, RGN_AND );
/* map regions to the parent client area */
@@ -1331,72 +1342,78 @@
my = (Wnd->hrgnUpdate > 1)? CombineRgn( newVisRgn, newVisRgn, Wnd->hrgnUpdate, RGN_DIFF)
: COMPLEXREGION;
- if( bNoCopy ) /* invalidate Wnd visible region */
+ if( uFlags & SMC_NOCOPY ) /* invalidate Wnd visible region */
{
- if (my != NULLREGION) RedrawWindow32( Wnd->hwndSelf, NULL, newVisRgn, RDW_INVALIDATE |
- RDW_FRAME | RDW_ALLCHILDREN | RDW_ERASE );
+ if (my != NULLREGION) PAINT_RedrawWindow( Wnd->hwndSelf, NULL, newVisRgn, RDW_INVALIDATE |
+ RDW_FRAME | RDW_ALLCHILDREN | RDW_ERASE, RDW_C_USEHRGN );
}
else /* bitblt old client area */
{
HDC hDC;
int update;
HRGN updateRgn;
+ int xfrom,yfrom,xto,yto,width,height;
- /* client rect */
+ if( uFlags & SMC_DRAWFRAME )
+ {
+ /* copy only client area, frame will be redrawn anyway */
- updateRgn = CreateRectRgn( 0,0, Wnd->rectClient.right - Wnd->rectClient.left,
- Wnd->rectClient.bottom - Wnd->rectClient.top );
+ xfrom = lpOldClientRect->left; yfrom = lpOldClientRect->top;
+ xto = Wnd->rectClient.left; yto = Wnd->rectClient.top;
+ width = lpOldClientRect->right - xfrom; height = lpOldClientRect->bottom - yfrom;
+ updateRgn = CreateRectRgn( 0, 0, width, height );
+ CombineRgn( newVisRgn, newVisRgn, updateRgn, RGN_AND );
+ SetRectRgn( updateRgn, 0, 0, Wnd->rectClient.right - xto, Wnd->rectClient.bottom - yto );
+ }
+ else
+ {
+ xfrom = lpOldWndRect->left; yfrom = lpOldWndRect->top;
+ xto = Wnd->rectWindow.left; yto = Wnd->rectWindow.top;
+ width = lpOldWndRect->right - xfrom; height = lpOldWndRect->bottom - yfrom;
+ updateRgn = CreateRectRgn( xto - Wnd->rectClient.left,
+ yto - Wnd->rectClient.top,
+ Wnd->rectWindow.right - Wnd->rectClient.left,
+ Wnd->rectWindow.bottom - Wnd->rectClient.top );
+ }
- /* clip visible region with client rect */
+ CombineRgn( newVisRgn, newVisRgn, updateRgn, RGN_AND );
- my = CombineRgn( newVisRgn, newVisRgn, updateRgn, RGN_AND );
-
- /* substract result from client rect to get region that won't be copied */
+ /* substract new visRgn from target rect to get a region that won't be copied */
update = CombineRgn( updateRgn, updateRgn, newVisRgn, RGN_DIFF );
/* Blt valid bits using parent window DC */
- if( my != NULLREGION )
+ if( my != NULLREGION && (xfrom != xto || yfrom != yto) )
{
- int xfrom = lpOldClientRect->left;
- int yfrom = lpOldClientRect->top;
- int xto = Wnd->rectClient.left;
- int yto = Wnd->rectClient.top;
+
+ /* compute clipping region in parent client coordinates */
- /* check if we can skip copying */
+ OffsetRgn( newVisRgn, Wnd->rectClient.left, Wnd->rectClient.top);
+ CombineRgn( oldVisRgn, oldVisRgn, newVisRgn, RGN_OR );
- if( xfrom != xto || yfrom != yto )
- {
- /* compute clipping region in parent client coordinates */
+ hDC = GetDCEx( Wnd->parent->hwndSelf, oldVisRgn, DCX_KEEPCLIPRGN | DCX_INTERSECTRGN | DCX_CACHE | DCX_CLIPSIBLINGS);
- OffsetRgn( newVisRgn, Wnd->rectClient.left, Wnd->rectClient.top);
- CombineRgn( oldVisRgn, oldVisRgn, newVisRgn, RGN_OR );
-
- hDC = GetDCEx( Wnd->parent->hwndSelf, oldVisRgn, DCX_KEEPCLIPRGN | DCX_INTERSECTRGN | DCX_CACHE | DCX_CLIPSIBLINGS);
-
- BitBlt(hDC, xto, yto, lpOldClientRect->right - lpOldClientRect->left,
- lpOldClientRect->bottom - lpOldClientRect->top,
- hDC, xfrom, yfrom, SRCCOPY );
+ BitBlt( hDC, xto, yto, width, height, hDC, xfrom, yfrom, SRCCOPY );
- ReleaseDC( Wnd->parent->hwndSelf, hDC);
- }
+ ReleaseDC( Wnd->parent->hwndSelf, hDC);
}
if( update != NULLREGION )
- RedrawWindow32( Wnd->hwndSelf, NULL, updateRgn, RDW_INVALIDATE |
- RDW_FRAME | RDW_ALLCHILDREN | RDW_ERASE );
+ PAINT_RedrawWindow( Wnd->hwndSelf, NULL, updateRgn, RDW_INVALIDATE |
+ RDW_FRAME | RDW_ALLCHILDREN | RDW_ERASE, RDW_C_USEHRGN );
+ else if( uFlags & SMC_DRAWFRAME ) Wnd->flags |= WIN_NEEDS_NCPAINT;
DeleteObject( updateRgn );
}
/* erase uncovered areas */
- if( other != NULLREGION )
- RedrawWindow32( Wnd->parent->hwndSelf, NULL, dirtyRgn,
- RDW_INVALIDATE | RDW_ALLCHILDREN | RDW_ERASE );
-
+ if( !(uFlags & SMC_NOPARENTERASE) && (other != NULLREGION ) )
+ PAINT_RedrawWindow( Wnd->parent->hwndSelf, NULL, dirtyRgn,
+ RDW_INVALIDATE | RDW_ALLCHILDREN | RDW_ERASE, RDW_C_USEHRGN );
DeleteObject(dirtyRgn);
DeleteObject(newVisRgn);
+ return uFlags;
}
@@ -1510,11 +1527,13 @@
BOOL SetWindowPos( HWND hwnd, HWND hwndInsertAfter, INT x, INT y,
INT cx, INT cy, WORD flags )
{
- WINDOWPOS16 winpos;
+ WINDOWPOS16 *winpos;
WND * wndPtr;
- RECT16 newWindowRect, newClientRect;
+ RECT16 newWindowRect, newClientRect, oldWindowRect;
HRGN visRgn = 0;
+ HWND tempInsertAfter= 0;
int result = 0;
+ UINT uFlags = 0;
dprintf_win(stddeb,"SetWindowPos: hwnd %04x, (%i,%i)-(%i,%i) flags %08x\n",
hwnd, x, y, x+cx, y+cy, flags);
@@ -1526,15 +1545,16 @@
if (wndPtr->dwStyle & WS_VISIBLE) flags &= ~SWP_SHOWWINDOW;
else
{
+ uFlags |= SMC_NOPARENTERASE;
flags &= ~SWP_HIDEWINDOW;
if (!(flags & SWP_SHOWWINDOW)) flags |= SWP_NOREDRAW;
}
/* Check for windows that may not be resized
FIXME: this should be done only for Windows 3.0 programs
- */ if (flags & (SWP_SHOWWINDOW | SWP_HIDEWINDOW ) )
+ if (flags & (SWP_SHOWWINDOW | SWP_HIDEWINDOW ) )
flags |= SWP_NOSIZE | SWP_NOMOVE;
-
+*/
/* Check dimensions */
if (cx <= 0) cx = 1;
@@ -1578,45 +1598,48 @@
/* Fill the WINDOWPOS structure */
- winpos.hwnd = hwnd;
- winpos.hwndInsertAfter = hwndInsertAfter;
- winpos.x = x;
- winpos.y = y;
- winpos.cx = cx;
- winpos.cy = cy;
- winpos.flags = flags;
+ if (!(winpos = SEGPTR_NEW(WINDOWPOS16))) return FALSE;
+ winpos->hwnd = hwnd;
+ winpos->hwndInsertAfter = hwndInsertAfter;
+ winpos->x = x;
+ winpos->y = y;
+ winpos->cx = cx;
+ winpos->cy = cy;
+ winpos->flags = flags;
/* Send WM_WINDOWPOSCHANGING message */
if (!(flags & SWP_NOSENDCHANGING))
- SendMessage16( hwnd, WM_WINDOWPOSCHANGING, 0, (LPARAM)MAKE_SEGPTR(&winpos) );
+ SendMessage16( hwnd, WM_WINDOWPOSCHANGING, 0,
+ (LPARAM)SEGPTR_GET(winpos) );
/* Calculate new position and size */
newWindowRect = wndPtr->rectWindow;
- newClientRect = wndPtr->rectClient;
+ newClientRect = (wndPtr->dwStyle & WS_MINIMIZE) ? wndPtr->rectWindow
+ : wndPtr->rectClient;
- if (!(winpos.flags & SWP_NOSIZE))
+ if (!(winpos->flags & SWP_NOSIZE))
{
- newWindowRect.right = newWindowRect.left + winpos.cx;
- newWindowRect.bottom = newWindowRect.top + winpos.cy;
+ newWindowRect.right = newWindowRect.left + winpos->cx;
+ newWindowRect.bottom = newWindowRect.top + winpos->cy;
}
- if (!(winpos.flags & SWP_NOMOVE))
+ if (!(winpos->flags & SWP_NOMOVE))
{
- newWindowRect.left = winpos.x;
- newWindowRect.top = winpos.y;
- newWindowRect.right += winpos.x - wndPtr->rectWindow.left;
- newWindowRect.bottom += winpos.y - wndPtr->rectWindow.top;
+ newWindowRect.left = winpos->x;
+ newWindowRect.top = winpos->y;
+ newWindowRect.right += winpos->x - wndPtr->rectWindow.left;
+ newWindowRect.bottom += winpos->y - wndPtr->rectWindow.top;
- OffsetRect16( &newClientRect, winpos.x - wndPtr->rectWindow.left,
- winpos.y - wndPtr->rectWindow.top );
+ OffsetRect16( &newClientRect, winpos->x - wndPtr->rectWindow.left,
+ winpos->y - wndPtr->rectWindow.top );
}
- winpos.flags |= SWP_NOCLIENTMOVE | SWP_NOCLIENTSIZE;
+ winpos->flags |= SWP_NOCLIENTMOVE | SWP_NOCLIENTSIZE;
/* Reposition window in Z order */
- if (!(winpos.flags & SWP_NOZORDER))
+ if (!(winpos->flags & SWP_NOZORDER))
{
/* reorder owned popups if hwnd is top-level window
*/
@@ -1626,10 +1649,10 @@
if (wndPtr->window)
{
- WIN_UnlinkWindow( winpos.hwnd );
- WIN_LinkWindow( winpos.hwnd, hwndInsertAfter );
+ WIN_UnlinkWindow( winpos->hwnd );
+ WIN_LinkWindow( winpos->hwnd, hwndInsertAfter );
}
- else WINPOS_MoveWindowZOrder( winpos.hwnd, hwndInsertAfter );
+ else WINPOS_MoveWindowZOrder( winpos->hwnd, hwndInsertAfter );
}
if ( !wndPtr->window && !(flags & SWP_NOREDRAW) &&
@@ -1640,26 +1663,26 @@
/* Send WM_NCCALCSIZE message to get new client area */
if( (flags & (SWP_FRAMECHANGED | SWP_NOSIZE)) != SWP_NOSIZE )
{
- result = WINPOS_SendNCCalcSize( winpos.hwnd, TRUE, &newWindowRect,
+ result = WINPOS_SendNCCalcSize( winpos->hwnd, TRUE, &newWindowRect,
&wndPtr->rectWindow, &wndPtr->rectClient,
- MAKE_SEGPTR(&winpos), &newClientRect );
+ SEGPTR_GET(winpos), &newClientRect );
/* FIXME: WVR_ALIGNxxx */
if( newClientRect.left != wndPtr->rectClient.left ||
newClientRect.top != wndPtr->rectClient.top )
- winpos.flags &= ~SWP_NOCLIENTMOVE;
+ winpos->flags &= ~SWP_NOCLIENTMOVE;
if( (newClientRect.right - newClientRect.left !=
wndPtr->rectClient.right - wndPtr->rectClient.left) ||
(newClientRect.bottom - newClientRect.top !=
wndPtr->rectClient.bottom - wndPtr->rectClient.top) )
- winpos.flags &= ~SWP_NOCLIENTSIZE;
+ winpos->flags &= ~SWP_NOCLIENTSIZE;
}
else
if( !(flags & SWP_NOMOVE) && (newClientRect.left != wndPtr->rectClient.left ||
newClientRect.top != wndPtr->rectClient.top) )
- winpos.flags &= ~SWP_NOCLIENTMOVE;
+ winpos->flags &= ~SWP_NOCLIENTMOVE;
/* Update active DCEs */
@@ -1673,33 +1696,40 @@
DCE_InvalidateDCE(wndPtr->parent, &rect);
}
- /* Perform the moving and resizing */
+ /* change geometry */
+
+ oldWindowRect = wndPtr->rectWindow;
if (wndPtr->window)
{
- RECT16 oldWindowRect = wndPtr->rectWindow;
RECT16 oldClientRect = wndPtr->rectClient;
- HWND bogusInsertAfter = winpos.hwndInsertAfter;
+ tempInsertAfter = winpos->hwndInsertAfter;
- winpos.hwndInsertAfter = hwndInsertAfter;
- WINPOS_SetXWindowPos( &winpos );
+ winpos->hwndInsertAfter = hwndInsertAfter;
+
+ /* postpone geometry change */
+
+ if( !(flags & (SWP_SHOWWINDOW | SWP_HIDEWINDOW)) )
+ {
+ WINPOS_SetXWindowPos( winpos );
+ winpos->hwndInsertAfter = tempInsertAfter;
+ }
+ else uFlags |= SMC_SETXPOS;
wndPtr->rectWindow = newWindowRect;
wndPtr->rectClient = newClientRect;
- winpos.hwndInsertAfter = bogusInsertAfter;
- /* FIXME: should do something like WINPOS_SizeMoveClean */
+ if( !(flags & (SWP_SHOWWINDOW | SWP_HIDEWINDOW)) )
+ if( (oldClientRect.left - oldWindowRect.left !=
+ newClientRect.left - newWindowRect.left) ||
+ (oldClientRect.top - oldWindowRect.top !=
+ newClientRect.top - newWindowRect.top) || winpos->flags & SWP_NOCOPYBITS )
- if( (oldClientRect.left - oldWindowRect.left !=
- newClientRect.left - newWindowRect.left) ||
- (oldClientRect.top - oldWindowRect.top !=
- newClientRect.top - newWindowRect.top) )
-
- RedrawWindow32( wndPtr->hwndSelf, NULL, 0, RDW_INVALIDATE |
- RDW_ALLCHILDREN | RDW_FRAME | RDW_ERASE );
- else
- if( winpos.flags & SWP_FRAMECHANGED )
+ PAINT_RedrawWindow( wndPtr->hwndSelf, NULL, 0, RDW_INVALIDATE |
+ RDW_ALLCHILDREN | RDW_FRAME | RDW_ERASE, 0 );
+ else
+ if( winpos->flags & SWP_FRAMECHANGED )
{
WORD wErase = 0;
RECT32 rect;
@@ -1709,8 +1739,8 @@
rect.left = newClientRect.right; rect.top = newClientRect.top;
rect.right = oldClientRect.right; rect.bottom = newClientRect.bottom;
wErase = 1;
- RedrawWindow32( wndPtr->hwndSelf, &rect, 0,
- RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN );
+ PAINT_RedrawWindow( wndPtr->hwndSelf, &rect, 0,
+ RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN, 0 );
}
if( oldClientRect.bottom > newClientRect.bottom )
{
@@ -1718,33 +1748,41 @@
rect.right = (wErase)?oldClientRect.right:newClientRect.right;
rect.bottom = oldClientRect.bottom;
wErase = 1;
- RedrawWindow32( wndPtr->hwndSelf, &rect, 0,
- RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN );
+ PAINT_RedrawWindow( wndPtr->hwndSelf, &rect, 0,
+ RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN, 0 );
}
if( !wErase ) wndPtr->flags |= WIN_NEEDS_NCPAINT;
}
}
else
{
- RECT16 oldWindowRect = wndPtr->rectWindow;
RECT16 oldClientRect = wndPtr->rectClient;
wndPtr->rectWindow = newWindowRect;
wndPtr->rectClient = newClientRect;
- if( !(flags & SWP_NOREDRAW) )
+ if( oldClientRect.bottom - oldClientRect.top ==
+ newClientRect.bottom - newClientRect.top ) result &= ~WVR_VREDRAW;
+
+ if( oldClientRect.right - oldClientRect.left ==
+ newClientRect.right - newClientRect.left ) result &= ~WVR_HREDRAW;
+
+ if( !(flags & (SWP_NOREDRAW | SWP_HIDEWINDOW | SWP_SHOWWINDOW)) )
{
- BOOL bNoCopy = (flags & SWP_NOCOPYBITS) ||
- (result >= WVR_HREDRAW && result < WVR_VALIDRECTS);
+ uFlags |= ((winpos->flags & SWP_NOCOPYBITS) ||
+ (result >= WVR_HREDRAW && result < WVR_VALIDRECTS)) ? SMC_NOCOPY : 0;
+ uFlags |= (winpos->flags & SWP_FRAMECHANGED) ? SMC_DRAWFRAME : 0;
- if( (winpos.flags & SWP_AGG_NOGEOMETRYCHANGE) != SWP_AGG_NOGEOMETRYCHANGE )
- /* optimize cleanup by BitBlt'ing where possible */
-
- WINPOS_SizeMoveClean(wndPtr, visRgn, &oldWindowRect, &oldClientRect, bNoCopy);
+ if( (winpos->flags & SWP_AGG_NOGEOMETRYCHANGE) != SWP_AGG_NOGEOMETRYCHANGE )
+ uFlags = WINPOS_SizeMoveClean(wndPtr, visRgn, &oldWindowRect,
+ &oldClientRect, uFlags);
else
- if( winpos.flags & SWP_FRAMECHANGED )
- RedrawWindow32( winpos.hwnd, NULL, 0, RDW_NOCHILDREN | RDW_FRAME );
+ {
+ /* adjust frame and do not erase parent */
+ if( winpos->flags & SWP_FRAMECHANGED ) wndPtr->flags |= WIN_NEEDS_NCPAINT;
+ if( winpos->flags & SWP_NOZORDER ) uFlags |= SMC_NOPARENTERASE;
+ }
}
DeleteObject(visRgn);
}
@@ -1754,14 +1792,19 @@
wndPtr->dwStyle |= WS_VISIBLE;
if (wndPtr->window)
{
+ if( uFlags & SMC_SETXPOS )
+ {
+ WINPOS_SetXWindowPos( winpos );
+ winpos->hwndInsertAfter = tempInsertAfter;
+ }
XMapWindow( display, wndPtr->window );
}
else
{
if (!(flags & SWP_NOREDRAW))
- RedrawWindow32( winpos.hwnd, NULL, 0,
+ PAINT_RedrawWindow( winpos->hwnd, NULL, 0,
RDW_INVALIDATE | RDW_ALLCHILDREN |
- RDW_FRAME | RDW_ERASE );
+ RDW_FRAME | RDW_ERASENOW | RDW_ERASE, 0 );
}
}
else if (flags & SWP_HIDEWINDOW)
@@ -1770,25 +1813,35 @@
if (wndPtr->window)
{
XUnmapWindow( display, wndPtr->window );
+ if( uFlags & SMC_SETXPOS )
+ {
+ WINPOS_SetXWindowPos( winpos );
+ winpos->hwndInsertAfter = tempInsertAfter;
+ }
}
else
{
if (!(flags & SWP_NOREDRAW))
- RedrawWindow16( wndPtr->parent->hwndSelf, &wndPtr->rectWindow, 0,
- RDW_INVALIDATE | RDW_ALLCHILDREN | RDW_ERASE );
+ {
+ RECT32 rect = { oldWindowRect.left, oldWindowRect.top,
+ oldWindowRect.right, oldWindowRect.bottom };
+ PAINT_RedrawWindow( wndPtr->parent->hwndSelf, &rect, 0,
+ RDW_INVALIDATE | RDW_ALLCHILDREN | RDW_ERASE | RDW_ERASENOW, 0);
+ }
+ uFlags |= SMC_NOPARENTERASE;
}
- if ((winpos.hwnd == GetFocus()) || IsChild(winpos.hwnd, GetFocus()))
- SetFocus( GetParent(winpos.hwnd) ); /* Revert focus to parent */
+ if ((winpos->hwnd == GetFocus()) || IsChild(winpos->hwnd, GetFocus()))
+ SetFocus( GetParent(winpos->hwnd) ); /* Revert focus to parent */
- if (winpos.hwnd == hwndActive)
+ if (winpos->hwnd == hwndActive)
{
/* Activate previously active window if possible */
HWND newActive = hwndPrevActive;
- if (!IsWindow(newActive) || (newActive == winpos.hwnd))
+ if (!IsWindow(newActive) || (newActive == winpos->hwnd))
{
newActive = GetTopWindow( GetDesktopWindow() );
- if (newActive == winpos.hwnd)
+ if (newActive == winpos->hwnd)
newActive = wndPtr->next ? wndPtr->next->hwndSelf : 0;
}
WINPOS_ChangeActiveWindow( newActive, FALSE );
@@ -1798,7 +1851,7 @@
/* Activate the window */
if (!(flags & SWP_NOACTIVATE))
- WINPOS_ChangeActiveWindow( winpos.hwnd, FALSE );
+ WINPOS_ChangeActiveWindow( winpos->hwnd, FALSE );
/* Repaint the window */
@@ -1806,19 +1859,21 @@
EVENT_DummyMotionNotify(); /* Simulate a mouse event to set the cursor */
- if (!(flags & SWP_DEFERERASE))
- RedrawWindow32( wndPtr->parent->hwndSelf, NULL, 0,
- RDW_ALLCHILDREN | RDW_ERASENOW );
+ if (!(flags & SWP_DEFERERASE) && !(uFlags & SMC_NOPARENTERASE) )
+ PAINT_RedrawWindow( wndPtr->parent->hwndSelf, NULL, 0, RDW_ALLCHILDREN | RDW_ERASENOW, 0 );
+ else if( wndPtr->parent == WIN_GetDesktop() && wndPtr->parent->flags & WIN_NEEDS_ERASEBKGND )
+ PAINT_RedrawWindow( wndPtr->parent->hwndSelf, NULL, 0, RDW_NOCHILDREN | RDW_ERASENOW, 0 );
/* And last, send the WM_WINDOWPOSCHANGED message */
- dprintf_win(stddeb,"\tstatus flags = %04x\n", winpos.flags & SWP_AGG_STATUSFLAGS);
+ dprintf_win(stddeb,"\tstatus flags = %04x\n", winpos->flags & SWP_AGG_STATUSFLAGS);
- if ( ((winpos.flags & SWP_AGG_STATUSFLAGS) != SWP_AGG_NOPOSCHANGE) &&
- !(winpos.flags & SWP_NOSENDCHANGING))
- SendMessage16( winpos.hwnd, WM_WINDOWPOSCHANGED,
- 0, (LPARAM)MAKE_SEGPTR(&winpos) );
+ if ( ((winpos->flags & SWP_AGG_STATUSFLAGS) != SWP_AGG_NOPOSCHANGE) &&
+ !(winpos->flags & SWP_NOSENDCHANGING))
+ SendMessage16( winpos->hwnd, WM_WINDOWPOSCHANGED,
+ 0, (LPARAM)SEGPTR_GET(winpos) );
+ SEGPTR_FREE(winpos);
return TRUE;
}
diff --git a/windows/winproc.c b/windows/winproc.c
index 79f99c4..d1c89d7 100644
--- a/windows/winproc.c
+++ b/windows/winproc.c
@@ -679,10 +679,6 @@
*pwparam32 = MAKEWPARAM( wParam16, HIWORD(*plparam) );
*plparam = (LPARAM)(HWND32)LOWORD(*plparam);
}
- else
- {
- *pwparam32 = MAKEWPARAM( wParam16, 0 /* FIXME? */ );
- }
return 0;
case WM_SETTEXT:
*plparam = (LPARAM)PTR_SEG_TO_LIN(*plparam);