1
0
Fork 0
mirror of synced 2025-03-07 03:53:26 +01:00

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.
This commit is contained in:
Alexandre Julliard 1995-03-02 17:44:29 +00:00
parent 18506558a7
commit 22945d5aba
22 changed files with 729 additions and 459 deletions

View file

@ -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 developer's only release. There are many bugs and many unimplemented API
features. Most applications still do not work. features. Most applications still do not work.
Patches should be submitted to "wine-new@amscons.com". Please don't forget 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. to include a ChangeLog entry. I'll make a new release every other Sunday.
WHAT'S NEW with Wine-950122: (see ChangeLog for details) WHAT'S NEW with Wine-950202: (see ChangeLog for details)
- ELF format support - Maximized windows
- New disassembler based on Mach code, replacing the gdb code - Edit control now uses \r\n for line endings
- Faster regions - Better registry functions
- Lots of bug fixes - Lots of bug fixes
See the README file in the distribution for installation instructions. 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 the release is available at the ftp sites. The sources will be available
from the following locations: from the following locations:
sunsite.unc.edu:/pub/Linux/ALPHA/wine/Wine-950122.tar.gz sunsite.unc.edu:/pub/Linux/ALPHA/wine/Wine-950202.tar.gz
aris.com:/pub/linux/ALPHA/Wine/development/Wine-950122.tar.gz aris.com:/pub/linux/ALPHA/Wine/development/Wine-950202.tar.gz
tsx-11.mit.edu:/pub/linux/ALPHA/Wine/development/Wine-950122.tar.gz tsx-11.mit.edu:/pub/linux/ALPHA/Wine/development/Wine-950202.tar.gz
ftp.funet.fi:/pub/OS/Linux/ALPHA/Wine/Wine-950122.tar.gz ftp.funet.fi:/pub/OS/Linux/ALPHA/Wine/Wine-950202.tar.gz
ftp.wonderland.org:/Wine/Wine-950122.tar.gz ftp.wonderland.org:/Wine/Wine-950202.tar.gz
If you submitted a patch, please check to make sure it has been If you submitted a patch, please check to make sure it has been
included in the new release. included in the new release.

View file

@ -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) Sun Jan 22 18:55:33 1995 Alexandre Julliard (julliard@lamisun.epfl.ch)

View file

@ -47,10 +47,11 @@ then
fi fi
echo echo
echo -n 'Use the XPM library (Y/N) [N]? ' echo -n 'Use the XPM library (Y/N) [Y]? '
read input read input
if [ "$input" = 'y' -o "$input" = 'Y' ] if [ "$input" = 'n' -o "$input" = 'N' ]
then then :
else
XPM='#define USE_XPM' XPM='#define USE_XPM'
ALLDEFINES="$ALLDEFINES -DUSE_XPM" ALLDEFINES="$ALLDEFINES -DUSE_XPM"
fi fi

23
controls/EDIT.TODO Normal file
View file

@ -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!

View file

@ -278,7 +278,10 @@ LONG EditWndProc(HWND hwnd, WORD uMsg, WORD wParam, LONG lParam)
break; break;
case EM_SETHANDLE: case EM_SETHANDLE:
HideCaret(hwnd);
EDIT_SetHandleMsg(hwnd, wParam); EDIT_SetHandleMsg(hwnd, wParam);
SetCaretPos(es->WndCol, es->WndRow * es->txtht);
ShowCaret(hwnd);
break; break;
case EM_SETMODIFY: case EM_SETMODIFY:
@ -431,7 +434,13 @@ LONG EditWndProc(HWND hwnd, WORD uMsg, WORD wParam, LONG lParam)
SetCaretPos(es->WndCol, es->WndRow * es->txtht); SetCaretPos(es->WndCol, es->WndRow * es->txtht);
ShowCaret(hwnd); ShowCaret(hwnd);
break; 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: case WM_SETTEXT:
EDIT_SetTextMsg(hwnd, lParam); EDIT_SetTextMsg(hwnd, lParam);
break; break;
@ -548,11 +557,14 @@ long EDIT_CreateMsg(HWND hwnd, LONG lParam)
char *text; char *text;
/* initialize state variable structure */ /* initialize state variable structure */
/* --- char width array */
hdc = GetDC(hwnd); 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); charWidths = (short *)EDIT_HeapAddr(hwnd, es->hCharWidths);
memset(charWidths, 0, 256 * sizeof(short)); memset(charWidths, 0, 256 * sizeof(short));
GetCharWidth(hdc, 0, 255, charWidths); GetCharWidth(hdc, 32, 254, &charWidths[32]);
/* --- other structure variables */ /* --- other structure variables */
GetTextMetrics(hdc, &tm); GetTextMetrics(hdc, &tm);
@ -737,7 +749,7 @@ HANDLE EDIT_GetTextLine(HWND hwnd, int selection)
dprintf_edit(stddeb,"GetTextLine %d\n", selection); dprintf_edit(stddeb,"GetTextLine %d\n", selection);
cp = cp1 = EDIT_TextLine(hwnd, selection); cp = cp1 = EDIT_TextLine(hwnd, selection);
/* advance through line */ /* advance through line */
while (*cp && *cp != '\n') while (*cp && *cp != '\r')
{ {
len++; len++;
cp++; cp++;
@ -804,7 +816,7 @@ int EDIT_LineLength(HWND hwnd, int num)
char *cp1; char *cp1;
if(!cp)return 0; if(!cp)return 0;
cp1 = strchr(cp, '\n'); cp1 = strchr(cp, '\r');
return cp1 ? (int)(cp1 - cp) : strlen(cp); 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); 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) while (i < off)
{ {
s_i = i; s_i = i;
@ -1111,6 +1123,8 @@ HANDLE EDIT_GetStr(HWND hwnd, char *lp, int off, int len, int *diff)
ch1 = ch; ch1 = ch;
while (i < len + off) while (i < len + off)
{ {
if (*(lp + ch) == '\r' || *(lp + ch) == '\n')
break;
i += EDIT_CharWidth(hwnd, (BYTE)(*(lp + ch)), i); i += EDIT_CharWidth(hwnd, (BYTE)(*(lp + ch)), i);
ch++; ch++;
} }
@ -1191,8 +1205,9 @@ void EDIT_KeyTyped(HWND hwnd, short ch)
if (*currchar == '\0' && IsMultiLine()) if (*currchar == '\0' && IsMultiLine())
{ {
/* insert a newline at end of text */ /* insert a newline at end of text */
*currchar = '\n'; *currchar = '\r';
*(currchar + 1) = '\0'; *(currchar + 1) = '\n';
*(currchar + 2) = '\0';
EDIT_BuildTextPointers(hwnd); EDIT_BuildTextPointers(hwnd);
} }
@ -1220,9 +1235,19 @@ void EDIT_KeyTyped(HWND hwnd, short ch)
currchar = CurrChar; currchar = CurrChar;
} }
/* make space for new character and put char in buffer */ /* make space for new character and put char in buffer */
memmove(currchar + 1, currchar, strlen(currchar) + 1); if (ch == '\n')
*currchar = ch; {
EDIT_ModTextPointers(hwnd, es->CurrLine + 1, 1); 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; es->TextChanged = TRUE;
NOTIFY_PARENT(hwnd, EN_UPDATE); NOTIFY_PARENT(hwnd, EN_UPDATE);
@ -1347,7 +1372,7 @@ void EDIT_Forward(HWND hwnd)
if (*CurrChar == '\0') if (*CurrChar == '\0')
return; return;
if (*CurrChar == '\n') if (*CurrChar == '\r')
{ {
EDIT_Home(hwnd); EDIT_Home(hwnd);
EDIT_Downward(hwnd); EDIT_Downward(hwnd);
@ -1465,7 +1490,7 @@ void EDIT_End(HWND hwnd)
EDITSTATE *es = EDITSTATE *es =
(EDITSTATE *)EDIT_HeapAddr(hwnd, (HANDLE)(*(wndPtr->wExtra))); (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->WndCol += EDIT_CharWidth(hwnd, (BYTE)(*CurrChar), es->WndCol + es->wleft);
es->CurrCol++; 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) if (es->WndCol > EDIT_StrLength(hwnd, cp, len, 0) - es->wleft || end)
es->WndCol = EDIT_StrLength(hwnd, cp, len, 0) - es->wleft; es->WndCol = EDIT_StrLength(hwnd, cp, len, 0) - es->wleft;
es->CurrCol = EDIT_PixelToChar(hwnd, es->CurrLine, &(es->WndCol)); es->CurrCol = EDIT_PixelToChar(hwnd, es->CurrLine, &(es->WndCol));
es->SelEndCol = es->CurrCol - 1; es->SelEndCol = es->CurrCol;
bel = es->SelEndLine; bel = es->SelEndLine;
bec = es->SelEndCol; bec = es->SelEndCol;
@ -2622,10 +2647,15 @@ void EDIT_WriteSel(HWND hwnd, int y, int start, int end)
if (end == -1) if (end == -1)
end = EDIT_LineLength(hwnd, y); 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); scol = EDIT_StrLength(hwnd, cp, start, 0);
if (scol > rc.right) return; if (scol > rc.right) return;
if (scol < rc.left) scol = rc.left; 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.left) return;
if (ecol > rc.right) ecol = rc.right; 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); hbrush = GetStockObject(BLACK_BRUSH);
holdbrush = (HBRUSH)SelectObject(hdc, (HANDLE)hbrush); holdbrush = (HBRUSH)SelectObject(hdc, (HANDLE)hbrush);
olddm = SetROP2(hdc, R2_XORPEN); 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); SetROP2(hdc, olddm);
SelectObject(hdc, (HANDLE)holdbrush); SelectObject(hdc, (HANDLE)holdbrush);
ReleaseDC(hwnd, hdc); ReleaseDC(hwnd, hdc);
@ -3054,7 +3084,7 @@ void EDIT_SetHandleMsg(HWND hwnd, WORD wParam)
if (IsMultiLine()) if (IsMultiLine())
{ {
es->hText = wParam; es->hText = wParam;
es->MaxTextLen = EDIT_HeapSize(hwnd, es->hText); es->textlen = EDIT_HeapSize(hwnd, es->hText);
es->wlines = 0; es->wlines = 0;
es->wtop = es->wleft = 0; es->wtop = es->wleft = 0;
es->CurrLine = es->CurrCol = 0; es->CurrLine = es->CurrCol = 0;
@ -3063,7 +3093,10 @@ void EDIT_SetHandleMsg(HWND hwnd, WORD wParam)
es->textwidth = 0; es->textwidth = 0;
es->SelBegLine = es->SelBegCol = 0; es->SelBegLine = es->SelBegCol = 0;
es->SelEndLine = es->SelEndCol = 0; es->SelEndLine = es->SelEndCol = 0;
dprintf_edit(stddeb, "EDIT_SetHandleMsg: textlen=%d\n",
es->textlen);
EDIT_BuildTextPointers(hwnd);
es->PaintBkgd = TRUE; es->PaintBkgd = TRUE;
InvalidateRect(hwnd, NULL, TRUE); InvalidateRect(hwnd, NULL, TRUE);
UpdateWindow(hwnd); UpdateWindow(hwnd);

View file

@ -896,8 +896,6 @@ void ShowScrollBar( HWND hwnd, WORD wBar, BOOL fShow )
} }
SetWindowPos( hwnd, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE SetWindowPos( hwnd, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE
| SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED ); | SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED );
/* FIXME: Hack until SetWindowPos works correctly */
InvalidateRect( hwnd, NULL, TRUE );
} }

