From e399fc3636e9bbe378cb9af6fc95a7e4ae9d4076 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Wed, 24 Nov 1993 17:08:56 +0000 Subject: [PATCH] Release 0.4.10 Mon Nov 22 13:58:56 1993 David Metcalfe * [windows/scroll.c] Preliminary implementations of ScrollWindow, ScrollDC and ScrollWindowEx. Nov 21, 93 martin2@trgcorp.solucorp.qc.ca (Martin Ayotte) * [controls/listbox.c] Optimization of redraw during 'Add' or 'Insert'. * [controls/scroll.c] Optimization of WM_PAINT during 'thumbtracking'. * [controls/button.c] Add of beta implement of 'BS_OWNERDRAW' * [controls/static.c] Style 'SS_ICON' new supported. * [misc/message.c] Begin of implemantation of MB_XXX styles. * [loader/resource.c] Function LoadIcon() : now prepare transparency Bitmap mask. Function LoadCursor() : now prepare a 'X pixmapcursor'. New function SetCursor() : not finished. New function ShowCursor() : not finished. New function AccessResource() : stub. * [obj/dib.c] Function DrawIcon(): deugging phase of icon transparency mask. * [loader/library.c] new file for news functions LoadLibrary() & FreeLibrary(). * [sysres.dll] Resources only 16bits DLL for System Resources, icons, etc... Sun Nov 14 14:39:06 1993 julliard@di.epfl.ch (Alexandre Julliard) * [include/dialog.h] [windows/dialog.c] Simplified dialog template parsing. Implemented DialogBoxIndirect(). * [windows/win.c] Fixed bug in CreateWindow() when aborting window creation. Modified UpdateWindow() to only update visible windows. Implemented IsWindow(). Nov 14, 93 martin2@trgcorp.solucorp.qc.ca (Martin Ayotte) * [controls/listbox.c] Listbox control window : new messages. * [controls/combo.c] Combo box control window : new messages. * [misc/message.c] Moved stub MessageBox() to this new file. Implemented of a callback, now MessageBox show a window. * [loader/resource.c] New function DestroyIcon() New function DestroyCursor() Filled stub LoadIcon() Filled stub LoadCursor() Bug fixed in FindResourceByName() : missing lseek(). * [obj/dib.c] New function DrawIcon() * [windows/win.c] New function CloseWindow() New function OpenIcon() New function IsIconic() New Function FindWindow() Sun Nov 14 08:27:19 1993 Karl Guenter Wuensch (hz225wu@unidui.uni-duisburg.de) * [loader/selector.c] Wrote AllocCStoDSAlias() and AllocDStoCSAlias() Sun Nov 14 08:27:19 1993 Bob Amstadt (bob at amscons) * [loader/selector.c] Wrote AllocSelector() and PrestoChangoSelector(). YUK! Sat Nov 13 13:56:42 1993 Bob Amstadt (bob at amscons) * [loader/resource.c] Wrote FindResource(), LoadResource(), LockResource(), and FreeResource() * [include/segmem.h] [loader/selector.c] [loader/signal.h] Changed selector allocation method. Sun Nov 10 08:27:19 1993 Karl Guenter Wuensch (hz225wu@unidui.uni-duisburg.de) * [if1632/callback.c if1632/call.S if1632/user.spec] added Catch (KERNEL.55) and Throw (KERNEL.56) Nov 7, 93 martin2@trgcorp.solucorp.qc.ca (Martin Ayotte) * [controls/scroll.c] Scroll bar control window Bug resolved : Painting message before scroll visible. * [controls/listbox.c] Listbox control window Destroy cleanup. * [controls/combo.c] Combo box control window Destroy cleanup. * [controls/button.c] GetCheck Message now return is state. * [windows/win.c] New function IsWindowVisible() --- ChangeLog | 123 +++++++ Makefile | 2 +- README | 13 + controls/button.c | 117 ++++++- controls/combo.c | 120 +++++-- controls/listbox.c | 71 ++-- controls/scroll.c | 135 +++++--- controls/static.c | 58 +++- if1632/call.S | 61 ++-- if1632/callback.c | 80 +++++ if1632/kernel.spec | 10 + if1632/relay.c | 9 +- if1632/user.spec | 21 ++ include/cursor.h | 27 ++ include/dialog.h | 10 - include/icon.h | 26 ++ include/segmem.h | 13 + include/windows.h | 163 +++++++-- loader/Makefile | 2 +- loader/files.c | 1 + loader/int21.c | 5 +- loader/library.c | 37 ++ loader/resource.c | 456 ++++++++++++++++++++++-- loader/selector.c | 464 ++++++++++++++----------- loader/signal.c | 5 +- loader/wine.c | 6 +- memory/global.c | 2 +- misc/Makefile | 2 +- misc/exec.c | 4 +- misc/message.c | 264 ++++++++++++++ misc/xt.c | 11 - objects/color.c | 2 +- objects/dib.c | 44 +++ sysres.dll | Bin 0 -> 66048 bytes test/btnlook.c | 146 -------- test/btnlook.exe | Bin 11987 -> 12021 bytes test/martin_ship2/widget.c | 442 ------------------------ test/martin_ship2/widget.def | 23 -- test/martin_ship2/widget.h | 250 -------------- test/martin_ship2/widget.ic2 | Bin 1094 -> 0 bytes test/martin_ship2/widget.ic3 | Bin 766 -> 0 bytes test/martin_ship2/widget.ico | Bin 766 -> 0 bytes test/martin_ship2/widget.rc | 78 ----- test/martin_ship4/widget.c | 649 ----------------------------------- test/martin_ship4/widget.exe | Bin 35298 -> 0 bytes test/widget.exe | Bin 23634 -> 140094 bytes windows/Makefile | 2 +- windows/dialog.c | 195 +++++++---- windows/event.c | 26 +- windows/scroll.c | 171 +++++++++ windows/win.c | 147 ++++++-- 51 files changed, 2357 insertions(+), 2136 deletions(-) create mode 100644 include/cursor.h create mode 100644 include/icon.h create mode 100644 loader/library.c create mode 100644 misc/message.c create mode 100755 sysres.dll delete mode 100755 test/btnlook.c delete mode 100755 test/martin_ship2/widget.c delete mode 100755 test/martin_ship2/widget.def delete mode 100755 test/martin_ship2/widget.h delete mode 100755 test/martin_ship2/widget.ic2 delete mode 100755 test/martin_ship2/widget.ic3 delete mode 100755 test/martin_ship2/widget.ico delete mode 100755 test/martin_ship2/widget.rc delete mode 100755 test/martin_ship4/widget.c delete mode 100755 test/martin_ship4/widget.exe create mode 100644 windows/scroll.c diff --git a/ChangeLog b/ChangeLog index 086760be77c..ebf46f14a76 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,126 @@ +Mon Nov 22 13:58:56 1993 David Metcalfe + + * [windows/scroll.c] + Preliminary implementations of ScrollWindow, ScrollDC and + ScrollWindowEx. + +Nov 21, 93 martin2@trgcorp.solucorp.qc.ca (Martin Ayotte) + + * [controls/listbox.c] + Optimization of redraw during 'Add' or 'Insert'. + + * [controls/scroll.c] + Optimization of WM_PAINT during 'thumbtracking'. + + * [controls/button.c] + Add of beta implement of 'BS_OWNERDRAW' + + * [controls/static.c] + Style 'SS_ICON' new supported. + + * [misc/message.c] + Begin of implemantation of MB_XXX styles. + + * [loader/resource.c] + Function LoadIcon() : now prepare transparency Bitmap mask. + Function LoadCursor() : now prepare a 'X pixmapcursor'. + New function SetCursor() : not finished. + New function ShowCursor() : not finished. + New function AccessResource() : stub. + + * [obj/dib.c] + Function DrawIcon(): deugging phase of icon transparency mask. + + * [loader/library.c] + new file for news functions LoadLibrary() & FreeLibrary(). + + * [sysres.dll] + Resources only 16bits DLL for System Resources, icons, etc... + +---------------------------------------------------------------------- +Sun Nov 14 14:39:06 1993 julliard@di.epfl.ch (Alexandre Julliard) + + * [include/dialog.h] [windows/dialog.c] + Simplified dialog template parsing. + Implemented DialogBoxIndirect(). + + * [windows/win.c] + Fixed bug in CreateWindow() when aborting window creation. + Modified UpdateWindow() to only update visible windows. + Implemented IsWindow(). + +Nov 14, 93 martin2@trgcorp.solucorp.qc.ca (Martin Ayotte) + + * [controls/listbox.c] + Listbox control window : new messages. + + * [controls/combo.c] + Combo box control window : new messages. + + * [misc/message.c] + Moved stub MessageBox() to this new file. + Implemented of a callback, now MessageBox show a window. + + * [loader/resource.c] + New function DestroyIcon() + New function DestroyCursor() + Filled stub LoadIcon() + Filled stub LoadCursor() + Bug fixed in FindResourceByName() : missing lseek(). + + * [obj/dib.c] + New function DrawIcon() + + * [windows/win.c] + New function CloseWindow() + New function OpenIcon() + New function IsIconic() + New Function FindWindow() + +Sun Nov 14 08:27:19 1993 Karl Guenter Wuensch (hz225wu@unidui.uni-duisburg.de) + + * [loader/selector.c] + Wrote AllocCStoDSAlias() and AllocDStoCSAlias() + +Sun Nov 14 08:27:19 1993 Bob Amstadt (bob at amscons) + + * [loader/selector.c] + Wrote AllocSelector() and PrestoChangoSelector(). YUK! + +Sat Nov 13 13:56:42 1993 Bob Amstadt (bob at amscons) + + * [loader/resource.c] + Wrote FindResource(), LoadResource(), LockResource(), + and FreeResource() + + * [include/segmem.h] [loader/selector.c] [loader/signal.h] + Changed selector allocation method. + +Sun Nov 10 08:27:19 1993 Karl Guenter Wuensch (hz225wu@unidui.uni-duisburg.de) + + * [if1632/callback.c if1632/call.S if1632/user.spec] + added Catch (KERNEL.55) and Throw (KERNEL.56) + +Nov 7, 93 martin2@trgcorp.solucorp.qc.ca (Martin Ayotte) + + * [controls/scroll.c] + Scroll bar control window + Bug resolved : Painting message before scroll visible. + + * [controls/listbox.c] + Listbox control window + Destroy cleanup. + + * [controls/combo.c] + Combo box control window + Destroy cleanup. + + * [controls/button.c] + GetCheck Message now return is state. + + * [windows/win.c] + New function IsWindowVisible() + Mon Nov 1 14:40:21 1993 julliard@di.epfl.ch (Alexandre Julliard) * [if1632/user.spec] diff --git a/Makefile b/Makefile index 8b508d988a3..11a884a9bbf 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ ###################################################################### # These variables are inherited by the sub-makefiles -DEBUGOPTS=-DDEBUG_RESOURCE +DEBUGOPTS= COPTS=-O2 -m486 INCLUDE_DIR=include LDFLAGS= diff --git a/README b/README index 9e326d62703..ba0b81b1a75 100644 --- a/README +++ b/README @@ -31,6 +31,19 @@ For example, to run Windows' solitaire: Have a nice game of solitaire, but be careful. Emulation isn't perfect. So, occassionally it will crash. +WHAT'S NEW with version 0.4.10: (see ChangeLog for details) + - Bug fixes + - More scroll bar functions + - More icon and cursor handling + +WHAT'S NEW with version 0.4.9: (see ChangeLog for details) + - Bug fixes + - real MessageBox() + - New resource functions + - Icon functions + - Selector manipulation functions + - Catch()/Throw() + WHAT'S NEW with version 0.4.7: (see ChangeLog for details) - More dialog box functions - More DOS interrupts diff --git a/controls/button.c b/controls/button.c index 1a13b9d8223..aad2aa10ca8 100644 --- a/controls/button.c +++ b/controls/button.c @@ -9,6 +9,7 @@ static char Copyright2[] = "Copyright David Metcalfe, 1993"; #include #include "win.h" +#include "user.h" LONG ButtonWndProc(HWND hWnd, WORD uMsg, WORD wParam, LONG lParam); @@ -48,6 +49,10 @@ static LONG UB_Paint(HWND hWnd); static LONG UB_LButtonDown(HWND hWnd, WORD wParam, LONG lParam); static LONG UB_LButtonUp(HWND hWnd, WORD wParam, LONG lParam); static LONG UB_KillFocus(HWND hWnd); +static LONG OB_Paint(HWND hWnd); +static LONG OB_LButtonDown(HWND hWnd, WORD wParam, LONG lParam); +static LONG OB_LButtonUp(HWND hWnd, WORD wParam, LONG lParam); +static LONG OB_KillFocus(HWND hWnd); typedef struct { @@ -60,7 +65,7 @@ typedef struct LONG (*getCheckfn)(); } BTNFN; -#define MAX_BTN_TYPE 10 +#define MAX_BTN_TYPE 12 static BTNFN btnfn[MAX_BTN_TYPE] = { @@ -153,7 +158,25 @@ static BTNFN btnfn[MAX_BTN_TYPE] = (LONG(*)())RB_KillFocus, (LONG(*)())RB_SetCheck, (LONG(*)())RB_GetCheck - } + }, + { + (LONG(*)())NULL, /* Not defined */ + (LONG(*)())NULL, + (LONG(*)())NULL, + (LONG(*)())NULL, + (LONG(*)())NULL, + (LONG(*)())NULL, + (LONG(*)())NULL + }, + { + (LONG(*)())OB_Paint, /* BS_OWNERDRAW */ + (LONG(*)())OB_LButtonDown, + (LONG(*)())OB_LButtonUp, + (LONG(*)())NULL, + (LONG(*)())OB_KillFocus, + (LONG(*)())NULL, + (LONG(*)())NULL + }, }; @@ -239,7 +262,7 @@ LONG ButtonWndProc(HWND hWnd, WORD uMsg, WORD wParam, LONG lParam) case BM_GETCHECK: if (btnfn[style].getCheckfn) - (btnfn[style].getCheckfn)(hWnd); + return (btnfn[style].getCheckfn)(hWnd); break; default: @@ -954,3 +977,91 @@ static LONG UB_KillFocus(HWND hWnd) UpdateWindow(hWnd); } + +/********************************************************************** + * Ownerdrawn Button Functions + */ + +static LONG OB_Paint(HWND hWnd) +{ + PAINTSTRUCT ps; + HDC hDC; + RECT rc; + HANDLE hDis; + LPDRAWITEMSTRUCT lpdis; + WND *wndPtr = WIN_FindWndPtr(hWnd); + hDC = BeginPaint(hWnd, &ps); + GetClientRect(hWnd, &rc); + hDis = USER_HEAP_ALLOC(GMEM_MOVEABLE, sizeof(DRAWITEMSTRUCT)); + lpdis = (LPDRAWITEMSTRUCT)USER_HEAP_ADDR(hDis); + lpdis->hDC = hDC; + lpdis->itemID = 0; + CopyRect(&lpdis->rcItem, &rc); + lpdis->CtlID = wndPtr->wIDmenu; + lpdis->CtlType = ODT_BUTTON; + lpdis->itemAction = ODA_DRAWENTIRE; +/* printf("ownerdrawn button WM_DRAWITEM CtrlID=%X\n", lpdis->CtlID);*/ + SendMessage(GetParent(hWnd), WM_DRAWITEM, 1, (LPARAM)lpdis); + USER_HEAP_FREE(hDis); + EndPaint(hWnd, &ps); +} + +static LONG OB_LButtonDown(HWND hWnd, WORD wParam, LONG lParam) +{ + HDC hDC; + RECT rc; + HANDLE hDis; + LPDRAWITEMSTRUCT lpdis; + WND *wndPtr = WIN_FindWndPtr(hWnd); +/* SetFocus(hWnd); */ + SetCapture(hWnd); + hDC = GetDC(hWnd); + GetClientRect(hWnd, &rc); + if (PtInRect(&rc, MAKEPOINT(lParam))) + NOTIFY_PARENT(hWnd, BN_CLICKED); + GetClientRect(hWnd, &rc); + hDis = USER_HEAP_ALLOC(GMEM_MOVEABLE, sizeof(DRAWITEMSTRUCT)); + lpdis = (LPDRAWITEMSTRUCT)USER_HEAP_ADDR(hDis); + lpdis->hDC = hDC; + lpdis->itemID = 0; + CopyRect(&lpdis->rcItem, &rc); + lpdis->CtlID = wndPtr->wIDmenu; + lpdis->CtlType = ODT_BUTTON; + lpdis->itemAction = ODA_SELECT; + SendMessage(GetParent(hWnd), WM_DRAWITEM, 1, (LPARAM)lpdis); + USER_HEAP_FREE(hDis); + ReleaseDC(hWnd, hDC); +} + +static LONG OB_LButtonUp(HWND hWnd, WORD wParam, LONG lParam) +{ + HDC hDC; + RECT rc; + HANDLE hDis; + LPDRAWITEMSTRUCT lpdis; + WND *wndPtr = WIN_FindWndPtr(hWnd); + ReleaseCapture(); + hDC = GetDC(hWnd); + GetClientRect(hWnd, &rc); + if (PtInRect(&rc, MAKEPOINT(lParam))) + NOTIFY_PARENT(hWnd, BN_CLICKED); + GetClientRect(hWnd, &rc); + hDis = USER_HEAP_ALLOC(GMEM_MOVEABLE, sizeof(DRAWITEMSTRUCT)); + lpdis = (LPDRAWITEMSTRUCT)USER_HEAP_ADDR(hDis); + lpdis->hDC = hDC; + lpdis->itemID = 0; + CopyRect(&lpdis->rcItem, &rc); + lpdis->CtlID = wndPtr->wIDmenu; + lpdis->CtlType = ODT_BUTTON; + lpdis->itemAction = ODA_SELECT; + SendMessage(GetParent(hWnd), WM_DRAWITEM, 1, (LPARAM)lpdis); + USER_HEAP_FREE(hDis); + ReleaseDC(hWnd, hDC); +} + +static LONG OB_KillFocus(HWND hWnd) +{ + InvalidateRect(hWnd, NULL, FALSE); + UpdateWindow(hWnd); +} + diff --git a/controls/combo.c b/controls/combo.c index ee90962635b..e4715891a87 100644 --- a/controls/combo.c +++ b/controls/combo.c @@ -74,16 +74,20 @@ LONG COMBOBOX_ComboBoxWndProc( HWND hwnd, WORD message, WND *wndPtr; LPHEADCOMBO lphc; char str[128]; + PAINTSTRUCT paintstruct; static RECT rectsel; switch(message) { case WM_CREATE: CreateComboStruct(hwnd); wndPtr = WIN_FindWndPtr(hwnd); - width = wndPtr->rectClient.right - wndPtr->rectClient.left; - height = wndPtr->rectClient.bottom - wndPtr->rectClient.top; lphc = ComboGetStorageHeader(hwnd); if (lphc == NULL) return 0; +#ifdef DEBUG_COMBO + printf("Combo WM_CREATE %lX !\n", lphc); +#endif + width = wndPtr->rectClient.right - wndPtr->rectClient.left; + height = wndPtr->rectClient.bottom - wndPtr->rectClient.top; lphc->hWndDrop = CreateWindow("BUTTON", "", WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | BS_PUSHBUTTON, width - 16, 0, 16, 16, hwnd, 1, wndPtr->hInstance, 0L); @@ -94,25 +98,23 @@ LONG COMBOBOX_ComboBoxWndProc( HWND hwnd, WORD message, WS_CHILD | WS_CLIPCHILDREN | WS_BORDER | WS_VSCROLL | LBS_NOTIFY, wndPtr->rectClient.left, wndPtr->rectClient.top + 16, width, height, wndPtr->hwndParent, 1, wndPtr->hInstance, (LPSTR)MAKELONG(0, hwnd)); -/* ShowWindow(lphc->hWndLBox, SW_HIDE); -*/ - InvalidateRect(lphc->hWndEdit, NULL, TRUE); - UpdateWindow(lphc->hWndEdit); - InvalidateRect(lphc->hWndDrop, NULL, TRUE); - UpdateWindow(lphc->hWndDrop); #ifdef DEBUG_COMBO printf("Combo Creation Drop=%X LBox=%X!\n", lphc->hWndDrop, lphc->hWndLBox); #endif return 0; case WM_DESTROY: lphc = ComboGetStorageHeader(hwnd); + if (lphc == 0) return 0; DestroyWindow(lphc->hWndDrop); DestroyWindow(lphc->hWndEdit); +/* DestroyWindow(lphc->hWndLBox); +*/ free(lphc); + *((LPHEADCOMBO *)&wndPtr->wExtra[1]) = 0; #ifdef DEBUG_COMBO - printf("Combo WM_DESTROY !\n"); + printf("Combo WM_DESTROY %lX !\n", lphc); #endif return 0; @@ -128,24 +130,33 @@ LONG COMBOBOX_ComboBoxWndProc( HWND hwnd, WORD message, lphc->dwState = lphc->dwState ^ CB_SHOWDROPDOWN; if ((lphc->dwState & CB_SHOWDROPDOWN) == CB_SHOWDROPDOWN) { ShowWindow(lphc->hWndLBox, SW_SHOW); +/* + SetFocus(lphc->hWndLBox); +*/ } else { +/* + SetFocus(lphc->hWndEdit); +*/ ShowWindow(lphc->hWndLBox, SW_HIDE); y = SendMessage(lphc->hWndLBox, LB_GETCURSEL, 0, 0L); - SendMessage(lphc->hWndLBox, LB_GETTEXT, (WORD)y, (LPARAM)str); - SendMessage(lphc->hWndEdit, WM_SETTEXT, (WORD)y, (LPARAM)str); - printf("combo hide\n"); + if (y != LB_ERR) { + SendMessage(lphc->hWndLBox, LB_GETTEXT, (WORD)y, (LPARAM)str); + SendMessage(lphc->hWndEdit, WM_SETTEXT, (WORD)y, (LPARAM)str); + } } } if (LOWORD(lParam) == lphc->hWndLBox) { switch(HIWORD(lParam)) { case LBN_SELCHANGE: - lphc->dwState = lphc->dwState ^ CB_SHOWDROPDOWN; + lphc->dwState = lphc->dwState & (CB_SHOWDROPDOWN ^ 0xFFFF); ShowWindow(lphc->hWndLBox, SW_HIDE); y = SendMessage(lphc->hWndLBox, LB_GETCURSEL, 0, 0L); - SendMessage(lphc->hWndLBox, LB_GETTEXT, (WORD)y, (LPARAM)str); - SendMessage(lphc->hWndEdit, WM_SETTEXT, (WORD)y, (LPARAM)str); + if (y != LB_ERR) { + SendMessage(lphc->hWndLBox, LB_GETTEXT, (WORD)y, (LPARAM)str); + SendMessage(lphc->hWndEdit, WM_SETTEXT, (WORD)y, (LPARAM)str); + } SendMessage(GetParent(hwnd), WM_COMMAND, wndPtr->wIDmenu, MAKELONG(hwnd, CBN_SELCHANGE)); break; @@ -165,6 +176,8 @@ LONG COMBOBOX_ComboBoxWndProc( HWND hwnd, WORD message, case WM_CTLCOLOR: return(SendMessage(GetParent(hwnd), WM_CTLCOLOR, wParam, lParam)); case WM_PAINT: + BeginPaint( hwnd, &paintstruct ); + EndPaint( hwnd, &paintstruct ); lphc = ComboGetStorageHeader(hwnd); InvalidateRect(lphc->hWndEdit, NULL, TRUE); UpdateWindow(lphc->hWndEdit); @@ -175,17 +188,6 @@ LONG COMBOBOX_ComboBoxWndProc( HWND hwnd, WORD message, UpdateWindow(lphc->hWndLBox); } break; - case WM_MOUSEMOVE: - if ((wParam & MK_LBUTTON) != 0) { - y = HIWORD(lParam); - if (y < 4) { - lphc = ComboGetStorageHeader(hwnd); - } - GetClientRect(hwnd, &rect); - if (y > (rect.bottom - 4)) { - lphc = ComboGetStorageHeader(hwnd); - } - } case CB_ADDSTRING: #ifdef DEBUG_COMBO printf("CB_ADDSTRING '%s' !\n", (LPSTR)lParam); @@ -196,6 +198,10 @@ LONG COMBOBOX_ComboBoxWndProc( HWND hwnd, WORD message, printf("CB_GETLBTEXT #%u !\n", wParam); lphc = ComboGetStorageHeader(hwnd); return(SendMessage(lphc->hWndLBox, LB_GETTEXT, wParam, lParam)); + case CB_GETLBTEXTLEN: + printf("CB_GETLBTEXTLEN !\n"); + lphc = ComboGetStorageHeader(hwnd); + return(SendMessage(lphc->hWndLBox, LB_GETTEXTLEN, wParam, lParam)); case CB_INSERTSTRING: printf("CB_INSERTSTRING '%s' !\n", (LPSTR)lParam); lphc = ComboGetStorageHeader(hwnd); @@ -210,17 +216,65 @@ LONG COMBOBOX_ComboBoxWndProc( HWND hwnd, WORD message, return(SendMessage(lphc->hWndLBox, LB_RESETCONTENT, 0, 0L)); case CB_DIR: printf("ComboBox CB_DIR !\n"); + lphc = ComboGetStorageHeader(hwnd); return(SendMessage(lphc->hWndLBox, LB_DIR, wParam, lParam)); case CB_FINDSTRING: + lphc = ComboGetStorageHeader(hwnd); return(SendMessage(lphc->hWndLBox, LB_FINDSTRING, wParam, lParam)); case CB_GETCOUNT: + lphc = ComboGetStorageHeader(hwnd); return(SendMessage(lphc->hWndLBox, LB_GETCOUNT, 0, 0L)); case CB_GETCURSEL: printf("ComboBox CB_GETCURSEL !\n"); - return(SendMessage(lphc->hWndLBox, LB_GETCOUNT, 0, 0L)); + lphc = ComboGetStorageHeader(hwnd); + return(SendMessage(lphc->hWndLBox, LB_GETCURSEL, 0, 0L)); case CB_SETCURSEL: - printf("ComboBox CB_SETCURSEL wParam=%x !\n", wParam); - return(SendMessage(lphc->hWndLBox, LB_GETCOUNT, wParam, 0L)); + printf("ComboBox CB_SETCURSEL wParam=%X !\n", wParam); + lphc = ComboGetStorageHeader(hwnd); + return(SendMessage(lphc->hWndLBox, LB_SETCURSEL, wParam, 0L)); + case CB_GETEDITSEL: + printf("ComboBox CB_GETEDITSEL !\n"); + lphc = ComboGetStorageHeader(hwnd); +/* return(SendMessage(lphc->hWndEdit, EM_GETSEL, 0, 0L)); */ + break; + case CB_SETEDITSEL: + printf("ComboBox CB_SETEDITSEL lParam=%lX !\n", lParam); + lphc = ComboGetStorageHeader(hwnd); +/* return(SendMessage(lphc->hWndEdit, EM_SETSEL, 0, lParam)); */ + break; + case CB_SELECTSTRING: + printf("ComboBox CB_SELECTSTRING !\n"); + lphc = ComboGetStorageHeader(hwnd); + break; + case CB_SHOWDROPDOWN: + printf("ComboBox CB_SHOWDROPDOWN !\n"); + lphc = ComboGetStorageHeader(hwnd); + lphc->dwState = lphc->dwState | CB_SHOWDROPDOWN; + if (wParam != 0) { + ShowWindow(lphc->hWndLBox, SW_SHOW); + } + else { + lphc->dwState = lphc->dwState ^ CB_SHOWDROPDOWN; + ShowWindow(lphc->hWndLBox, SW_HIDE); + SendMessage(GetParent(hwnd), WM_COMMAND, wndPtr->wIDmenu, + MAKELONG(hwnd, CBN_DROPDOWN)); + } + break; + case CB_GETITEMDATA: + printf("ComboBox CB_GETITEMDATA wParam=%X !\n", wParam); + lphc = ComboGetStorageHeader(hwnd); + return(SendMessage(lphc->hWndLBox, LB_GETITEMDATA, wParam, 0L)); + break; + case CB_SETITEMDATA: + printf("ComboBox CB_SETITEMDATA wParam=%X lParam=%lX !\n", wParam, lParam); + lphc = ComboGetStorageHeader(hwnd); + return(SendMessage(lphc->hWndLBox, LB_SETITEMDATA, wParam, lParam)); + break; + case CB_LIMITTEXT: + printf("ComboBox CB_LIMITTEXT !\n"); + lphc = ComboGetStorageHeader(hwnd); +/* return(SendMessage(lphc->hWndEdit, EM_LIMITTEXT, wParam, 0L)); */ + break; default: return DefWindowProc( hwnd, message, wParam, lParam ); @@ -235,6 +289,10 @@ LPHEADCOMBO ComboGetStorageHeader(HWND hwnd) WND *wndPtr; LPHEADCOMBO lphc; wndPtr = WIN_FindWndPtr(hwnd); + if (wndPtr == 0) { + printf("Bad Window handle on ComboBox !\n"); + return 0; + } lphc = *((LPHEADCOMBO *)&wndPtr->wExtra[1]); return lphc; } @@ -246,6 +304,10 @@ int CreateComboStruct(HWND hwnd) WND *wndPtr; LPHEADCOMBO lphc; wndPtr = WIN_FindWndPtr(hwnd); + if (wndPtr == 0) { + printf("Bad Window handle on ComboBox !\n"); + return 0; + } lphc = (LPHEADCOMBO)malloc(sizeof(HEADCOMBO)); *((LPHEADCOMBO *)&wndPtr->wExtra[1]) = lphc; lphc->dwState = 0; diff --git a/controls/listbox.c b/controls/listbox.c index dc2ae493c38..a71eb92b3fe 100644 --- a/controls/listbox.c +++ b/controls/listbox.c @@ -107,6 +107,9 @@ LONG LISTBOX_ListBoxWndProc( HWND hwnd, WORD message, case WM_CREATE: CreateListBoxStruct(hwnd); lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); +#ifdef DEBUG_LISTBOX + printf("ListBox WM_CREATE %lX !\n", lphl); +#endif createStruct = (CREATESTRUCT *)lParam; if (HIWORD(createStruct->lpCreateParams) != 0) lphl->hWndLogicParent = (HWND)HIWORD(createStruct->lpCreateParams); @@ -122,10 +125,14 @@ LONG LISTBOX_ListBoxWndProc( HWND hwnd, WORD message, return 0; case WM_DESTROY: lphl = ListBoxGetStorageHeader(hwnd); + if (lphl == 0) return 0; ListBoxResetContent(hwnd); DestroyWindow(lphl->hWndScroll); free(lphl); - printf("ListBox WM_DESTROY !\n"); + *((LPHEADLIST *)&wndPtr->wExtra[1]) = 0; +#ifdef DEBUG_LISTBOX + printf("ListBox WM_DESTROY %lX !\n", lphl); +#endif return 0; case WM_VSCROLL: @@ -164,6 +171,10 @@ LONG LISTBOX_ListBoxWndProc( HWND hwnd, WORD message, return 0; case WM_LBUTTONDOWN: +/* + SetFocus(hwnd); +*/ + SetCapture(hwnd); lphl = ListBoxGetStorageHeader(hwnd); if (lphl == NULL) return 0; lphl->PrevSelected = lphl->ItemSelected; @@ -174,6 +185,7 @@ LONG LISTBOX_ListBoxWndProc( HWND hwnd, WORD message, UpdateWindow(hwnd); return 0; case WM_LBUTTONUP: + ReleaseCapture(); lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); if (lphl == NULL) return 0; if (lphl->PrevSelected != lphl->ItemSelected) @@ -248,8 +260,10 @@ LONG LISTBOX_ListBoxWndProc( HWND hwnd, WORD message, case LB_DIR: printf("ListBox LB_DIR !\n"); wRet = ListBoxDirectory(hwnd, wParam, (LPSTR)lParam); - InvalidateRect(hwnd, NULL, TRUE); - UpdateWindow(hwnd); + if (IsWindowVisible(hwnd)) { + InvalidateRect(hwnd, NULL, TRUE); + UpdateWindow(hwnd); + } return wRet; case LB_ADDSTRING: wRet = ListBoxAddString(hwnd, (LPSTR)lParam); @@ -315,30 +329,38 @@ LONG LISTBOX_ListBoxWndProc( HWND hwnd, WORD message, printf("ListBox LB_SETCURSEL wParam=%x !\n", wParam); #endif wRet = ListBoxSetCurSel(hwnd, wParam); - InvalidateRect(hwnd, NULL, TRUE); - UpdateWindow(hwnd); + if (IsWindowVisible(hwnd)) { + InvalidateRect(hwnd, NULL, TRUE); + UpdateWindow(hwnd); + } return wRet; case LB_SETSEL: printf("ListBox LB_SETSEL wParam=%x lParam=%lX !\n", wParam, lParam); wRet = ListBoxSetSel(hwnd, wParam); - InvalidateRect(hwnd, NULL, TRUE); - UpdateWindow(hwnd); + if (IsWindowVisible(hwnd)) { + InvalidateRect(hwnd, NULL, TRUE); + UpdateWindow(hwnd); + } return wRet; case LB_SETTOPINDEX: printf("ListBox LB_SETTOPINDEX wParam=%x !\n", wParam); lphl = ListBoxGetStorageHeader(hwnd); lphl->FirstVisible = wParam; SetScrollPos(lphl->hWndScroll, WM_VSCROLL, lphl->FirstVisible, TRUE); - InvalidateRect(hwnd, NULL, TRUE); - UpdateWindow(hwnd); + if (IsWindowVisible(hwnd)) { + InvalidateRect(hwnd, NULL, TRUE); + UpdateWindow(hwnd); + } break; case LB_SETITEMHEIGHT: #ifdef DEBUG_LISTBOX printf("ListBox LB_SETITEMHEIGHT wParam=%x lParam=%lX !\n", wParam, lParam); #endif wRet = ListBoxSetItemHeight(hwnd, wParam, lParam); - InvalidateRect(hwnd, NULL, TRUE); - UpdateWindow(hwnd); + if (IsWindowVisible(hwnd)) { + InvalidateRect(hwnd, NULL, TRUE); + UpdateWindow(hwnd); + } return wRet; default: @@ -381,6 +403,10 @@ void StdDrawListBox(HWND hwnd) char C[128]; h = 0; hdc = BeginPaint( hwnd, &ps ); + if (!IsWindowVisible(hwnd)) { + EndPaint( hwnd, &ps ); + return; + } GetClientRect(hwnd, &rect); lphl = ListBoxGetStorageHeader(hwnd); if (lphl == NULL) goto EndOfPaint; @@ -425,7 +451,6 @@ void OwnerDrawListBox(HWND hwnd) { LPHEADLIST lphl; LPLISTSTRUCT lpls; - HANDLE hTemp; PAINTSTRUCT ps; HBRUSH hBrush; HWND hWndParent; @@ -435,6 +460,10 @@ void OwnerDrawListBox(HWND hwnd) char C[128]; h = 0; hdc = BeginPaint( hwnd, &ps ); + if (!IsWindowVisible(hwnd)) { + EndPaint( hwnd, &ps ); + return; + } GetClientRect(hwnd, &rect); lphl = ListBoxGetStorageHeader(hwnd); if (lphl == NULL) goto EndOfPaint; @@ -465,11 +494,9 @@ void OwnerDrawListBox(HWND hwnd) lpls->dis.rcItem.right, lpls->dis.rcItem.bottom); printf("LBOX WM_DRAWITEM Parent=%X &dis=%lX CtlID=%u !\n", hWndParent, (LONG)&lpls->dis, lpls->dis.CtlID); -#endif printf("LBOX WM_DRAWITEM '%s' !\n", lpls->dis.itemData); +#endif SendMessage(lphl->hWndLogicParent, WM_DRAWITEM, i, (LPARAM)&lpls->dis); - GlobalUnlock(hTemp); - GlobalFree(hTemp); if (lpls->dis.itemState != 0) { InvertRect(hdc, &lpls->dis.rcItem); } @@ -575,7 +602,8 @@ int ListBoxAddString(HWND hwnd, LPSTR newstr) lplsnew->dis.itemID = lphl->ItemsCount; lplsnew->dis.itemData = (DWORD)newstr; lplsnew->hData = hTemp; - SetScrollRange(lphl->hWndScroll, WM_VSCROLL, 1, lphl->ItemsCount, TRUE); + SetScrollRange(lphl->hWndScroll, WM_VSCROLL, 1, lphl->ItemsCount, + (lphl->FirstVisible != 1)); if (lphl->FirstVisible >= (lphl->ItemsCount - lphl->ItemsVisible)) { InvalidateRect(hwnd, NULL, TRUE); UpdateWindow(hwnd); @@ -625,7 +653,8 @@ int ListBoxInsertString(HWND hwnd, UINT uIndex, LPSTR newstr) lplsnew->dis.itemID = lphl->ItemsCount; lplsnew->dis.itemData = (DWORD)newstr; lplsnew->hData = hTemp; - SetScrollRange(lphl->hWndScroll, WM_VSCROLL, 1, lphl->ItemsCount, TRUE); + SetScrollRange(lphl->hWndScroll, WM_VSCROLL, 1, lphl->ItemsCount, + (lphl->FirstVisible != 1)); if (((lphl->ItemsCount - lphl->FirstVisible) == lphl->ItemsVisible) && (lphl->ItemsVisible != 0)) ShowWindow(lphl->hWndScroll, SW_NORMAL); @@ -768,10 +797,10 @@ int ListBoxSetCurSel(HWND hwnd, WORD wIndex) lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); if (lphl == NULL) return LB_ERR; lphl->ItemSelected = LB_ERR; - if (wIndex < 1 || wIndex > lphl->ItemsCount) return LB_ERR; + if (wIndex < 0 || wIndex >= lphl->ItemsCount) return LB_ERR; lpls = lphl->lpFirst; if (lpls == NULL) return LB_ERR; - for(i = 1; i <= lphl->ItemsCount; i++) { + for(i = 0; i < lphl->ItemsCount; i++) { lpls2 = lpls; lpls = (LPLISTSTRUCT)lpls->lpNext; if (i == wIndex) @@ -797,10 +826,10 @@ int ListBoxSetSel(HWND hwnd, WORD wIndex) UINT i; lphl = ListBoxGetStorageHeader(hwnd); if (lphl == NULL) return LB_ERR; - if (wIndex < 1 || wIndex > lphl->ItemsCount) return LB_ERR; + if (wIndex < 0 || wIndex >= lphl->ItemsCount) return LB_ERR; lpls = lphl->lpFirst; if (lpls == NULL) return LB_ERR; - for(i = 1; i <= lphl->ItemsCount; i++) { + for(i = 0; i < lphl->ItemsCount; i++) { lpls2 = lpls; lpls = (LPLISTSTRUCT)lpls->lpNext; if (i == wIndex) { diff --git a/controls/scroll.c b/controls/scroll.c index 83816f5b879..fd8e45a24ee 100644 --- a/controls/scroll.c +++ b/controls/scroll.c @@ -86,11 +86,15 @@ LONG SCROLLBAR_ScrollBarWndProc( HWND hwnd, WORD message, #endif return 0; case WM_DESTROY: - lphs = ScrollBarGetStorageHeader(hwnd); + lphs = ScrollBarGetWindowAndStorage(hwnd, &wndPtr); + if (lphs == 0) return 0; +#ifdef DEBUG_SCROLL + printf("ScrollBar WM_DESTROY %lX !\n", lphs); +#endif DestroyWindow(lphs->hWndUp); DestroyWindow(lphs->hWndDown); free(lphs); - printf("ScrollBar WM_DESTROY !\n"); + *((LPHEADSCROLL *)&wndPtr->wExtra[1]) = 0; return 0; case WM_COMMAND: @@ -105,10 +109,17 @@ LONG SCROLLBAR_ScrollBarWndProc( HWND hwnd, WORD message, if (LOWORD(lParam) == lphs->hWndDown) SendMessage(wndPtr->hwndParent, lphs->Direction, SB_LINEDOWN, MAKELONG(0, hwnd)); +/* + SetFocus(hwnd); +*/ return 0; case WM_LBUTTONDOWN: lphs = ScrollBarGetWindowAndStorage(hwnd, &wndPtr); +/* + SetFocus(hwnd); +*/ + SetCapture(hwnd); GetClientRect(hwnd, &rect); if (lphs->Direction == WM_VSCROLL) { y = HIWORD(lParam); @@ -152,11 +163,13 @@ LONG SCROLLBAR_ScrollBarWndProc( HWND hwnd, WORD message, } break; case WM_LBUTTONUP: + lphs = ScrollBarGetStorageHeader(hwnd); lphs->ThumbActive = FALSE; + ReleaseCapture(); break; case WM_KEYDOWN: - printf("ScrollBar WM_KEYDOWN wParam %X!\n", wParam); + printf("ScrollBar WM_KEYDOWN wParam %X !\n", wParam); break; case WM_PAINT: StdDrawScrollBar(hwnd); @@ -192,6 +205,10 @@ LPHEADSCROLL ScrollBarGetWindowAndStorage(HWND hwnd, WND **wndPtr) WND *Ptr; LPHEADSCROLL lphs; *(wndPtr) = Ptr = WIN_FindWndPtr(hwnd); + if (Ptr == 0) { + printf("Bad Window handle on ScrollBar !\n"); + return 0; + } lphs = *((LPHEADSCROLL *)&Ptr->wExtra[1]); return lphs; } @@ -202,6 +219,10 @@ LPHEADSCROLL ScrollBarGetStorageHeader(HWND hwnd) WND *wndPtr; LPHEADSCROLL lphs; wndPtr = WIN_FindWndPtr(hwnd); + if (wndPtr == 0) { + printf("Bad Window handle on ScrollBar !\n"); + return 0; + } lphs = *((LPHEADSCROLL *)&wndPtr->wExtra[1]); return lphs; } @@ -209,49 +230,53 @@ LPHEADSCROLL ScrollBarGetStorageHeader(HWND hwnd) void StdDrawScrollBar(HWND hwnd) { - LPHEADSCROLL lphs; - PAINTSTRUCT ps; - HBRUSH hBrush; - HDC hdc; - RECT rect; - UINT i, w, h, siz; - char C[128]; - hdc = BeginPaint( hwnd, &ps ); - hBrush = SendMessage(GetParent(hwnd), WM_CTLCOLOR, (WORD)hdc, - MAKELONG(hwnd, CTLCOLOR_SCROLLBAR)); - if (hBrush == (HBRUSH)NULL) hBrush = GetStockObject(LTGRAY_BRUSH); - lphs = ScrollBarGetStorageHeader(hwnd); - if (lphs == NULL) goto EndOfPaint; - GetClientRect(hwnd, &rect); - w = rect.right - rect.left; - h = rect.bottom - rect.top; - if (lphs->Direction == WM_VSCROLL) { - rect.top += w; - rect.bottom -= w; - } - else { - rect.left += h; - rect.right -= h; - } - FillRect(hdc, &rect, hBrush); - if (lphs->Direction == WM_VSCROLL) - SetRect(&rect, 0, lphs->CurPix + w, - w, lphs->CurPix + (w << 1)); - else - SetRect(&rect, lphs->CurPix + h, - 0, lphs->CurPix + (h << 1), h); - FrameRect(hdc, &rect, GetStockObject(BLACK_BRUSH)); - InflateRect(&rect, -1, -1); - FillRect(hdc, &rect, GetStockObject(LTGRAY_BRUSH)); - DrawReliefRect(hdc, rect, 2, 0); - InflateRect(&rect, -3, -3); - DrawReliefRect(hdc, rect, 1, 1); -EndOfPaint: + LPHEADSCROLL lphs; + PAINTSTRUCT ps; + HBRUSH hBrush; + HDC hdc; + RECT rect; + UINT i, w, h, siz; + char C[128]; + hdc = BeginPaint( hwnd, &ps ); + if (!IsWindowVisible(hwnd)) { EndPaint( hwnd, &ps ); - InvalidateRect(lphs->hWndUp, NULL, TRUE); - UpdateWindow(lphs->hWndUp); - InvalidateRect(lphs->hWndDown, NULL, TRUE); - UpdateWindow(lphs->hWndDown); + return; + } + hBrush = SendMessage(GetParent(hwnd), WM_CTLCOLOR, (WORD)hdc, + MAKELONG(hwnd, CTLCOLOR_SCROLLBAR)); + if (hBrush == (HBRUSH)NULL) hBrush = GetStockObject(LTGRAY_BRUSH); + lphs = ScrollBarGetStorageHeader(hwnd); + if (lphs == NULL) goto EndOfPaint; + GetClientRect(hwnd, &rect); + w = rect.right - rect.left; + h = rect.bottom - rect.top; + if (lphs->Direction == WM_VSCROLL) { + rect.top += w; + rect.bottom -= w; + } + else { + rect.left += h; + rect.right -= h; + } + FillRect(hdc, &rect, hBrush); + if (lphs->Direction == WM_VSCROLL) + SetRect(&rect, 0, lphs->CurPix + w, w, lphs->CurPix + (w << 1)); + else + SetRect(&rect, lphs->CurPix + h, 0, lphs->CurPix + (h << 1), h); + FrameRect(hdc, &rect, GetStockObject(BLACK_BRUSH)); + InflateRect(&rect, -1, -1); + FillRect(hdc, &rect, GetStockObject(LTGRAY_BRUSH)); + DrawReliefRect(hdc, rect, 2, 0); + InflateRect(&rect, -3, -3); + DrawReliefRect(hdc, rect, 1, 1); + if (!lphs->ThumbActive) { + InvalidateRect(lphs->hWndUp, NULL, TRUE); + UpdateWindow(lphs->hWndUp); + InvalidateRect(lphs->hWndDown, NULL, TRUE); + UpdateWindow(lphs->hWndDown); + } +EndOfPaint: + EndPaint( hwnd, &ps ); } @@ -264,16 +289,22 @@ int CreateScrollBarStruct(HWND hwnd) LPHEADSCROLL lphs; wndPtr = WIN_FindWndPtr(hwnd); lphs = (LPHEADSCROLL)malloc(sizeof(HEADSCROLL)); + if (lphs == 0) { + printf("Bad Memory Alloc on ScrollBar !\n"); + return 0; + } + +#ifdef DEBUG_SCROLL + printf("CreateScrollBarStruct %lX !\n", lphs); +#endif *((LPHEADSCROLL *)&wndPtr->wExtra[1]) = lphs; - lphs->ThumbActive; + lphs->ThumbActive = FALSE; lphs->MinVal = 0; lphs->MaxVal = 100; lphs->CurVal = 0; lphs->CurPix = 0; width = wndPtr->rectClient.right - wndPtr->rectClient.left; height = wndPtr->rectClient.bottom - wndPtr->rectClient.top; - lphs = ScrollBarGetStorageHeader(hwnd); - if (lphs == NULL) return 0; if (width <= height) { lphs->MaxPix = height - 3 * width; @@ -308,7 +339,7 @@ int GetScrollPos(HWND hwnd, int nBar) { LPHEADSCROLL lphs; lphs = ScrollBarGetStorageHeader(hwnd); - if (lphs == NULL) return; + if (lphs == NULL) return 0; return lphs->CurVal; } @@ -330,7 +361,7 @@ int SetScrollPos(HWND hwnd, int nBar, int nPos, BOOL bRedraw) int nRet; LPHEADSCROLL lphs; lphs = ScrollBarGetStorageHeader(hwnd); - if (lphs == NULL) return; + if (lphs == NULL) return 0; nRet = lphs->CurVal; lphs->CurVal = (short)nPos; if (lphs->MaxVal != lphs->MinVal) @@ -343,7 +374,7 @@ int SetScrollPos(HWND hwnd, int nBar, int nPos, BOOL bRedraw) printf("SetScrollPos min=%d max=%d\n", lphs->MinVal, lphs->MaxVal); #endif - if (bRedraw) { + if ((bRedraw) && (IsWindowVisible(hwnd))) { InvalidateRect(hwnd, NULL, TRUE); UpdateWindow(hwnd); } @@ -367,7 +398,7 @@ void SetScrollRange(HWND hwnd, int nBar, int MinPos, int MaxPos, BOOL bRedraw) #ifdef DEBUG_SCROLL printf("SetScrollRange min=%d max=%d\n", lphs->MinVal, lphs->MaxVal); #endif - if (bRedraw) { + if ((bRedraw) && (IsWindowVisible(hwnd))) { InvalidateRect(hwnd, NULL, TRUE); UpdateWindow(hwnd); } diff --git a/controls/static.c b/controls/static.c index 40e5fbb814b..692813973d8 100644 --- a/controls/static.c +++ b/controls/static.c @@ -16,6 +16,8 @@ LONG StaticWndProc(HWND hWnd, WORD uMsg, WORD wParam, LONG lParam); static LONG PaintTextfn(HWND hwnd); static LONG PaintRectfn(HWND hwnd); static LONG PaintFramefn(HWND hwnd); +static LONG PaintIconfn(HWND hwnd); + static COLORREF color_windowframe, color_background, color_window, color_windowtext; @@ -37,7 +39,7 @@ static STATICFN staticfn[MAX_STATIC_TYPE] = { (LONG(*)())PaintTextfn }, /* SS_LEFT */ { (LONG(*)())PaintTextfn }, /* SS_CENTER */ { (LONG(*)())PaintTextfn }, /* SS_RIGHT */ - { (LONG(*)())NULL }, /* SS_ICON */ + { (LONG(*)())PaintIconfn }, /* SS_ICON */ { (LONG(*)())PaintRectfn }, /* SS_BLACKRECT */ { (LONG(*)())PaintRectfn }, /* SS_GRAYRECT */ { (LONG(*)())PaintRectfn }, /* SS_WHITERECT */ @@ -65,17 +67,22 @@ LONG StaticWndProc(HWND hWnd, WORD uMsg, WORD wParam, LONG lParam) break; case WM_CREATE: - if (style < 0L || style >= (LONG)DIM(staticfn)) + if (style < 0L || style >= (LONG)DIM(staticfn)) { lResult = -1L; - else - { - /* initialise colours */ - color_windowframe = GetSysColor(COLOR_WINDOWFRAME); - color_background = GetSysColor(COLOR_BACKGROUND); - color_window = GetSysColor(COLOR_WINDOW); - color_windowtext = GetSysColor(COLOR_WINDOWTEXT); - lResult = 0L; - } + break; + } + /* initialise colours */ + color_windowframe = GetSysColor(COLOR_WINDOWFRAME); + color_background = GetSysColor(COLOR_BACKGROUND); + color_window = GetSysColor(COLOR_WINDOW); + color_windowtext = GetSysColor(COLOR_WINDOWTEXT); + lResult = 0L; + if (style == SS_ICON) { +/* + SetWindowPos(hWnd, (HWND)NULL, 0, 0, 32, 32, + SWP_NOZORDER | SWP_NOMOVE); +*/ + } break; case WM_PAINT: @@ -259,6 +266,35 @@ static LONG PaintFramefn(HWND hwnd) } +static LONG PaintIconfn(HWND hwnd) +{ + WND *wndPtr; + PAINTSTRUCT ps; + RECT rc; + HDC hdc; + LPSTR textPtr; + HICON hIcon; + + wndPtr = WIN_FindWndPtr(hwnd); + hdc = BeginPaint(hwnd, &ps); + GetClientRect(hwnd, &rc); + FillRect(hdc, &rc, GetStockObject(WHITE_BRUSH)); + textPtr = (LPSTR)USER_HEAP_ADDR(wndPtr->hText); + printf("SS_ICON : textPtr='%s' / left=%d top=%d right=%d bottom=%d \n", + textPtr, rc.left, rc.top, rc.right, rc.bottom); +/* + SetWindowPos(hwnd, (HWND)NULL, 0, 0, 32, 32, + SWP_NOZORDER | SWP_NOMOVE); + GetClientRect(hwnd, &rc); + printf("SS_ICON : textPtr='%s' / left=%d top=%d right=%d bottom=%d \n", + textPtr, rc.left, rc.top, rc.right, rc.bottom); +*/ + hIcon = LoadIcon(wndPtr->hInstance, textPtr); + DrawIcon(hdc, rc.left, rc.top, hIcon); + EndPaint(hwnd, &ps); + GlobalUnlock(hwnd); +} + diff --git a/if1632/call.S b/if1632/call.S index 9da87f091af..c8ac0300874 100644 --- a/if1632/call.S +++ b/if1632/call.S @@ -15,11 +15,12 @@ return_value: /********************************************************************** * Places to keep info about the current 32-bit stack frame. */ -saved_esp: + .globl _IF1632_Saved32_esp,_IF1632_Saved32_ebp,_IF1632_Saved32_ss +_IF1632_Saved32_esp: .long 0 -saved_ebp: +_IF1632_Saved32_ebp: .long 0 -saved_ss: +_IF1632_Saved32_ss: .word 0 /********************************************************************** @@ -64,9 +65,9 @@ _CallToInit16: * Save our registers */ pushal - pushl saved_esp - pushl saved_ebp - pushw saved_ss + pushl _IF1632_Saved32_esp + pushl _IF1632_Saved32_ebp + pushw _IF1632_Saved32_ss /* * Get target address. @@ -78,9 +79,9 @@ _CallToInit16: /* * Put stack registers where we can get them after stack switch. */ - movw %ss,saved_ss - movl %esp,saved_esp - movl %ebp,saved_ebp + movw %ss,_IF1632_Saved32_ss + movl %esp,_IF1632_Saved32_esp + movl %ebp,_IF1632_Saved32_ebp /* * Load initial registers @@ -130,16 +131,16 @@ _CallToInit16: movw %ax,%fs movw %ax,%gs popl %eax - movw saved_ss,%ss - movl saved_esp,%esp - movl saved_ebp,%ebp + movw _IF1632_Saved32_ss,%ss + movl _IF1632_Saved32_esp,%esp + movl _IF1632_Saved32_ebp,%ebp /* * Restore registers, but do not destroy return value. */ - popw saved_ss - popl saved_ebp - popl saved_esp + popw _IF1632_Saved32_ss + popl _IF1632_Saved32_ebp + popl _IF1632_Saved32_esp movl %eax,return_value popal movl return_value,%eax @@ -173,13 +174,13 @@ _CallTo16: /* * Switch to 16-bit stack */ - pushl saved_esp - pushl saved_ebp - pushw saved_ss + pushl _IF1632_Saved32_esp + pushl _IF1632_Saved32_ebp + pushw _IF1632_Saved32_ss - movw %ss,saved_ss - movl %esp,saved_esp - movl %ebp,saved_ebp + movw %ss,_IF1632_Saved32_ss + movl %esp,_IF1632_Saved32_esp + movl %ebp,_IF1632_Saved32_ebp movw _IF1632_Saved16_ss,%ss movl _IF1632_Saved16_esp,%esp @@ -215,13 +216,13 @@ _CallTo16: movl %esp,_IF1632_Saved16_esp movl %ebp,_IF1632_Saved16_ebp - movw saved_ss,%ss - movl saved_esp,%esp - movl saved_ebp,%ebp + movw _IF1632_Saved32_ss,%ss + movl _IF1632_Saved32_esp,%esp + movl _IF1632_Saved32_ebp,%ebp - popw saved_ss - popl saved_ebp - popl saved_esp + popw _IF1632_Saved32_ss + popl _IF1632_Saved32_ebp + popl _IF1632_Saved32_esp movl %eax,return_value movw return_value+2,%dx @@ -276,9 +277,9 @@ _CallTo32: movl %esp,_IF1632_Saved16_esp movl %ebp,_IF1632_Saved16_ebp - movw saved_ss,%ss - movl saved_esp,%esp - movl saved_ebp,%ebp + movw _IF1632_Saved32_ss,%ss + movl _IF1632_Saved32_esp,%esp + movl _IF1632_Saved32_ebp,%ebp /* * Call entry point diff --git a/if1632/callback.c b/if1632/callback.c index 60a9e88cdd0..1852185f8d5 100644 --- a/if1632/callback.c +++ b/if1632/callback.c @@ -5,10 +5,16 @@ static char Copyright[] = "Copyright Robert J. Amstadt, 1993"; #include "callback.h" #include "wine.h" #include "segmem.h" +#include extern unsigned short SelectorOwners[]; extern unsigned short IF1632_Saved16_ss; +extern unsigned long IF1632_Saved16_ebp; extern unsigned long IF1632_Saved16_esp; +extern unsigned short IF1632_Saved32_ss; +extern unsigned long IF1632_Saved32_ebp; +extern unsigned long IF1632_Saved32_esp; + extern struct segment_descriptor_s *MakeProcThunks; struct thunk_s @@ -169,3 +175,77 @@ void CallLineDDAProc(FARPROC func, short xPos, short yPos, long lParam) (*func)(xPos, yPos, lParam); } } + +/* ------------------------------------------------------------------------ */ +/* + * The following functions realize the Catch/Throw functionality. + * My thought is to use the setjmp, longjmp combination to do the + * major part of this one. All I have to remember, in addition to + * whatever the jmp_buf contains, is the contents of the 16-bit + * sp, bp and ss. I do this by storing them in the structure passed + * to me by the 16-bit program (including my own jmp_buf...). + * Hopefully there isn't any program that modifies the contents! + * Bad thing: I have to save part of the stack, since this will + * get reused on the next call after my return, leaving it in an + * undefined state. + */ +#define STACK_DEPTH_16 28 + +struct special_buffer { + jmp_buf buffer; + long regs [6]; + char stack_part [STACK_DEPTH_16]; +} *sb; + +int Catch (LPCATCHBUF cbuf) +{ + WORD retval; + jmp_buf *tmp_jmp; + char *stack16 = (char *) (((unsigned int)IF1632_Saved16_ss << 16) + + (IF1632_Saved16_esp & 0xffff)); + + sb = malloc (sizeof (struct special_buffer)); + + sb -> regs [0] = IF1632_Saved16_esp; + sb -> regs [1] = IF1632_Saved16_ebp; + sb -> regs [2] = IF1632_Saved16_ss & 0xffff; + sb -> regs [3] = IF1632_Saved32_esp; + sb -> regs [4] = IF1632_Saved32_ebp; + sb -> regs [5] = IF1632_Saved32_ss & 0xffff; + memcpy (sb -> stack_part, stack16, STACK_DEPTH_16); + tmp_jmp = &sb -> buffer; + *((struct special_buffer **)cbuf) = sb; + + if ((retval = setjmp (*tmp_jmp))) + { + IF1632_Saved16_esp = sb -> regs [0]; + IF1632_Saved16_ebp = sb -> regs [1]; + IF1632_Saved16_ss = sb -> regs [2] & 0xffff; + IF1632_Saved32_esp = sb -> regs [3]; + IF1632_Saved32_ebp = sb -> regs [4]; + IF1632_Saved32_ss = sb -> regs [5] & 0xffff; + stack16 = (char *) (((unsigned int)IF1632_Saved16_ss << 16) + + (IF1632_Saved16_esp & 0xffff)); + + memcpy (stack16, sb -> stack_part, STACK_DEPTH_16); +#ifdef DEBUG_CATCH + printf ("Been thrown here: %d, retval = %d\n", sb, retval); +#endif + free ((void *) sb); + return (retval); + } else { +#ifdef DEBUG_CATCH + printf ("Will somtime get thrown here: %d\n", sb); +#endif + return (retval); + } +} + +void Throw (LPCATCHBUF cbuf, int val) +{ + sb = *((struct special_buffer **)cbuf); +#ifdef DEBUG_CATCH + printf ("Throwing to: %d\n", sb); +#endif + longjmp (sb -> buffer, val); +} diff --git a/if1632/kernel.spec b/if1632/kernel.spec index 755f8431a0e..142f4512f59 100644 --- a/if1632/kernel.spec +++ b/if1632/kernel.spec @@ -32,11 +32,14 @@ length 415 50 pascal GetProcAddress(word ptr) GetProcAddress(1 2) 51 pascal MakeProcInstance(ptr word) CALLBACK_MakeProcInstance(1 2) 52 pascal FreeProcInstance(ptr) FreeProcInstance(1) +55 pascal Catch(ptr) Catch (1) +56 pascal Throw(ptr word) Throw(1 2) 59 pascal WriteProfileString(ptr ptr ptr) WriteProfileString(1 2 3) 60 pascal FindResource(word ptr ptr) FindResource(1 2 3) 61 pascal LoadResource(word word) LoadResource(1 2) 62 pascal LockResource(word) LockResource(1) 63 pascal FreeResource(word) FreeResource(1) +64 pascal AccessResource(word word) AccessResource(1 2) 74 pascal OpenFile(ptr ptr word) KERNEL_OpenFile(1 2 3) 81 pascal _lclose(word) KERNEL__lclose(1) 82 pascal _lread(word ptr word) KERNEL__lread(1 2 3) @@ -48,6 +51,8 @@ length 415 91 register InitTask(word word word word word word word word word word) KERNEL_InitTask() +95 pascal LoadLibrary(ptr) LoadLibrary(1) +96 pascal FreeLibrary(word) FreeLibrary(1) 102 register DOS3Call(word word word word word word word word word word) KERNEL_DOS3Call() @@ -67,6 +72,11 @@ length 415 163 pascal GlobalLRUOldest(word) ReturnArg(1) 164 pascal GlobalLRUNewest(word) ReturnArg(1) 166 pascal WinExec(ptr word) WinExec(1 2) +170 pascal AllocCStoDSAlias(word) AllocDStoCSAlias(1) +171 pascal AllocDStoCSAlias(word) AllocDStoCSAlias(1) +175 pascal AllocSelector(word) AllocSelector(1) +176 pascal FreeSelector(word) FreeSelector(1) +177 pascal PrestoChangoSelector(word word) PrestoChangoSelector(1 2) 178 equate __WINFLAGS 0x413 184 return GlobalDOSAlloc 4 0 185 return GlobalDOSFree 2 0 diff --git a/if1632/relay.c b/if1632/relay.c index 9bf6b127b1f..859144c7274 100644 --- a/if1632/relay.c +++ b/if1632/relay.c @@ -166,10 +166,17 @@ DLLRelay(unsigned int func_num, unsigned int seg_off) break; case DLL_ARGTYPE_LONG: - case DLL_ARGTYPE_FARPTR: ip = (int *) ((char *) arg_ptr + offset); arg_table[i] = *ip; break; + + case DLL_ARGTYPE_FARPTR: + ip = (int *) ((char *) arg_ptr + offset); + if (*ip & 0xffff0000) + arg_table[i] = SAFEMAKEPTR((unsigned) *ip >> 16, *ip); + else + arg_table[i] = *ip; + break; } } diff --git a/if1632/user.spec b/if1632/user.spec index 9f92bd80d54..bf032d68149 100644 --- a/if1632/user.spec +++ b/if1632/user.spec @@ -15,6 +15,8 @@ length 540 15 pascal GetCurrentTime() GetTickCount() 18 pascal SetCapture(word) SetCapture(1) 19 pascal ReleaseCapture() ReleaseCapture() +20 pascal SetDoubleClickTime(word) SetDoubleClickTime(1) +21 pascal GetDoubleClickTime() GetDoubleClickTime() 22 pascal SetFocus(word) SetFocus(1) 23 pascal GetFocus() GetFocus() 31 pascal IsIconic(word) IsIconic(1) @@ -28,16 +30,24 @@ length 540 41 pascal CreateWindow(ptr ptr long s_word s_word s_word s_word word word word ptr) CreateWindow(1 2 3 4 5 6 7 8 9 10 11) 42 pascal ShowWindow(word word) ShowWindow(1 2) +43 pascal CloseWindow(word) CloseWindow(1) +44 pascal OpenIcon(word) OpenIcon(1) 46 pascal GetParent(word) GetParent(1) +47 pascal IsWindow(word) IsWindow(1) 48 pascal IsChild(word word) IsChild(1 2) +49 pascal IsWindowVisible(word) IsWindowVisible(1) +50 pascal FindWindow(ptr ptr) FindWindow(1 2) 53 pascal DestroyWindow(word) DestroyWindow(1) 56 pascal MoveWindow(word word word word word word) MoveWindow(1 2 3 4 5 6) 57 pascal RegisterClass(ptr) RegisterClass(1) +61 pascal ScrollWindow(word s_word s_word ptr ptr) ScrollWindow(1 2 3 4 5) 62 pascal SetScrollPos(word word word word) SetScrollPos(1 2 3 4) 64 pascal SetScrollRange(word word word word word) SetScrollRange(1 2 3 4 5) 66 pascal GetDC(word) GetDC(1) 68 pascal ReleaseDC(word word) ReleaseDC(1 2) +69 pascal SetCursor(word word) SetCursor(1 2) +71 pascal ShowCursor(word word) ShowCursor(1 2) 72 pascal SetRect(ptr s_word s_word s_word s_word) SetRect(1 2 3 4 5) 73 pascal SetRectEmpty(ptr) SetRectEmpty(1) 74 pascal CopyRect(ptr ptr) CopyRect(1 2) @@ -50,6 +60,7 @@ length 540 81 pascal FillRect(word ptr word) FillRect(1 2 3) 82 pascal InvertRect(word ptr) InvertRect(1 2) 83 pascal FrameRect(word ptr word) FrameRect(1 2 3) +84 pascal DrawIcon(word s_word s_word word) DrawIcon(1 2 3 4) 85 pascal DrawText(word ptr s_word ptr word) DrawText(1 2 3 4 5) 87 pascal DialogBox(word ptr word ptr) DialogBox(1 2 3 4) 88 pascal EndDialog(word s_word) EndDialog(1 2) @@ -109,8 +120,11 @@ length 540 181 pascal SetSysColors(word ptr ptr) SetSysColors(1 2 3) 182 pascal KillSystemTimer(word word) KillSystemTimer(1 2) 190 pascal GetUpdateRect(word ptr word) GetUpdateRect(1 2 3) +218 pascal DialogBoxIndirect(word word word ptr) DialogBoxIndirect(1 2 3 4) 219 pascal CreateDialogIndirect(word ptr word ptr) CreateDialogIndirect(1 2 3 4) +221 pascal ScrollDC(word s_word s_word ptr ptr word ptr) + ScrollDC(1 2 3 4 5 6 7) 227 pascal GetNextDlgGroupItem(word word word) GetNextDlgGroupItem(1 2 3) 228 pascal GetNextDlgTabItem(word word word) GetNextDlgTabItem(1 2 3) 229 pascal GetTopWindow(word) GetTopWindow(1) @@ -118,6 +132,9 @@ length 540 232 pascal SetWindowPos(word word word word word word word) SetWindowPos(1 2 3 4 5 6 7) 237 pascal GetUpdateRgn(word word word) GetUpdateRgn(1 2 3) +239 pascal DialogBoxParam(word ptr word ptr long) DialogBoxParam(1 2 3 4 5) +240 pascal DialogBoxIndirectParam(word word word ptr long) + DialogBoxIndirectParam(1 2 3 4 5) 241 pascal CreateDialogParam(word ptr word ptr long) CreateDialogParam(1 2 3 4 5) 242 pascal CreateDialogIndirectParam(word ptr word ptr long) @@ -128,6 +145,8 @@ length 540 277 pascal GetDlgCtrlID(word) GetDlgCtrlID(1) 286 pascal GetDesktopWindow() GetDesktopWindow() 288 pascal GetMessageExtraInfo() GetMessageExtraInfo() +319 pascal ScrollWindowEx(word s_word s_word ptr ptr word ptr word) + ScrollWindowEx(1 2 3 4 5 6 7 8) 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) 334 pascal GetQueueStatus(word) GetQueueStatus(1) @@ -149,6 +168,8 @@ length 540 452 pascal CreateWindowEx(long ptr ptr long s_word s_word s_word s_word word word word ptr) CreateWindowEx(1 2 3 4 5 6 7 8 9 10 11 12) +457 pascal DestroyIcon(word) DestroyIcon(1) +458 pascal DestroyCursor(word) DestroyCursor(1) 471 pascal lstrcmpi(ptr ptr) lstrcmpi(1 2) 472 pascal AnsiNext(ptr) AnsiNext(1 ) 473 pascal AnsiPrev(ptr ptr) AnsiPrev(1 2) diff --git a/include/cursor.h b/include/cursor.h new file mode 100644 index 00000000000..c70df90728d --- /dev/null +++ b/include/cursor.h @@ -0,0 +1,27 @@ +/* + * structure definitions for CURSOR + * + * Copyright Martin Ayotte, 1993 + * + */ + +typedef struct { + BYTE Width; + BYTE Reserved1; + BYTE Height; + BYTE Reserved2; + WORD curXHotspot; + WORD curYHotspot; + DWORD curDIBSize; + DWORD curDIBOffset; + } CURSORDESCRIP; + +typedef struct { + CURSORDESCRIP descriptor; + HBITMAP hBitmap; + Display *display; + Pixmap pixshape; + Pixmap pixmask; + Cursor xcursor; + } CURSORALLOC; + diff --git a/include/dialog.h b/include/dialog.h index 190c8c97ed1..4cfddbaaebb 100644 --- a/include/dialog.h +++ b/include/dialog.h @@ -54,15 +54,6 @@ typedef struct } DLGCONTROLHEADER; - /* Dialog control data */ -typedef struct -{ - DLGCONTROLHEADER * header; - LPSTR class; - LPSTR text; -} DLGCONTROL; - - /* Dialog template */ typedef struct { @@ -72,7 +63,6 @@ typedef struct LPSTR caption; WORD pointSize; LPSTR faceName; - DLGCONTROL * controls; } DLGTEMPLATE; diff --git a/include/icon.h b/include/icon.h new file mode 100644 index 00000000000..4a38a60f5bf --- /dev/null +++ b/include/icon.h @@ -0,0 +1,26 @@ +/* + * structure definitions for ICON + * + * Copyright Martin Ayotte, 1993 + * + */ + + +typedef struct { + BYTE Width; + BYTE Height; + BYTE ColorCount; + BYTE Reserved1; + WORD Reserved2; + WORD Reserved3; + DWORD icoDIBSize; + DWORD icoDIBOffset; + } ICONDESCRIP; + +typedef struct { + ICONDESCRIP descriptor; + HBITMAP hBitmap; + HBITMAP hBitMask; + } ICONALLOC; + + diff --git a/include/segmem.h b/include/segmem.h index 6c4f7c5588b..ea9f8512402 100644 --- a/include/segmem.h +++ b/include/segmem.h @@ -6,6 +6,19 @@ #ifndef SEGMEM_H #define SEGMEM_H +/* + * Array to track selector allocation. + */ +#define MAX_SELECTORS 512 +#define SELECTOR_ISFREE 0x8000 +#define SELECTOR_INDEXMASK 0x0fff + +extern unsigned short SelectorMap[MAX_SELECTORS]; + +#define SAFEMAKEPTR(s, o) \ + (((int) SelectorMap[SelectorMap[(s) >> 3] & SELECTOR_INDEXMASK] << 19) \ + | 0x70000 | ((o) & 0xffff)) + /* * Structure to hold info about each selector we create. */ diff --git a/include/windows.h b/include/windows.h index dd937c5383e..9d3eaf3ba76 100644 --- a/include/windows.h +++ b/include/windows.h @@ -66,6 +66,14 @@ typedef int *LPCATCHBUF; #define MAKELONG(low, high) ((LONG)(((WORD)(low)) | (((DWORD)((WORD)(high))) << 16))) +#ifndef max +#define max(a,b) (((a) > (b)) ? (a) : (b)) +#endif + +#ifndef min +#define min(a,b) (((a) < (b)) ? (a) : (b)) +#endif + /* typedef long LONG; typedef WORD HANDLE; @@ -136,6 +144,8 @@ typedef struct { LPSTR lpszClassName __attribute__ ((packed)); } WNDCLASS, *LPWNDCLASS; +typedef LONG (* WNDPROC)() __attribute__ ((packed)); + #define CS_VREDRAW 0x0001 #define CS_HREDRAW 0x0002 #define CS_KEYCVTWINDOW 0x0004 @@ -230,6 +240,15 @@ typedef struct { #define DLGC_STATIC 0x0100 #define DLGC_BUTTON 0x2000 +/* Standard dialog button IDs */ +#define IDOK 1 +#define IDCANCEL 2 +#define IDABORT 3 +#define IDRETRY 4 +#define IDIGNORE 5 +#define IDYES 6 +#define IDNO 7 + typedef struct { short x, y; } POINT; typedef POINT *PPOINT; @@ -735,17 +754,17 @@ typedef struct { BYTE rgbtBlue, rgbtGreen, rgbtRed; } RGBTRIPLE; typedef struct tagBITMAPINFOHEADER { - unsigned long biSize; - unsigned long biWidth; - unsigned long biHeight; - unsigned short biPlanes; - unsigned short biBitCount; - unsigned long biCompression; - unsigned long biSizeImage; - unsigned long biXPelsPerMeter; - unsigned long biYPelsPerMeter; - unsigned long biClrUsed; - unsigned long biClrImportant; + DWORD biSize; + DWORD biWidth; + DWORD biHeight; + WORD biPlanes; + WORD biBitCount; + DWORD biCompression; + DWORD biSizeImage; + DWORD biXPelsPerMeter; + DWORD biYPelsPerMeter; + DWORD biClrUsed; + DWORD biClrImportant; } BITMAPINFOHEADER; typedef BITMAPINFOHEADER * LPBITMAPINFOHEADER; @@ -1021,8 +1040,34 @@ enum { SW_HIDE, SW_SHOWNORMAL, SW_NORMAL, SW_SHOWMINIMIZED, SW_SHOWMAXIMIZED, #define GCW_HBRBACKGROUND (-10) #endif -#define MB_OK 0 -#define MB_ICONINFORMATION 0x0040 +#define MB_OK 0x0000 +#define MB_OKCANCEL 0x0001 +#define MB_ABORTRETRYIGNORE 0x0002 +#define MB_YESNOCANCEL 0x0003 +#define MB_YESNO 0x0004 +#define MB_RETRYCANCEL 0x0005 +#define MB_TYPEMASK 0x000F + +#define MB_ICONHAND 0x0010 +#define MB_ICONQUESTION 0x0020 +#define MB_ICONEXCLAMATION 0x0030 +#define MB_ICONASTERISK 0x0040 +#define MB_ICONMASK 0x00F0 + +#define MB_ICONINFORMATION MB_ICONASTERISK +#define MB_ICONSTOP MB_ICONHAND + +#define MB_DEFBUTTON1 0x0000 +#define MB_DEFBUTTON2 0x0100 +#define MB_DEFBUTTON3 0x0200 +#define MB_DEFMASK 0x0F00 + +#define MB_APPLMODAL 0x0000 +#define MB_SYSTEMMODAL 0x1000 +#define MB_TASKMODAL 0x2000 + +#define MB_NOFOCUS 0x8000 + #define DT_TOP 0 #define DT_LEFT 0 @@ -1079,6 +1124,11 @@ enum { SW_HIDE, SW_SHOWNORMAL, SW_NORMAL, SW_SHOWMINIMIZED, SW_SHOWMAXIMIZED, #define WS_EX_ACCEPTFILES 0x00000010L #define WS_EX_TRANSPARENT 0x00000020L +/* Window scrolling */ +#define SW_SCROLLCHILDREN 0x0001 +#define SW_INVALIDATE 0x0002 +#define SW_ERASE 0x0003 + /* Button control styles */ #define BS_PUSHBUTTON 0x00000000L #define BS_DEFPUSHBUTTON 0x00000001L @@ -1319,6 +1369,70 @@ enum { SW_HIDE, SW_SHOWNORMAL, SW_NORMAL, SW_SHOWMINIMIZED, SW_SHOWMAXIMIZED, #define ODS_CHECKED 0x0008 #define ODS_FOCUS 0x0010 +/* Edit control styles */ +#define ES_LEFT 0x00000000L +#define ES_CENTER 0x00000001L +#define ES_RIGHT 0x00000002L +#define ES_MULTILINE 0x00000004L +#define ES_UPPERCASE 0x00000008L +#define ES_LOWERCASE 0x00000010L +#define ES_PASSWORD 0x00000020L +#define ES_AUTOVSCROLL 0x00000040L +#define ES_AUTOHSCROLL 0x00000080L +#define ES_NOHISESEL 0x00000100L +#define ES_OEMCONVERT 0x00000400L +#define ES_READONLY 0x00000800L +#define ES_WANTRETURN 0x00001000L + +/* Edit control messages */ +#define EM_GETSEL (WM_USER+0) +#define EM_SETSEL (WM_USER+1) +#define EM_GETRECT (WM_USER+2) +#define EM_SETRECT (WM_USER+3) +#define EM_SETRECTNP (WM_USER+4) +#define EM_LINESCROLL (WM_USER+6) +#define EM_GETMODIFY (WM_USER+8) +#define EM_SETMODIFY (WM_USER+9) +#define EM_GETLINECOUNT (WM_USER+10) +#define EM_LINEINDEX (WM_USER+11) +#define EM_SETHANDLE (WM_USER+12) +#define EM_GETHANDLE (WM_USER+13) +#define EM_LINELENGTH (WM_USER+17) +#define EM_REPLACESEL (WM_USER+18) +#define EM_GETLINE (WM_USER+20) +#define EM_LIMITTEXT (WM_USER+21) +#define EM_CANUNDO (WM_USER+22) +#define EM_UNDO (WM_USER+23) +#define EM_FMTLINES (WM_USER+24) +#define EM_LINEFROMCHAR (WM_USER+25) +#define EM_SETTABSTOPS (WM_USER+27) +#define EM_SETPASSWORDCHAR (WM_USER+28) +#define EM_EMPTYUNDOBUFFER (WM_USER+29) +#define EM_GETFIRSTVISIBLELINE (WM_USER+30) +#define EM_SETREADONLY (WM_USER+31) +#define EM_SETWORDBREAKPROC (WM_USER+32) +#define EM_GETWORDBREAKPROC (WM_USER+33) +#define EM_GETPASSWORDCHAR (WM_USER+34) + +typedef int (CALLBACK *EDITWORDBREAKPROC)(LPSTR lpch, int ichCurrent, + int cch, int code); + +/* EDITWORDBREAKPROC code values */ +#define WB_LEFT 0 +#define WB_RIGHT 1 +#define WB_ISDELIMITER 2 + +/* Edit control notification codes */ +#define EN_SETFOCUS 0x0100 +#define EN_KILLFOCUS 0x0200 +#define EN_CHANGE 0x0300 +#define EN_UPDATE 0x0400 +#define EN_ERRSPACE 0x0500 +#define EN_MAXTEXT 0x0501 +#define EN_HSCROLL 0x0601 +#define EN_VSCROLL 0x0602 + + #define WM_DRAWITEM 0x002B typedef struct tagDRAWITEMSTRUCT @@ -1485,12 +1599,12 @@ Fb(int,_lopen,LPSTR,a,int,b) Fa(int,lstrlen,LPCSTR,a) Fa(LONG,DispatchMessage,LPMSG,msg) Fa(void,UpdateWindow,HWND,a) -Fa(ATOM,AddAtom,LPSTR,a) +Fa(ATOM,AddAtom,LPCSTR,a) Fa(ATOM,DeleteAtom,ATOM,a) -Fa(ATOM,FindAtom,LPSTR,a) -Fa(ATOM,GlobalAddAtom,LPSTR,a) +Fa(ATOM,FindAtom,LPCSTR,a) +Fa(ATOM,GlobalAddAtom,LPCSTR,a) Fa(ATOM,GlobalDeleteAtom,ATOM,a) -Fa(ATOM,GlobalFindAtom,LPSTR,a) +Fa(ATOM,GlobalFindAtom,LPCSTR,a) Fa(BOOL,DeleteDC,HDC,a) Fa(BOOL,DeleteMetaFile,HANDLE,a) Fa(BOOL,DeleteObject,HANDLE,a) @@ -1504,7 +1618,7 @@ Fa(BOOL,FreeResource,HANDLE,a) Fa(BOOL,GlobalUnWire,HANDLE,a) Fa(BOOL,GlobalUnfix,HANDLE,a) Fa(BOOL,GlobalUnlock,HANDLE,a) -Fa(BOOL,InitAtomTable,int,a) +Fa(BOOL,InitAtomTable,WORD,a) Fa(BOOL,IsClipboardFormatAvailable,WORD,a) Fa(BOOL,IsIconic,HWND,a) Fa(BOOL,IsRectEmpty,LPRECT,a) @@ -1858,10 +1972,10 @@ Fc(LONG,GetBitmapBits,HBITMAP,a,LONG,b,LPSTR,c) Fc(LONG,SetBitmapBits,HBITMAP,a,LONG,b,LPSTR,c) Fc(LONG,SetClassLong,HWND,a,short,b,LONG,c) Fc(LONG,SetWindowLong,HWND,a,short,b,LONG,c) -Fc(WORD,GetAtomName,ATOM,a,LPSTR,b,int,c) +Fc(WORD,GetAtomName,ATOM,a,LPSTR,b,short,c) Fc(WORD,GetMenuState,HMENU,a,WORD,b,WORD,c) Fc(WORD,GetProfileInt,LPSTR,a,LPSTR,b,int,c) -Fc(WORD,GlobalGetAtomName,ATOM,a,LPSTR,b,int,c) +Fc(WORD,GlobalGetAtomName,ATOM,a,LPSTR,b,short,c) Fc(WORD,SetClassWord,HWND,a,short,b,WORD,c) Fc(WORD,SetWindowWord,HWND,a,short,b,WORD,c) Fb(WORD,SetBkMode,HDC,a,WORD,b) @@ -1911,7 +2025,7 @@ Fd(BOOL,PostMessage,HWND,a,WORD,b,WORD,c,LONG,d) Fd(LONG,SendMessage,HWND,a,WORD,b,WORD,c,LONG,d) Fd(BOOL,GetMessage,LPMSG,msg,HWND,b,WORD,c,WORD,d) Fd(BOOL,GetTextExtentPoint,HDC,a,LPSTR,b,short,c,LPSIZE,d) -Fd(BOOL,DrawIcon,HDC,a,int,b,int,c,HICON,d) +Fd(BOOL,DrawIcon,HDC,a,short,b,short,c,HICON,d) Fd(BOOL,EnumMetaFile,HDC,a,LOCALHANDLE,b,FARPROC,c,BYTE FAR*,d) Fd(BOOL,FloodFill,HDC,a,int,b,int,c,DWORD,d) Fd(BOOL,GetCharWidth,HDC,a,WORD,b,WORD,c,LPINT,d) @@ -1986,7 +2100,7 @@ Fe(HWND,CreateDialogParam,HANDLE,a,LPCSTR,b,HWND,c,FARPROC,d,LPARAM,e) Fe(LONG,DefFrameProc,HWND,a,HWND,b,WORD,c,WORD,d,LONG,e) Fe(LONG,SendDlgItemMessage,HWND,a,WORD,b,WORD,c,WORD,d,LONG,e) Fe(int,DialogBoxIndirectParam,HANDLE,a,HANDLE,b,HWND,c,FARPROC,d,LONG,e) -Fe(int,DialogBoxParam,HANDLE,a,LPSTR,b,HWND,c,FARPROC,d,LONG,e) +Fe(int,DialogBoxParam,HANDLE,a,LPCSTR,b,HWND,c,FARPROC,d,LONG,e) Fe(int,DlgDirList,HWND,a,LPSTR,b,int,c,int,d,WORD,e) Fe(int,DlgDirListComboBox,HWND,a,LPSTR,b,int,c,int,d,WORD,e) Fe(int,Escape,HDC,a,int,b,int,c,LPSTR,d,LPSTR,e) @@ -1999,7 +2113,7 @@ Fe(int,IntersectVisRect,HDC,a,short,b,short,c,short,d,short,e) Fe(int,SetVoiceAccent,int,a,int,b,int,c,int,d,int,e) Fe(int,ToAscii,WORD,wVirtKey,WORD,wScanCode,LPSTR,lpKeyState,LPVOID,lpChar,WORD,wFlags) Fe(void,PaintRect,HWND,a,HWND,b,HDC,c,HBRUSH,d,LPRECT,e) -Fe(void,ScrollWindow,HWND,a,int,b,int,c,LPRECT,d,LPRECT,e) +Fe(void,ScrollWindow,HWND,a,short,b,short,c,LPRECT,d,LPRECT,e) Fe(void,SetRect,LPRECT,a,short,b,short,c,short,d,short,e) Fe(void,SetRectRgn,HRGN,a,short,b,short,c,short,d,short,e) Fe(void,SetScrollRange,HWND,a,int,b,int,c,int,d,BOOL,e) @@ -2012,7 +2126,7 @@ Ff(void,MoveWindow,HWND,a,short,b,short,c,short,d,short,e,BOOL,f) Ff(BOOL,ScaleViewportExtEx,HDC,a,short,b,short,c,short,d,short,e,LPSIZE,f) Ff(BOOL,ScaleWindowExtEx,HDC,a,short,b,short,c,short,d,short,e,LPSIZE,f) Fg(BOOL,RoundRect,HDC,a,short,b,short,c,short,d,short,e,short,f,short,g) -Fg(BOOL,ScrollDC,HDC,a,int,b,int,c,LPRECT,d,LPRECT,e,HRGN,f,LPRECT,g) +Fg(BOOL,ScrollDC,HDC,a,short,b,short,c,LPRECT,d,LPRECT,e,HRGN,f,LPRECT,g) Fg(BOOL,TrackPopupMenu,HMENU,a,WORD,b,int,c,int,d,int,e,HWND,f,LPRECT,g) Fg(HCURSOR,CreateCursor,HANDLE,a,int,b,int,c,int,d,int,e,LPSTR,f,LPSTR,g) Fg(HICON,CreateIcon,HANDLE,a,int,b,int,c,BYTE,d,BYTE,e,LPSTR,f,LPSTR,g) @@ -2022,6 +2136,7 @@ Fg(void,SetWindowPos,HWND,a,HWND,b,short,c,short,d,short,e,short,f,WORD,g) Fh(BOOL,ExtTextOut,HDC,a,int,b,int,c,WORD,d,LPRECT,e,LPSTR,f,WORD,g,LPINT,h) Fh(HANDLE,DeferWindowPos,HANDLE,hWinPosInfo,HWND,hWnd,HWND,hWndInsertAfter,int,x,int,y,int,cx,int,cy,WORD,wFlags) Fh(LONG,TabbedTextOut,HDC,a,int,b,int,c,LPSTR,d,int,e,int,f,LPINT,g,int,h) +Fh(int,ScrollWindowEx,HWND,a,short,b,short,c,LPRECT,d,LPRECT,e,HRGN,f,LPRECT,g,WORD,h) Fi(BOOL,Arc,HDC,a,int,xLeft,int,yTop,int,xRight,int,yBottom,int,xStart,int,yStart,int,xEnd,int,yEnd) Fi(BOOL,Chord,HDC,a,int,xLeft,int,yTop,int,xRight,int,yBottom,int,xStart,int,yStart,int,xEnd,int,yEnd) Fi(BOOL,BitBlt,HDC,a,short,b,short,c,short,d,short,e,HDC,f,short,g,short,h,DWORD,i) diff --git a/loader/Makefile b/loader/Makefile index 662b5975af7..873a6acd59d 100644 --- a/loader/Makefile +++ b/loader/Makefile @@ -1,7 +1,7 @@ CFLAGS=$(COPTS) $(DEBUGOPTS) -I../include OBJS=dump.o files.o ldt.o ldtlib.o resource.o selector.o signal.o int1a.o \ - int21.o wine.o + int21.o wine.o library.o default: loader.o diff --git a/loader/files.c b/loader/files.c index 8bf3fbb23b3..a4371c6e8ac 100644 --- a/loader/files.c +++ b/loader/files.c @@ -66,6 +66,7 @@ FindFileInPath(char *buffer, int buflen, char *rootname, strncpy(buffer, dirname, buflen); strncat(buffer, "/", buflen - strlen(buffer)); strncat(buffer, f->d_name, buflen - strlen(buffer)); + closedir(d); return buffer; } } diff --git a/loader/int21.c b/loader/int21.c index 968801b34f0..fdf506aa486 100644 --- a/loader/int21.c +++ b/loader/int21.c @@ -665,6 +665,7 @@ void GetFileDateTime(struct sigcontext_struct *context) struct stat filestat; struct tm *now; + dirname = (char *) pointer(DS,DX); ParseDOSFileName(unixname, dirname, &drive); { @@ -872,7 +873,7 @@ int do_int21(struct sigcontext_struct * context){ case 0x12: /* FIND NEXT MATCHING FILE USING FCB */ case 0x13: /* DELETE FILE USING FCB */ case 0x14: /* SEQUENTIAL READ FROM FCB FILE */ - case 0x15: /* SEQUENTIAL WRITE TO FCB FILE + case 0x15: /* SEQUENTIAL WRITE TO FCB FILE */ case 0x16: /* CREATE OR TRUNCATE FILE USING FCB */ case 0x17: /* RENAME FILE USING FCB */ case 0x1a: /* SET DISK TRANSFER AREA ADDRESS */ @@ -888,7 +889,7 @@ int do_int21(struct sigcontext_struct * context){ case 0x2e: /* SET VERIFY FLAG */ break; - case 0x18: /* NULL FUNCTIONS FOR CP/M COMPATIBILITY * + case 0x18: /* NULL FUNCTIONS FOR CP/M COMPATIBILITY */ case 0x1d: case 0x1e: case 0x20: diff --git a/loader/library.c b/loader/library.c new file mode 100644 index 00000000000..6e96351de24 --- /dev/null +++ b/loader/library.c @@ -0,0 +1,37 @@ + +#include +#include +#include +#include +#include +#include +#include "prototypes.h" +#include "windows.h" +#include "win.h" +#include "gdi.h" +#include "wine.h" + + + +/********************************************************************** + * LoadLibrary [KERNEL.95] + */ +HANDLE LoadLibrary(LPSTR libname) +{ + HANDLE hRet; + printf("LoadLibrary '%s'\n", libname); + hRet = LoadImage(libname, NULL); + printf("after LoadLibrary hRet=%04X\n", hRet); + return hRet; +} + + +/********************************************************************** + * FreeLibrary [KERNEL.96] + */ +void FreeLibrary(HANDLE hLib) +{ + printf("FreeLibrary(%04X);\n", hLib); + if (hLib != (HANDLE)NULL) GlobalFree(hLib); +} + diff --git a/loader/resource.c b/loader/resource.c index eeafc9e8622..a0c986c49f1 100644 --- a/loader/resource.c +++ b/loader/resource.c @@ -1,6 +1,7 @@ static char RCSId[] = "$Id: resource.c,v 1.4 1993/07/04 04:04:21 root Exp root $"; static char Copyright[] = "Copyright Robert J. Amstadt, 1993"; +#include #include #include #include @@ -8,16 +9,32 @@ static char Copyright[] = "Copyright Robert J. Amstadt, 1993"; #include #include #include "prototypes.h" -#include "neexe.h" #include "windows.h" +#include "win.h" #include "gdi.h" #include "wine.h" +#include "icon.h" +#include "cursor.h" #define MIN(a,b) ((a) < (b) ? (a) : (b)) +typedef struct resource_s +{ + struct resource_s *next; + HANDLE info_mem; + int size_shift; + struct resource_nameinfo_s nameinfo; + HANDLE rsc_mem; +} RESOURCE; + static int ResourceFd = -1; static HANDLE ResourceInst = 0; static struct w_files *ResourceFileInfo = NULL; +static RESOURCE *Top = NULL; +static HCURSOR hActiveCursor; +extern HINSTANCE hSysRes; + +HANDLE RSC_LoadResource(int instance, char *rsc_name, int type, int *image_size_ret); /********************************************************************** @@ -227,6 +244,11 @@ FindResourceByName(struct resource_nameinfo_s *result_p, printf("FindResourceByName (%s) bad typeinfo size !\n", resource_name); return -1; } +#ifdef DEBUG_RESOURCE + printf("FindResourceByName typeinfo.type_id=%d type_id=%d\n", + typeinfo.type_id, type_id); +#endif + if (typeinfo.type_id == 0) break; if (typeinfo.type_id == type_id || type_id == -1) { for (i = 0; i < typeinfo.count; i++) @@ -248,6 +270,10 @@ FindResourceByName(struct resource_nameinfo_s *result_p, read(ResourceFd, name, nbytes); lseek(ResourceFd, old_pos, SEEK_SET); name[nbytes] = '\0'; +#ifdef DEBUG_RESOURCE + printf("FindResourceByName type_id=%d name='%s' resource_name='%s'\n", + typeinfo.type_id, name, resource_name); +#endif if (strcasecmp(name, resource_name) == 0) { memcpy(result_p, &nameinfo, sizeof(nameinfo)); @@ -255,31 +281,289 @@ FindResourceByName(struct resource_nameinfo_s *result_p, } } } + else { + lseek(ResourceFd, (typeinfo.count * sizeof(nameinfo)), SEEK_CUR); + } } - printf("FindResourceByName (%s) typeinfo.type_id = 0 !\n", resource_name); - return -1; } - + + /********************************************************************** - * LoadIcon + * LoadIcon [USER.174] */ -HICON -LoadIcon(HANDLE instance, LPSTR icon_name) +HICON LoadIcon(HANDLE instance, LPSTR icon_name) { - fprintf(stderr,"LoadIcon: (%d),%d\n",instance,icon_name); + HICON hIcon; + HANDLE rsc_mem; + WORD *lp; + ICONDESCRIP *lpicodesc; + ICONALLOC *lpico; + int width, height; + BITMAPINFO *bmi; + BITMAPINFOHEADER *bih; + RGBQUAD *rgbq; + HBITMAP hBitMap; + HDC hMemDC; + HDC hMemDC2; + HDC hdc; + int i, j, image_size; +#ifdef DEBUG_RESOURCE + printf("LoadIcon: instance = %04x, name = %08x\n", + instance, icon_name); +#endif + + if (instance == (HANDLE)NULL) instance = hSysRes; + if (!(hdc = GetDC(GetDesktopWindow()))) return 0; + rsc_mem = RSC_LoadResource(instance, icon_name, NE_RSCTYPE_GROUP_ICON, + &image_size); + if (rsc_mem == (HANDLE)NULL) { + printf("LoadIcon / Icon %04X not Found !\n", icon_name); + return 0; + } + lp = (WORD *)GlobalLock(rsc_mem); + if (lp == NULL) { + GlobalFree(rsc_mem); + return 0; + } + lpicodesc = (ICONDESCRIP *)(lp + 3); + hIcon = GlobalAlloc(GMEM_MOVEABLE, sizeof(ICONALLOC) + 1024); + if (hIcon == (HICON)NULL) { + GlobalFree(rsc_mem); + return 0; + } + printf("LoadIcon Alloc hIcon=%X\n", hIcon); + lpico = (ICONALLOC *)GlobalLock(hIcon); + lpico->descriptor = *lpicodesc; + width = lpicodesc->Width; + height = lpicodesc->Height; + GlobalUnlock(rsc_mem); + GlobalFree(rsc_mem); + rsc_mem = RSC_LoadResource(instance, + MAKEINTRESOURCE(lpicodesc->icoDIBOffset), + NE_RSCTYPE_ICON, &image_size); + if (rsc_mem == (HANDLE)NULL) { + printf("LoadIcon / Icon %04X Bitmaps not Found !\n", icon_name); + return 0; + } + lp = (WORD *)GlobalLock(rsc_mem); + if (lp == NULL) { + GlobalFree(rsc_mem); + return 0; + } + bmi = (BITMAPINFO *)lp; + bih = (BITMAPINFOHEADER *)lp; + rgbq = &bmi->bmiColors[0]; + bih->biHeight = bih->biHeight / 2; +/* + printf("LoadIcon / image_size=%d width=%d height=%d bih->biBitCount=%d bih->biSizeImage=%ld\n", + image_size, width, height, bih->biBitCount, bih->biSizeImage); +*/ + if (bih->biSize == sizeof(BITMAPINFOHEADER)) + lpico->hBitmap = ConvertInfoBitmap(hdc, (BITMAPINFO *)bih); + else + lpico->hBitmap = 0; + bih->biBitCount = 1; + bih->biClrUsed = bih->biClrImportant = 2; + rgbq[0].rgbBlue = 0xFF; + rgbq[0].rgbGreen = 0xFF; + rgbq[0].rgbRed = 0xFF; + rgbq[0].rgbReserved = 0x00; + rgbq[1].rgbBlue = 0x00; + rgbq[1].rgbGreen = 0x00; + rgbq[1].rgbRed = 0x00; + rgbq[1].rgbReserved = 0x00; + lpico->hBitMask = CreateDIBitmap(hdc, bih, CBM_INIT, + (LPSTR)lp + bih->biSizeImage - sizeof(BITMAPINFOHEADER) / 2 - 4, + (BITMAPINFO *)bih, DIB_RGB_COLORS ); + GlobalUnlock(rsc_mem); + GlobalFree(rsc_mem); + + hMemDC = CreateCompatibleDC(hdc); + hMemDC2 = CreateCompatibleDC(hdc); + SelectObject(hMemDC, lpico->hBitmap); + SelectObject(hMemDC2, lpico->hBitMask); + BitBlt(hMemDC, 0, 0, bih->biWidth, bih->biHeight, hMemDC2, 0, 0, SRCINVERT); + DeleteDC(hMemDC); + DeleteDC(hMemDC2); + + ReleaseDC(0, hdc); + return hIcon; +} + + +/********************************************************************** + * DestroyIcon [USER.457] + */ +BOOL DestroyIcon(HICON hIcon) +{ + ICONALLOC *lpico; + if (hIcon == (HICON)NULL) return FALSE; + lpico = (ICONALLOC *)GlobalLock(hIcon); + if (lpico->hBitmap != (HBITMAP)NULL) DeleteObject(lpico->hBitmap); + GlobalFree(hIcon); + return TRUE; +} + + +/********************************************************************** + * LoadCursor [USER.173] + */ +HCURSOR LoadCursor(HANDLE instance, LPSTR cursor_name) +{ + XColor bkcolor; + XColor fgcolor; + HCURSOR hCursor; + HANDLE rsc_mem; + WORD *lp; + CURSORDESCRIP *lpcurdesc; + CURSORALLOC *lpcur; + BITMAP BitMap; + HBITMAP hBitMap; + HDC hMemDC; + HDC hdc; + int i, j, image_size; +#ifdef DEBUG_RESOURCE + printf("LoadCursor: instance = %04x, name = %08x\n", + instance, cursor_name); +#endif + if (!(hdc = GetDC(GetDesktopWindow()))) return 0; + if (instance == (HANDLE)NULL) instance = hSysRes; + rsc_mem = RSC_LoadResource(instance, cursor_name, NE_RSCTYPE_GROUP_CURSOR, + &image_size); + if (rsc_mem == (HANDLE)NULL) { + printf("LoadCursor / Cursor %08X not Found !\n", cursor_name); + return 0; + } + lp = (WORD *)GlobalLock(rsc_mem); + if (lp == NULL) { + GlobalFree(rsc_mem); + return 0; + } + lpcurdesc = (CURSORDESCRIP *)(lp + 3); +#ifdef DEBUG_CURSOR + printf("LoadCursor / image_size=%d\n", image_size); + printf("LoadCursor / curReserved=%X\n", *lp); + printf("LoadCursor / curResourceType=%X\n", *(lp + 1)); + printf("LoadCursor / curResourceCount=%X\n", *(lp + 2)); + printf("LoadCursor / cursor Width=%d\n", (int)lpcurdesc->Width); + printf("LoadCursor / cursor Height=%d\n", (int)lpcurdesc->Height); + printf("LoadCursor / cursor curXHotspot=%d\n", (int)lpcurdesc->curXHotspot); + printf("LoadCursor / cursor curYHotspot=%d\n", (int)lpcurdesc->curYHotspot); + printf("LoadCursor / cursor curDIBSize=%lX\n", (DWORD)lpcurdesc->curDIBSize); + printf("LoadCursor / cursor curDIBOffset=%lX\n", (DWORD)lpcurdesc->curDIBOffset); +#endif + hCursor = GlobalAlloc(GMEM_MOVEABLE, sizeof(CURSORALLOC) + 1024L); + if (hCursor == (HCURSOR)NULL) { + GlobalFree(rsc_mem); + return 0; + } + printf("LoadCursor Alloc hCursor=%X\n", hCursor); + lpcur = (CURSORALLOC *)GlobalLock(hCursor); + lpcur->descriptor = *lpcurdesc; + GlobalUnlock(rsc_mem); + GlobalFree(rsc_mem); + rsc_mem = RSC_LoadResource(instance, + MAKEINTRESOURCE(lpcurdesc->curDIBOffset), + NE_RSCTYPE_CURSOR, &image_size); + if (rsc_mem == (HANDLE)NULL) { + printf("LoadCursor / Cursor %08X Bitmap not Found !\n", cursor_name); + return 0; + } + lp = (WORD *)GlobalLock(rsc_mem); + if (lp == NULL) { + GlobalFree(rsc_mem); + return 0; + } + lp += 2; + for (j = 0; j < 16; j++) + printf("%04X ", *(lp + j)); + if (*lp == sizeof(BITMAPINFOHEADER)) + lpcur->hBitmap = ConvertInfoBitmap(hdc, (BITMAPINFO *)lp); + else + lpcur->hBitmap = 0; + lp += sizeof(BITMAP); + for (i = 0; i < 81; i++) { + char temp = *((char *)lp + 162 + i); + *((char *)lp + 162 + i) = *((char *)lp + 324 - i); + *((char *)lp + 324 - i) = temp; + } +printf("LoadCursor / before XCreatePixmapFromBitmapData !\n"); + lpcur->pixshape = XCreatePixmapFromBitmapData( + XT_display, DefaultRootWindow(XT_display), + ((char *)lp + 211), 32, 32, +/* + lpcurdesc->Width / 2, lpcurdesc->Height / 4, +*/ + WhitePixel(XT_display, DefaultScreen(XT_display)), + BlackPixel(XT_display, DefaultScreen(XT_display)), 1); + lpcur->pixmask = lpcur->pixshape; + bkcolor.pixel = WhitePixel(XT_display, DefaultScreen(XT_display)); + fgcolor.pixel = BlackPixel(XT_display, DefaultScreen(XT_display)); +printf("LoadCursor / before XCreatePixmapCursor !\n"); + lpcur->xcursor = XCreatePixmapCursor(XT_display, + lpcur->pixshape, lpcur->pixmask, + &fgcolor, &bkcolor, lpcur->descriptor.curXHotspot, + lpcur->descriptor.curYHotspot); + + ReleaseDC(0, hdc); + GlobalUnlock(rsc_mem); + GlobalFree(rsc_mem); + return hCursor; +} + + + +/********************************************************************** + * DestroyCursor [USER.458] + */ +BOOL DestroyCursor(HCURSOR hCursor) +{ + CURSORALLOC *lpcur; + if (hCursor == (HCURSOR)NULL) return FALSE; + lpcur = (CURSORALLOC *)GlobalLock(hCursor); + if (lpcur->hBitmap != (HBITMAP)NULL) DeleteObject(lpcur->hBitmap); + GlobalUnlock(hCursor); + GlobalFree(hCursor); + return TRUE; +} + + +/********************************************************************** + * SetCursor [USER.69] + */ +HCURSOR SetCursor(HCURSOR hCursor) +{ + HDC hDC; + HDC hMemDC; + BITMAP bm; + CURSORALLOC *lpcur; + HCURSOR hOldCursor; +#ifdef DEBUG_CURSOR + printf("SetCursor / hCursor=%04X !\n", hCursor); +#endif + if (hCursor == (HCURSOR)NULL) return FALSE; + lpcur = (CURSORALLOC *)GlobalLock(hCursor); + hOldCursor = hActiveCursor; + +printf("SetCursor / before XDefineCursor !\n"); + XDefineCursor(XT_display, DefaultRootWindow(XT_display), lpcur->xcursor); + GlobalUnlock(hCursor); + hActiveCursor = hCursor; + return hOldCursor; +} + + +/********************************************************************** + * ShowCursor [USER.71] + */ +int ShowCursor(BOOL bShow) +{ + if (bShow) { + } return 0; } -/********************************************************************** - * LoadCursor - */ -HCURSOR -LoadCursor(HANDLE instance, LPSTR cursor_name) -{ - fprintf(stderr,"LoadCursor: (%d),%d\n",instance,cursor_name); - return 0; -} /********************************************************************** * LoadAccelerators @@ -296,8 +580,43 @@ LoadAccelerators(HANDLE instance, LPSTR lpTableName) */ HANDLE FindResource(HANDLE instance, LPSTR resource_name, LPSTR type_name) { - fprintf(stderr,"FindResource: (%d),%d\n",instance, resource_name, type_name); - return 0; + RESOURCE *r; + HANDLE rh; + + if (instance == 0) + return 0; + + if (OpenResourceFile(instance) < 0) + return 0; + + rh = GlobalAlloc(GMEM_MOVEABLE, sizeof(*r)); + if (rh == 0) + return 0; + r = (RESOURCE *)GlobalLock(rh); + + r->next = Top; + Top = r; + r->info_mem = rh; + r->rsc_mem = 0; + + if (((int) resource_name & 0xffff0000) == 0) + { + r->size_shift = FindResourceByNumber(&r->nameinfo, type_name, + (int) resource_name | 0x8000); + } + else + { + r->size_shift = FindResourceByName(&r->nameinfo, type_name, + resource_name); + } + + if (r->size_shift == -1) + { + GlobalFree(rh); + return 0; + } + + return rh; } /********************************************************************** @@ -305,8 +624,36 @@ HANDLE FindResource(HANDLE instance, LPSTR resource_name, LPSTR type_name) */ HANDLE LoadResource(HANDLE instance, HANDLE hResInfo) { - fprintf(stderr,"LoadResource: (%d),%d\n",instance, hResInfo); - return ; + RESOURCE *r; + int image_size; + void *image; + HANDLE h; + + if (instance == 0) + return 0; + + if (OpenResourceFile(instance) < 0) + return 0; + + r = (RESOURCE *)GlobalLock(hResInfo); + if (r == NULL) + return 0; + + image_size = r->nameinfo.length << r->size_shift; + + h = r->rsc_mem = GlobalAlloc(GMEM_MOVEABLE, image_size); + image = GlobalLock(h); + + if (image == NULL || read(ResourceFd, image, image_size) != image_size) + { + GlobalFree(h); + GlobalUnlock(hResInfo); + return 0; + } + + GlobalUnlock(h); + GlobalUnlock(hResInfo); + return h; } /********************************************************************** @@ -314,19 +661,51 @@ HANDLE LoadResource(HANDLE instance, HANDLE hResInfo) */ LPSTR LockResource(HANDLE hResData) { - fprintf(stderr,"LockResource: %d\n", hResData); - return ; + return GlobalLock(hResData); } /********************************************************************** * FreeResource [KERNEL.63] */ -BOOL FreeResource(HANDLE hResData) +HANDLE FreeResource(HANDLE hResData) { - fprintf(stderr,"FreeResource: %d\n", hResData); - return ; + RESOURCE *r, *rp; + + for (r = rp = Top; r != NULL; r = r->next) + { + if (r->info_mem == hResData) + { + if (rp != NULL) + rp->next = r->next; + else + Top = r->next; + + GlobalFree(r->rsc_mem); + GlobalFree(r->info_mem); + return 0; + } + } + + return hResData; } +/********************************************************************** + * AccessResource [KERNEL.64] + */ +int AccessResource(HANDLE instance, HANDLE hResInfo) +{ + int resfile; +#ifdef DEBUG_RESOURCE + printf("AccessResource(%04X, %04X);\n", instance, hResInfo); +#endif +/* + resfile = OpenResourceFile(instance); + return resfile; +*/ + return - 1; +} + + /********************************************************************** * RSC_LoadResource @@ -365,9 +744,10 @@ RSC_LoadResource(int instance, char *rsc_name, int type, int *image_size_ret) { size_shift = FindResourceByName(&nameinfo, type, rsc_name); } - if (size_shift == -1) + if (size_shift == -1) { + printf("RSC_LoadResource / Resource '%X' not Found !\n", rsc_name); return 0; - + } /* * Read resource. */ @@ -406,15 +786,15 @@ LoadString(HANDLE instance, WORD resource_id, LPSTR buffer, int buflen) instance, resource_id, buffer, buflen); #endif - hmem = RSC_LoadResource(instance, (char *) (resource_id >> 4), + hmem = RSC_LoadResource(instance, (char *) ((resource_id >> 4) + 1), NE_RSCTYPE_STRING, &rsc_size); if (hmem == 0) return 0; p = GlobalLock(hmem); string_num = resource_id & 0x000f; - for (i = 0; i < resource_id; i++) - p += *p; + for (i = 0; i < string_num; i++) + p += *p + 1; i = MIN(buflen - 1, *p); memcpy(buffer, p + 1, i); @@ -445,7 +825,6 @@ LoadBitmap(HANDLE instance, LPSTR bmp_name) { HBITMAP hbitmap; HANDLE rsc_mem; - GDIOBJHDR * ptr; HDC hdc; long *lp; int image_size; @@ -454,11 +833,20 @@ LoadBitmap(HANDLE instance, LPSTR bmp_name) printf("LoadBitmap: instance = %04x, name = %08x\n", instance, bmp_name); #endif + printf("LoadBitmap: instance = %04x, name = %08x\n", + instance, bmp_name); - if (!(hdc = GetDC( 0 ))) return 0; + if (instance == (HANDLE)NULL) instance = hSysRes; + if (!(hdc = GetDC(GetDesktopWindow()))) return 0; +printf("before RSC_Load\n"); rsc_mem = RSC_LoadResource(instance, bmp_name, NE_RSCTYPE_BITMAP, &image_size); + if (rsc_mem == (HANDLE)NULL) { + printf("LoadBitmap / BitMap %04X not Found !\n", bmp_name); + return 0; + } +printf("before GlobalLock\n"); lp = (long *) GlobalLock(rsc_mem); if (lp == NULL) { @@ -470,7 +858,7 @@ LoadBitmap(HANDLE instance, LPSTR bmp_name) else if (*lp == sizeof(BITMAPINFOHEADER)) hbitmap = ConvertInfoBitmap( hdc, (BITMAPINFO *) lp ); else hbitmap = 0; - +printf("LoadBitmap %04X\n", hbitmap); GlobalFree(rsc_mem); ReleaseDC( 0, hdc ); return hbitmap; diff --git a/loader/selector.c b/loader/selector.c index 489dfd6833f..f091d1da963 100644 --- a/loader/selector.c +++ b/loader/selector.c @@ -38,52 +38,260 @@ static char Copyright[] = "Copyright Robert J. Amstadt, 1993"; #define UTEXTSEL 0x1f #endif -#define MAX_SELECTORS 512 - static struct segment_descriptor_s * EnvironmentSelector = NULL; static struct segment_descriptor_s * PSP_Selector = NULL; struct segment_descriptor_s * MakeProcThunks = NULL; unsigned short PSPSelector; unsigned char ran_out = 0; unsigned short SelectorOwners[MAX_SELECTORS]; +unsigned short SelectorMap[MAX_SELECTORS]; +unsigned short SelectorLimits[MAX_SELECTORS]; +unsigned char SelectorTypes[MAX_SELECTORS]; +int LastUsedSelector = FIRST_SELECTOR - 1; + +#ifdef DEV_ZERO + static FILE *zfile = NULL; +#endif -static int next_unused_selector = FIRST_SELECTOR; extern void KERNEL_Ordinal_102(); extern void UNIXLIB_Ordinal_0(); extern char **Argv; extern int Argc; - + /********************************************************************** - * GetNextSegment + * FindUnusedSelector + */ +int +FindUnusedSelector(void) +{ + int i; + + for (i = LastUsedSelector + 1; i != LastUsedSelector; i++) + { + if (i >= MAX_SELECTORS) + i = FIRST_SELECTOR; + + if (!SelectorMap[i]) + break; + } + + if (i == LastUsedSelector) + return 0; + + LastUsedSelector = i; + return i; +} + +/********************************************************************** + * AllocSelector + * + * This is very bad!!! This function is implemented for Windows + * compatibility only. Do not call this from the emulation library. + */ +unsigned int +AllocSelector(unsigned int old_selector) +{ + int i_new, i_old; + long base; + + i_new = FindUnusedSelector(); + if (old_selector) + { + i_old = (old_selector >> 3); + SelectorMap[i_new] = i_old; + base = SAFEMAKEPTR(old_selector, 0); + if (set_ldt_entry(i_new, base, + SelectorLimits[i_old], 0, + SelectorTypes[i_old], 0, 0) < 0) + { + return 0; + } + + SelectorLimits[i_new] = SelectorLimits[i_old]; + SelectorTypes[i_new] = SelectorTypes[i_old]; + SelectorMap[i_new] = SelectorMap[i_old]; + } + else + { + SelectorMap[i_new] = i_new; + } + + return i_new; +} + +/********************************************************************** + * PrestoChangoSelector + * + * This is very bad!!! This function is implemented for Windows + * compatibility only. Do not call this from the emulation library. + */ +unsigned int PrestoChangoSelector(unsigned src_selector, unsigned dst_selector) +{ + long dst_base, src_base; + char *p; + int src_idx, dst_idx; + int alias_count; + int i; + + src_idx = (SelectorMap[src_selector >> 3]); + dst_idx = dst_selector >> 3; + src_base = (src_idx << 19) | 0x70000; + dst_base = (dst_idx << 19) | 0x70000; + + alias_count = 0; + for (i = FIRST_SELECTOR; i < MAX_SELECTORS; i++) + if (SelectorMap[i] == src_idx) + alias_count++; + + if (SelectorTypes[src_idx] == MODIFY_LDT_CONTENTS_DATA + || alias_count > 1 || src_idx == dst_idx) + { + if (SelectorTypes[src_idx] == MODIFY_LDT_CONTENTS_DATA) + SelectorTypes[dst_idx] = MODIFY_LDT_CONTENTS_CODE; + else + SelectorTypes[dst_idx] = MODIFY_LDT_CONTENTS_DATA; + + SelectorMap[dst_idx] = SelectorMap[src_idx]; + SelectorLimits[dst_idx] = SelectorLimits[src_idx]; + if (set_ldt_entry(dst_idx, src_base, + SelectorLimits[dst_idx], 0, + SelectorTypes[dst_idx], 0, 0) < 0) + { + return 0; + } + } + else + { + /* + * We're changing an unaliased code segment into a data + * segment. The SAFEST (but ugliest) way to deal with + * this is to map the new segment and copy all the contents. + */ + SelectorTypes[dst_idx] = MODIFY_LDT_CONTENTS_DATA; + SelectorMap[dst_idx] = SelectorMap[src_idx]; + SelectorLimits[dst_idx] = SelectorLimits[src_idx]; +#ifdef DEV_ZERO + if (zfile == NULL) + zfile = fopen("/dev/zero","r"); + p = (void *) mmap((char *) dst_base, + ((SelectorLimits[dst_idx] + PAGE_SIZE) + & ~(PAGE_SIZE - 1)), + PROT_EXEC | PROT_READ | PROT_WRITE, + MAP_FIXED | MAP_PRIVATE, fileno(zfile), 0); +#else + p = (void *) mmap((char *) dst_base, + ((SelectorLimits[dst_idx] + PAGE_SIZE) + & ~(PAGE_SIZE - 1)), + PROT_EXEC | PROT_READ | PROT_WRITE, + MAP_FIXED | MAP_PRIVATE | MAP_ANON, -1, 0); +#endif + if (p == NULL) + return 0; + + memcpy((void *) dst_base, (void *) src_base, + SelectorLimits[dst_idx] + 1); + if (set_ldt_entry(src_idx, dst_base, + SelectorLimits[dst_idx], 0, + SelectorTypes[dst_idx], 0, 0) < 0) + { + return 0; + } + if (set_ldt_entry(dst_idx, dst_base, + SelectorLimits[dst_idx], 0, + SelectorTypes[dst_idx], 0, 0) < 0) + { + return 0; + } + } + + return (dst_idx << 3) | 0x0007; +} + +/********************************************************************** + * AllocCStoDSAlias + */ +AllocDStoCSAlias(unsigned int ds_selector) +{ + unsigned int cs_selector; + + if (ds_selector == 0) + return 0; + + cs_selector = AllocSelector(0); + return PrestoChangoSelector(ds_selector, cs_selector); +} + +/********************************************************************** + * FreeSelector + */ +unsigned int FreeSelector(unsigned int sel) +{ + int sel_idx; + int alias_count; + int i; + + sel_idx = SelectorMap[sel >> 3]; + + if (sel_idx != (sel >> 3)) + { + SelectorMap[sel >> 3] = 0; + return 0; + } + + alias_count = 0; + for (i = FIRST_SELECTOR; i < MAX_SELECTORS; i++) + if (SelectorMap[i] == sel_idx) + alias_count++; + + if (alias_count == 1) + { + munmap((char *) (sel << 16), + ((SelectorLimits[sel_idx] + PAGE_SIZE) & ~(PAGE_SIZE - 1))); + SelectorMap[sel >> 3] = 0; + } + + return 0; +} + +/********************************************************************** + * CreateNewSegment */ struct segment_descriptor_s * -GetNextSegment(unsigned int flags, unsigned int limit) +CreateNewSegment(int code_flag, int read_only, int length) { - struct segment_descriptor_s *selectors, *s; - int sel_idx; -#ifdef DEV_ZERO - FILE *zfile; -#endif - - sel_idx = next_unused_selector++; + struct segment_descriptor_s *s; + int contents; + int i; + + i = FindUnusedSelector(); /* * Fill in selector info. */ s = malloc(sizeof(*s)); - s->flags = NE_SEGFLAGS_DATA; - s->selector = (sel_idx << 3) | 0x0007; - s->length = limit; + if (code_flag) + { + contents = MODIFY_LDT_CONTENTS_CODE; + s->flags = 0; + } + else + { + contents = MODIFY_LDT_CONTENTS_DATA; + s->flags = NE_SEGFLAGS_DATA; + } + + s->selector = (i << 3) | 0x0007; + s->length = length; #ifdef DEV_ZERO - zfile = fopen("/dev/zero","r"); + if (zfile == NULL) + zfile = fopen("/dev/zero","r"); s->base_addr = (void *) mmap((char *) (s->selector << 16), ((s->length + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1)), PROT_EXEC | PROT_READ | PROT_WRITE, MAP_FIXED | MAP_PRIVATE, fileno(zfile), 0); - fclose(zfile); #else s->base_addr = (void *) mmap((char *) (s->selector << 16), ((s->length + PAGE_SIZE - 1) & @@ -93,18 +301,30 @@ GetNextSegment(unsigned int flags, unsigned int limit) #endif - if (set_ldt_entry(sel_idx, (unsigned long) s->base_addr, + if (set_ldt_entry(i, (unsigned long) s->base_addr, (s->length - 1) & 0xffff, 0, - MODIFY_LDT_CONTENTS_DATA, 0, 0) < 0) + contents, read_only, 0) < 0) { - next_unused_selector--; free(s); return NULL; } + SelectorMap[i] = (unsigned short) i; + SelectorLimits[i] = s->length - 1; + SelectorTypes[i] = contents; + return s; } - + +/********************************************************************** + * GetNextSegment + */ +struct segment_descriptor_s * +GetNextSegment(unsigned int flags, unsigned int limit) +{ + return CreateNewSegment(0, 0, limit); +} + /********************************************************************** * GetEntryPointFromOrdinal */ @@ -275,37 +495,14 @@ GetDOSEnvironment() * CreateEnvironment */ static struct segment_descriptor_s * -#ifdef DEV_ZERO -CreateEnvironment(FILE *zfile) -#else CreateEnvironment(void) -#endif { char *p; - int sel_idx; struct segment_descriptor_s * s; - s = (struct segment_descriptor_s *) - malloc(sizeof(struct segment_descriptor_s)); - - sel_idx = next_unused_selector++; - /* - * Create memory to hold environment. - */ - s->flags = NE_SEGFLAGS_DATA; - s->selector = (sel_idx << 3) | 0x0007; - s->length = PAGE_SIZE; -#ifdef DEV_ZERO - s->base_addr = (void *) mmap((char *) (s->selector << 16), - PAGE_SIZE, - PROT_EXEC | PROT_READ | PROT_WRITE, - MAP_FIXED | MAP_PRIVATE, fileno(zfile), 0); -#else - s->base_addr = (void *) mmap((char *) (s->selector << 16), - PAGE_SIZE, - PROT_EXEC | PROT_READ | PROT_WRITE, - MAP_FIXED | MAP_PRIVATE | MAP_ANON, -1, 0); -#endif + s = CreateNewSegment(0, 0, PAGE_SIZE); + if (s == NULL) + return NULL; /* * Fill environment with meaningless babble. @@ -318,63 +515,6 @@ CreateEnvironment(void) *p++ = 0; strcpy(p, "C:\\TEST.EXE"); - /* - * Create entry in LDT for this segment. - */ - if (set_ldt_entry(sel_idx, (unsigned long) s->base_addr, - (s->length - 1) & 0xffff, 0, - MODIFY_LDT_CONTENTS_DATA, 0, 0) < 0) - { - myerror("Could not create LDT entry for environment"); - } - return s; -} - -/********************************************************************** - * CreateThunks - */ -static struct segment_descriptor_s * -#ifdef DEV_ZERO -CreateThunks(FILE *zfile) -#else -CreateThunks(void) -#endif -{ - int sel_idx; - struct segment_descriptor_s * s; - - s = (struct segment_descriptor_s *) - malloc(sizeof(struct segment_descriptor_s)); - - sel_idx = next_unused_selector++; - /* - * Create memory to hold environment. - */ - s->flags = 0; - s->selector = (sel_idx << 3) | 0x0007; - s->length = 0x10000; -#ifdef DEV_ZERO - s->base_addr = (void *) mmap((char *) (s->selector << 16), - s->length, - PROT_EXEC | PROT_READ | PROT_WRITE, - MAP_FIXED | MAP_PRIVATE, fileno(zfile), 0); -#else - s->base_addr = (void *) mmap((char *) (s->selector << 16), - s->length, - PROT_EXEC | PROT_READ | PROT_WRITE, - MAP_FIXED | MAP_PRIVATE | MAP_ANON, -1, 0); -#endif - - - /* - * Create entry in LDT for this segment. - */ - if (set_ldt_entry(sel_idx, (unsigned long) s->base_addr, - (s->length - 1) & 0xffff, 0, - MODIFY_LDT_CONTENTS_CODE, 0, 0) < 0) - { - myerror("Could not create LDT entry for thunks"); - } return s; } @@ -382,40 +522,15 @@ CreateThunks(void) * CreatePSP */ static struct segment_descriptor_s * -#ifdef DEV_ZERO -CreatePSP(FILE *zfile) -#else CreatePSP(void) -#endif { struct dos_psp_s *psp; unsigned short *usp; - int sel_idx; struct segment_descriptor_s * s; char *p1, *p2; int i; - s = (struct segment_descriptor_s *) - malloc(sizeof(struct segment_descriptor_s)); - - sel_idx = next_unused_selector++; - /* - * Create memory to hold PSP. - */ - s->flags = NE_SEGFLAGS_DATA; - s->selector = (sel_idx << 3) | 0x0007; - s->length = PAGE_SIZE; -#ifdef DEV_ZERO - s->base_addr = (void *) mmap((char *) (s->selector << 16), - PAGE_SIZE, - PROT_EXEC | PROT_READ | PROT_WRITE, - MAP_FIXED | MAP_PRIVATE, fileno(zfile), 0); -#else - s->base_addr = (void *) mmap((char *) (s->selector << 16), - PAGE_SIZE, - PROT_EXEC | PROT_READ | PROT_WRITE, - MAP_FIXED | MAP_PRIVATE | MAP_ANON, -1, 0); -#endif + s = CreateNewSegment(0, 0, PAGE_SIZE); /* * Fill PSP @@ -451,15 +566,6 @@ CreatePSP(void) *p1 = '\0'; psp->pspCommandTailCount = strlen(psp->pspCommandTail); - /* - * Create entry in LDT for this segment. - */ - if (set_ldt_entry(sel_idx, (unsigned long) s->base_addr, - (s->length - 1) & 0xffff, 0, - MODIFY_LDT_CONTENTS_DATA, 0, 0) < 0) - { - myerror("Could not create LDT entry for PSP"); - } return s; } @@ -472,15 +578,12 @@ CreateSelectors(struct w_files * wpnt) int fd = wpnt->fd; struct ne_segment_table_entry_s *seg_table = wpnt->seg_table; struct ne_header_s *ne_header = wpnt->ne_header; - struct segment_descriptor_s *selectors, *s; - unsigned short *sp; + struct segment_descriptor_s *selectors, *s, *stmp; + unsigned short auto_data_sel; int contents, read_only; int SelectorTableLength; int i; int status; -#ifdef DEV_ZERO - FILE * zfile; -#endif int old_length, file_image_length; /* @@ -495,24 +598,12 @@ CreateSelectors(struct w_files * wpnt) * Step through the segment table in the exe header. */ s = selectors; -#ifdef DEV_ZERO - zfile = fopen("/dev/zero","r"); -#endif for (i = 0; i < ne_header->n_segment_tab; i++, s++) { -#ifdef DEBUG_SEGMENT - printf(" %2d: OFFSET %04.4x, LENGTH %04.4x, ", - i + 1, seg_table[i].seg_data_offset, - seg_table[i].seg_data_length); - printf("FLAGS %04.4x, MIN ALLOC %04.4x\n", - seg_table[i].seg_flags, seg_table[i].min_alloc); -#endif - /* * Store the flags in our table. */ s->flags = seg_table[i].seg_flags; - s->selector = ((next_unused_selector + i) << 3) | 0x0007; /* * Is there an image for this segment in the file? @@ -570,19 +661,12 @@ CreateSelectors(struct w_files * wpnt) if (s->flags & NE_SEGFLAGS_EXECUTEONLY) read_only = 1; } -#ifdef DEV_ZERO - s->base_addr = - (void *) mmap((char *) (s->selector << 16), - (s->length + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1), - PROT_EXEC | PROT_READ | PROT_WRITE, - MAP_FIXED | MAP_PRIVATE, fileno(zfile), 0); -#else - s->base_addr = - (void *) mmap((char *) (s->selector << 16), - (s->length + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1), - PROT_EXEC | PROT_READ | PROT_WRITE, - MAP_FIXED | MAP_PRIVATE | MAP_ANON, -1, 0); -#endif + + stmp = CreateNewSegment(!(s->flags & NE_SEGFLAGS_DATA), read_only, + s->length); + s->base_addr = stmp->base_addr; + s->selector = stmp->selector; + if (seg_table[i].seg_data_offset != 0) { /* @@ -593,56 +677,28 @@ CreateSelectors(struct w_files * wpnt) if(read(fd, s->base_addr, file_image_length) != file_image_length) myerror("Unable to read segment from file"); } - /* - * Create entry in LDT for this segment. - */ - if (set_ldt_entry(s->selector >> 3, (unsigned long) s->base_addr, - (s->length - 1) & 0xffff, 0, - contents, read_only, 0) < 0) - { - free(selectors); - fprintf(stderr,"Ran out of ldt entries.\n"); - ran_out++; - return NULL; - } -#ifdef DEBUG_SEGMENT - printf(" SELECTOR %04.4x, %s\n", - s->selector, - contents == MODIFY_LDT_CONTENTS_CODE ? "CODE" : "DATA"); -#endif + /* * If this is the automatic data segment, then we must initialize * the local heap. */ if (i + 1 == ne_header->auto_data_seg) { + auto_data_sel = s->selector; HEAP_LocalInit(s->base_addr + old_length, ne_header->local_heap_length); } } - sp = &SelectorOwners[next_unused_selector]; - for (i = 0; i < ne_header->n_segment_tab; i++) - *sp++ = (((next_unused_selector + ne_header->auto_data_seg - 1) << 3) - | 0x0007); - - next_unused_selector += ne_header->n_segment_tab; + s = selectors; + for (i = 0; i < ne_header->n_segment_tab; i++, s++) + SelectorOwners[s->selector >> 3] = auto_data_sel; if(!EnvironmentSelector) { -#ifdef DEV_ZERO - EnvironmentSelector = CreateEnvironment(zfile); - PSP_Selector = CreatePSP(zfile); - MakeProcThunks = CreateThunks(zfile); -#else EnvironmentSelector = CreateEnvironment(); PSP_Selector = CreatePSP(); - MakeProcThunks = CreateThunks(); -#endif + MakeProcThunks = CreateNewSegment(1, 0, 0x10000); }; -#ifdef DEV_ZERO - fclose(zfile); -#endif - return selectors; } diff --git a/loader/signal.c b/loader/signal.c index cc85fc751f7..7b2727cae54 100644 --- a/loader/signal.c +++ b/loader/signal.c @@ -10,7 +10,8 @@ #include #include #endif -#include +#include "wine.h" +#include "segmem.h" char * cstack[4096]; struct sigaction segv_act; @@ -64,7 +65,7 @@ static void win_fault(int signal, int code, struct sigcontext *scp){ /* Now take a look at the actual instruction where the program bombed */ - instr = (char *) ((scp->sc_cs << 16) | (scp->sc_eip & 0xffff)); + instr = (char *) SAFEMAKEPTR(scp->sc_cs, scp->sc_eip); if(*instr != 0xcd) { fprintf(stderr, diff --git a/loader/wine.c b/loader/wine.c index 82928caf75a..7124317f09a 100644 --- a/loader/wine.c +++ b/loader/wine.c @@ -38,11 +38,13 @@ int Argc; struct mz_header_s *CurrentMZHeader; struct ne_header_s *CurrentNEHeader; int CurrentNEFile; +HINSTANCE hSysRes; static char *dllExtensions[] = { "dll", "exe", NULL }; static char *exeExtensions[] = { "exe", NULL }; static char *WinePath = NULL; + /********************************************************************** * DebugPrintString */ @@ -99,7 +101,7 @@ GetFileInfo(unsigned short instance) * LoadImage * Load one NE format executable into memory */ -LoadImage(char * filename, char * modulename) +HINSTANCE LoadImage(char * filename, char * modulename) { unsigned int read_size; int i; @@ -236,6 +238,7 @@ LoadImage(char * filename, char * modulename) fprintf(stderr,"Unable to load:%s\n", buff); } +return(wpnt->hinstance); } @@ -278,6 +281,7 @@ _WinMain(int argc, char **argv) } LoadImage(exe_path, NULL); + hSysRes = LoadImage("sysres.dll", NULL); if(ran_out) exit(1); #ifdef DEBUG diff --git a/memory/global.c b/memory/global.c index 3edfbbeadcb..169ebc3878a 100644 --- a/memory/global.c +++ b/memory/global.c @@ -555,7 +555,7 @@ GlobalReAlloc(unsigned int block, unsigned int new_size, unsigned int flags) * reallocate the block. If this fails, call GlobalAlloc() to get * a new block. */ - if (g->sequence = 0) + if (g->sequence == 0) { MDESC **free_list; void *p; diff --git a/misc/Makefile b/misc/Makefile index e5d5542df59..12180d04200 100644 --- a/misc/Makefile +++ b/misc/Makefile @@ -1,7 +1,7 @@ CFLAGS=$(COPTS) $(DEBUGOPTS) -I$(INCLUDE_DIR) OBJS=dos.o kernel.o user.o xt.o rect.o file.o sound.o emulate.o \ - keyboard.o profile.o lstr.o exec.o + keyboard.o profile.o lstr.o exec.o message.o default: misc.o diff --git a/misc/exec.c b/misc/exec.c index d2e7866cf8e..8bbace75dfa 100644 --- a/misc/exec.c +++ b/misc/exec.c @@ -41,7 +41,7 @@ WORD WinExec(LPSTR lpCmdLine, WORD nCmdShow) } switch(fork()) { case -1: - printf("Can'k 'fork' process !\n"); + printf("Can't 'fork' process !\n"); break; case 0: printf("New process started !\n"); @@ -68,7 +68,7 @@ BOOL WinHelp(HWND hWnd, LPSTR lpHelpFile, WORD wCommand, DWORD dwData) printf("WinHelp(%s, %u, %lu)\n", lpHelpFile, wCommand, dwData); switch(fork()) { case -1: - printf("Can'k 'fork' process !\n"); + printf("Can't 'fork' process !\n"); break; case 0: printf("New process started !\n"); diff --git a/misc/message.c b/misc/message.c new file mode 100644 index 00000000000..281b0121a14 --- /dev/null +++ b/misc/message.c @@ -0,0 +1,264 @@ +/* + * 'Wine' MessageBox function handling + * + * Copyright 1993 Martin Ayotte + */ + +static char Copyright[] = "Copyright Martin Ayotte, 1993"; + +#include "windows.h" +#include "heap.h" +#include "win.h" + + +typedef struct tagMSGBOX { + LPSTR Title; + LPSTR Str; + WORD wType; + WORD wRetVal; + BOOL ActiveFlg; + HWND hWndYes; + HWND hWndNo; + HWND hWndCancel; + HICON hIcon; +} MSGBOX; +typedef MSGBOX FAR* LPMSGBOX; + + +LONG SystemMessageBoxProc(HWND hwnd, WORD message, WORD wParam, LONG lParam); + +/************************************************************************** + * MessageBox [USER.1] + */ + +int MessageBox( HWND hWnd, LPSTR str, LPSTR title, WORD type ) +{ + HWND hDlg; + WND *wndPtr; + WNDCLASS wndClass; + MSG msg; + MSGBOX mb; + wndPtr = WIN_FindWndPtr(hWnd); + printf( "MessageBox: '%s'\n", str ); + wndClass.style = CS_HREDRAW | CS_VREDRAW ; + wndClass.lpfnWndProc = (WNDPROC)SystemMessageBoxProc; + wndClass.cbClsExtra = 0; + wndClass.cbWndExtra = 0; + wndClass.hInstance = wndPtr->hInstance; + wndClass.hIcon = (HICON)NULL; + wndClass.hCursor = LoadCursor((HANDLE)NULL, IDC_ARROW); + wndClass.hbrBackground = GetStockObject(WHITE_BRUSH); + wndClass.lpszMenuName = NULL; + wndClass.lpszClassName = "MESSAGEBOX"; + if (!RegisterClass(&wndClass)) return 0; + memset(&mb, 0, sizeof(MSGBOX)); + mb.Title = title; + mb.Str = str; + mb.wType = type; + mb.ActiveFlg = TRUE; + hDlg = CreateWindow("MESSAGEBOX", title, + WS_POPUP | WS_DLGFRAME | WS_VISIBLE, 100, 150, 320, 120, + (HWND)NULL, (HMENU)NULL, wndPtr->hInstance, (LPSTR)&mb); + if (hDlg == 0) return 0; + while(TRUE) { + if (!mb.ActiveFlg) break; + if (!GetMessage(&msg, (HWND)NULL, 0, 0)) break; + TranslateMessage(&msg); + DispatchMessage(&msg); + } + printf( "after MessageBox !\n"); + if (!UnregisterClass("MESSAGEBOX", wndPtr->hInstance)) return 0; + return(mb.wRetVal); +} + + + +LPMSGBOX MsgBoxGetStorageHeader(HWND hwnd) +{ + WND *wndPtr; + LPMSGBOX lpmb; + wndPtr = WIN_FindWndPtr(hwnd); + if (wndPtr == 0) { + printf("Bad Window handle on MessageBox !\n"); + return 0; + } + lpmb = *((LPMSGBOX *)&wndPtr->wExtra[1]); + return lpmb; +} + + + + +LONG SystemMessageBoxProc(HWND hWnd, WORD message, WORD wParam, LONG lParam) +{ + WND *wndPtr; + CREATESTRUCT *createStruct; + PAINTSTRUCT ps; + HDC hDC; + RECT rect; + LPMSGBOX lpmb; + LPMSGBOX lpmbInit; + BITMAP bm; + HBITMAP hBitMap; + HDC hMemDC; + HICON hIcon; + HINSTANCE hInst2; + int x; + switch(message) { + case WM_CREATE: + wndPtr = WIN_FindWndPtr(hWnd); + createStruct = (CREATESTRUCT *)lParam; + lpmbInit = (LPMSGBOX)createStruct->lpCreateParams; + if (lpmbInit == 0) break; + *((LPMSGBOX *)&wndPtr->wExtra[1]) = lpmbInit; + lpmb = MsgBoxGetStorageHeader(hWnd); + GetClientRect(hWnd, &rect); + switch(lpmb->wType & MB_TYPEMASK) { + case MB_OK : + lpmb->hWndYes = CreateWindow("BUTTON", "&Ok", + WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | BS_PUSHBUTTON, + rect.right / 2 - 70, rect.bottom - 25, + 60, 18, hWnd, 1, wndPtr->hInstance, 0L); + break; + case MB_OKCANCEL : + lpmb->hWndYes = CreateWindow("BUTTON", "&Ok", + WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | BS_PUSHBUTTON, + rect.right / 2 - 70, rect.bottom - 25, + 60, 18, hWnd, 1, wndPtr->hInstance, 0L); + lpmb->hWndCancel = CreateWindow("BUTTON", "&Cancel", + WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | BS_PUSHBUTTON, + rect.right / 2 + 10, rect.bottom - 25, + 60, 18, hWnd, 2, wndPtr->hInstance, 0L); + break; + case MB_ABORTRETRYIGNORE : + lpmb->hWndYes = CreateWindow("BUTTON", "&Retry", + WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | BS_PUSHBUTTON, + rect.right / 2 - 70, rect.bottom - 25, + 60, 18, hWnd, 1, wndPtr->hInstance, 0L); + lpmb->hWndNo = CreateWindow("BUTTON", "&Ignore", + WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | BS_PUSHBUTTON, + rect.right / 2 + 10, rect.bottom - 25, + 60, 18, hWnd, 2, wndPtr->hInstance, 0L); + lpmb->hWndCancel = CreateWindow("BUTTON", "&Abort", + WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | BS_PUSHBUTTON, + rect.right / 2 + 80, rect.bottom - 25, + 60, 18, hWnd, 3, wndPtr->hInstance, 0L); + break; + case MB_YESNO : + lpmb->hWndYes = CreateWindow("BUTTON", "&Yes", + WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | BS_PUSHBUTTON, + rect.right / 2 - 70, rect.bottom - 25, + 60, 18, hWnd, 1, wndPtr->hInstance, 0L); + lpmb->hWndNo = CreateWindow("BUTTON", "&No", + WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | BS_PUSHBUTTON, + rect.right / 2 + 10, rect.bottom - 25, + 60, 18, hWnd, 2, wndPtr->hInstance, 0L); + break; + } + switch(lpmb->wType & MB_ICONMASK) { + case MB_ICONEXCLAMATION: + printf("MsgBox LoadIcon Exclamation !\n"); + lpmb->hIcon = LoadIcon((HINSTANCE)NULL, IDI_EXCLAMATION); + break; + case MB_ICONQUESTION: + printf("MsgBox LoadIcon Question !\n"); + lpmb->hIcon = LoadIcon((HINSTANCE)NULL, IDI_QUESTION); + break; + case MB_ICONASTERISK: + printf("MsgBox LoadIcon Asterisk !\n"); + lpmb->hIcon = LoadIcon((HINSTANCE)NULL, IDI_ASTERISK); + break; + case MB_ICONHAND: + printf("MsgBox LoadIcon Hand !\n"); + lpmb->hIcon = LoadIcon((HINSTANCE)NULL, IDI_HAND); + break; + } + break; + case WM_PAINT: + lpmb = MsgBoxGetStorageHeader(hWnd); + GetClientRect(hWnd, &rect); + hDC = BeginPaint(hWnd, &ps); + if (lpmb->hIcon) DrawIcon(hDC, 30, 20, lpmb->hIcon); + TextOut(hDC, rect.right / 2, 15, + lpmb->Title, strlen(lpmb->Title)); + TextOut(hDC, rect.right / 2, 30, + lpmb->Str, strlen(lpmb->Str)); + EndPaint(hWnd, &ps); + break; + case WM_DESTROY: + printf("MessageBox WM_DESTROY !\n"); + ReleaseCapture(); + lpmb = MsgBoxGetStorageHeader(hWnd); + lpmb->ActiveFlg = FALSE; + if (lpmb->hIcon) DestroyIcon(lpmb->hIcon); + if (lpmb->hWndYes) DestroyWindow(lpmb->hWndYes); + if (lpmb->hWndNo) DestroyWindow(lpmb->hWndNo); + if (lpmb->hWndCancel) DestroyWindow(lpmb->hWndCancel); + break; + case WM_COMMAND: + lpmb = MsgBoxGetStorageHeader(hWnd); + switch(wParam) { + case 1: + lpmb->wRetVal = IDOK; + break; + case 2: + wndPtr = WIN_FindWndPtr(hWnd); + hDC = GetDC(hWnd); +/* + for (x = 1; x < 50; x++) { + hBitMap = LoadBitmap(wndPtr->hInstance, MAKEINTRESOURCE(x)); + GetObject(hBitMap, sizeof(BITMAP), (LPSTR)&bm); + hMemDC = CreateCompatibleDC(hDC); + SelectObject(hMemDC, hBitMap); + printf(" bm.bmWidth=%d bm.bmHeight=%d\n", + bm.bmWidth, bm.bmHeight); + BitBlt(hDC, x * 20, 30, bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY); + DeleteDC(hMemDC); + } +*/ + hBitMap = LoadBitmap((HINSTANCE)NULL, "SMILE"); + GetObject(hBitMap, sizeof(BITMAP), (LPSTR)&bm); + printf("bm.bmWidth=%d bm.bmHeight=%d\n", + bm.bmWidth, bm.bmHeight); + hMemDC = CreateCompatibleDC(hDC); + SelectObject(hMemDC, hBitMap); + BitBlt(hDC, 100, 30, bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY); + DeleteDC(hMemDC); + ReleaseDC(hWnd, hDC); + lpmb->wRetVal = IDCANCEL; +/* + SetWindowPos(lpmb->hWndNo, (HWND)NULL, 20, 20, 0, 0, + SWP_NOSIZE | SWP_NOZORDER); +*/ + return 0; + break; + case 3: + hDC = GetDC(hWnd); + hInst2 = LoadImage("ev3lite.exe", NULL); + hIcon = LoadIcon(hInst2, "EV3LITE"); + DrawIcon(hDC, 20, 20, hIcon); + DestroyIcon(hIcon); + hInst2 = LoadImage("sysres.dll", NULL); + hIcon = LoadIcon(hInst2, "WINEICON"); + DrawIcon(hDC, 60, 20, hIcon); + DestroyIcon(hIcon); + hIcon = LoadIcon((HINSTANCE)NULL, IDI_EXCLAMATION); + DrawIcon(hDC, 1000, 20, hIcon); + DestroyIcon(hIcon); + ReleaseDC(hWnd, hDC); + lpmb->wRetVal = IDIGNORE; + return(0); + break; + default: + return(0); + } + CloseWindow(hWnd); + break; + default: + return DefWindowProc(hWnd, message, wParam, lParam ); + } +return(0); +} + + + diff --git a/misc/xt.c b/misc/xt.c index 928d6dd38ab..8d386ae87d4 100644 --- a/misc/xt.c +++ b/misc/xt.c @@ -53,11 +53,6 @@ void main(int argc, char **argv) */ -int MessageBox( HWND hwnd, LPSTR str, LPSTR title, WORD type ) -{ - printf( "MessageBox: '%s'\n", str ); -} - void MessageBeep( WORD i ) { XBell(XT_display, 100); @@ -102,12 +97,6 @@ void AdjustWindowRect( LPRECT rect, DWORD style, BOOL menu ) } -BOOL IsIconic( HWND hwnd ) -{ - printf( "IsIconic: returning FALSE\n" ); - return FALSE; -} - HMENU CreateMenu() { return 0; } BOOL AppendMenu( HMENU hmenu, WORD flags, WORD id, LPSTR text ) { return TRUE;} diff --git a/objects/color.c b/objects/color.c index 0215d47c9ac..19065ea81d8 100644 --- a/objects/color.c +++ b/objects/color.c @@ -19,7 +19,7 @@ extern Screen * XT_screen; * We try to use a private color map if possible, because Windows programs * assume that palette(0) == Black and palette(max-1) == White. */ -#define USE_PRIVATE_MAP +#undef USE_PRIVATE_MAP Colormap COLOR_WinColormap = 0; diff --git a/objects/dib.c b/objects/dib.c index 839f0b57b50..735e449e001 100644 --- a/objects/dib.c +++ b/objects/dib.c @@ -6,9 +6,11 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1993"; +#include #include #include "gdi.h" +#include "icon.h" extern XImage * BITMAP_BmpToImage( BITMAP *, void * ); @@ -201,3 +203,45 @@ HBITMAP CreateDIBitmap( HDC hdc, BITMAPINFOHEADER * header, DWORD init, bits, data, coloruse ); return handle; } + +/*********************************************************************** + * DrawIcon (USER.84) + */ +BOOL DrawIcon(HDC hDC, short x, short y, HICON hIcon) +{ + ICONALLOC *lpico; + BITMAP bm; + HBITMAP hBitTemp; + HDC hMemDC; + HDC hMemDC2; +#ifdef DEBUG_ICON + printf("DrawIcon(%04X, %d, %d, %04X) \n", hDC, x, y, hIcon); +#endif + if (hIcon == (HICON)NULL) return FALSE; + lpico = (ICONALLOC *)GlobalLock(hIcon); + GetObject(lpico->hBitmap, sizeof(BITMAP), (LPSTR)&bm); +#ifdef DEBUG_ICON + printf("DrawIcon / x=%d y=%d\n", x, y); + printf("DrawIcon / icon Width=%d\n", (int)lpico->descriptor.Width); + printf("DrawIcon / icon Height=%d\n", (int)lpico->descriptor.Height); + printf("DrawIcon / icon ColorCount=%d\n", (int)lpico->descriptor.ColorCount); + printf("DrawIcon / icon icoDIBSize=%lX\n", (DWORD)lpico->descriptor.icoDIBSize); + printf("DrawIcon / icon icoDIBOffset=%lX\n", (DWORD)lpico->descriptor.icoDIBOffset); + printf("DrawIcon / bitmap bmWidth=%d bmHeight=%d\n", bm.bmWidth, bm.bmHeight); +#endif + hMemDC = CreateCompatibleDC(hDC); +#ifdef DEBUG_ICON + SelectObject(hMemDC, lpico->hBitmap); + BitBlt(hDC, x, y, bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY); + SelectObject(hMemDC, lpico->hBitMask); + BitBlt(hDC, x, y + bm.bmHeight, bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY); +#else + SelectObject(hMemDC, lpico->hBitMask); + BitBlt(hDC, x, y, bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCAND); + SelectObject(hMemDC, lpico->hBitmap); + BitBlt(hDC, x, y, bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCPAINT); +#endif + DeleteDC(hMemDC); + return TRUE; +} + diff --git a/sysres.dll b/sysres.dll new file mode 100755 index 0000000000000000000000000000000000000000..44a53abd38e2eccc301fd1aa8481aa829a9fce04 GIT binary patch literal 66048 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 O96bhI>Ca!}_WuV;YmdqR literal 0 HcmV?d00001 diff --git a/test/btnlook.c b/test/btnlook.c deleted file mode 100755 index 28f56083dd3..00000000000 --- a/test/btnlook.c +++ /dev/null @@ -1,146 +0,0 @@ -/*------------------------------------------ - BTNLOOK.C -- Button Look Program - ------------------------------------------*/ - -#include -#include - -struct -{ - long style; - char *text; -} -button[] = -{ - BS_PUSHBUTTON, "PUSHBUTTON", - BS_DEFPUSHBUTTON, "DEFPUSHBUTTON", - BS_CHECKBOX, "CHECKBOX", - BS_AUTOCHECKBOX, "AUTOCHECKBOX", - BS_RADIOBUTTON, "RADIOBUTTON", - BS_3STATE, "3STATE", - BS_AUTO3STATE, "AUTO3STATE", - BS_GROUPBOX, "GROUPBOX", - BS_USERBUTTON, "USERBUTTON", - BS_AUTORADIOBUTTON, "AUTORADIOBUTTON" -}; - -#define NUM (sizeof button / sizeof button[0]) - -long FAR PASCAL _export WndProc(HWND, WORD, WORD, LONG); - -int PASCAL WinMain(HANDLE hInstance, HANDLE hPrevInstance, - LPSTR lpszCmdParam, int nCmdShow) -{ - static char szAppName[] = "BtnLook"; - HWND hwnd; - MSG msg; - WNDCLASS wndclass; - - if (!hPrevInstance) - { - wndclass.style = CS_HREDRAW | CS_VREDRAW; - wndclass.lpfnWndProc = WndProc; - wndclass.cbClsExtra = 0; - wndclass.cbWndExtra = 0; - wndclass.hInstance = hInstance; - wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION); - wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); - wndclass.hbrBackground = GetStockObject(WHITE_BRUSH); - wndclass.lpszMenuName = NULL; - wndclass.lpszClassName = szAppName; - - RegisterClass(&wndclass); - } - - hwnd = CreateWindow(szAppName, "Button Look", - WS_OVERLAPPEDWINDOW, - CW_USEDEFAULT, CW_USEDEFAULT, - CW_USEDEFAULT, CW_USEDEFAULT, - NULL, NULL, hInstance, NULL); - - ShowWindow(hwnd, nCmdShow); - UpdateWindow(hwnd); - - while (GetMessage(&msg, NULL, 0, 0)) - { - TranslateMessage(&msg); - DispatchMessage(&msg); - } - return msg.wParam; -} - -long FAR PASCAL _export WndProc(HWND hwnd, WORD message, WORD wParam, LONG lParam) -{ - static char szPrm[] = "wParam LOWORD(lParam) HIWORD(lParam)", - szTop[] = "Control ID Window Handle Notification", - szUnd[] = "__________ _____________ ____________", - szFormat[] = " %5u %4X %5u", - szBuffer[50]; - static HWND hwndButton[NUM]; - static RECT rect; - static int cxChar, cyChar; - HDC hdc; - PAINTSTRUCT ps; - int i; - TEXTMETRIC tm; - - switch (message) - { - case WM_CREATE: - hdc = GetDC(hwnd); - SelectObject(hdc, GetStockObject(SYSTEM_FIXED_FONT)); - GetTextMetrics(hdc, &tm); - cxChar = tm.tmAveCharWidth; - cyChar = tm.tmHeight + tm.tmExternalLeading; - ReleaseDC(hwnd, hdc); - - for (i = 0; i < NUM; i++) - hwndButton[i] = CreateWindow("button", button[i].text, - WS_CHILD | WS_VISIBLE | button[i].style, - cxChar, cyChar * (1 + 2 * i), - 20 * cxChar, 7 * cyChar / 4, - hwnd, i, - ((LPCREATESTRUCT) lParam)->hInstance, NULL); - return 0; - - case WM_SIZE: - rect.left = 24 * cxChar; - rect.top = 3 * cyChar; - rect.right = LOWORD(lParam); - rect.bottom = HIWORD(lParam); - return 0; - - case WM_PAINT: - InvalidateRect(hwnd, &rect, TRUE); - - hdc = BeginPaint(hwnd, &ps); - SelectObject(hdc, GetStockObject(SYSTEM_FIXED_FONT)); - SetBkMode(hdc, TRANSPARENT); - TextOut(hdc, 24 * cxChar, 1 * cyChar, szPrm, sizeof szPrm - 1); - TextOut(hdc, 24 * cxChar, 2 * cyChar, szTop, sizeof szTop - 1); - TextOut(hdc, 24 * cxChar, 2 * cyChar, szUnd, sizeof szUnd - 1); - - EndPaint(hwnd, &ps); - return 0; - - case WM_COMMAND: -/* ScrollWindow(hwnd, 0, -cyChar, &rect, &rect); */ - hdc = GetDC(hwnd); - SelectObject(hdc, GetStockObject(SYSTEM_FIXED_FONT)); - - TextOut(hdc, 24 * cxChar, cyChar * 5, /* (rect.bottom / cyChar - 1), */ - szBuffer, sprintf(szBuffer, szFormat, wParam, - LOWORD(lParam), HIWORD(lParam))); - - ReleaseDC(hwnd, hdc); - ValidateRect(hwnd, NULL); - return 0; - - case WM_DESTROY: - PostQuitMessage(0); - return 0; - } - - return DefWindowProc(hwnd, message, wParam, lParam); -} - diff --git a/test/btnlook.exe b/test/btnlook.exe index 134c8a14d1b7184dc568d67364ad0eff694f8987..d952b617895e231810578630a4c7d25b0fc167b4 100755 GIT binary patch delta 2534 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 -#include "STDIO.h" -#include "STDLIB.h" -#include "STDARG.h" -#include "STRING.H" - -#include "widget.H" -#include "widget.VAR" -#include "widget.P" - -#define NoREF(a) a=a - -WORD wPlayDiskID; - -HWND hWndBut; -HWND hWndChk; -HWND hWndRadio; -HWND hWndLBox; -HWND hWndScrol; -HWND hWndScro2; -HWND hWndStat; -HWND hWndEdit; -HWND hWndCBox; -int x, y; - -/**********************************************************************/ - - -int PASCAL WinMain(HANDLE hInstance,HANDLE hPrevInstance, - LPSTR lpszCmdLine,int nCmdShow) -{ -WNDCLASS wndClass; -MSG msg; -HWND hWnd; -HDC hDC; -char C[40]; -int X; -NoREF(lpszCmdLine); -if ( !hPrevInstance ) - { - wndClass.style = CS_HREDRAW | CS_VREDRAW ; - wndClass.lpfnWndProc = (WNDPROC)WndProc; - wndClass.cbClsExtra = 0; - wndClass.cbWndExtra = 0; - wndClass.hInstance = hInstance; - wndClass.hIcon = LoadIcon(hInstance,(LPSTR)"ICON_1"); - wndClass.hCursor = LoadCursor(NULL, IDC_ARROW ); - wndClass.hbrBackground = GetStockObject(WHITE_BRUSH ); - wndClass.lpszMenuName = szAppName; - wndClass.lpszClassName = szAppName; - if (!RegisterClass(&wndClass)) - return FALSE; - } -hWnd = CreateWindow(szAppName, "widget test program", - WS_POPUP | WS_BORDER | WS_VISIBLE, 50, 50, - 400, 400, NULL, NULL, hInstance, NULL); -hWndMain = hWnd; -hInst = hInstance; -hDCMain = GetDC(hWndMain); - -InitWidgets(); - -while (GetMessage(&msg, NULL, 0, 0)) - { - TranslateMessage(&msg ); - DispatchMessage(&msg ); - } -ReleaseDC(hWndMain, hDC); -return(0); -} - - -void InitWidgets() -{ -hWndBut = CreateWindow("BUTTON", "Button #1", - WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE | BS_PUSHBUTTON, - 230, 40, 80, 30, hWndMain, 1001, hInst, NULL); -hWndScrol = CreateWindow("SCROLLBAR", "Scroll #1", - WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE | SBS_VERT, - 200, 140, 15, 100, hWndMain, 1004, hInst, NULL); -hWndScro2 = CreateWindow("SCROLLBAR", "Scroll #2", - WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE | SBS_HORZ, - 50, 140, 100, 15, hWndMain, 1005, hInst, NULL); -x = y = 25; -SetVertScroll(NULL, hWndScrol, 25, 0, 50); -SetScrollRange(hWndScro2, SB_CTL, 0, 50, TRUE); -SetScrollPos(hWndScro2, SB_CTL, 25, TRUE); -hWndLBox = CreateWindow("LISTBOX", "", - WS_CHILD | WS_VISIBLE | WS_BORDER | WS_VSCROLL | LBS_NOTIFY, - 230, 160, 150, 100, hWndMain, 1004, hInst, NULL); -SendMessage(hWndLBox, LB_ADDSTRING, 0, (LPARAM)"ListBox item #1"); -} - - - -long FAR PASCAL WndProc(HWND hWnd, unsigned Message, WORD wParam, LONG lParam) -{ -int ShiftState; -char C[80]; -ShiftState = GetKeyState(VK_SHIFT); -switch(Message) - { - case WM_COMMAND: - if (LOWORD(lParam) != 0) - { - sprintf(C, "MAIN WM_COMMAND wParam=%X lParam=%lX !!!", wParam, lParam); - TextOut(hDCMain, 25, 280, C, strlen(C)); - } - break; - - case WM_KEYDOWN: - sprintf(C, "WM_KEYDOWN !!!"); - TextOut(hDCMain, 25, 40, C, strlen(C)); - KeyDown(hWnd, Message, wParam); - break; - - case WM_CHAR: - sprintf(C, "WM_CHAR !!!"); - TextOut(hDCMain, 25, 50, C, strlen(C)); - break; - - case WM_LBUTTONDOWN: - break; - - case WM_LBUTTONUP: - break; - - case WM_RBUTTONDOWN: - break; - - case WM_RBUTTONUP: - break; - - case WM_MOUSEMOVE: - break; - - case WM_VSCROLL: - sprintf(C, "WM_VSCROLL %X %X %lX !!!", Message, wParam, lParam); - TextOut(hDCMain, 25, 370, C, strlen(C)); - Do_Dlg_VertScroll(hWnd, wParam, lParam, &y, 0, 50); - break; - - case WM_HSCROLL: - sprintf(C, "WM_HSCROLL %X %X %lX !!!", Message, wParam, lParam); - TextOut(hDCMain, 25, 370, C, strlen(C)); - Do_Dlg_HorzScroll(hWnd, wParam, lParam, &x, 0, 50); - break; - - case WM_PAINT: - DoPaint(hWnd); - break; - - case WM_DESTROY: - PostQuitMessage(0); - break; - - default: - return DefWindowProc(hWnd, Message, wParam, lParam); - } -return(0); -} - - - -BOOL KeyDown(HWND hWnd, unsigned Message, WORD wParam) -{ -WORD wRet; -UINT uRet; -DWORD dwRet; -char C[128]; -char C2[64]; -NoREF(hWnd); -NoREF(Message); -sprintf(C, "KeyDown %x !!!", wParam); -TextOut(hDCMain, 25, 100, C, strlen(C)); -switch (wParam) - { - case VK_HOME: /* 'HOME' KEY */ - break; - case VK_LEFT: /* 'LEFT' CURSOR KEY */ - break; - case VK_RIGHT: /* 'RIGHT' CURSOR KEY */ - break; - case VK_UP: /* 'UP' CURSOR KEY */ - break; - case VK_DOWN: /* 'DOWN' CURSOR KEY */ - break; - case VK_PRIOR: /* 'PGUP' CURSOR KEY */ - break; - case VK_NEXT: /* 'PGDN' CURSOR KEY */ - break; - case '1': - break; - case '2': - break; - case '3': - break; - case '4': - break; - case '5': - break; - case 'A': - break; - case 'B': - break; - case 'C': - break; - case 'D': - break; - case 'E': - break; - case 'F': - break; - case 'G': - break; - case 'H': - WinHelp(hWndMain, "toto.hlp", HELP_INDEX, 0L); - break; - case 'J': - WinExec("/D:/wine/widget.exe arg1 arg2 arg3 arg4 arg5 arg6", SW_NORMAL); - break; - case 'K': - break; - case 'Q': - hWndStat = CreateWindow("STATIC", "Static #1", - WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE | SS_SIMPLE, - 230, 20, 80, 20, hWndMain, 1000, hInst, NULL); - break; - case 'W': - hWndChk = CreateWindow("BUTTON", "CheckBox #1", - WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE | BS_CHECKBOX, - 230, 90, 120, 20, hWndMain, 1002, hInst, NULL); - break; - case 'R': - hWndRadio = CreateWindow("BUTTON", "RadioBut #1", - WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE | BS_RADIOBUTTON, - 230, 120, 120, 20, hWndMain, 1003, hInst, NULL); - SendMessage(hWndRadio, BM_SETCHECK, 0, 0L); - break; - case 'T': - SendMessage(hWndLBox, LB_ADDSTRING, 0, (LPARAM)"ListBox Single item"); - break; - case 'Y': - SendMessage(hWndLBox, LB_ADDSTRING, 0, (LPARAM)"ListBox item #2"); - SendMessage(hWndLBox, LB_ADDSTRING, 0, (LPARAM)"ListBox item #3"); - SendMessage(hWndLBox, LB_ADDSTRING, 0, (LPARAM)"ListBox item #4"); - SendMessage(hWndLBox, LB_ADDSTRING, 0, (LPARAM)"ListBox item #5"); - SendMessage(hWndLBox, LB_ADDSTRING, 0, (LPARAM)"ListBox item #6"); - SendMessage(hWndLBox, LB_SETCURSEL, 3, 0L); - SendMessage(hWndLBox, LB_INSERTSTRING, 5, (LPARAM)"Item between 5 & 6"); - wRet = SendMessage(hWndLBox, LB_FINDSTRING, -1, (LPARAM)"Item between 5 & 6"); - sprintf(C, "LB_FINDSTRING returned #%u ", wRet); - TextOut(hDCMain, 25, 300, C, strlen(C)); - wRet = SendMessage(hWndLBox, LB_GETCURSEL, 0, 0L); - sprintf(C, "LB_GETCURSEL returned #%u ", wRet); - TextOut(hDCMain, 25, 320, C, strlen(C)); - break; - case 'U': - SendMessage(hWndLBox, LB_DELETESTRING, 3, 0L); - break; - case 'I': - SendMessage(hWndLBox, LB_RESETCONTENT, 0, 0L); - break; - case 'O': - C2[0] = '\0'; - SendMessage(hWndLBox, LB_GETTEXT, 2, (DWORD)C2); - sprintf(C, "LB_GETTEXT returned '%s' ", C2); - TextOut(hDCMain, 25, 320, C, strlen(C)); - break; - case 'P': - SendMessage(hWndLBox, LB_DIR, 0, (DWORD)"*.*"); - break; - case 'Z': - ShowWindow(hWndScrol, SW_HIDE); - break; - case 'X': - ShowWindow(hWndScrol, SW_SHOW); - break; - case 'V': - hWndCBox = CreateWindow("COMBOBOX", "Combo #1", - WS_CHILD | WS_VISIBLE | WS_BORDER | CBS_DROPDOWNLIST, - 230, 270, 150, 100, hWndMain, 1006, hInst, NULL); - SendMessage(hWndCBox, CB_ADDSTRING, 0, (LPARAM)"ComboBox item #1"); - SendMessage(hWndCBox, CB_ADDSTRING, 0, (LPARAM)"ComboBox item #2"); - break; - case 'N': - hWndCBox = CreateWindow("COMBOBOX", "Combo #2", - WS_CHILD | WS_VISIBLE | WS_BORDER | CBS_DROPDOWN, - 30, 270, 150, 100, hWndMain, 1007, hInst, NULL); - SendMessage(hWndCBox, CB_ADDSTRING, 0, (LPARAM)"ComboBox item #1"); - SendMessage(hWndCBox, CB_ADDSTRING, 0, (LPARAM)"ComboBox item #2"); - break; - - case VK_F10: /* 'F10' FUNCTION KEY */ - break; - case VK_F11: /* 'F11' FUNCTION KEY */ - break; - } -return(TRUE); -} - - - -void DoPaint(HWND hWnd) -{ -HDC hDC; -RECT rect; -PAINTSTRUCT ps; -char C[80]; -GetClientRect(hWnd, &rect); -hDC = BeginPaint(hWnd, &ps); -FillRect(hDC, &rect, GetStockObject(GRAY_BRUSH)); -InflateRect(&rect, -3, -3); -FrameRect(hDC, &rect, GetStockObject(BLACK_BRUSH)); -InflateRect(&rect, -10, -10); -FillRect(hDC, &rect, GetStockObject(WHITE_BRUSH)); -sprintf(C, "Wine Testing !!!"); -TextOut(hDC, 25, 25, C, strlen(C)); -ReleaseDC(hWnd,hDC); -EndPaint(hWnd,&ps); -} - - -/**********************************************************************/ - - -void SetVertScroll(int hDlg, int hWndSCROLL, int VAL, int MIN, int MAX) -{ -char C[12]; -SetScrollRange(hWndSCROLL, SB_CTL, -MAX, -MIN, FALSE); -SetScrollPos(hWndSCROLL, SB_CTL, -VAL, TRUE); -itoa(VAL, C, 10); -//SetDlgItemText(hDlg, (IDDTXT1 + GetDlgCtrlID(hWndSCROLL) - IDDSCROLL1), C); -} - - - -void SetHorzScroll(int hDlg, int hWndSCROLL, int VAL, int MIN, int MAX) -{ -char C[12]; -SetScrollRange(hWndSCROLL, SB_CTL, MAX, MIN, FALSE); -SetScrollPos(hWndSCROLL, SB_CTL, VAL, TRUE); -itoa(VAL, C, 10); -//SetDlgItemText(hDlg, (IDDTXT1 + GetDlgCtrlID(hWndSCROLL) - IDDSCROLL1), C); -} - - - -void Do_Dlg_VertScroll(HWND hDlg, WORD wParam, DWORD lParam, int *V, int MIN, int MAX) -{ -char C[12]; -int VAL; -int VAL2; -int Step = 100; -if (MAX < 1000) Step = 10; -if (MAX < 100) Step = MAX / 10; -VAL = *(V); -VAL2 = VAL; -switch (wParam) - { - case SB_LINEUP: - VAL++; - break; - case SB_LINEDOWN: - VAL--; - break; - case SB_PAGEUP: - VAL += Step; - break; - case SB_PAGEDOWN: - VAL -= Step; - break; - case SB_THUMBTRACK: - case SB_THUMBPOSITION: - VAL = -(LOWORD(lParam)); - break; - } -if (VAL > MAX) VAL = MAX; -if (VAL < MIN) VAL = MIN; -if (VAL != VAL2) - { - SetScrollPos(HIWORD(lParam), SB_CTL, -VAL, TRUE); - ltoa(VAL, C, 10); -// SetDlgItemText(hDlg, (IDDTXT1 + GetDlgCtrlID(HIWORD(lParam)) - IDDSCROLL1), C); - } -*(V) = VAL; -} - - -void Do_Dlg_HorzScroll(HWND hDlg, WORD wParam, DWORD lParam, int *V, int MIN, int MAX) -{ -char C[12]; -int VAL; -int VAL2; -int Step = 100; -if (MAX < 1000) Step = 10; -if (MAX < 100) Step = MAX / 10; -VAL = *(V); -VAL2 = VAL; -switch (wParam) - { - case SB_LINEUP: - VAL--; - break; - case SB_LINEDOWN: - VAL++; - break; - case SB_PAGEUP: - VAL -= Step; - break; - case SB_PAGEDOWN: - VAL += Step; - break; - case SB_THUMBTRACK: - case SB_THUMBPOSITION: - VAL = (LOWORD(lParam)); - break; - } -if (VAL > MAX) VAL = MAX; -if (VAL < MIN) VAL = MIN; -if (VAL != VAL2) - { - SetScrollPos(HIWORD(lParam), SB_CTL, VAL, TRUE); - ltoa(VAL, C, 10); -// SetDlgItemText(hDlg, (IDDTXT1 + GetDlgCtrlID(HIWORD(lParam)) - IDDSCROLL1), C); - } -*(V) = VAL; -} - - -/**********************************************************************/ - - - \ No newline at end of file diff --git a/test/martin_ship2/widget.def b/test/martin_ship2/widget.def deleted file mode 100755 index 9a5296b90fc..00000000000 --- a/test/martin_ship2/widget.def +++ /dev/null @@ -1,23 +0,0 @@ -;********************************************************************** -;* Copyright (c) 1991 by TRG ELECTRONIK * -;********************************************************************** - - -NAME WineTest -DESCRIPTION 'Drink Inventry Controler' -STUB 'WINSTUB.EXE' -CODE PRELOAD MOVEABLE DISCARDABLE -DATA PRELOAD MOVEABLE MULTIPLE -EXETYPE WINDOWS -SEGMENTS - DRINK_TEXT PRELOAD MOVEABLE DISCARDABLE - -HEAPSIZE 20000 -STACKSIZE 8192 - -EXPORTS WndProc @1 - About_Proc @3 - - - - \ No newline at end of file diff --git a/test/martin_ship2/widget.h b/test/martin_ship2/widget.h deleted file mode 100755 index a0d9f01cc97..00000000000 --- a/test/martin_ship2/widget.h +++ /dev/null @@ -1,250 +0,0 @@ -/********************************************************************** -* Copyright (c) 1991 by TRG ELECTRONIK * -**********************************************************************/ - -#define szAppName "widgetClass" - -#define IDNULL -1 - -#define IDSCLOSE 20 -#define IDSOKCLOSE 21 -#define IDSSAVE 22 -#define IDSOKSAVE 23 -#define IDINFO 24 -#define IDSAVE 25 -#define IDDELETE 26 -#define IDNEW 27 - - -#define IDBUSER 30 -#define IDBUSER1 31 -#define IDBUSER2 32 -#define IDBUSER3 33 -#define IDBUSER4 34 -#define IDBUSER5 35 -#define IDBUSER6 36 -#define IDBUSER7 37 -#define IDBUSER8 38 -#define IDBUSER9 39 - -#define IDDJOBNAME 50 -#define IDDPRINTER 51 - -#define IDSETUP 60 - - -#define IDI_MKSICON 99 - -/******************************************/ - -#define MID_NEW 100 -#define MID_OPEN 101 -#define MID_SAVE 102 -#define MID_SAVEAS 103 -#define MID_PRINT 104 -#define MID_PRSETUP 105 -#define MID_STATUS 106 -#define MID_QUIT 107 - -#define MID_CUT 121 -#define MID_COPY 122 -#define MID_PASTE 123 -#define MID_CLEAR 124 -#define MID_COPYTO 125 -#define MID_PASTEFROM 126 - -#define MID_NEWPROD 140 -#define MID_NEWBEER 141 -#define MID_USERCFG 142 - -#define MID_POREGIE 151 -#define MID_POBIERE 152 -#define MID_DAYSTOCK 153 -#define MID_RESERVE 154 -#define MID_COCKSALE 155 -#define MID_DRYSALE 156 -#define MID_COMPILE 157 -#define MID_RECETTES 158 -#define MID_HD 159 -#define MID_TESTPRN 160 -#define MID_INFODSK 161 -#define MID_SHARP 162 -#define MID_PASSWORD 163 - -/******************************************/ - -#define IDDTEXT 200 -#define IDDTXT1 201 -#define IDDTXT2 202 -#define IDDTXT3 203 -#define IDDTXT4 204 -#define IDDTXT5 205 -#define IDDTXT6 206 -#define IDDTXT7 207 -#define IDDTXT8 208 -#define IDDTXT9 209 -#define IDDTXT10 210 -#define IDDTXT11 211 -#define IDDTXT12 212 -#define IDDTXT13 213 -#define IDDTXT14 214 -#define IDDTXT15 215 -#define IDDTXT16 216 -#define IDDTXT17 217 -#define IDDTXT18 218 -#define IDDTXT19 219 - -#define IDDBUTTON1 220 -#define IDDBUTTON2 221 -#define IDDBUTTON3 222 -#define IDDBUTTON4 223 -#define IDDBUTTON5 224 -#define IDDBUTTON6 225 -#define IDDBUTTON7 226 -#define IDDBUTTON8 227 -#define IDDBUTTON9 228 -#define IDDBUTTON10 229 - -#define IDDCHKBOX1 240 -#define IDDCHKBOX2 241 -#define IDDCHKBOX3 242 -#define IDDCHKBOX4 243 -#define IDDCHKBOX5 244 -#define IDDCHKBOX6 245 -#define IDDCHKBOX7 246 -#define IDDCHKBOX8 247 -#define IDDCHKBOX9 248 -#define IDDCHKBOX10 249 - -#define IDDSCROLL1 250 -#define IDDSCROLL2 251 -#define IDDSCROLL3 252 -#define IDDSCROLL4 253 -#define IDDSCROLL5 254 -#define IDDSCROLL6 255 -#define IDDSCROLL7 256 -#define IDDSCROLL8 257 - -#define IDDSTR1 2000 -#define IDDSTR2 2001 -#define IDDSTR3 2002 -#define IDDSTR4 2003 -#define IDDSTR5 2004 -#define IDDSTR6 2005 -#define IDDSTR7 2006 -#define IDDSTR8 2007 -#define IDDSTR9 2008 -#define IDDSTR10 2009 -#define IDDSTR11 2010 -#define IDDSTR12 2011 -#define IDDSTR13 2012 -#define IDDSTR14 2013 -#define IDDSTR15 2014 -#define IDDSTR16 2015 -#define IDDSTR17 2016 -#define IDDSTR18 2017 -#define IDDSTR19 2018 -#define IDDSTR20 2019 -#define IDDSTR21 2020 -#define IDDSTR22 2021 -#define IDDSTR23 2022 -#define IDDSTR24 2023 -#define IDDSTR25 2024 -#define IDDSTR26 2025 -#define IDDSTR27 2026 -#define IDDSTR28 2027 -#define IDDSTR29 2028 -#define IDDSTR30 2029 -#define IDDSTR31 2030 -#define IDDSTR32 2031 -#define IDDSTR33 2032 -#define IDDSTR34 2033 -#define IDDSTR35 2034 -#define IDDSTR36 2035 -#define IDDSTR37 2036 -#define IDDSTR38 2037 -#define IDDSTR39 2038 -#define IDDSTR40 2039 -#define IDDSTR41 2040 -#define IDDSTR42 2041 -#define IDDSTR43 2042 -#define IDDSTR44 2043 -#define IDDSTR45 2044 -#define IDDSTR46 2045 -#define IDDSTR47 2046 -#define IDDSTR48 2047 -#define IDDSTR49 2048 -#define IDDSTR50 2049 -#define IDDSTR51 2050 -#define IDDSTR52 2051 -#define IDDSTR53 2052 -#define IDDSTR54 2053 -#define IDDSTR55 2054 -#define IDDSTR56 2055 -#define IDDSTR57 2056 -#define IDDSTR58 2057 -#define IDDSTR59 2058 -#define IDDSTR60 2059 -#define IDDSTR61 2060 -#define IDDSTR62 2061 -#define IDDSTR63 2062 -#define IDDSTR64 2063 -#define IDDSTR65 2064 -#define IDDSTR66 2065 -#define IDDSTR67 2066 -#define IDDSTR68 2067 -#define IDDSTR69 2068 -#define IDDSTR70 2069 - - -/******************************************/ - -#define IDDDEFAULTS 1001 -#define IDDCHECKBOX 1002 -#define IDDNULL 1003 -#define IDDRBLEFT 1004 -#define IDDRBRIGHT 1005 -#define IDDRBCENTER 1006 -#define IDDLISTBOX 1007 -#define IDDSBH 1008 -#define IDDSBV 1009 - -/******************************************/ - -#define ABOUT_Dlg 2001 -#define NEW_Dlg 2002 -#define OPEN_Dlg 2003 -#define SAVE_Dlg 2004 -#define SAVEAS_Dlg 2005 -#define PRINT_Dlg 2006 -#define ABORT_Dlg 2007 -#define PRSETUP_Dlg 2008 -#define QUIT_Dlg 2009 - -#define GETOBJ_Dlg 2020 -#define NEWPROD_Dlg 2021 -#define NEWBEER_Dlg 2022 -#define USERCFG_Dlg 2023 -#define POREGIE_Dlg 2024 -#define POBIERE_Dlg 2025 -#define PASSWORD_Dlg 2026 -#define TVQ_Dlg 2027 - -#define LTEXTOK_Dlg 2070 - - -/******************************************/ - -#define RED 0x000000FF -#define GREEN 0x0000FF00 -#define BLUE 0x00FF0000 -#define CYAN 0x00FFFF00 -#define MAGENTA 0x00FF00FF -#define BLACK 0x00000000 -#define WHITE 0x00FFFFFF -#define GRAY 0x00808080 -#define LTGRAY 0x00C0C0C0 -#define DKGRAY 0x00404040 - - - \ No newline at end of file diff --git a/test/martin_ship2/widget.ic2 b/test/martin_ship2/widget.ic2 deleted file mode 100755 index 3e0e0d5743524e8b9bac63fa3dee6048d53d3900..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1094 zcmeIwu?~VT5C-6@n6Q|1bH#+k$uK(dNIrlO41=SuR3m}c!0-asje+=kEp_7oNc5WP z2X{j+O^KAOJYUg)Hk7T2wnVg-%q2@n*Y_d4xd1R%{?~r!2ILJaI&_#$WAI;J?-)!Z z6{o_87HsHEPIRNwV(2EhI~DHV^jx%wW#!bCqaJ8u%lc)}MAjnM@&k>sd}D=X*K<5X mXfkossIzoTJL)NIz<#@kn-Fw3+j)U|$&=AUA<&R>EZvuvud}uvt8$NO TK6Jar+HKu&`H}Z^)?fKAq+WB@ diff --git a/test/martin_ship2/widget.ico b/test/martin_ship2/widget.ico deleted file mode 100755 index 824d52d71151627636c197daf5c923a08a371f0a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 766 zcmd^7OG?B*5PdNY?h;q-Bw4x?npwy!CPxs4oWrF{8(eq-7jptn;40wf1YSTeOF=O1 zW*{-o*PYIcg5UwHN>%lH^{SGF0FgY;_u=ey2RKkYQsjz45n)#uu>%XL13yo5pTDr;SKdrCnE;LB*6HIIy#6T7-2Fg!-V8sKMwc>;sUNUkvP`^ z)-k)R%UZH&+otIbpEK5%WPkrh%*l01e(cfh;6p@O|65)3z`O&pHIS}=^LJqOxN0Kt RS>N|pd}&gC@`-2F%@?=Njhg@f diff --git a/test/martin_ship2/widget.rc b/test/martin_ship2/widget.rc deleted file mode 100755 index 5a86c23dba8..00000000000 --- a/test/martin_ship2/widget.rc +++ /dev/null @@ -1,78 +0,0 @@ -/********************************************************************** - * Copyright (c) 1991 by TRG ELECTRONIK * - * * - * widget.RC * - * widget RESSOURCES * - * * - **********************************************************************/ - -#include <\BC\INCLUDE\WINDOWS.H> -#include "widget.H" - -#define TABGRP WS_TABSTOP | WS_GROUP -#define LBSTYLES WS_VSCROLL | WS_BORDER | WS_VISIBLE | LBS_SORT | TABGRP -#define HSCROLL WS_VISIBLE | SBS_HORZ | SBS_TOPALIGN | TABGRP -#define VSCROLL WS_VISIBLE | SBS_VERT | SBS_LEFTALIGN | TABGRP -#define BLACKRECT SS_BLACKRECT | WS_VISIBLE | WS_GROUP -#define WHITEFRAME SS_WHITEFRAME | WS_VISIBLE | WS_GROUP - - -ICON_1 ICON widget.ICO -ICON_2 ICON widget.IC2 -ICON_3 ICON widget.IC3 - -MENU_1 MENU -BEGIN - POPUP "&File" - BEGIN - MENUITEM "&New", MID_NEW - MENUITEM "&Open", MID_OPEN - MENUITEM "&Save", MID_SAVE - MENUITEM "Save &As", MID_SAVEAS - MENUITEM SEPARATOR - MENUITEM "&Quit!", MID_QUIT - END -END - - - - -ABOUT_Dlg DIALOG 100, 100, 154, 75 -STYLE WS_POPUP | WS_DLGFRAME -BEGIN - ICON "widget" -1, 9, 23, 0, 0 - ICON "DKICON2" -1, 30, 23, 0, 0 - ICON "DKICON3" -1, 50, 23, 0, 0 - CTEXT "About widget Inventory Controler" -1, 0, 14,154, 8 - CTEXT "Version 0.50" -1, 30, 34, 94, 8 - CTEXT "Copyright © 1991, TRG Electronik" -1, 0, 47,154, 9 - DEFPUSHBUTTON "Ok" IDOK, 61, 59, 32, 14, WS_GROUP -END - - -LTEXTOK_Dlg DIALOG 100, 100, 300, 120 -STYLE WS_POPUP | WS_DLGFRAME -BEGIN - LTEXT "", IDDTXT1, 20, 15,118, 12 - LTEXT "", IDDTXT2, 20, 30,118, 25 - LTEXT "", IDDTXT3, 20, 45,118, 35 - LTEXT "", IDDTXT3, 20, 60,118, 35 - DEFPUSHBUTTON "OK", IDOK, 150, 85, 40, 14, TABGRP -END - - -STRINGTABLE -BEGIN -IDDSTR1, "Wine Test Program" -IDDSTR2, "" -IDDSTR3, "" -IDDSTR4, "" -IDDSTR5, "" -IDDSTR6, "" -IDDSTR7, "" -IDDSTR8, "" -IDDSTR9, "" -IDDSTR10, "" -END - - \ No newline at end of file diff --git a/test/martin_ship4/widget.c b/test/martin_ship4/widget.c deleted file mode 100755 index 4d2dfcf4eff..00000000000 --- a/test/martin_ship4/widget.c +++ /dev/null @@ -1,649 +0,0 @@ -/********************************************************************** - * Copyright (c) 1991 by TRG ELECTRONIK * - * * - * widget.C * - * widget Inventory Controler PART # 1 * - * * - **********************************************************************/ - -#include -#include "STDIO.h" -#include "STDLIB.h" -#include "STDARG.h" -#include "STRING.H" - -#include "widget.H" -#include "widget.VAR" -#include "widget.P" - -#define NoREF(a) a=a - -HWND hWndBut; -HWND hWndChk; -HWND hWndRadio; -HWND hWndLBox; -HWND hWndLBox2; -HWND hWndLBox3; -HWND hWndLBox4; -HWND hWndScrol; -HWND hWndScro2; -HWND hWndScro3; -HWND hWndStat; -HWND hWndEdit; -HWND hWndCBox; -int x, y; - -HBRUSH hREDBrush; -HBRUSH hGREENBrush; -HBRUSH hBLUEBrush; -HBRUSH hGRAYBrush; -HBITMAP hBitMap; -HBITMAP hBitMap2; -HBITMAP hBitMap3; -BITMAP BitMap; - -/**********************************************************************/ - - -int PASCAL WinMain(HANDLE hInstance,HANDLE hPrevInstance, - LPSTR lpszCmdLine,int nCmdShow) -{ -WNDCLASS wndClass; -MSG msg; -HWND hWnd; -HDC hDC; -char C[40]; -int X; -NoREF(lpszCmdLine); -if ( !hPrevInstance ) - { - wndClass.style = CS_HREDRAW | CS_VREDRAW ; - wndClass.lpfnWndProc = (WNDPROC)WndProc; - wndClass.cbClsExtra = 0; - wndClass.cbWndExtra = 0; - wndClass.hInstance = hInstance; - wndClass.hIcon = LoadIcon(hInstance,(LPSTR)"ICON_1"); - wndClass.hCursor = LoadCursor(NULL, IDC_ARROW ); - wndClass.hbrBackground = GetStockObject(WHITE_BRUSH ); - wndClass.lpszMenuName = szAppName; - wndClass.lpszClassName = szAppName; - if (!RegisterClass(&wndClass)) - return FALSE; - } -hWnd = CreateWindow(szAppName, "widget test program", - WS_POPUP | WS_CAPTION | WS_BORDER | WS_VISIBLE, 50, 50, - 400, 500, NULL, NULL, hInstance, NULL); -hWndMain = hWnd; -hInst = hInstance; -hDCMain = GetDC(hWndMain); -hREDBrush = CreateSOLIDBrush(0x000000FF); -hGREENBrush = CreateSOLIDBrush(0x00007F00); -hBLUEBrush = CreateSOLIDBrush(0x00FF0000); -hGRAYBrush = CreateSOLIDBrush(0x00C0C0C0); - -InitWidgets(); - -while (GetMessage(&msg, NULL, 0, 0)) - { - TranslateMessage(&msg ); - DispatchMessage(&msg ); - } -DeleteObject(hREDBrush); -DeleteObject(hGREENBrush); -DeleteObject(hBLUEBrush); -DeleteObject(hGRAYBrush); -if (hBitMap != NULL) DeleteObject(hBitMap); -if (hBitMap2 != NULL) DeleteObject(hBitMap2); -if (hBitMap3 != NULL) DeleteObject(hBitMap3); -ReleaseDC(hWndMain, hDC); -return(0); -} - - -void InitWidgets() -{ -hWndBut = CreateWindow("BUTTON", "Button #1", - WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE | BS_PUSHBUTTON, - 230, 40, 80, 30, hWndMain, 1001, hInst, NULL); -hWndScrol = CreateWindow("SCROLLBAR", "Scroll #1", - WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE | SBS_VERT, - 200, 150, 15, 100, hWndMain, 1004, hInst, NULL); -hWndScro2 = CreateWindow("SCROLLBAR", "Scroll #2", - WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE | SBS_HORZ, - 50, 150, 100, 15, hWndMain, 1005, hInst, NULL); -hWndScro3 = CreateWindow("SCROLLBAR", "Scroll #3", - WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE | SBS_SIZEBOX, - 50, 180, 25, 25, hWndMain, 1006, hInst, NULL); -x = y = 25; -SetVertScroll(NULL, hWndScrol, 25, 0, 50); -SetScrollRange(hWndScro2, SB_CTL, 0, 50, TRUE); -SetScrollPos(hWndScro2, SB_CTL, 25, TRUE); -hWndLBox = CreateWindow("LISTBOX", "", - WS_CHILD | WS_VISIBLE | WS_BORDER | WS_VSCROLL | LBS_NOTIFY, - 230, 160, 150, 100, hWndMain, 1004, hInst, NULL); -SendMessage(hWndLBox, LB_ADDSTRING, 0, (LPARAM)"ListBox item #1"); -hWndStat = CreateWindow("STATIC", "Static #1", - WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE | SS_LEFT, - 30, 120, 150, 20, hWndMain, 1011, hInst, NULL); -SendMessage(hWndStat, WM_SETTEXT, 0, (LPARAM)"Static Left Text"); -hWndCBox = CreateWindow("COMBOBOX", "Combo #1", - WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_BORDER | CBS_DROPDOWNLIST, - 230, 270, 150, 100, hWndMain, 1060, hInst, NULL); -SendMessage(hWndCBox, CB_ADDSTRING, 0, (LPARAM)"ComboBox item #1"); -SendMessage(hWndCBox, CB_ADDSTRING, 0, (LPARAM)"ComboBox item #2"); -SendMessage(hWndCBox, CB_ADDSTRING, 0, (LPARAM)"ComboBox item #3"); -SendMessage(hWndCBox, CB_ADDSTRING, 0, (LPARAM)"ComboBox item #4"); -SendMessage(hWndCBox, CB_ADDSTRING, 0, (LPARAM)"ComboBox item #5"); -SendMessage(hWndCBox, CB_ADDSTRING, 0, (LPARAM)"ComboBox item #6"); -} - - - -long FAR PASCAL WndProc(HWND hWnd, unsigned Message, WORD wParam, LONG lParam) -{ -int ShiftState; -LPDRAWITEMSTRUCT dis; -HDC hMemDC; -HBRUSH hBrush; -char C[128]; -ShiftState = GetKeyState(VK_SHIFT); -switch(Message) - { - case WM_COMMAND: - if (LOWORD(lParam) != 0) - { - sprintf(C, "MAIN WM_COMMAND wParam=%X lParam=%lX !!!", wParam, lParam); - TextOut(hDCMain, 25, 280, C, strlen(C)); - } - break; - - case WM_KEYDOWN: - sprintf(C, "WM_KEYDOWN !!!"); - TextOut(hDCMain, 25, 40, C, strlen(C)); - KeyDown(hWnd, Message, wParam); - break; - - case WM_CHAR: - sprintf(C, "WM_CHAR !!!"); - TextOut(hDCMain, 25, 50, C, strlen(C)); - break; - - case WM_CTLCOLOR: - switch(HIWORD(lParam)) - { - case CTLCOLOR_SCROLLBAR: - return(hBLUEBrush); - case CTLCOLOR_LISTBOX: - SetBkColor((HDC)wParam, 0x00C0C000); - SetTextColor((HDC)wParam, 0x00FF0000); - return(hGREENBrush); - case CTLCOLOR_STATIC: - SetBkColor((HDC)wParam, 0x00C0C0C0); - SetTextColor((HDC)wParam, 0x0000FFFF); - return(hREDBrush); - } - return((HBRUSH)NULL); - - case WM_LBUTTONDOWN: - break; - - case WM_LBUTTONUP: - break; - - case WM_RBUTTONDOWN: - break; - - case WM_RBUTTONUP: - break; - - case WM_MOUSEMOVE: - break; - - case WM_VSCROLL: - sprintf(C, "WM_VSCROLL %X %lX !!!", wParam, lParam); - TextOut(hDCMain, 25, 380, C, strlen(C)); - Do_Dlg_VertScroll(hWnd, wParam, lParam, &y, 0, 50); - break; - - case WM_HSCROLL: - sprintf(C, "WM_HSCROLL %X %lX !!!", wParam, lParam); - TextOut(hDCMain, 25, 380, C, strlen(C)); - Do_Dlg_HorzScroll(hWnd, wParam, lParam, &x, 0, 50); - break; - - case WM_DRAWITEM: - sprintf(C, "WM_DRAWITEM %X %lX !!!", wParam, lParam); - TextOut(hDCMain, 25, 380, C, strlen(C)); - if (lParam == 0L) break; - if (wParam == 0) break; - dis = (LPDRAWITEMSTRUCT)lParam; - if ((dis->CtlType == ODT_LISTBOX) && (dis->CtlID == 1062)) { - hBrush = SelectObject(dis->hDC, GetStockObject(LTGRAY_BRUSH)); - SelectObject(dis->hDC, hBrush); - FillRect(dis->hDC, &dis->rcItem, hBrush); - sprintf(C, "Item #%X", dis->itemID); - if (dis->itemData == NULL) break; - TextOut(dis->hDC, dis->rcItem.left, - dis->rcItem.top, C, strlen(C)); - } - if ((dis->CtlType == ODT_LISTBOX) && (dis->CtlID == 1063)) { - hBrush = SelectObject(dis->hDC, GetStockObject(LTGRAY_BRUSH)); - SelectObject(dis->hDC, hBrush); - FillRect(dis->hDC, &dis->rcItem, hBrush); - if (dis->itemData == NULL) break; - TextOut(dis->hDC, dis->rcItem.left, dis->rcItem.top, - (LPSTR)dis->itemData, lstrlen((LPSTR)dis->itemData)); - } - if ((dis->CtlType == ODT_LISTBOX) && (dis->CtlID == 1064)) { - hBrush = SelectObject(dis->hDC, GetStockObject(LTGRAY_BRUSH)); - SelectObject(dis->hDC, hBrush); - FillRect(dis->hDC, &dis->rcItem, hBrush); - hMemDC = CreateCompatibleDC(dis->hDC); - SelectObject(hMemDC,hBitMap); - BitBlt(dis->hDC, dis->rcItem.left, dis->rcItem.top, - BitMap.bmWidth, BitMap.bmHeight, hMemDC, 0, 0, SRCCOPY); - DeleteDC(hMemDC); - sprintf(C, "Item #%X", dis->itemID); - TextOut(dis->hDC, dis->rcItem.left + BitMap.bmWidth, - dis->rcItem.top, C, strlen(C)); -// if (dis->itemData == NULL) break; -// TextOut(dis->hDC, dis->rcItem.left + BitMap.bmWidth, -// dis->rcItem.top, (LPSTR)dis->itemData, -// lstrlen((LPSTR)dis->itemData)); - } - break; - - case WM_PAINT: - DoPaint(hWnd); - break; - - case WM_DESTROY: - PostQuitMessage(0); - break; - - default: - return DefWindowProc(hWnd, Message, wParam, lParam); - } -return(0); -} - - - -BOOL KeyDown(HWND hWnd, unsigned Message, WORD wParam) -{ -WORD wRet; -UINT uRet; -DWORD dwRet; -HDC hMemDC; -char C[128]; -char C2[64]; -NoREF(hWnd); -NoREF(Message); -sprintf(C, "KeyDown %x !!!", wParam); -TextOut(hDCMain, 25, 100, C, strlen(C)); -switch (wParam) - { - case VK_HOME: /* 'HOME' KEY */ - break; - case VK_LEFT: /* 'LEFT' CURSOR KEY */ - break; - case VK_RIGHT: /* 'RIGHT' CURSOR KEY */ - break; - case VK_UP: /* 'UP' CURSOR KEY */ - break; - case VK_DOWN: /* 'DOWN' CURSOR KEY */ - break; - case VK_PRIOR: /* 'PGUP' CURSOR KEY */ - break; - case VK_NEXT: /* 'PGDN' CURSOR KEY */ - break; - case '1': - break; - case '2': - hWndStat = CreateWindow("STATIC", "Static #2", - WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE | SS_CENTER, - 30, 150, 150, 20, hWndMain, 1012, hInst, NULL); - SendMessage(hWndStat, WM_SETTEXT, 0, (LPARAM)"Static Center Text"); - break; - case '3': - hWndStat = CreateWindow("STATIC", "Static #3", - WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE | SS_RIGHT, - 30, 180, 150, 20, hWndMain, 1013, hInst, NULL); - SendMessage(hWndStat, WM_SETTEXT, 0, (LPARAM)"Static Right Text"); - break; - case '4': - hWndStat = CreateWindow("STATIC", "Static #4", - WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE | SS_SIMPLE, - 30, 210, 150, 20, hWndMain, 1014, hInst, NULL); - SendMessage(hWndStat, WM_SETTEXT, 0, (LPARAM)"SS_SIMPLE"); - break; - case '5': - hWndStat = CreateWindow("STATIC", "Static #5", - WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE | SS_GRAYRECT, - 30, 240, 150, 20, hWndMain, 1015, hInst, NULL); - SendMessage(hWndStat, WM_SETTEXT, 0, (LPARAM)"SS_GRAYRECT"); - break; - case 'A': - hWndStat = CreateWindow("STATIC", "Static #6", - WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE | SS_BLACKRECT, - 30, 240, 150, 20, hWndMain, 1016, hInst, NULL); - SendMessage(hWndStat, WM_SETTEXT, 0, (LPARAM)"SS_BLACKRECT"); - break; - case 'C': - if (hBitMap2 == NULL) { - hBitMap2 = LoadBitmap(hInst, "LBICON"); - GetObject(hBitMap2, sizeof(BITMAP), (LPSTR)&BitMap); - } - hMemDC = CreateCompatibleDC(hDCMain); - SelectObject(hMemDC, hBitMap2); - BitBlt(hDCMain, 10, 10, BitMap.bmWidth, - BitMap.bmHeight, hMemDC, 0, 0, SRCCOPY); - DeleteDC(hMemDC); - sprintf(C, "DrawBitmap"); - TextOut(hDCMain, 25, 320, C, strlen(C)); - break; - case 'D': - if (hBitMap3 == NULL) { - hBitMap3 = LoadBitmap(hInst, MAKEINTRESOURCE(3333)); - GetObject(hBitMap3, sizeof(BITMAP), (LPSTR)&BitMap); - } - hMemDC = CreateCompatibleDC(hDCMain); - SelectObject(hMemDC, hBitMap3); - BitBlt(hDCMain, 80, 10, BitMap.bmWidth, - BitMap.bmHeight, hMemDC, 0, 0, SRCCOPY); - DeleteDC(hMemDC); - sprintf(C, "DrawBitmap"); - TextOut(hDCMain, 25, 320, C, strlen(C)); - break; - case 'F': - MoveWindow(hWnd, 10, 10, 500, 600, TRUE); - break; - case 'G': - MoveWindow(hWndBut, 20, 20, 100, 20, TRUE); - break; - case 'H': - WinHelp(hWndMain, "toto.hlp", HELP_INDEX, 0L); - break; - case 'J': - WinExec("/D:/wine/widget.exe arg1 arg2 arg3 arg4 arg5 arg6", SW_NORMAL); - break; - case 'K': - break; - case 'Q': - hWndChk = CreateWindow("BUTTON", "CheckBox #1", - WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE | BS_CHECKBOX, - 30, 300, 120, 20, hWndMain, 1020, hInst, NULL); - break; - case 'W': - wRet = SendMessage(hWndChk , BM_GETCHECK, 0, 0L); - SendMessage(hWndChk , BM_SETCHECK, wRet, 0L); - break; - case 'E': - break; - case 'R': - hWndRadio = CreateWindow("BUTTON", "RadioBut #1", - WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE | BS_RADIOBUTTON, - 230, 120, 120, 20, hWndMain, 1003, hInst, NULL); - SendMessage(hWndRadio, BM_SETCHECK, TRUE, 0L); - break; - case 'T': - SendMessage(hWndLBox, LB_ADDSTRING, 0, (LPARAM)"ListBox Single item"); - break; - case 'Y': - SendMessage(hWndLBox, LB_ADDSTRING, 0, (LPARAM)"ListBox item #2"); - SendMessage(hWndLBox, LB_ADDSTRING, 0, (LPARAM)"ListBox item #3"); - SendMessage(hWndLBox, LB_ADDSTRING, 0, (LPARAM)"ListBox item #4"); - SendMessage(hWndLBox, LB_ADDSTRING, 0, (LPARAM)"ListBox item #5"); - SendMessage(hWndLBox, LB_ADDSTRING, 0, (LPARAM)"ListBox item #6"); - SendMessage(hWndLBox, LB_SETCURSEL, 3, 0L); - SendMessage(hWndLBox, LB_INSERTSTRING, 5, (LPARAM)"Item between 5 & 6"); - wRet = SendMessage(hWndLBox, LB_FINDSTRING, -1, (LPARAM)"Item between 5 & 6"); - sprintf(C, "LB_FINDSTRING returned #%u ", wRet); - TextOut(hDCMain, 25, 300, C, strlen(C)); - wRet = SendMessage(hWndLBox, LB_GETCURSEL, 0, 0L); - sprintf(C, "LB_GETCURSEL returned #%u ", wRet); - TextOut(hDCMain, 25, 320, C, strlen(C)); - break; - case 'U': - wRet = SendMessage(hWndLBox, LB_GETCURSEL, 0, 0L); - SendMessage(hWndLBox, LB_DELETESTRING, wRet, 0L); - SendMessage(hWndLBox, LB_SETCURSEL, wRet, 0L); - break; - case 'I': - SendMessage(hWndLBox, LB_RESETCONTENT, 0, 0L); - break; - case 'O': - C2[0] = '\0'; - wRet = SendMessage(hWndLBox, LB_GETCURSEL, 0, 0L); - SendMessage(hWndLBox, LB_GETTEXT, wRet, (DWORD)C2); - sprintf(C, "LB_GETTEXT #%d returned '%s' ", wRet, C2); - TextOut(hDCMain, 25, 320, C, strlen(C)); - break; - case 'P': - SendMessage(hWndLBox, LB_DIR, 0, (DWORD)"*.*"); - break; - case 'Z': - ShowWindow(hWndScrol, SW_HIDE); - break; - case 'X': - ShowWindow(hWndScrol, SW_SHOW); - break; - case 'V': - MoveWindow(hWndScrol, 120, 150, 15, 60, TRUE); - break; - case 'B': - hWndCBox = CreateWindow("COMBOBOX", "Combo #2", - WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_BORDER | CBS_DROPDOWN, - 30, 270, 150, 100, hWndMain, 1061, hInst, NULL); - SendMessage(hWndCBox, CB_ADDSTRING, 0, (LPARAM)"ComboBox item #1"); - SendMessage(hWndCBox, CB_ADDSTRING, 0, (LPARAM)"ComboBox item #2"); - SendMessage(hWndCBox, CB_DIR, 0, (DWORD)"*.*"); - break; - case 'N': - hWndLBox2 = CreateWindow("LISTBOX", "", WS_CHILD | WS_VISIBLE | - WS_BORDER | WS_VSCROLL | LBS_OWNERDRAWVARIABLE | LBS_NOTIFY, -// WS_BORDER | WS_VSCROLL | LBS_OWNERDRAWVARIABLE | LBS_HASSTRINGS | LBS_NOTIFY, - 30, 300, 150, 60, hWndMain, 1062, hInst, NULL); - SendMessage(hWndLBox2, LB_ADDSTRING, 0, (LPARAM)"DRAWFIXED #1"); - SendMessage(hWndLBox2, LB_ADDSTRING, 0, (LPARAM)"DRAWFIXED #2"); - SendMessage(hWndLBox2, LB_ADDSTRING, 0, (LPARAM)"DRAWFIXED #3"); - SendMessage(hWndLBox2, LB_ADDSTRING, 0, (LPARAM)"DRAWFIXED #4"); - SendMessage(hWndLBox2, LB_ADDSTRING, 0, (LPARAM)"DRAWFIXED #5"); - SendMessage(hWndLBox2, LB_ADDSTRING, 0, (LPARAM)"DRAWFIXED #6"); - break; - case 'M': - hWndLBox3 = CreateWindow("LISTBOX", "", WS_CHILD | WS_VISIBLE | - WS_BORDER | WS_VSCROLL | LBS_OWNERDRAWVARIABLE | LBS_NOTIFY, -// WS_BORDER | WS_VSCROLL | LBS_OWNERDRAWVARIABLE | LBS_HASSTRINGS | LBS_NOTIFY, - 230, 300, 150, 60, hWndMain, 1063, hInst, NULL); - SendMessage(hWndLBox3, LB_ADDSTRING, 0, (LPARAM)"DRAWVARIABLE #1"); - SendMessage(hWndLBox3, LB_ADDSTRING, 0, (LPARAM)"DRAWVARIABLE #2"); - SendMessage(hWndLBox3, LB_ADDSTRING, 0, (LPARAM)"DRAWVARIABLE #3"); - SendMessage(hWndLBox3, LB_ADDSTRING, 0, (LPARAM)"DRAWVARIABLE #4"); - SendMessage(hWndLBox3, LB_ADDSTRING, 0, (LPARAM)"DRAWVARIABLE #5"); - SendMessage(hWndLBox3, LB_ADDSTRING, 0, (LPARAM)"DRAWVARIABLE #6"); - SendMessage(hWndLBox3, LB_ADDSTRING, 0, (LPARAM)"DRAWVARIABLE #7"); - SendMessage(hWndLBox3, LB_SETITEMHEIGHT, 1, 10L); - SendMessage(hWndLBox3, LB_SETITEMHEIGHT, 2, 20L); - SendMessage(hWndLBox3, LB_SETITEMHEIGHT, 3, 30L); - SendMessage(hWndLBox3, LB_SETITEMHEIGHT, 4, 40L); - SendMessage(hWndLBox3, LB_SETITEMHEIGHT, 5, 50L); - break; - case 'L': - hBitMap = LoadBitmap(hInst, MAKEINTRESOURCE(3333)); - GetObject(hBitMap, sizeof(BITMAP), (LPSTR)&BitMap); - hWndLBox4 = CreateWindow("LISTBOX", "", WS_CHILD | WS_VISIBLE | - WS_BORDER | WS_VSCROLL | LBS_OWNERDRAWVARIABLE | LBS_HASSTRINGS | LBS_NOTIFY, - 230, 380, 150, 60, hWndMain, 1064, hInst, NULL); - SendMessage(hWndLBox4, LB_ADDSTRING, 0, (LPARAM)"DRAWVARIABLE #1"); - SendMessage(hWndLBox4, LB_ADDSTRING, 0, (LPARAM)"DRAWVARIABLE #2"); - SendMessage(hWndLBox4, LB_ADDSTRING, 0, (LPARAM)"DRAWVARIABLE #3"); - SendMessage(hWndLBox4, LB_ADDSTRING, 0, (LPARAM)"DRAWVARIABLE #4"); - SendMessage(hWndLBox4, LB_ADDSTRING, 0, (LPARAM)"DRAWVARIABLE #5"); - SendMessage(hWndLBox4, LB_ADDSTRING, 0, (LPARAM)"DRAWVARIABLE #6"); - SendMessage(hWndLBox4, LB_SETITEMHEIGHT, 1, 10L); - SendMessage(hWndLBox4, LB_SETITEMHEIGHT, 2, 20L); - SendMessage(hWndLBox4, LB_SETITEMHEIGHT, 3, 30L); - SendMessage(hWndLBox4, LB_SETITEMHEIGHT, 4, 40L); - SendMessage(hWndLBox4, LB_SETITEMHEIGHT, 5, 50L); - break; - - case VK_F10: /* 'F10' FUNCTION KEY */ - break; - case VK_F11: /* 'F11' FUNCTION KEY */ - break; - } -return(TRUE); -} - - - -void DoPaint(HWND hWnd) -{ -HDC hDC; -RECT rect; -PAINTSTRUCT ps; -char C[80]; -GetClientRect(hWnd, &rect); -hDC = BeginPaint(hWnd, &ps); -FillRect(hDC, &rect, GetStockObject(GRAY_BRUSH)); -InflateRect(&rect, -3, -3); -FrameRect(hDC, &rect, GetStockObject(BLACK_BRUSH)); -InflateRect(&rect, -10, -10); -FillRect(hDC, &rect, GetStockObject(WHITE_BRUSH)); -sprintf(C, "Wine Testing !!!"); -TextOut(hDC, 25, 25, C, strlen(C)); -ReleaseDC(hWnd,hDC); -EndPaint(hWnd,&ps); -} - - -HBRUSH CreateLTGRAYBrush() -{ -return(CreateSOLIDBrush(0x00C0C0C0)); -} - - - -HBRUSH CreateSOLIDBrush(COLORREF Color) -{ -LOGBRUSH logGRAYBrush; -logGRAYBrush.lbStyle = BS_SOLID; -logGRAYBrush.lbColor = Color; -logGRAYBrush.lbHatch = NULL; -return(CreateBrushIndirect(&logGRAYBrush)); -} - - - -/**********************************************************************/ - - -void SetVertScroll(int hDlg, int hWndSCROLL, int VAL, int MIN, int MAX) -{ -char C[12]; -SetScrollRange(hWndSCROLL, SB_CTL, -MAX, -MIN, FALSE); -SetScrollPos(hWndSCROLL, SB_CTL, -VAL, TRUE); -itoa(VAL, C, 10); -//SetDlgItemText(hDlg, (IDDTXT1 + GetDlgCtrlID(hWndSCROLL) - IDDSCROLL1), C); -} - - - -void SetHorzScroll(int hDlg, int hWndSCROLL, int VAL, int MIN, int MAX) -{ -char C[12]; -SetScrollRange(hWndSCROLL, SB_CTL, MAX, MIN, FALSE); -SetScrollPos(hWndSCROLL, SB_CTL, VAL, TRUE); -itoa(VAL, C, 10); -//SetDlgItemText(hDlg, (IDDTXT1 + GetDlgCtrlID(hWndSCROLL) - IDDSCROLL1), C); -} - - - -void Do_Dlg_VertScroll(HWND hDlg, WORD wParam, DWORD lParam, int *V, int MIN, int MAX) -{ -char C[12]; -int VAL; -int VAL2; -int Step = 100; -if (MAX < 1000) Step = 10; -if (MAX < 100) Step = MAX / 10; -VAL = *(V); -VAL2 = VAL; -switch (wParam) - { - case SB_LINEUP: - VAL++; - break; - case SB_LINEDOWN: - VAL--; - break; - case SB_PAGEUP: - VAL += Step; - break; - case SB_PAGEDOWN: - VAL -= Step; - break; - case SB_THUMBTRACK: - case SB_THUMBPOSITION: - VAL = -(LOWORD(lParam)); - break; - } -if (VAL > MAX) VAL = MAX; -if (VAL < MIN) VAL = MIN; -if (VAL != VAL2) - { - SetScrollPos(HIWORD(lParam), SB_CTL, -VAL, TRUE); - ltoa(VAL, C, 10); -// SetDlgItemText(hDlg, (IDDTXT1 + GetDlgCtrlID(HIWORD(lParam)) - IDDSCROLL1), C); - } -*(V) = VAL; -} - - -void Do_Dlg_HorzScroll(HWND hDlg, WORD wParam, DWORD lParam, int *V, int MIN, int MAX) -{ -char C[12]; -int VAL; -int VAL2; -int Step = 100; -if (MAX < 1000) Step = 10; -if (MAX < 100) Step = MAX / 10; -VAL = *(V); -VAL2 = VAL; -switch (wParam) - { - case SB_LINEUP: - VAL--; - break; - case SB_LINEDOWN: - VAL++; - break; - case SB_PAGEUP: - VAL -= Step; - break; - case SB_PAGEDOWN: - VAL += Step; - break; - case SB_THUMBTRACK: - case SB_THUMBPOSITION: - VAL = (LOWORD(lParam)); - break; - } -if (VAL > MAX) VAL = MAX; -if (VAL < MIN) VAL = MIN; -if (VAL != VAL2) - { - SetScrollPos(HIWORD(lParam), SB_CTL, VAL, TRUE); - ltoa(VAL, C, 10); -// SetDlgItemText(hDlg, (IDDTXT1 + GetDlgCtrlID(HIWORD(lParam)) - IDDSCROLL1), C); - } -*(V) = VAL; -} - - -/**********************************************************************/ - - - \ No newline at end of file diff --git a/test/martin_ship4/widget.exe b/test/martin_ship4/widget.exe deleted file mode 100755 index 91ecd00fa480713f3ea712fee33d1bed2393cbda..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 35298 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≻E%_o+tes#D| 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 KR})jl68$%wrB1^D delta 8787 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 diff --git a/windows/Makefile b/windows/Makefile index 812bd343730..0c5d34add37 100644 --- a/windows/Makefile +++ b/windows/Makefile @@ -2,7 +2,7 @@ CFLAGS=$(COPTS) $(DEBUGOPTS) -I$(INCLUDE_DIR) OBJS=class.o dc.o dce.o event.o message.o win.o timer.o graphics.o \ clipping.o mapping.o painting.o keyboard.o utility.o syscolor.o \ - defwnd.o defdlg.o dialog.o focus.o + defwnd.o defdlg.o dialog.o focus.o scroll.o default: windows.o diff --git a/windows/dialog.c b/windows/dialog.c index e60b62d84c0..108c964c5cb 100644 --- a/windows/dialog.c +++ b/windows/dialog.c @@ -6,10 +6,9 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1993"; -#include - #include "windows.h" #include "dialog.h" +#include "prototypes.h" #include "win.h" @@ -29,7 +28,7 @@ BOOL DIALOG_Init() /* Calculate the dialog base units */ - if (!(hdc = GetDC( 0 ))) return FALSE; + if (!(hdc = GetDC(GetDesktopWindow()))) return FALSE; GetTextMetrics( hdc, &tm ); ReleaseDC( 0, hdc ); xBaseUnit = tm.tmAveCharWidth; @@ -79,15 +78,17 @@ static DLGCONTROLHEADER * DIALOG_GetControl( DLGCONTROLHEADER * ptr, /*********************************************************************** * DIALOG_ParseTemplate * - * Fill a DLGTEMPLATE structure from the dialog template. + * Fill a DLGTEMPLATE structure from the dialog template, and return + * a pointer to the first control. */ -static void DIALOG_ParseTemplate( LPCSTR template, DLGTEMPLATE * result ) +static DLGCONTROLHEADER * DIALOG_ParseTemplate( LPCSTR template, + DLGTEMPLATE * result ) { - int i; unsigned char * p = (unsigned char *)template; result->header = (DLGTEMPLATEHEADER *)p; p += 13; + result->menuName = p; if (*p == 0xff) p += 3; else p += strlen(p) + 1; @@ -104,18 +105,8 @@ static void DIALOG_ParseTemplate( LPCSTR template, DLGTEMPLATE * result ) result->pointSize = *(WORD *)p; p += sizeof(WORD); result->faceName = p; p += strlen(p) + 1; } - result->controls = NULL; - if (!result->header->nbItems) return; - result->controls = (DLGCONTROL *) malloc( result->header->nbItems * sizeof(DLGCONTROL) ); - if (!result->controls) return; - for (i = 0; i < result->header->nbItems; i++) - { - result->controls[i].header = (DLGCONTROLHEADER *)p; - p = (char *)DIALOG_GetControl( result->controls[i].header, - &result->controls[i].class, - &result->controls[i].text ); - } + return (DLGCONTROLHEADER *)p; } @@ -125,9 +116,6 @@ static void DIALOG_ParseTemplate( LPCSTR template, DLGTEMPLATE * result ) #ifdef DEBUG_DIALOG static void DIALOG_DisplayTemplate( DLGTEMPLATE * result ) { - int i; - DLGCONTROL * ctrl = result->controls; - printf( "DIALOG %d, %d, %d, %d\n", result->header->x, result->header->y, result->header->cx, result->header->cy ); printf( " STYLE %08x\n", result->header->style ); @@ -138,18 +126,6 @@ static void DIALOG_DisplayTemplate( DLGTEMPLATE * result ) else printf( " MENU '%s'\n", result->menuName ); if (result->header->style & DS_SETFONT) printf( " FONT %d,'%s'\n", result->pointSize, result->faceName ); - - printf( " BEGIN\n" ); - - for (i = 0; i < result->header->nbItems; i++, ctrl++) - { - printf( " %s '%s' %d, %d, %d, %d, %d, %08x\n", - ctrl->class, ctrl->text, ctrl->header->id, - ctrl->header->x, ctrl->header->y, ctrl->header->cx, - ctrl->header->cy, ctrl->header->style ); - } - - printf( " END\n" ); } #endif /* DEBUG_DIALOG */ @@ -187,7 +163,7 @@ HWND CreateDialogParam( HINSTANCE hInst, LPCSTR dlgTemplate, else hwnd = CreateDialogIndirectParam(hInst, data, owner, dlgProc, param); FreeResource( hmem ); #else - hmem = RSC_LoadResource( hInst, dlgTemplate, 0x8005, &size ); + hmem = RSC_LoadResource( hInst, dlgTemplate, NE_RSCTYPE_DIALOG, &size ); data = (LPCSTR) GlobalLock( hmem ); hwnd = CreateDialogIndirectParam( hInst, data, owner, dlgProc, param ); GlobalFree( hmem ); @@ -212,31 +188,39 @@ HWND CreateDialogIndirect( HINSTANCE hInst, LPCSTR dlgTemplate, HWND CreateDialogIndirectParam( HINSTANCE hInst, LPCSTR dlgTemplate, HWND owner, FARPROC dlgProc, LPARAM param ) { - HMENU hMenu = 0; + HMENU hMenu; HFONT hFont = 0; HWND hwnd; WND * wndPtr; + int i; DLGTEMPLATE template; + DLGCONTROLHEADER * header; DIALOGINFO * dlgInfo; WORD xUnit = xBaseUnit; WORD yUnit = yBaseUnit; - - if (!dlgTemplate) return 0; - DIALOG_ParseTemplate( dlgTemplate, &template ); + /* Parse dialog template */ + + if (!dlgTemplate) return 0; + header = DIALOG_ParseTemplate( dlgTemplate, &template ); #ifdef DEBUG_DIALOG DIALOG_DisplayTemplate( &template ); #endif /* Load menu */ - if (template.menuName[0]) + switch (template.menuName[0]) { - if (template.menuName[0] != 0xff) - hMenu = LoadMenu( hInst, template.menuName ); - else - hMenu = LoadMenu( hInst, MAKEINTRESOURCE( template.menuName[1] + + case 0x00: + hMenu = 0; + break; + case 0xff: + hMenu = LoadMenu( hInst, MAKEINTRESOURCE( template.menuName[1] + 256*template.menuName[2] )); + break; + default: + hMenu = LoadMenu( hInst, template.menuName ); + break; } /* Create custom font if needed */ @@ -252,7 +236,7 @@ HWND CreateDialogIndirectParam( HINSTANCE hInst, LPCSTR dlgTemplate, HFONT oldFont; HDC hdc; - hdc = GetDC( 0 ); + hdc = GetDC(GetDesktopWindow()); oldFont = SelectObject( hdc, hFont ); GetTextMetrics( hdc, &tm ); SelectObject( hdc, oldFont ); @@ -261,11 +245,11 @@ HWND CreateDialogIndirectParam( HINSTANCE hInst, LPCSTR dlgTemplate, yUnit = tm.tmHeight; } } - + /* Create dialog main window */ hwnd = CreateWindow( template.className, template.caption, - template.header->style & ~WS_VISIBLE, + template.header->style, template.header->x * xUnit / 4, template.header->y * yUnit / 8, template.header->cx * xUnit / 4, @@ -276,27 +260,42 @@ HWND CreateDialogIndirectParam( HINSTANCE hInst, LPCSTR dlgTemplate, { if (hFont) DeleteObject( hFont ); if (hMenu) DestroyMenu( hMenu ); - if (template.controls) free( template.controls ); return 0; } /* Create control windows */ - if (hwnd && template.header->nbItems) +#ifdef DEBUG_DIALOG + printf( " BEGIN\n" ); +#endif + + for (i = 0; i < template.header->nbItems; i++) { - int i; - DLGCONTROL * ctrl = template.controls; - for (i = 0; i < template.header->nbItems; i++, ctrl++) - { - CreateWindowEx( WS_EX_NOPARENTNOTIFY, - ctrl->class, ctrl->text, ctrl->header->style, - ctrl->header->x * xUnit / 4, - ctrl->header->y * yUnit / 8, - ctrl->header->cx * xUnit / 4, - ctrl->header->cy * yUnit / 8, - hwnd, ctrl->header->id, hInst, NULL ); - } - } + DLGCONTROLHEADER * next_header; + LPSTR class, text; + next_header = DIALOG_GetControl( header, &class, &text ); + +#ifdef DEBUG_DIALOG + printf( " %s '%s' %d, %d, %d, %d, %d, %08x\n", + class, text, header->id, header->x, header->y, header->cx, + header->cy, header->style ); +#endif + if ((strcmp(class, "STATIC") == 0) & ((header->style & SS_ICON) == SS_ICON)) { + header->cx = 32; + header->cy = 32; + } + header->style |= WS_CHILD; + CreateWindowEx( WS_EX_NOPARENTNOTIFY, + class, text, header->style, + header->x * xUnit / 4, header->y * yUnit / 8, + header->cx * xUnit / 4, header->cy * yUnit / 8, + hwnd, header->id, hInst, NULL ); + header = next_header; + } + +#ifdef DEBUG_DIALOG + printf( " END\n" ); +#endif /* Initialise dialog extra data */ @@ -318,35 +317,24 @@ HWND CreateDialogIndirectParam( HINSTANCE hInst, LPCSTR dlgTemplate, if (SendMessage( hwnd, WM_INITDIALOG, dlgInfo->hwndFocus, param )) SetFocus( dlgInfo->hwndFocus ); - /* Display dialog */ - - if (template.header->style & WS_VISIBLE) ShowWindow( hwnd, SW_SHOW ); - - if (template.controls) free( template.controls ); return hwnd; } /*********************************************************************** - * DialogBox (USER.87) + * DIALOG_DoDialogBox */ -int DialogBox( HINSTANCE hInst, LPCSTR dlgTemplate, - HWND owner, FARPROC dlgProc ) +static int DIALOG_DoDialogBox( HWND hwnd ) { - HWND hwnd; WND * wndPtr; DIALOGINFO * dlgInfo; MSG msg; int retval; -#ifdef DEBUG_DIALOG - printf( "DialogBox: %d,'%s',%d,%p\n", hInst, dlgTemplate, owner, dlgProc ); -#endif - - hwnd = CreateDialog( hInst, dlgTemplate, owner, dlgProc ); - if (!hwnd) return -1; - wndPtr = WIN_FindWndPtr( hwnd ); + if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return -1; dlgInfo = (DIALOGINFO *)wndPtr->wExtra; + ShowWindow( hwnd, SW_SHOW ); + while (GetMessage (&msg, 0, 0, 0)) { if (!IsDialogMessage( hwnd, &msg)) @@ -362,6 +350,61 @@ int DialogBox( HINSTANCE hInst, LPCSTR dlgTemplate, } +/*********************************************************************** + * DialogBox (USER.87) + */ +int DialogBox( HINSTANCE hInst, LPCSTR dlgTemplate, + HWND owner, FARPROC dlgProc ) +{ + return DialogBoxParam( hInst, dlgTemplate, owner, dlgProc, 0 ); +} + + +/*********************************************************************** + * DialogBoxParam (USER.239) + */ +int DialogBoxParam( HINSTANCE hInst, LPCSTR dlgTemplate, + HWND owner, FARPROC dlgProc, LPARAM param ) +{ + HWND hwnd; + +#ifdef DEBUG_DIALOG + printf( "DialogBoxParam: %d,'%s',%d,%p,%d\n", + hInst, dlgTemplate, owner, dlgProc, param ); +#endif + hwnd = CreateDialogParam( hInst, dlgTemplate, owner, dlgProc, param ); + if (hwnd) return DIALOG_DoDialogBox( hwnd ); + return -1; +} + + +/*********************************************************************** + * DialogBoxIndirect (USER.218) + */ +int DialogBoxIndirect( HINSTANCE hInst, HANDLE dlgTemplate, + HWND owner, FARPROC dlgProc ) +{ + return DialogBoxIndirectParam( hInst, dlgTemplate, owner, dlgProc, 0 ); +} + + +/*********************************************************************** + * DialogBoxIndirectParam (USER.240) + */ +int DialogBoxIndirectParam( HINSTANCE hInst, HANDLE dlgTemplate, + HWND owner, FARPROC dlgProc, LPARAM param ) +{ + HWND hwnd; + LPCSTR ptr; + + if (!(ptr = GlobalLock( dlgTemplate ))) return -1; + hwnd = CreateDialogIndirectParam( hInst, ptr, owner, dlgProc, param ); + GlobalUnlock( dlgTemplate ); + if (hwnd) return DIALOG_DoDialogBox( hwnd ); + return -1; +} + + /*********************************************************************** * EndDialog (USER.88) */ diff --git a/windows/event.c b/windows/event.c index f9c5e21f3fe..31301896e61 100644 --- a/windows/event.c +++ b/windows/event.c @@ -16,8 +16,7 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1993"; #define NB_BUTTONS 3 /* Windows can handle 3 buttons */ -#define DBLCLICK_TIME 300 /* Max. time for a double click (milliseconds) */ - +static WORD dblclick_time = 300; /* Max. time for a double click (milliseconds) */ /* Event handlers */ static void EVENT_expose(); @@ -191,7 +190,7 @@ static void EVENT_mouse_button( Widget w, int hwnd, XButtonEvent *event, { /* Check if double-click */ prevTime = lastClickTime[buttonNum]; lastClickTime[buttonNum] = event->time; - if (event->time - prevTime < DBLCLICK_TIME) + if (event->time - prevTime < dblclick_time) { WND * wndPtr; CLASS * classPtr; @@ -329,3 +328,24 @@ void ReleaseCapture() captureWnd = 0; } + +/********************************************************************** + * SetDoubleClickTime (USER.20) + */ +void SetDoubleClickTime (WORD interval) +{ + if (interval == 0) + dblclick_time = 500; + else + dblclick_time = interval; +} + +/********************************************************************** + * GetDoubleClickTime (USER.21) + */ +WORD GetDoubleClickTime () +{ + return ((WORD)dblclick_time); +} + + diff --git a/windows/scroll.c b/windows/scroll.c new file mode 100644 index 00000000000..34d43fd2c6c --- /dev/null +++ b/windows/scroll.c @@ -0,0 +1,171 @@ +/* + * Scroll windows and DCs + * + * Copyright David W. Metcalfe, 1993 + * + */ + +static char Copyright[] = "Copyright David W. Metcalfe, 1993"; + +#include +#include "windows.h" +#include "gdi.h" + +static int RgnType; + + +/************************************************************************* + * ScrollWindow (USER.61) + */ + +void ScrollWindow(HWND hwnd, short dx, short dy, LPRECT rect, LPRECT clipRect) +{ + HDC hdc; + HRGN hrgnUpdate; + RECT rc, cliprc; + +#ifdef DEBUG_SCROLL + printf("ScrollWindow: dx=%d, dy=%d, rect=%d,%d,%d,%d\n", dx, dy, + rect->left, rect->top, rect->right, rect->bottom); +#endif + + hdc = GetDC(hwnd); + + if (rect == NULL) + GetWindowRect(hwnd, &rc); + else + CopyRect(&rc, rect); + if (clipRect == NULL) + GetWindowRect(hwnd, &cliprc); + else + CopyRect(&cliprc, clipRect); + + hrgnUpdate = CreateRectRgn(0, 0, 0, 0); + ScrollDC(hdc, dx, dy, &rc, &cliprc, hrgnUpdate, NULL); + InvalidateRgn(hwnd, hrgnUpdate, TRUE); + ReleaseDC(hwnd, hdc); +} + + +/************************************************************************* + * ScrollDC (USER.221) + */ + +BOOL ScrollDC(HDC hdc, short dx, short dy, LPRECT rc, LPRECT cliprc, + HRGN hrgnUpdate, LPRECT rcUpdate) +{ + HRGN hrgnClip, hrgn1, hrgn2; + POINT src, dest; + short width, height; + DC *dc = (DC *)GDI_GetObjPtr(hdc, DC_MAGIC); + +#ifdef DEBUG_SCROLL + printf("ScrollDC: dx=%d, dy=%d, rc=%d,%d,%d,%d\n", dx, dy, + rc->left, rc->top, rc->right, rc->bottom); +#endif + + if (rc == NULL) + return; + + if (cliprc) + { + hrgnClip = CreateRectRgnIndirect(cliprc); + SelectClipRgn(hdc, hrgnClip); + } + + if (dx > 0) + { + src.x = XDPTOLP(dc, rc->left); + dest.x = XDPTOLP(dc, rc->left + abs(dx)); + } + else + { + src.x = XDPTOLP(dc, rc->left + abs(dx)); + dest.x = XDPTOLP(dc, rc->left); + } + if (dy > 0) + { + src.y = YDPTOLP(dc, rc->top); + dest.y = YDPTOLP(dc, rc->top + abs(dy)); + } + else + { + src.y = YDPTOLP(dc, rc->top + abs(dy)); + dest.y = YDPTOLP(dc, rc->top); + } + + width = rc->right - rc->left - abs(dx); + height = rc->bottom - rc->top - abs(dy); + + if (!BitBlt(hdc, dest.x, dest.y, width, height, hdc, src.x, src.y, + SRCCOPY)) + return; + + if (hrgnUpdate) + { + if (dx > 0) + hrgn1 = CreateRectRgn(rc->left, rc->top, rc->left+dx, rc->bottom); + else if (dx < 0) + hrgn1 = CreateRectRgn(rc->right+dx, rc->top, rc->right, + rc->bottom); + else + hrgn1 = CreateRectRgn(0, 0, 0, 0); + + if (dy > 0) + hrgn2 = CreateRectRgn(rc->left, rc->top, rc->right, rc->top+dy); + else if (dy < 0) + hrgn2 = CreateRectRgn(rc->left, rc->bottom+dy, rc->right, + rc->bottom); + else + hrgn2 = CreateRectRgn(0, 0, 0, 0); + + RgnType = CombineRgn(hrgnUpdate, hrgn1, hrgn2, RGN_OR); + } + + if (rcUpdate) + { + SelectClipRgn(hdc, hrgnUpdate); + GetClipBox(hdc, rcUpdate); + } +} + + +/************************************************************************* + * ScrollWindowEx (USER.319) + */ + +int ScrollWindowEx(HWND hwnd, short dx, short dy, LPRECT rect, LPRECT clipRect, + HRGN hrgnUpdate, LPRECT rcUpdate, WORD flags) +{ + HDC hdc; + RECT rc, cliprc; + +#ifdef DEBUG_SCROLL + printf("ScrollWindowEx: dx=%d, dy=%d, rect=%d,%d,%d,%d\n", dx, dy, + rect->left, rect->top, rect->right, rect->bottom); +#endif + + hdc = GetDC(hwnd); + + if (rect == NULL) + GetWindowRect(hwnd, &rc); + else + CopyRect(&rc, rect); + if (clipRect == NULL) + GetWindowRect(hwnd, &cliprc); + else + CopyRect(&cliprc, clipRect); + + ScrollDC(hdc, dx, dy, &rc, &cliprc, hrgnUpdate, rcUpdate); + + if (flags | SW_INVALIDATE) + { + InvalidateRgn(hwnd, hrgnUpdate, FALSE); + + if (flags | SW_ERASE) + SendMessage(hwnd, WM_ERASEBKGND, (WORD)hdc, (LONG)NULL); + } + + ReleaseDC(hwnd, hdc); + return RgnType; +} diff --git a/windows/win.c b/windows/win.c index 3e50a37fba9..d7fe3a2c88e 100644 --- a/windows/win.c +++ b/windows/win.c @@ -52,9 +52,11 @@ HWND WIN_FindWinToRepaint( HWND hwnd ) WND * wndPtr; if (!hwnd) hwnd = firstWindow; - while (hwnd) + for ( ; hwnd != 0; hwnd = wndPtr->hwndNext ) { if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0; + if (!wndPtr || !wndPtr->winWidget) continue; + if (!XtIsRealized( wndPtr->winWidget )) continue; if (wndPtr->hrgnUpdate) return hwnd; if (wndPtr->hwndChild) { @@ -62,7 +64,6 @@ HWND WIN_FindWinToRepaint( HWND hwnd ) if ((child = WIN_FindWinToRepaint( wndPtr->hwndChild ))) return child; } - hwnd = wndPtr->hwndNext; } return 0; } @@ -122,8 +123,8 @@ HWND CreateWindowEx( DWORD exStyle, LPSTR className, LPSTR windowName, if (y == CW_USEDEFAULT) y = 0; if (width == CW_USEDEFAULT) width = 600; if (height == CW_USEDEFAULT) height = 400; - if (!width) width = 1; - if (!height) height = 1; + if (width == 0) width = 1; + if (height == 0) height = 1; /* Find the parent and class */ @@ -135,9 +136,10 @@ HWND CreateWindowEx( DWORD exStyle, LPSTR className, LPSTR windowName, } else if (style & WS_CHILD) return 0; /* WS_CHILD needs a parent */ - if (!(class = CLASS_FindClassByName( className, &classPtr ))) + if (!(class = CLASS_FindClassByName( className, &classPtr ))) { + printf("CreateWindow BAD CLASSNAME '%s' !\n", className); return 0; - + } /* Create the window structure */ hwnd = USER_HEAP_ALLOC(GMEM_MOVEABLE, sizeof(WND)+classPtr->wc.cbWndExtra); @@ -250,6 +252,8 @@ HWND CreateWindowEx( DWORD exStyle, LPSTR className, LPSTR windowName, formWidgetClass, wndPtr->shellWidget, NULL ); +/* wndPtr->winWidget = wndPtr->compositeWidget; */ + wndPtr->winWidget = wndPtr->shellWidget; if (wndPtr->wIDmenu == 0) { wndPtr->menuBarPtr = @@ -322,8 +326,13 @@ WinCreated: if (wmcreate == -1) { /* Abort window creation */ + + if (parent) parentPtr->hwndChild = wndPtr->hwndNext; + else firstWindow = wndPtr->hwndNext; if (wndPtr->shellWidget) XtDestroyWidget( wndPtr->shellWidget ); else XtDestroyWidget( wndPtr->winWidget ); + if (wndPtr->hdc) DeleteDC( wndPtr->hdc ); + classPtr->cWindows--; USER_HEAP_FREE( hwnd ); return 0; } @@ -446,28 +455,32 @@ BOOL ShowWindow( HWND hwnd, int cmd ) XtNwidth, &width, XtNheight, &height, NULL ); - SendMessage( hwnd, WM_SIZE, SIZE_RESTORED, - (width & 0xffff) | (height << 16) ); - SendMessage( hwnd, WM_SHOWWINDOW, TRUE, 0 ); -/* - printf("ShowWindow(%X, %X); !\n", hwnd, cmd); -*/ switch(cmd) { case SW_HIDE: XtSetMappedWhenManaged(wndPtr->winWidget, FALSE); + wndPtr->dwStyle &= (WS_VISIBLE ^ 0xFFFFFFFL); + SendMessage( hwnd, WM_SHOWWINDOW, FALSE, 0 ); break; - case SW_SHOWNA: case SW_SHOWMINNOACTIVE: - case SW_SHOWNOACTIVATE: + case SW_SHOWMINIMIZED: case SW_MINIMIZE: + wndPtr->dwStyle |= WS_ICONIC; + goto WINVisible; + case SW_SHOWNA: + case SW_SHOWNOACTIVATE: case SW_MAXIMIZE: case SW_SHOWMAXIMIZED: - case SW_SHOWMINIMIZED: case SW_SHOW: case SW_NORMAL: case SW_SHOWNORMAL: + wndPtr->dwStyle &= (WS_ICONIC ^ 0xFFFFFFFL); +WINVisible: XtSetMappedWhenManaged(wndPtr->winWidget, TRUE); + wndPtr->dwStyle |= WS_VISIBLE; + SendMessage( hwnd, WM_SIZE, SIZE_RESTORED, + (width & 0xffff) | (height << 16) ); + SendMessage( hwnd, WM_SHOWWINDOW, TRUE, 0 ); break; default: break; @@ -477,6 +490,42 @@ BOOL ShowWindow( HWND hwnd, int cmd ) } +/*********************************************************************** + * CloseWindow (USER.43) + */ +void CloseWindow(HWND hWnd) +{ + WND * wndPtr = WIN_FindWndPtr(hWnd); + if (wndPtr->dwStyle & WS_CHILD) return; + ShowWindow(hWnd, SW_MINIMIZE); + PostMessage(hWnd, WM_CLOSE, 0, 0L); +} + + + +/*********************************************************************** + * OpenIcon (USER.44) + */ +BOOL OpenIcon(HWND hWnd) +{ + WND * wndPtr = WIN_FindWndPtr(hWnd); + if (!IsIconic(hWnd)) return FALSE; + ShowWindow(hWnd, SW_SHOWNORMAL); + return(TRUE); +} + + + +/*********************************************************************** + * FindWindow (USER.50) + */ +HWND FindWindow(LPSTR ClassMatch, LPSTR TitleMatch) +{ + return((HWND)NULL); +} + + + /*********************************************************************** * MoveWindow (USER.56) */ @@ -508,7 +557,9 @@ void MoveWindow(HWND hWnd, short x, short y, short w, short h, BOOL bRepaint) void UpdateWindow( HWND hwnd ) { if (GetUpdateRect( hwnd, NULL, FALSE )) - SendMessage( hwnd, WM_PAINT, 0, 0 ); + { + if (IsWindowVisible( hwnd )) SendMessage( hwnd, WM_PAINT, 0, 0 ); + } } /********************************************************************** @@ -578,17 +629,17 @@ void SetWindowPos(HWND hWnd, HWND hWndInsertAfter, short x, short y, short w, sh WND * wndPtr = WIN_FindWndPtr( hWnd ); if (wndPtr) { - if ((wFlag & SWP_NOMOVE) == 0) { + if ((wFlag & SWP_NOMOVE) != SWP_NOMOVE) { wndPtr->rectClient.left = x; wndPtr->rectClient.top = y; XtVaSetValues(wndPtr->winWidget, XtNx, x, XtNy, y, NULL ); } - if ((wFlag & SWP_NOSIZE) == 0) { + if ((wFlag & SWP_NOSIZE) != SWP_NOSIZE) { wndPtr->rectClient.right = x + w; wndPtr->rectClient.bottom = y + h; XtVaSetValues(wndPtr->winWidget, XtNwidth, w, XtNheight, h, NULL ); } - if ((wFlag & SWP_NOREDRAW) == 0) { + if ((wFlag & SWP_NOREDRAW) != SWP_NOREDRAW) { InvalidateRect(hWnd, NULL, TRUE); UpdateWindow(hWnd); } @@ -597,8 +648,10 @@ void SetWindowPos(HWND hWnd, HWND hWndInsertAfter, short x, short y, short w, sh if ((wFlag & SWP_SHOWWINDOW) == SWP_SHOWWINDOW) ShowWindow(hWnd, SW_SHOW); /* - if ((wFlag & SWP_NOACTIVATE) == 0) + if ((wFlag & SWP_NOACTIVATE) != SWP_NOACTIVATE) SetActiveWindow(hWnd); + if ((wFlag & SWP_NOZORDER) != SWP_NOZORDER) + { } */ printf("SetWindowPos(%X, %X, %d, %d, %d, %d, %X); !\n", hWnd, hWndInsertAfter, x, y, w, h, wFlag); @@ -695,16 +748,21 @@ LONG SetWindowLong( HWND hwnd, short offset, LONG newval ) } -/***************************************************************** - * GetParent (USER.46) +/*********************************************************************** + * IsIconic (USER.31) */ -HWND GetParent(HWND hwnd) +BOOL IsIconic(HWND hWnd) { - WND *wndPtr = WIN_FindWndPtr(hwnd); - return wndPtr->hwndParent; + WND * wndPtr; + if (hWnd == 0) return(FALSE); + wndPtr = WIN_FindWndPtr(hWnd); + if (wndPtr == 0) return(FALSE); + if (wndPtr->dwStyle & WS_ICONIC) return(TRUE); + return(FALSE); } - + + /******************************************************************* * GetWindowText (USER.36) */ @@ -732,6 +790,26 @@ int GetWindowTextLength(HWND hwnd) } +/******************************************************************* + * IsWindow (USER.47) + */ +BOOL IsWindow( HWND hwnd ) +{ + WND * wndPtr = WIN_FindWndPtr( hwnd ); + return (wndPtr->dwMagic == WND_MAGIC); +} + + +/***************************************************************** + * GetParent (USER.46) + */ +HWND GetParent(HWND hwnd) +{ + WND *wndPtr = WIN_FindWndPtr(hwnd); + return wndPtr->hwndParent; +} + + /******************************************************************* * IsChild (USER.48) */ @@ -755,6 +833,23 @@ BOOL IsChild( HWND parent, HWND child ) } +/*********************************************************************** + * IsWindowVisible (USER.49) + */ +BOOL IsWindowVisible(HWND hWnd) +{ + WND * wndPtr; + if (hWnd == 0) return(FALSE); + wndPtr = WIN_FindWndPtr(hWnd); + if (wndPtr == 0) return(FALSE); + if (wndPtr->dwStyle & WS_VISIBLE) { + if (XtIsRealized(wndPtr->winWidget)) return(TRUE); + } + return(FALSE); +} + + + /******************************************************************* * GetTopWindow (USER.229) */