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.
diff --git a/ANNOUNCE b/ANNOUNCE
index ebdf2dc..ed22ab8 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 @@
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 7592fc4..f2a9d94 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,33 @@
----------------------------------------------------------------------
+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)
* [loader/resource.c] [objects/dib.c]
diff --git a/Configure b/Configure
index d1b3650..63e261c 100644
--- a/Configure
+++ b/Configure
@@ -47,10 +47,11 @@
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 0000000..3aa0ff9
--- /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 a04b2b9..e81ab13 100644
--- a/controls/edit.c
+++ b/controls/edit.c
@@ -278,7 +278,10 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
if (*CurrChar == '\0')
return;
- if (*CurrChar == '\n')
+ if (*CurrChar == '\r')
{
EDIT_Home(hwnd);
EDIT_Downward(hwnd);
@@ -1465,7 +1490,7 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 03de3c8..e335ade 100644
--- a/controls/scroll.c
+++ b/controls/scroll.c
@@ -896,8 +896,6 @@
}
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 87b6510..ac57b7b 100644
--- a/if1632/user.spec
+++ b/if1632/user.spec
@@ -320,7 +320,7 @@
#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 0e8c665..0a34d90 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 0ffedbf..c33e722 100644
--- a/include/win.h
+++ b/include/win.h
@@ -48,7 +48,6 @@
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 65ebf08..0c4c17e 100644
--- a/include/windows.h
+++ b/include/windows.h
@@ -2711,6 +2711,7 @@
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 1df7d57..19ca5c7 100644
--- a/include/winpos.h
+++ b/include/winpos.h
@@ -22,8 +22,6 @@
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 6d7e973..ef7bd18 100644
--- a/loader/library.c
+++ b/loader/library.c
@@ -203,7 +203,8 @@
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 7ccc901..b662d99 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 97a9653..c4c4a46 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 @@
{
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 @@
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 @@
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 @@
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 @@
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 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 @@
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 36decda..9e89e0c 100644
--- a/rc/Imakefile
+++ b/rc/Imakefile
@@ -23,6 +23,7 @@
$(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 9a4bce6..c2ea2f2 100644
--- a/tools/build.c
+++ b/tools/build.c
@@ -757,8 +757,10 @@
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 7c98f92..911637e 100644
--- a/windows/cursor.c
+++ b/windows/cursor.c
@@ -82,7 +82,6 @@
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 ee6f575..f59d501 100644
--- a/windows/mdi.c
+++ b/windows/mdi.c
@@ -283,23 +283,13 @@
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 6d0903f..6f586a4 100644
--- a/windows/nonclient.c
+++ b/windows/nonclient.c
@@ -110,6 +110,82 @@
}
+/*******************************************************************
+ * 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 @@
/* 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 @@
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 @@
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 e44110b..782626c 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>
@@ -104,12 +104,22 @@
/***********************************************************************
+ * 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 @@
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 @@
*/
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 @@
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 809c333..5148b94 100644
--- a/windows/win.c
+++ b/windows/win.c
@@ -400,7 +400,7 @@
/* 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 @@
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 @@
}
-
/***********************************************************************
* OpenIcon (USER.44)
*/
@@ -572,7 +586,6 @@
}
-
/***********************************************************************
* FindWindow (USER.50)
*/
diff --git a/windows/winpos.c b/windows/winpos.c
index 6de8899..5f71349 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"
@@ -17,6 +18,95 @@
/***********************************************************************
+ * 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)
*/
void GetWindowRect( HWND hwnd, LPRECT rect )
@@ -99,6 +189,7 @@
return hwndRet;
}
+
/*******************************************************************
* ChildWindowFromPoint (USER.191)
*/
@@ -187,6 +278,7 @@
return hwndActive;
}
+
/*******************************************************************
* SetActiveWindow (USER.59)
*/
@@ -229,84 +321,126 @@
{
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))
@@ -422,50 +556,6 @@
/*******************************************************************
- * 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
*
* Change the active window and send the corresponding messages.
@@ -543,7 +633,7 @@
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 @@
* 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 @@
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,7 +709,7 @@
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;
}
}
@@ -627,6 +717,47 @@
/***********************************************************************
+ * 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
*
* Helper function for SetWindowPos.
@@ -637,8 +768,6 @@
WND *wndPtr;
RECT newWindowRect, newClientRect;
int flags, result;
- int changeMask = 0;
- XWindowChanges winChanges;
/* Send WM_WINDOWPOSCHANGING message */
@@ -657,13 +786,20 @@
/* 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 @@
/* 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 @@
if (wndPtr->window)
{
- if (changeMask) XConfigureWindow( display, wndPtr->window,
- changeMask, &winChanges );
+ WINPOS_SetXWindowPos( winpos );
wndPtr->rectWindow = newWindowRect;
wndPtr->rectClient = newClientRect;
}
@@ -767,20 +866,21 @@
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 @@
}
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 @@
}
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 @@
/* 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 @@
{
printf("STUB CascadeChildWindows(%04X, %d)\n", parent, action);
}
-
-/***********************************************************************
- * ArrangeIconicWindows (USER.170)
- */
-WORD ArrangeIconicWindows( HWND parent )
-{
- printf("STUB ArrangeIconicWindows(%04X)\n", parent);
- return 0;
-}