View file

@ -320,7 +320,7 @@ length 540
#323 GETMESSAGE2 #323 GETMESSAGE2
324 pascal FillWindow(word word word word) FillWindow(1 2 3 4) 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) 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) 331 pascal EnableHardwareInput(word) EnableHardwareInput(1)
332 return UserYield 0 0 332 return UserYield 0 0
#333 ISUSERIDLE #333 ISUSERIDLE

View file

@ -10,6 +10,8 @@
#include "windows.h" #include "windows.h"
extern void NC_GetInsideRect( HWND hwnd, RECT *rect ); 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 void NC_DoNCPaint( HWND hwnd, BOOL active, BOOL suppress_menupaint );
extern LONG NC_HandleNCPaint( HWND hwnd ); extern LONG NC_HandleNCPaint( HWND hwnd );
extern LONG NC_HandleNCActivate( HWND hwnd, WORD wParam ); extern LONG NC_HandleNCActivate( HWND hwnd, WORD wParam );

View file

@ -48,7 +48,6 @@ typedef struct tagWND
HANDLE hText; /* Handle of window text */ HANDLE hText; /* Handle of window text */
WORD flags; /* Misc. flags (see below) */ WORD flags; /* Misc. flags (see below) */
Window window; /* X window (only for top-level windows) */ 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 */ HMENU hSysMenu; /* window's copy of System Menu */
HANDLE hProp; /* Handle of Properties List */ HANDLE hProp; /* Handle of Properties List */
HTASK hTask; /* Task Handle of the owner */ HTASK hTask; /* Task Handle of the owner */

View file

