Release 960811

Sun Aug 11 13:00:20 1996  Alexandre Julliard  <julliard@lrc.epfl.ch>

	* [configure.in] [include/acconfig.h] [tools/build.c]
	Added check for underscore on external symbols.

	* [memory/selector.c] [memory/global.c]
	Fixed FreeSelector() to free only one selector.
	Added SELECTOR_FreeBlock() to free an array of selectors.

	* [objects/color.c]
	Fixed a bug in COLOR_ToLogical() that caused GetPixel() to fail on
	hi-color displays.

	* [tools/build.c] [if1632/crtdll.spec]
	Added 'extern' type, used for external variables or functions.

	* [windows/winpos.c]
	Allow de-activating a window in WINPOS_ChangeActiveWindow().

	* [windows/winproc.c]
	Added 32-to-16 translation for button messages.
	Fixed WINPROC_GetPtr() to avoid crashes on 32-bit procedures that
	happen to be valid SEGPTRs.

Sat Aug 10 18:22:25 1996  Albrecht Kleine  <kleine@ak.sax.de>

	* [windows/message.c]
	Removed a FIXME in MSG_PeekHardwareMsg(): produces correct 
	data for the JOURNALRECORD-hook (using EVENTMSG16 structure).

	* [if1632/gdi.spec] [include/windows.h] [objects/metafile.c]
	Introduced undocumented API function IsValidMetaFile(), plus a
 	minor fix in last patch of CopyMetaFile().

	* [objects/gdiobj.c]
	Removed a FIXME in IsGDIObject(): added magic word check.

Sun Aug 10 18:10:10 1996  Bruce Milner <Bruce.Milner@genetics.utah.edu>

	* [controls/statuswin.c]
	First pass at implementing the StatusWindow class.

	* [include/commctrl.h]
	Header file for common controls.

	* [controls/widgets.c]
	Added InitCommonControls().

	* [if1632/comctl32.spec]
	Add DrawStatusTextA, CreateStatusWindowA, InitCommonControls.

	* [win32/findfile.c] [if1632/kernel32.spec]
	Add FindNextFile32A, FindClose.
	Modified FindFirstFile32A so it works with FindNextFile32A.

	* [include/winbase.h]
	Fixed WIN32_FIND_DATA structure member names.

Sat Aug 10 09:00:00 1996  Alex Korobka <alex@phm30.pharm.sunysb.edu>

	* [windows/scroll.c]
	Changed scrolling routines to benefit from DCE code update.

