Release 970914
Thu Sep 11 18:24:56 1997 Philippe De Muyter <phdm@info.ucl.ac.be>
* [objects/dc.c]
In DC_SetupGCForPatBlt, replace R2_NOT by GXxor with (black xor white).
Tue Sep 9 23:04:02 1997 U. Bonnes <bon@elektron.ikp.physik.th-darmstadt.de>
* [memory/virtual.c]
Do not write debugging info unconditionally to stderr.
* [files/profile.c]
Call PROFILE_GetSection in PROFILE_GetString for key_name "" too.
* [misc/crtdll.c]
Many new functions.
* [include/windows.h] [windows/winpos.c]
ClientToScreen16 doesn't have a return value.
Sun Sep 7 10:06:39 1997 Alexandre Julliard <julliard@lrc.epfl.ch>
* [misc/main.c] [AUTHORS]
Update the list of contributors. Please let me know if I forgot
someone.
* [if1632/*.spec] [if1632/builtin.c] [tools/build.c]
Ordinal base for Win32 DLLs is now computed automatically from the
lowest ordinal found.
* [include/wintypes.h]
WINAPI is now defined as attribute((stdcall)). This will require
gcc to compile.
* [if1632/thunk.c]
Removed Win32 thunks (no longer needed with stdcall).
* [if1632/crtdll.spec] [misc/crtdll.c]
Make sure we only reference cdecl functions in the spec file.
* [objects/dc.c]
Use CapNotLast drawing style for 1-pixel wide lines.
* [tools/build.c]
Added 'double' argument type.
Added 'varargs' function type for Win32.
Made CallTo16_xxx functions stdcall.
Fri Sep 5 14:50:49 1997 Alex Korobka <alex@trantor.pharm.sunysb.edu>
* [tools/build.c] [windows/win.c] [windows/event.c] [windows/message.c]
More fixes to get message exchange closer to the original.
* [misc/spy.c]
Message logs now contain window names.
* [loader/resource.c] [loader/ne_resource.c] [loader/task.c]
[objects/cursoricon.c] [windows/user.c]
Added some obscure features to fix memory leaks.
Fri Sep 5 00:46:28 1997 Jan Willamowius <jan@janhh.shnet.org>
* [if1632/kernel32.spec] [win32/newfns.c]
Added stub for UTRegister() and UTUnRegister().
Thu Sep 4 12:03:12 1997 Frans van Dorsselaer <dorssel@rulhmpc49.LeidenUniv.nl>
* [controls/edit.c]
Allow ASCII codes > 127 in WM_CHAR.
Mon Sep 1 17:23:24 1997 Dimitrie O. Paun <dimi@mail.cs.toronto.edu>
* [controls/widgets.c]
In InitCommonControls, remember the name of the class
because lpszClassName was made to point to a local array
Added the ProgressBar to the list of implemented controls.
Call InitCommonControls from WIDGETS_Init to register all
implemented Common Controls.
* [include/commctrl.h]
Added misc decl for the Progress Bar.
* [controls/progress.c] [include/progress.h]
First attempt at implementiong the Progress Bar class.
* [objects/brush.h]
Implementation for GetSysColorBrush[16|32]
* [controls/status.c]
Use DrawEdge to draw the borders and fill the background
* [controls/uitools.c]
Added DrawDiagEdge32 and DrawRectEdge32
* [graphics/painting.c]
Implement DrawEdge[16|32]
Started DrawFrameControl32
Mon Sep 1 10:07:09 1997 Lawson Whitney <lawson_whitney@juno.com>
* [misc/comm.c] [include/windows.h]
SetCommEventMask returns a SEGPTR.
Sun Aug 31 23:28:32 1997 Marcus Meissner <msmeissn@cip.informatik.uni-erlangen.de>
* [loader/pe_image.c][loader/module.c][include/pe_image.h]
[include/module.h]
Cleaned up the whole Win32 library mess (a bit).
* [debugger/stabs.c]
If 'wine' has no absolute path and isn't found, check $PATH too.
* [misc/ole2nls.c]
Some fixes.
* [misc/ver.c]
Added support for PE style version resources.
* [memory/string.c]
Check for NULL pointers to _lstr* functions, just as Windows95 does.
* [multimedia/time.c]
Made list of timers a simple linked list.
* [loader/resource.c]
Netscape 3 seems to pass NEGATIVE resource Ids (in an
unsigned int, yes). Don't know why, fixed it anyway.
* [objects/bitmap.c]
LoadImageW added.
* [include/win.h][windows/win.c]
Change wIDmenu from UINT16 to UINT32 and changed the
SetWindow(Long|Word) accordingly.
Thu Aug 28 19:30:08 1997 Morten Welinder <terra@diku.dk>
* [include/windows.h]
Add a few more colors defined for Win95.
Add a few more brush styles.
* [windows/syscolor.c]
Add error checks for SYSCOLOR_SetColor, SYSCOLOR_Init,
GetSysColor16, GetSysColor32. Add support for above colors.
Sun Aug 24 16:22:57 1997 Andrew Taylor <andrew@riscan.com>
* [multimedia/mmsystem.c]
Changed mmioDescend to use mmio functions for file I/O, neccessary
for memory files.
diff --git a/controls/Makefile.in b/controls/Makefile.in
index 9d24345..9be0848 100644
--- a/controls/Makefile.in
+++ b/controls/Makefile.in
@@ -13,9 +13,11 @@
icontitle.c \
listbox.c \
menu.c \
+ progress.c \
scroll.c \
static.c \
status.c \
+ uitools.c \
updown.c \
widgets.c
diff --git a/controls/edit.c b/controls/edit.c
index 28373cd..7e32b57 100644
--- a/controls/edit.c
+++ b/controls/edit.c
@@ -982,11 +982,17 @@
segptr + start, index, count, action);
LocalUnlock16(hloc16);
return ret;
- } else if (es->word_break_proc32A)
- return (INT32)CallWordBreakProc32A((FARPROC32)es->word_break_proc32A,
- es->text + start, index, count, action);
+ }
+ else if (es->word_break_proc32A)
+ {
+ dprintf_relay( stddeb, "CallTo32(wordbrk=%p,str='%s',idx=%d,cnt=%d,act=%d)\n",
+ es->word_break_proc32A, es->text + start, index,
+ count, action );
+ return (INT32)es->word_break_proc32A( es->text + start, index,
+ count, action );
+ }
else
- return EDIT_WordBreakProc(es->text + start, index, count, action);
+ return EDIT_WordBreakProc(es->text + start, index, count, action);
}
@@ -2819,7 +2825,7 @@
EDIT_EM_ReplaceSel(wnd, es, TRUE, "\t");
break;
default:
- if (!(es->style & ES_READONLY) && (c >= ' ') && (c != 127)) {
+ if (!(es->style & ES_READONLY) && ((BYTE)c >= ' ') && (c != 127)) {
char str[2];
str[0] = c;
str[1] = '\0';
diff --git a/controls/listbox.c b/controls/listbox.c
index 5466abe..1308e81 100644
--- a/controls/listbox.c
+++ b/controls/listbox.c
@@ -2462,7 +2462,7 @@
default:
if ((msg >= WM_USER) && (msg < 0xc000))
- fprintf(stderr,"Listbox %04x: unknown msg %04x wp %08x lp %08lx\n",
+ dprintf_listbox(stddeb,"Listbox %04x: unknown msg %04x wp %08x lp %08lx\n",
hwnd, msg, wParam, lParam );
return DefWindowProc32A( hwnd, msg, wParam, lParam );
}
diff --git a/controls/menu.c b/controls/menu.c
index 5a1e28c..9e08d31 100644
--- a/controls/menu.c
+++ b/controls/menu.c
@@ -1141,48 +1141,44 @@
/***********************************************************************
* MENU_PatchResidentPopup
*/
-BOOL32 MENU_PatchResidentPopup( HQUEUE16 checkQueue, WND* wndOwner )
+BOOL32 MENU_PatchResidentPopup( HQUEUE16 checkQueue, WND* checkWnd )
{
- /* checkQueue tells us whether we have to disconnect top
- * popup from the wndOwner or (if the latter is NULL) from
- * the checkQueue. If checkQueue is 0 then we need to set
- * popup owner to the wndOwner.
- *
- * This is supposed to be called when top popup is hidden. */
-
if( pTopPopupWnd )
{
HTASK16 hTask = 0;
- dprintf_menu(stddeb,"patching resident popup: %04x, %08x\n",
- checkQueue, (unsigned) wndOwner);
- if( wndOwner )
- {
- if( pTopPopupWnd->owner == wndOwner )
- {
- if( checkQueue ) pTopPopupWnd->owner = NULL;
- return TRUE;
- }
-
- /* switch to the new owner */
+ dprintf_menu(stddeb,"patching resident popup: %04x %04x [%04x %04x]\n",
+ checkQueue, checkWnd ? checkWnd->hwndSelf : 0, pTopPopupWnd->hmemTaskQ,
+ pTopPopupWnd->owner ? pTopPopupWnd->owner->hwndSelf : 0);
- if( wndOwner->hmemTaskQ == pTopPopupWnd->hmemTaskQ )
- return TRUE;
- hTask = QUEUE_GetQueueTask( wndOwner->hmemTaskQ );
- }
- else if( pTopPopupWnd->hmemTaskQ == checkQueue )
+ switch( checkQueue )
{
- /* switch to the different task */
+ case 0: /* checkWnd is the new popup owner */
+ if( checkWnd )
+ {
+ pTopPopupWnd->owner = checkWnd;
+ if( pTopPopupWnd->hmemTaskQ != checkWnd->hmemTaskQ )
+ hTask = QUEUE_GetQueueTask( checkWnd->hmemTaskQ );
+ }
+ break;
- hTask = QUEUE_GetQueueTask( pTopPopupWnd->hmemTaskQ );
- hTask = TASK_GetNextTask( hTask );
+ case 0xFFFF: /* checkWnd is destroyed */
+ if( pTopPopupWnd->owner == checkWnd )
+ pTopPopupWnd->owner = NULL;
+ return TRUE;
+
+ default: /* checkQueue is exiting */
+ if( pTopPopupWnd->hmemTaskQ == checkQueue )
+ {
+ hTask = QUEUE_GetQueueTask( pTopPopupWnd->hmemTaskQ );
+ hTask = TASK_GetNextTask( hTask );
+ }
+ break;
}
if( hTask )
{
TDB* task = (TDB*)GlobalLock16( hTask );
-
- pTopPopupWnd->owner = wndOwner;
if( task )
{
pTopPopupWnd->hInstance = task->hInstance;
@@ -3537,7 +3533,7 @@
if (!name) return 0;
/* check for Win32 module */
- instance = GetExePtr( instance );
+ instance = MODULE_HANDLEtoHMODULE16( instance );
if (MODULE_GetPtr(instance)->flags & NE_FFLAGS_WIN32)
return LoadMenu32A(instance,PTR_SEG_TO_LIN(name));
@@ -3837,7 +3833,7 @@
miia.cbSize = sizeof(miia);
miia.fMask = mii->fMask;
- miia.dwTypeData = miia.dwTypeData;
+ miia.dwTypeData = mii->dwTypeData;
miia.fType = mii->fType;
miia.fState = mii->fState;
miia.wID = mii->wID;
diff --git a/controls/progress.c b/controls/progress.c
new file mode 100644
index 0000000..c0311e2
--- /dev/null
+++ b/controls/progress.c
@@ -0,0 +1,208 @@
+/*
+ * Progress control
+ *
+ * Copyright 1997 Dimitrie O. Paun
+ *
+ * TODO:
+ * - I do not know what to to on WM_[SG]ET_FONT
+ * Problems:
+ * - I think I do not compute correctly the numer of leds to be drawn
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include "windows.h"
+#include "syscolor.h"
+#include "sysmetrics.h"
+#include "progress.h"
+#include "graphics.h"
+#include "heap.h"
+#include "win.h"
+#include "stddebug.h"
+#include "debug.h"
+
+/* Control configuration constants */
+
+#define LED_WIDTH 8
+#define LED_GAP 2
+
+/* Work constants */
+
+#define UNKNOWN_PARAM(msg, wParam, lParam) dprintf_progress(stddeb, \
+ "Progress Ctrl: Unknown parameter(s) for message " #msg \
+ "(%04x): wp=%04x lp=%08lx\n", msg, wParam, lParam);
+
+#define PROGRESS_GetInfoPtr(wndPtr) ((PROGRESS_INFO *)wndPtr->wExtra)
+
+
+/***********************************************************************
+ * PROGRESS_Paint
+ * Draw the arrows. The background need not be erased.
+ * If dc!=0, it draws on it
+ */
+static void PROGRESS_Paint(WND *wndPtr, HDC32 dc)
+{
+ PROGRESS_INFO *infoPtr = PROGRESS_GetInfoPtr(wndPtr);
+ HBRUSH32 ledBrush;
+ int rightBar, rightMost;
+ PAINTSTRUCT32 ps;
+ RECT32 rect;
+ HDC32 hdc;
+
+ dprintf_progress(stddeb, "Progress Bar: paint pos=%d min=%d, max=%d\n",
+ infoPtr->CurVal, infoPtr->MinVal, infoPtr->MaxVal);
+
+ /* get a dc */
+ hdc = dc==0 ? BeginPaint32(wndPtr->hwndSelf, &ps) : dc;
+
+ /* get the required brush */
+ ledBrush = GetSysColorBrush32(COLOR_HIGHLIGHT);
+
+ /* get rect for the bar, adjusted for the border */
+ GetClientRect32(wndPtr->hwndSelf, &rect);
+
+ /* draw the border */
+ DrawEdge32(hdc, &rect, BDR_SUNKENOUTER, BF_RECT|BF_ADJUST|BF_MIDDLE);
+ rect.left++; rect.right--; rect.top++; rect.bottom--;
+ rightMost = rect.right;
+
+ /* compute extent of progress bar */
+ rightBar = rect.left +
+ MulDiv32(infoPtr->CurVal-infoPtr->MinVal,
+ rect.right - rect.left,
+ infoPtr->MaxVal-infoPtr->MinVal);
+
+ /* now draw the bar */
+ while(rect.left < rightBar) {
+ rect.right = rect.left+LED_WIDTH;
+ FillRect32(hdc, &rect, ledBrush);
+ rect.left = rect.right+LED_GAP;
+ }
+
+ /* clean-up */
+ if(!dc)
+ EndPaint32(wndPtr->hwndSelf, &ps);
+}
+
+/***********************************************************************
+ * PROGRESS_CoercePos
+ * Makes sure the current position (CUrVal) is within bounds.
+ */
+static void PROGRESS_CoercePos(WND *wndPtr)
+{
+ PROGRESS_INFO *infoPtr = PROGRESS_GetInfoPtr(wndPtr);
+
+ if(infoPtr->CurVal < infoPtr->MinVal)
+ infoPtr->CurVal = infoPtr->MinVal;
+ if(infoPtr->CurVal > infoPtr->MaxVal)
+ infoPtr->CurVal = infoPtr->MaxVal;
+}
+
+/***********************************************************************
+ * ProgressWindowProc
+ */
+LRESULT WINAPI ProgressWindowProc(HWND32 hwnd, UINT32 message,
+ WPARAM32 wParam, LPARAM lParam)
+{
+ WND *wndPtr = WIN_FindWndPtr(hwnd);
+ PROGRESS_INFO *infoPtr = PROGRESS_GetInfoPtr(wndPtr);
+ UINT32 temp;
+
+ switch(message)
+ {
+ case WM_CREATE:
+ /* initialize the info struct */
+ infoPtr->MinVal=0;
+ infoPtr->MaxVal=100;
+ infoPtr->CurVal=0;
+ infoPtr->Step=10;
+ dprintf_updown(stddeb, "Progress Ctrl creation, hwnd=%04x\n", hwnd);
+ break;
+
+ case WM_DESTROY:
+ dprintf_updown(stddeb, "Progress Ctrl destruction, hwnd=%04x\n", hwnd);
+ break;
+
+ case WM_ERASEBKGND:
+ /* pretend to erase it here, but we will do it in the paint
+ function to avoid flicker */
+ return 1;
+
+ case WM_GETFONT:
+ /* FIXME: What do we need to do? */
+ break;
+
+ case WM_SETFONT:
+ /* FIXME: What do we need to do? */
+ break;
+
+ case WM_PAINT:
+ PROGRESS_Paint(wndPtr, wParam);
+ break;
+
+ case PBM_DELTAPOS:
+ if(lParam)
+ UNKNOWN_PARAM(PBM_DELTAPOS, wParam, lParam);
+ temp = infoPtr->CurVal;
+ if(wParam != 0){
+ infoPtr->CurVal += (UINT16)wParam;
+ PROGRESS_CoercePos(wndPtr);
+ PROGRESS_Paint(wndPtr, 0);
+ }
+ return temp;
+
+ case PBM_SETPOS:
+ if (lParam)
+ UNKNOWN_PARAM(PBM_SETPOS, wParam, lParam);
+ temp = infoPtr->CurVal;
+ if(temp != wParam){
+ infoPtr->CurVal = (UINT16)wParam;
+ PROGRESS_CoercePos(wndPtr);
+ PROGRESS_Paint(wndPtr, 0);
+ }
+ return temp;
+
+ case PBM_SETRANGE:
+ if (wParam)
+ UNKNOWN_PARAM(PBM_SETRANGE, wParam, lParam);
+ temp = MAKELONG(infoPtr->MinVal, infoPtr->MaxVal);
+ if(temp != lParam){
+ infoPtr->MinVal = LOWORD(lParam);
+ infoPtr->MaxVal = HIWORD(lParam);
+ if(infoPtr->MaxVal <= infoPtr->MinVal)
+ infoPtr->MaxVal = infoPtr->MinVal+1;
+ PROGRESS_CoercePos(wndPtr);
+ PROGRESS_Paint(wndPtr, 0);
+ }
+ return temp;
+
+ case PBM_SETSTEP:
+ if (lParam)
+ UNKNOWN_PARAM(PBM_SETSTEP, wParam, lParam);
+ temp = infoPtr->Step;
+ infoPtr->Step = (UINT16)wParam;
+ return temp;
+
+ case PBM_STEPIT:
+ if (wParam || lParam)
+ UNKNOWN_PARAM(PBM_STEPIT, wParam, lParam);
+ temp = infoPtr->CurVal;
+ infoPtr->CurVal += infoPtr->Step;
+ if(infoPtr->CurVal > infoPtr->MaxVal)
+ infoPtr->CurVal = infoPtr->MinVal;
+ if(temp != infoPtr->CurVal)
+ PROGRESS_Paint(wndPtr, 0);
+ return temp;
+
+ default:
+ if (message >= WM_USER)
+ fprintf( stderr, "Progress Ctrl: unknown msg %04x wp=%04x lp=%08lx\n",
+ message, wParam, lParam );
+ return DefWindowProc32A( hwnd, message, wParam, lParam );
+ }
+
+ return 0;
+}
+
+
+
diff --git a/controls/status.c b/controls/status.c
index 0732664..df14c53 100644
--- a/controls/status.c
+++ b/controls/status.c
@@ -41,34 +41,29 @@
void WINAPI DrawStatusText32A( HDC32 hdc, LPRECT32 lprc, LPCSTR text,
UINT32 style )
{
- RECT32 r, rt;
+ RECT32 r, rt;
int oldbkmode;
+ UINT32 border;
r = *lprc;
- if (style == 0 ||
- style == SBT_POPOUT) {
- InflateRect32(&r, -1, -1);
- SelectObject32(hdc, sysColorObjects.hbrushScrollbar);
- Rectangle32(hdc, r.left, r.top, r.right, r.bottom);
+ if(style == SBT_OWNERDRAW){
+ /* FIXME for SBT_OWNERDRAW, SBT_RTLREADING */
+ }
+ else{
+ DrawEdge32(hdc, &r, BDR_RAISEDINNER, BF_RECT|BF_ADJUST|BF_FLAT);
- /* draw border */
- SelectObject32(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) {
- SelectObject32(hdc, sysColorObjects.hbrushScrollbar);
- Rectangle32(hdc, r.left, r.top, r.right, r.bottom);
- }
- else { /* fixme for SBT_OWNERDRAW, SBT_RTLREADING */
-
- }
+ if(style==SBT_POPOUT)
+ border = BDR_RAISEDOUTER;
+ else if(style==SBT_NOBORDERS)
+ border = 0;
+ else
+ border = BDR_SUNKENOUTER;
- /* now draw text */
- if ((style != SBT_OWNERDRAW) && text) {
+ DrawEdge32(hdc, &r, border, BF_RECT | BF_ADJUST | BF_MIDDLE);
+
+ /* now draw text */
+ if (text) {
SelectObject32(hdc, sysColorObjects.hpenWindowText);
oldbkmode = SetBkMode32(hdc, TRANSPARENT);
rt = r;
@@ -77,8 +72,10 @@
&rt, DT_LEFT | DT_VCENTER | DT_SINGLELINE);
if (oldbkmode != TRANSPARENT)
- SetBkMode32(hdc, oldbkmode);
+ SetBkMode32(hdc, oldbkmode);
+ }
}
+
}
static BOOL32 SW_Refresh( HWND32 hwnd, HDC32 hdc, STATUSWINDOWINFO *self )
diff --git a/controls/uitools.c b/controls/uitools.c
new file mode 100644
index 0000000..b245ebc
--- /dev/null
+++ b/controls/uitools.c
@@ -0,0 +1,390 @@
+/*
+ * User Interface Functions
+ *
+ * Copyright 1997 Dimitrie O. Paun
+ */
+
+#include <stdio.h>
+#include "windows.h"
+#include "debug.h"
+
+/***********************************************************************
+ * UITOOLS_DrawDiagEdge
+ *
+ * Same as DrawEdge, but with BF_DIAGONAL
+ * I tested it extensively and as far as I can tell it is identical to the
+ * implementaion in Win95.
+ * I do not like that I create and
+ * use the 3 Pens to draw the diagonals. It would be better to draw them
+ * using the brushes returned by GetSysColorBrush func, but I did not have
+ * the patience to implement that yet.
+ */
+static BOOL32 UITOOLS_DrawDiagEdge(HDC32 hdc, RECT32 *rect, UINT32 edge,
+ UINT32 flags)
+{
+ HPEN32 facePen, shadowPen, lightPen, blackPen, grayPen, nullPen;
+ HPEN32 iPen, oPen, oldPen;
+ HBRUSH32 oldBrush, faceBrush;
+ int cl, cr, ct, cb;
+ BOOL32 mainDiag;
+ POINT32 tp;
+ RECT32 r;
+
+ /* If both rasied and sunken is specified, they anihilate one another */
+ if( !((flags & BF_MONO) || (flags & BF_FLAT)) ){
+ if( (edge & BDR_RAISEDOUTER) && (edge & BDR_SUNKENOUTER) )
+ return FALSE;
+ if( (edge & BDR_RAISEDINNER) && (edge & BDR_SUNKENINNER) )
+ return FALSE;
+ }
+
+ /* Create/get the tools of the trade... */
+ facePen = CreatePen32(PS_SOLID, 0, GetSysColor32(COLOR_BTNFACE));
+ shadowPen = CreatePen32(PS_SOLID, 0, GetSysColor32(COLOR_BTNSHADOW));
+ lightPen = CreatePen32(PS_SOLID, 0, GetSysColor32(COLOR_BTNHILIGHT));
+ grayPen = CreatePen32(PS_SOLID, 0, RGB(168, 152, 144));
+ blackPen = GetStockObject32(BLACK_PEN);
+ nullPen = GetStockObject32(NULL_PEN);
+ faceBrush = GetSysColorBrush32(COLOR_BTNFACE);
+ oldPen = SelectObject32(hdc, nullPen);
+ oldBrush = SelectObject32(hdc, faceBrush);
+
+ /* this is my working rectangle */
+ r = *rect;
+
+ if(flags & BF_MONO){
+ oPen = blackPen;
+ iPen = nullPen;
+ }else if(flags & BF_FLAT){
+ oPen = shadowPen;
+ iPen = facePen;
+ }else {
+ if(flags & BF_SOFT){
+ if(flags & BF_BOTTOM){
+ oPen = (edge & BDR_RAISEDOUTER) ? blackPen : lightPen;
+ iPen = (edge & BDR_RAISEDINNER) ? shadowPen : grayPen;
+ }
+ else{
+ oPen = (edge & BDR_RAISEDOUTER) ? lightPen : blackPen;
+ iPen = (edge & BDR_RAISEDINNER) ? grayPen : shadowPen;
+ }
+ }
+ else{
+ if(flags & BF_BOTTOM){
+ oPen = (edge & BDR_RAISEDOUTER) ? blackPen : lightPen;
+ iPen = (edge & BDR_RAISEDINNER) ? shadowPen : grayPen;
+ }
+ else{
+ oPen = (edge & BDR_RAISEDOUTER) ? grayPen : shadowPen;
+ iPen = (edge & BDR_RAISEDINNER) ? lightPen : blackPen;
+ }
+ }
+ }
+
+ if(flags & BF_BOTTOM){
+ if(flags & BF_LEFT){
+ cr = -1; cl = 0;
+ ct = 0; cb = -1;
+ mainDiag = TRUE;
+ tp.x = r.left; tp.y = r.top;
+ }
+ else{ /* RIGHT */
+ cr = -1; cl = 0;
+ ct = 1; cb = 0;
+ tp.x = r.left; tp.y = r.bottom-1;
+ mainDiag = FALSE;
+ }
+ }
+ else{ /* TOP */
+ if(flags & BF_LEFT){
+ cr = 0; cl = 1;
+ ct = 0; cb = -1;
+ mainDiag = FALSE;
+ tp.x = r.right; tp.y = r.top;
+ }
+ else{ /* RIGHT */
+ cr = 0; cl = 1;
+ ct = 1; cb = 0;
+ tp.x = r.right; tp.y = r.bottom-1;
+ mainDiag = TRUE;
+ }
+ }
+
+ /* if it has external edge, draw it */
+ if(edge & BDR_OUTER){
+ SelectObject32(hdc, oPen);
+ MoveToEx32(hdc, r.left, mainDiag ? r.bottom-1 : r.top, 0);
+ LineTo32(hdc, r.right, mainDiag ? r.top-1 : r.bottom);
+ r.left += cl; r.right += cr; r.top += ct; r.bottom += cb;
+ }
+
+ /* if it has internal edge, draw it */
+ if(edge & BDR_INNER){
+ SelectObject32(hdc, iPen);
+ MoveToEx32(hdc, r.left, mainDiag ? r.bottom-1 : r.top, 0);
+ LineTo32(hdc, r.right, mainDiag ? r.top-1 : r.bottom);
+ r.left += cl; r.right += cr; r.top += ct; r.bottom += cb;
+ }
+
+ if((flags & BF_MIDDLE) && !(flags & BF_MONO)){
+ POINT32 p[3];
+ p[0].x = mainDiag ? r.right: r.left;
+ p[0].y = r.top;
+ p[1].x = mainDiag ? r.left : r.right;
+ p[1].y = r.bottom;
+ p[2].x = tp.x;
+ p[2].y = tp.y;
+ SelectObject32(hdc, nullPen);
+ SelectObject32(hdc, faceBrush);
+ Polygon32(hdc, p, 3);
+ }
+
+ if(flags & BF_ADJUST)
+ *rect = r;
+
+ /* Restore the DC */
+ SelectObject32(hdc, oldPen);
+ SelectObject32(hdc, oldBrush);
+
+ /* Clean-up */
+ DeleteObject32(facePen);
+ DeleteObject32(shadowPen);
+ DeleteObject32(lightPen);
+ DeleteObject32(grayPen);
+
+ return TRUE;
+}
+
+
+/***********************************************************************
+ * UITOOLS_DrawRectEdge
+ *
+ * Same as DrawEdge, but without BF_DIAGONAL
+ * I tested this function and it works very well. You should not change it
+ * unless you find a bug. If you don't like the colors, it it not its
+ * fault - the system colors are not OK.
+ * Again, I tested this function on Win95 and I compared the output with the
+ * one generated by the native DrawEdge and it is identical on all cases that
+ * I tried, and I tried quite a few.
+ */
+static BOOL32 UITOOLS_DrawRectEdge(HDC32 hdc, RECT32 *rect,
+ UINT32 edge, UINT32 flags)
+{
+ HBRUSH32 faceBrush, shadowBrush, lightBrush, blackBrush, grayBrush, nullBrush;
+ HBRUSH32 iNBrush, iSBrush, iEBrush, iWBrush;
+ HBRUSH32 oNBrush, oSBrush, oEBrush, oWBrush;
+ HBRUSH32 oldBrush;
+ RECT32 r;
+
+ /* If both rasied and sunken is specified, they anihilate one another */
+ if( !((flags & BF_MONO) || (flags & BF_FLAT)) ){
+ if( (edge & BDR_RAISEDOUTER) && (edge & BDR_SUNKENOUTER) )
+ return FALSE;
+ if( (edge & BDR_RAISEDINNER) && (edge & BDR_SUNKENINNER) )
+ return FALSE;
+ }
+
+ faceBrush = GetSysColorBrush32(COLOR_BTNFACE);
+ shadowBrush = GetSysColorBrush32(COLOR_BTNSHADOW);
+ lightBrush = GetSysColorBrush32(COLOR_BTNHILIGHT);
+ blackBrush = GetStockObject32(BLACK_BRUSH);
+ grayBrush = GetStockObject32(LTGRAY_BRUSH);
+ nullBrush = GetStockObject32(NULL_BRUSH);
+ oldBrush = SelectObject32(hdc, nullBrush);
+
+ /* this is my working rectangle */
+ r = *rect;
+
+ if(flags & BF_MONO){
+ oNBrush = oSBrush = oEBrush = oWBrush = blackBrush;
+ iNBrush = iSBrush = iEBrush = iWBrush = nullBrush;
+ }else if(flags & BF_FLAT){
+ oNBrush = oSBrush = oEBrush = oWBrush = shadowBrush;
+ iNBrush = iSBrush = iEBrush = iWBrush = faceBrush;
+ }else {
+ if(flags & BF_SOFT){
+ oNBrush = oWBrush = (edge & BDR_RAISEDOUTER) ? lightBrush : blackBrush;
+ oSBrush = oEBrush = (edge & BDR_RAISEDOUTER) ? blackBrush : lightBrush;
+ iNBrush = iWBrush = (edge & BDR_RAISEDINNER) ? grayBrush : shadowBrush;
+ iSBrush = iEBrush = (edge & BDR_RAISEDINNER) ? shadowBrush : grayBrush;
+ }
+ else{
+ oNBrush = oWBrush = (edge & BDR_RAISEDOUTER) ? grayBrush : shadowBrush;
+ oSBrush = oEBrush = (edge & BDR_RAISEDOUTER) ? blackBrush : lightBrush;
+ iNBrush = iWBrush = (edge & BDR_RAISEDINNER) ? lightBrush : blackBrush;
+ iSBrush = iEBrush = (edge & BDR_RAISEDINNER) ? shadowBrush : grayBrush;
+ }
+ }
+
+ /* if it has external edge, draw it */
+ if(edge & BDR_OUTER){
+ if(flags & BF_RIGHT){
+ SelectObject32(hdc, oEBrush);
+ PatBlt32(hdc, r.right-1, r.top, 1, r.bottom - r.top, PATCOPY);
+ r.right--;
+ }
+ if(flags & BF_BOTTOM){
+ SelectObject32(hdc, oSBrush);
+ PatBlt32(hdc, r.left, r.bottom-1, r.right-r.left, 1, PATCOPY);
+ r.bottom--;
+ }
+ if(flags & BF_LEFT){
+ SelectObject32(hdc, oWBrush);
+ PatBlt32(hdc, r.left, r.top, 1, r.bottom - r.top, PATCOPY);
+ r.left++;
+ }
+ if(flags & BF_TOP){
+ SelectObject32(hdc, oNBrush);
+ PatBlt32(hdc, r.left, r.top, r.right-r.left, 1, PATCOPY);
+ r.top++;
+ }
+ }
+
+ /* if it has internal edge, draw it */
+ if(edge & BDR_INNER){
+ if(flags & BF_RIGHT){
+ SelectObject32(hdc, iEBrush);
+ PatBlt32(hdc, r.right-1, r.top, 1, r.bottom - r.top, PATCOPY);
+ r.right--;
+ }
+ if(flags & BF_BOTTOM){
+ SelectObject32(hdc, iSBrush);
+ PatBlt32(hdc, r.left, r.bottom-1, r.right-r.left, 1, PATCOPY);
+ r.bottom--;
+ }
+ if(flags & BF_LEFT){
+ SelectObject32(hdc, iWBrush);
+ PatBlt32(hdc, r.left, r.top, 1, r.bottom - r.top, PATCOPY);
+ r.left++;
+ }
+ if(flags & BF_TOP){
+ SelectObject32(hdc, iNBrush);
+ PatBlt32(hdc, r.left, r.top, r.right-r.left, 1, PATCOPY);
+ r.top++;
+ }
+ }
+
+ /* if we got to fill the middle, to it now */
+ if((flags & BF_MIDDLE) && !(flags & BF_MONO))
+ FillRect32(hdc, &r, faceBrush);
+
+ /* adjust the rectangle if required */
+ if(flags & BF_ADJUST)
+ *rect = r;
+
+ /* Restore the DC */
+ SelectObject32(hdc, oldBrush);
+
+ return TRUE;
+}
+
+
+/**********************************************************************
+ * DrawEdge16 (USER.659)
+ */
+BOOL16 WINAPI DrawEdge16( HDC16 hdc, LPRECT16 rc, UINT16 edge, UINT16 flags )
+{
+ RECT32 rect32;
+ BOOL32 ret;
+
+ CONV_RECT16TO32( rc, &rect32 );
+ ret = DrawEdge32( hdc, &rect32, edge, flags );
+ CONV_RECT32TO16( &rect32, rc );
+ return ret;
+}
+
+/**********************************************************************
+ * DrawEdge32 (USER32.154)
+ */
+BOOL32 WINAPI DrawEdge32( HDC32 hdc, LPRECT32 rc, UINT32 edge, UINT32 flags )
+{
+ dprintf_graphics( stddeb, "DrawEdge: %04x %d,%d-%d,%d %04x %04x\n",
+ hdc, rc->left, rc->top, rc->right, rc->bottom,
+ edge, flags );
+
+ if(flags & BF_DIAGONAL)
+ return UITOOLS_DrawDiagEdge(hdc, rc, edge, flags);
+ else
+ return UITOOLS_DrawRectEdge(hdc, rc, edge, flags);
+}
+
+
+/***********************************************************************
+ * UITOOLS_DrawFrameButton
+ */
+static BOOL32 UITOOLS_DrawFrameButton(HDC32 hdc, LPRECT32 rc, UINT32 uState)
+{
+ fprintf( stdnimp,"DrawFrameButton(%x,%p,%x), empty stub!\n",
+ hdc,rc,uState );
+ return FALSE;
+}
+
+/***********************************************************************
+ * UITOOLS_DrawFrameCaption
+ */
+static BOOL32 UITOOLS_DrawFrameCaption(HDC32 hdc, LPRECT32 rc, UINT32 uState)
+{
+ fprintf( stdnimp,"DrawFrameCaption(%x,%p,%x), empty stub!\n",
+ hdc,rc,uState );
+ return FALSE;
+}
+
+/***********************************************************************
+ * UITOOLS_DrawFrameMenu
+ */
+static BOOL32 UITOOLS_DrawFrameMenu(HDC32 hdc, LPRECT32 rc, UINT32 uState)
+{
+ fprintf( stdnimp,"DrawFrameMenu32(%x,%p,%x), empty stub!\n",
+ hdc,rc,uState );
+ return FALSE;
+}
+
+/***********************************************************************
+ * UITOOLS_DrawFrameScroll
+ */
+static BOOL32 UITOOLS_DrawFrameScroll(HDC32 hdc, LPRECT32 rc, UINT32 uState)
+{
+ fprintf( stdnimp,"DrawFrameScroll32(%x,%p,%x), empty stub!\n",
+ hdc,rc,uState );
+ return FALSE;
+}
+
+
+/**********************************************************************
+ * DrawFrameControl16 (USER.656)
+ */
+BOOL16 WINAPI DrawFrameControl16( HDC16 hdc, LPRECT16 rc, UINT16 uType,
+ UINT16 uState )
+{
+ RECT32 rect32;
+ BOOL32 ret;
+
+ CONV_RECT16TO32( rc, &rect32 );
+ ret = DrawFrameControl32( hdc, &rect32, uType, uState );
+ CONV_RECT32TO16( &rect32, rc );
+ return ret;
+}
+
+
+/**********************************************************************
+ * DrawFrameControl32 (USER32.157)
+ */
+BOOL32 WINAPI DrawFrameControl32( HDC32 hdc, LPRECT32 rc, UINT32 uType,
+ UINT32 uState )
+{
+ switch(uType)
+ {
+ case DFC_BUTTON:
+ return UITOOLS_DrawFrameButton(hdc, rc, uState);
+ case DFC_CAPTION:
+ return UITOOLS_DrawFrameCaption(hdc, rc, uState);
+ case DFC_MENU:
+ return UITOOLS_DrawFrameMenu(hdc, rc, uState);
+ case DFC_SCROLL:
+ return UITOOLS_DrawFrameScroll(hdc, rc, uState);
+ default:
+ fprintf( stdnimp,"DrawFrameControl32(%x,%p,%d,%x), bad type!\n",
+ hdc,rc,uType,uState );
+ }
+ return FALSE;
+}
diff --git a/controls/updown.c b/controls/updown.c
index a3a75ef..4282300 100644
--- a/controls/updown.c
+++ b/controls/updown.c
@@ -8,6 +8,7 @@
* arrow keys
* - I am not sure about the default values for the Min, Max, Pos
* (in the UPDOWN_INFO the fields: MinVal, MaxVal, CurVal)
+ * - I think I do not handle correctly the WS_BORDER style.
* Testing:
* Not much. The following have not been tested at all:
* - horizontal arrows
@@ -20,10 +21,7 @@
* behave very well so I am confident it does work in most (all) of the
* untested cases.
* Problems:
- * At the moment, the control will no draw itself very well because it
- * uses some features in DrawEdge that are not yet implemented.
- * In other words, there is no known problem, exempt for the things in
- * the TODO list above.
+ * I do not like the arrows yet, I'll work more on them later on.
*/
#include <stdlib.h>
@@ -47,10 +45,10 @@
#define INITIAL_DELAY 500 /* initial timer until auto-increment kicks in */
#define REPEAT_DELAY 50 /* delay between auto-increments */
-#define DEFAULT_WIDTH 10 /* default width of the ctrl */
-#define DEFAULT_XSEP 0 /* default separation between buddy and crtl */
-#define DEFAULT_ADDTOP 1 /* amount to extend above the buddy window */
-#define DEFAULT_ADDBOT 1 /* amount to extend below the buddy window */
+#define DEFAULT_WIDTH 14 /* default width of the ctrl */
+#define DEFAULT_XSEP 0 /* default separation between buddy and crtl */
+#define DEFAULT_ADDTOP 0 /* amount to extend above the buddy window */
+#define DEFAULT_ADDBOT 0 /* amount to extend below the buddy window */
/* Work constants */
@@ -65,9 +63,6 @@
static int accelIndex = -1;
-#define max(a,b) ((a)>(b)?(a):(b))
-#define min(a,b) ((a)<(b)?(a):(b))
-
#define UNKNOWN_PARAM(msg, wParam, lParam) dprintf_updown(stddeb, \
"UpDown Ctrl: Unknown parameter(s) for message " #msg \
"(%04x): wp=%04x lp=%08lx\n", msg, wParam, lParam);
@@ -129,7 +124,7 @@
if (wndPtr->dwStyle & UDS_HORZ) {
len = rect->right - rect->left; /* compute the width */
if (incr)
- rect->left = len/2;
+ rect->left = len/2+1;
else
rect->right = len/2;
}
@@ -138,7 +133,7 @@
if (incr)
rect->bottom = len/2;
else
- rect->top = len/2;
+ rect->top = len/2+1;
}
}
@@ -290,48 +285,57 @@
static void UPDOWN_DrawArrow(HDC32 hdc, RECT32 *rect, BOOL32 incr,
BOOL32 pressed, BOOL32 horz)
{
- const int w = rect->right - rect->left;
- const int h = rect->bottom - rect->top;
- int offset = pressed ? 1 : 0, tmp;
- POINT32 pts[3];
+ const int rw = rect->right - rect->left;
+ const int rh = rect->bottom - rect->top;
+ int offset = pressed ? 1 : 0;
+ int th, x, y, len;
+ /* compute max extents of the triangle */
if(horz){ /* horizontal arrows */
- pts[0].x = rect->right - max(2, w/3) + offset;
- pts[0].y = rect->top + max(2, h/4) + offset;
- pts[1].x = pts[0].x;
- pts[1].y = rect->bottom - max(2, h/4) + offset;
- pts[2].x = rect->left + w/3 + offset;
- pts[2].y = (pts[0].y + pts[1].y)/2;
- if(pts[2].x-2<rect->left)
- pts[2].x = rect->left + 2;
- if(pts[2].x <= pts[0].x)
- pts[2].x = pts[0].x - 1;
+ th = (3*rh)/5-2*4;
+ if(th > rw/2)
+ th = rw/2;
+ if(th < 2)
+ th = 2;
- if(incr){
- tmp = pts[2].x;
- pts[2].x = pts[0].x;
- pts[0].x = pts[1].x = tmp;
- }
+ /* compute the position of the tip */
+ y = (rect->top+rect->bottom+1)/2 + offset;
+ if(incr)
+ x = (rect->left+rect->right+1)/2 + (2*th)/3 + offset;
+ else
+ x = (rect->left+rect->right)/2 + th/3 + offset;
+
+ for(len=1; th>0; th--, len+=2){
+ MoveToEx32(hdc, x, y, 0);
+ LineTo32(hdc, x, y+len);
+ if(incr) x--;
+ else x++;
+ y++;
+ }
}
else{ /* vertical arrows */
- pts[0].x = rect->left + max(2, w/4) + offset;
- pts[0].y = rect->top + max(2, h/3) + offset;
- pts[1].x = rect->right- max(2, w/4) + offset;
- pts[1].y = pts[0].y;
- pts[2].x = (pts[0].x + pts[1].x)/2;
- pts[2].y = pts[0].y + h/3 + offset;
- if(pts[2].y+2>rect->bottom)
- pts[2].y = rect->bottom - 2;
- if(pts[2].y <= pts[0].y)
- pts[2].y = pts[0].y + 1;
+ th = (3*rw)/5-2*4;
+ if(th > rh/2)
+ th = rh/2;
+ if(th < 2)
+ th = 2;
- if(incr){
- tmp = pts[2].y;
- pts[2].y = pts[0].y;
- pts[0].y = pts[1].y = tmp;
+ /* compute the position of the tip */
+ x = (rect->left+rect->right+1)/2 + offset;
+ if(incr)
+ y = (rect->top+rect->bottom+1)/2 - th/3 + offset;
+ else
+ y = (rect->top+rect->bottom)/2 + (2*th)/3 + offset;
+
+ for(len=1; th>0; th--, len+=2){
+ MoveToEx32(hdc, x, y, 0);
+ LineTo32(hdc, x+len, y);
+ if(incr) y++;
+ else y--;
+ x--;
}
+
}
- Polygon32(hdc, pts, 3);
}
@@ -350,14 +354,6 @@
hdc = BeginPaint32( wndPtr->hwndSelf, &ps );
- /*FIXME - this is just for test */
- /* - when DrawEdge works properly, this should dissapear
- as DrawEdge will erase the background */
-/*oldBrush = SelectObject32(hdc, GetStockObject32(GRAY_BRUSH));
- GetClientRect32(wndPtr->hwndSelf, &rect);
- Rectangle32(hdc, rect.left, rect.top, rect.right, rect.bottom);
- SelectObject32(hdc, oldBrush);*/
-
/* First select the proper brush */
oldBrush = wndPtr->dwStyle & WS_DISABLED ? GRAY_BRUSH : BLACK_BRUSH;
oldBrush = SelectObject32(hdc, GetStockObject32(oldBrush));
@@ -365,9 +361,12 @@
/* Draw the incr button */
UPDOWN_GetArrowRect(wndPtr, &rect, TRUE);
prssed = (infoPtr->Flags & FLAG_INCR) && (infoPtr->Flags & FLAG_MOUSEIN);
- DrawEdge32(hdc, &rect, prssed ? EDGE_SUNKEN : EDGE_RAISED,
- BF_RECT | BF_SOFT | BF_MIDDLE);
+ DrawEdge32(hdc, &rect, prssed?EDGE_SUNKEN:EDGE_RAISED, BF_RECT|BF_MIDDLE);
UPDOWN_DrawArrow(hdc, &rect, TRUE, prssed, wndPtr->dwStyle & UDS_HORZ);
+
+ /* Draw the space between the buttons */
+ rect.top = rect.bottom; rect.bottom++;
+ DrawEdge32(hdc, &rect, 0, BF_MIDDLE);
/* Draw the decr button */
UPDOWN_GetArrowRect(wndPtr, &rect, FALSE);
@@ -634,7 +633,7 @@
* UpDownWndProc
*/
LRESULT WINAPI UpDownWindowProc(HWND32 hwnd, UINT32 message, WPARAM32 wParam,
- LPARAM lParam)
+ LPARAM lParam)
{
WND *wndPtr = WIN_FindWndPtr(hwnd);
UPDOWN_INFO *infoPtr = UPDOWN_GetInfoPtr(wndPtr);
@@ -643,6 +642,9 @@
switch(message)
{
case WM_CREATE:
+ /* get rid of border, if any */
+ wndPtr->dwStyle &= ~WS_BORDER;
+
/* initialize the info struct */
infoPtr->AccelCount=0; infoPtr->AccelVect=0;
infoPtr->CurVal=0; infoPtr->MinVal=0; infoPtr->MaxVal=100; /*FIXME*/
@@ -745,7 +747,7 @@
UNKNOWN_PARAM(UDM_GETACCEL, wParam, lParam);
return 0;
}
- temp = min(infoPtr->AccelCount, wParam);
+ temp = MIN(infoPtr->AccelCount, wParam);
memcpy((void *)lParam, infoPtr->AccelVect, temp*sizeof(UDACCEL));
return temp;
diff --git a/controls/widgets.c b/controls/widgets.c
index c8b9990..9c1d4a3 100644
--- a/controls/widgets.c
+++ b/controls/widgets.c
@@ -9,8 +9,10 @@
#include "win.h"
#include "commctrl.h"
#include "button.h"
+#include "progress.h"
#include "static.h"
#include "status.h"
+#include "updown.h"
#include "scroll.h"
#include "updown.h"
#include "desktop.h"
@@ -104,7 +106,9 @@
{ CS_GLOBALCLASS | CS_VREDRAW | CS_HREDRAW, StatusWindowProc, 0,
sizeof(STATUSWINDOWINFO), 0, 0, 0, 0, 0, STATUSCLASSNAME32A },
{ CS_GLOBALCLASS | CS_VREDRAW | CS_HREDRAW, UpDownWindowProc, 0,
- sizeof(UPDOWN_INFO), 0, 0, 0, 0, 0, UPDOWN_CLASS32A }
+ sizeof(UPDOWN_INFO), 0, 0, 0, 0, 0, UPDOWN_CLASS32A },
+ { CS_GLOBALCLASS | CS_VREDRAW | CS_HREDRAW, ProgressWindowProc, 0,
+ sizeof(PROGRESS_INFO), 0, 0, 0, 0, 0, PROGRESS_CLASS32A }
};
#define NB_COMMON_CONTROLS32 \
@@ -155,6 +159,8 @@
if (!(bicAtomTable[i] = RegisterClass32A( class32 ))) return FALSE;
}
+ /* FIXME: hack to enable using built-in controls with Windows COMCTL32 */
+ InitCommonControls();
SEGPTR_FREE(name);
return TRUE;
}
@@ -167,15 +173,18 @@
{
int i;
char name[30];
+ const char *old_name;
WNDCLASS32A *class32 = WIDGETS_CommonControls32;
for (i = 0; i < NB_COMMON_CONTROLS32; i++, class32++)
{
/* Just to make sure the string is > 0x10000 */
+ old_name = class32->lpszClassName;
strcpy( name, (char *)class32->lpszClassName );
class32->lpszClassName = name;
class32->hCursor = LoadCursor16( 0, IDC_ARROW );
RegisterClass32A( class32 );
+ class32->lpszClassName = old_name;
}
}