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 | 448 +++++++++++++++++++++++++++-- loader/selector.c | 458 ++++++++++++++++-------------- 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, 2350 insertions(+), 2129 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 rewrite test/widget.exe (64%) 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 @@ -7,6 +7,19 @@ #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,32 +281,290 @@ 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); - return 0; + 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; } + /********************************************************************** - * LoadCursor + * ShowCursor [USER.71] */ -HCURSOR -LoadCursor(HANDLE instance, LPSTR cursor_name) +int ShowCursor(BOOL bShow) { - fprintf(stderr,"LoadCursor: (%d),%d\n",instance,cursor_name); + if (bShow) { + } 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; + +/********************************************************************** + * 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; +} + /********************************************************************** - * GetNextSegment + * AllocSelector + * + * This is very bad!!! This function is implemented for Windows + * compatibility only. Do not call this from the emulation library. */ -struct segment_descriptor_s * -GetNextSegment(unsigned int flags, unsigned int limit) +unsigned int +AllocSelector(unsigned int old_selector) { - struct segment_descriptor_s *selectors, *s; - int sel_idx; + 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 - FILE *zfile; + 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]; - sel_idx = next_unused_selector++; + 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 * +CreateNewSegment(int code_flag, int read_only, int length) +{ + 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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 -#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 HcwPel00001 literal 1094 zcwX(!F$%&k6vpuvQ|KaObFI+DNjf_ANFG3JrGukas#ub1RC3uY36b!V=PTONnzD#!Lqt2jx!=-nxDQ1%8-V%4zn=*UPkrpayrHkI;Fo|UmRF-82nAoyk(@<=Ehb>>7YC1e3j%uaQxC7ZTw zn(pL9(Oi-C;g4LB+m!q~q}##Ah%EiHy0pNu1Jo8sH^9XQuz1=uk?6`=d(GD- -#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 HcwPel00001 literal 35298 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 delta 8787 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 yaFv1{^iPX8AQH - #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)) @@ -363,6 +351,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) */ void EndDialog( HWND hwnd, short retval ) 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; @@ -478,6 +491,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) */ void MoveWindow(HWND hWnd, short x, short y, short w, short h, BOOL bRepaint) @@ -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) */ @@ -733,6 +791,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) */ BOOL IsChild( HWND parent, HWND child ) @@ -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) */ -- 2.11.4.GIT