Thu Aug  8 18:05:09 1996  Marcus Meissner <msmeissn@cip.informatik.uni-erlangen.de>

	* [files/file.c]
	SearchPath* could get NULL for lastpart argument.

	* [if1632/build-spec.txt] [documentation/debugging]
	Varargs documentation added, debugging hints updated.

	* [if1632/crtdll.spec][misc/crtdll.c][misc/Makefile.in]
	Started to implement CRTDLL.

	* [if1632/wsock32.spec]
	Some thunks to standard libc functions (structures have the same
 	elements, but perhaps wrong offset due to packing).

	* [include/kernel32.h][include/windows.h][win32/*.c][loader/main.c]
	Merged kernel32.h into windows.h.

	* [misc/lstr.c]
	Enhanced FormatMessage().

	* [misc/main.c] [if1632/kernel.spec] [include/windows.h]
	GetVersion() updated to new naming standard.
	Changed language handling to support language ids.

	* [misc/shell.c]
	Enhanced FindExecutable, so it finds files in the search path too.

	* [win32/environment.c]
	GetCommandLine* updated.

	* [loader/resource.c] [loader/pe_resource.c]
	FindResourceEx32* added.
	Loading of messagetables added.
	Language handling now uses Wine default language id.
diff --git a/controls/Makefile.in b/controls/Makefile.in
index 6dde058..0b99780 100644
--- a/controls/Makefile.in
+++ b/controls/Makefile.in
@@ -11,6 +11,7 @@
 	menu.c \
 	scroll.c \
 	static.c \
+	status.c \
 	widgets.c
 
 all: $(MODULE).o
diff --git a/controls/combo.c b/controls/combo.c
index d7563a9..213a3e3 100644
--- a/controls/combo.c
+++ b/controls/combo.c
@@ -163,7 +163,7 @@
      lphc->RectButton.bottom = lphc->RectButton.top + lphl->StdItemHeight;
      SetWindowPos(hwnd, 0, 0, 0, rect.right -rect.left + 2*SYSMETRICS_CXBORDER,
 		 lphl->StdItemHeight + 2*SYSMETRICS_CYBORDER,
-		 SWP_NOMOVE | SWP_NOZORDER | SWP_NOSENDCHANGING);
+		 SWP_NOMOVE | SWP_NOZORDER | SWP_NOSENDCHANGING | SWP_NOACTIVATE);
      dprintf_combo(stddeb,(cstyle & 3)==CBS_DROPDOWN ? "CBS_DROPDOWN\n": "CBS_DROPDOWNLIST\n");
      break;
      
@@ -615,7 +615,8 @@
     lphc->DropDownVisible = wParam;
     GetWindowRect32(hwnd,&rect);
     SetWindowPos(lphc->hWndLBox, 0, rect.left, rect.top+lphc->LBoxTop, 0, 0,
-		 SWP_NOSIZE | (wParam ? SWP_SHOWWINDOW : SWP_HIDEWINDOW));
+		 SWP_NOSIZE | SWP_NOACTIVATE |
+                 (wParam ? SWP_SHOWWINDOW : SWP_HIDEWINDOW));
     if (!wParam) SetFocus(hwnd);
   }
   return 0;
@@ -1005,7 +1006,7 @@
   int        y;
   RECT16     rectsel;
 
-  SetFocus(hwnd);
+/*  SetFocus(hwnd); */
   SetCapture(hwnd);
 
   lphl->PrevFocused = lphl->ItemFocused;
@@ -1213,6 +1214,8 @@
      case WM_MOUSEMOVE: return CBLMouseMove(hwnd, wParam, lParam);
      case WM_VSCROLL: return CBLVScroll(hwnd, wParam, lParam);
      case WM_SIZE: return CBLCheckSize(hwnd);
+     case WM_MOUSEACTIVATE:  /* We don't want to be activated */
+	return MA_NOACTIVATE;
     }
     return DefWindowProc16(hwnd, message, wParam, lParam);
 }