@ -2711,6 +2711,7 @@ Fc(HANDLE,FindResource,HANDLE,a,LPSTR,b,LPSTR,c)
Fc(HANDLE,LocalReAlloc,HANDLE,a,WORD,b,WORD,c) Fc(HANDLE,LocalReAlloc,HANDLE,a,WORD,b,WORD,c)
Fc(HBITMAP,CreateCompatibleBitmap,HDC,a,short,b,short,c) Fc(HBITMAP,CreateCompatibleBitmap,HDC,a,short,b,short,c)
Fc(HBITMAP,CreateDiscardableBitmap,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(HDC,GetDCEx,HWND,a,HRGN,b,DWORD,c)
Fc(HPALETTE,SelectPalette,HDC,a,HPALETTE,b,BOOL,c) Fc(HPALETTE,SelectPalette,HDC,a,HPALETTE,b,BOOL,c)
Fc(HPEN,CreatePen,short,a,short,b,COLORREF,c) Fc(HPEN,CreatePen,short,a,short,b,COLORREF,c)

View file

@ -22,8 +22,6 @@ typedef struct
extern HWND WINPOS_NextWindowFromPoint( HWND hwnd, POINT pt ); extern HWND WINPOS_NextWindowFromPoint( HWND hwnd, POINT pt );
extern HWND WINPOS_ChangeActiveWindow( HWND hwnd, BOOL mouseMsg ); 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, extern LONG WINPOS_SendNCCalcSize( HWND hwnd, BOOL calcValidRect,
RECT *newWindowRect, RECT *oldWindowRect, RECT *newWindowRect, RECT *oldWindowRect,
RECT *oldClientRect, WINDOWPOS *winpos, RECT *oldClientRect, WINDOWPOS *winpos,

View file

@ -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)) != if (read(wpnt->fd, wpnt->mz_header, sizeof(struct mz_header_s)) !=
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 */ /* This field is ignored according to "Windows Internals", p.242 */

View file

@ -4,7 +4,6 @@
#include "stdio.h" #include "stdio.h"
#include "windows.h" #include "windows.h"
#include "win.h"
#include "user.h" #include "user.h"
#define WN_SUCCESS 0x0000 #define WN_SUCCESS 0x0000

View file

@ -14,60 +14,88 @@
/* #define DEBUG_REG */ /* #define DEBUG_REG */
#include "debug.h" #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] * RegOpenKey [SHELL.1]
*/ */
LONG RegOpenKey(HKEY hKey, LPCSTR lpSubKey, HKEY FAR *lphKey) LONG RegOpenKey(HKEY hKey, LPCSTR lpSubKey, HKEY FAR *lphKey)
{ {
LPKEYSTRUCT lpKey = lphRootKey; LPKEYSTRUCT lpKey;
LPSTR ptr; LPCSTR ptr;
char str[128]; char str[128];
LONG dwRet;
dwRet = SHELL_RegCheckForRoot();
if (dwRet != ERROR_SUCCESS) return dwRet;
dprintf_reg(stddeb, "RegOpenKey(%08lX, %p='%s', %p)\n", dprintf_reg(stddeb, "RegOpenKey(%08lX, %p='%s', %p)\n",
hKey, lpSubKey, lpSubKey, lphKey); hKey, lpSubKey, lpSubKey, lphKey);
if (lpKey == NULL) return ERROR_BADKEY;
if (lpSubKey == NULL) return ERROR_INVALID_PARAMETER; if (lpSubKey == NULL) return ERROR_INVALID_PARAMETER;
if (lphKey == NULL) return ERROR_INVALID_PARAMETER; if (lphKey == NULL) return ERROR_INVALID_PARAMETER;
if (hKey != HKEY_CLASSES_ROOT) { switch(hKey) {
dprintf_reg(stddeb,"RegOpenKey // specific key = %08lX !\n", hKey); case 0:
lpKey = (LPKEYSTRUCT)GlobalLock(hKey); lpKey = lphTopKey; break;
} case HKEY_CLASSES_ROOT: /* == 1 */
while ( (ptr = strchr(lpSubKey, '\\')) != NULL ) { lpKey = lphRootKey; break;
strncpy(str, lpSubKey, (LONG)ptr - (LONG)lpSubKey); default:
str[(LONG)ptr - (LONG)lpSubKey] = '\0'; dprintf_reg(stddeb,"RegOpenKey // specific key = %08lX !\n", hKey);
lpSubKey = ptr + 1; lpKey = (LPKEYSTRUCT)GlobalLock(hKey);
dprintf_reg(stddeb,"RegOpenKey // next level '%s' !\n", str); }
while(TRUE) { while(*lpSubKey) {
dprintf_reg(stddeb,"RegOpenKey // '%s' <-> '%s' !\n", str, lpKey->lpSubKey); ptr = strchr(lpSubKey,'\\');
if (lpKey->lpSubKey != NULL && lpKey->lpSubKey[0] != '\0' && if (!ptr) ptr = lpSubKey + strlen(lpSubKey);
strcmp(lpKey->lpSubKey, str) == 0) { strncpy(str,lpSubKey,ptr-lpSubKey);
lpKey = lpKey->lpSubLvl; str[ptr-lpSubKey] = 0;
if (lpKey == NULL) { lpSubKey = ptr;
printf("RegOpenKey // can't find subkey '%s' !\n", str); if (*lpSubKey) lpSubKey++;
return ERROR_BADKEY;
} lpKey = lpKey->lpSubLvl;
break; while(lpKey != NULL && strcmp(lpKey->lpSubKey, str) != 0) { lpKey = lpKey->lpNextKey; }
} if (lpKey == NULL) {
if (lpKey->lpNextKey == NULL) { dprintf_reg(stddeb,"RegOpenKey: key %s not found!\n",str);
printf("RegOpenKey // can't find subkey '%s' !\n", str); return ERROR_BADKEY;
return ERROR_BADKEY; }
} }
lpKey = lpKey->lpNextKey; *lphKey = lpKey->hKey;
}
}
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);
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
@ -79,86 +107,69 @@ LONG RegCreateKey(HKEY hKey, LPCSTR lpSubKey, HKEY FAR *lphKey)
{ {
HKEY hNewKey; HKEY hNewKey;
LPKEYSTRUCT lpNewKey; LPKEYSTRUCT lpNewKey;
LPKEYSTRUCT lpKey = lphRootKey; LPKEYSTRUCT lpKey;
LPKEYSTRUCT lpPrevKey; LPKEYSTRUCT lpPrevKey;
LONG dwRet; LONG dwRet;
LPSTR ptr; LPCSTR ptr;
char str[128]; char str[128];
dwRet = SHELL_RegCheckForRoot();
if (dwRet != ERROR_SUCCESS) return dwRet;
dprintf_reg(stddeb, "RegCreateKey(%08lX, '%s', %p)\n", hKey, lpSubKey, lphKey); dprintf_reg(stddeb, "RegCreateKey(%08lX, '%s', %p)\n", hKey, lpSubKey, lphKey);
if (lpSubKey == NULL) return ERROR_INVALID_PARAMETER; if (lpSubKey == NULL) return ERROR_INVALID_PARAMETER;
if (lphKey == NULL) return ERROR_INVALID_PARAMETER; if (lphKey == NULL) return ERROR_INVALID_PARAMETER;
if (hKey != HKEY_CLASSES_ROOT) { switch(hKey) {
dprintf_reg(stddeb,"RegCreateKey // specific key = %08lX !\n", hKey); case 0:
lpKey = (LPKEYSTRUCT)GlobalLock(hKey); lpKey = lphTopKey; break;
} case HKEY_CLASSES_ROOT: /* == 1 */
while ( (ptr = strchr(lpSubKey, '\\')) != NULL ) { lpKey = lphRootKey; break;
strncpy(str, lpSubKey, (LONG)ptr - (LONG)lpSubKey); default:
str[(LONG)ptr - (LONG)lpSubKey] = '\0'; dprintf_reg(stddeb,"RegCreateKey // specific key = %08lX !\n", hKey);
lpSubKey = ptr + 1; lpKey = (LPKEYSTRUCT)GlobalLock(hKey);
dprintf_reg(stddeb,"RegCreateKey // next level '%s' !\n", str); }
lpPrevKey = lpKey; while (*lpSubKey) {
while(TRUE) { dprintf_reg(stddeb, "RegCreateKey: Looking for subkey %s\n", lpSubKey);
dprintf_reg(stddeb,"RegCreateKey // '%s' <-> '%s' !\n", str, lpKey->lpSubKey); ptr = strchr(lpSubKey,'\\');
if (lpKey->lpSubKey != NULL && if (!ptr) ptr = lpSubKey + strlen(lpSubKey);
strcmp(lpKey->lpSubKey, str) == 0) { strncpy(str,lpSubKey,ptr-lpSubKey);
if (lpKey->lpSubLvl == NULL) { str[ptr-lpSubKey] = 0;
dprintf_reg(stddeb,"RegCreateKey // '%s' found !\n", str); lpSubKey = ptr;
if ( (ptr = strchr(lpSubKey, '\\')) != NULL ) { if (*lpSubKey) lpSubKey++;
strncpy(str, lpSubKey, (LONG)ptr - (LONG)lpSubKey);
str[(LONG)ptr - (LONG)lpSubKey] = '\0'; lpPrevKey = lpKey;
lpSubKey = ptr + 1; lpKey = lpKey->lpSubLvl;
} while(lpKey != NULL && strcmp(lpKey->lpSubKey, str) != 0) {
else lpKey = lpKey->lpNextKey;
strcpy(str, lpSubKey); }
dwRet = RegCreateKey(lpKey->hKey, str, &hNewKey); if (lpKey == NULL) {
if (dwRet != ERROR_SUCCESS) { hNewKey = GlobalAlloc(GMEM_MOVEABLE, sizeof(KEYSTRUCT));
printf("RegCreateKey // can't create subkey '%s' !\n", str); lpNewKey = (LPKEYSTRUCT) GlobalLock(hNewKey);
return dwRet; if (lpNewKey == NULL) {
} printf("RegCreateKey // Can't alloc new key !\n");
lpKey->lpSubLvl = (LPKEYSTRUCT)GlobalLock(hNewKey); return ERROR_OUTOFMEMORY;
} }
lpKey = lpKey->lpSubLvl; lpNewKey->hKey = hNewKey;
break; lpNewKey->lpSubKey = malloc(strlen(str) + 1);
} if (lpNewKey->lpSubKey == NULL) {
if (lpKey->lpNextKey == NULL) { printf("RegCreateKey // Can't alloc key string !\n");
dwRet = RegCreateKey(lpPrevKey->hKey, str, &hNewKey); return ERROR_OUTOFMEMORY;
if (dwRet != ERROR_SUCCESS) { }
printf("RegCreateKey // can't create subkey '%s' !\n", str); strcpy(lpNewKey->lpSubKey, str);
return dwRet; lpNewKey->lpNextKey = lpPrevKey->lpSubLvl;
} lpNewKey->lpPrevKey = NULL;
lpKey = (LPKEYSTRUCT)GlobalLock(hNewKey); lpPrevKey->lpSubLvl = lpNewKey;
break;
} lpNewKey->dwType = 0;
lpKey = lpKey->lpNextKey; lpNewKey->lpValue = NULL;
} lpNewKey->lpSubLvl = NULL;
} *lphKey = hNewKey;
hNewKey = GlobalAlloc(GMEM_MOVEABLE, sizeof(KEYSTRUCT)); dprintf_reg(stddeb,"RegCreateKey // successful '%s' key=%08lX !\n", str, hNewKey);
lpNewKey = (LPKEYSTRUCT) GlobalLock(hNewKey); lpKey = lpNewKey;
if (lpNewKey == NULL) { } else {
printf("RegCreateKey // Can't alloc new key !\n"); *lphKey = lpKey->hKey;
return ERROR_OUTOFMEMORY; dprintf_reg(stddeb,"RegCreateKey // found '%s', key=%08lX\n", str, *lphKey);
} }
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);
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
@ -198,7 +209,7 @@ LONG RegSetValue(HKEY hKey, LPCSTR lpSubKey, DWORD dwType,
if (lpSubKey == NULL) return ERROR_INVALID_PARAMETER; if (lpSubKey == NULL) return ERROR_INVALID_PARAMETER;
if (lpVal == NULL) return ERROR_INVALID_PARAMETER; if (lpVal == NULL) return ERROR_INVALID_PARAMETER;
if ((dwRet = RegOpenKey(hKey, lpSubKey, &hRetKey)) != ERROR_SUCCESS) { 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) { if ((dwRet = RegCreateKey(hKey, lpSubKey, &hRetKey)) != ERROR_SUCCESS) {
fprintf(stderr, "RegSetValue // key creation error %08lX !\n", dwRet); fprintf(stderr, "RegSetValue // key creation error %08lX !\n", dwRet);
return dwRet; return dwRet;
@ -209,7 +220,7 @@ LONG RegSetValue(HKEY hKey, LPCSTR lpSubKey, DWORD dwType,
if (lpKey->lpValue != NULL) free(lpKey->lpValue); if (lpKey->lpValue != NULL) free(lpKey->lpValue);
lpKey->lpValue = malloc(strlen(lpVal) + 1); lpKey->lpValue = malloc(strlen(lpVal) + 1);
strcpy(lpKey->lpValue, lpVal); 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; 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 (lpSubKey == NULL) return ERROR_INVALID_PARAMETER;
if (lpVal == NULL) return ERROR_INVALID_PARAMETER; if (lpVal == NULL) return ERROR_INVALID_PARAMETER;
if (lpcb == 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) { if ((dwRet = RegOpenKey(hKey, lpSubKey, &hRetKey)) != ERROR_SUCCESS) {
fprintf(stderr, "RegQueryValue // key not found !\n"); fprintf(stderr, "RegQueryValue // key not found !\n");
return dwRet; return dwRet;
@ -235,14 +248,17 @@ LONG RegQueryValue(HKEY hKey, LPCSTR lpSubKey, LPSTR lpVal, LONG FAR *lpcb)
lpKey = (LPKEYSTRUCT)GlobalLock(hRetKey); lpKey = (LPKEYSTRUCT)GlobalLock(hRetKey);
if (lpKey == NULL) return ERROR_BADKEY; if (lpKey == NULL) return ERROR_BADKEY;
if (lpKey->lpValue != NULL) { if (lpKey->lpValue != NULL) {
size = min(strlen(lpKey->lpValue), *lpcb); if ((size = strlen(lpKey->lpValue)+1) > *lpcb){
strncpy(lpVal, lpKey->lpValue, size); strncpy(lpVal,lpKey->lpValue,*lpcb-1);
*lpcb = (LONG)size; lpVal[*lpcb-1] = 0;
} } else {
else { strcpy(lpVal,lpKey->lpValue);
lpVal[0] = '\0'; *lpcb = size;
*lpcb = (LONG)0; }
} } else {
*lpVal = 0;
*lpcb = (LONG)1;
}
dprintf_reg(stddeb,"RegQueryValue // return '%s' !\n", lpVal); dprintf_reg(stddeb,"RegQueryValue // return '%s' !\n", lpVal);
return ERROR_SUCCESS; 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) 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; return ERROR_INVALID_PARAMETER;
} }
@ -340,7 +386,9 @@ INT ShellAbout(HWND hWnd, LPCSTR szApp, LPCSTR szOtherStuff, HICON hIcon)
else else
*AppMisc = 0; *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);
} }

View file

@ -23,6 +23,7 @@ WineRelocatableTarget($(MODULE),,$(RCOBJS))
$(RCOBJS): winerc $(TOP)/include/windows.h $(RCOBJS): winerc $(TOP)/include/windows.h
includes:: includes::
touch $(RCSRCS:.rc=.h)
clean:: clean::
$(RM) $(RCSRCS:.rc=.c) $(RCSRCS:.rc=.h) $(RM) $(RCSRCS:.rc=.c) $(RCSRCS:.rc=.h)

View file

@ -757,8 +757,10 @@ int main(int argc, char **argv)
sprintf(filename, "dll_%s.S", LowerDLLName); sprintf(filename, "dll_%s.S", LowerDLLName);
fp = fopen(filename, "w"); fp = fopen(filename, "w");
#ifdef __ELF__
fprintf (fp, "#define __ASSEMBLY__\n"); fprintf (fp, "#define __ASSEMBLY__\n");
fprintf (fp, "#include <asm/segment.h>\n"); fprintf (fp, "#include <asm/segment.h>\n");
#endif
fprintf(fp, "\t.globl " PREFIX "%s_Dispatch\n", UpperDLLName); fprintf(fp, "\t.globl " PREFIX "%s_Dispatch\n", UpperDLLName);
fprintf(fp, PREFIX "%s_Dispatch:\n", UpperDLLName); fprintf(fp, PREFIX "%s_Dispatch:\n", UpperDLLName);
fprintf(fp, "\tandl\t$0x0000ffff,%%esp\n"); fprintf(fp, "\tandl\t$0x0000ffff,%%esp\n");

View file

@ -82,7 +82,6 @@ HCURSOR LoadCursor(HANDLE instance, LPSTR cursor_name)
lpcur = (CURSORALLOC *)GlobalLock(hCursor); lpcur = (CURSORALLOC *)GlobalLock(hCursor);
memset(lpcur, 0, sizeof(CURSORALLOC)); memset(lpcur, 0, sizeof(CURSORALLOC));
if (instance == (HANDLE)NULL) { if (instance == (HANDLE)NULL) {
instance = hSysRes;
switch((LONG)cursor_name) { switch((LONG)cursor_name) {
case IDC_ARROW: case IDC_ARROW:
lpcur->xcursor = XCreateFontCursor(display, XC_top_left_arrow); lpcur->xcursor = XCreateFontCursor(display, XC_top_left_arrow);

View file

@ -283,23 +283,13 @@ LONG MDIMaximizeChild(HWND parent, HWND child, MDICLIENTINFO *ci)
LONG MDIRestoreChild(HWND parent, MDICLIENTINFO *ci) LONG MDIRestoreChild(HWND parent, MDICLIENTINFO *ci)
{ {
HWND child; HWND child;
WND *w = WIN_FindWndPtr(parent);
LPRECT lprect = &ci->rectRestore;
dprintf_mdi(stddeb,"restoring mdi child\n"); dprintf_mdi(stddeb,"restoring mdi child\n");
child = ci->hwndActiveChild; 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; ci->flagChildMaximized = FALSE;
ShowWindow(child, SW_RESTORE); /* display the window */ ShowWindow(child, SW_RESTORE); /* display the window */
SendMessage(GetParent(parent), WM_NCPAINT, 0, 0);
MDIBringChildToTop(parent, child, FALSE, FALSE); MDIBringChildToTop(parent, child, FALSE, FALSE);
return 0; return 0;

View file

@ -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 * NC_HandleNCCalcSize
* *
@ -841,7 +917,7 @@ static void NC_DoSizeMove( HWND hwnd, WORD wParam, POINT pt )
/* Get min/max info */ /* Get min/max info */
WINPOS_GetMinMaxInfo( hwnd, NULL, NULL, &minTrack, &maxTrack ); NC_GetMinMaxInfo( hwnd, NULL, NULL, &minTrack, &maxTrack );
sizingRect = wndPtr->rectWindow; sizingRect = wndPtr->rectWindow;
if (wndPtr->dwStyle & WS_CHILD) if (wndPtr->dwStyle & WS_CHILD)
GetClientRect( wndPtr->hwndParent, &mouseRect ); GetClientRect( wndPtr->hwndParent, &mouseRect );
@ -1162,7 +1238,8 @@ LONG NC_HandleNCLButtonDblClk( HWND hwnd, WORD wParam, LONG lParam )
switch(wParam) /* Hit test */ switch(wParam) /* Hit test */
{ {
case HTCAPTION: case HTCAPTION:
SendMessage( hwnd, WM_SYSCOMMAND, SC_MAXIMIZE, lParam ); SendMessage( hwnd, WM_SYSCOMMAND,
IsZoomed(hwnd) ? SC_RESTORE : SC_MAXIMIZE, lParam );
break; break;
case HTSYSMENU: case HTSYSMENU:
@ -1239,7 +1316,7 @@ LONG NC_HandleSysCommand( HWND hwnd, WORD wParam, POINT pt )
case SC_SCREENSAVE: case SC_SCREENSAVE:
if (wParam == SC_ABOUTWINE) if (wParam == SC_ABOUTWINE)
{ extern char sysres_DIALOG_2[]; { extern char sysres_DIALOG_2[];
DialogBoxIndirectPtr( hSysRes, sysres_DIALOG_2, DialogBoxIndirectPtr( wndPtr->hInstance, sysres_DIALOG_2,
hwnd, (WNDPROC)AboutWine_Proc ); hwnd, (WNDPROC)AboutWine_Proc );
} }
break; break;

View file

@ -1,7 +1,7 @@
/* /*
* Window painting functions * Window painting functions
* *
* Copyright 1993 Alexandre Julliard * Copyright 1993, 1994, 1995 Alexandre Julliard
*/ */
#include <stdio.h> #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) * RedrawWindow (USER.290)
*/ */
BOOL RedrawWindow( HWND hwnd, LPRECT rectUpdate, HRGN hrgnUpdate, UINT flags ) BOOL RedrawWindow( HWND hwnd, LPRECT rectUpdate, HRGN hrgnUpdate, UINT flags )
{ {
HRGN tmpRgn, hrgn = 0; HRGN tmpRgn, hrgn;
RECT rectClient, rectWindow; RECT rectClient;
WND * wndPtr; WND * wndPtr;
if (!hwnd) hwnd = GetDesktopWindow(); if (!hwnd) hwnd = GetDesktopWindow();
@ -129,111 +139,68 @@ BOOL RedrawWindow( HWND hwnd, LPRECT rectUpdate, HRGN hrgnUpdate, UINT flags )
hwnd, hrgnUpdate, flags); hwnd, hrgnUpdate, flags);
} }
GetClientRect( hwnd, &rectClient ); GetClientRect( hwnd, &rectClient );
rectWindow = wndPtr->rectWindow;
OffsetRect(&rectWindow, -wndPtr->rectClient.left, -wndPtr->rectClient.top);
if (flags & RDW_INVALIDATE) /* Invalidate */ if (flags & RDW_INVALIDATE) /* Invalidate */
{ {
if (hrgnUpdate) /* Invalidate a region */ if (wndPtr->hrgnUpdate) /* Is there already an update region? */
{ {
if (flags & RDW_FRAME) tmpRgn = CreateRectRgnIndirect(&rectWindow); tmpRgn = CreateRectRgn( 0, 0, 0, 0 );
else tmpRgn = CreateRectRgnIndirect( &rectClient ); if ((hrgn = hrgnUpdate) == 0)
if (!tmpRgn) return FALSE; hrgn = CreateRectRgnIndirect( rectUpdate ? rectUpdate :
hrgn = CreateRectRgn( 0, 0, 0, 0 ); &rectClient );
if (CombineRgn( hrgn, hrgnUpdate, tmpRgn, RGN_AND ) == NULLREGION) CombineRgn( tmpRgn, wndPtr->hrgnUpdate, hrgn, RGN_OR );
{ DeleteObject( wndPtr->hrgnUpdate );
DeleteObject( hrgn ); wndPtr->hrgnUpdate = tmpRgn;
hrgn = 0; if (!hrgnUpdate) DeleteObject( hrgn );
} }
DeleteObject( tmpRgn ); else /* No update region yet */
} {
else /* Invalidate a rectangle */ if (!(wndPtr->flags & WIN_INTERNAL_PAINT))
{ MSG_IncPaintCount( wndPtr->hmemTaskQ );
RECT rect; if (hrgnUpdate)
if (flags & RDW_FRAME) {
{ wndPtr->hrgnUpdate = CreateRectRgn( 0, 0, 0, 0 );
if (rectUpdate) IntersectRect( &rect, rectUpdate, &rectWindow); CombineRgn( wndPtr->hrgnUpdate, hrgnUpdate, 0, RGN_COPY );
else rect = rectWindow; }
} else wndPtr->hrgnUpdate = CreateRectRgnIndirect( rectUpdate ?
else rectUpdate : &rectClient );
{ }
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 (flags & RDW_FRAME) wndPtr->flags |= WIN_NEEDS_NCPAINT; if (flags & RDW_FRAME) wndPtr->flags |= WIN_NEEDS_NCPAINT;
if (flags & RDW_ERASE) wndPtr->flags |= WIN_NEEDS_ERASEBKGND; if (flags & RDW_ERASE) wndPtr->flags |= WIN_NEEDS_ERASEBKGND;
flags |= RDW_FRAME; /* Force invalidating the frame of children */ flags |= RDW_FRAME; /* Force invalidating the frame of children */
} }
else if (flags & RDW_VALIDATE) /* Validate */ else if (flags & RDW_VALIDATE) /* Validate */
{ {
if (flags & RDW_NOERASE) wndPtr->flags &= ~WIN_NEEDS_ERASEBKGND; /* We need an update region in order to validate anything */
if (!(hrgn = CreateRectRgn( 0, 0, 0, 0 ))) return FALSE; if (wndPtr->hrgnUpdate)
{
/* Remove frame from update region */ if (!hrgnUpdate && !rectUpdate)
{
if (wndPtr->hrgnUpdate && (flags & RDW_NOFRAME)) /* Special case: validate everything */
{ DeleteObject( wndPtr->hrgnUpdate );
if (!(tmpRgn = CreateRectRgnIndirect( &rectClient ))) wndPtr->hrgnUpdate = 0;
return FALSE; }
if (CombineRgn(hrgn,tmpRgn,wndPtr->hrgnUpdate,RGN_AND) == NULLREGION) else
{ {
DeleteObject( hrgn ); tmpRgn = CreateRectRgn( 0, 0, 0, 0 );
hrgn = 0; if ((hrgn = hrgnUpdate) == 0)
} hrgn = CreateRectRgnIndirect( rectUpdate );
DeleteObject( tmpRgn ); if (CombineRgn( tmpRgn, wndPtr->hrgnUpdate,
DeleteObject( wndPtr->hrgnUpdate ); hrgn, RGN_DIFF ) == NULLREGION)
wndPtr->hrgnUpdate = hrgn; {
hrgn = CreateRectRgn( 0, 0, 0, 0 ); DeleteObject( tmpRgn );
} tmpRgn = 0;
}
/* Set update region */ DeleteObject( wndPtr->hrgnUpdate );
wndPtr->hrgnUpdate = tmpRgn;
if (wndPtr->hrgnUpdate) if (!hrgnUpdate) DeleteObject( hrgn );
{ }
int res; if (!wndPtr->hrgnUpdate) /* No more update region */
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;
if (!(wndPtr->flags & WIN_INTERNAL_PAINT)) if (!(wndPtr->flags & WIN_INTERNAL_PAINT))
MSG_DecPaintCount( wndPtr->hmemTaskQ ); 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 */ /* 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 ) int GetUpdateRgn( HWND hwnd, HRGN hrgn, BOOL erase )
{ {
HRGN hrgnClip;
int retval; int retval;
WND * wndPtr = WIN_FindWndPtr( hwnd ); WND * wndPtr = WIN_FindWndPtr( hwnd );
if (!wndPtr) return ERROR; if (!wndPtr) return ERROR;
@ -403,13 +369,8 @@ int GetUpdateRgn( HWND hwnd, HRGN hrgn, BOOL erase )
SetRectRgn( hrgn, 0, 0, 0, 0 ); SetRectRgn( hrgn, 0, 0, 0, 0 );
return NULLREGION; return NULLREGION;
} }
hrgnClip = CreateRectRgn( 0, 0, retval = CombineRgn( hrgn, wndPtr->hrgnUpdate, 0, RGN_COPY );
wndPtr->rectClient.right-wndPtr->rectClient.left,
wndPtr->rectClient.bottom-wndPtr->rectClient.top);
if (!hrgnClip) return ERROR;
retval = CombineRgn( hrgn, wndPtr->hrgnUpdate, hrgnClip, RGN_AND );
if (erase) RedrawWindow( hwnd, NULL, 0, RDW_ERASENOW | RDW_NOCHILDREN ); if (erase) RedrawWindow( hwnd, NULL, 0, RDW_ERASENOW | RDW_NOCHILDREN );
DeleteObject( hrgnClip );
return retval; return retval;
} }

View file

@ -400,7 +400,7 @@ HWND CreateWindowEx( DWORD exStyle, LPSTR className, LPSTR windowName,
/* Send the WM_GETMINMAXINFO message and fix the size if needed */ /* 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) if ( maxSize.x < width)
{ {
@ -532,6 +532,21 @@ BOOL DestroyWindow( HWND hwnd )
ReleaseCapture(); ReleaseCapture();
WIN_SendParentNotify( hwnd, WM_DESTROY, MAKELONG(hwnd, wndPtr->wIDmenu) ); 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 */ /* Send destroy messages and destroy children */
SendMessage( hwnd, WM_DESTROY, 0, 0 ); SendMessage( hwnd, WM_DESTROY, 0, 0 );
@ -560,7 +575,6 @@ void CloseWindow(HWND hWnd)
} }
/*********************************************************************** /***********************************************************************
* OpenIcon (USER.44) * OpenIcon (USER.44)
*/ */
@ -572,7 +586,6 @@ BOOL OpenIcon(HWND hWnd)
} }
/*********************************************************************** /***********************************************************************
* FindWindow (USER.50) * FindWindow (USER.50)
*/ */

View file

@ -1,7 +1,7 @@
/* /*
* Window position related functions. * Window position related functions.
* *
* Copyright 1993, 1994 Alexandre Julliard * Copyright 1993, 1994, 1995 Alexandre Julliard
*/ */
#include "sysmetrics.h" #include "sysmetrics.h"
@ -9,6 +9,7 @@
#include "win.h" #include "win.h"
#include "message.h" #include "message.h"
#include "winpos.h" #include "winpos.h"
#include "nonclient.h"
#include "stddebug.h" #include "stddebug.h"
/* #define DEBUG_WIN */ /* #define DEBUG_WIN */
#include "debug.h" #include "debug.h"
@ -16,6 +17,95 @@
static HWND hwndActive = 0; /* Currently active window */ 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) * GetWindowRect (USER.32)
*/ */
@ -99,6 +189,7 @@ HWND WindowFromPoint( POINT pt )
return hwndRet; return hwndRet;
} }
/******************************************************************* /*******************************************************************
* ChildWindowFromPoint (USER.191) * ChildWindowFromPoint (USER.191)
*/ */
@ -187,6 +278,7 @@ HWND GetActiveWindow()
return hwndActive; return hwndActive;
} }
/******************************************************************* /*******************************************************************
* SetActiveWindow (USER.59) * SetActiveWindow (USER.59)
*/ */
@ -229,84 +321,126 @@ BOOL ShowWindow( HWND hwnd, int cmd )
{ {
WND * wndPtr = WIN_FindWndPtr( hwnd ); WND * wndPtr = WIN_FindWndPtr( hwnd );
BOOL wasVisible; BOOL wasVisible;
BOOL wasIconic; POINT maxSize;
int swpflags = 0; int swpflags = 0;
short x = 0, y = 0, cx = 0, cy = 0;
if (!wndPtr) return FALSE; if (!wndPtr) return FALSE;
dprintf_win(stddeb,"ShowWindow: hwnd=%04X, cmd=%d\n", hwnd, cmd); 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; wasVisible = (wndPtr->dwStyle & WS_VISIBLE) != 0;
switch(cmd) switch(cmd)
{ {
case SW_HIDE: 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 | swpflags |= SWP_HIDEWINDOW | SWP_NOSIZE | SWP_NOMOVE |
SWP_NOACTIVATE | SWP_NOZORDER; SWP_NOACTIVATE | SWP_NOZORDER;
break; break;
case SW_SHOWMINNOACTIVE: case SW_SHOWMINNOACTIVE:
swpflags |= SWP_NOACTIVATE | SWP_NOZORDER;
/* fall through */
case SW_SHOWMINIMIZED: case SW_SHOWMINIMIZED:
case SW_MINIMIZE: swpflags |= SWP_SHOWWINDOW;
wndPtr->dwStyle |= WS_MINIMIZE; /* fall through */
swpflags |= SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE | case SW_MINIMIZE:
SWP_NOACTIVATE | SWP_NOZORDER; swpflags |= SWP_FRAMECHANGED;
if (!(wndPtr->dwStyle & WS_MINIMIZE))
/* store the size and position of the window, so we can {
* deiconify it to the same size and position if (wndPtr->dwStyle & WS_MAXIMIZE)
*/ {
wndPtr->rectNormal = wndPtr->rectWindow; wndPtr->flags |= WIN_RESTORE_MAX;
wndPtr->ptIconPos.x = wndPtr->rectWindow.left; wndPtr->dwStyle &= ~WS_MAXIMIZE;
wndPtr->ptIconPos.y = wndPtr->rectWindow.top; }
/* move the window to icon size and position and else
* tell it that it is going to have to be painted {
*/ wndPtr->flags &= ~WIN_RESTORE_MAX;
MoveWindow(hwnd, wndPtr->ptIconPos.x, wndPtr->ptIconPos.y, wndPtr->rectNormal = wndPtr->rectWindow;
SYSMETRICS_CXICON, SYSMETRICS_CYICON, FALSE); }
RedrawWindow( hwnd, NULL, 0, RDW_FRAME | RDW_ERASE | RDW_ERASENOW); 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; break;
case SW_SHOWNA:
case SW_SHOWMAXIMIZED: /* same as SW_MAXIMIZE: */ 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: case SW_SHOW:
swpflags |= SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE; swpflags |= SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE;
break; break;
case SW_SHOWNORMAL: /* same as SW_NORMAL: */
case SW_SHOWNOACTIVATE: case SW_SHOWNOACTIVATE:
swpflags |= SWP_NOZORDER;
if (GetActiveWindow()) swpflags |= SWP_NOACTIVATE;
/* fall through */
case SW_SHOWNORMAL: /* same as SW_NORMAL: */
case SW_RESTORE: case SW_RESTORE:
wasIconic = IsIconic(hwnd); swpflags |= SWP_SHOWWINDOW | SWP_FRAMECHANGED;
wndPtr->dwStyle &= ~WS_MINIMIZE; if (wndPtr->dwStyle & WS_MINIMIZE)
wndPtr->dwStyle &= ~WS_MAXIMIZE; {
swpflags |= SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE; wndPtr->ptIconPos.x = wndPtr->rectWindow.left;
if (cmd == SW_SHOWNOACTIVATE) wndPtr->ptIconPos.y = wndPtr->rectWindow.top;
{ wndPtr->dwStyle &= ~WS_MINIMIZE;
swpflags |= SWP_NOZORDER; if (wndPtr->flags & WIN_RESTORE_MAX)
if (GetActiveWindow()) swpflags |= SWP_NOACTIVATE; {
} /* Restore to maximized position */
if (wasIconic) { NC_GetMinMaxInfo( hwnd, &maxSize, &wndPtr->ptMaxPos,
MoveWindow(hwnd, wndPtr->rectNormal.left, NULL, NULL );
wndPtr->rectNormal.top, x = wndPtr->ptMaxPos.x;
wndPtr->rectNormal.right - wndPtr->rectNormal.left, y = wndPtr->ptMaxPos.y;
wndPtr->rectNormal.bottom - wndPtr->rectNormal.top, cx = maxSize.x;
FALSE); 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; break;
} }
SendMessage( hwnd, WM_SHOWWINDOW, (cmd != SW_HIDE), 0 ); 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 */ /* Send WM_SIZE and WM_MOVE messages if not already done */
if (!(wndPtr->flags & WIN_GOT_SIZEMSG)) 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 * WINPOS_ChangeActiveWindow
* *
@ -543,7 +633,7 @@ LONG WINPOS_HandleWindowPosChanging( WINDOWPOS *winpos )
if ((wndPtr->dwStyle & WS_THICKFRAME) || if ((wndPtr->dwStyle & WS_THICKFRAME) ||
(wndPtr->dwStyle & (WS_POPUP | WS_CHILD) == 0)) (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->cx = min( winpos->cx, maxSize.x );
winpos->cy = min( winpos->cy, maxSize.y ); 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. * Move a window in Z order, invalidating everything that needs it.
* Only necessary for windows without associated X window. * 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; BOOL movingUp;
HWND hwndCur; HWND hwndCur;
@ -603,7 +693,7 @@ static void WINPOS_MoveWindowZOrder( HWND hwnd, HWND hwndAfter, BOOL erase )
OffsetRect( &rect, -wndPtr->rectClient.left, OffsetRect( &rect, -wndPtr->rectClient.left,
-wndPtr->rectClient.top ); -wndPtr->rectClient.top );
RedrawWindow( hwnd, &rect, 0, RDW_INVALIDATE | RDW_ALLCHILDREN | RedrawWindow( hwnd, &rect, 0, RDW_INVALIDATE | RDW_ALLCHILDREN |
RDW_FRAME | RDW_ERASE | (erase ? RDW_ERASENOW : 0) ); RDW_FRAME | RDW_ERASE );
hwndCur = curPtr->hwndNext; hwndCur = curPtr->hwndNext;
} }
} }
@ -619,13 +709,54 @@ static void WINPOS_MoveWindowZOrder( HWND hwnd, HWND hwndAfter, BOOL erase )
OffsetRect( &rect, -curPtr->rectClient.left, OffsetRect( &rect, -curPtr->rectClient.left,
-curPtr->rectClient.top ); -curPtr->rectClient.top );
RedrawWindow( hwndCur, &rect, 0, RDW_INVALIDATE | RDW_ALLCHILDREN | RedrawWindow( hwndCur, &rect, 0, RDW_INVALIDATE | RDW_ALLCHILDREN |
RDW_FRAME | RDW_ERASE | (erase ? RDW_ERASENOW : 0) ); RDW_FRAME | RDW_ERASE );
hwndCur = curPtr->hwndNext; 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 * WINPOS_InternalSetWindowPos
* *
@ -637,8 +768,6 @@ static BOOL WINPOS_InternalSetWindowPos( WINDOWPOS *winpos )
WND *wndPtr; WND *wndPtr;
RECT newWindowRect, newClientRect; RECT newWindowRect, newClientRect;
int flags, result; int flags, result;
int changeMask = 0;
XWindowChanges winChanges;
/* Send WM_WINDOWPOSCHANGING message */ /* Send WM_WINDOWPOSCHANGING message */
@ -657,13 +786,20 @@ static BOOL WINPOS_InternalSetWindowPos( WINDOWPOS *winpos )
/* Check flags */ /* 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; flags = winpos->flags;
if (winpos->hwnd == hwndActive) flags |= SWP_NOACTIVATE; /*Already active*/
/* Check hwndAfter */ /* Check hwndAfter */
hwndAfter = winpos->hwndInsertAfter; hwndAfter = winpos->hwndInsertAfter;
if (!(flags & (SWP_NOZORDER | SWP_NOACTIVATE))) if (!(winpos->flags & (SWP_NOZORDER | SWP_NOACTIVATE)))
{ {
/* Ignore TOPMOST flags when activating a window */ /* Ignore TOPMOST flags when activating a window */
/* _and_ moving it in Z order. */ /* _and_ moving it in Z order. */
@ -676,72 +812,36 @@ static BOOL WINPOS_InternalSetWindowPos( WINDOWPOS *winpos )
/* hwndAfter must be a sibling of the window */ /* hwndAfter must be a sibling of the window */
if ((hwndAfter != HWND_TOP) && (hwndAfter != HWND_BOTTOM) && if ((hwndAfter != HWND_TOP) && (hwndAfter != HWND_BOTTOM) &&
(GetParent(winpos->hwnd) != GetParent(hwndAfter))) return FALSE; (GetParent(winpos->hwnd) != GetParent(hwndAfter))) return FALSE;
winpos->hwndInsertAfter = hwndAfter;
/* Calculate new position and size */ /* Calculate new position and size */
newWindowRect = wndPtr->rectWindow; newWindowRect = wndPtr->rectWindow;
newClientRect = wndPtr->rectClient; newClientRect = wndPtr->rectClient;
if (!(flags & SWP_NOSIZE)) if (!(winpos->flags & SWP_NOSIZE))
{ {
if ((newWindowRect.right != newWindowRect.left + winpos->cx) || newWindowRect.right = newWindowRect.left + winpos->cx;
(newWindowRect.bottom != newWindowRect.top + winpos->cy)) 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;
} }
if (!(flags & SWP_NOMOVE)) if (!(winpos->flags & SWP_NOMOVE))
{ {
if ((newWindowRect.left != winpos->x) || newWindowRect.left = winpos->x;
(newWindowRect.top != winpos->y)) newWindowRect.top = winpos->y;
{ newWindowRect.right += winpos->x - wndPtr->rectWindow.left;
newWindowRect.left = winpos->x; newWindowRect.bottom += winpos->y - wndPtr->rectWindow.top;
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;
} }
/* Reposition window in Z order */ /* Reposition window in Z order */
if (!(flags & SWP_NOZORDER)) if (!(winpos->flags & SWP_NOZORDER))
{ {
if (wndPtr->window) if (wndPtr->window)
{ {
WIN_UnlinkWindow( winpos->hwnd ); WIN_UnlinkWindow( winpos->hwnd );
WIN_LinkWindow( winpos->hwnd, hwndAfter ); 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, else WINPOS_MoveWindowZOrder( winpos->hwnd, hwndAfter );
!(flags & SWP_DEFERERASE) );
} }
/* Send WM_NCCALCSIZE message to get new client area */ /* Send WM_NCCALCSIZE message to get new client area */
@ -755,8 +855,7 @@ static BOOL WINPOS_InternalSetWindowPos( WINDOWPOS *winpos )
if (wndPtr->window) if (wndPtr->window)
{ {
if (changeMask) XConfigureWindow( display, wndPtr->window, WINPOS_SetXWindowPos( winpos );
changeMask, &winChanges );
wndPtr->rectWindow = newWindowRect; wndPtr->rectWindow = newWindowRect;
wndPtr->rectClient = newClientRect; wndPtr->rectClient = newClientRect;
} }
@ -767,20 +866,21 @@ static BOOL WINPOS_InternalSetWindowPos( WINDOWPOS *winpos )
wndPtr->rectWindow = newWindowRect; wndPtr->rectWindow = newWindowRect;
wndPtr->rectClient = newClientRect; wndPtr->rectClient = newClientRect;
if (changeMask) if (!(flags & SWP_NOREDRAW) &&
(!(flags & SWP_NOSIZE) || !(flags & SWP_NOMOVE) ||
!(flags & SWP_NOZORDER)))
{ {
HRGN hrgn1 = CreateRectRgnIndirect( &oldWindowRect ); HRGN hrgn1 = CreateRectRgnIndirect( &oldWindowRect );
HRGN hrgn2 = CreateRectRgnIndirect( &wndPtr->rectWindow ); HRGN hrgn2 = CreateRectRgnIndirect( &wndPtr->rectWindow );
HRGN hrgn3 = CreateRectRgn( 0, 0, 0, 0 ); HRGN hrgn3 = CreateRectRgn( 0, 0, 0, 0 );
CombineRgn( hrgn3, hrgn1, hrgn2, RGN_DIFF ); CombineRgn( hrgn3, hrgn1, hrgn2, RGN_DIFF );
RedrawWindow( wndPtr->hwndParent, NULL, hrgn3, RedrawWindow( wndPtr->hwndParent, NULL, hrgn3,
RDW_INVALIDATE | RDW_ALLCHILDREN | RDW_INVALIDATE | RDW_ALLCHILDREN | RDW_ERASE );
RDW_ERASE | RDW_ERASENOW );
if ((oldWindowRect.left != wndPtr->rectWindow.left) || if ((oldWindowRect.left != wndPtr->rectWindow.left) ||
(oldWindowRect.top != wndPtr->rectWindow.top)) (oldWindowRect.top != wndPtr->rectWindow.top))
{ {
RedrawWindow( winpos->hwnd, NULL, 0, RDW_INVALIDATE | RedrawWindow( winpos->hwnd, NULL, 0, RDW_INVALIDATE |
RDW_FRAME | RDW_ALLCHILDREN | RDW_ERASE | RDW_ERASENOW ); RDW_FRAME | RDW_ALLCHILDREN | RDW_ERASE );
} }
DeleteObject( hrgn1 ); DeleteObject( hrgn1 );
DeleteObject( hrgn2 ); DeleteObject( hrgn2 );
@ -797,8 +897,9 @@ static BOOL WINPOS_InternalSetWindowPos( WINDOWPOS *winpos )
} }
else else
{ {
RedrawWindow( winpos->hwnd, NULL, 0, if (!(flags & SWP_NOREDRAW))
RDW_INVALIDATE | RDW_FRAME | RDW_ERASE ); RedrawWindow( winpos->hwnd, NULL, 0,
RDW_INVALIDATE | RDW_FRAME | RDW_ERASE );
} }
} }
else if (flags & SWP_HIDEWINDOW) else if (flags & SWP_HIDEWINDOW)
@ -810,9 +911,10 @@ static BOOL WINPOS_InternalSetWindowPos( WINDOWPOS *winpos )
} }
else else
{ {
RedrawWindow( wndPtr->hwndParent, &wndPtr->rectWindow, 0, if (!(flags & SWP_NOREDRAW))
RDW_INVALIDATE | RDW_FRAME | RedrawWindow( wndPtr->hwndParent, &wndPtr->rectWindow, 0,
RDW_ALLCHILDREN | RDW_ERASE | RDW_ERASENOW ); RDW_INVALIDATE | RDW_FRAME |
RDW_ALLCHILDREN | RDW_ERASE );
} }
if ((winpos->hwnd == GetFocus()) || IsChild(winpos->hwnd, GetFocus())) if ((winpos->hwnd == GetFocus()) || IsChild(winpos->hwnd, GetFocus()))
SetFocus( GetParent(winpos->hwnd) ); /* Revert focus to parent */ SetFocus( GetParent(winpos->hwnd) ); /* Revert focus to parent */
@ -840,15 +942,17 @@ static BOOL WINPOS_InternalSetWindowPos( WINDOWPOS *winpos )
/* Repaint the window */ /* Repaint the window */
if (wndPtr->window) MSG_Synchronize(); /* Wait for all expose events */ 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, RedrawWindow( winpos->hwnd, NULL, 0,
RDW_INVALIDATE | RDW_FRAME | RDW_ERASE ); RDW_INVALIDATE | RDW_FRAME | RDW_ERASE );
RedrawWindow( winpos->hwnd, NULL, 0, if (!(flags & SWP_DEFERERASE))
(flags & SWP_NOREDRAW) ? RDW_VALIDATE : RDW_ERASENOW ); RedrawWindow( wndPtr->hwndParent, NULL, 0,
RDW_ALLCHILDREN | RDW_ERASENOW );
/* And last, send the WM_WINDOWPOSCHANGED message */ /* 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; return TRUE;
} }
@ -996,12 +1100,3 @@ void CascadeChildWindows( HWND parent, WORD action )
{ {
printf("STUB CascadeChildWindows(%04X, %d)\n", parent, action); printf("STUB CascadeChildWindows(%04X, %d)\n", parent, action);
} }
/***********************************************************************
* ArrangeIconicWindows (USER.170)
*/
WORD ArrangeIconicWindows( HWND parent )
{
printf("STUB ArrangeIconicWindows(%04X)\n", parent);
return 0;
}