From 22945d5aba6bb572560651184b00d9892fc58cf3 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard <julliard@winehq.org> Date: Thu, 2 Mar 1995 17:44:29 +0000 Subject: [PATCH] Release 950202 Wed Feb 1 19:27:55 1995 Alexandre Julliard (julliard@lamisun.epfl.ch) * [windows/nonclient.c] [windows/winpos.c] Implemented maximized windows. Implemented icon positioning and ArrangeIconicWindows(). Bug fixes in SetWindowPos(). * [windows/painting.c] Implemented GetControlBrush(). Window frame is no longer contained in the update region. * [windows/win.c] Destroy owned windows upon DestroyWindow(). Sun Jan 29 16:17:22 1995 David Metcalfe <david@prism.demon.co.uk> * [controls/edit.c] Changed line terminator to \r\n to be compatible with Windows. Fixed bug in text selection. Sun Jan 29 14:10:22 1995 Bernd Schmidt <crux@pool.informatik.rwth-aachen.de> * [misc/shell.c] Rewrote RegCreateKey and RegOpenKey, since they were completely broken. Fixed a bug in RegQueryKeyValue. Implemented RegEnumKey These functions now work somewhat more the way Windows programs expect them to work. --- ANNOUNCE | 20 +- ChangeLog | 29 +++ Configure | 7 +- controls/EDIT.TODO | 23 +++ controls/edit.c | 67 +++++-- controls/scroll.c | 2 - if1632/user.spec | 2 +- include/nonclient.h | 2 + include/win.h | 1 - include/windows.h | 1 + include/winpos.h | 2 - loader/library.c | 3 +- misc/network.c | 1 - misc/shell.c | 304 +++++++++++++++++------------- rc/Imakefile | 1 + tools/build.c | 2 + windows/cursor.c | 1 - windows/mdi.c | 10 - windows/nonclient.c | 83 ++++++++- windows/painting.c | 169 +++++++---------- windows/win.c | 19 +- windows/winpos.c | 439 +++++++++++++++++++++++++++----------------- 22 files changed, 729 insertions(+), 459 deletions(-) create mode 100644 controls/EDIT.TODO diff --git a/ANNOUNCE b/ANNOUNCE index ebdf2dcc090..ed22ab88ade 100644 --- a/ANNOUNCE +++ b/ANNOUNCE @@ -1,14 +1,14 @@ -This is release 950122 of Wine the MS Windows emulator. This is still a +This is release 950202 of Wine the MS Windows emulator. This is still a developer's only release. There are many bugs and many unimplemented API features. Most applications still do not work. Patches should be submitted to "wine-new@amscons.com". Please don't forget to include a ChangeLog entry. I'll make a new release every other Sunday. -WHAT'S NEW with Wine-950122: (see ChangeLog for details) - - ELF format support - - New disassembler based on Mach code, replacing the gdb code - - Faster regions +WHAT'S NEW with Wine-950202: (see ChangeLog for details) + - Maximized windows + - Edit control now uses \r\n for line endings + - Better registry functions - Lots of bug fixes See the README file in the distribution for installation instructions. @@ -17,11 +17,11 @@ Because of lags created by using mirror, this message may reach you before the release is available at the ftp sites. The sources will be available from the following locations: - sunsite.unc.edu:/pub/Linux/ALPHA/wine/Wine-950122.tar.gz - aris.com:/pub/linux/ALPHA/Wine/development/Wine-950122.tar.gz - tsx-11.mit.edu:/pub/linux/ALPHA/Wine/development/Wine-950122.tar.gz - ftp.funet.fi:/pub/OS/Linux/ALPHA/Wine/Wine-950122.tar.gz - ftp.wonderland.org:/Wine/Wine-950122.tar.gz + sunsite.unc.edu:/pub/Linux/ALPHA/wine/Wine-950202.tar.gz + aris.com:/pub/linux/ALPHA/Wine/development/Wine-950202.tar.gz + tsx-11.mit.edu:/pub/linux/ALPHA/Wine/development/Wine-950202.tar.gz + ftp.funet.fi:/pub/OS/Linux/ALPHA/Wine/Wine-950202.tar.gz + ftp.wonderland.org:/Wine/Wine-950202.tar.gz If you submitted a patch, please check to make sure it has been included in the new release. diff --git a/ChangeLog b/ChangeLog index 7592fc4e9f0..f2a9d94d324 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,32 @@ +---------------------------------------------------------------------- +Wed Feb 1 19:27:55 1995 Alexandre Julliard (julliard@lamisun.epfl.ch) + + * [windows/nonclient.c] [windows/winpos.c] + Implemented maximized windows. + Implemented icon positioning and ArrangeIconicWindows(). + Bug fixes in SetWindowPos(). + + * [windows/painting.c] + Implemented GetControlBrush(). + Window frame is no longer contained in the update region. + + * [windows/win.c] + Destroy owned windows upon DestroyWindow(). + +Sun Jan 29 16:17:22 1995 David Metcalfe <david@prism.demon.co.uk> + + * [controls/edit.c] + Changed line terminator to \r\n to be compatible with + Windows. Fixed bug in text selection. + +Sun Jan 29 14:10:22 1995 Bernd Schmidt <crux@pool.informatik.rwth-aachen.de> + + * [misc/shell.c] + Rewrote RegCreateKey and RegOpenKey, since they were completely broken. + Fixed a bug in RegQueryKeyValue. Implemented RegEnumKey + These functions now work somewhat more the way Windows programs expect + them to work. + ---------------------------------------------------------------------- Sun Jan 22 18:55:33 1995 Alexandre Julliard (julliard@lamisun.epfl.ch) diff --git a/Configure b/Configure index d1b365091f3..63e261cd8f1 100644 --- a/Configure +++ b/Configure @@ -47,10 +47,11 @@ then fi echo -echo -n 'Use the XPM library (Y/N) [N]? ' +echo -n 'Use the XPM library (Y/N) [Y]? ' read input -if [ "$input" = 'y' -o "$input" = 'Y' ] -then +if [ "$input" = 'n' -o "$input" = 'N' ] +then : +else XPM='#define USE_XPM' ALLDEFINES="$ALLDEFINES -DUSE_XPM" fi diff --git a/controls/EDIT.TODO b/controls/EDIT.TODO new file mode 100644 index 00000000000..3aa0ff904d2 --- /dev/null +++ b/controls/EDIT.TODO @@ -0,0 +1,23 @@ +- Find all the remaining bugs! + +- ES_LEFT, ES_RIGHT and ES_CENTER. ES_RIGHT and ES_CENTER cannot be + used with single line edit controls or be combined with ES_AUTOHSCROLL. + +- Hide selection when window loses focus and ES_NOHIDESEL to disable + this functionality. + +- ES_LOWERCASE and ES_UPPERCASE. + +- ES_PASSWORD and EM_PASSWORDCHAR. + +- ES_OEMCONVERT. Probably won't do anything very much. + +- ES_READONLY. + +- ES_WANTRETURN and Ctrl-Enter to move to next line when this + functionality is enabled. + +- Implement undo buffer correctly. Windows allows the user to undo + entered text as well as deleted text. You can also undo an undo. + +- Add word wrap - this is a very big change! diff --git a/controls/edit.c b/controls/edit.c index a04b2b96924..e81ab13a132 100644 --- a/controls/edit.c +++ b/controls/edit.c @@ -278,7 +278,10 @@ LONG EditWndProc(HWND hwnd, WORD uMsg, WORD wParam, LONG lParam) break; case EM_SETHANDLE: + HideCaret(hwnd); EDIT_SetHandleMsg(hwnd, wParam); + SetCaretPos(es->WndCol, es->WndRow * es->txtht); + ShowCaret(hwnd); break; case EM_SETMODIFY: @@ -431,7 +434,13 @@ LONG EditWndProc(HWND hwnd, WORD uMsg, WORD wParam, LONG lParam) SetCaretPos(es->WndCol, es->WndRow * es->txtht); ShowCaret(hwnd); break; - +#if 0 + case WM_SETREDRAW: + dprintf_edit(stddeb, "WM_SETREDRAW: hwnd=%d, wParam=%x\n", + hwnd, wParam); + lResult = 0; + break; +#endif case WM_SETTEXT: EDIT_SetTextMsg(hwnd, lParam); break; @@ -548,11 +557,14 @@ long EDIT_CreateMsg(HWND hwnd, LONG lParam) char *text; /* initialize state variable structure */ - /* --- char width array */ hdc = GetDC(hwnd); + + /* --- char width array */ + /* only initialise chars <= 32 as X returns strange widths */ + /* for other chars */ charWidths = (short *)EDIT_HeapAddr(hwnd, es->hCharWidths); memset(charWidths, 0, 256 * sizeof(short)); - GetCharWidth(hdc, 0, 255, charWidths); + GetCharWidth(hdc, 32, 254, &charWidths[32]); /* --- other structure variables */ GetTextMetrics(hdc, &tm); @@ -737,7 +749,7 @@ HANDLE EDIT_GetTextLine(HWND hwnd, int selection) dprintf_edit(stddeb,"GetTextLine %d\n", selection); cp = cp1 = EDIT_TextLine(hwnd, selection); /* advance through line */ - while (*cp && *cp != '\n') + while (*cp && *cp != '\r') { len++; cp++; @@ -804,7 +816,7 @@ int EDIT_LineLength(HWND hwnd, int num) char *cp1; if(!cp)return 0; - cp1 = strchr(cp, '\n'); + cp1 = strchr(cp, '\r'); return cp1 ? (int)(cp1 - cp) : strlen(cp); } @@ -1094,7 +1106,7 @@ HANDLE EDIT_GetStr(HWND hwnd, char *lp, int off, int len, int *diff) dprintf_edit(stddeb,"EDIT_GetStr lp='%s' off=%d len=%d\n", lp, off, len); - if (off<0) off=0; + if (off < 0) off = 0; while (i < off) { s_i = i; @@ -1111,6 +1123,8 @@ HANDLE EDIT_GetStr(HWND hwnd, char *lp, int off, int len, int *diff) ch1 = ch; while (i < len + off) { + if (*(lp + ch) == '\r' || *(lp + ch) == '\n') + break; i += EDIT_CharWidth(hwnd, (BYTE)(*(lp + ch)), i); ch++; } @@ -1191,8 +1205,9 @@ void EDIT_KeyTyped(HWND hwnd, short ch) if (*currchar == '\0' && IsMultiLine()) { /* insert a newline at end of text */ - *currchar = '\n'; - *(currchar + 1) = '\0'; + *currchar = '\r'; + *(currchar + 1) = '\n'; + *(currchar + 2) = '\0'; EDIT_BuildTextPointers(hwnd); } @@ -1220,9 +1235,19 @@ void EDIT_KeyTyped(HWND hwnd, short ch) currchar = CurrChar; } /* make space for new character and put char in buffer */ - memmove(currchar + 1, currchar, strlen(currchar) + 1); - *currchar = ch; - EDIT_ModTextPointers(hwnd, es->CurrLine + 1, 1); + if (ch == '\n') + { + memmove(currchar + 2, currchar, strlen(currchar) + 1); + *currchar = '\r'; + *(currchar + 1) = '\n'; + EDIT_ModTextPointers(hwnd, es->CurrLine + 1, 2); + } + else + { + memmove(currchar + 1, currchar, strlen(currchar) + 1); + *currchar = ch; + EDIT_ModTextPointers(hwnd, es->CurrLine + 1, 1); + } es->TextChanged = TRUE; NOTIFY_PARENT(hwnd, EN_UPDATE); @@ -1347,7 +1372,7 @@ void EDIT_Forward(HWND hwnd) if (*CurrChar == '\0') return; - if (*CurrChar == '\n') + if (*CurrChar == '\r') { EDIT_Home(hwnd); EDIT_Downward(hwnd); @@ -1465,7 +1490,7 @@ void EDIT_End(HWND hwnd) EDITSTATE *es = (EDITSTATE *)EDIT_HeapAddr(hwnd, (HANDLE)(*(wndPtr->wExtra))); - while (*CurrChar && *CurrChar != '\n') + while (*CurrChar && *CurrChar != '\r') { es->WndCol += EDIT_CharWidth(hwnd, (BYTE)(*CurrChar), es->WndCol + es->wleft); es->CurrCol++; @@ -2557,7 +2582,7 @@ void EDIT_ExtendSel(HWND hwnd, int x, int y) if (es->WndCol > EDIT_StrLength(hwnd, cp, len, 0) - es->wleft || end) es->WndCol = EDIT_StrLength(hwnd, cp, len, 0) - es->wleft; es->CurrCol = EDIT_PixelToChar(hwnd, es->CurrLine, &(es->WndCol)); - es->SelEndCol = es->CurrCol - 1; + es->SelEndCol = es->CurrCol; bel = es->SelEndLine; bec = es->SelEndCol; @@ -2622,10 +2647,15 @@ void EDIT_WriteSel(HWND hwnd, int y, int start, int end) if (end == -1) end = EDIT_LineLength(hwnd, y); + /* For some reason Rectangle, when called with R2_XORPEN filling, + * appears to leave a 2 pixel gap between characters and between + * lines. I have kludged this by adding on two pixels to ecol and + * to the line height in the call to Rectangle. + */ scol = EDIT_StrLength(hwnd, cp, start, 0); if (scol > rc.right) return; if (scol < rc.left) scol = rc.left; - ecol = EDIT_StrLength(hwnd, cp, end, 0); + ecol = EDIT_StrLength(hwnd, cp, end, 0) + 2; /* ??? */ if (ecol < rc.left) return; if (ecol > rc.right) ecol = rc.right; @@ -2633,7 +2663,7 @@ void EDIT_WriteSel(HWND hwnd, int y, int start, int end) hbrush = GetStockObject(BLACK_BRUSH); holdbrush = (HBRUSH)SelectObject(hdc, (HANDLE)hbrush); olddm = SetROP2(hdc, R2_XORPEN); - Rectangle(hdc, scol, y * es->txtht, ecol, (y + 1) * es->txtht); + Rectangle(hdc, scol, y * es->txtht, ecol, (y + 1) * es->txtht + 2); SetROP2(hdc, olddm); SelectObject(hdc, (HANDLE)holdbrush); ReleaseDC(hwnd, hdc); @@ -3054,7 +3084,7 @@ void EDIT_SetHandleMsg(HWND hwnd, WORD wParam) if (IsMultiLine()) { es->hText = wParam; - es->MaxTextLen = EDIT_HeapSize(hwnd, es->hText); + es->textlen = EDIT_HeapSize(hwnd, es->hText); es->wlines = 0; es->wtop = es->wleft = 0; es->CurrLine = es->CurrCol = 0; @@ -3063,7 +3093,10 @@ void EDIT_SetHandleMsg(HWND hwnd, WORD wParam) es->textwidth = 0; es->SelBegLine = es->SelBegCol = 0; es->SelEndLine = es->SelEndCol = 0; + dprintf_edit(stddeb, "EDIT_SetHandleMsg: textlen=%d\n", + es->textlen); + EDIT_BuildTextPointers(hwnd); es->PaintBkgd = TRUE; InvalidateRect(hwnd, NULL, TRUE); UpdateWindow(hwnd); diff --git a/controls/scroll.c b/controls/scroll.c index 03de3c857da..e335ade3197 100644 --- a/controls/scroll.c +++ b/controls/scroll.c @@ -896,8 +896,6 @@ void ShowScrollBar( HWND hwnd, WORD wBar, BOOL fShow ) } SetWindowPos( hwnd, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED ); - /* FIXME: Hack until SetWindowPos works correctly */ - InvalidateRect( hwnd, NULL, TRUE ); } diff --git a/if1632/user.spec b/if1632/user.spec index 87b6510a6c7..ac57b7bc767 100644 --- a/if1632/user.spec +++ b/if1632/user.spec @@ -320,7 +320,7 @@ length 540 #323 GETMESSAGE2 324 pascal FillWindow(word word word word) FillWindow(1 2 3 4) 325 pascal PaintRect(word word word word ptr) PaintRect(1 2 3 4 5) -#326 GETCONTROLBRUSH +326 pascal16 GetControlBrush(word word word) GetControlBrush(1 2 3) 331 pascal EnableHardwareInput(word) EnableHardwareInput(1) 332 return UserYield 0 0 #333 ISUSERIDLE diff --git a/include/nonclient.h b/include/nonclient.h index 0e8c665acba..0a34d9085c5 100644 --- a/include/nonclient.h +++ b/include/nonclient.h @@ -10,6 +10,8 @@ #include "windows.h" extern void NC_GetInsideRect( HWND hwnd, RECT *rect ); +extern void NC_GetMinMaxInfo( HWND hwnd, POINT *maxSize, POINT *maxPos, + POINT *minTrack, POINT *maxTrack ); extern void NC_DoNCPaint( HWND hwnd, BOOL active, BOOL suppress_menupaint ); extern LONG NC_HandleNCPaint( HWND hwnd ); extern LONG NC_HandleNCActivate( HWND hwnd, WORD wParam ); diff --git a/include/win.h b/include/win.h index 0ffedbf0f6c..c33e72269cc 100644 --- a/include/win.h +++ b/include/win.h @@ -48,7 +48,6 @@ typedef struct tagWND HANDLE hText; /* Handle of window text */ WORD flags; /* Misc. flags (see below) */ Window window; /* X window (only for top-level windows) */ - RECT rectClientSave; /* where client rect is saved when icon*/ HMENU hSysMenu; /* window's copy of System Menu */ HANDLE hProp; /* Handle of Properties List */ HTASK hTask; /* Task Handle of the owner */ diff --git a/include/windows.h b/include/windows.h index 65ebf083d6a..0c4c17e5350 100644 --- a/include/windows.h +++ b/include/windows.h @@ -2711,6 +2711,7 @@ Fc(HANDLE,FindResource,HANDLE,a,LPSTR,b,LPSTR,c) Fc(HANDLE,LocalReAlloc,HANDLE,a,WORD,b,WORD,c) Fc(HBITMAP,CreateCompatibleBitmap,HDC,a,short,b,short,c) Fc(HBITMAP,CreateDiscardableBitmap,HDC,a,short,b,short,c) +Fc(HBRUSH,GetControlBrush,HWND,a,HDC,b,WORD,c) Fc(HDC,GetDCEx,HWND,a,HRGN,b,DWORD,c) Fc(HPALETTE,SelectPalette,HDC,a,HPALETTE,b,BOOL,c) Fc(HPEN,CreatePen,short,a,short,b,COLORREF,c) diff --git a/include/winpos.h b/include/winpos.h index 1df7d571955..19ca5c74d29 100644 --- a/include/winpos.h +++ b/include/winpos.h @@ -22,8 +22,6 @@ typedef struct extern HWND WINPOS_NextWindowFromPoint( HWND hwnd, POINT pt ); extern HWND WINPOS_ChangeActiveWindow( HWND hwnd, BOOL mouseMsg ); -extern void WINPOS_GetMinMaxInfo( HWND hwnd, POINT *maxSize, POINT *maxPos, - POINT *minTrack, POINT *maxTrack ); extern LONG WINPOS_SendNCCalcSize( HWND hwnd, BOOL calcValidRect, RECT *newWindowRect, RECT *oldWindowRect, RECT *oldClientRect, WINDOWPOS *winpos, diff --git a/loader/library.c b/loader/library.c index 6d7e9736860..ef7bd18738e 100644 --- a/loader/library.c +++ b/loader/library.c @@ -203,7 +203,8 @@ HINSTANCE LoadImage(char *module, int filetype, int change_dir) if (read(wpnt->fd, wpnt->mz_header, sizeof(struct mz_header_s)) != sizeof(struct mz_header_s)) { - myerror("Unable to read MZ header from file"); + fprintf(stderr, "Unable to read MZ header from file '%s'\n", buffer); + exit(1); } /* This field is ignored according to "Windows Internals", p.242 */ diff --git a/misc/network.c b/misc/network.c index 7ccc9013bbc..b662d996801 100644 --- a/misc/network.c +++ b/misc/network.c @@ -4,7 +4,6 @@ #include "stdio.h" #include "windows.h" -#include "win.h" #include "user.h" #define WN_SUCCESS 0x0000 diff --git a/misc/shell.c b/misc/shell.c index 97a9653a287..c4c4a46708a 100644 --- a/misc/shell.c +++ b/misc/shell.c @@ -14,60 +14,88 @@ /* #define DEBUG_REG */ #include "debug.h" -LPKEYSTRUCT lphRootKey = NULL; +LPKEYSTRUCT lphRootKey = NULL,lphTopKey = NULL; + +static char RootKeyName[]=".classes", TopKeyName[] = "(null)"; + +/************************************************************************* + * SHELL_RegCheckForRoot() internal use only + */ +static LONG SHELL_RegCheckForRoot() +{ + HKEY hNewKey; + + if (lphRootKey == NULL){ + hNewKey = GlobalAlloc(GMEM_MOVEABLE,sizeof(KEYSTRUCT)); + lphRootKey = (LPKEYSTRUCT) GlobalLock(hNewKey); + if (lphRootKey == NULL) { + printf("SHELL_RegCheckForRoot: Couldn't allocate root key!\n"); + return ERROR_OUTOFMEMORY; + } + lphRootKey->hKey = 1; + lphRootKey->lpSubKey = RootKeyName; + lphRootKey->dwType = 0; + lphRootKey->lpValue = NULL; + lphRootKey->lpSubLvl = lphRootKey->lpNextKey = lphRootKey->lpPrevKey = NULL; + + hNewKey = GlobalAlloc(GMEM_MOVEABLE,sizeof(KEYSTRUCT)); + lphTopKey = (LPKEYSTRUCT) GlobalLock(hNewKey); + if (lphTopKey == NULL) { + printf("SHELL_RegCheckForRoot: Couldn't allocate top key!\n"); + return ERROR_OUTOFMEMORY; + } + lphTopKey->hKey = 0; + lphTopKey->lpSubKey = TopKeyName; + lphTopKey->dwType = 0; + lphTopKey->lpValue = NULL; + lphTopKey->lpSubLvl = lphRootKey; lphTopKey->lpNextKey = lphTopKey->lpPrevKey = NULL; + + dprintf_reg(stddeb,"SHELL_RegCheckForRoot: Root/Top created\n"); + } + return ERROR_SUCCESS; +} /************************************************************************* * RegOpenKey [SHELL.1] */ LONG RegOpenKey(HKEY hKey, LPCSTR lpSubKey, HKEY FAR *lphKey) { - LPKEYSTRUCT lpKey = lphRootKey; - LPSTR ptr; + LPKEYSTRUCT lpKey; + LPCSTR ptr; char str[128]; + LONG dwRet; + dwRet = SHELL_RegCheckForRoot(); + if (dwRet != ERROR_SUCCESS) return dwRet; dprintf_reg(stddeb, "RegOpenKey(%08lX, %p='%s', %p)\n", hKey, lpSubKey, lpSubKey, lphKey); - if (lpKey == NULL) return ERROR_BADKEY; if (lpSubKey == NULL) return ERROR_INVALID_PARAMETER; if (lphKey == NULL) return ERROR_INVALID_PARAMETER; - if (hKey != HKEY_CLASSES_ROOT) { - dprintf_reg(stddeb,"RegOpenKey // specific key = %08lX !\n", hKey); - lpKey = (LPKEYSTRUCT)GlobalLock(hKey); - } - while ( (ptr = strchr(lpSubKey, '\\')) != NULL ) { - strncpy(str, lpSubKey, (LONG)ptr - (LONG)lpSubKey); - str[(LONG)ptr - (LONG)lpSubKey] = '\0'; - lpSubKey = ptr + 1; - dprintf_reg(stddeb,"RegOpenKey // next level '%s' !\n", str); - while(TRUE) { - dprintf_reg(stddeb,"RegOpenKey // '%s' <-> '%s' !\n", str, lpKey->lpSubKey); - if (lpKey->lpSubKey != NULL && lpKey->lpSubKey[0] != '\0' && - strcmp(lpKey->lpSubKey, str) == 0) { - lpKey = lpKey->lpSubLvl; - if (lpKey == NULL) { - printf("RegOpenKey // can't find subkey '%s' !\n", str); - return ERROR_BADKEY; - } - break; - } - if (lpKey->lpNextKey == NULL) { - printf("RegOpenKey // can't find subkey '%s' !\n", str); - return ERROR_BADKEY; - } - lpKey = lpKey->lpNextKey; - } - } - while(TRUE) { - if (lpKey->lpSubKey != NULL && - strcmp(lpKey->lpSubKey, lpSubKey) == 0) break; - if (lpKey->lpNextKey == NULL) { - printf("RegOpenKey // can't find subkey '%s' !\n", str); - return ERROR_BADKEY; - } - lpKey = lpKey->lpNextKey; - } - *lphKey = lpKey->hKey; - dprintf_reg(stddeb,"RegOpenKey // return hKey=%08lX !\n", lpKey->hKey); + switch(hKey) { + case 0: + lpKey = lphTopKey; break; + case HKEY_CLASSES_ROOT: /* == 1 */ + lpKey = lphRootKey; break; + default: + dprintf_reg(stddeb,"RegOpenKey // specific key = %08lX !\n", hKey); + lpKey = (LPKEYSTRUCT)GlobalLock(hKey); + } + while(*lpSubKey) { + ptr = strchr(lpSubKey,'\\'); + if (!ptr) ptr = lpSubKey + strlen(lpSubKey); + strncpy(str,lpSubKey,ptr-lpSubKey); + str[ptr-lpSubKey] = 0; + lpSubKey = ptr; + if (*lpSubKey) lpSubKey++; + + lpKey = lpKey->lpSubLvl; + while(lpKey != NULL && strcmp(lpKey->lpSubKey, str) != 0) { lpKey = lpKey->lpNextKey; } + if (lpKey == NULL) { + dprintf_reg(stddeb,"RegOpenKey: key %s not found!\n",str); + return ERROR_BADKEY; + } + } + *lphKey = lpKey->hKey; return ERROR_SUCCESS; } @@ -79,86 +107,69 @@ LONG RegCreateKey(HKEY hKey, LPCSTR lpSubKey, HKEY FAR *lphKey) { HKEY hNewKey; LPKEYSTRUCT lpNewKey; - LPKEYSTRUCT lpKey = lphRootKey; + LPKEYSTRUCT lpKey; LPKEYSTRUCT lpPrevKey; LONG dwRet; - LPSTR ptr; + LPCSTR ptr; char str[128]; + + dwRet = SHELL_RegCheckForRoot(); + if (dwRet != ERROR_SUCCESS) return dwRet; dprintf_reg(stddeb, "RegCreateKey(%08lX, '%s', %p)\n", hKey, lpSubKey, lphKey); if (lpSubKey == NULL) return ERROR_INVALID_PARAMETER; if (lphKey == NULL) return ERROR_INVALID_PARAMETER; - if (hKey != HKEY_CLASSES_ROOT) { - dprintf_reg(stddeb,"RegCreateKey // specific key = %08lX !\n", hKey); - lpKey = (LPKEYSTRUCT)GlobalLock(hKey); - } - while ( (ptr = strchr(lpSubKey, '\\')) != NULL ) { - strncpy(str, lpSubKey, (LONG)ptr - (LONG)lpSubKey); - str[(LONG)ptr - (LONG)lpSubKey] = '\0'; - lpSubKey = ptr + 1; - dprintf_reg(stddeb,"RegCreateKey // next level '%s' !\n", str); - lpPrevKey = lpKey; - while(TRUE) { - dprintf_reg(stddeb,"RegCreateKey // '%s' <-> '%s' !\n", str, lpKey->lpSubKey); - if (lpKey->lpSubKey != NULL && - strcmp(lpKey->lpSubKey, str) == 0) { - if (lpKey->lpSubLvl == NULL) { - dprintf_reg(stddeb,"RegCreateKey // '%s' found !\n", str); - if ( (ptr = strchr(lpSubKey, '\\')) != NULL ) { - strncpy(str, lpSubKey, (LONG)ptr - (LONG)lpSubKey); - str[(LONG)ptr - (LONG)lpSubKey] = '\0'; - lpSubKey = ptr + 1; - } - else - strcpy(str, lpSubKey); - dwRet = RegCreateKey(lpKey->hKey, str, &hNewKey); - if (dwRet != ERROR_SUCCESS) { - printf("RegCreateKey // can't create subkey '%s' !\n", str); - return dwRet; - } - lpKey->lpSubLvl = (LPKEYSTRUCT)GlobalLock(hNewKey); - } - lpKey = lpKey->lpSubLvl; - break; - } - if (lpKey->lpNextKey == NULL) { - dwRet = RegCreateKey(lpPrevKey->hKey, str, &hNewKey); - if (dwRet != ERROR_SUCCESS) { - printf("RegCreateKey // can't create subkey '%s' !\n", str); - return dwRet; - } - lpKey = (LPKEYSTRUCT)GlobalLock(hNewKey); - break; - } - lpKey = lpKey->lpNextKey; - } - } - hNewKey = GlobalAlloc(GMEM_MOVEABLE, sizeof(KEYSTRUCT)); - lpNewKey = (LPKEYSTRUCT) GlobalLock(hNewKey); - if (lpNewKey == NULL) { - printf("RegCreateKey // Can't alloc new key !\n"); - return ERROR_OUTOFMEMORY; - } - if (lphRootKey == NULL) { - lphRootKey = lpNewKey; - lpNewKey->lpPrevKey = NULL; - } - else { - lpKey->lpNextKey = lpNewKey; - lpNewKey->lpPrevKey = lpKey; - } - lpNewKey->hKey = hNewKey; - lpNewKey->lpSubKey = malloc(strlen(lpSubKey) + 1); - if (lpNewKey->lpSubKey == NULL) { - printf("RegCreateKey // Can't alloc key string !\n"); - return ERROR_OUTOFMEMORY; - } - strcpy(lpNewKey->lpSubKey, lpSubKey); - lpNewKey->dwType = 0; - lpNewKey->lpValue = NULL; - lpNewKey->lpNextKey = NULL; - lpNewKey->lpSubLvl = NULL; - *lphKey = hNewKey; - dprintf_reg(stddeb,"RegCreateKey // successful '%s' key=%08lX !\n", lpSubKey, hNewKey); + switch(hKey) { + case 0: + lpKey = lphTopKey; break; + case HKEY_CLASSES_ROOT: /* == 1 */ + lpKey = lphRootKey; break; + default: + dprintf_reg(stddeb,"RegCreateKey // specific key = %08lX !\n", hKey); + lpKey = (LPKEYSTRUCT)GlobalLock(hKey); + } + while (*lpSubKey) { + dprintf_reg(stddeb, "RegCreateKey: Looking for subkey %s\n", lpSubKey); + ptr = strchr(lpSubKey,'\\'); + if (!ptr) ptr = lpSubKey + strlen(lpSubKey); + strncpy(str,lpSubKey,ptr-lpSubKey); + str[ptr-lpSubKey] = 0; + lpSubKey = ptr; + if (*lpSubKey) lpSubKey++; + + lpPrevKey = lpKey; + lpKey = lpKey->lpSubLvl; + while(lpKey != NULL && strcmp(lpKey->lpSubKey, str) != 0) { + lpKey = lpKey->lpNextKey; + } + if (lpKey == NULL) { + hNewKey = GlobalAlloc(GMEM_MOVEABLE, sizeof(KEYSTRUCT)); + lpNewKey = (LPKEYSTRUCT) GlobalLock(hNewKey); + if (lpNewKey == NULL) { + printf("RegCreateKey // Can't alloc new key !\n"); + return ERROR_OUTOFMEMORY; + } + lpNewKey->hKey = hNewKey; + lpNewKey->lpSubKey = malloc(strlen(str) + 1); + if (lpNewKey->lpSubKey == NULL) { + printf("RegCreateKey // Can't alloc key string !\n"); + return ERROR_OUTOFMEMORY; + } + strcpy(lpNewKey->lpSubKey, str); + lpNewKey->lpNextKey = lpPrevKey->lpSubLvl; + lpNewKey->lpPrevKey = NULL; + lpPrevKey->lpSubLvl = lpNewKey; + + lpNewKey->dwType = 0; + lpNewKey->lpValue = NULL; + lpNewKey->lpSubLvl = NULL; + *lphKey = hNewKey; + dprintf_reg(stddeb,"RegCreateKey // successful '%s' key=%08lX !\n", str, hNewKey); + lpKey = lpNewKey; + } else { + *lphKey = lpKey->hKey; + dprintf_reg(stddeb,"RegCreateKey // found '%s', key=%08lX\n", str, *lphKey); + } + } return ERROR_SUCCESS; } @@ -198,7 +209,7 @@ LONG RegSetValue(HKEY hKey, LPCSTR lpSubKey, DWORD dwType, if (lpSubKey == NULL) return ERROR_INVALID_PARAMETER; if (lpVal == NULL) return ERROR_INVALID_PARAMETER; if ((dwRet = RegOpenKey(hKey, lpSubKey, &hRetKey)) != ERROR_SUCCESS) { - dprintf_reg(stddeb, "RegSetValue // key not found ... so create it !\n"); + dprintf_reg(stddeb, "RegSetValue // key not found ... so create it !\n"); if ((dwRet = RegCreateKey(hKey, lpSubKey, &hRetKey)) != ERROR_SUCCESS) { fprintf(stderr, "RegSetValue // key creation error %08lX !\n", dwRet); return dwRet; @@ -209,7 +220,7 @@ LONG RegSetValue(HKEY hKey, LPCSTR lpSubKey, DWORD dwType, if (lpKey->lpValue != NULL) free(lpKey->lpValue); lpKey->lpValue = malloc(strlen(lpVal) + 1); strcpy(lpKey->lpValue, lpVal); - dprintf_reg(stddeb,"RegSetValue // successful key='%s' val='%s' !\n", lpSubKey, lpVal); + dprintf_reg(stddeb,"RegSetValue // successful key='%s' val='%s' !\n", lpSubKey, lpKey->lpValue); return ERROR_SUCCESS; } @@ -228,6 +239,8 @@ LONG RegQueryValue(HKEY hKey, LPCSTR lpSubKey, LPSTR lpVal, LONG FAR *lpcb) if (lpSubKey == NULL) return ERROR_INVALID_PARAMETER; if (lpVal == NULL) return ERROR_INVALID_PARAMETER; if (lpcb == NULL) return ERROR_INVALID_PARAMETER; + if (!*lpcb) return ERROR_INVALID_PARAMETER; + if ((dwRet = RegOpenKey(hKey, lpSubKey, &hRetKey)) != ERROR_SUCCESS) { fprintf(stderr, "RegQueryValue // key not found !\n"); return dwRet; @@ -235,14 +248,17 @@ LONG RegQueryValue(HKEY hKey, LPCSTR lpSubKey, LPSTR lpVal, LONG FAR *lpcb) lpKey = (LPKEYSTRUCT)GlobalLock(hRetKey); if (lpKey == NULL) return ERROR_BADKEY; if (lpKey->lpValue != NULL) { - size = min(strlen(lpKey->lpValue), *lpcb); - strncpy(lpVal, lpKey->lpValue, size); - *lpcb = (LONG)size; - } - else { - lpVal[0] = '\0'; - *lpcb = (LONG)0; - } + if ((size = strlen(lpKey->lpValue)+1) > *lpcb){ + strncpy(lpVal,lpKey->lpValue,*lpcb-1); + lpVal[*lpcb-1] = 0; + } else { + strcpy(lpVal,lpKey->lpValue); + *lpcb = size; + } + } else { + *lpVal = 0; + *lpcb = (LONG)1; + } dprintf_reg(stddeb,"RegQueryValue // return '%s' !\n", lpVal); return ERROR_SUCCESS; } @@ -253,7 +269,37 @@ LONG RegQueryValue(HKEY hKey, LPCSTR lpSubKey, LPSTR lpVal, LONG FAR *lpcb) */ LONG RegEnumKey(HKEY hKey, DWORD dwSubKey, LPSTR lpBuf, DWORD dwSize) { - dprintf_reg(stdnimp, "RegEnumKey : Empty Stub !!!\n"); + LPKEYSTRUCT lpKey; + LONG dwRet; + LONG len; + + dwRet = SHELL_RegCheckForRoot(); + if (dwRet != ERROR_SUCCESS) return dwRet; + dprintf_reg(stddeb, "RegEnumKey(%08lX, %ld)\n", hKey, dwSubKey); + if (lpBuf == NULL) return ERROR_INVALID_PARAMETER; + switch(hKey) { + case 0: + lpKey = lphTopKey; break; + case HKEY_CLASSES_ROOT: /* == 1 */ + lpKey = lphRootKey; break; + default: + dprintf_reg(stddeb,"RegEnumKey // specific key = %08lX !\n", hKey); + lpKey = (LPKEYSTRUCT)GlobalLock(hKey); + } + + lpKey = lpKey->lpSubLvl; + while(lpKey != NULL){ + if (!dwSubKey){ + len = min(dwSize-1,strlen(lpKey->lpSubKey)); + strncpy(lpBuf,lpKey->lpSubKey,len); + lpBuf[len] = 0; + dprintf_reg(stddeb, "RegEnumKey: found %s\n",lpBuf); + return ERROR_SUCCESS; + } + dwSubKey--; + lpKey = lpKey->lpNextKey; + } + dprintf_reg(stddeb, "RegEnumKey: key not found!\n"); return ERROR_INVALID_PARAMETER; } @@ -340,7 +386,9 @@ INT ShellAbout(HWND hWnd, LPCSTR szApp, LPCSTR szOtherStuff, HICON hIcon) else *AppMisc = 0; - return DialogBoxIndirectPtr(hSysRes, sysres_DIALOG_SHELL_ABOUT_MSGBOX, hWnd, (WNDPROC)AboutDlgProc); + return DialogBoxIndirectPtr( GetWindowWord(hWnd, GWW_HINSTANCE), + sysres_DIALOG_SHELL_ABOUT_MSGBOX, + hWnd, (WNDPROC)AboutDlgProc); } diff --git a/rc/Imakefile b/rc/Imakefile index 36decda65ca..9e89e0c24fa 100644 --- a/rc/Imakefile +++ b/rc/Imakefile @@ -23,6 +23,7 @@ WineRelocatableTarget($(MODULE),,$(RCOBJS)) $(RCOBJS): winerc $(TOP)/include/windows.h includes:: + touch $(RCSRCS:.rc=.h) clean:: $(RM) $(RCSRCS:.rc=.c) $(RCSRCS:.rc=.h) diff --git a/tools/build.c b/tools/build.c index 9a4bce6f61e..c2ea2f2aafc 100644 --- a/tools/build.c +++ b/tools/build.c @@ -757,8 +757,10 @@ int main(int argc, char **argv) sprintf(filename, "dll_%s.S", LowerDLLName); fp = fopen(filename, "w"); +#ifdef __ELF__ fprintf (fp, "#define __ASSEMBLY__\n"); fprintf (fp, "#include <asm/segment.h>\n"); +#endif fprintf(fp, "\t.globl " PREFIX "%s_Dispatch\n", UpperDLLName); fprintf(fp, PREFIX "%s_Dispatch:\n", UpperDLLName); fprintf(fp, "\tandl\t$0x0000ffff,%%esp\n"); diff --git a/windows/cursor.c b/windows/cursor.c index 7c98f92114f..911637e39bd 100644 --- a/windows/cursor.c +++ b/windows/cursor.c @@ -82,7 +82,6 @@ HCURSOR LoadCursor(HANDLE instance, LPSTR cursor_name) lpcur = (CURSORALLOC *)GlobalLock(hCursor); memset(lpcur, 0, sizeof(CURSORALLOC)); if (instance == (HANDLE)NULL) { - instance = hSysRes; switch((LONG)cursor_name) { case IDC_ARROW: lpcur->xcursor = XCreateFontCursor(display, XC_top_left_arrow); diff --git a/windows/mdi.c b/windows/mdi.c index ee6f5759f52..f59d50146b0 100644 --- a/windows/mdi.c +++ b/windows/mdi.c @@ -283,23 +283,13 @@ LONG MDIMaximizeChild(HWND parent, HWND child, MDICLIENTINFO *ci) LONG MDIRestoreChild(HWND parent, MDICLIENTINFO *ci) { HWND child; - WND *w = WIN_FindWndPtr(parent); - LPRECT lprect = &ci->rectRestore; dprintf_mdi(stddeb,"restoring mdi child\n"); child = ci->hwndActiveChild; - - w->dwStyle &= ~WS_MAXIMIZE; - SetWindowPos(child, 0, lprect->left, lprect->top, - lprect->right - lprect->left + 1, - lprect->bottom - lprect->top + 1, - SWP_NOACTIVATE | SWP_NOZORDER); - ci->flagChildMaximized = FALSE; ShowWindow(child, SW_RESTORE); /* display the window */ - SendMessage(GetParent(parent), WM_NCPAINT, 0, 0); MDIBringChildToTop(parent, child, FALSE, FALSE); return 0; diff --git a/windows/nonclient.c b/windows/nonclient.c index 6d0903f988c..6f586a4f994 100644 --- a/windows/nonclient.c +++ b/windows/nonclient.c @@ -110,6 +110,82 @@ void AdjustWindowRectEx( LPRECT rect, DWORD style, BOOL menu, DWORD exStyle ) } +/******************************************************************* + * NC_GetMinMaxInfo + * + * Get the minimized and maximized information for a window. + */ +void NC_GetMinMaxInfo( HWND hwnd, POINT *maxSize, POINT *maxPos, + POINT *minTrack, POINT *maxTrack ) +{ + HANDLE minmaxHandle; + MINMAXINFO MinMax, *pMinMax; + short xinc, yinc; + WND *wndPtr = WIN_FindWndPtr( hwnd ); + + /* Compute default values */ + + MinMax.ptMaxSize.x = SYSMETRICS_CXSCREEN; + MinMax.ptMaxSize.y = SYSMETRICS_CYSCREEN; + MinMax.ptMinTrackSize.x = SYSMETRICS_CXMINTRACK; + MinMax.ptMinTrackSize.y = SYSMETRICS_CYMINTRACK; + MinMax.ptMaxTrackSize.x = SYSMETRICS_CXSCREEN; + MinMax.ptMaxTrackSize.y = SYSMETRICS_CYSCREEN; + + if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle )) + { + xinc = SYSMETRICS_CXDLGFRAME; + yinc = SYSMETRICS_CYDLGFRAME; + } + else + { + xinc = yinc = 0; + if (HAS_THICKFRAME(wndPtr->dwStyle)) + { + xinc += SYSMETRICS_CXFRAME; + yinc += SYSMETRICS_CYFRAME; + } + if (wndPtr->dwStyle & WS_BORDER) + { + xinc += SYSMETRICS_CXBORDER; + yinc += SYSMETRICS_CYBORDER; + } + } + MinMax.ptMaxSize.x += 2 * xinc; + MinMax.ptMaxSize.y += 2 * yinc; + + if ((wndPtr->ptMaxPos.x != -1) || (wndPtr->ptMaxPos.y != -1)) + MinMax.ptMaxPosition = wndPtr->ptMaxPos; + else + { + MinMax.ptMaxPosition.x = -xinc; + MinMax.ptMaxPosition.y = -yinc; + } + + minmaxHandle = USER_HEAP_ALLOC( LMEM_MOVEABLE, sizeof(MINMAXINFO) ); + if (minmaxHandle) + { + pMinMax = (MINMAXINFO *) USER_HEAP_ADDR( minmaxHandle ); + memcpy( pMinMax, &MinMax, sizeof(MinMax) ); + SendMessage( hwnd, WM_GETMINMAXINFO, 0, (LONG)pMinMax ); + } + else pMinMax = &MinMax; + + /* Some sanity checks */ + + pMinMax->ptMaxTrackSize.x = max( pMinMax->ptMaxTrackSize.x, + pMinMax->ptMinTrackSize.x ); + pMinMax->ptMaxTrackSize.y = max( pMinMax->ptMaxTrackSize.y, + pMinMax->ptMinTrackSize.y ); + + if (maxSize) *maxSize = pMinMax->ptMaxSize; + if (maxPos) *maxPos = pMinMax->ptMaxPosition; + if (minTrack) *minTrack = pMinMax->ptMinTrackSize; + if (maxTrack) *maxTrack = pMinMax->ptMaxTrackSize; + if (minmaxHandle) USER_HEAP_FREE( minmaxHandle ); +} + + /*********************************************************************** * NC_HandleNCCalcSize * @@ -841,7 +917,7 @@ static void NC_DoSizeMove( HWND hwnd, WORD wParam, POINT pt ) /* Get min/max info */ - WINPOS_GetMinMaxInfo( hwnd, NULL, NULL, &minTrack, &maxTrack ); + NC_GetMinMaxInfo( hwnd, NULL, NULL, &minTrack, &maxTrack ); sizingRect = wndPtr->rectWindow; if (wndPtr->dwStyle & WS_CHILD) GetClientRect( wndPtr->hwndParent, &mouseRect ); @@ -1162,7 +1238,8 @@ LONG NC_HandleNCLButtonDblClk( HWND hwnd, WORD wParam, LONG lParam ) switch(wParam) /* Hit test */ { case HTCAPTION: - SendMessage( hwnd, WM_SYSCOMMAND, SC_MAXIMIZE, lParam ); + SendMessage( hwnd, WM_SYSCOMMAND, + IsZoomed(hwnd) ? SC_RESTORE : SC_MAXIMIZE, lParam ); break; case HTSYSMENU: @@ -1239,7 +1316,7 @@ LONG NC_HandleSysCommand( HWND hwnd, WORD wParam, POINT pt ) case SC_SCREENSAVE: if (wParam == SC_ABOUTWINE) { extern char sysres_DIALOG_2[]; - DialogBoxIndirectPtr( hSysRes, sysres_DIALOG_2, + DialogBoxIndirectPtr( wndPtr->hInstance, sysres_DIALOG_2, hwnd, (WNDPROC)AboutWine_Proc ); } break; diff --git a/windows/painting.c b/windows/painting.c index e44110bd070..782626c07a2 100644 --- a/windows/painting.c +++ b/windows/painting.c @@ -1,7 +1,7 @@ /* * Window painting functions * - * Copyright 1993 Alexandre Julliard + * Copyright 1993, 1994, 1995 Alexandre Julliard */ #include <stdio.h> @@ -103,13 +103,23 @@ void PaintRect(HWND hwndParent, HWND hwnd, HDC hdc, HBRUSH hbrush, LPRECT rect) } +/*********************************************************************** + * GetControlBrush (USER.326) + */ +HBRUSH GetControlBrush( HWND hwnd, HDC hdc, WORD control ) +{ + return (HBRUSH)SendMessage( GetParent(hwnd), WM_CTLCOLOR, + hdc, MAKELONG( hwnd, control ) ); +} + + /*********************************************************************** * RedrawWindow (USER.290) */ BOOL RedrawWindow( HWND hwnd, LPRECT rectUpdate, HRGN hrgnUpdate, UINT flags ) { - HRGN tmpRgn, hrgn = 0; - RECT rectClient, rectWindow; + HRGN tmpRgn, hrgn; + RECT rectClient; WND * wndPtr; if (!hwnd) hwnd = GetDesktopWindow(); @@ -129,111 +139,68 @@ BOOL RedrawWindow( HWND hwnd, LPRECT rectUpdate, HRGN hrgnUpdate, UINT flags ) hwnd, hrgnUpdate, flags); } GetClientRect( hwnd, &rectClient ); - rectWindow = wndPtr->rectWindow; - OffsetRect(&rectWindow, -wndPtr->rectClient.left, -wndPtr->rectClient.top); if (flags & RDW_INVALIDATE) /* Invalidate */ { - if (hrgnUpdate) /* Invalidate a region */ - { - if (flags & RDW_FRAME) tmpRgn = CreateRectRgnIndirect(&rectWindow); - else tmpRgn = CreateRectRgnIndirect( &rectClient ); - if (!tmpRgn) return FALSE; - hrgn = CreateRectRgn( 0, 0, 0, 0 ); - if (CombineRgn( hrgn, hrgnUpdate, tmpRgn, RGN_AND ) == NULLREGION) - { - DeleteObject( hrgn ); - hrgn = 0; - } - DeleteObject( tmpRgn ); - } - else /* Invalidate a rectangle */ - { - RECT rect; - if (flags & RDW_FRAME) - { - if (rectUpdate) IntersectRect( &rect, rectUpdate, &rectWindow); - else rect = rectWindow; - } - else - { - if (rectUpdate) IntersectRect( &rect, rectUpdate, &rectClient); - else rect = rectClient; - } - if (!IsRectEmpty(&rect)) hrgn = CreateRectRgnIndirect( &rect ); - } - - /* Set update region */ - - if (hrgn) - { - if (!wndPtr->hrgnUpdate) - { - wndPtr->hrgnUpdate = hrgn; - if (!(wndPtr->flags & WIN_INTERNAL_PAINT)) - MSG_IncPaintCount( wndPtr->hmemTaskQ ); - } - else - { - tmpRgn = CreateRectRgn( 0, 0, 0, 0 ); - CombineRgn( tmpRgn, wndPtr->hrgnUpdate, hrgn, RGN_OR ); - DeleteObject( wndPtr->hrgnUpdate ); - DeleteObject( hrgn ); - wndPtr->hrgnUpdate = tmpRgn; - } - } + if (wndPtr->hrgnUpdate) /* Is there already an update region? */ + { + tmpRgn = CreateRectRgn( 0, 0, 0, 0 ); + if ((hrgn = hrgnUpdate) == 0) + hrgn = CreateRectRgnIndirect( rectUpdate ? rectUpdate : + &rectClient ); + CombineRgn( tmpRgn, wndPtr->hrgnUpdate, hrgn, RGN_OR ); + DeleteObject( wndPtr->hrgnUpdate ); + wndPtr->hrgnUpdate = tmpRgn; + if (!hrgnUpdate) DeleteObject( hrgn ); + } + else /* No update region yet */ + { + if (!(wndPtr->flags & WIN_INTERNAL_PAINT)) + MSG_IncPaintCount( wndPtr->hmemTaskQ ); + if (hrgnUpdate) + { + wndPtr->hrgnUpdate = CreateRectRgn( 0, 0, 0, 0 ); + CombineRgn( wndPtr->hrgnUpdate, hrgnUpdate, 0, RGN_COPY ); + } + else wndPtr->hrgnUpdate = CreateRectRgnIndirect( rectUpdate ? + rectUpdate : &rectClient ); + } if (flags & RDW_FRAME) wndPtr->flags |= WIN_NEEDS_NCPAINT; if (flags & RDW_ERASE) wndPtr->flags |= WIN_NEEDS_ERASEBKGND; flags |= RDW_FRAME; /* Force invalidating the frame of children */ } else if (flags & RDW_VALIDATE) /* Validate */ { - if (flags & RDW_NOERASE) wndPtr->flags &= ~WIN_NEEDS_ERASEBKGND; - if (!(hrgn = CreateRectRgn( 0, 0, 0, 0 ))) return FALSE; - - /* Remove frame from update region */ - - if (wndPtr->hrgnUpdate && (flags & RDW_NOFRAME)) - { - if (!(tmpRgn = CreateRectRgnIndirect( &rectClient ))) - return FALSE; - if (CombineRgn(hrgn,tmpRgn,wndPtr->hrgnUpdate,RGN_AND) == NULLREGION) - { - DeleteObject( hrgn ); - hrgn = 0; - } - DeleteObject( tmpRgn ); - DeleteObject( wndPtr->hrgnUpdate ); - wndPtr->hrgnUpdate = hrgn; - hrgn = CreateRectRgn( 0, 0, 0, 0 ); - } - - /* Set update region */ - - if (wndPtr->hrgnUpdate) - { - int res; - if (hrgnUpdate) /* Validate a region */ - { - res = CombineRgn(hrgn,wndPtr->hrgnUpdate,hrgnUpdate,RGN_DIFF); - } - else /* Validate a rectangle */ - { - if (rectUpdate) tmpRgn = CreateRectRgnIndirect( rectUpdate ); - else tmpRgn = CreateRectRgnIndirect( &rectWindow ); - res = CombineRgn( hrgn, wndPtr->hrgnUpdate, tmpRgn, RGN_DIFF ); - DeleteObject( tmpRgn ); - } - DeleteObject( wndPtr->hrgnUpdate ); - if (res == NULLREGION) - { - DeleteObject( hrgn ); - wndPtr->hrgnUpdate = 0; + /* We need an update region in order to validate anything */ + if (wndPtr->hrgnUpdate) + { + if (!hrgnUpdate && !rectUpdate) + { + /* Special case: validate everything */ + DeleteObject( wndPtr->hrgnUpdate ); + wndPtr->hrgnUpdate = 0; + } + else + { + tmpRgn = CreateRectRgn( 0, 0, 0, 0 ); + if ((hrgn = hrgnUpdate) == 0) + hrgn = CreateRectRgnIndirect( rectUpdate ); + if (CombineRgn( tmpRgn, wndPtr->hrgnUpdate, + hrgn, RGN_DIFF ) == NULLREGION) + { + DeleteObject( tmpRgn ); + tmpRgn = 0; + } + DeleteObject( wndPtr->hrgnUpdate ); + wndPtr->hrgnUpdate = tmpRgn; + if (!hrgnUpdate) DeleteObject( hrgn ); + } + if (!wndPtr->hrgnUpdate) /* No more update region */ if (!(wndPtr->flags & WIN_INTERNAL_PAINT)) MSG_DecPaintCount( wndPtr->hmemTaskQ ); - } - else wndPtr->hrgnUpdate = hrgn; - } + } + if (flags & RDW_NOFRAME) wndPtr->flags &= ~WIN_NEEDS_NCPAINT; + if (flags & RDW_NOERASE) wndPtr->flags &= ~WIN_NEEDS_ERASEBKGND; } /* Set/clear internal paint flag */ @@ -393,7 +360,6 @@ BOOL GetUpdateRect( HWND hwnd, LPRECT rect, BOOL erase ) */ int GetUpdateRgn( HWND hwnd, HRGN hrgn, BOOL erase ) { - HRGN hrgnClip; int retval; WND * wndPtr = WIN_FindWndPtr( hwnd ); if (!wndPtr) return ERROR; @@ -403,13 +369,8 @@ int GetUpdateRgn( HWND hwnd, HRGN hrgn, BOOL erase ) SetRectRgn( hrgn, 0, 0, 0, 0 ); return NULLREGION; } - hrgnClip = CreateRectRgn( 0, 0, - wndPtr->rectClient.right-wndPtr->rectClient.left, - wndPtr->rectClient.bottom-wndPtr->rectClient.top); - if (!hrgnClip) return ERROR; - retval = CombineRgn( hrgn, wndPtr->hrgnUpdate, hrgnClip, RGN_AND ); + retval = CombineRgn( hrgn, wndPtr->hrgnUpdate, 0, RGN_COPY ); if (erase) RedrawWindow( hwnd, NULL, 0, RDW_ERASENOW | RDW_NOCHILDREN ); - DeleteObject( hrgnClip ); return retval; } diff --git a/windows/win.c b/windows/win.c index 809c333dd6a..5148b94203c 100644 --- a/windows/win.c +++ b/windows/win.c @@ -400,7 +400,7 @@ HWND CreateWindowEx( DWORD exStyle, LPSTR className, LPSTR windowName, /* Send the WM_GETMINMAXINFO message and fix the size if needed */ - WINPOS_GetMinMaxInfo( hwnd, &maxSize, &maxPos, &minTrack, &maxTrack ); + NC_GetMinMaxInfo( hwnd, &maxSize, &maxPos, &minTrack, &maxTrack ); if ( maxSize.x < width) { @@ -532,6 +532,21 @@ BOOL DestroyWindow( HWND hwnd ) ReleaseCapture(); WIN_SendParentNotify( hwnd, WM_DESTROY, MAKELONG(hwnd, wndPtr->wIDmenu) ); + /* Recursively destroy owned windows */ + + for (;;) + { + HWND hwndSibling = GetWindow( hwnd, GW_HWNDFIRST ); + while (hwndSibling) + { + WND *siblingPtr = WIN_FindWndPtr( hwndSibling ); + if (siblingPtr->hwndOwner == hwnd) break; + hwndSibling = siblingPtr->hwndNext; + } + if (hwndSibling) DestroyWindow( hwndSibling ); + else break; + } + /* Send destroy messages and destroy children */ SendMessage( hwnd, WM_DESTROY, 0, 0 ); @@ -560,7 +575,6 @@ void CloseWindow(HWND hWnd) } - /*********************************************************************** * OpenIcon (USER.44) */ @@ -572,7 +586,6 @@ BOOL OpenIcon(HWND hWnd) } - /*********************************************************************** * FindWindow (USER.50) */ diff --git a/windows/winpos.c b/windows/winpos.c index 6de8899110d..5f71349cf0d 100644 --- a/windows/winpos.c +++ b/windows/winpos.c @@ -1,7 +1,7 @@ /* * Window position related functions. * - * Copyright 1993, 1994 Alexandre Julliard + * Copyright 1993, 1994, 1995 Alexandre Julliard */ #include "sysmetrics.h" @@ -9,6 +9,7 @@ #include "win.h" #include "message.h" #include "winpos.h" +#include "nonclient.h" #include "stddebug.h" /* #define DEBUG_WIN */ #include "debug.h" @@ -16,6 +17,95 @@ static HWND hwndActive = 0; /* Currently active window */ +/*********************************************************************** + * WINPOS_FindIconPos + * + * Find a suitable place for an iconic window. + * The new position is stored into wndPtr->ptIconPos. + */ +static void WINPOS_FindIconPos( HWND hwnd ) +{ + RECT rectParent; + short x, y, xspacing, yspacing; + WND * wndPtr = WIN_FindWndPtr( hwnd ); + + if (!wndPtr) return; + GetClientRect( wndPtr->hwndParent, &rectParent ); + if ((wndPtr->ptIconPos.x >= rectParent.left) && + (wndPtr->ptIconPos.x + SYSMETRICS_CXICON < rectParent.right) && + (wndPtr->ptIconPos.y >= rectParent.top) && + (wndPtr->ptIconPos.y + SYSMETRICS_CYICON < rectParent.bottom)) + return; /* The icon already has a suitable position */ + + xspacing = yspacing = 70; /* FIXME: This should come from WIN.INI */ + y = rectParent.bottom; + for (;;) + { + for (x = rectParent.left; x<=rectParent.right-xspacing; x += xspacing) + { + /* Check if another icon already occupies this spot */ + HWND hwndChild = GetWindow( wndPtr->hwndParent, GW_CHILD ); + while (hwndChild) + { + WND *childPtr = WIN_FindWndPtr( hwndChild ); + if ((childPtr->dwStyle & WS_MINIMIZE) && (hwndChild != hwnd)) + { + if ((childPtr->rectWindow.left < x + xspacing) && + (childPtr->rectWindow.right >= x) && + (childPtr->rectWindow.top <= y) && + (childPtr->rectWindow.bottom > y - yspacing)) + break; /* There's a window in there */ + } + + hwndChild = childPtr->hwndNext; + } + if (!hwndChild) + { + /* No window was found, so it's OK for us */ + wndPtr->ptIconPos.x = x + (xspacing - SYSMETRICS_CXICON) / 2; + wndPtr->ptIconPos.y = y - (yspacing + SYSMETRICS_CYICON) / 2; + return; + } + } + y -= yspacing; + } +} + + +/*********************************************************************** + * ArrangeIconicWindows (USER.170) + */ +WORD ArrangeIconicWindows( HWND parent ) +{ + RECT rectParent; + HWND hwndChild; + short x, y, xspacing, yspacing; + + GetClientRect( parent, &rectParent ); + x = rectParent.left; + y = rectParent.bottom; + xspacing = yspacing = 70; /* FIXME: This should come from WIN.INI */ + hwndChild = GetWindow( parent, GW_CHILD ); + while (hwndChild) + { + if (IsIconic( hwndChild )) + { + SetWindowPos( hwndChild, 0, x + (xspacing - SYSMETRICS_CXICON) / 2, + y - (yspacing + SYSMETRICS_CYICON) / 2, 0, 0, + SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE ); + if (x <= rectParent.right - xspacing) x += xspacing; + else + { + x = rectParent.left; + y -= yspacing; + } + } + hwndChild = GetWindow( hwndChild, GW_HWNDNEXT ); + } + return yspacing; +} + + /*********************************************************************** * GetWindowRect (USER.32) */ @@ -99,6 +189,7 @@ HWND WindowFromPoint( POINT pt ) return hwndRet; } + /******************************************************************* * ChildWindowFromPoint (USER.191) */ @@ -187,6 +278,7 @@ HWND GetActiveWindow() return hwndActive; } + /******************************************************************* * SetActiveWindow (USER.59) */ @@ -229,84 +321,126 @@ BOOL ShowWindow( HWND hwnd, int cmd ) { WND * wndPtr = WIN_FindWndPtr( hwnd ); BOOL wasVisible; - BOOL wasIconic; + POINT maxSize; int swpflags = 0; + short x = 0, y = 0, cx = 0, cy = 0; if (!wndPtr) return FALSE; dprintf_win(stddeb,"ShowWindow: hwnd=%04X, cmd=%d\n", hwnd, cmd); - /* - * wasVisible is true if user has not made window invisible - * wasIconic is true if the window is not iconified - */ wasVisible = (wndPtr->dwStyle & WS_VISIBLE) != 0; switch(cmd) { case SW_HIDE: - /* - * if the window wasn't visible to begin with -- just return - */ - if (!wasVisible) - return FALSE; /* Nothing to do */ swpflags |= SWP_HIDEWINDOW | SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER; break; - case SW_SHOWMINNOACTIVE: + swpflags |= SWP_NOACTIVATE | SWP_NOZORDER; + /* fall through */ case SW_SHOWMINIMIZED: - case SW_MINIMIZE: - wndPtr->dwStyle |= WS_MINIMIZE; - swpflags |= SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE | - SWP_NOACTIVATE | SWP_NOZORDER; - - /* store the size and position of the window, so we can - * deiconify it to the same size and position - */ - wndPtr->rectNormal = wndPtr->rectWindow; - wndPtr->ptIconPos.x = wndPtr->rectWindow.left; - wndPtr->ptIconPos.y = wndPtr->rectWindow.top; - /* move the window to icon size and position and - * tell it that it is going to have to be painted - */ - MoveWindow(hwnd, wndPtr->ptIconPos.x, wndPtr->ptIconPos.y, - SYSMETRICS_CXICON, SYSMETRICS_CYICON, FALSE); - RedrawWindow( hwnd, NULL, 0, RDW_FRAME | RDW_ERASE | RDW_ERASENOW); + swpflags |= SWP_SHOWWINDOW; + /* fall through */ + case SW_MINIMIZE: + swpflags |= SWP_FRAMECHANGED; + if (!(wndPtr->dwStyle & WS_MINIMIZE)) + { + if (wndPtr->dwStyle & WS_MAXIMIZE) + { + wndPtr->flags |= WIN_RESTORE_MAX; + wndPtr->dwStyle &= ~WS_MAXIMIZE; + } + else + { + wndPtr->flags &= ~WIN_RESTORE_MAX; + wndPtr->rectNormal = wndPtr->rectWindow; + } + wndPtr->dwStyle |= WS_MINIMIZE; + WINPOS_FindIconPos( hwnd ); + x = wndPtr->ptIconPos.x; + y = wndPtr->ptIconPos.y; + cx = SYSMETRICS_CXICON; + cy = SYSMETRICS_CYICON; + } + else swpflags |= SWP_NOSIZE | SWP_NOMOVE; break; - case SW_SHOWNA: case SW_SHOWMAXIMIZED: /* same as SW_MAXIMIZE: */ + swpflags |= SWP_SHOWWINDOW | SWP_FRAMECHANGED; + if (!(wndPtr->dwStyle & WS_MAXIMIZE)) + { + /* Store the current position and find the maximized size */ + if (!(wndPtr->dwStyle & WS_MINIMIZE)) + wndPtr->rectNormal = wndPtr->rectWindow; + NC_GetMinMaxInfo( hwnd, &maxSize, + &wndPtr->ptMaxPos, NULL, NULL ); + x = wndPtr->ptMaxPos.x; + y = wndPtr->ptMaxPos.y; + cx = maxSize.x; + cy = maxSize.y; + wndPtr->dwStyle &= ~WS_MINIMIZE; + wndPtr->dwStyle |= WS_MAXIMIZE; + } + else swpflags |= SWP_NOSIZE | SWP_NOMOVE; + break; + + case SW_SHOWNA: + swpflags |= SWP_NOACTIVATE | SWP_NOZORDER; + /* fall through */ case SW_SHOW: swpflags |= SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE; break; - - case SW_SHOWNORMAL: /* same as SW_NORMAL: */ case SW_SHOWNOACTIVATE: + swpflags |= SWP_NOZORDER; + if (GetActiveWindow()) swpflags |= SWP_NOACTIVATE; + /* fall through */ + case SW_SHOWNORMAL: /* same as SW_NORMAL: */ case SW_RESTORE: - wasIconic = IsIconic(hwnd); - wndPtr->dwStyle &= ~WS_MINIMIZE; - wndPtr->dwStyle &= ~WS_MAXIMIZE; - swpflags |= SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE; - if (cmd == SW_SHOWNOACTIVATE) - { - swpflags |= SWP_NOZORDER; - if (GetActiveWindow()) swpflags |= SWP_NOACTIVATE; - } - if (wasIconic) { - MoveWindow(hwnd, wndPtr->rectNormal.left, - wndPtr->rectNormal.top, - wndPtr->rectNormal.right - wndPtr->rectNormal.left, - wndPtr->rectNormal.bottom - wndPtr->rectNormal.top, - FALSE); - } + swpflags |= SWP_SHOWWINDOW | SWP_FRAMECHANGED; + if (wndPtr->dwStyle & WS_MINIMIZE) + { + wndPtr->ptIconPos.x = wndPtr->rectWindow.left; + wndPtr->ptIconPos.y = wndPtr->rectWindow.top; + wndPtr->dwStyle &= ~WS_MINIMIZE; + if (wndPtr->flags & WIN_RESTORE_MAX) + { + /* Restore to maximized position */ + NC_GetMinMaxInfo( hwnd, &maxSize, &wndPtr->ptMaxPos, + NULL, NULL ); + x = wndPtr->ptMaxPos.x; + y = wndPtr->ptMaxPos.y; + cx = maxSize.x; + cy = maxSize.y; + wndPtr->dwStyle |= WS_MAXIMIZE; + } + else /* Restore to normal position */ + { + x = wndPtr->rectNormal.left; + y = wndPtr->rectNormal.top; + cx = wndPtr->rectNormal.right - wndPtr->rectNormal.left; + cy = wndPtr->rectNormal.bottom - wndPtr->rectNormal.top; + } + } + else if (wndPtr->dwStyle & WS_MAXIMIZE) + { + wndPtr->ptMaxPos.x = wndPtr->rectWindow.left; + wndPtr->ptMaxPos.y = wndPtr->rectWindow.top; + wndPtr->dwStyle &= ~WS_MAXIMIZE; + x = wndPtr->rectNormal.left; + y = wndPtr->rectNormal.top; + cx = wndPtr->rectNormal.right - wndPtr->rectNormal.left; + cy = wndPtr->rectNormal.bottom - wndPtr->rectNormal.top; + } + else swpflags |= SWP_NOSIZE | SWP_NOMOVE; break; } SendMessage( hwnd, WM_SHOWWINDOW, (cmd != SW_HIDE), 0 ); - SetWindowPos( hwnd, 0, 0, 0, 0, 0, swpflags ); + SetWindowPos( hwnd, HWND_TOP, x, y, cx, cy, swpflags ); /* Send WM_SIZE and WM_MOVE messages if not already done */ if (!(wndPtr->flags & WIN_GOT_SIZEMSG)) @@ -421,50 +555,6 @@ HWND WINPOS_NextWindowFromPoint( HWND hwnd, POINT pt ) } -/******************************************************************* - * WINPOS_GetMinMaxInfo - * - * Send a WM_GETMINMAXINFO to the window. - */ -void WINPOS_GetMinMaxInfo( HWND hwnd, POINT *maxSize, POINT *maxPos, - POINT *minTrack, POINT *maxTrack ) -{ - HANDLE minmaxHandle; - MINMAXINFO MinMax, *pMinMax; - WND *wndPtr = WIN_FindWndPtr( hwnd ); - - MinMax.ptMaxSize.x = SYSMETRICS_CXSCREEN; - MinMax.ptMaxSize.y = SYSMETRICS_CYSCREEN; - MinMax.ptMaxPosition = wndPtr->ptMaxPos; - MinMax.ptMinTrackSize.x = SYSMETRICS_CXMINTRACK; - MinMax.ptMinTrackSize.y = SYSMETRICS_CYMINTRACK; - MinMax.ptMaxTrackSize.x = SYSMETRICS_CXSCREEN; - MinMax.ptMaxTrackSize.y = SYSMETRICS_CYSCREEN; - - minmaxHandle = USER_HEAP_ALLOC( LMEM_MOVEABLE, sizeof(MINMAXINFO) ); - if (minmaxHandle) - { - pMinMax = (MINMAXINFO *) USER_HEAP_ADDR( minmaxHandle ); - memcpy( pMinMax, &MinMax, sizeof(MinMax) ); - SendMessage( hwnd, WM_GETMINMAXINFO, 0, (LONG)pMinMax ); - } - else pMinMax = &MinMax; - - /* Some sanity checks */ - - pMinMax->ptMaxTrackSize.x = max( pMinMax->ptMaxTrackSize.x, - pMinMax->ptMinTrackSize.x ); - pMinMax->ptMaxTrackSize.y = max( pMinMax->ptMaxTrackSize.y, - pMinMax->ptMinTrackSize.y ); - - if (maxSize) *maxSize = pMinMax->ptMaxSize; - if (maxPos) *maxPos = pMinMax->ptMaxPosition; - if (minTrack) *minTrack = pMinMax->ptMinTrackSize; - if (maxTrack) *maxTrack = pMinMax->ptMaxTrackSize; - if (minmaxHandle) USER_HEAP_FREE( minmaxHandle ); -} - - /******************************************************************* * WINPOS_ChangeActiveWindow * @@ -543,7 +633,7 @@ LONG WINPOS_HandleWindowPosChanging( WINDOWPOS *winpos ) if ((wndPtr->dwStyle & WS_THICKFRAME) || (wndPtr->dwStyle & (WS_POPUP | WS_CHILD) == 0)) { - WINPOS_GetMinMaxInfo( winpos->hwnd, &maxSize, NULL, NULL, NULL ); + NC_GetMinMaxInfo( winpos->hwnd, &maxSize, NULL, NULL, NULL ); winpos->cx = min( winpos->cx, maxSize.x ); winpos->cy = min( winpos->cy, maxSize.y ); } @@ -557,7 +647,7 @@ LONG WINPOS_HandleWindowPosChanging( WINDOWPOS *winpos ) * Move a window in Z order, invalidating everything that needs it. * Only necessary for windows without associated X window. */ -static void WINPOS_MoveWindowZOrder( HWND hwnd, HWND hwndAfter, BOOL erase ) +static void WINPOS_MoveWindowZOrder( HWND hwnd, HWND hwndAfter ) { BOOL movingUp; HWND hwndCur; @@ -603,7 +693,7 @@ static void WINPOS_MoveWindowZOrder( HWND hwnd, HWND hwndAfter, BOOL erase ) OffsetRect( &rect, -wndPtr->rectClient.left, -wndPtr->rectClient.top ); RedrawWindow( hwnd, &rect, 0, RDW_INVALIDATE | RDW_ALLCHILDREN | - RDW_FRAME | RDW_ERASE | (erase ? RDW_ERASENOW : 0) ); + RDW_FRAME | RDW_ERASE ); hwndCur = curPtr->hwndNext; } } @@ -619,13 +709,54 @@ static void WINPOS_MoveWindowZOrder( HWND hwnd, HWND hwndAfter, BOOL erase ) OffsetRect( &rect, -curPtr->rectClient.left, -curPtr->rectClient.top ); RedrawWindow( hwndCur, &rect, 0, RDW_INVALIDATE | RDW_ALLCHILDREN | - RDW_FRAME | RDW_ERASE | (erase ? RDW_ERASENOW : 0) ); + RDW_FRAME | RDW_ERASE ); hwndCur = curPtr->hwndNext; } } } +/*********************************************************************** + * WINPOS_SetXWindosPos + * + * SetWindowPos() for an X window. Used by the real SetWindowPos(). + */ +static void WINPOS_SetXWindowPos( WINDOWPOS *winpos ) +{ + XWindowChanges winChanges; + int changeMask = 0; + WND *wndPtr = WIN_FindWndPtr( winpos->hwnd ); + + if (!(winpos->flags & SWP_NOSIZE)) + { + winChanges.width = winpos->cx; + winChanges.height = winpos->cy; + changeMask |= CWWidth | CWHeight; + } + if (!(winpos->flags & SWP_NOMOVE)) + { + winChanges.x = winpos->x; + winChanges.y = winpos->y; + changeMask |= CWX | CWY; + } + if (!(winpos->flags & SWP_NOZORDER)) + { + if (winpos->hwndInsertAfter == HWND_TOP) winChanges.stack_mode = Above; + else winChanges.stack_mode = Below; + if ((winpos->hwndInsertAfter != HWND_TOP) && + (winpos->hwndInsertAfter != HWND_BOTTOM)) + { + WND * insertPtr = WIN_FindWndPtr( winpos->hwndInsertAfter ); + winChanges.sibling = insertPtr->window; + changeMask |= CWSibling; + } + changeMask |= CWStackMode; + } + if (changeMask) + XConfigureWindow( display, wndPtr->window, changeMask, &winChanges ); +} + + /*********************************************************************** * WINPOS_InternalSetWindowPos * @@ -637,8 +768,6 @@ static BOOL WINPOS_InternalSetWindowPos( WINDOWPOS *winpos ) WND *wndPtr; RECT newWindowRect, newClientRect; int flags, result; - int changeMask = 0; - XWindowChanges winChanges; /* Send WM_WINDOWPOSCHANGING message */ @@ -657,13 +786,20 @@ static BOOL WINPOS_InternalSetWindowPos( WINDOWPOS *winpos ) /* Check flags */ + if (winpos->hwnd == hwndActive) + winpos->flags |= SWP_NOACTIVATE; /* Already active */ + if ((wndPtr->rectWindow.right-wndPtr->rectWindow.left == winpos->cx) && + (wndPtr->rectWindow.bottom-wndPtr->rectWindow.top == winpos->cy)) + winpos->flags |= SWP_NOSIZE; /* Already the right size */ + if ((wndPtr->rectWindow.left == winpos->x) && + (wndPtr->rectWindow.top == winpos->y)) + winpos->flags |= SWP_NOMOVE; /* Already the right position */ flags = winpos->flags; - if (winpos->hwnd == hwndActive) flags |= SWP_NOACTIVATE; /*Already active*/ /* Check hwndAfter */ hwndAfter = winpos->hwndInsertAfter; - if (!(flags & (SWP_NOZORDER | SWP_NOACTIVATE))) + if (!(winpos->flags & (SWP_NOZORDER | SWP_NOACTIVATE))) { /* Ignore TOPMOST flags when activating a window */ /* _and_ moving it in Z order. */ @@ -676,72 +812,36 @@ static BOOL WINPOS_InternalSetWindowPos( WINDOWPOS *winpos ) /* hwndAfter must be a sibling of the window */ if ((hwndAfter != HWND_TOP) && (hwndAfter != HWND_BOTTOM) && (GetParent(winpos->hwnd) != GetParent(hwndAfter))) return FALSE; + winpos->hwndInsertAfter = hwndAfter; /* Calculate new position and size */ newWindowRect = wndPtr->rectWindow; newClientRect = wndPtr->rectClient; - if (!(flags & SWP_NOSIZE)) + if (!(winpos->flags & SWP_NOSIZE)) { - if ((newWindowRect.right != newWindowRect.left + winpos->cx) || - (newWindowRect.bottom != newWindowRect.top + winpos->cy)) - { - newWindowRect.right = newWindowRect.left + winpos->cx; - newWindowRect.bottom = newWindowRect.top + winpos->cy; - winChanges.width = winpos->cx; - winChanges.height = winpos->cy; - changeMask |= CWWidth | CWHeight; - } - else flags = winpos->flags |= SWP_NOSIZE; + newWindowRect.right = newWindowRect.left + winpos->cx; + newWindowRect.bottom = newWindowRect.top + winpos->cy; } - if (!(flags & SWP_NOMOVE)) + if (!(winpos->flags & SWP_NOMOVE)) { - if ((newWindowRect.left != winpos->x) || - (newWindowRect.top != winpos->y)) - { - newWindowRect.left = winpos->x; - newWindowRect.top = winpos->y; - newWindowRect.right += winpos->x - wndPtr->rectWindow.left; - newWindowRect.bottom += winpos->y - wndPtr->rectWindow.top; - if (wndPtr->dwStyle & WS_CHILD) - { - WND *parentPtr = WIN_FindWndPtr(wndPtr->hwndParent); - winChanges.x = winpos->x + parentPtr->rectClient.left - - parentPtr->rectWindow.left; - winChanges.y = winpos->y + parentPtr->rectClient.top - - parentPtr->rectWindow.top; - } - else - { - winChanges.x = winpos->x; - winChanges.y = winpos->y; - } - changeMask |= CWX | CWY; - } - else flags = 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; } /* Reposition window in Z order */ - if (!(flags & SWP_NOZORDER)) + if (!(winpos->flags & SWP_NOZORDER)) { if (wndPtr->window) { WIN_UnlinkWindow( winpos->hwnd ); WIN_LinkWindow( winpos->hwnd, hwndAfter ); - if (hwndAfter == HWND_TOP) winChanges.stack_mode = Above; - else winChanges.stack_mode = Below; - if ((hwndAfter != HWND_TOP) && (hwndAfter != HWND_BOTTOM)) - { - WND * insertPtr = WIN_FindWndPtr( hwndAfter ); - winChanges.sibling = insertPtr->window; - changeMask |= CWSibling; - } - changeMask |= CWStackMode; } - else WINPOS_MoveWindowZOrder( winpos->hwnd, hwndAfter, - !(flags & SWP_DEFERERASE) ); + else WINPOS_MoveWindowZOrder( winpos->hwnd, hwndAfter ); } /* Send WM_NCCALCSIZE message to get new client area */ @@ -755,8 +855,7 @@ static BOOL WINPOS_InternalSetWindowPos( WINDOWPOS *winpos ) if (wndPtr->window) { - if (changeMask) XConfigureWindow( display, wndPtr->window, - changeMask, &winChanges ); + WINPOS_SetXWindowPos( winpos ); wndPtr->rectWindow = newWindowRect; wndPtr->rectClient = newClientRect; } @@ -767,20 +866,21 @@ static BOOL WINPOS_InternalSetWindowPos( WINDOWPOS *winpos ) wndPtr->rectWindow = newWindowRect; wndPtr->rectClient = newClientRect; - if (changeMask) + if (!(flags & SWP_NOREDRAW) && + (!(flags & SWP_NOSIZE) || !(flags & SWP_NOMOVE) || + !(flags & SWP_NOZORDER))) { HRGN hrgn1 = CreateRectRgnIndirect( &oldWindowRect ); HRGN hrgn2 = CreateRectRgnIndirect( &wndPtr->rectWindow ); HRGN hrgn3 = CreateRectRgn( 0, 0, 0, 0 ); CombineRgn( hrgn3, hrgn1, hrgn2, RGN_DIFF ); RedrawWindow( wndPtr->hwndParent, NULL, hrgn3, - RDW_INVALIDATE | RDW_ALLCHILDREN | - RDW_ERASE | RDW_ERASENOW ); + RDW_INVALIDATE | RDW_ALLCHILDREN | RDW_ERASE ); if ((oldWindowRect.left != wndPtr->rectWindow.left) || (oldWindowRect.top != wndPtr->rectWindow.top)) { RedrawWindow( winpos->hwnd, NULL, 0, RDW_INVALIDATE | - RDW_FRAME | RDW_ALLCHILDREN | RDW_ERASE | RDW_ERASENOW ); + RDW_FRAME | RDW_ALLCHILDREN | RDW_ERASE ); } DeleteObject( hrgn1 ); DeleteObject( hrgn2 ); @@ -797,8 +897,9 @@ static BOOL WINPOS_InternalSetWindowPos( WINDOWPOS *winpos ) } else { - RedrawWindow( winpos->hwnd, NULL, 0, - RDW_INVALIDATE | RDW_FRAME | RDW_ERASE ); + if (!(flags & SWP_NOREDRAW)) + RedrawWindow( winpos->hwnd, NULL, 0, + RDW_INVALIDATE | RDW_FRAME | RDW_ERASE ); } } else if (flags & SWP_HIDEWINDOW) @@ -810,9 +911,10 @@ static BOOL WINPOS_InternalSetWindowPos( WINDOWPOS *winpos ) } else { - RedrawWindow( wndPtr->hwndParent, &wndPtr->rectWindow, 0, - RDW_INVALIDATE | RDW_FRAME | - RDW_ALLCHILDREN | RDW_ERASE | RDW_ERASENOW ); + if (!(flags & SWP_NOREDRAW)) + RedrawWindow( wndPtr->hwndParent, &wndPtr->rectWindow, 0, + RDW_INVALIDATE | RDW_FRAME | + RDW_ALLCHILDREN | RDW_ERASE ); } if ((winpos->hwnd == GetFocus()) || IsChild(winpos->hwnd, GetFocus())) SetFocus( GetParent(winpos->hwnd) ); /* Revert focus to parent */ @@ -840,15 +942,17 @@ static BOOL WINPOS_InternalSetWindowPos( WINDOWPOS *winpos ) /* Repaint the window */ if (wndPtr->window) MSG_Synchronize(); /* Wait for all expose events */ - if (flags & SWP_FRAMECHANGED) + if ((flags & SWP_FRAMECHANGED) && !(flags & SWP_NOREDRAW)) RedrawWindow( winpos->hwnd, NULL, 0, RDW_INVALIDATE | RDW_FRAME | RDW_ERASE ); - RedrawWindow( winpos->hwnd, NULL, 0, - (flags & SWP_NOREDRAW) ? RDW_VALIDATE : RDW_ERASENOW ); + if (!(flags & SWP_DEFERERASE)) + RedrawWindow( wndPtr->hwndParent, NULL, 0, + RDW_ALLCHILDREN | RDW_ERASENOW ); /* And last, send the WM_WINDOWPOSCHANGED message */ - SendMessage( winpos->hwnd, WM_WINDOWPOSCHANGED, 0, (LONG)winpos ); + if (!(winpos->flags & SWP_NOSENDCHANGING)) + SendMessage( winpos->hwnd, WM_WINDOWPOSCHANGED, 0, (LONG)winpos ); return TRUE; } @@ -996,12 +1100,3 @@ void CascadeChildWindows( HWND parent, WORD action ) { printf("STUB CascadeChildWindows(%04X, %d)\n", parent, action); } - -/*********************************************************************** - * ArrangeIconicWindows (USER.170) - */ -WORD ArrangeIconicWindows( HWND parent ) -{ - printf("STUB ArrangeIconicWindows(%04X)\n", parent); - return 0; -} -- GitLab