diff --git a/controls/edit.c b/controls/edit.c
index c646fb6..69507b9 100644
--- a/controls/edit.c
+++ b/controls/edit.c
@@ -2177,7 +2177,7 @@
 {
 	UINT s = LOWORD(EDIT_EM_GetSel(wndPtr, 0, 0L));
 	UINT e = HIWORD(EDIT_EM_GetSel(wndPtr, 0, 0L));
-	HGLOBAL hdst;
+	HGLOBAL16 hdst;
 	char *text;
 	char *dst;
 	char *src;
@@ -2717,7 +2717,7 @@
  */
 static LRESULT EDIT_WM_Paste(WND *wndPtr, WPARAM wParam, LPARAM lParam)
 {
-	HGLOBAL hsrc;
+	HGLOBAL16 hsrc;
 	char *src;
 
 	OpenClipboard(wndPtr->hwndSelf);
diff --git a/controls/menu.c b/controls/menu.c
index a83db51..fc36acb 100644
--- a/controls/menu.c
+++ b/controls/menu.c
@@ -107,7 +107,7 @@
 static HMENU MENU_CopySysMenu(void)
 {
     HMENU hMenu;
-    HGLOBAL handle;
+    HGLOBAL16 handle;
     POPUPMENU *menu;
 
     if (!(handle = SYSRES_LoadResource( SYSRES_MENU_SYSMENU ))) return 0;
diff --git a/controls/static.c b/controls/static.c
index 72ded64..faa8241 100644
--- a/controls/static.c
+++ b/controls/static.c
@@ -46,9 +46,9 @@
  *
  * Set the icon for an SS_ICON control.
  */
-static HICON STATIC_SetIcon( WND *wndPtr, HICON hicon )
+static HICON16 STATIC_SetIcon( WND *wndPtr, HICON16 hicon )
 {
-    HICON prevIcon;
+    HICON16 prevIcon;
     STATICINFO *infoPtr = (STATICINFO *)wndPtr->wExtra;
 
     if ((wndPtr->dwStyle & 0x0f) != SS_ICON) return 0;
@@ -167,7 +167,7 @@
 	    return infoPtr->hIcon;
 
 	case STM_SETICON:
-            lResult = STATIC_SetIcon( wndPtr, (HICON)wParam );
+            lResult = STATIC_SetIcon( wndPtr, (HICON16)wParam );
             InvalidateRect32( hWnd, NULL, FALSE );
             UpdateWindow( hWnd );
 	    break;
diff --git a/controls/status.c b/controls/status.c
new file mode 100644
index 0000000..0b6eb80
--- /dev/null
+++ b/controls/status.c
@@ -0,0 +1,499 @@
+/*
+ * Interface code to StatusWindow widget/control
+ *
+ * Copyright 1996 Bruce Milner
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "windows.h"
+#include "status.h"
+#include "commctrl.h"
+#include "heap.h"
+#include "syscolor.h"
+#include "win.h"
+
+/*
+ * Run tests using Waite Group Windows95 API Bible Vol. 1&2
+ * The second cdrom contains executables drawstat.exe,gettext.exe,
+ * simple.exe, getparts.exe, setparts.exe, statwnd.exe
+ */
+
+/*
+ * Fixme/Todo
+ * 1) Add size grip to status bar - SBARS_SIZEGRIP
+ * 2) Don't hard code bar to bottom of window, allow CCS_TOP also
+ * 3) Fix SBT_OWNERDRAW
+ * 4) Add DrawStatusText32A funtion
+ */
+
+static STATUSWINDOWINFO *GetStatusInfo(HWND32 hwnd)
+{
+    WND *wndPtr;
+
+    wndPtr = WIN_FindWndPtr(hwnd);
+    return ((STATUSWINDOWINFO *) &wndPtr->wExtra[0]);
+}
+
+/***********************************************************************
+ *           DrawStatusText32A   (COMCTL32.3)
+ */
+void DrawStatusText32A( HDC32 hdc, LPRECT32 lprc, LPCSTR text, UINT32 style )
+{
+    RECT32		r, rt;
+    int	oldbkmode;
+
+    r = *lprc;
+
+    if (style == 0 ||
+	style == SBT_POPOUT) {
+	InflateRect32(&r, -1, -1);
+	SelectObject(hdc, sysColorObjects.hbrushScrollbar);
+	Rectangle(hdc, r.left, r.top, r.right, r.bottom);
+
+	/* draw border */
+	SelectObject(hdc, sysColorObjects.hpenWindowFrame);
+	if (style == 0)
+	    DrawEdge32(hdc, &r, EDGE_SUNKEN, BF_RECT);
+	else
+	    DrawEdge32(hdc, &r, EDGE_RAISED, BF_RECT);
+    }
+    else if (style == SBT_NOBORDERS) {
+	SelectObject(hdc, sysColorObjects.hbrushScrollbar);
+	Rectangle(hdc, r.left, r.top, r.right, r.bottom);
+    }
+    else {	/* fixme for SBT_OWNERDRAW, SBT_RTLREADING */
+	
+    }
+
+    /* now draw text */
+    if ((style != SBT_OWNERDRAW) && text) {
+	SelectObject(hdc, sysColorObjects.hpenWindowText);
+	oldbkmode = SetBkMode(hdc, TRANSPARENT);
+	rt = r;
+	rt.left += 3;
+	DrawText32A(hdc, text, lstrlen32A(text),
+		    &rt, DT_LEFT | DT_VCENTER | DT_SINGLELINE);
+
+	if (oldbkmode != TRANSPARENT)
+	    SetBkMode(hdc, oldbkmode);
+    }
+}
+
+static BOOL32 SW_Refresh( HWND32 hwnd, HDC32 hdc, STATUSWINDOWINFO *self )
+{
+	int	i;
+
+	if (!IsWindowVisible(hwnd)) {
+	    return (TRUE);
+	}
+
+	if (self->simple) {
+	    DrawStatusText32A(hdc,
+			      &self->part0.bound,
+			      self->part0.text,
+			      self->part0.style);
+	}
+	else {
+	    for (i = 0; i < self->numParts; i++) {
+		DrawStatusText32A(hdc,
+				  &self->parts[i].bound,
+				  self->parts[i].text,
+				  self->parts[i].style);
+	    }
+	}
+
+	return TRUE;
+}
+
+
+static LRESULT
+SW_GetBorders(STATUSWINDOWINFO *self, HWND32 hwnd, WPARAM32 wParam, LPARAM lParam)
+{
+    LPINT32	out;
+
+    /* FIXME for sizegrips */
+    out = (LPINT32) lParam;
+    out[0] = 1; /* vertical border width */
+    out[1] = 1; /* horizontal border width */
+    out[2] = 1; /* width of border between rectangles */
+    return TRUE;
+}
+
+static void
+SW_SetPartBounds(HWND32 hwnd, STATUSWINDOWINFO *self)
+{
+    int	i;
+    RECT32	rect, *r;
+    STATUSWINDOWPART *part;
+    int	sep = 1;
+
+    /* get our window size */
+    GetClientRect32(hwnd, &rect);
+
+    /* set bounds for simple rectangle */
+    self->part0.bound = rect;
+
+    /* set bounds for non-simple rectangles */
+    for (i = 0; i < self->numParts; i++) {
+	part = &self->parts[i];
+	r = &self->parts[i].bound;
+	r->top = rect.top;
+	r->bottom = rect.bottom;
+	if (i == 0)
+	    r->left = 0;
+	else
+	    r->left = self->parts[i-1].bound.right+sep;
+	if (part->x == -1)
+	    r->right = rect.right;
+	else
+	    r->right = part->x;
+    }
+}
+
+static LRESULT
+SW_SetText(STATUSWINDOWINFO *self, HWND32 hwnd, WPARAM32 wParam, LPARAM lParam)
+{
+    int	part_num;
+    int	style;
+    LPSTR	text;
+    int	len;
+    STATUSWINDOWPART *part;
+
+    text = (LPSTR) lParam;
+    part_num = ((INT32) wParam) & 0x00ff;
+    style = ((INT32) wParam) & 0xff00;
+
+    if (part_num > 255)
+	return FALSE;
+
+    if (self->simple)
+	part = &self->part0;
+    else
+	part = &self->parts[part_num];
+    part->style = style;
+    if (style == SBT_OWNERDRAW) {
+	part->text = text;
+    }
+    else {
+	/* duplicate string */
+	if (part->text)
+	    HeapFree(SystemHeap, 0, part->text);
+	part->text = 0;
+	if (text && (len = lstrlen32A(text))) {
+	    part->text = HeapAlloc(SystemHeap, 0, len+1);
+	    lstrcpy32A(part->text, text);
+	}
+    }
+    InvalidateRect32(hwnd, &part->bound, FALSE);
+    return TRUE;
+}
+
+static LRESULT
+SW_SetParts(STATUSWINDOWINFO *self, HWND32 hwnd, WPARAM32 wParam, LPARAM lParam)
+{
+    HDC32	hdc;
+    LPINT32 parts;
+    STATUSWINDOWPART *	tmp;
+    int	i;
+    int	oldNumParts;
+
+    if (self->simple) {
+	self->simple = FALSE;
+    }
+    oldNumParts = self->numParts;
+    self->numParts = (INT32) wParam;
+    parts = (LPINT32) lParam;
+    if (oldNumParts > self->numParts) {
+	for (i = self->numParts ; i < oldNumParts; i++) {
+	    if (self->parts[i].text && (self->parts[i].style != SBT_OWNERDRAW))
+		HeapFree(SystemHeap, 0, self->parts[i].text);
+	}
+    }
+    else if (oldNumParts < self->numParts) {
+	tmp = HeapAlloc(SystemHeap, HEAP_ZERO_MEMORY,
+			sizeof(STATUSWINDOWPART) * self->numParts);
+	for (i = 0; i < oldNumParts; i++) {
+	    tmp[i] = self->parts[i];
+	}
+	if (self->parts)
+	    HeapFree(SystemHeap, 0, self->parts);
+	self->parts = tmp;
+    }
+    
+    for (i = 0; i < self->numParts; i++) {
+	self->parts[i].x = parts[i];
+    }
+    SW_SetPartBounds(hwnd, self);
+
+    hdc = GetDC(hwnd);
+    SW_Refresh(hwnd, hdc, self);
+    ReleaseDC(hwnd, hdc);
+    return TRUE;
+}
+
+static LRESULT
+SW_GetParts(STATUSWINDOWINFO *self, HWND32 hwnd, WPARAM32 wParam, LPARAM lParam)
+{
+    LPINT32 parts;
+    INT32	num_parts;
+    int	i;
+
+    self = GetStatusInfo(hwnd);
+    num_parts = (INT32) wParam;
+    parts = (LPINT32) lParam;
+    if (parts) {
+	return (self->numParts);
+	for (i = 0; i < num_parts; i++) {
+	    parts[i] = self->parts[i].x;
+	}
+    }
+    return (self->numParts);
+}
+
+static LRESULT
+SW_Create(STATUSWINDOWINFO *self, HWND32 hwnd, WPARAM32 wParam, LPARAM lParam)
+{
+    RECT32	rect;
+    LPCREATESTRUCT32A lpCreate = (LPCREATESTRUCT32A) lParam;
+    int	height, width;
+    HDC32	hdc;
+    HWND32	parent;
+
+    self->numParts = 0;
+    self->parts = 0;
+    self->simple = TRUE;
+    GetClientRect32(hwnd, &rect);
+
+    /* initialize simple case */
+    self->part0.bound = rect;
+    self->part0.text = 0;
+    self->part0.x = 0;
+    self->part0.style = 0;
+
+    height = 40;
+    if ((hdc = GetDC(0))) {
+	TEXTMETRIC32A tm;
+	GetTextMetrics32A(hdc, &tm);
+	self->textHeight = tm.tmHeight;
+	ReleaseDC(0, hdc);
+    }
+
+    parent = GetParent(hwnd);
+    GetClientRect32(parent, &rect);
+    width = rect.right - rect.left;
+    height = (self->textHeight * 3)/2;
+    MoveWindow(hwnd, lpCreate->x, lpCreate->y-1, width, height, FALSE);
+    SW_SetPartBounds(hwnd, self);
+    return 0;
+}
+
+static LRESULT
+SW_GetRect(STATUSWINDOWINFO *self, HWND32 hwnd, WPARAM32 wParam, LPARAM lParam)
+{
+    int	part_num;
+    LPRECT32  rect;
+
+    part_num = ((INT32) wParam) & 0x00ff;
+    rect = (LPRECT32) lParam;
+    if (self->simple)
+	*rect = self->part0.bound;
+    else
+	*rect = self->parts[part_num].bound;
+    return TRUE;
+}
+
+static LRESULT
+SW_GetText(STATUSWINDOWINFO *self, HWND32 hwnd, WPARAM32 wParam, LPARAM lParam)
+{
+    int	part_num;
+    LRESULT	result;
+    STATUSWINDOWPART *part;
+    LPSTR	out_text;
+
+    part_num = ((INT32) wParam) & 0x00ff;
+    out_text = (LPSTR) lParam;
+    if (self->simple)
+	part = &self->part0;
+    else
+	part = &self->parts[part_num];
+
+    if (part->style == SBT_OWNERDRAW)
+	result = (LRESULT) part->text;
+    else {
+	result = part->text ? lstrlen32A(part->text) : 0;
+	result |= (part->style << 16);
+	if (out_text) {
+	    lstrcpy32A(out_text, part->text);
+	}
+    }
+    return result;
+}
+
+static LRESULT
+SW_GetTextLength(STATUSWINDOWINFO *self, HWND32 hwnd, WPARAM32 wParam, LPARAM lParam)
+{
+    int	part_num;
+    STATUSWINDOWPART *part;
+    DWORD	result;
+
+    part_num = ((INT32) wParam) & 0x00ff;
+
+    if (self->simple)
+	part = &self->part0;
+    else
+	part = &self->parts[part_num];
+
+    if (part->text)
+	result = lstrlen32A(part->text);
+    else
+	result = 0;
+
+    result |= (part->style << 16);
+    return result;
+}
+
+static LRESULT
+SW_SetMinHeight(STATUSWINDOWINFO *self, HWND32 hwnd, WPARAM32 wParam, LPARAM lParam)
+{
+    /* FIXME */
+    /* size is wParam | 2*pixels_of_horz_border */
+    return TRUE;
+}
+
+static LRESULT
+SW_Simple(STATUSWINDOWINFO *self, HWND32 hwnd, WPARAM32 wParam, LPARAM lParam)
+{
+    BOOL32 simple;
+    HDC32	hdc;
+
+    simple = (BOOL32) wParam;
+    self->simple = simple;
+    hdc = GetDC(hwnd);
+    SW_Refresh(hwnd, hdc, self);
+    ReleaseDC(hwnd, hdc);
+    return TRUE;
+}
+
+static LRESULT
+SW_Size(STATUSWINDOWINFO *self, HWND32 hwnd, WPARAM32 wParam, LPARAM lParam)
+{
+    /* Need to resize width to match parent */
+    INT32	width, height, x, y;
+    RECT32	parent_rect;
+    HWND32	parent;
+
+    INT32  	flags;
+
+    flags = (INT32) wParam;
+
+    /* FIXME for flags =
+     * SIZE_MAXIMIZED, SIZE_MAXSHOW, SIZE_MINIMIZED, SIZE_RESTORED
+     */
+
+    if (flags == SIZE_RESTORED) {
+	/* width and height don't apply */
+	parent = GetParent(hwnd);
+	GetClientRect32(parent, &parent_rect);
+	height = (self->textHeight * 3)/2;
+	width = parent_rect.right - parent_rect.left;
+	x = parent_rect.left;
+	y = parent_rect.bottom - height;
+	MoveWindow(hwnd, parent_rect.left, parent_rect.bottom - height - 1,
+		   width, height, TRUE);
+	SW_SetPartBounds(hwnd, self);
+    }
+    return 0;
+}
+
+static LRESULT
+SW_Destroy(STATUSWINDOWINFO *self, HWND32 hwnd, WPARAM32 wParam, LPARAM lParam)
+{
+    int	i;
+
+    for (i = 0; i < self->numParts; i++) {
+	if (self->parts[i].text && (self->parts[i].style != SBT_OWNERDRAW))
+	    HeapFree(SystemHeap, 0, self->parts[i].text);
+    }
+    if (self->part0.text && (self->part0.style != SBT_OWNERDRAW))
+	HeapFree(SystemHeap, 0, self->part0.text);
+    HeapFree(SystemHeap, 0, self->parts);
+    return 0;
+}
+
+
+
+static LRESULT
+SW_Paint(STATUSWINDOWINFO *self, HWND32 hwnd)
+{
+    HDC32 hdc;
+    PAINTSTRUCT32	ps;
+
+    hdc = BeginPaint32(hwnd, &ps);
+    SW_Refresh(hwnd, hdc, self);
+    EndPaint32(hwnd, &ps);
+    return 0;
+}
+
+LRESULT StatusWindowProc( HWND32 hwnd, UINT32 msg,
+                          WPARAM32 wParam, LPARAM lParam )
+{
+    STATUSWINDOWINFO *self;
+
+    self = GetStatusInfo(hwnd);
+
+    switch (msg) {
+    case SB_GETBORDERS:
+	return SW_GetBorders(self, hwnd, wParam, lParam);
+    case SB_GETPARTS:
+	return SW_GetParts(self, hwnd, wParam, lParam);
+    case SB_GETRECT:
+	return SW_GetRect(self, hwnd, wParam, lParam);
+    case SB_GETTEXT32A:
+	return SW_GetText(self, hwnd, wParam, lParam);
+    case SB_GETTEXTLENGTH32A:
+	return SW_GetTextLength(self, hwnd, wParam, lParam);
+    case SB_SETMINHEIGHT:
+	return SW_SetMinHeight(self, hwnd, wParam, lParam);
+    case SB_SETPARTS:	
+	return SW_SetParts(self, hwnd, wParam, lParam);
+    case SB_SETTEXT32A:
+	return SW_SetText(self, hwnd, wParam, lParam);
+    case SB_SIMPLE:
+	return SW_Simple(self, hwnd, wParam, lParam);
+
+    case WM_CREATE:
+	return SW_Create(self, hwnd, wParam, lParam);
+    case WM_DESTROY:
+	return SW_Destroy(self, hwnd, wParam, lParam);
+    case WM_PAINT:
+	return SW_Paint(self, hwnd);
+    case WM_SIZE:
+	return SW_Size(self, hwnd, wParam, lParam);
+    default:
+	return DefWindowProc32A(hwnd, msg, wParam, lParam);
+    }
+    return 0;
+}
+
+
+/***********************************************************************
+ *           CreateStatusWindow32A   (COMCTL32.4)
+ */
+HWND32 CreateStatusWindow32A( INT32 style, LPCSTR text, HWND32 parent,
+                              UINT32 wid )
+{
+    HWND32 ret;
+    ATOM atom;
+
+    atom = GlobalFindAtom32A(STATUSCLASSNAME32A);
+    if (!atom) {
+	/* Some apps don't call InitCommonControls */
+	InitCommonControls();
+    }
+
+    ret = CreateWindowEx32A(0, STATUSCLASSNAME32A, "Status Window",
+			    style, CW_USEDEFAULT32, CW_USEDEFAULT32,
+			    CW_USEDEFAULT32, CW_USEDEFAULT32, parent, 0, 0, 0);
+    return (ret);
+}
diff --git a/controls/widgets.c b/controls/widgets.c
index 4f8a78c..eccaa10 100644
--- a/controls/widgets.c
+++ b/controls/widgets.c
@@ -5,8 +5,10 @@
  */
 
 #include "win.h"
+#include "commctrl.h"
 #include "button.h"
 #include "static.h"
+#include "status.h"
 #include "scroll.h"
 #include "desktop.h"
 #include "mdi.h"
@@ -49,6 +51,7 @@
 #define NB_BUILTIN_CLASSES16 \
          (sizeof(WIDGETS_BuiltinClasses16)/sizeof(WIDGETS_BuiltinClasses16[0]))
 
+
 static WNDCLASS32A WIDGETS_BuiltinClasses32[] =
 {
     { CS_GLOBALCLASS | CS_DBLCLKS | CS_VREDRAW | CS_HREDRAW | CS_PARENTDC,
@@ -61,6 +64,16 @@
          (sizeof(WIDGETS_BuiltinClasses32)/sizeof(WIDGETS_BuiltinClasses32[0]))
 
 
+static WNDCLASS32A WIDGETS_CommonControls32[] =
+{
+    { CS_GLOBALCLASS | CS_VREDRAW | CS_HREDRAW, StatusWindowProc, 0,
+      sizeof(STATUSWINDOWINFO), 0, 0, 0, 0, 0, STATUSCLASSNAME32A },
+};
+
+#define NB_COMMON_CONTROLS32 \
+         (sizeof(WIDGETS_CommonControls32)/sizeof(WIDGETS_CommonControls32[0]))
+
+
 /***********************************************************************
  *           WIDGETS_Init
  * 
@@ -108,3 +121,23 @@
     SEGPTR_FREE(name);
     return TRUE;
 }
+
+
+/***********************************************************************
+ *           InitCommonControls   (COMCTL32.15)
+ */
+void InitCommonControls(void)
+{
+    int i;
+    char name[30];
+    WNDCLASS32A *class32 = WIDGETS_CommonControls32;
+
+    for (i = 0; i < NB_COMMON_CONTROLS32; i++, class32++)
+    {
+        /* Just to make sure the string is > 0x10000 */
+        strcpy( name, (char *)class32->lpszClassName );
+        class32->lpszClassName = name;
+        class32->hCursor = LoadCursor16( 0, IDC_ARROW );
+        RegisterClass32A( class32 );
+    }
+}