--- a/WinWorkstation.st Tue Dec 04 17:45:42 2001 +0100
+++ b/WinWorkstation.st Wed Dec 05 15:56:15 2001 +0100
@@ -28,30 +28,24 @@
#define COUNT_RESOURCES /* */
#define COUNT_BMP_RESOURCES /* */
#define DEBUG_DELETEOBJECT /* */
-#define DEBUG_DC_REUSE /* */
+#define DEBUG_DC_REUSE /* */
#define ADJUSTWINDOW
#define ALWAYSTRUECOLOR
#define WIN32THREADS
+
/* #define DEBUGMASK /* */
#define SET_FOCUS_IN_WINTHREAD
#define SET_CURSOR_IN_WINTHREAD
#define DELAY_ENTER_LEAVE_WHILE_IN_SIZE_MOVE /* */
-/* #define BEEP_IN_WINTHREAD /* */
-/* #define KEEP_STD_CURSORS /* not useful - those are allocated only once, in any case */
-/* #define HANDLE_VIEWGRAVITY /* not yet working */
+#define xxBEEP_IN_WINTHREAD /* */
+#define xxKEEP_STD_CURSORS /* not useful - those are allocated only once, in any case */
+#define xxHANDLE_VIEWGRAVITY /* not yet working */
+#define xxCOMPRESS_WINDOWPOSCHANGED
#define LATE_WM_PAINT /* fill-bg in ST/X thread (instead of in event-thread) */
/* seems to be needed to avoid DC conflicts */
-#ifdef LATE_WM_PAINT
-# define ONE_IF_LATE_WM_PAINT 1
-# define ZERO_IF_LATE_WM_PAINT 0
-#else
-# define ONE_IF_LATE_WM_PAINT 0
-# define ZERO_IF_LATE_WM_PAINT 1
-#endif
-
#define CACHE_LAST_DC /* remember last DC in gcData */
#define CACHE_LAST_PEN /* remember last pen in gcData */
#define CACHE_LAST_BRUSH /* remember last brush in gcData */
@@ -67,6 +61,14 @@
#define MAX_NUM_PEN_CACHED 32 /* upper limit */
#define MAX_NUM_BRUSH_CACHED 32 /* upper limit */
+#ifdef LATE_WM_PAINT
+# define ONE_IF_LATE_WM_PAINT 1
+# define ZERO_IF_LATE_WM_PAINT 0
+#else
+# define ONE_IF_LATE_WM_PAINT 0
+# define ZERO_IF_LATE_WM_PAINT 1
+#endif
+
#undef INT
#define INT WIN_INT
#undef Array
@@ -787,7 +789,8 @@
* a need to access the Mutex
*/
#define NUMQUICKFREE_EV 32
-static struct queuedEvent *quickFreeEvent[NUMQUICKFREE_EV];
+#define NUMQUICKFREE_EV 0
+static struct queuedEvent *quickFreeEvent[NUMQUICKFREE_EV+1];
static struct queuedEvent *eventQueueHead = (struct queuedEvent *)0;
static struct queuedEvent *eventQueueTail = (struct queuedEvent *)0;
static int eventsendcount = 0;
@@ -816,11 +819,13 @@
static HDC last_wm_paint_dc = 0;
#endif
-static HWND lastPos_win = 0;
-static int lastPos_w;
-static int lastPos_h;
-static int lastPos_x;
-static int lastPos_y;
+#ifdef COMPRESS_WINDOWPOSCHANGED
+ static HWND lastPos_win = 0;
+ static int lastPos_w;
+ static int lastPos_h;
+ static int lastPos_x;
+ static int lastPos_y;
+#endif
%}
! !
@@ -1955,7 +1960,9 @@
}
}
if (i == NUMQUICKFREE_EV) {
- lockEventFreeList();
+ if (! lockEventFreeList()) {
+ fprintf(stderr, "WinWorkstation [error]: could not lock evFreeList\n");
+ }
ev->ev_next = eventFreeList;
eventFreeList = ev;
unlockEventFreeList();
@@ -2117,7 +2124,7 @@
RECT *pRect;
union {
RGNDATA rgnData;
- char bytes[256];
+ char bytes[512];
} data;
wantExpose = (GetWindow_eventMask(hWnd) & ExposureMask);
@@ -2125,11 +2132,18 @@
if (hRgnInOrNull) {
updRgn = hRgnInOrNull;
} else {
+ PAINTSTRUCT ps;
+
/*
* fetch the update region, even if ExposureMask is empty.
*/
updRgn = CreateRectRgn(0, 0, 0, 0);
ret = GetUpdateRgn(hWnd, updRgn, FALSE);
+
+ BeginPaint(hWnd, &ps);
+ /* store the rectangle required for image bit reversal */
+ /* updateRect = ps.rcPaint; */
+ EndPaint(hWnd, &ps);
switch (ret) {
case ERROR:
@@ -2157,7 +2171,7 @@
numRects = data.rgnData.rdh.nCount;
pRect = data.rgnData.Buffer;
DPRINTF(("region numRects=%d\n", numRects));
- } else{
+ } else {
/* a big region ... */
GetRgnBox(updRgn, &updRect);
numRects = 1;
@@ -2172,10 +2186,6 @@
}
}
- if (updRgn && (updRgn != hRgnInOrNull)) {
- _DeleteObject(updRgn, __LINE__);
- }
-
if (numRects) {
if (doClear) {
__clearRectangles(hWnd, numRects, pRect);
@@ -2198,6 +2208,10 @@
}
}
+ if (updRgn && (updRgn != hRgnInOrNull)) {
+ _DeleteObject(updRgn, __LINE__);
+ }
+
return numRects;
}
@@ -2378,7 +2392,7 @@
}
#endif /* HANDLE_VIEWGRAVITY */
-static
+static int
winEventProcessing(hWnd, message, wParam, lParam, pDefault)
HWND hWnd; /* window handle */
UINT message; /* type of message */
@@ -2742,7 +2756,8 @@
}
if (!(wp->flags & SWP_NOSIZE)
|| !(wp->flags & SWP_NOMOVE)) {
- enqEvent(ENQ_AT_END, 0, hWnd, WM_WINDOWPOSCHANGED, wParam, x, y, w, h, EV_NOTIME);
+ enqEvent(ENQ_AT_END, 0, hWnd, WM_WINDOWPOSCHANGED, 0, x, y, w, h, EV_NOTIME);
+#ifdef COMPRESS_WINDOWPOSCHANGED
/*
* remember the current
* window and size;
@@ -2755,6 +2770,7 @@
lastPos_x = x;
lastPos_y = y;
lastPos_win = hWnd;
+#endif
}
}
}
@@ -2796,8 +2812,12 @@
if (((GetWindow_flag(hWnd) & LI_INPUTWIN) == 0)
&& (hWnd != __rootWinSpezial)) {
- switch (__generateExposes(hWnd, NULL, WM_PAINT, ZERO_IF_LATE_WM_PAINT))
- {
+ PAINTSTRUCT dummyPaint;
+ int retVal;
+
+ retVal = __generateExposes(hWnd, NULL, WM_PAINT, ZERO_IF_LATE_WM_PAINT);
+
+ switch (retVal) {
case -1: /* error */
*pDefault = 0;
break;
@@ -2805,7 +2825,7 @@
default: /* generated events */
break;
}
-# if 0
+# ifdef THIS_IS_BAD
*pDefault = 0;
return 1;
# endif
@@ -2818,8 +2838,65 @@
case WM_SIZE:
EVENT_PRINTF(("WM_SIZE\n"));
- *pDefault = 0;
- return 0;
+ /*
+ * ignore child window messages ...
+ */
+ if (GetParent(hWnd) != NULL) {
+ *pDefault = 0;
+ return 0;
+ }
+
+ switch (wParam) {
+ case SIZE_MAXIMIZED: /* default handling */
+ case SIZE_MINIMIZED: /* default handling */
+ case SIZE_RESTORED: /* default handling */
+ {
+ RECT rct;
+ int x, y, w, h;
+
+ GetClientRect(hWnd, &rct);
+
+ x = rct.left;
+ y = rct.top;
+ w = rct.right - rct.left;
+ h = rct.bottom - rct.top;
+
+ if ((w == 0) && (h == 0)) {
+ /*
+ * iconified ...
+ */
+ if (! GetWindow_iconified(hWnd)) {
+ SetWindow_iconified(hWnd, 1);
+ enqEvent(ENQ_AT_END, 0, hWnd, __WM_ICONIFIED, 1, 0, 0, 0, 0, EV_NOTIME);
+ }
+ } else {
+ if (GetWindow_iconified(hWnd)) {
+ SetWindow_iconified(hWnd, 0);
+ enqEvent(ENQ_AT_END, 0, hWnd, __WM_ICONIFIED, 0, 0, 0, 0, 0, EV_NOTIME);
+ }
+ enqEvent(ENQ_AT_END, 0, hWnd, WM_WINDOWPOSCHANGED, 0, x, y, w, h, EV_NOTIME);
+#ifdef COMPRESS_WINDOWPOSCHANGED
+ /*
+ * remember the current
+ * window and size;
+ * This allows the backend to ignore
+ * intermediate events.
+ */
+ lastPos_win = 0;
+ lastPos_w = w;
+ lastPos_h = h;
+ lastPos_x = x;
+ lastPos_y = y;
+ lastPos_win = hWnd;
+#endif
+ }
+ }
+ break;
+
+ default: /* ignore */
+ *pDefault = 0;
+ return 0;
+ }
break;
case WM_DROPFILES:
@@ -3475,7 +3552,11 @@
EVENT_PRINTF(("WM_SETTEXT\n"));
break;
+#ifdef WM_SYNCPAINT
+ case WM_SYNCPAINT:
+#else
case 0x88:
+#endif
EVENT_PRINTF(("0x88 (undoc)\n"));
break;
@@ -3776,6 +3857,165 @@
enqEvent(ENQ_AT_END, 0, hWnd, message, wParam, 0, 0, 0, 0, EV_NOTIME);
break;
+#if 0
+ case WM_NULL:
+ EVENT_PRINTF(("WM_NULL\n"));
+ break;
+
+ case WM_ENABLE:
+ EVENT_PRINTF(("WM_ENABLE\n"));
+ break;
+
+ case WM_SETREDRAW:
+ EVENT_PRINTF(("WM_SETREDRAW\n"));
+ break;
+
+ case WM_DEVMODECHANGE:
+ EVENT_PRINTF(("WM_DEVMODECHANGE\n"));
+ break;
+
+ case WM_TIMECHANGE:
+ EVENT_PRINTF(("WM_TIMECHANGE\n"));
+ break;
+
+ case WM_CANCELMODE:
+ EVENT_PRINTF(("WM_CANCELMODE\n"));
+ break;
+
+ case WM_CHILDACTIVATE:
+ EVENT_PRINTF(("WM_CHILDACTIVATE\n"));
+ break;
+
+ case WM_QUEUESYNC:
+ EVENT_PRINTF(("WM_QUEUESYNC\n"));
+ break;
+
+ case WM_NEXTDLGCTL:
+ EVENT_PRINTF(("WM_NEXTDLGCTL\n"));
+ break;
+
+ case WM_SPOOLERSTATUS:
+ EVENT_PRINTF(("WM_SPOOLERSTATUS\n"));
+ break;
+
+ case WM_DRAWITEM:
+ EVENT_PRINTF(("WM_DRAWITEM\n"));
+ break;
+
+ case WM_MEASUREITEM:
+ EVENT_PRINTF(("WM_MEASUREITEM\n"));
+ break;
+
+ case WM_DELETEITEM:
+ EVENT_PRINTF(("WM_DELETEITEM\n"));
+ break;
+
+ case WM_VKEYTOITEM:
+ EVENT_PRINTF(("WM_VKEYTOITEM\n"));
+ break;
+
+ case WM_CHARTOITEM:
+ EVENT_PRINTF(("WM_CHARTOITEM\n"));
+ break;
+
+ case WM_SETFONT:
+ EVENT_PRINTF(("WM_SETFONT\n"));
+ break;
+
+ case WM_GETFONT:
+ EVENT_PRINTF(("WM_GETFONT\n"));
+ break;
+
+ case WM_SETHOTKEY:
+ EVENT_PRINTF(("WM_SETHOTKEY\n"));
+ break;
+
+ case WM_GETHOTKEY:
+ EVENT_PRINTF(("WM_GETHOTKEY\n"));
+ break;
+
+ case WM_QUERYDRAGICON:
+ EVENT_PRINTF(("WM_QUERYDRAGICON\n"));
+ break;
+
+ case WM_COMPAREITEM:
+ EVENT_PRINTF(("WM_COMPAREITEM\n"));
+ break;
+
+ case WM_GETOBJECT:
+ EVENT_PRINTF(("WM_GETOBJECT\n"));
+ break;
+
+ case WM_COMPACTING:
+ EVENT_PRINTF(("WM_COMPACTING\n"));
+ break;
+
+ case WM_COMMNOTIFY:
+ EVENT_PRINTF(("WM_COMMNOTIFY\n"));
+ break;
+
+ case WM_COPYDATA:
+ EVENT_PRINTF(("WM_COPYDATA\n"));
+ break;
+
+ case WM_CANCELJOURNAL:
+ EVENT_PRINTF(("WM_CANCELJOURNAL\n"));
+ break;
+
+ case WM_NOTIFY:
+ EVENT_PRINTF(("WM_NOTIFY\n"));
+ break;
+
+ case WM_INPUTLANGCHANGEREQUEST:
+ EVENT_PRINTF(("WM_INPUTLANGCHANGEREQUEST\n"));
+ break;
+
+ case WM_INPUTLANGCHANGE:
+ EVENT_PRINTF(("WM_INPUTLANGCHANGE\n"));
+ break;
+
+ case WM_TCARD:
+ EVENT_PRINTF(("WM_TCARD\n"));
+ break;
+
+ case WM_HELP:
+ EVENT_PRINTF(("WM_HELP\n"));
+ break;
+
+ case WM_USERCHANGED:
+ EVENT_PRINTF(("WM_USERCHANGED\n"));
+ break;
+
+ case WM_NOTIFYFORMAT:
+ EVENT_PRINTF(("WM_NOTIFYFORMAT\n"));
+ break;
+
+ case WM_CONTEXTMENU:
+ EVENT_PRINTF(("WM_CONTEXTMENU\n"));
+ break;
+
+ case WM_GETICON:
+ EVENT_PRINTF(("WM_GETICON\n"));
+ break;
+
+ case WM_SETICON:
+ EVENT_PRINTF(("WM_SETICON\n"));
+ break;
+
+ case WM_NCXBUTTONDOWN:
+ EVENT_PRINTF(("WM_NCXBUTTONDOWN\n"));
+ break;
+
+ case WM_NCXBUTTONUP:
+ EVENT_PRINTF(("WM_NCXBUTTONUP\n"));
+ break;
+
+ case WM_NCXBUTTONDBLCLK:
+ EVENT_PRINTF(("WM_NCXBUTTONDBLCLK\n"));
+ break;
+
+#endif
+
default:
UNHANDLED_EVENT_PRINTF(("WinWorkstat [info]: unhandled msg = %x\n", message));
break;
@@ -4029,9 +4269,11 @@
EVENT_PRINTF(("*WM_KILLFOCUS\n"));
continue;
#endif
+#if 0
case WM_SIZE:
EVENT_PRINTF(("*WM_SIZE\n"));
continue;
+#endif
}
/*
@@ -9843,6 +10085,7 @@
do { /* only to allow continue */
if (deqEvent(ev, wWanted, evMask)) {
+#ifdef COMPRESS_WINDOWPOSCHANGED
if ((ev->ev_hWnd == lastPos_win)
&& (ev->ev_message == WM_WINDOWPOSCHANGED)
&& ((ev->ev_arg1 != lastPos_x)
@@ -9850,11 +10093,13 @@
|| (ev->ev_arg3 != lastPos_w)
|| (ev->ev_arg4 != lastPos_h))) {
/*
- * ignore resize
- * (that event is an intermediate one)
+ * ignore intermediate resize events
+ * (that event is an intermediate one, because the peek-values
+ * have already been updated for another event)
*/
continue;
}
+#endif
RETURN ( true );
}
} while (0);
@@ -12304,6 +12549,161 @@
extension:nil
blocking:true
"
+!
+
+nativeMessageBoxFor:ownerId text:textOrNil title:titleOrNil flags:flagArray blocking:blocking
+ "start a native message box dialog.
+
+ EXPERIMENTAL & non-portable: use with caution"
+
+ |errorCode answer|
+
+%{ /* STACK: 32000*/
+
+#ifndef NO_NATIVE_DIALOGS
+ HWND hWndOwner = NULL;
+ int boxFlags = 0;
+ char *__title;
+ char *__text;
+ int __answer;
+
+ if (__isExternalAddress(ownerId)) {
+ hWndOwner = _HWNDVal(ownerId);
+ }
+ if (__isString(titleOrNil)) {
+ __title = __stringVal(titleOrNil);
+ } else {
+ __title = "";
+ }
+ if (__isString(textOrNil)) {
+ __text = __stringVal(textOrNil);
+ } else {
+ __text = "";
+ }
+
+ if (__isNonNilObject(flagArray) && __isArray(flagArray)) {
+ int i;
+
+ for (i=0; i<__arraySize(flagArray); i++) {
+ OBJ flag = __ArrayInstPtr(flagArray)->a_element[i];
+ int flagVal = 0;
+
+ if (__isSmallInteger(flag)) {
+ flagVal = __intVal(flag);
+ } else if (flag == @symbol(ABORTRETRYIGNORE)) {
+ flagVal = MB_ABORTRETRYIGNORE;
+ } else if (flag == @symbol(APPLMODAL)) {
+ flagVal = MB_APPLMODAL;
+ } else if (flag == @symbol(DEFAULT_DESKTOP_ONLY)) {
+ flagVal = MB_DEFAULT_DESKTOP_ONLY;
+ } else if (flag == @symbol(DEFBUTTON1)) {
+ flagVal = MB_DEFBUTTON1;
+ } else if (flag == @symbol(DEFBUTTON2)) {
+ flagVal = MB_DEFBUTTON2;
+ } else if (flag == @symbol(DEFBUTTON3)) {
+ flagVal = MB_DEFBUTTON3;
+ } else if (flag == @symbol(ICONASTERISK)) {
+ flagVal = MB_ICONASTERISK;
+ } else if (flag == @symbol(ICONHAND)) {
+ flagVal = MB_ICONHAND;
+ } else if (flag == @symbol(ICONINFORMATION)) {
+ flagVal = MB_ICONINFORMATION;
+ } else if (flag == @symbol(ICONQUESTION)) {
+ flagVal = MB_ICONQUESTION;
+ } else if (flag == @symbol(ICONSTOP)) {
+ flagVal = MB_ICONSTOP;
+ } else if (flag == @symbol(OK)) {
+ flagVal = MB_OK;
+ } else if (flag == @symbol(OKCANCEL)) {
+ flagVal = MB_OKCANCEL;
+ } else if (flag == @symbol(RETRYCANCEL)) {
+ flagVal = MB_RETRYCANCEL;
+ } else if (flag == @symbol(SETFOREGROUND)) {
+ flagVal = MB_SETFOREGROUND;
+ } else if (flag == @symbol(SYSTEMMODAL)) {
+ flagVal = MB_SYSTEMMODAL;
+ } else if (flag == @symbol(TASKMODAL)) {
+ flagVal = MB_TASKMODAL;
+ } else if (flag == @symbol(YESNO)) {
+ flagVal = MB_YESNO;
+ } else if (flag == @symbol(YESNOCANCEL)) {
+ flagVal = MB_YESNOCANCEL;
+ }
+ boxFlags |= flagVal;
+ }
+ }
+
+ if (blocking == true) {
+ __answer = MessageBox(hWndOwner,
+ __text,
+ __title,
+ boxFlags);
+ } else {
+ __answer = __STX_API_CALL4( (void *)MessageBox,
+ (void *)hWndOwner,
+ (void *)__text,
+ (void *)__title,
+ (void *)boxFlags);
+ }
+
+ switch (__answer) {
+ case IDABORT:
+ answer = @symbol(IDABORT);
+ break;
+ case IDCANCEL:
+ answer = @symbol(IDCANCEL);
+ break;
+ case IDIGNORE:
+ answer = @symbol(IDIGNORE);
+ break;
+ case IDNO:
+ answer = @symbol(IDNO);
+ break;
+ case IDOK:
+ answer = @symbol(IDOK);
+ break;
+ case IDRETRY:
+ answer = @symbol(IDRETRY);
+ break;
+ case IDYES:
+ answer = @symbol(IDYES);
+ break;
+ default:
+ answer = __MKSMALLINT(__answer);
+ break;
+ }
+#else
+ errorCode = __MKSMALLINT(-1);
+#endif /* NO_NATIVE_DIALOGS */
+%}.
+ (errorCode notNil) ifTrue:[
+ self primitiveFailed.
+ ].
+
+ ^ answer
+
+ "
+ Display
+ nativeMessageBoxFor:nil
+ text:'Hello world'
+ title:'Message'
+ flags:#( OK APPLMODAL ICONSTOP )
+ blocking:true
+
+ Display
+ nativeMessageBoxFor:nil
+ text:'Hello world'
+ title:'Message'
+ flags:#( OK APPLMODAL ICONSTOP )
+ blocking:false
+
+ Display
+ nativeMessageBoxFor:nil
+ text:'Hello world'
+ title:'Message'
+ flags:#( ABORTRETRYIGNORE ICONSTOP )
+ blocking:false
+ "
! !
!WinWorkstation methodsFor:'pointer queries '!
@@ -14220,6 +14620,6 @@
!WinWorkstation class methodsFor:'documentation'!
version
- ^ '$Header: /cvs/stx/stx/libview/WinWorkstation.st,v 1.211 2001-11-28 15:17:53 cg Exp $'
+ ^ '$Header: /cvs/stx/stx/libview/WinWorkstation.st,v 1.212 2001-12-05 14:56:15 cg Exp $'
! !
WinWorkstation initialize!